MODIS alan verilerinden belirli enlem, boylam değerlerini çıkarma


9

Dünyadaki belirli noktalara, yani astronomik gözlemevlerimize göre zamanın bir fonksiyonu olarak çökebilir su buharı (PWV), ozon ve aerosollerin miktarını belirlemeye çalışıyorum. Bunu yapmak için, modapsclientilgilendiğim özel enlem ve boylamı kapsayan günde iki kez MODIS Aqua ve Terra MYDATML2 ve MODATML2 ürünlerini indirecek bazı Python kodlarım var.

Emin olmadığım, MODIS verilerinin alındığı zaman ve gözlemevimin belirli enlem ve boylam pozisyonu için PWV gibi onları istediğiniz zamana dönüştürmek. MYDATML2 ürünleri 2D enlem ve boylam ızgaraları içeriyor gibi görünüyor Cell_Along_Swath_5kmve Cell_Across_Swath_5kmbu yüzden bu veri döşeme veya ızgara verileri yerine swath yapar sanırım ? İstediğim miktarlar Precipitable_Water_Infrared_ClearSkyda buna karşı gibi görünüyor Cell_Along_Swath_5kmve Cell_Across_Swath_5kmama bu lateks PWV değerini nasıl elde edeceğimi bilmiyorum, uzun zamandır ilgileniyorum. Yardım lütfen?


Lütfen görüntülere bir bağlantı veya bir örnek verebilir misiniz?
Andrea Massetti


Merhaba, cevabımı denemek için bir şansın oldu mu?
Andrea Massetti

1
Maalesef, uydu verilerinden benzer PWV tespitlerine dayanan bir konferansta uzaktayım ... Güncellenmiş kodunuz bana aynı hücre için PanoplyJ'de gördüğüm değerlerin aynısını veriyor (farklı dizi indeksi sırasını ve bir dizi endeksinde 'off by 1' farkı başlar)
astrosnapper

Yanıtlar:


1

[DÜZENLEME 1 - Piksel koordinat aramasını değiştirdim]

Sağladığınız bu MODATML örneğini ve gdal kütüphanesini kullanarak. HDF'yi gdal ile açalım:

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

Ardından, ihtiyacımız olanları doğru bir şekilde içe aktarmak için alt veri kümelerinin nasıl adlandırıldığını görmek istiyoruz:

datasets_meta = dataset.GetMetadata("SUBDATASETS")

Bu bir sözlük döndürür:

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

Diyelim ki ilk değişkeni, bulut optik kalınlığını elde etmek istiyoruz, adına şu şekilde erişebiliriz:

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

Şimdi değişkeni tekrar çağırarak belleğe yükleyebiliriz.

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

Örneğin, ilgilendiğiniz Precipitable_Water_Infrared_ClearSky öğesine 'SUBDATASET_20_NAME' sağlayarak erişebilirsiniz. Datasets_meta sözlüğüne bir göz atın.

Ancak, çıkarılan değişken, GeoTiff gibi diğer dosya türlerinden beklediğiniz gibi bir coğrafi projeksiyona (var.GetGeoprojection ()) sahip değildir. Değişkeni bir numpy dizisi olarak yükleyebilir ve 2d değişkenini izdüşüm olmadan çizebilirsiniz:

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

Şimdi, coğrafi projeksiyon olmadığından, değişkenin meta verilerine bakacağız:

Cloud_opt_th_meta = Cloud_opt_th.GetMetadata()

Bu, Cell_Along_Swath'in açıklamasını içeren alt örneklemenin uzun bir açıklaması da dahil olmak üzere ihtiyacınız olan tüm bilgileri içeren başka bir sözlüktür (bunun yalnızca ilk alt veri kümesiyle sağlandığını fark ettim):

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

Bence bu 1km piksellerine dayanarak 5km, 5x5 algılama dizisinde belirli bir pozisyonda tam olarak piksel değerlerini alarak oluşturulmuştur (konum meta verilerde gösterilir, bence bu hataları azaltmak için bir araçtır).

Her neyse, bu noktada 1x1 km'lik bir hücre dizimiz var (yukarıdaki alt örneklemenin açıklamasına bakın, arkasındaki bilimden emin değilim). Her piksel sentroidinin koordinatlarını elde etmek için enlem ve boylam alt veri kümelerini yüklememiz gerekir.

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

Örneğin,

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)        

Enlem ve Boylam koordinatlarının her piksel için farklı olduğunu fark edebilirsiniz.

Gözlemcinizin x, y koordinat farkını en aza indirdiğinizden lat_obs, long_obs koordinatlarında bulunduğunu varsayalım:

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

ve değerini çıkar

Cloud_opt_th_array[coordinates]

Bilgi için teşekkürler ama koordinat dönüşüm bölümü ile ilgili sorunlar yaşıyorum; Longitude_pxve Latitude_pxher ikisi de sıfır uzunlukta diziler bulunmaktadır. Ayrıca dönüştürme kullanarak gdalkendisi işlemek için bir yolu var mı? (1 derecelik bir yaklaşıma dayanmak yerine X mil sayısı ve daha sonra
km'ye

Enlem ve Boylam alt veri kümeleri olarak, yani 66 ve 67 olarak sağlanır. İkinci bölümü güncelleyeceğim.
Andrea Massetti

@astrosnapper şimdi cevap tamamen sorunuza cevap vermelidir.
Andrea Massetti
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.