【问题标题】:Writing a 3D array to HDF5将 3D 数组写入 HDF5
【发布时间】:2017-09-16 00:09:03
【问题描述】:

我正在尝试将 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 容器中。这必须可以使用 hyperslabs,但我不确定如何

编辑 2

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

编辑 3

联系了 HDF 小组,发现在当前实施中无法进行维度转换。必须在写入数据集之前完成。

【问题讨论】:

  • data 是如何声明的?每个元素的预期原始类型是什么?
  • 类型实际上是模板化的。 data 被声明为向量,但是,在此方法的上下文中,const T*
  • 由于数据是模板化的,你如何定义type?我们还能看到数据样本及其“混乱”形式吗?
  • 我发布的方法是类私有的,具有一堆重载(每种数据类型一个),这些重载转发给提供 HDF 类型的此方法。由于索引更改,数据混乱。请查看我的编辑。
  • 对不起,我的意思是我还不明白数据在数据集中(错误地)的组织方式。假设 3D 数据集中的每个位置都为 T 类型的一个实例腾出空间,那么很难理解为什么索引是一个问题。一个具体的例子会很有帮助。

标签: c++ hdf5


【解决方案1】:

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

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

【讨论】:

  • 那也没用。事实上,它给出了(看似)相同的答案。我添加了一张图片,显示正在发生的事情和预期的事情。我忘记了你可以用不同的方式指定内存空间,我真的认为这会奏效。
  • 我尝试进一步更改 mem_space 以测试会发生什么。我使用什么作为mem_space似乎并不重要,输出是一样的,甚至const hsize_t mem_dim[3] = { layers * rows * cols, 1, 1 };
  • 这确实很有趣。 HDFView 应该允许您在将数据集作为图像打开时分配每个图像尺寸。您是否尝试过所有可能的组合?我们离解开这个“谜”还差得远。 :)
  • 我已经尝试了很多。我想我需要对 file_space 进行 hyperslab,因为它的配置与内存空间不同。我一直在尝试,但没有运气。文档不明确,没有这样的 3D 示例。
猜你喜欢
  • 2016-03-22
  • 2022-01-14
  • 1970-01-01
  • 2012-03-04
  • 1970-01-01
  • 2023-03-31
  • 2017-06-10
  • 2016-01-26
  • 2020-07-31
相关资源
最近更新 更多