Вилучення значень на конкретній широті, довготі з даних прокосів 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.