How to create an array attribute?

I have some C++ that reads an attribute from a dataset like this:

  hsize_t szN[1] = {3};
  hid_t   long3_id = H5Tarray_create(H5T_NATIVE_LONG, 1, szN);
  long   val[3];

  auto const attrH = H5Aopen_by_name(handle_, dset.c_str(), attr.c_str(), H5P_DEFAULT, H5P_DEFAULT);
  H5Aread(attrH, long3_id, val);

I want to write this attribute using h5py, but I cannot figure out how. If I simply do:

dset.attrs['attribute'] = [3, 3, 3]

for example, then the attribute is created as integers with a dataspace of [3]. I think I need it to be an array datatype with dataspace [1]. I have also tried:

traj.attrs.create('attribute', [3, 3, 3], dtype=h5py.h5t.array_create(h5py.h5t.NATIVE_INT64, (3,)))

but this results in:

ValueError: Changing the dtype to a subarray type is only supported if the total itemsize is unchanged

I can’t find any examples using h5t.array_create(). Any pointers much appreciated!

Did you try with numpy:

import h5py
import numpy as np
with h5py.File('test.h5', mode='w') as h5f:
     h5f.attrs.create(name='attribute', data=np.array([3,3,3], dtype='i8'))
>>> h5dump test.h5 
HDF5 "test.h5" {
GROUP "/" {
   ATTRIBUTE "attribute" {
      DATATYPE  H5T_STD_I64LE
      DATASPACE  SIMPLE { ( 3 ) / ( 3 ) }
      DATA {
      (0): 3, 3, 3
      }
   }
}
}

Using a Numpy array is half the solution. A friend worked out that we need to do:

traj.attrs.create('attribute', np.array([3, 3, 3]), dtype=h5py.h5t.array_create(h5py.h5t.NATIVE_INT64, (3,)))

Which results in:

      ATTRIBUTE "matrix" {
         DATATYPE  H5T_ARRAY { [3] H5T_STD_I64LE }
         DATASPACE  SCALAR
         DATA {
         (0): [ 96, 96, 3 ]
         }
      }

which is the right datatype.

1 Like