C++ 将3D阵列写入HDF5

C++ 将3D阵列写入HDF5,c++,hdf5,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,

我正在尝试将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数据作为Y,X,Z存储在HDF5容器中。这必须是可能的使用Hyperslab,但我不确定如何

编辑2

由于数据具有结构,我可以在HDFView中以图像的形式查看数据。以下内容有助于说明问题:

编辑3

联系了HDF小组,发现在当前实施中无法移动尺寸。必须在写入数据集之前完成此操作


由于指定了不正确的内存数据空间,数据集中的元素未按预期顺序排列

第4节中的演示了HDF5如何在两个总体大小相同的数据空间之间读取数据,但将维度从文件交换到内存。实际上,函数声明如下:

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 )
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));
第三个参数是指内存数据空间,在我们的例子中,它与文件的(以前定义为
(行、列、层)
)不同。 它应该定义为
(层、行、列)
。指南中的同一页说明HDF5遵循与C中相同的阵列存储约定:

数据空间维度从1到秩进行编号。HDF5使用C存储约定,假设最后列出的维度是变化最快的维度,而第一个列出的维度是变化最慢的维度。在文件中存储数据空间维度时,HDF5文件格式存储布局规范遵循C约定,HDF5库遵循相同约定

更正后的代码应如下所示:

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 )
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));

数据如何声明?每个元素的预期基元类型是什么?该类型实际上是模板化的<代码>数据
被声明为向量,但是,在该方法的上下文中,当数据被模板化时,如何定义
类型
?我们还可以看到数据及其“混乱”形式的示例吗?我发布的方法对于类是私有的,带有一堆重载(每个数据类型一个重载),这些重载转发给提供HDF类型的方法。由于索引更改,数据混乱。请看我的编辑。对不起,我的意思是,我还不明白数据集中的数据组织方式(错误)。假设3D数据集中的每个位置都为类型为
T
的一个实例腾出空间,很难理解为什么索引是一个问题。一个具体的例子会很有帮助,但这也不起作用。事实上,它给出了(似乎)相同的答案。我添加了一张图片,显示正在发生的事情和预期的结果。我忘了你可以用不同的方式指定内存空间,我真的认为这是可行的。我试着进一步改变内存空间来测试会发生什么。我使用什么作为mem_空间似乎并不重要,输出是相同的,甚至
const-hsize_t mem_dim[3]={layers*rows*cols,1,1}这确实很有趣。HDFView应允许您在将数据集作为图像打开时分配每个图像维度。你试过所有可能的组合了吗?我们离解开这个“谜”不远了:)我试过好几次了。我想我需要对文件_空间进行超实验室测试,因为它的配置与内存空间不同。我一直在努力,但运气不好。文档不明确,没有类似的3D示例。