How to create multi-value attribute in a HDF5 file using C++ API

馋奶兔 提交于 2019-12-31 05:35:14

问题


EDIT STARTS

I'm trying to create an "pair, triplet or n-uplet" attribute based on a native type (float, int...) :

  • pair of float, triplet of float, n-uplet of floats attribute
  • pair of int, triplet of int, n-uplet of int attribute

I'm not trying to create an "Array" attribute, I'm not trying to create a "Compound" attribute

EDIT END

I'm trying to create an attribute based on a native type (float, int...) but which contains 2,3 or more values (equivalent to a pair or a n-uplet).

I don't want to create an array ! I want to create something very similar to an array, but not the same

I can create single value attribute this way (for a "double" attribute) :

H5::DataSpace dataSpace = H5::DataSpace();
H5::Attribute attribute = group.createAttribute(attributeName, H5::PredType::IEEE_F64LE, dataSpace);
attribute.write(H5::PredType::IEEE_F64LE, &attributeValue);

To create a couple of "double", I've tried this :

hsize_t dimension;
dimension = 2;
H5::ArrayType dataType(H5::PredType::IEEE_F64LE, 1, &dimension);

H5::DataSpace dataSpace = H5::DataSpace();
H5::Attribute attribute = group.createAttribute(attributeName, dataType, dataSpace);

double attributeValue[2];
attributeValue[0] = x;
attributeValue[1] = y;

attribute.write(dataType, attributeValue);

But it creates an array type attribute in the HDF5 file.

I know it's possible to create an attribute whcih contains multiple values because I can do it using the HDFView GUI software (the first one is created using the above code, the second line is an attribute created using the GUI - I want to create this kind of attribute) :

Any help will be appreciated !


回答1:


Without exactly knowing what you are trying to accomplish, I believe what you are looking for is a self-defined datatype using the HDF5 compound datatype H5::CompType, which is usually used to save simple structs. Taken from the HDF5 C++ compound example page, the struct

  typedef struct s1_t {
    int    a;
    float  b;
    double c;
  } s1_t;

has the associated compound datatype:

  CompType mtype1( sizeof(s1_t) );
  mtype1.insertMember( MEMBER1, HOFFSET(s1_t, a), PredType::NATIVE_INT);
  mtype1.insertMember( MEMBER3, HOFFSET(s1_t, c), PredType::NATIVE_DOUBLE);
  mtype1.insertMember( MEMBER2, HOFFSET(s1_t, b), PredType::NATIVE_FLOAT);

Compound datatyped are then treated the same way as native datatypes and may also be saved as attributes.

Edit

The error you made in your code above was to define your datatype to be saved as an H5::ArrayType when you didn't actually want to save an Array. What you really want is a simple datatype (such as PredType::NATIVE_DOUBLE) saved in a higher dimensional dataspace.

#include "H5Cpp.h"

#ifndef H5_NO_NAMESPACE
  using namespace H5;
#ifndef H5_NO_STD
  using std::cout;
  using std::endl;
#endif  // H5_NO_STD
#endif  
const H5std_string FILE_NAME("save.h5");
const H5std_string ATT_NAME("Attribute");

int main(){
  const hsize_t dims=5;
  int ndims=1;

  DataType dtype=PredType::NATIVE_DOUBLE;

  H5File h5file(FILE_NAME, H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT);

  DataSpace* dspace = new DataSpace(ndims,&dims);
  Attribute att=h5file.createAttribute(ATT_NAME,dtype,*dspace);
  delete dspace;

  double attvalue[dims];
  for(auto i=0;i<dims;++i) attvalue[i]=i;

  att.write(dtype,attvalue);
  h5file.close();

  return 0;
} 

This should reproduce the "createdUsingHDFVIEW" attribute above (except for the datatype). I can't check to make sure as I dont have HDFView. This didn't occur to me at first as I tend to think of H5::DataSpace as a type of array (which it actually is).



来源:https://stackoverflow.com/questions/35580279/how-to-create-multi-value-attribute-in-a-hdf5-file-using-c-api

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!