|
| 1 | +package ucar.nc2.grib.grib2; |
| 2 | + |
| 3 | +import org.junit.Before; |
| 4 | +import org.junit.Test; |
| 5 | +import java.io.IOException; |
| 6 | +import org.junit.runner.RunWith; |
| 7 | +import org.junit.runners.JUnit4; |
| 8 | + |
| 9 | +import ucar.nc2.grib.coord.TimeCoordIntvDateValue; |
| 10 | +import ucar.nc2.grib.grib2.table.Grib2Tables; |
| 11 | +import static org.junit.Assert.assertEquals; |
| 12 | +import static org.junit.Assert.assertTrue; |
| 13 | + |
| 14 | +@RunWith(JUnit4.class) |
| 15 | +public class TestPds8 { |
| 16 | + @Before |
| 17 | + public void openTestFile() throws IOException { |
| 18 | + String testfile = "../grib/src/test/data/index/example_pds_8_quirks.grib2.gbx9"; |
| 19 | + |
| 20 | + Grib2Index gi = new Grib2Index(); |
| 21 | + boolean success = gi.readIndex(testfile, -1); |
| 22 | + assertTrue(success); |
| 23 | + assertEquals(gi.getRecords().size(), 2); |
| 24 | + quirky = gi.getRecords().get(0); |
| 25 | + normal = gi.getRecords().get(1); |
| 26 | + } |
| 27 | + |
| 28 | + @Test |
| 29 | + public void testForQuirkyRecord() { |
| 30 | + Grib2Pds normal_pds = normal.getPDS(); |
| 31 | + Grib2Pds quirky_pds = quirky.getPDS(); |
| 32 | + |
| 33 | + assertEquals(normal_pds.getRawLength(), 58); |
| 34 | + assertEquals(quirky_pds.getRawLength(), 58); |
| 35 | + |
| 36 | + // byte 41 is numberOfTimeRange, which is generally 1 for |
| 37 | + // this type of GRIB2 record. For the quirk, it is zero. |
| 38 | + assertEquals(normal_pds.getOctet(42), 1); |
| 39 | + assertEquals(quirky_pds.getOctet(42), 0); |
| 40 | + } |
| 41 | + |
| 42 | + @Test |
| 43 | + public void testPds8ReadBasic() { |
| 44 | + Grib2Pds pds8 = quirky.getPDS(); |
| 45 | + assertEquals(pds8.getTemplateNumber(), 8); |
| 46 | + assertEquals(pds8.getParameterCategory(), 1); |
| 47 | + assertEquals(pds8.getParameterNumber(), 29); |
| 48 | + assertEquals(pds8.getGenProcessType(), 2); |
| 49 | + assertEquals(pds8.getGenProcessId(), 105); |
| 50 | + assertEquals(pds8.getBackProcessId(), 0); |
| 51 | + assertEquals(pds8.getTimeUnit(), 1); |
| 52 | + assertEquals(pds8.getForecastTime(), 0); |
| 53 | + } |
| 54 | + |
| 55 | + @Test |
| 56 | + public void testPds8CanGetNormalTime() { |
| 57 | + Grib2Tables tbl = Grib2Tables.factory(normal); |
| 58 | + TimeCoordIntvDateValue tc = tbl.getForecastTimeInterval(normal); |
| 59 | + // start and end times are the same |
| 60 | + assertEquals(tc.getStart().getMillis(), tc.getEnd().getMillis()); |
| 61 | + assertEquals(tc.getStart().getMillis(), 1500508800000L); |
| 62 | + } |
| 63 | + |
| 64 | + @Test |
| 65 | + public void testPds8CanStillGetQuirkyTime() { |
| 66 | + Grib2Tables tbl = Grib2Tables.factory(quirky); |
| 67 | + TimeCoordIntvDateValue tc = tbl.getForecastTimeInterval(quirky); |
| 68 | + // start and end times are the same |
| 69 | + assertEquals(tc.getStart().getMillis(), tc.getEnd().getMillis()); |
| 70 | + assertEquals(tc.getStart().getMillis(), 1500508800000L); |
| 71 | + } |
| 72 | + |
| 73 | + /* |
| 74 | + * ====================== SECTION_4 ( length=58, padding=0 ) ====================== |
| 75 | + * 1-4 section4Length = 58 |
| 76 | + * 5 numberOfSection = 4 |
| 77 | + * 6-7 NV = 0 |
| 78 | + * 8-9 productDefinitionTemplateNumber = 8 [Average, accumulation, extreme values or other statistically processed |
| 79 | + * values at a horizontal level or in a horizontal layer in a continuous or non-continuous time interval |
| 80 | + * (grib2/tables/2/4.0.table) ] |
| 81 | + * 10 parameterCategory = 1 [Moisture (grib2/tables/2/4.1.0.table) ] |
| 82 | + * 11 parameterNumber = 8 [Total precipitation (kg m-2) (grib2/tables/2/4.2.0.1.table) ] |
| 83 | + * 12 typeOfGeneratingProcess = 2 [Forecast (grib2/tables/2/4.3.table) ] |
| 84 | + * 13 backgroundProcess = 0 |
| 85 | + * 14 generatingProcessIdentifier = 105 |
| 86 | + * 15-16 hoursAfterDataCutoff = 0 |
| 87 | + * 17 minutesAfterDataCutoff = 0 |
| 88 | + * 18 indicatorOfUnitOfTimeRange = 1 [Hour (grib2/tables/2/4.4.table) ] |
| 89 | + * 19-22 forecastTime = 0 |
| 90 | + * 23 typeOfFirstFixedSurface = 1 [Ground or water surface (grib2/tables/2/4.5.table , |
| 91 | + * grib2/tables/local/kwbc/1/4.5.table) ] |
| 92 | + * 24 scaleFactorOfFirstFixedSurface = 0 |
| 93 | + * 25-28 scaledValueOfFirstFixedSurface = 0 |
| 94 | + * 29 typeOfSecondFixedSurface = 255 [Missing (grib2/tables/2/4.5.table , grib2/tables/local/kwbc/1/4.5.table) ] |
| 95 | + * 30 scaleFactorOfSecondFixedSurface = 0 |
| 96 | + * 31-34 scaledValueOfSecondFixedSurface = 0 |
| 97 | + * 35-36 yearOfEndOfOverallTimeInterval = 2017 |
| 98 | + * 37 monthOfEndOfOverallTimeInterval = 7 |
| 99 | + * 38 dayOfEndOfOverallTimeInterval = 20 |
| 100 | + * 39 hourOfEndOfOverallTimeInterval = 0 |
| 101 | + * 40 minuteOfEndOfOverallTimeInterval = 0 |
| 102 | + * 41 secondOfEndOfOverallTimeInterval = 0 |
| 103 | + * 42 numberOfTimeRange = 1 |
| 104 | + * 43-46 numberOfMissingInStatisticalProcess = 0 |
| 105 | + * 47 typeOfStatisticalProcessing = 1 [Accumulation (grib2/tables/2/4.10.table) ] |
| 106 | + * 48 typeOfTimeIncrement = 2 [Successive times processed have same start time of forecast, forecast time is |
| 107 | + * incremented (grib2/tables/2/4.11.table) ] |
| 108 | + * 49 indicatorOfUnitForTimeRange = 1 [Hour (grib2/tables/2/4.4.table) ] |
| 109 | + * 50-53 lengthOfTimeRange = 0 |
| 110 | + * 54 indicatorOfUnitForTimeIncrement = 255 [Missing (grib2/tables/2/4.4.table) ] |
| 111 | + * 55-58 timeIncrement = 0 |
| 112 | + */ |
| 113 | + private Grib2Record quirky; |
| 114 | + |
| 115 | + /* |
| 116 | + * ====================== SECTION_4 ( length=58, padding=0 ) ====================== |
| 117 | + * 1-4 section4Length = 58 |
| 118 | + * 5 numberOfSection = 4 |
| 119 | + * 6-7 NV = 0 |
| 120 | + * 8-9 productDefinitionTemplateNumber = 8 [Average, accumulation, extreme values or other statistically processed |
| 121 | + * values at a horizontal level or in a horizontal layer in a continuous or non-continuous time interval |
| 122 | + * (grib2/tables/2/4.0.table) ] |
| 123 | + * 10 parameterCategory = 1 [Moisture (grib2/tables/2/4.1.0.table) ] |
| 124 | + * 11 parameterNumber = 8 [Total precipitation (kg m-2) (grib2/tables/2/4.2.0.1.table) ] |
| 125 | + * 12 typeOfGeneratingProcess = 2 [Forecast (grib2/tables/2/4.3.table) ] |
| 126 | + * 13 backgroundProcess = 0 |
| 127 | + * 14 generatingProcessIdentifier = 105 |
| 128 | + * 15-16 hoursAfterDataCutoff = 0 |
| 129 | + * 17 minutesAfterDataCutoff = 0 |
| 130 | + * 18 indicatorOfUnitOfTimeRange = 1 [Hour (grib2/tables/2/4.4.table) ] |
| 131 | + * 19-22 forecastTime = 0 |
| 132 | + * 23 typeOfFirstFixedSurface = 1 [Ground or water surface (grib2/tables/2/4.5.table , |
| 133 | + * grib2/tables/local/kwbc/1/4.5.table) ] |
| 134 | + * 24 scaleFactorOfFirstFixedSurface = 0 |
| 135 | + * 25-28 scaledValueOfFirstFixedSurface = 0 |
| 136 | + * 29 typeOfSecondFixedSurface = 255 [Missing (grib2/tables/2/4.5.table , grib2/tables/local/kwbc/1/4.5.table) ] |
| 137 | + * 30 scaleFactorOfSecondFixedSurface = 0 |
| 138 | + * 31-34 scaledValueOfSecondFixedSurface = 0 |
| 139 | + * 35-36 yearOfEndOfOverallTimeInterval = 2017 |
| 140 | + * 37 monthOfEndOfOverallTimeInterval = 7 |
| 141 | + * 38 dayOfEndOfOverallTimeInterval = 20 |
| 142 | + * 39 hourOfEndOfOverallTimeInterval = 0 |
| 143 | + * 40 minuteOfEndOfOverallTimeInterval = 0 |
| 144 | + * 41 secondOfEndOfOverallTimeInterval = 0 |
| 145 | + * 42 numberOfTimeRange = 1 |
| 146 | + * 43-46 numberOfMissingInStatisticalProcess = 0 |
| 147 | + * 47 typeOfStatisticalProcessing = 1 [Accumulation (grib2/tables/2/4.10.table) ] |
| 148 | + * 48 typeOfTimeIncrement = 2 [Successive times processed have same start time of forecast, forecast time is |
| 149 | + * incremented (grib2/tables/2/4.11.table) ] |
| 150 | + * 49 indicatorOfUnitForTimeRange = 1 [Hour (grib2/tables/2/4.4.table) ] |
| 151 | + * 50-53 lengthOfTimeRange = 0 |
| 152 | + * 54 indicatorOfUnitForTimeIncrement = 255 [Missing (grib2/tables/2/4.4.table) ] |
| 153 | + * 55-58 timeIncrement = 0 |
| 154 | + */ |
| 155 | + private Grib2Record normal; |
| 156 | +} |
| 157 | + |
| 158 | +/* |
| 159 | + * # steps to reproduce test data |
| 160 | + * |
| 161 | + * baseurl='www.ncei.noaa.gov/oa/prod-model/rapid-refresh/access/historical/analysis' |
| 162 | + * curl -O "https://${baseurl}/201707/20170720/rap_130_20170720_0000_000.grb2" |
| 163 | + * |
| 164 | + * codes_split_file -1 rap_130_20170720_0000_000.grb2 |
| 165 | + * |
| 166 | + * # quirky |
| 167 | + * grib_dump -O -p section_4 \ |
| 168 | + * -w section4Length=58,numberOfTimeRange=0 \ |
| 169 | + * rap_130_20170720_0000_000.grb2_199 |
| 170 | + * |
| 171 | + * # normal |
| 172 | + * grib_dump -O -p section_4 \ |
| 173 | + * -w section4Length=58,numberOfTimeRange=1 \ |
| 174 | + * rap_130_20170720_0000_000.grb2_212 |
| 175 | + * |
| 176 | + * cat \ |
| 177 | + * rap_130_20170720_0000_000.grb2_199 \ |
| 178 | + * rap_130_20170720_0000_000.grb2_212 \ |
| 179 | + * >example_pds_8_quirks.grib2 |
| 180 | + * |
| 181 | + * # index |
| 182 | + * java -jar netcdfAll-5.10.0-SNAPSHOT.jar \ |
| 183 | + * example_pds_8_quirks.grib2 |
| 184 | + * |
| 185 | + * # generates example_pds_8_quirks.grib2.gbx9 |
| 186 | + */ |
0 commit comments