javascalagrib

Accessing GRIB data using GRIB2Tools causes IndexOutOfBoundException


I'm manipulating GRIB2 forecast files and I'm having trouble using the GRIB2Tools library.

I have an Array[Byte] representing the content of a GRIB2 dataset. Because I want to be able to get value at specific location, I wrote this variable's content to a file which I'm then loading as an InputStream to use it with the getValueAtLocation(id, lat, long) and/or interpolateValueAtLocation(id, lat, long). I can perfectly read the metadata of the file, but as soon as I call one of those 2 previous methods, I get an IndexOutOfBoundException.

Here is the Scala code I use to write the GRIB2 bytes array (variable bytes) on a file and then load it as an InputStream:

val file: File = new File("my-data.grib")
val temp = FileUtils.writeByteArrayToFile(file, bytes)
val input = new FileInputStream("my-data.grib")
val grib: RandomAccessGribFile = new RandomAccessGribFile("my-grib", "my-data.grib")      
grib.importFromStream(input, 0)

According to the README.md I am doing it right, isn't it?

Then I can easily get those metadata from the GRIB2 (using some code of the GRIB2FileTest.java):

Body format : GRIB2
Date: 12.10.2021
Time: 9:0.0
Generating centre: 85
Forecast time: 5
Parameter category: 0
Parameter number: 0
Covered area:
   from (latitude, longitude): 51.47, 348.0
   to: (latitude, longitude): 37.5, 16.0

When calling getValueAtLocation(id, lat, long) and interpolateValueAtLocation(id, lat, long) with id = 0 and lat = 48 and long = 2 (which seems to be ok when reading the metadata) I got this :

java.lang.IndexOutOfBoundsException
    at java.nio.Buffer.checkIndex(Buffer.java:551)
    at java.nio.HeapByteBuffer.getShort(HeapByteBuffer.java:327)
    at com.ph.grib2tools.grib2file.RandomAccessGribFile.interpolateValueAt(RandomAccessGribFile.java:196)
    at com.ph.grib2tools.grib2file.RandomAccessGribFile.interpolateValueAtLocation(RandomAccessGribFile.java:133)

The faulting line seems to be this one in this file RandomAccessGribFile.java:196 :

float val11 = sec5.calcValue(ByteBuffer.wrap(data).getShort((jidx1*gridDefinition.numberPointsLon+iidx1)*bytesperval));

Am I doing something wrong or is there an issue with the library source code or my GRIB file? The file comes from a national forecast agency and should be ok. I give you the structure of the GRIB2 file in the screenshot attached (from the Panoply software).

image


Solution

  • After some research with the dev of the Grib2Tools library, it turns out that the issue was coming from my GRIB file. The national forecast organization of my country, Météo France, add a bitmap on top of the data to indicate whether or not there's a value available at given coordinates. This feature wasn't supported by Grib2Tools, wich lead to data misunderstanding and errors at execution. This bitmap feature will be supported soon thanks to the dev.