将3D阵列写入HDF5

时间:2017-04-19 16:25:37

标签: c++ hdf5

我正在尝试将3D数据集写入HDF5文件。写入成功并且文件中的尺寸都是正确的,但是,当使用HDFView工具时,数据混乱,但具有可识别的结构,所以我必须接近。我无法弄清楚我错过了什么,也找不到编写3D数据的好例子。

数据是连续的一块内存索引:data[layer][row][col]data[layer*rows*cols + row*cols + col]

以下是我正在使用的代码,其中HDF5_CHECK是一个在出错时抛出异常的宏。

const hsize_t dim[] = { rows, cols, layers };
hid_t space = H5Screate_simple(3, dim, NULL);

hid_t dataset = H5Dcreate(file, "dataset", type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
HDF5_CHECK(dataset);
HDF5_CHECK(H5Dwrite(dataset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, data));

HDF5_CHECK(H5Sclose(space));
HDF5_CHECK(H5Dclose(dataset));

修改

我认为这个问题与索引有关。 C ++中的数组是正确的。但是,我相信我想将Z,Y,X数据存储为HDF5容器中的Y,X,Z。这必须是使用hyperslabs可能的,但我不确定如何

编辑2

由于数据具有结构,我可以在HDFView中将数据视为图像。以下内容应该有助于说明问题:

编辑3

与HDF小组联系并发现在当前的实施中不可能改变尺寸。必须在写入数据集之前完成。

Expected vs Actual results

1 个答案:

答案 0 :(得分:0)

数据集中的元素不符合预期的顺序,因为指定了不正确的内存数据空间。

第4节中的user guide显示了HDF5如何在相同总大小的两个数据空间之间读取,但是从文件到内存的交换尺寸。在实践中,H5Dwrite函数声明如下:

herr_t H5Dwrite(hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_plist_id, const void * buf )

第三个参数是指内存数据空间,在我们的例子中,它与文件(以前定义为(row, col, layer))不同。 它应该被定义为(layer, row, col)。指南中的同一页面阐明了HDF5遵循与C中相同的阵列存储约定:

  

数据空间维度从1到排名编号。 HDF5使用C存储约定,假设最后列出的维度是变化最快的维度,并且首先列出的维度是最慢的维度。 HDF5文件格式存储布局规范遵循C约定,当在文件中存储数据空间维度时,HDF5库遵循相同的约定。

更正的代码应该是这样的:

const hsize_t dim[] = { rows, cols, layers };
hid_t space = H5Screate_simple(3, dim, NULL);

hid_t dataset = H5Dcreate(file, "dataset", type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

HDF5_CHECK(dataset);

const hsize_t mem_dim[] = { layers, rows, cols };
hid_t mem_space = H5Screate_simple(3, dim, NULL);
HDF5_CHECK(H5Dwrite(dataset, type, mem_space, H5S_ALL, H5P_DEFAULT, data));