如何在C++中读取 HDF5 对象引用

How do I read an HDF5 object reference in C++

本文关键字:读取 HDF5 对象引用 C++      更新时间:2023-10-16

我想使用具有对象引用数组的C++读取HDF5文件。我可以在 python 中获得正确的结果,但我在C++遇到了麻烦。

我尝试了教程文档中的一些 C 示例,但看起来缺少C++包装器,并且很难填补空白。

H5File file = H5File("example.h5", H5F_ACC_RDONLY);  
DataSet dataset = file.openDataSet("units/electrode_group");  
H5T_class_t type_class = dataset.getTypeClass();  
cout << type_class << endl; // correctly obtains H5T_REFERENCE.    
// Need to read and apply the references next.

下面的python代码可以完成我想要的一切,但我需要一个c ++版本。

import h5py               
FileName = 'example.h5'    
myHDF5file = h5py.File(FileName)  
ElectrodeGroup = myHDF5file['units/electrode_group']  
for electrodeRef in ElectrodeGroup:  
print(myHDF5file[electrodeRef].name) 

python代码正确打印:

/general/extracellular_ephys/shank1  
/general/extracellular_ephys/shank1  
/general/extracellular_ephys/shank2   
/general/extracellular_ephys/shank3

尽管 OP 使用 C API 使其工作,但如果您(像我一样)通过 Google 来到这里并想要一个C++ API 答案:

HDF5 C++ API 文档很糟糕。 我煞费苦心地将 C API 文档与我在 C++ API 标头中搜索并h5dump告诉我的有关我拥有的具有区域引用的.h5的内容进行了交叉关联。 最终我发现有两个重要的方法:

H5::
  • H5位置::d ereference()
  • H5::
  • H5位置::getRegion()

诀窍在于,由于H5Location是一个抽象类,因此您必须在具体派生类的实例上调用它们。 在这个问题的情况下,人们只需要dereference()一个,它用引用指向的东西填充H5Location对象(有点不直观,恕我直言,但这就是它的作用)。 在这种情况下,我们知道 ref 指向的东西是一个DataSet,所以我们只是直接做一个DataSet并调用它的dereference()参数。 (如果引用是指向数据集中记录的子集,则可以使用getRegion()方法获取指向所选元素的DataSpace

因为数据集包含一组引用,所以我认为您可以执行以下操作:


// create holder for the references when they're read
// references are of type `hdset_reg_ref_t`
std::vector<hdset_reg_ref_t> refs(dataset.getSpace().getSimpleExtentNdims());
// read them out of the dataset.  
// `H5::PredType::STD_REF_DSETREG` is the H5 internal type for region references
dataset.read(refs.data(), H5::PredType::STD_REF_DSETREG);
for (const auto & ref : refs)
{
// we know these are dataset region refs,
// so we create DataSet objects directly
H5::DataSet ds_ref;
// make the dataset point to the right object using the reference
ds_ref.dereference(file, ref, H5R_DATASET_REGION);  
std::cout << ds_ref.getObjName() << "n";
// if you wanted to use the corresponding DataSpace
// (say, your region ref was to a subset of records),
// you'd grab it by doing:
// H5::DataSpace dspc_ref = file.getRegion(ref);
}