Вилучення значень на конкретній широті, довготі з даних прокосів MODIS


9

Я намагаюся визначити кількість осаджуваної водної пари (PWV), озону та аерозолів як функцію часу над конкретними плямами на Землі, а саме нашими астрономічними обсерваторіями. Для цього я вже отримав деякий код Python, за допомогою modapsclientякого завантажуватимуться два рази на день продукти MODIS Aqua і Terra MYDATML2 та MODATML2, які охоплюють конкретну широту та довготу, що мене цікавить.

Я не впевнений у тому, як отримати конкретні великі кількості, які я хочу, наприклад, час взяття даних MODIS та PWV для конкретного положення широти та довготи моєї обсерваторії, щоб перетворити їх у часовий ряд значень. У MYDATML2 продуктах , здається, містять 2D широти і довготи сіток Cell_Along_Swath_5kmі Cell_Across_Swath_5kmтому я припускаю , що це робить його SWATH дані , на відміну від плитки або сіток даних? Мені потрібні такі кількості, як, Precipitable_Water_Infrared_ClearSkyздається, і проти, Cell_Along_Swath_5kmале Cell_Across_Swath_5kmя не впевнений, як отримати це значення PWV на конкретному латі, довго мене цікавить. Допоможіть, будь ласка?


Чи можете ви надати посилання на зображення чи його зразок?
Андреа Массетті

Звичайно, ось приклад файлу в архіві MODIS: ladsweb.modaps.eosdis.nasa.gov/archive/allData/61/MODATML2/2018/…
astrosnapper

Привіт, ти отримала можливість спробувати мою відповідь?
Андреа Массетті

1
Вибачте, я не був на конференції, де було представлено роботу, засновану на подібних визначеннях PWV із даних даних ... Ваш оновлений код дає мені ті самі значення, що я бачу в PanoplyJ для тієї ж комірки (з урахуванням різного порядку індексу масиву та різниця "від 1" у індексі масиву починається)
astrosnapper

Відповіді:


1

[EDIT 1 - я змінив пошук координат пікселів]

Використовуючи цей зразок MODATML, який ви надали, та використовуючи бібліотеку gdal. Відкриємо hdf з gdal:

import gdal
dataset = gdal.Open(r"E:\modis\MODATML2.A2018182.0800.061.2018182195418.hdf")

Потім ми хочемо переглянути, як називаються піддані, щоб правильно імпортувати потрібні:

datasets_meta = dataset.GetMetadata("SUBDATASETS")

Це повертає словник:

datasets_meta
>>>{'SUBDATASET_1_NAME': 'HDF4_EOS:EOS_SWATH:"E:\\modis\\MODATML2.A2018182.0800.061.2018182195418.hdf":atml2:Cloud_Optical_Thickness', 
'SUBDATASET_1_DESC': '[406x271] Cloud_Optical_Thickness atml2 (16-bit integer)',
'SUBDATASET_2_NAME':'HDF4_EOS:EOS_SWATH:"E:\\modis\\MODATML2.A2018182.0800.061.2018182195418.hdf":atml2:Cloud_Effective_Radius',
'SUBDATASET_2_DESC': '[406x271] Cloud_Effective_Radius atml2 (16-bit integer)',
[....]}

Скажімо, ми хочемо отримати першу змінну, оптичну товщину хмари, ми можемо отримати доступ до її назви:

datasets_meta['SUBDATASET_1_NAME']
>>>'HDF4_EOS:EOS_SWATH:"E:\\modis\\MODATML2.A2018182.0800.061.2018182195418.hdf":atml2:Cloud_Optical_Thickness'

Тепер ми можемо знову завантажити змінну у виклик пам'яті .Открити () метод:

Cloud_opt_th = gdal.Open(datasets_meta['SUBDATASET_1_NAME'])

Наприклад, ви можете отримати доступ до Precipitable_Water_Infrared_ClearSky, який вас цікавить, надавши "SUBDATASET_20_NAME". Просто погляньте на словник даних_sets_meta.

Однак видобута змінна не має геопроекції (var.GetGeoprojection ()), як можна було б очікувати від інших типів файлів, таких як GeoTiff. Ви можете завантажити змінну у масиві numpy та побудувати графік 2d без проекції:

