2014-08-29 125 views
1

更新:看过一个h5dump后,事实证明这是一种复合数据格式。我错了使用python创建该死的文件,我想!从h5dump将HDF5中的数据加载到C++中的矢量中

SNIPPIT:

DATASET "dset1" { 
       DATATYPE H5T_COMPOUND { 
        16-bit little-endian floating-point "value"; 

我有一大堆的HDF5文件,我可以读取和Matlab中写的,但现在我想用C++。下面的例子后,我仍然无法破解它。

我不认为我正确理解或执行内存类型,由我在运行时得到的错误来判断。你如何知道使用哪种内存类型?

下面是我的代码和我在运行时得到的错误。它在dset.read行失败。 (我在这里试过各种实现/内存类型)。

在Windows 64位机器上由HDFView报告的数据集属性是32位浮点数。代码运行在Mint 17 64bit上。

使用编译:

g++ importH5.cpp -o importH5 -std=c++11 -lhdf5_cpp -lhdf5 

ImportH5.cpp:

#include <iostream> 
#include <string> 
#include <vector> 
#include <H5Cpp.h> 

using namespace std; 
using namespace H5; 

int main() 
{ 
    string ifn = "test.h5"; 
    string datasetPath = "/grp1/grp2/grp3/dset1"; 

    // Open HDF5 file handle, read only 
    H5File fp(ifn.c_str(),H5F_ACC_RDONLY); 

    // access the required dataset by path name 
    DataSet dset = fp.openDataSet(datasetPath.c_str()); 

    // get the dataspace 
    DataSpace dspace = dset.getSpace(); 

    // get the dataset type class 
    H5T_class_t type_class = dset.getTypeClass(); 
    // According to HDFView, this is a 32-bit floating-point 

    // get the size of the dataset 
    hsize_t rank; 
    hsize_t dims[2]; 
    rank = dspace.getSimpleExtentDims(dims, NULL); // rank = 1 
    cout<<"Datasize: "<<dims[0]<<endl; // this is the correct number of values 

    // Define the memory dataspace 
    hsize_t dimsm[1]; 
    dimsm[0] = dims[0]; 
    DataSpace memspace (1,dimsm); 


    // create a vector the same size as the dataset 
    vector<float> data; 
    data.resize(dims[0]); 
    cout<<"Vectsize: "<<data.size()<<endl; 


    float data_out[65341]; 
    for (int i=0;i<65341;i++) 
    { 
     data_out[i]=0; 
    } 
    // pass pointer to the array (or vector) to read function, along with the data type and space. 
    dset.read(data_out, PredType::NATIVE_FLOAT, memspace, dspace); // FAILS 
    dset.read(data_out, PredType::NATIVE_FLOAT, dspace);   // FAILS 
    dset.read(data.data(), PredType::NATIVE_FLOAT, memspace, dspace); // FAILS 


    // close the HDF5 file 
    fp.close(); 



return 0; 
} 

和错误:

Datasize: 65341 
Vectsize: 65341 
HDF5-DIAG: Error detected in HDF5 (1.8.11) thread 139863993304960: 
    #000: ../../../src/H5Dio.c line 182 in H5Dread(): can't read data 
    major: Dataset 
    minor: Read failed 
    #001: ../../../src/H5Dio.c line 438 in H5D__read(): unable to set up type info 
    major: Dataset 
    minor: Unable to initialize object 
    #002: ../../../src/H5Dio.c line 939 in H5D__typeinfo_init(): unable to convert between src and dest datatype 
    major: Dataset 
    minor: Feature is unsupported 
    #003: ../../../src/H5T.c line 4525 in H5T_path_find(): no appropriate function for conversion path 
    major: Datatype 
    minor: Unable to initialize object 
terminate called after throwing an instance of 'H5::DataSetIException' 
Aborted 

而这里的HDF5文件的链接,如果是使用: https://dl.dropboxusercontent.com/u/63051/test.h5

+0

你打电话后'排名= dspace.getSimpleExtentDims(dims,NULL);','rank'的值是什么? – 2014-08-29 12:47:15

+0

使用cout <<等级我得到1的值(我会更新问题来澄清这一点) – zotty 2014-08-29 12:49:44

回答

1

是的,你的问题是使用python来创建它。正如你已经提到的那样,它已经把它变成了一个复合的数据类型。

你几乎在那里...

首先你需要创建一个结构来保存数据。可以称之为pyf(缺乏想象力的我 - python float)。

struct pyf { 
     float x; 
}; 

然后,您需要将您的data_out更改为此类型。

struct pyf data_out[65341]; 
for (int i=0;i<65341;i++) 
{ 
    data_out[i].x=0; 
} 

最后,你需要创建一个HDF5复合型,并告诉它你从文件中想要什么成员:

CompType mtype(sizeof(struct pyf)); 
mtype.insertMember("value", HOFFSET(struct pyf, x), PredType::NATIVE_FLOAT); 
dset.read(data_out, mtype); 

最后进行仔细的检查:

for (int i=0;i<65341;i++) 
{ 
    cout<<data_out[i].x << " "; 
    cout << endl; 
} 
+0

作品一种享受!我想我会用另一种方法(C或C++)来重新创建HDF5,以避免这种情况发生 - 没有任何理由为将来的头痛留下复杂的遗迹! – zotty 2014-08-29 15:07:01

相关问题