gpt4 book ai didi

c++ - 读取具有复合数据类型的 HDF5 数据集,其中包含多个具有可变数量的 float 和整数的集合

转载 作者:行者123 更新时间:2023-11-30 03:44:26 43 4
gpt4 key购买 nike

我正在尝试使用 C++ 中的 H5Cpp 库读取具有复合数据类型的 HDF5 数据集。 HDF5 文件是由模拟器创建的,所以不幸的是我无法控制结构。每个单元格包含多组可变长度 float 和一组可变长度整数。 h5dump 显示的头部结构为:

DATASET "SET_NAME" {
DATATYPE H5T_COMPOUND {
H5T_VLEN { H5T_IEEE_F64LE} "dProp1";
H5T_VLEN { H5T_IEEE_F64LE} "dProp2";
H5T_VLEN { H5T_STD_I32LE} "iProp1";
H5T_VLEN { H5T_IEEE_F64LE} "dProp3";
}
DATASPACE SIMPLE { ( 5, 122 ) / ( H5S_UNLIMITED, H5S_UNLIMITED ) }
}

我试图创建一个包含 VarLenTypeCompType,但是在运行时抛出异常,指出一个成员与另一个成员重叠(这就是我当任何地方给出的唯一大小是包含指针的结构的大小时会期望)。这是我到目前为止的摘录:

#include <H5Cpp.h>
typedef struct mytype_t {
double* dprop1;
double* dprop2;
int* iprop1;
double* dprop3;
} mytype_t;

H5::CompType ctype(sizeof(mytype_t));
auto double_type = H5::PredType::NATIVE_DOUBLE;
auto int_type = H5::PredType::NATIVE_INT;
auto vdouble_type = H5::VarLenType(&double_type);
auto vint_type = H5::VarLenType(&int_type);
ctype.insertMember("dProp1", HOFFSET(mytype_t, dprop1), vdouble_type);
ctype.insertMember("dProp2", HOFFSET(mytype_t, dprop2), vdouble_type);
ctype.insertMember("vProp1", HOFFSET(mytype_t, iprop1), vint_type);
ctype.insertMember("dProp3", HOFFSET(mytype_t, dprop3), vdouble_type);

std::vector<mytype_t> data_vector;
data_vector.resize(dims[0]*dims[1]);
dataset.read(data_vector.data(), ctype);

如何读取这样的数据集?

最佳答案

HDF5 文档和示例在这个问题上非常薄弱。

HDF5 要求用户保留可变长度数据的句柄(hvl_t 类型),并在您将数组作为成员插入复合类型时引用该句柄。

这引入了使这些句柄和您的 vector 、数组等与句柄保持同步的开销。也就是说,如果您保留动态数组,每当您更改元素数量时,您都需要更新 "len" 字段,并且无论何时重新分配数组,您都需要设置 “p” 字段到新数组的第一个元素。

这也适用于 std::vectors,请记住,无论何时您都需要不断更新 plen在 vector 中添加/删除元素。在 https://github.com/dguest/hdf5-ntuples/blob/master/include/h5container.hh 有一段很好的代码可以做到这一点由 dguest 提供。

您的案例的解决方案(简化):

#include <H5Cpp.h>
typedef struct mytype_t {
double* dProp;
hvl_t dPropHandle;
int* iProp;
hvl_t iPropHandle;
} mytype_t;

H5::CompType ctype(sizeof(mytype_t));
auto double_type = H5::PredType::NATIVE_DOUBLE;
auto int_type = H5::PredType::NATIVE_INT;
auto vdouble_type = H5::VarLenType(&double_type);
auto vint_type = H5::VarLenType(&int_type);

// use handles instead of array pointers
ctype.insertMember("dProp", HOFFSET(mytype_t, dPropHandle), vdouble_type);
ctype.insertMember("iProp", HOFFSET(mytype_t, iPropHandle), vint_type);

std::vector<mytype_t> data_vector;
data_vector.resize(dims[0]*dims[1]);
dataset.read(data_vector.data(), ctype);

// update array pointers accordingly
for(mytype_t &m : data_vector)
{
m.dProp = dPropHandle.p;
m.iProp = iPropHandle.p;
}

使用 vector :

#include <H5Cpp.h>
typedef struct mytype_t {
std::vector<double> dProp;
hvl_t dPropHandle;
std::vector<int> iProp;
hvl_t iPropHandle;
} mytype_t;

H5::CompType ctype(sizeof(mytype_t));
auto double_type = H5::PredType::NATIVE_DOUBLE;
auto int_type = H5::PredType::NATIVE_INT;
auto vdouble_type = H5::VarLenType(&double_type);
auto vint_type = H5::VarLenType(&int_type);

// use handles instead of array pointers
ctype.insertMember("dProp", HOFFSET(mytype_t, dPropHandle), vdouble_type);
ctype.insertMember("iProp", HOFFSET(mytype_t, iPropHandle), vint_type);

std::vector<mytype_t> data_vector;
data_vector.resize(dims[0]*dims[1]);
dataset.read(data_vector.data(), ctype);

// update vectors accordingly
for(mytype_t &m : data_vector)
{
m.dProp.assign(static_cast<double*>(m.dPropHandle.p),
static_cast<double*>(m.dPropHandle.p) + m.dPropHandle.len);

m.iProp.assign(static_cast<int*>(m.iPropHandle.p),
static_cast<int*>(m.iPropHandle.p) + m.iPropHandle.len);
}

关于c++ - 读取具有复合数据类型的 HDF5 数据集,其中包含多个具有可变数量的 float 和整数的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35477590/

43 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com