MODISスワスデータから特定の緯度、経度の値を抽出する


9

私は、地球上の特定の場所、つまり天文台での時間の関数として、可降水量(PWV)、オゾン、およびエアロゾルの量を測定しようとしています。これを行うために、私がmodapsclient興味のある特定の緯度と経度をカバーする1日2回のMODIS AquaおよびTerra MYDATML2およびMODATML2製品をダウンロードするPythonコードをすでに使用しています。

よくわからないのは、MODISデータが取得された時間や、天文台の特定の緯度と経度の位置のPWVなど、必要な特定の量を抽出して時系列の値にする方法です。MYDATML2製品は、の2次元緯度と経度のグリッドを含んでいるように見えるCell_Along_Swath_5kmCell_Across_Swath_5km私は推測するので、これは作るの帯タイルまたはグリッドデータとは対照的に、データを?私のような希望の数量Precipitable_Water_Infrared_ClearSkyもが反対であるように見えるCell_Along_Swath_5kmCell_Across_Swath_5km長い間、私は。ヘルプにしてください興味を持って、butI'mがないことを確認する方法LAT特定の時とPWV値を取得するには?


画像またはそのサンプルへのリンクを提供していただけますか?
Andrea

:確かに、ここでのMODISのアーカイブ内のファイルの例ですladsweb.modaps.eosdis.nasa.gov/archive/allData/61/MODATML2/2018/...
astrosnapper

こんにちは、私の答えを試す機会がありましたか?
Andrea

1
申し訳ありませんが、satデータからの同様のPWV決定に基づく作業を発表する会議に出席していません...更新されたコードは、同じセルに対してPanoplyJで表示されるのと同じ値を提供します(異なる配列インデックスの順序と配列インデックスの「1
ずつ

回答:


1

[編集1-ピクセル座標検索を変更しました]

提供したMODATMLのこのサンプルを使用し、gdalライブラリーを使用します。gdalでhdfを開きましょう:

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'

これで、変数をメモリにロードして、再度.Open()メソッドを呼び出すことができます。

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

たとえば、「SUBDATASET_20_NAME」を指定すると、興味のあるPrecipitable_Water_Infrared_ClearSkyにアクセスできます。datasets_meta辞書をご覧ください。

ただし、抽出された変数には、GeoTiffなどの他のファイルタイプから予想されるようなジオプロジェクション(var.GetGeoprojection())がありません。変数を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 kmピクセルに基づいて、5 x 5センシングアレイの特定の位置のピクセル値を正確に取得して5 kmが構築されたことを意味します(位置はメタデータに示されています。これは、障害を減らすための手段だと思います)。

とにかく、この時点で1x1 kmのセルの配列があります(上記のサブサンプリングの説明を参照してください。その背後にある科学については不明です)。各ピクセルの重心の座標を取得するには、緯度と経度のサブデータセットを読み込む必要があります。

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マイル数であり、それをkmに再近似するのではなく)
astrosnapper

緯度と経度は、66と67のサブデータセットとして提供されます。2番目の部分を更新します。
Andrea Massetti、

@astrosnapperが答えを完全にあなたの質問に対処する必要があります。
Andrea
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.