如何使用 C++ 库在 HDF5 中找出数据集的 PredType

Posted

技术标签:

【中文标题】如何使用 C++ 库在 HDF5 中找出数据集的 PredType【英文标题】:How to find out the PredType of a dataset in HDF5 using the C++ library 【发布时间】:2016-11-02 22:12:31 【问题描述】:

所以我刚刚发现,如果我将 unsigned char 数组写入我的 HDF5 文件中的 float 数据集,则库不会抱怨。因此,我想在写之前检查这两者实际上是兼容的。所以对于我的unsigned char 数组,我有相应的PredType。但如果我没记错的话,数据集并没有提供获取PredType 的明显方法。

问题:给定一个H5::Dataset,我如何获得用于初始化它的PredType

【问题讨论】:

【参考方案1】:

https://www.hdfgroup.org/HDF5/doc/cpplus_RM/readdata_8cpp-example.html 上的示例代码演示了如何执行此操作。

总结;您可以使用DataSet::getTypeClass() 函数找到存储的数据的“类”。然而,这个“类”并没有完全定义数据类型,因为它不允许您推断本机类型的大小(即 8 位、32 位......等)或符号表示(即无符号、2 的补码) .

在浮动的情况下;您还需要使用DataSet::getFloatType() 并使用FloatType::getSize() 来推断数据类型是PredType::NATIVE_FLOAT 还是PredType::NATIVE_DOUBLE,如:

auto dataClass = dataSet.getTypeClass();

if(dataClass == H5T_FLOAT)

    auto floatType = dataSet.getFloatType();

    size_t byteSize = floatType.getSize();

    if(byteSize == 4) 
    
         // use PredType::NATIVE_FLOAT to write
    
    else if(byteSize == 8)
     
         // use PredType::NATIVE_DOUBLE to write
    

对于整数的符号表示,需要使用IntType::getSign()

【讨论】:

让您想知道为什么 HDF5-Library 中不包含此功能。你的方法总是正确的吗?还是您使用了哪些假设? 我现在看不出有任何会失败的情况,如果我这样做了,我会更新帖子。 @KaanC.Fidan PredType::NATIVE_FLOATPredType::NATIVE_DOUBLE 不是 HDF5 中唯一可能的浮点类型,因此您假设它是这两者之一。例如,如果 HDF5 文件中的浮点数与 NATIVE_FLOAT/NATIVE_DOUBLE 的字节序不同(例如 PredType::IEEE_F64BEPredType::IEEE_F64LE),这将无法正常工作。【参考方案2】:

解决问题的另一种方法(即找出 HDF5 数据集的数据类型)是使用工具HDFql for C++ 如下(本示例假设文件example.h5 和数据集my_dataset 已经存在):

// include HDFql C++ header file (make sure it can be found by the C++ compiler)
#include <iostream>
#include "HDFql.hpp"

int main(int argc, char *argv[])

    int data_type;

    // get data type of dataset "my_dataset" from HDF5 file "example.h5" and populate HDFql default cursor with it
    HDFql::execute("SHOW DATA TYPE example.h5 my_dataset");

    // move HDFql default cursor to first position
    HDFql::cursorFirst();

    // retrieve data type from HDFql default cursor
    data_type = *HDFql::cursorGetInt();

    // print message according to data type
    if (data_type == HDFql::TinyInt || data_type == HDFql::VarTinyInt)
        std::cout << "Data type is a char";
    else if (data_type == HDFql::UnsignedTinyInt || data_type == HDFql::UnsignedVarTinyInt)
        std::cout << "Data type is an unsigned char";
    else if (data_type == HDFql::SmallInt || data_type == HDFql::VarSmallInt)
        std::cout << "Data type is a short";
    else if (data_type == HDFql::UnsignedSmallInt || data_type == HDFql::UnsignedVarSmallInt)
        std::cout << "Data type is an unsigned short";
    else if (data_type == HDFql::Int || data_type == HDFql::VarInt)
        std::cout << "Data type is an int";
    else if (data_type == HDFql::UnsignedInt || data_type == HDFql::UnsignedVarInt)
        std::cout << "Data type is an unsigned int";
    else if (data_type == HDFql::BigInt || data_type == HDFql::VarBigInt)
        std::cout << "Data type is a long long";
    else if (data_type == HDFql::UnsignedBigInt || data_type == HDFql::UnsignedVarBigInt)
        std::cout << "Data type is an unsigned long long";
    else if (data_type == HDFql::Float || data_type == HDFql::VarFloat)
        std::cout << "Data type is a float";
    else if (data_type == HDFql::Double || data_type == HDFql::VarDouble)
        std::cout << "Data type is a double";
    else if (data_type == HDFql::Char || data_type == HDFql::VarChar)
        std::cout << "Data type is a char";
    else if (data_type == HDFql::Opaque)
        std::cout << "Data type is an opaque";
    else if (data_type == HDFql::Enumeration)
        std::cout << "Data type is an enumeration";
    else if (data_type == HDFql::Compound)
        std::cout << "Data type is a compound";
    else
        std::cout << "Unknown data type";

    return 0;

最终,如果您需要获取数据集my_dataset 的字节序或大小,请执行HDFql::execute("SHOW ENDIANNESS example.h5 my_dataset");HDFql::execute("SHOW SIZE example.h5 my_dataset");

【讨论】:

以上是关于如何使用 C++ 库在 HDF5 中找出数据集的 PredType的主要内容,如果未能解决你的问题,请参考以下文章

C++ HDF5 使用数据集的维度作为 const int

用于创建 HDF5 数据集的 4 维 c++ 数组的动态内存分配

如何从 C++ 中的 hdf5 文件中读取数据块?

获取 HDF5 数据集的维度

C++ 代码创建空 HDF5 文件而不是数据集

在 Fortran 中读取 HDF5 数据集的子集时出现问题