Skip to content
This repository was archived by the owner on Sep 1, 2022. It is now read-only.

Commit 7db9a62

Browse files
authored
Merge pull request #1334 from lesserwhirls/rad
Add four new super-res level 3 products:
2 parents 02d69c9 + 8bc5fe6 commit 7db9a62

File tree

6 files changed

+148
-60
lines changed

6 files changed

+148
-60
lines changed

cdm/src/main/java/ucar/nc2/iosp/nids/Nidsheader.java

+66-60
Original file line numberDiff line numberDiff line change
@@ -1729,10 +1729,20 @@ int pcode_radial( ByteBuffer bos, int hoff, int hedsiz, boolean isZ, byte[] dat
17291729
addParameter(vName, lName, ncfile, dims1, att, DataType.DOUBLE, "milliseconds since 1970-01-01 00:00 UTC"
17301730
,hoff, hedsiz, isZ, 0);
17311731
//add RAW, BRIT variables for all radial variable
1732-
if(pcode == 182 || pcode == 99 || pcode == 180) {
1733-
levels = getTDWRLevels(nlevel, threshold);
1734-
iscale = 10;
1735-
} else if (pcode == 186 || pcode == 94) {
1732+
if(pcode == 182 || pcode == 99 || pcode == 180 || pcode == 154) {
1733+
levels = getTDWRLevels(nlevel, threshold);
1734+
iscale = 10;
1735+
} else if (pcode == 155) {
1736+
// ICD v19 3-34
1737+
// "For product 155, data levels 129 through 152
1738+
// denote data values starting from the minimum data value in even data increments."
1739+
// Let's compute the correct offset based on the fact that the levels start at 129
1740+
// and not 0. We need 129 to correspond to what was in threshold 0 when the scale is applied
1741+
// First two levels are missing and range folded (set in getTDWRLevels), so we use 127, not 129.
1742+
threshold[0] += -127 * threshold[1];
1743+
levels = getTDWRLevels(nlevel, threshold);
1744+
iscale = 10;
1745+
} else if (pcode == 186 || pcode == 94 || pcode == 153) {
17361746
threshold[0] = -320;
17371747
threshold[1] = 5;
17381748
threshold[2] = 254;
@@ -1750,7 +1760,8 @@ int pcode_radial( ByteBuffer bos, int hoff, int hedsiz, boolean isZ, byte[] dat
17501760
} else if (pcode ==159 || pcode ==161 || pcode == 163
17511761
|| pcode == 170 || pcode == 172 || pcode == 173
17521762
|| pcode == 174 || pcode == 175
1753-
|| pcode == 165 || pcode == 177) {
1763+
|| pcode == 165 || pcode == 177 || pcode == 167
1764+
|| pcode == 168) {
17541765

17551766
levels = getDualpolLevels(threshold);
17561767
iscale = 100;
@@ -2327,18 +2338,20 @@ void setProductInfo(int prod_type, Pinfo pinfo)
23272338
cmemo = "Base Specturm Width " + prod_elevation/10 + " DEG " + cmode[pinfo.opmode];
23282339

23292340
ctilt = pname_lookup(pcode, prod_elevation/10);
2330-
ctitle = "BREF: Base Spectrum Width";
2341+
ctitle = "Base Spectrum Width";
23312342
cunit = "Knots";
23322343
cname = "SpectrumWidth";
2333-
summary = ctilt + " is a radial image of base reflectivity at tilt " + (prod_elevation/10 + 1) + " and range 124 nm";
2344+
summary = ctilt + " is a radial image of base spectrum width at tilt " + (prod_elevation / 10 + 1)
2345+
+ " and range 124 nm";
23342346
if(pcode == 28 ){
23352347
t1 = t1 * 0.25;
23362348
t2 = t2 * 0.25;
23372349
lat_min = latitude - t1;
23382350
lat_max = latitude + t1;
23392351
lon_min = longitude + t2; //* Math.cos(Math.toRadians(lat_min));
23402352
lon_max = longitude - t2; //* Math.cos(Math.toRadians(lat_min));
2341-
summary = ctilt + " is a radial image of base reflectivity at tilt " + (prod_elevation/10 + 1) + " and range 32 nm";
2353+
summary = ctilt + " is a radial image of base spectrum width at tilt " + (prod_elevation / 10 + 1)
2354+
+ " and range 32 nm";
23422355
}
23432356
}
23442357
else if (prod_type == DigitalDifferentialReflectivity) {
@@ -2402,16 +2415,16 @@ else if (prod_type == HydrometeorClassification ) {
24022415
else if (prod_type == HypridHydrometeorClassification ) {
24032416
radial = 1;
24042417
prod_elevation = pinfo.p3;
2405-
cmemo = "Hyprid Hydrometeor Classification " + prod_elevation/10 + " DEG " + cmode[pinfo.opmode];
2418+
cmemo = "Hybrid Hydrometeor Classification " + prod_elevation/10 + " DEG " + cmode[pinfo.opmode];
24062419

24072420
int pLevel = getProductLevel(prod_elevation);
24082421
ctilt = pname_lookup(18, pLevel);
24092422

24102423

2411-
ctitle = "Dualpol: Hyprid Hydrometeor Classification";
2424+
ctitle = "Dualpol: Hybrid Hydrometeor Classification";
24122425
cunit = " ";
24132426
cname = "HypridHydrometeorClassification";
2414-
summary = ctilt + " is a radial image of dual pol Hyprid Hydrometeor Classification field and its range 162 nm";
2427+
summary = ctilt + " is a radial image of dual pol Hybrid Hydrometeor Classification field and its range 162 nm";
24152428

24162429
}
24172430
else if (prod_type == OneHourAccumulation ) {
@@ -3243,14 +3256,16 @@ Pinfo read_proddesc( ByteBuffer buf, int offset ){
32433256
p3 = (short)getInt(b2, 2);
32443257
off += 40;
32453258
if(pcode == 182 || pcode == 186 || pcode == 32
3246-
|| pcode == 94 || pcode == 99 || pcode == 180) {
3259+
|| pcode == 94 || pcode == 99 || pcode == 180
3260+
|| pcode == 153 || pcode == 154 || pcode == 155) {
32473261
for(int i = 0; i< 16; i++) {
32483262
buf.get(b2, 0, 2);
32493263
threshold[i] = (short)bytesToInt(b2[0], b2[1], false);
32503264
}
32513265
} else if(pcode == 159 || pcode == 161 || pcode == 163
32523266
|| pcode == 170 || pcode == 172 || pcode == 173
3253-
|| pcode == 174 || pcode == 175 ) {
3267+
|| pcode == 174 || pcode == 175 || pcode == 167
3268+
|| pcode == 168) {
32543269
// Scale hw 31 32
32553270
buf.get(b4, 0, 4);
32563271
byte[] b44 = {b4[3], b4[2], b4[1], b4[0]};
@@ -3711,49 +3726,39 @@ byte[] GetZlibedNexr( byte[] buf, int buflen, int hoff ) throws IOException
37113726
static int code_typelookup( int code )
37123727
{
37133728
int type;
3714-
final int[] types = {
3715-
Other, Other, Other, Other, Other, /* 0- 9 */
3716-
Other, Other, Other, Other, Other,
3717-
Other, Other, Other, Other, Other, /* 10- 19 */
3718-
Other, Base_Reflect, Base_Reflect, Base_Reflect, Base_Reflect,
3719-
BaseReflect248, Base_Reflect, Velocity, /* 20- 29 */
3720-
Velocity, Velocity, Velocity, Velocity, Velocity, SPECTRUM, SPECTRUM,
3721-
SPECTRUM, Other, DigitalHybridReflect, Other, Other, /* 30- 39 */
3722-
Comp_Reflect, Comp_Reflect, Comp_Reflect, Comp_Reflect, Other,
3723-
Other, Echo_Tops, Other, Other, Other, /* 40- 49 */
3724-
Other, Other, Other, VAD, Other,
3725-
Other, Other, Other, Other, Other, /* 50- 59 */
3726-
StrmRelMeanVel, StrmRelMeanVel, Vert_Liquid, Other, Other,
3727-
Other, Other, Other, Layer_Reflect_Avg, /* 60- 69 */
3728-
Layer_Reflect_Avg, Layer_Reflect_Max,
3729-
Layer_Reflect_Max, Other, Other, Other,
3730-
Other, Other, Other, Other, Other, /* 70- 79 */
3731-
Other, Other, Other, Precip_1, Precip_3,
3732-
Precip_Accum, Precip_Array, Other, /* 80- 89 */
3733-
Other, Other, Other, Other, Other, Other, Layer_Reflect_Avg,
3734-
Layer_Reflect_Max, Other, Other, Other, /* 90- 99 */
3735-
BaseReflectivityDR, Other, Other, Other, Other, BaseVelocityDV,
3736-
Other, Other, Other, Other, Other, /* 100-109 */
3737-
Other, Other, Other, Other, Other,
3738-
Other, Other, Other, Other, Other, /* 110-119 */
3739-
Other, Other, Other, Other, Other,
3740-
Other, Other, Other, Other, Other, /* 120-129 */
3741-
Other, Other, Other, Other, Other,
3742-
Other, Other, Other, Other, DigitalVert_Liquid, /* 130-139 */
3743-
EnhancedEcho_Tops, Other, Other, DigitalStormTotalPrecip, Other,
3744-
Other, Other, Other, Other, Other, /* 140-149 */
3745-
Other, Other, Other, Other, Other,
3746-
Other, Other, Other, Other, Other, /* 150-159 */
3747-
Other, Other, Other, Other, DigitalDifferentialReflectivity,
3748-
Other, DigitalCorrelationCoefficient, Other, DigitalDifferentialPhase, Other, /* 160-169 */
3749-
HydrometeorClassification, Other, Other, Other, OneHourAccumulation,
3750-
DigitalAccumulationArray, StormTotalAccumulation, DigitalStormTotalAccumulation,
3751-
Accumulation3Hour, Digital1HourDifferenceAccumulation,/* 170-179 */
3752-
DigitalTotalDifferenceAccumulation, DigitalInstantaneousPrecipitationRate,
3753-
HypridHydrometeorClassification, Other, Other,
3754-
Reflect1, Reflect1, Velocity1, Velocity1, Other, /* 180-189 */
3755-
SPECTRUM1, Reflect1, Reflect1, Other, Other,
3756-
};
3729+
int[] types = {Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, // 0 - 9
3730+
Other, Other, Other, Other, Other, Other, Base_Reflect, Base_Reflect, Base_Reflect, Base_Reflect, // 10 - 19
3731+
BaseReflect248, Base_Reflect, Velocity, Velocity, Velocity, // 20 - 24
3732+
Velocity, Velocity, Velocity, SPECTRUM, SPECTRUM, // 25 - 29
3733+
SPECTRUM, Other, DigitalHybridReflect, Other, Other, // 30 - 34
3734+
Comp_Reflect, Comp_Reflect, Comp_Reflect, Comp_Reflect, Other, // 35 - 39
3735+
Other, Echo_Tops, Other, Other, Other, // 40 - 44
3736+
Other, Other, Other, VAD, Other, Other, Other, Other, Other, Other, // 45- 54
3737+
StrmRelMeanVel, StrmRelMeanVel, Vert_Liquid, Other, Other, // 55 - 59
3738+
Other, Other, Other, Layer_Reflect_Avg, Layer_Reflect_Avg, // 60 - 64
3739+
Layer_Reflect_Max, Layer_Reflect_Max, Other, Other, Other, // 65 - 69
3740+
Other, Other, Other, Other, Other, // 70 - 74
3741+
Other, Other, Other, Precip_1, Precip_3, // 75 - 79
3742+
Precip_Accum, Precip_Array, Other, Other, Other, // 80 - 84
3743+
Other, Other, Other, Other, Layer_Reflect_Avg, // 85 - 89
3744+
Layer_Reflect_Max, Other, Other, Other, BaseReflectivityDR, // 90 - 94
3745+
Other, Other, Other, Other, BaseVelocityDV, // 95 - 99
3746+
Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, // 100 - 109
3747+
Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, // 110 - 119
3748+
Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, // 120 - 129
3749+
Other, Other, Other, Other, DigitalVert_Liquid, // 130 - 134
3750+
EnhancedEcho_Tops, Other, Other, DigitalStormTotalPrecip, Other, // 135 - 139
3751+
Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, // 140 - 149
3752+
Other, Other, Other, BaseReflectivityDR, BaseVelocityDV, // 150 - 154
3753+
SPECTRUM, Other, Other, Other, DigitalDifferentialReflectivity, // 155 - 159
3754+
Other, DigitalCorrelationCoefficient, Other, DigitalDifferentialPhase, Other, // 160 - 164
3755+
HydrometeorClassification, Other, DigitalCorrelationCoefficient, Other, // 165 - 168
3756+
OneHourAccumulation, DigitalAccumulationArray, // 169 - 170
3757+
StormTotalAccumulation, DigitalStormTotalAccumulation, Accumulation3Hour, // 171 - 173
3758+
Digital1HourDifferenceAccumulation, DigitalTotalDifferenceAccumulation, // 174 - 175
3759+
DigitalInstantaneousPrecipitationRate, HypridHydrometeorClassification, Other, Other, // 176 - 179
3760+
Reflect1, Reflect1, Velocity1, Velocity1, Other, // 180 - 184
3761+
SPECTRUM1, Reflect1, Reflect1, Other, Other}; // 185 - 189
37573762

37583763
if ( code < 0 || code > 189 )
37593764
type = Other;
@@ -3905,6 +3910,7 @@ else if(elevation == 3)
39053910
case 183:
39063911
pname = "V";
39073912
break;
3913+
case 155:
39083914
case 185:
39093915
pname = "SW";
39103916
break;
@@ -3944,8 +3950,8 @@ static double code_reslookup( int code )
39443950
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 120-129 */
39453951
0, 0, 0, 0, 1, 1, 0, 0, 1, 0, /* 130-139 */
39463952
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 140-149 */
3947-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0.25, /* 150-159 */
3948-
0, 0.25, 0, 0.25, 0, 0.25, 0, 0, 0, 2, /* 160-169 */
3953+
0, 0, 0, 0.25, 0.25, 0.25, 0, 0, 0, 0.25, /* 150-159 */
3954+
0, 0.25, 0, 0.25, 0, 0.25, 0, 0.25, 0.25, 2, /* 160-169 */
39493955
0.25, 2, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0, 0, /* 170-179 */
39503956
150.0, 150.0, 150.0, 0, 0, 0, 300.0, 0, 0, 0, /* 180-189 */
39513957
};
@@ -3986,8 +3992,8 @@ static int code_levelslookup( int code )
39863992
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 120-129 */
39873993
0, 0, 0, 0, 256, 199, 0, 0, 256, 0, /* 130-139 */
39883994
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 140-149 */
3989-
0, 0, 0, 0, 0, 0, 0, 0, 0, 256, /* 150-159 */
3990-
0, 256, 0, 256, 0, 256, 0, 0, 0, 16, /* 160-169 */
3995+
0, 0, 0, 256, 256, 256, 0, 0, 0, 256, /* 150-159 */
3996+
0, 256, 0, 256, 0, 256, 0, 256, 256, 16, /* 160-169 */
39913997
256, 16, 256, 256, 0, 0, 0, 16, 0, 0, /* 170-179 */
39923998
256, 16, 256, 0, 0, 0, 256, 0, 0, 0, /* 180-189 */
39933999
};
502 KB
Binary file not shown.
157 KB
Binary file not shown.
140 KB
Binary file not shown.
252 KB
Binary file not shown.

cdm/src/test/java/ucar/nc2/iosp/nids/TestNids.java

+82
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,88 @@ public void testRadialImageMessagePcode180() throws IOException {
437437
}
438438
}
439439

440+
public void testRadialImageMessagePcode153() throws IOException {
441+
// Radial Image message, product code 153 (super res reflectivity).
442+
double comparisonTolerance = 0.1;
443+
String datafile = TestDir.cdmLocalTestDataDir + "nids/H0Z_20200812_1318";
444+
try (NetcdfFile ncf = NetcdfFile.open(datafile)) {
445+
Variable bref = ncf.findVariable("BaseReflectivityDR");
446+
Array data = bref.read();
447+
double max = MAMath.getMaximum(data);
448+
// expected max reflectivity value obtained from metpy decoder.
449+
Assert.assertTrue(Math.abs(max - 59.0) < comparisonTolerance);
450+
// test that range of the radial axis variable is good.
451+
Variable gate = ncf.findVariable("gate");
452+
Array gateValues = gate.read();
453+
MinMax minMax = MAMath.getMinMax(gateValues);
454+
Assert.assertTrue(Math.abs(minMax.min) < comparisonTolerance);
455+
// within 1 km of 460 km.
456+
Assert.assertTrue(Math.abs(minMax.max - 460000) < 1000);
457+
}
458+
}
459+
460+
public void testRadialImageMessagePcode154() throws IOException {
461+
// Radial Image message, product code 154 (super res velocity).
462+
double comparisonTolerance = 0.1;
463+
String datafile = TestDir.cdmLocalTestDataDir + "nids/H0V_20200812_1309";
464+
try (NetcdfFile ncf = NetcdfFile.open(datafile)) {
465+
Variable bref = ncf.findVariable("BaseVelocityDV");
466+
Array data = bref.read();
467+
double max = MAMath.getMaximum(data);
468+
// expected max velocity value obtained from metpy decoder.
469+
Assert.assertTrue(Math.abs(max - 44.5) < comparisonTolerance);
470+
// test that range of the radial axis variable is good.
471+
Variable gate = ncf.findVariable("gate");
472+
Array gateValues = gate.read();
473+
MinMax minMax = MAMath.getMinMax(gateValues);
474+
Assert.assertTrue(Math.abs(minMax.min) < comparisonTolerance);
475+
// within 1 km of 300 km.
476+
Assert.assertTrue(Math.abs(minMax.max - 300000) < 1000);
477+
}
478+
}
479+
480+
public void testRadialImageMessagePcode155() throws IOException {
481+
// Radial Image message, product code 155 (super res spectrum width).
482+
double comparisonTolerance = 0.1;
483+
String datafile = TestDir.cdmLocalTestDataDir + "nids/H0W_20200812_1305";
484+
try (NetcdfFile ncf = NetcdfFile.open(datafile)) {
485+
Variable bref = ncf.findVariable("SpectrumWidth");
486+
Array data = bref.read();
487+
double max = MAMath.getMaximum(data);
488+
// expected max spectrum width value obtained from metpy decoder.
489+
Assert.assertTrue(Math.abs(max - 15.0) < comparisonTolerance);
490+
// test that range of the radial axis variable is good.
491+
Variable gate = ncf.findVariable("gate");
492+
Array gateValues = gate.read();
493+
MinMax minMax = MAMath.getMinMax(gateValues);
494+
Assert.assertTrue(Math.abs(minMax.min) < comparisonTolerance);
495+
// within 1 km of 300 km.
496+
Assert.assertTrue(Math.abs(minMax.max - 300000) < 1000);
497+
}
498+
}
499+
500+
public void testRadialImageMessagePcode167() throws IOException {
501+
// Radial Image message, product code 167 (super res digital correlation coefficient).
502+
double comparisonTolerance = 0.1;
503+
String datafile = TestDir.cdmLocalTestDataDir + "nids/H0C_20200814_0417";
504+
try (NetcdfFile ncf = NetcdfFile.open(datafile)) {
505+
Variable bref = ncf.findVariable("CorrelationCoefficient");
506+
Array data = bref.read();
507+
double max = MAMath.getMaximum(data);
508+
// expected max correlation coefficient value obtained from metpy decoder.
509+
// can be greater than 1 due to the way it is measured, but should not be much greater than one.
510+
Assert.assertTrue(Math.abs(max - 1.05167) < comparisonTolerance);
511+
// test that range of the radial axis variable is good.
512+
Variable gate = ncf.findVariable("gate");
513+
Array gateValues = gate.read();
514+
MinMax minMax = MAMath.getMinMax(gateValues);
515+
Assert.assertTrue(Math.abs(minMax.min) < comparisonTolerance);
516+
// within 1 km of 300 km.
517+
Assert.assertTrue(Math.abs(minMax.max - 300000) < 1000);
518+
}
519+
}
520+
521+
440522
private void testReadData(Variable v) {
441523
Array a = null;
442524
assert(null != v);

0 commit comments

Comments
 (0)