From bc381705dcf7efbb7a33d83c52b9fb647bcfd1e8 Mon Sep 17 00:00:00 2001 From: Sean Arms <67096+lesserwhirls@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:14:21 -0600 Subject: [PATCH] Add tests for GRIB2 PDS 40 --- .../java/ucar/nc2/grib/grib2/Grib2Pds.java | 2 +- ...ch1-202606181100-0-poacsnc-ctrl.grib2.gbx9 | Bin 0 -> 288 bytes .../java/ucar/nc2/grib/grib2/TestPds40.java | 133 ++++++++++++++++++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 grib/src/test/data/index/kenda-ch1-202606181100-0-poacsnc-ctrl.grib2.gbx9 create mode 100644 grib/src/test/java/ucar/nc2/grib/grib2/TestPds40.java diff --git a/grib/src/main/java/ucar/nc2/grib/grib2/Grib2Pds.java b/grib/src/main/java/ucar/nc2/grib/grib2/Grib2Pds.java index f310e73937..e652628f46 100644 --- a/grib/src/main/java/ucar/nc2/grib/grib2/Grib2Pds.java +++ b/grib/src/main/java/ucar/nc2/grib/grib2/Grib2Pds.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2018 John Caron and University Corporation for Atmospheric Research/Unidata + * Copyright (c) 1998-2026 John Caron and University Corporation for Atmospheric Research/Unidata * See LICENSE for license information. */ diff --git a/grib/src/test/data/index/kenda-ch1-202606181100-0-poacsnc-ctrl.grib2.gbx9 b/grib/src/test/data/index/kenda-ch1-202606181100-0-poacsnc-ctrl.grib2.gbx9 new file mode 100644 index 0000000000000000000000000000000000000000..868a2b8921538a33f9833a22666dff368589f002 GIT binary patch literal 288 zcmZ=S%1koy%u7kFV4KXu<*grDoLW?@Uz}K!TdePrTAW>yU!b3!0Ytinre+rU*{OLc ziMq)dhPp-uMrHT;$~p5V02*A5@-0w!2XI&h{uErXcinW8ZcPd0C_en3~US8zRWT$}` z0bnxFX%Pd1Ljwat{>qnIyRJlQO{w8)TXkFafx`ku4~Bp<9c~d@85909X6$Axm^-nD Nv4Ww2k)eZ;0RUxDNl^d* literal 0 HcmV?d00001 diff --git a/grib/src/test/java/ucar/nc2/grib/grib2/TestPds40.java b/grib/src/test/java/ucar/nc2/grib/grib2/TestPds40.java new file mode 100644 index 0000000000..89eb062866 --- /dev/null +++ b/grib/src/test/java/ucar/nc2/grib/grib2/TestPds40.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2026 University Corporation for Atmospheric Research/Unidata + * See LICENSE for license information. + */ + +package ucar.nc2.grib.grib2; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.IOException; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test data from github issue https://github.com/Unidata/netcdf-java/pull/1568 + * Data was used to create a .gbx9 file for testing. + *

+ * PDS (Secton 4) output from ecCodes grib_dump at the end of the file, uses as a basis for + * testing PDS (Secton 4) parsing + */ +@RunWith(JUnit4.class) +public class TestPds40 { + + private Grib2Pds pds; + + @Before + public void openTestFile() throws IOException { + String testfile = "../grib/src/test/data/index/kenda-ch1-202606181100-0-poacsnc-ctrl.grib2.gbx9"; + + Grib2Index gi = new Grib2Index(); + boolean success = gi.readIndex(testfile, -1); + assertThat(success).isTrue(); + List records = gi.getRecords(); + Grib2Record record = records.get(0); + pds = record.getPDS(); + } + + @Test + public void testPdsBasic() { + assertThat(pds.getRawLength()).isEqualTo(60); + assertThat(pds.getTemplateNumber()).isEqualTo(40); + } + + // check overrides + @Test + public void testGenProcessType() { + assertThat(pds.getGenProcessType()).isEqualTo(2);; + } + + @Test + public void testBackProcessId() { + assertThat(pds.getBackProcessId()).isEqualTo(0);; + } + + @Test + public void testGenProcessId() { + assertThat(pds.getGenProcessId()).isEqualTo(151);; + } + + @Test + public void testTimeUnit() { + assertThat(pds.getTimeUnit()).isEqualTo(0); + } + + @Test + public void testLevelType1() { + assertThat(pds.getLevelType1()).isEqualTo(150); + } + + @Test + public void testLevelScale1() { + assertThat(pds.getLevelScale1()).isEqualTo(0); + } + + @Test + public void testLevelValue1() { + assertThat(pds.getLevelValue1()).isEqualTo(80); + } + + @Test + public void testLevelType2() { + assertThat(pds.getLevelType2()).isEqualTo(150); + } + + @Test + public void testLevelScale2() { + assertThat(pds.getLevelScale2()).isEqualTo(0); + } + + @Test + public void testLevelValue2() { + assertThat(pds.getLevelValue2()).isEqualTo(81); + } + + @Test + public void testTemplateLength() { + assertThat(pds.templateLength()).isEqualTo(36); + } +} + +// grib_dump -O kenda-ch1-202606181100-0-poacsnc-ctrl.grib2 +// ***** FILE: kenda-ch1-202606181100-0-poacsnc-ctrl.grib2 +// ... +// ====================== SECTION_4 ( length=60, padding=0 ) ====================== +// 1-4 section4Length = 60 +// 5 numberOfSection = 4 +// 6-7 NV = 6 +// 8-9 productDefinitionTemplateNumber = 40 [Analysis or forecast at a horizontal level or in a horizontal layer at a +// point in time for atmospheric chemical constituents (grib2/tables/15/4.0.table) ] +// 10 parameterCategory = 20 [Atmospheric chemical constituents (grib2/tables/15/4.1.0.table) ] +// 11 parameterNumber = 60 [Unknown code table entry (grib2/tables/15/4.2.0.20.table) ] +// 12-13 constituentType = 62300 [Unknown code table entry (grib2/tables/15/4.230.table) ] +// 14 typeOfGeneratingProcess = 2 [Forecast (grib2/tables/15/4.3.table) ] +// 15 backgroundProcess = 0 +// 16 generatingProcessIdentifier = 151 +// 17-18 hoursAfterDataCutoff = 0 +// 19 minutesAfterDataCutoff = 0 +// 20 indicatorOfUnitForForecastTime = 0 [Minute (grib2/tables/15/4.4.table) ] +// 21-24 forecastTime = 0 +// 25 typeOfFirstFixedSurface = 150 [Generalized vertical height coordinate (grib2/tables/15/4.5.table) ] +// 26 scaleFactorOfFirstFixedSurface = 0 +// 27-30 scaledValueOfFirstFixedSurface = 80 +// 31 typeOfSecondFixedSurface = 150 [Generalized vertical height coordinate (grib2/tables/15/4.5.table) ] +// 32 scaleFactorOfSecondFixedSurface = 0 +// 33-36 scaledValueOfSecondFixedSurface = 81 +// 37-40 nlev = 81 +// 41-44 numberOfVGridUsed = 4 +// 45-60 uuidOfVGrid = 16 { +// 6f, a9, e9, b5, 8a, d4, 5b, 2a, 94, 7c, 0e, 86, aa, db, 2d, e0 +// } # bytes uuidOfVGrid