diff --git a/grib/src/main/java/ucar/nc2/grib/collection/Grib2Collection.java b/grib/src/main/java/ucar/nc2/grib/collection/Grib2Collection.java index fcbce2fad8..cdf80f6834 100644 --- a/grib/src/main/java/ucar/nc2/grib/collection/Grib2Collection.java +++ b/grib/src/main/java/ucar/nc2/grib/collection/Grib2Collection.java @@ -273,8 +273,8 @@ else if (vindex.getProbabilityName() != null && !vindex.getProbabilityName().isE v.addAttribute(new Attribute("Grib2_Generating_Process_Type", vindex.getGenProcessType())); } - String statType = cust2.getStatisticName(vindex.getIntvType()); - if (statType != null) { + if (vindex.getIntvType() >= 0) { + String statType = cust2.getStatisticName(vindex.getIntvType()); v.addAttribute(new Attribute("Grib2_Statistical_Process_Type", statType)); } diff --git a/grib/src/main/java/ucar/nc2/grib/collection/Grib2Iosp.java b/grib/src/main/java/ucar/nc2/grib/collection/Grib2Iosp.java index 770e763518..5727033630 100644 --- a/grib/src/main/java/ucar/nc2/grib/collection/Grib2Iosp.java +++ b/grib/src/main/java/ucar/nc2/grib/collection/Grib2Iosp.java @@ -60,9 +60,7 @@ static String makeVariableNameFromTable(Grib2Tables cust, GribCollectionImmutabl if (vindex.getIntvType() >= 0) { String statName = cust.getStatisticNameShort(vindex.getIntvType()); - if (statName != null) { - f.format("_%s", statName); - } + f.format("_%s", statName); } if (vindex.getSpatialStatisticalProcessType() >= 0) { @@ -109,20 +107,14 @@ static String makeVariableLongName(Grib2Tables cust, GribCollectionImmutable.Var f.format("%s", gp.getName()); } - if (vindex.getIntvType() >= 0 && vindex.getIntvName() != null && !vindex.getIntvName().isEmpty()) { - String intvName = cust.getStatisticNameShort(vindex.getIntvType()); - if (intvName == null || intvName.equalsIgnoreCase("Missing")) { - intvName = cust.getStatisticNameShort(vindex.getIntvType()); - } - if (intvName == null) { - f.format(" (%s)", vindex.getIntvName()); + if (vindex.getIntvType() >= 0) { + String intvName = vindex.getIntvName(); + String statName = cust.getStatisticNameShort(vindex.getIntvType()); + if (intvName != null && !intvName.isEmpty()) { + f.format(" (%s %s)", intvName, statName); } else { - f.format(" (%s %s)", vindex.getIntvName(), intvName); + f.format(" (%s)", statName); } - - } else if (vindex.getIntvType() >= 0) { - String intvName = cust.getStatisticNameShort(vindex.getIntvType()); - f.format(" (%s)", intvName); } if (vindex.getSpatialStatisticalProcessType() >= 0) { diff --git a/grib/src/main/java/ucar/nc2/grib/grib2/table/FslHrrrLocalTables.java b/grib/src/main/java/ucar/nc2/grib/grib2/table/FslHrrrLocalTables.java index 218707d8bd..5ef4c38bda 100644 --- a/grib/src/main/java/ucar/nc2/grib/grib2/table/FslHrrrLocalTables.java +++ b/grib/src/main/java/ucar/nc2/grib/grib2/table/FslHrrrLocalTables.java @@ -9,6 +9,8 @@ import java.nio.charset.StandardCharsets; import ucar.nc2.grib.GribTables; import ucar.nc2.grib.grib2.Grib2Parameter; + +import javax.annotation.Nonnull; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -105,6 +107,7 @@ public String getLevelName(int id) { return super.getLevelName(id); } + @Nonnull public String getStatisticNameShort(int id) { if (id == 255) { return "Interval"; diff --git a/grib/src/main/java/ucar/nc2/grib/grib2/table/Grib2Tables.java b/grib/src/main/java/ucar/nc2/grib/grib2/table/Grib2Tables.java index 2e2d46aae7..cc639ede56 100644 --- a/grib/src/main/java/ucar/nc2/grib/grib2/table/Grib2Tables.java +++ b/grib/src/main/java/ucar/nc2/grib/grib2/table/Grib2Tables.java @@ -6,6 +6,8 @@ package ucar.nc2.grib.grib2.table; import com.google.common.collect.ImmutableList; + +import javax.annotation.Nonnull; import javax.annotation.Nullable; import thredds.featurecollection.TimeUnitConverter; import ucar.nc2.grib.GribNumbers; @@ -236,6 +238,7 @@ public String getCategory(int discipline, int category) { return (entry == null) ? null : entry.getName(); } + @Nonnull public String getStatisticName(int id) { String result = getCodeTableValue("4.10", id); // WMO if (result == null) { @@ -244,9 +247,10 @@ public String getStatisticName(int id) { return result; } + @Nonnull public String getStatisticNameShort(int id) { GribStatType stat = GribStatType.getStatTypeFromGrib2(id); - return (stat == null) ? "UnknownStatType-" + id : stat.toString(); + return (stat == null) ? String.format("UnknownStatType%d", id) : stat.toString(); } @Override diff --git a/grib/src/main/java/ucar/nc2/grib/grib2/table/NcepLocalTables.java b/grib/src/main/java/ucar/nc2/grib/grib2/table/NcepLocalTables.java index 20b0b5624f..2fca0126a2 100644 --- a/grib/src/main/java/ucar/nc2/grib/grib2/table/NcepLocalTables.java +++ b/grib/src/main/java/ucar/nc2/grib/grib2/table/NcepLocalTables.java @@ -6,6 +6,8 @@ package ucar.nc2.grib.grib2.table; import com.google.common.collect.ImmutableList; + +import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.jdom2.Element; import org.jdom2.JDOMException; @@ -298,6 +300,7 @@ public String getLevelNameShort(int id) { ////////////////////////////////////////////////////////////// @Override + @Nonnull public String getStatisticNameShort(int id) { switch (id) { case 192: @@ -381,18 +384,17 @@ public GribStatType getStatType(int id) { private static Map statName; // shared by all instances @Override - @Nullable + @Nonnull public String getStatisticName(int id) { if (id < 192) return super.getStatisticName(id); if (statName == null) statName = initTable410(); - if (statName == null) - return null; - return statName.get(id); + String result = statName.get(id); + return result != null ? result : getStatisticNameShort(id); } - @Nullable + @Nonnull private Map initTable410() { String path = config.getPath() + "Table4.10.xml"; try (InputStream is = GribResourceReader.getInputStream(path)) { @@ -412,7 +414,7 @@ private Map initTable410() { } catch (IOException | JDOMException ioe) { logger.error("Cant read " + path, ioe); - return null; + return Collections.emptyMap(); } } diff --git a/grib/src/test/data/gfs.t00z.pgrb2.1p00.f003 b/grib/src/test/data/gfs.t00z.pgrb2.1p00.f003 new file mode 100644 index 0000000000..7d733552c4 Binary files /dev/null and b/grib/src/test/data/gfs.t00z.pgrb2.1p00.f003 differ diff --git a/grib/src/test/java/ucar/nc2/grib/grib2/TestPdsInterval.java b/grib/src/test/java/ucar/nc2/grib/grib2/TestPdsInterval.java new file mode 100644 index 0000000000..aef70b325b --- /dev/null +++ b/grib/src/test/java/ucar/nc2/grib/grib2/TestPdsInterval.java @@ -0,0 +1,39 @@ +package ucar.nc2.grib.grib2; + +import org.junit.Test; +import ucar.nc2.Attribute; +import ucar.nc2.NetcdfFile; +import ucar.nc2.NetcdfFiles; +import ucar.nc2.Variable; + +import javax.annotation.Nullable; +import java.io.IOException; + +import static com.google.common.truth.Truth.assertThat; + +public class TestPdsInterval { + + private static void assertStatType(@Nullable Variable v, String expected) { + Attribute grib2StatType = v.findAttribute("Grib2_Statistical_Process_Type"); + assertThat(grib2StatType.getStringValue()).isEqualTo(expected); + } + + @Test + public void testStatisticalProcessTypeAttributeExists() throws IOException { + try (NetcdfFile nc = NetcdfFiles.open("../grib/src/test/data/gfs.t00z.pgrb2.1p00.f003")) { + assertStatType(nc.findVariable("Albedo_surface_3_Hour_Average"), "Average"); + assertStatType(nc.findVariable("Maximum_temperature_height_above_ground_3_Hour_Maximum"), "Maximum"); + assertStatType(nc.findVariable("Minimum_temperature_height_above_ground_3_Hour_Minimum"), "Minimum"); + assertStatType(nc.findVariable("Total_precipitation_surface_3_Hour_Accumulation"), "Accumulation"); + } + } + + @Test + public void testStatisticalProcessTypeAttributeNotPresent() throws IOException { + try (NetcdfFile nc = NetcdfFiles.open("../grib/src/test/data/gfs.t00z.pgrb2.1p00.f003")) { + Variable v = nc.findVariable("Convective_available_potential_energy_surface"); + assertThat(v.findAttribute("Grib2_Statistical_Process_Type")).isNull(); + } + } + +}