c++ - 从 C++ : How to read this specific format? 读取 HDF5 数据

标签 c++ hdf5

我有一个需要用 C++ 读取的 HDF5 文件,但我遇到了麻烦,因为该文件的格式似乎有点复杂...

HDF5 文件包含从两个设备保存的数据。数据是一个时间序列;它可以被视为两个数组,一个用于时间,第二个用于设备的实际输出。 采集次数是用户定义的,但两个设备的采集次数相同(因为它们的数据是同时采集的)。

例如,一个文件将包含来自比方说 10 次采集的数据,其组织方式类似于:

/Device1/Acquisition_000
/Device1/Acquisition_001
[...]
/Device2/Acquisition_000
/Device2/Acquisition_001
[...]

每次采集都将包含一个时间数组和一个数据数组。

这是 HDFView 在文件中看到的内容的屏幕截图: File opened in HDFView

虽然“路径”/Device2/Acquisition_000 是一个数据集,但我尝试这样读取它,但我遇到了麻烦。然后我使用 h5dump 转储了 .h5 文件并得到以下内容:

HDF5 "data.h5" {
GROUP "/" {
GROUP "Device1" {
    DATASET "Acquisition_000" {
        DATATYPE  H5T_COMPOUND {
            H5T_IEEE_F64BE "Time";
            H5T_IEEE_F64BE "Signal";
        }
        DATASPACE  SIMPLE { ( 270000 ) / ( 270000 ) }
        DATA {
        (0): {
            0,
            -0.0933597
            },
        (1): {
            2e-05,
            -0.0476648
            },
        (2): {
            4e-05,
            -0.0628964
            },
[...]

现在我不知道应该如何阅读该结构。我看到了 H5T_COMPOUND,所以我尝试了 http://www.hdfgroup.org/HDF5/doc/cpplus_RM/compound_8cpp-example.html 中的复合示例但是 dataset->read() 似乎无法读取数据;当 std::cout 在循环中处理数据时,valgrind 报告访问未初始化的数据。

另一个混淆来源是转储中的“H5T_IEEE_F64BE”; BE 不是 big-endian 的一部分吗?生成数据的机器和读取数据的机器都是 x86_64 ...

如何将“时间”和“信号”数组读入 C/C++ 数组?

作为引用,这是我尝试改编示例:

const H5std_string FILE_NAME("data.h5");
const H5std_string DATASET_NAME("/Device1/Acquisition_000/");
H5File file(FILE_NAME, H5F_ACC_RDONLY);
DataSet dataset = file.openDataSet(DATASET_NAME);
const H5std_string MEMBER_TIME("time_name");
const H5std_string MEMBER_SIGN("signal_name");
// Try reading a single array:
CompType mtype3( sizeof(double) );
mtype3.insertMember(MEMBER_SIGN, 0, PredType::NATIVE_DOUBLE);
double *data_signal = new double[270000];
memset(data_signal, 0, 270000);
dataset.read(data_signal, mtype3);
// Print the data
for (int i = 0 ; i < 10 ; i++)
{
    std::cout << "data_signal[i=" << i << "] = " << data_signal[i] << std::endl;
}

及其输出:

data_signal[i=0] = 0
data_signal[i=1] = 0
data_signal[i=2] = 0
data_signal[i=3] = 0
data_signal[i=4] = 0
data_signal[i=5] = 0
data_signal[i=6] = 0
data_signal[i=7] = 0
data_signal[i=8] = 0
data_signal[i=9] = 0

此外,Matlab 可以使用以下方式读取文件:

data = h5read('data.h5', '/Device1/Acquisition_000')
data = 

      Time: [270000x1 double]
    Signal: [270000x1 double]

非常感谢。

最佳答案

成员名称用于从文件中提取正确的数据字段。 “signal_name”与文件中的数据名称不匹配。尝试使用“信号”,这在 MATLAB 和 GUI 查看器中可见。

最终,您需要定义一个表示时间/信号对的 C++ 结构,如复合示例:

struct dataPoint
{
    double timePoint;
    double signal;
};

CompType hdf5DataPointType( sizeof(dataPoint) );
hdf5DataPointType.insertMember(MEMBER_TIME, 0, PredType::NATIVE_DOUBLE);
hdf5DataPointType.insertMember(MEMBER_SIGN, sizeof(double), PredType::NATIVE_DOUBLE);

然后直接读入一个dataPoint数组。

关于c++ - 从 C++ : How to read this specific format? 读取 HDF5 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18068261/

相关文章:

c++ - std::vector 比普通数组快多少?

c++ - 如何使用 C++ API 在 HDF5 文件中创建多值属性

mysql - 如何存储历史时间序列数据

python - 我可以将自己的类对象存储到 hdf5 中吗?

java - 如何从HDF5文件读取属性?

c++ - clang iostream - 找不到符号

c++ - 声明嵌套结构实例的语法

c++ - 嵌套模板(即模板 <typename T< typename templateArgumentFor_T >>)

python - 从Python调用C++ 64位共享库

python - 使用Python的Pandas包将hdf5文件中的列从int64转换为日期时间