编写H5T_ARRAY类型的数据集

时间:2014-06-13 16:02:20

标签: c++ hdf5

我正在尝试使用C ++ API在HDF5中写入数据。 我使用Visual Studio 2010处理Windows XP 64位。我使用的是1.8.9版本。 目标设置为X86所以我不得不使用32位版本的HDF(说实话,我对Windows和VS编程很新,并没有自己配置整个事情,所以我真的不确定这是正确的选择)。

尝试编写H5T_ARRAY类型的数据集的一部分时,会出现问题。

我想要实现的HDF5文件结构是4维(i1,i2,i3,i4)的数据集,其数据类型为:具有2维的双精度数组(a1,a2)。 这是DDL的总结:

HDF5 "result.h5" {
GROUP "/" {
 DATASET "mydata" {
    DATATYPE  H5T_ARRAY { [a1][a2] H5T_IEEE_F64LE }
    DATASPACE  SIMPLE { ( i1,i2,i3,i4) / ( i1,i2,i3,i4 ) }
    DATA { <my data> }
 }
}

由于我的程序结构,我逐个元素地写这个数据集,即H5T_ARRAY由H5T_ARRAY。

我已经定义了一个类OutputFile来管理所有HDF5 I / O.它包含以下属性:

H5::H5File *_H5fileHandle ;     // HDF5 file
H5::DataSpace *_dataspaceHandle ;   // Handle of the Dataspace of the datasets
int _dataspaceRank ;        // Rank of the dataspace
H5::ArrayType *_datatypeHandle ;    // Handle of the datatype of the datasets (= array of N dimensions)
int _datatypeRank ;             // Rank of the datatype
H5::DataSet *_datasetHandle ;   // Handle of the dataset

文件在程序开头就打开了,然后设置了所有句柄(数据空间,数据类型和数据集):

void OutputFile ::createFile(std::string filename, 
            std::vector<int> dsdims, 
            std::vector<int> adims, 
            std::vector<std::string> datasetName) {

    _filename = filename ;
    _H5fileHandle = new H5::H5File(_filename.c_str(), H5F_ACC_TRUNC);

    // Defining the dataspace 
    _dataspaceRank = dsdims.size() ; 
    hsize_t *h5dsdims = new hsize_t[_dataspaceRank] ; 
    for (int iDim=0 ; iDim < _dataspaceRank ; iDim++) h5dsdims[iDim] = hsize_t(dsdims[iDim]) ;
    _dataspaceHandle = new H5::DataSpace(_dataspaceRank, h5dsdims, NULL); 

    // Defining the datatype = array type
    _datatypeRank = adims.size() ; 
    hsize_t *h5adims = new hsize_t[_datatypeRank] ; 
    for (int iDim=0 ; iDim < _datatypeRank ; iDim++) h5adims[iDim] = hsize_t(adims[iDim]) ;
    _datatypeHandle = new H5::ArrayType(H5::PredType::IEEE_F64LE, _datatypeRank, h5adims);

   // Creating the dataset
    _datasetHandle = _H5fileHandle->createDataSet( _datasetName.c_str(),*_datatypeHandle, *_dataspaceHandle );

    // Clean up
    delete h5dsdims ;
    delete h5adims ;
}

然后,每次我准备一个元素(即H5T_ARRAY)时,我都会写入数据:

void OutputFile::writeMyData(double **Values, int *positionInDataSet) {

    // set the element position
    hsize_t position[1][4] ; 
    position[0][0] = hsize_t(positionInDataset[0]);
    position[0][1] = hsize_t(positionInDataset[1]);
    position[0][2] = hsize_t(positionInDataset[2]);
    position[0][3] = hsize_t(positionInDataset[3]);
    _fileDataspace->selectElements( H5S_SELECT_SET, 1, (const hsize_t *)position);

    //Set the memory dataspace
    hsize_t memdims[] = {1} ; 
    H5::DataSpace memspace(1, memdims, NULL); 

    // set the memory datatype 
    hsize_t memTypeRank = 2 ;
    hsize_t *memTypedims = new hsize_t[memTypeRank] ; 
    for (int iDim=0 ; iDim < memTypeRank ; iDim++) memTypedims[iDim] = hsize_t(dataDims[iDim]) ;
    H5::ArrayType memtypeHandle(H5::PredType::IEEE_F64LE, memTypeRank, memTypedims);

    _datasetHandle->write(Values, memtypeHandle, memspace, *_dataspaceHandle);
    _H5fileHandle->flush(H5F_SCOPE_GLOBAL) ; 
}   

Values参数在调用函数中分配,大小为[a1] [a2]。

不幸的是,它无法正常工作。我在HDF5文件中获得了无效数据,并且所有元素都相等(意味着所有H5T_ARRAY都包含相同的值)。 例如:

(0,0,0,0): [ 5.08271e-275, 5.08517e-275, -7.84591e+298, -2.53017e-098, 0, 2.18992e-303,
        5.08094e-275, 0, 2.122e-314, -7.84591e+298, 5.08301e-275, 5.08652e-275,
        -7.84591e+298, -2.53017e-098, 0, 2.18994e-303, 5.08116e-275, 0,
        2.122e-314, -7.84591e+298, 5.08332e-275, 5.08683e-275, -7.84591e+298, -2.53017e-098,
        0, 2.18995e-303, 5.08138e-275, 0, 2.122e-314, -7.84591e+298 ], 

......等等每个元素。

现在,我有:

  • 检查writeMyData()中“Value”数组的内容是否正确并包含有效数据
  • 检查过,如果我只写一个元素,那么这个元素,只有这个元素,包含HDF5文件中的无效数据(其他只包含零)
  • 使用了这些其他类型组合,但没有成功:
    • memType = NATIVE_DOUBLE,fileType = IEEE_64LE
    • memType = NATIVE_DOUBLE,fileType = NATIVE_DOUBLE
    • memType = IEEE_32LE,fileType = IEEE_32_LE
  • 使用类型IEEE_F64LE
  • 检查是否正确写入了双值属性
  • 尝试在writeMyData()结束时关闭文件,并在开头打开它,强制在磁盘上写入数据。结果是一样的。
  • 在DataSet :: write()的调用中传递了&amp; Values而不是Values(结果是相同的)。

我有点在我的智慧结束。我找到了数据集的部分I / 0和数组数据类型的其他示例,但是没有用于部分写入数组类型数据集的示例。 我想这是一个内存问题,我的感觉是我在将“Values”数组传递给DataSet :: write()时出错了,但我无法查明问题。

提前感谢您提供的任何指示。

0 个答案:

没有答案