Trích xuất các giá trị ở vĩ độ, kinh độ cụ thể từ dữ liệu swath MODIS


9

Tôi đang cố gắng xác định lượng hơi nước kết tủa (PWV), ozone và aerosol là một hàm của thời gian trên các điểm cụ thể trên Trái đất, cụ thể là các đài quan sát thiên văn của chúng ta. Để làm điều này, tôi đã có một số mã Python sử dụng modapsclientđể tải xuống hai sản phẩm MODIS Aqua và Terra MYDATML2 và MODATML2 hai lần mỗi ngày, bao gồm vĩ độ và kinh độ cụ thể mà tôi quan tâm.

Điều tôi không chắc chắn là làm thế nào để trích xuất số lượng cụ thể mà tôi muốn, chẳng hạn như thời gian dữ liệu MODIS được lấy và PWV cho vị trí vĩ độ và kinh độ cụ thể của đài quan sát của tôi để biến chúng thành một chuỗi giá trị thời gian. Các sản phẩm MYDATML2 dường như chứa 2D vĩ độ và kinh độ lưới của Cell_Along_Swath_5kmCell_Across_Swath_5kmvì vậy tôi đoán này làm cho nó rộng quét dữ liệu như trái ngược với gạch hoặc lưới dữ liệu? Số lượng tôi muốn như Precipitable_Water_Infrared_ClearSkydường như cũng chống lại Cell_Along_Swath_5kmCell_Across_Swath_5kmnhưng tôi không chắc làm thế nào để có được giá trị PWV đó vào một thời gian cụ thể, lâu nay tôi quan tâm. Xin vui lòng giúp đỡ?


Bạn có thể vui lòng cung cấp một liên kết đến hình ảnh hoặc một mẫu của nó?
Andrea Massetti

Chắc chắn, đây là một tệp ví dụ trong kho lưu trữ MODIS: ladsweb.modaps.eosdis.nasa.gov/archive/allData/61/MODATML2/2018/ trộm
astrosnapper

Xin chào, bạn đã có cơ hội để thử câu trả lời của tôi?
Andrea Massetti

1
Xin lỗi, tôi đã đi dự hội thảo trình bày dựa trên các xác định PWV tương tự từ dữ liệu sat ... Mã cập nhật của bạn đang cho tôi các giá trị giống như tôi thấy trong PanoplyJ cho cùng một ô (có tính đến thứ tự chỉ số mảng khác nhau và 'off by 1' sự khác biệt trong chỉ số mảng bắt đầu)
astrosnapper

Câu trả lời:


1

[EDIT 1 - Tôi đã thay đổi tìm kiếm tọa độ pixel]

Sử dụng mẫu MODATML này mà bạn đã cung cấp và sử dụng thư viện gdal. Hãy mở hdf bằng gdal:

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

Sau đó, chúng tôi muốn xem cách các tập hợp con được đặt tên để nhập chính xác những cái chúng tôi cần:

datasets_meta = dataset.GetMetadata("SUBDATASETS")

Điều này trả về một từ điển:

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)',
[....]}

Giả sử chúng ta muốn lấy biến đầu tiên, độ dày quang học đám mây, chúng ta có thể truy cập tên của nó bằng cách:

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

Bây giờ chúng ta có thể tải biến trong bộ nhớ gọi lại phương thức .Open ():

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

Ví dụ: bạn có thể truy cập Precipitable_Water_Infrared_ClearSky mà bạn quan tâm bằng cách cung cấp 'SUBDATASET_20_NAME'. Chỉ cần nhìn vào từ điển dataets_meta.

Tuy nhiên, biến được trích xuất không có tính năng geoprojection (var.GetGeoprojection ()) như bạn mong đợi từ các loại tệp khác như GeoTiff. Bạn có thể tải biến dưới dạng một mảng numpy và vẽ biến 2d mà không cần chiếu:

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

Bây giờ, vì không có địa vật lý, chúng ta sẽ xem xét siêu dữ liệu của biến:

Cloud_opt_th_meta = Cloud_opt_th.GetMetadata()

Đây là một từ điển khác Bao gồm tất cả thông tin bạn cần, bao gồm một mô tả dài về mẫu phụ (tôi nhận thấy điều này chỉ được cung cấp với tập hợp con đầu tiên), bao gồm phần giải thích về các Cell_Along_Swath này:

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.'

Tôi nghĩ điều này có nghĩa là dựa trên các pixel 1km này, 5km được xây dựng lấy chính xác các giá trị pixel ở một vị trí nhất định trong mảng cảm biến 5x5 (vị trí được chỉ định trong siêu dữ liệu, tôi nghĩ rằng đây là một công cụ để giảm lỗi).

Nhưng dù sao, tại thời điểm này, chúng ta có một loạt các ô 1x1 km (xem mô tả về mẫu phụ ở trên, không chắc chắn về khoa học đằng sau nó). Để có được tọa độ của từng pixel pixel, chúng ta cần tải các tập hợp con vĩ độ và kinh độ.

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

Ví dụ,

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)        

Bạn có thể nhận thấy rằng tọa độ Vĩ độ và Kinh độ là khác nhau đối với mỗi pixel.

Giả sử đài quan sát của bạn được đặt tại tọa độ lat_obs, long_obs, hơn là bạn giảm thiểu chênh lệch tọa độ x, y:

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

và trích xuất giá trị của bạn

Cloud_opt_th_array[coordinates]

Cảm ơn thông tin nhưng tôi gặp vấn đề với phần chuyển đổi phối hợp; các Longitude_pxLatitude_pxđều mảng zero-length. Ngoài ra có cách nào để xử lý việc chuyển đổi bằng gdalchính nó? (. chứ không phải dựa vào một xấp xỉ là 1 độ là X không dặm và sau đó lại xấp xỉ đến km)
astrosnapper

Vĩ độ và Kinh độ được cung cấp dưới dạng các tập hợp con, cụ thể là 66 và 67. Tôi sẽ cập nhật phần thứ hai.
Andrea Massetti

@astrosnapper bây giờ câu trả lời nên giải quyết hoàn toàn câu hỏi của bạn.
Andrea Massetti
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.