如何使用GO语言读取HDF5属性,该属性可能是两种不同数据类型之一?

时间:2019-02-21 15:07:52

标签: c++ go hdf5

作为评估项目的一部分,我正在将现有的C ++应用程序移植到GO。在此过程中,我需要读取两个数据集属性,在某些文件中该属性存储为double值,在某些文件中为float值。我用来处理此问题的C ++代码如下所示(在Debian Linux上使用的是libhdf5-cpp-100)。

const auto att = dataSet.openAttribute(attributeName);
if (att.getDataType() == H5::PredType::NATIVE_DOUBLE) {
    att.read(att.getDataType(), &attributeValue);
}
else if (att.getDataType() == H5::PredType::NATIVE_FLOAT) {
    float temp = 0.F;
    att.read(att.getDataType(), &temp);
    attributeValue = static_cast<double>(temp);
}
else {
    // we throw an exception indicating we don't support the type
}

我的问题是我在用GO编写等效代码时遇到了麻烦。 (我正在使用“ gonum.org/v1/hdf5”包。)read方法似乎很简单:

func (s *Attribute) Read(data interface{}, dtype *Datatype) error

但是我正在努力确定作为数据类型传递的内容,因为属性类型似乎没有GetDataType方法。我看到的最接近的是以下内容:

func (s *Attribute) GetType() Identifier

但是这不会返回数据类型,而是返回一个标识符。我在给定标识符可以确定数据类型的假设下尝试了以下比较:

if attr.GetType().ID() == hdf5.T_NATIVE_DOUBLE.ID() {
    // handle as a double
}

但这不起作用。从GetType()返回的ID与double或float的ID不同。

我已经浏览过https://godoc.org/gonum.org/v1/hdf5上的在线文档,但是无法找到解决我问题的方法。 (或使用GO读取HDF5属性的任何示例。)

有人能做这样的事情吗?还是大多数示例只是假设类型而不是查询类型?

1 个答案:

答案 0 :(得分:0)

我已经证实了自己的怀疑,现在有一个正确的答案。根本的问题是,我在使用C ++ API时出现错误(在某些情况下,这只会导致写入两倍的double值),而我实际上是在尝试在GO中重复该错误。实际上,解决方案非常简单。

传递到属性myAdapter.setHasStableIds(true); 方法中的属性类型不是属性的类型,而是存储在内存中时要转换为的类型。这意味着我的C ++代码应该简单得多,因为不需要检查属性类型,也不需要将其read生成结果。要读取和存储属性值,只需依赖HDF5进行转换,并在属性不可转换为双精度的情况下抛出适当的异常就很简单

static_cast

GO版本的工作量更大,因为我们必须手动管理对象生命周期和错误条件,但实际情况是这样。 (请注意,我假设“ ...处理错误...”还涉及提前退出,否则需要额外的if语句来检查att是否为nil。)

const auto att = dataSet.openAttribute("my attribute name");
att.read(H5::PredType::NATIVE_DOUBLE, &attributeValue);