Java 无法读取NetCDF结构变量数组子范围

Java 无法读取NetCDF结构变量数组子范围,java,hdf5,netcdf,Java,Hdf5,Netcdf,我有一个从HDF5文件中检索的NCDF结构,我正在尝试使用Java NetCDF 4.3.16库读取数组变量的子范围。我发现变量如下: Variable netCDFVariable = netCDFFile.findVariable("/group/struct.var"); 此时,如果需要,我可以读取整个变量: netCDFArray = netCDFVariable.read(); 但假设变量是长度为10的整数数组,我只想读取索引3、4、5、6和7的子范围: Section secti

我有一个从HDF5文件中检索的NCDF结构,我正在尝试使用Java NetCDF 4.3.16库读取数组变量的子范围。我发现变量如下:

Variable netCDFVariable = netCDFFile.findVariable("/group/struct.var");
此时,如果需要,我可以读取整个变量:

netCDFArray = netCDFVariable.read();
但假设变量是长度为10的整数数组,我只想读取索引3、4、5、6和7的子范围:

Section section=new Section(new int[]{3}, new int[]{5});
netCDFArray = netCDFVariable.read(section);
但是这里的
Variable.read(Section)
抛出一个
InvalidRangeException
。通过跟踪代码,变量检查自己的内部
形状
变量,该变量恰好是
[]
,并发现该变量无效


那么为什么变量没有合适的
形状
?我必须先读取变量才能得到正确的形状吗?(这当然不能满足一开始就试图读取子范围的目的。)

从NetCDF 4.3.17开始,
Variable.read()
Variable.read(Section)
的实现在读取结构数组的成员时有很大的不同,两者都不遵循API文档。下面我将介绍一种解决方法

为了举例说明,假设我有以下内容:

Structure {
  int foo;
    :_Unsigned = "true";
  int bar;
    :_Unsigned = "true";
} example(24);
这是一个名为结构的
example
的24元素数组,每个结构包含两个成员,
foo
bar
。假设我得到了对
foo
成员的引用,如下所示:

final Variable fooVariable = netcdfFile.findVariable("/blah/example.foo");
如果我调用
fooVariable.read()
,API文档会说我将返回第一个值,因为
foo
是数组中元素结构的一部分。事实并非如此;相反,库实际上进行了一些巧妙的读取,并将所有结构中的
foo
成员作为
foo
值的单个数组返回。这是我想要的行为

不幸的是,
fooavariable.read(Section)
实现没有与
fooavariable.read()
相同的智能代码位,而是编写为抛出一个
不支持操作异常。(由于缺少一个附加的检查,代码甚至没有走那么远,抛出了一个
InvalidRangeException
,因为它认为给定的
无效。这是一个遗憾,因为(一旦添加了一个检查以避免
InvalidRangeException
)变量中的聪明代码。read()
实现对于
变量同样有效。读取(部分)
只需在一行上插入一个方法参数

使用
Variable.read()中的智能代码
我创建了一个解决此问题的方法,允许调用者请求包含任何变量的数组部分。如果该变量是数组中某个结构的成员,则只读取该成员的子范围,从而有效地创建了另一个版本的
fooavariable.read(section)
方法,该方法与结构成员的
fooVariable.read()具有相同的行为:

  /**
   * Reads an array of data from the provided NetCDF variable. If the variable is a member of a structure, that member is read
   * from all the structures in the array and returned as a single array containing that member from each structure.
   * @param variable The NetCDF variable to read.
   * @param section The section indicating the element of the array to read
   * @param indexEnd The ending source index, exclusive, or -1 if all available values should be read.
   * @return An array representing the requested range of values read for the given variable.
   * @throws IOException if there is an error reading the data.
   */
  public static Array readArray(final Variable variable, final Section section) throws IOException, InvalidRangeException {
    if (variable.isMemberOfStructure()) { //if the variable is member of a structure
      final Structure parentStructure = variable.getParentStructure().select(variable.getShortName()); //select just the member variable
      final ArrayStructure arrayStructure = (ArrayStructure) parentStructure.read(section); //read the array of structures
      return arrayStructure.extractMemberArray(arrayStructure.findMember(variable.getShortName())); //extract just the member into an array
    } else { //if the variable is not a member of a structure
      return variable.read(section); //just read the section directly from the variable
    }
  }
我用报告了这个问题(现在识别为NRW-974703)。起初,我被告知这些方法不适用于HDF5,只适用于Unidata自己的NetCDF文件格式。(这完全不正确。)然后我被告知我不理解Java NetCDF API(虽然从前面的回答中我问了一个问题,到底是谁缺乏对Unidata库的了解)。在追踪具体问题代码并提供上述解决方法后,我还没有收到Unidata的回复