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

Commit

Permalink
Merge pull request #1334 from lesserwhirls/rad
Browse files Browse the repository at this point in the history
Add four new super-res level 3 products:
  • Loading branch information
lesserwhirls authored Aug 17, 2020
2 parents 02d69c9 + 8bc5fe6 commit 7db9a62
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 60 deletions.
126 changes: 66 additions & 60 deletions cdm/src/main/java/ucar/nc2/iosp/nids/Nidsheader.java
Original file line number Diff line number Diff line change
Expand Up @@ -1729,10 +1729,20 @@ int pcode_radial( ByteBuffer bos, int hoff, int hedsiz, boolean isZ, byte[] dat
addParameter(vName, lName, ncfile, dims1, att, DataType.DOUBLE, "milliseconds since 1970-01-01 00:00 UTC"
,hoff, hedsiz, isZ, 0);
//add RAW, BRIT variables for all radial variable
if(pcode == 182 || pcode == 99 || pcode == 180) {
levels = getTDWRLevels(nlevel, threshold);
iscale = 10;
} else if (pcode == 186 || pcode == 94) {
if(pcode == 182 || pcode == 99 || pcode == 180 || pcode == 154) {
levels = getTDWRLevels(nlevel, threshold);
iscale = 10;
} else if (pcode == 155) {
// ICD v19 3-34
// "For product 155, data levels 129 through 152
// denote data values starting from the minimum data value in even data increments."
// Let's compute the correct offset based on the fact that the levels start at 129
// and not 0. We need 129 to correspond to what was in threshold 0 when the scale is applied
// First two levels are missing and range folded (set in getTDWRLevels), so we use 127, not 129.
threshold[0] += -127 * threshold[1];
levels = getTDWRLevels(nlevel, threshold);
iscale = 10;
} else if (pcode == 186 || pcode == 94 || pcode == 153) {
threshold[0] = -320;
threshold[1] = 5;
threshold[2] = 254;
Expand All @@ -1750,7 +1760,8 @@ int pcode_radial( ByteBuffer bos, int hoff, int hedsiz, boolean isZ, byte[] dat
} else if (pcode ==159 || pcode ==161 || pcode == 163
|| pcode == 170 || pcode == 172 || pcode == 173
|| pcode == 174 || pcode == 175
|| pcode == 165 || pcode == 177) {
|| pcode == 165 || pcode == 177 || pcode == 167
|| pcode == 168) {

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

ctilt = pname_lookup(pcode, prod_elevation/10);
ctitle = "BREF: Base Spectrum Width";
ctitle = "Base Spectrum Width";
cunit = "Knots";
cname = "SpectrumWidth";
summary = ctilt + " is a radial image of base reflectivity at tilt " + (prod_elevation/10 + 1) + " and range 124 nm";
summary = ctilt + " is a radial image of base spectrum width at tilt " + (prod_elevation / 10 + 1)
+ " and range 124 nm";
if(pcode == 28 ){
t1 = t1 * 0.25;
t2 = t2 * 0.25;
lat_min = latitude - t1;
lat_max = latitude + t1;
lon_min = longitude + t2; //* Math.cos(Math.toRadians(lat_min));
lon_max = longitude - t2; //* Math.cos(Math.toRadians(lat_min));
summary = ctilt + " is a radial image of base reflectivity at tilt " + (prod_elevation/10 + 1) + " and range 32 nm";
summary = ctilt + " is a radial image of base spectrum width at tilt " + (prod_elevation / 10 + 1)
+ " and range 32 nm";
}
}
else if (prod_type == DigitalDifferentialReflectivity) {
Expand Down Expand Up @@ -2402,16 +2415,16 @@ else if (prod_type == HydrometeorClassification ) {
else if (prod_type == HypridHydrometeorClassification ) {
radial = 1;
prod_elevation = pinfo.p3;
cmemo = "Hyprid Hydrometeor Classification " + prod_elevation/10 + " DEG " + cmode[pinfo.opmode];
cmemo = "Hybrid Hydrometeor Classification " + prod_elevation/10 + " DEG " + cmode[pinfo.opmode];

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


ctitle = "Dualpol: Hyprid Hydrometeor Classification";
ctitle = "Dualpol: Hybrid Hydrometeor Classification";
cunit = " ";
cname = "HypridHydrometeorClassification";
summary = ctilt + " is a radial image of dual pol Hyprid Hydrometeor Classification field and its range 162 nm";
summary = ctilt + " is a radial image of dual pol Hybrid Hydrometeor Classification field and its range 162 nm";

}
else if (prod_type == OneHourAccumulation ) {
Expand Down Expand Up @@ -3243,14 +3256,16 @@ Pinfo read_proddesc( ByteBuffer buf, int offset ){
p3 = (short)getInt(b2, 2);
off += 40;
if(pcode == 182 || pcode == 186 || pcode == 32
|| pcode == 94 || pcode == 99 || pcode == 180) {
|| pcode == 94 || pcode == 99 || pcode == 180
|| pcode == 153 || pcode == 154 || pcode == 155) {
for(int i = 0; i< 16; i++) {
buf.get(b2, 0, 2);
threshold[i] = (short)bytesToInt(b2[0], b2[1], false);
}
} else if(pcode == 159 || pcode == 161 || pcode == 163
|| pcode == 170 || pcode == 172 || pcode == 173
|| pcode == 174 || pcode == 175 ) {
|| pcode == 174 || pcode == 175 || pcode == 167
|| pcode == 168) {
// Scale hw 31 32
buf.get(b4, 0, 4);
byte[] b44 = {b4[3], b4[2], b4[1], b4[0]};
Expand Down Expand Up @@ -3711,49 +3726,39 @@ byte[] GetZlibedNexr( byte[] buf, int buflen, int hoff ) throws IOException
static int code_typelookup( int code )
{
int type;
final int[] types = {
Other, Other, Other, Other, Other, /* 0- 9 */
Other, Other, Other, Other, Other,
Other, Other, Other, Other, Other, /* 10- 19 */
Other, Base_Reflect, Base_Reflect, Base_Reflect, Base_Reflect,
BaseReflect248, Base_Reflect, Velocity, /* 20- 29 */
Velocity, Velocity, Velocity, Velocity, Velocity, SPECTRUM, SPECTRUM,
SPECTRUM, Other, DigitalHybridReflect, Other, Other, /* 30- 39 */
Comp_Reflect, Comp_Reflect, Comp_Reflect, Comp_Reflect, Other,
Other, Echo_Tops, Other, Other, Other, /* 40- 49 */
Other, Other, Other, VAD, Other,
Other, Other, Other, Other, Other, /* 50- 59 */
StrmRelMeanVel, StrmRelMeanVel, Vert_Liquid, Other, Other,
Other, Other, Other, Layer_Reflect_Avg, /* 60- 69 */
Layer_Reflect_Avg, Layer_Reflect_Max,
Layer_Reflect_Max, Other, Other, Other,
Other, Other, Other, Other, Other, /* 70- 79 */
Other, Other, Other, Precip_1, Precip_3,
Precip_Accum, Precip_Array, Other, /* 80- 89 */
Other, Other, Other, Other, Other, Other, Layer_Reflect_Avg,
Layer_Reflect_Max, Other, Other, Other, /* 90- 99 */
BaseReflectivityDR, Other, Other, Other, Other, BaseVelocityDV,
Other, Other, Other, Other, Other, /* 100-109 */
Other, Other, Other, Other, Other,
Other, Other, Other, Other, Other, /* 110-119 */
Other, Other, Other, Other, Other,
Other, Other, Other, Other, Other, /* 120-129 */
Other, Other, Other, Other, Other,
Other, Other, Other, Other, DigitalVert_Liquid, /* 130-139 */
EnhancedEcho_Tops, Other, Other, DigitalStormTotalPrecip, Other,
Other, Other, Other, Other, Other, /* 140-149 */
Other, Other, Other, Other, Other,
Other, Other, Other, Other, Other, /* 150-159 */
Other, Other, Other, Other, DigitalDifferentialReflectivity,
Other, DigitalCorrelationCoefficient, Other, DigitalDifferentialPhase, Other, /* 160-169 */
HydrometeorClassification, Other, Other, Other, OneHourAccumulation,
DigitalAccumulationArray, StormTotalAccumulation, DigitalStormTotalAccumulation,
Accumulation3Hour, Digital1HourDifferenceAccumulation,/* 170-179 */
DigitalTotalDifferenceAccumulation, DigitalInstantaneousPrecipitationRate,
HypridHydrometeorClassification, Other, Other,
Reflect1, Reflect1, Velocity1, Velocity1, Other, /* 180-189 */
SPECTRUM1, Reflect1, Reflect1, Other, Other,
};
int[] types = {Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, // 0 - 9
Other, Other, Other, Other, Other, Other, Base_Reflect, Base_Reflect, Base_Reflect, Base_Reflect, // 10 - 19
BaseReflect248, Base_Reflect, Velocity, Velocity, Velocity, // 20 - 24
Velocity, Velocity, Velocity, SPECTRUM, SPECTRUM, // 25 - 29
SPECTRUM, Other, DigitalHybridReflect, Other, Other, // 30 - 34
Comp_Reflect, Comp_Reflect, Comp_Reflect, Comp_Reflect, Other, // 35 - 39
Other, Echo_Tops, Other, Other, Other, // 40 - 44
Other, Other, Other, VAD, Other, Other, Other, Other, Other, Other, // 45- 54
StrmRelMeanVel, StrmRelMeanVel, Vert_Liquid, Other, Other, // 55 - 59
Other, Other, Other, Layer_Reflect_Avg, Layer_Reflect_Avg, // 60 - 64
Layer_Reflect_Max, Layer_Reflect_Max, Other, Other, Other, // 65 - 69
Other, Other, Other, Other, Other, // 70 - 74
Other, Other, Other, Precip_1, Precip_3, // 75 - 79
Precip_Accum, Precip_Array, Other, Other, Other, // 80 - 84
Other, Other, Other, Other, Layer_Reflect_Avg, // 85 - 89
Layer_Reflect_Max, Other, Other, Other, BaseReflectivityDR, // 90 - 94
Other, Other, Other, Other, BaseVelocityDV, // 95 - 99
Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, // 100 - 109
Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, // 110 - 119
Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, // 120 - 129
Other, Other, Other, Other, DigitalVert_Liquid, // 130 - 134
EnhancedEcho_Tops, Other, Other, DigitalStormTotalPrecip, Other, // 135 - 139
Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, // 140 - 149
Other, Other, Other, BaseReflectivityDR, BaseVelocityDV, // 150 - 154
SPECTRUM, Other, Other, Other, DigitalDifferentialReflectivity, // 155 - 159
Other, DigitalCorrelationCoefficient, Other, DigitalDifferentialPhase, Other, // 160 - 164
HydrometeorClassification, Other, DigitalCorrelationCoefficient, Other, // 165 - 168
OneHourAccumulation, DigitalAccumulationArray, // 169 - 170
StormTotalAccumulation, DigitalStormTotalAccumulation, Accumulation3Hour, // 171 - 173
Digital1HourDifferenceAccumulation, DigitalTotalDifferenceAccumulation, // 174 - 175
DigitalInstantaneousPrecipitationRate, HypridHydrometeorClassification, Other, Other, // 176 - 179
Reflect1, Reflect1, Velocity1, Velocity1, Other, // 180 - 184
SPECTRUM1, Reflect1, Reflect1, Other, Other}; // 185 - 189

if ( code < 0 || code > 189 )
type = Other;
Expand Down Expand Up @@ -3905,6 +3910,7 @@ else if(elevation == 3)
case 183:
pname = "V";
break;
case 155:
case 185:
pname = "SW";
break;
Expand Down Expand Up @@ -3944,8 +3950,8 @@ static double code_reslookup( int code )
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 120-129 */
0, 0, 0, 0, 1, 1, 0, 0, 1, 0, /* 130-139 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 140-149 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0.25, /* 150-159 */
0, 0.25, 0, 0.25, 0, 0.25, 0, 0, 0, 2, /* 160-169 */
0, 0, 0, 0.25, 0.25, 0.25, 0, 0, 0, 0.25, /* 150-159 */
0, 0.25, 0, 0.25, 0, 0.25, 0, 0.25, 0.25, 2, /* 160-169 */
0.25, 2, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0, 0, /* 170-179 */
150.0, 150.0, 150.0, 0, 0, 0, 300.0, 0, 0, 0, /* 180-189 */
};
Expand Down Expand Up @@ -3986,8 +3992,8 @@ static int code_levelslookup( int code )
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 120-129 */
0, 0, 0, 0, 256, 199, 0, 0, 256, 0, /* 130-139 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 140-149 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 256, /* 150-159 */
0, 256, 0, 256, 0, 256, 0, 0, 0, 16, /* 160-169 */
0, 0, 0, 256, 256, 256, 0, 0, 0, 256, /* 150-159 */
0, 256, 0, 256, 0, 256, 0, 256, 256, 16, /* 160-169 */
256, 16, 256, 256, 0, 0, 0, 16, 0, 0, /* 170-179 */
256, 16, 256, 0, 0, 0, 256, 0, 0, 0, /* 180-189 */
};
Expand Down
Binary file added cdm/src/test/data/nids/H0C_20200814_0417
Binary file not shown.
Binary file added cdm/src/test/data/nids/H0V_20200812_1309
Binary file not shown.
Binary file added cdm/src/test/data/nids/H0W_20200812_1305
Binary file not shown.
Binary file added cdm/src/test/data/nids/H0Z_20200812_1318
Binary file not shown.
82 changes: 82 additions & 0 deletions cdm/src/test/java/ucar/nc2/iosp/nids/TestNids.java
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,88 @@ public void testRadialImageMessagePcode180() throws IOException {
}
}

public void testRadialImageMessagePcode153() throws IOException {
// Radial Image message, product code 153 (super res reflectivity).
double comparisonTolerance = 0.1;
String datafile = TestDir.cdmLocalTestDataDir + "nids/H0Z_20200812_1318";
try (NetcdfFile ncf = NetcdfFile.open(datafile)) {
Variable bref = ncf.findVariable("BaseReflectivityDR");
Array data = bref.read();
double max = MAMath.getMaximum(data);
// expected max reflectivity value obtained from metpy decoder.
Assert.assertTrue(Math.abs(max - 59.0) < comparisonTolerance);
// test that range of the radial axis variable is good.
Variable gate = ncf.findVariable("gate");
Array gateValues = gate.read();
MinMax minMax = MAMath.getMinMax(gateValues);
Assert.assertTrue(Math.abs(minMax.min) < comparisonTolerance);
// within 1 km of 460 km.
Assert.assertTrue(Math.abs(minMax.max - 460000) < 1000);
}
}

public void testRadialImageMessagePcode154() throws IOException {
// Radial Image message, product code 154 (super res velocity).
double comparisonTolerance = 0.1;
String datafile = TestDir.cdmLocalTestDataDir + "nids/H0V_20200812_1309";
try (NetcdfFile ncf = NetcdfFile.open(datafile)) {
Variable bref = ncf.findVariable("BaseVelocityDV");
Array data = bref.read();
double max = MAMath.getMaximum(data);
// expected max velocity value obtained from metpy decoder.
Assert.assertTrue(Math.abs(max - 44.5) < comparisonTolerance);
// test that range of the radial axis variable is good.
Variable gate = ncf.findVariable("gate");
Array gateValues = gate.read();
MinMax minMax = MAMath.getMinMax(gateValues);
Assert.assertTrue(Math.abs(minMax.min) < comparisonTolerance);
// within 1 km of 300 km.
Assert.assertTrue(Math.abs(minMax.max - 300000) < 1000);
}
}

public void testRadialImageMessagePcode155() throws IOException {
// Radial Image message, product code 155 (super res spectrum width).
double comparisonTolerance = 0.1;
String datafile = TestDir.cdmLocalTestDataDir + "nids/H0W_20200812_1305";
try (NetcdfFile ncf = NetcdfFile.open(datafile)) {
Variable bref = ncf.findVariable("SpectrumWidth");
Array data = bref.read();
double max = MAMath.getMaximum(data);
// expected max spectrum width value obtained from metpy decoder.
Assert.assertTrue(Math.abs(max - 15.0) < comparisonTolerance);
// test that range of the radial axis variable is good.
Variable gate = ncf.findVariable("gate");
Array gateValues = gate.read();
MinMax minMax = MAMath.getMinMax(gateValues);
Assert.assertTrue(Math.abs(minMax.min) < comparisonTolerance);
// within 1 km of 300 km.
Assert.assertTrue(Math.abs(minMax.max - 300000) < 1000);
}
}

public void testRadialImageMessagePcode167() throws IOException {
// Radial Image message, product code 167 (super res digital correlation coefficient).
double comparisonTolerance = 0.1;
String datafile = TestDir.cdmLocalTestDataDir + "nids/H0C_20200814_0417";
try (NetcdfFile ncf = NetcdfFile.open(datafile)) {
Variable bref = ncf.findVariable("CorrelationCoefficient");
Array data = bref.read();
double max = MAMath.getMaximum(data);
// expected max correlation coefficient value obtained from metpy decoder.
// can be greater than 1 due to the way it is measured, but should not be much greater than one.
Assert.assertTrue(Math.abs(max - 1.05167) < comparisonTolerance);
// test that range of the radial axis variable is good.
Variable gate = ncf.findVariable("gate");
Array gateValues = gate.read();
MinMax minMax = MAMath.getMinMax(gateValues);
Assert.assertTrue(Math.abs(minMax.min) < comparisonTolerance);
// within 1 km of 300 km.
Assert.assertTrue(Math.abs(minMax.max - 300000) < 1000);
}
}


private void testReadData(Variable v) {
Array a = null;
assert(null != v);
Expand Down

0 comments on commit 7db9a62

Please sign in to comment.