Невозможно прочитать набор данных HDF4 с помощью pyhdf (pyhdf.error.HDF4Error: выберите: несуществующий набор данных)

Я пытаюсь прочитать файл HDF4 (https://www.dropbox.com/s/5d40ukfsu0yupwl/MOD13A2.A2016001.h23v05.006.2016029070140.hdf?dl=0).

import os
import numpy as np
from pyhdf.SD import SD, SDC

# Open file.
FILE_NAME = 'MOD13A2.A2016001.h23v05.006.2016029070140.hdf'
hdf = SD(FILE_NAME, SDC.READ)

# List available SDS datasets.
print (hdf.datasets())

# Read dataset.
DATAFIELD_NAME="1_km_16_days_NDVI"
data2D = hdf.select(DATAFIELD_NAME)
data = data2D[:,:] 

Когда я выполнил этот скрипт, я получаю следующую ошибку: Traceback (последний последний вызов): файл «Test.py», строка 15, в data2D = hdf.select(DATAFIELD_NAME) файл «C:\Python35\lib\site- пакеты\pyhdf\SD.py", строка 1599, в select поднять HDF4Error("выбрать: несуществующий набор данных") pyhdf.error.HDF4Error: выбрать: несуществующий набор данных

Я использовал аналогичный код Python для чтения других файлов HDF4, и он работает хорошо. Но я не могу понять проблему в этом случае.


person Yogesh Sathe    schedule 05.04.2018    source источник


Ответы (1)


Если вы внимательно посмотрите на вывод print(hdf.datasets()), вы заметите следующую строку:

 ...
 '1 km 16 days NDVI': (('YDim:MODIS_Grid_16DAY_1km_VI',
                        'XDim:MODIS_Grid_16DAY_1km_VI'),
                       (1200, 1200),
                       22,
                       0),
 ...

Ключ — это имя набора данных. Обратите внимание, что в имени используются пробелы для разделения слов, а не символы подчеркивания, как в вашем примере.

Если заменить DATAFIELD_NAME на DATAFIELD_NAME='1 km 16 days NDVI'. То есть замените подчеркивания на пробелы в имени набора данных, ваш код будет работать без ошибки.

Этого достаточно для доступа к данным внутри тайла, но геолокация требует дополнительной работы. На данный момент вы уже можете визуализировать данные с помощью

from matplotlib import pyplot as plt
plt.imshow(data)
plt.colorbar()
plt.show()

введите здесь описание изображения

Что еще предстоит сделать, так это

  • масштабирование до научных единиц
  • геолокация

Кроме того, используйте модуль pprint для вывода больших словарей со сложной структурой, т.е. замените print(hdf.datasets()) на

import pprint
...
pprint.pprint(hdf.datasets())
person Dmitri Chubarov    schedule 06.04.2018
comment
Спасибо за ответ. Теперь он работает нормально. Я столкнулся с другой проблемой с этим набором данных. Я не могу извлечь поля геолокации (т.е. Широта/Долгота) из этого файла. Когда я открыл файл HDF в программном обеспечении Panoply, он показывает массивы XDim и YDim, но программное обеспечение pprint output или HDFView не показывает эти массивы. Не могли бы вы помочь мне в этом? - person Yogesh Sathe; 06.04.2018
comment
Файлы данных плитки @YogeshSathe HDF-EOS не содержат массивов геолокации. Поскольку данные расположены на регулярной сетке (в синусоидальной проекции MODIS), вы можете восстановить геолокацию каждого пикселя по координатам углов тайла, которые можно прочитать из атрибутов CoreMetadata.0 и StructMetadata.0. Проверьте вывод из print(getattr(hdf,'CoreMetadata.0')) и print(getattr(hdf,'StructMetadata.0')). - person Dmitri Chubarov; 06.04.2018
comment
Еще раз спасибо за ваш ответ. Я попробовал способ, предложенный вами, но я не могу извлечь геолокацию. Не могли бы вы привести пример/ссылку извлечения геолокации для каждого пикселя в python - person Yogesh Sathe; 06.04.2018
comment
После поиска в вашем направлении я получил этот пример, который читает широту и долготу также для указанного файла [ссылка] (hdfeos.org/zoo/LPDAAC/MOD13A1_500m_16_days_EVI.py) - person Yogesh Sathe; 06.04.2018
comment
@YogeshSathe этот пример использует внешние инструменты, GDAL или eos2dump. ИМХО, жаль, что разработка pyhdf остановилась на том, чтобы полностью выполнять вычисления на Python. - person Dmitri Chubarov; 06.04.2018
comment
Привет.... Я написал код Python для извлечения данных широты/долготы и NDVI из HDF-файла синусоидальной проекции MODIS с использованием GDAL и PYPROJ. - person Yogesh Sathe; 01.06.2018