Cloud_opt_th_array = Cloud_opt_th.ReadAsArray()
import matplotlib.pyplot as plt
plt.imshow(Cloud_opt_th_array)

Тепер, оскільки немає геопроекції, ми розглянемо метадані змінної:

Cloud_opt_th_meta = Cloud_opt_th.GetMetadata()

Це ще один словник, який включає всю необхідну інформацію, включаючи довгий опис підсистеми (я помітив, що це надається лише з першим підданим), що включає пояснення цих Cell_Along_Swath:

Cloud_opt_th_meta['1_km_to_5_km_subsampling_description']
>>>'Each value in this dataset does not represent an average of properties over a 5 x 5 km grid box, but rather a single sample from within each 5 km box. Normally, pixels in across-track rows 4 and 9 (counting in the direction of increasing scan number) out of every set of 10 rows are used for subsampling the 1 km retrievals to a 5 km resolution. If the array contents are determined to be all fill values after selecting the default pixel subset (e.g., from failed detectors), a different pair of pixel rows is used to perform the subsampling. Note that 5 km data sets are centered on rows 3 and 8; the default sampling choice of 4 and 9 is for better data quality and avoidance of dead detectors on Aqua. The row pair used for the 1 km sample is always given by the first number and last digit of the second number of the attribute Cell_Along_Swath_Sampling. The attribute Cell_Across_Swath_Sampling indicates that columns 3 and 8 are used, as they always are, for across-track sampling. Again these values are to be interpreted counting in the direction of the scan, from 1 through 10 inclusively. For example, if the value of attribute Cell_Along_Swath_Sampling is 3, 2028, 5, then the third and eighth pixel rows were used for subsampling. A value of 4, 2029, 5 indicates that the default fourth and ninth rows pair was used.'

Я думаю, це означає, що на основі цих пікселів 1 км було побудовано 5 км, приймаючи точно значення пікселів у певному положенні в сенсорному масиві 5x5 (позиція вказана у метаданих, я думаю, що це інструмент для зменшення помилок).

Як би там не було, ми маємо масив комірок 1х1 км (див. Опис піддиагностики вище, не впевнений у науці, що стоїть за ним). Щоб отримати координати кожного піксельного центроїда, нам потрібно завантажити піддані широти та довготи.

Latitude = gdal.Open(datasets_meta['SUBDATASET_66_NAME']).ReadAsArray()
Longitude = gdal.Open(datasets_meta['SUBDATASET_67_NAME']).ReadAsArray()

Наприклад,

Longitude
>>> array([[-133.92064, -134.1386 , -134.3485 , ..., -154.79303, -154.9963 ,
    -155.20723],
   [-133.9295 , -134.14743, -134.3573 , ..., -154.8107 , -155.01431,
    -155.2256 ],
   [-133.93665, -134.1547 , -134.36465, ..., -154.81773, -155.02109,
    -155.23212],
   ...,
   [-136.54477, -136.80055, -137.04684, ..., -160.59378, -160.82101,
    -161.05663],
   [-136.54944, -136.80536, -137.05179, ..., -160.59897, -160.8257 ,
    -161.06076],
   [-136.55438, -136.81052, -137.05714, ..., -160.6279 , -160.85527,
    -161.09099]], dtype=float32)        

Ви можете помітити, що координати широти та довготи відрізняються для кожного пікселя.

Скажімо, ваша обсерваторія розташована за координатами lat_obs, long_obs, ніж ви мінімізуєте різницю координат x, y:

coordinates = np.unravel_index((np.abs(Latitude - lat_obs) + np.abs(Longitude - long_obs)).argmin(), Latitude.shape)

і витягувати свою цінність

Cloud_opt_th_array[coordinates]

Дякую за інформацію, але у мене виникають проблеми з частиною перетворення координат; Longitude_pxі Latitude_pxобидва нульової довжини масивів. Чи є спосіб обробити конверсію, використовуючи gdalсам? (. , А не покладатися на наближення 1 -й ступеня є X немає миль , а потім знову аппроксимирующих , що км)
astrosnapper

Широта та Довгота подані у вигляді підданих, а саме 66 та 67. Я оновлю другу частину.
Андреа Массетті

@astrosnapper тепер відповідь має повністю відповісти на ваше запитання.
Андреа Массетті
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.