Как мне прочитать атрибут HDF5, который может быть одним из двух разных типов данных, используя язык GO? - PullRequest
0 голосов
/ 21 февраля 2019

Я портирую существующее приложение C ++ на GO как часть оценочного проекта.В рамках этого мне нужно прочитать два атрибута набора данных, которые в некоторых файлах хранятся как двойные, а в некоторых - как плавающие.Код C ++, который я использую для этого, выглядит следующим образом (мы используем libhdf5-cpp-100 в Debian Linux).

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".) Метод чтения кажется достаточно простым:

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 (), не совпадает с идентификатором для double или float.

Я просматривал онлайн-документы по адресу https://godoc.org/gonum.org/v1/hdf5, но не смог найти решение для моегопроблема.(Или любой пример чтения атрибутов HDF5 с помощью GO.)

Кому-нибудь удалось сделать что-то подобное?Или большинство примеров просто предполагают тип, а не запрашивают его?

1 Ответ

0 голосов
/ 22 февраля 2019

Я подтвердил свои подозрения и теперь имею правильный ответ.Основная проблема заключается в том, что в моем использовании API C ++ произошла ошибка (которая в некоторых случаях привела бы только к записи 1/2 двойного), и я по сути пытался повторить эту ошибку в GO.На самом деле, решение очень простое.

Тип атрибута, который передается в метод атрибута read, это не тип атрибута, это тип, в который вы хотите преобразовать его при сохранении вобъем памяти.Это означает, что мой код на C ++ должен быть намного проще, так как нет необходимости проверять тип атрибута или static_cast его результат.Чтобы прочитать и сохранить значение атрибута, полагаясь на HDF5, чтобы выполнить преобразование, и для подходящего исключения, которое будет выдано, если атрибут не может быть преобразован в двойное, просто, как

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

Версия GO:больше работы, так как мы должны управлять жизненным циклом объекта и условиями ошибки вручную, но это так.(Обратите внимание, что я предполагаю, что «... обработать ошибку ...» также предполагает ранний выход, в противном случае требуется дополнительный оператор if, чтобы проверить, что att не равен nil.)

att, err := dataSet.OpenAttribute("my attribute name")
if err != nil {
    ...handle the error...
}

err = att.Read(&attributeValue, hdf5.T_NATIVE_DOUBLE)
if err != nil {
    ...handle the error...
}

err = att.Close()
if err != nil {
    ...handle the error...
}
...