แยกค่าที่ละติจูดเฉพาะลองจิจูดจากข้อมูล MODIS swath


9

ฉันกำลังพยายามหาปริมาณของไอน้ำที่ตกตะกอน (PWV), โอโซนและละอองลอยเป็นหน้าที่ของเวลาเหนือจุดเฉพาะบนโลกนั่นคือหอสังเกตการณ์ทางดาราศาสตร์ของเรา ในการทำเช่นนี้ฉันได้รับรหัส Python แล้วmodapsclientซึ่งจะดาวน์โหลดผลิตภัณฑ์ MODIS Aqua และ Terra MYDATML2 และ MODATML2 สองครั้งต่อวันซึ่งครอบคลุมละติจูดและลองจิจูดเฉพาะที่ฉันสนใจ

สิ่งที่ฉันไม่แน่ใจเกี่ยวกับคือวิธีการดึงปริมาณเฉพาะที่ฉันต้องการเช่นเวลาที่ใช้ข้อมูล MODIS และ PWV สำหรับตำแหน่งละติจูดและลองจิจูดเฉพาะของหอดูดาวของฉันเพื่อทำให้เป็นค่าอนุกรมเวลา ผลิตภัณฑ์ MYDATML2 ดูเหมือนจะมี 2D ละติจูดและลองจิจูดกริดของCell_Along_Swath_5kmและCell_Across_Swath_5kmดังนั้นฉันเดานี้ทำให้แนวข้อมูลเมื่อเทียบกับข้อมูลตารางกระเบื้องหรือ? ปริมาณที่ฉันต้องการเช่นนั้นPrecipitable_Water_Infrared_ClearSkyดูเหมือนว่าจะขัดกับCell_Along_Swath_5kmและCell_Across_Swath_5kmฉันไม่แน่ใจว่าจะรับค่า PWV ที่ lat ที่เฉพาะเจาะจงได้นานแค่ไหนที่ฉันสนใจโปรดช่วยด้วย?


คุณช่วยระบุลิงก์ไปยังภาพหรือตัวอย่างของมันได้หรือไม่?
Andrea Massetti

แน่นอนว่านี่คือไฟล์ตัวอย่างในไฟล์เก็บถาวร MODIS: ladsweb.modaps.eosdis.nasa.gov/archive/allData/61/MODATML2/2018/ …
astrosnapper

สวัสดีคุณได้รับโอกาสลองตอบคำถามหรือไม่?
Andrea Massetti

1
ขออภัยฉันออกไปจากการประชุมที่นำเสนองานโดยใช้การคำนวณ PWV ที่คล้ายกันจากข้อมูล sat ... รหัสที่อัปเดตของคุณให้ค่าเดียวกับที่ฉันเห็นใน PanoplyJ สำหรับเซลล์เดียวกัน (คำนึงถึงลำดับดัชนีอาร์เรย์ที่แตกต่างกันและ ความแตกต่าง 'off by 1' ในดัชนีอาร์เรย์เริ่มต้น)
astrosnapper

คำตอบ:


1

[แก้ไข 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'

ตอนนี้เราสามารถโหลดตัวแปรในการเรียกหน่วยความจำอีกครั้ง. Open () วิธีการ:

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

ตัวอย่างเช่นคุณสามารถเข้าถึง Precipitable_Water_Infrared_ClearSky ที่คุณสนใจโดยระบุ 'SUBDATASET_20_NAME' เพียงแค่ดูพจนานุกรม datasets_meta

อย่างไรก็ตามตัวแปรที่แยกออกมานั้นไม่มี geoproject (var.GetGeoproject ()) ตามที่คุณคาดหวังจากไฟล์ประเภทอื่นเช่น GeoTiff คุณสามารถโหลดตัวแปรเป็นอาร์เรย์ numpy และพล็อตตัวแปร 2d โดยไม่ต้องฉายภาพ:

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

ตอนนี้เนื่องจากไม่มี geoproject เราจะพิจารณาข้อมูลเมตาของตัวแปร:

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

ฉันคิดว่านี่หมายความว่าตามพิกเซล 1km เหล่านี้ 5km ถูกสร้างขึ้นโดยใช้ค่าพิกเซลที่ตำแหน่งใดตำแหน่งหนึ่งในอาร์เรย์การตรวจจับ 5x5 (ตำแหน่งที่ระบุไว้ในเมตาดาต้าฉันคิดว่านี่เป็นเครื่องมือสำหรับลดความผิดพลาด)

อย่างไรก็ตาม ณ จุดนี้เรามีเซลล์จำนวนหนึ่ง 1x1 กม. (ดูคำอธิบายของการสุ่มตัวอย่างด้านบนไม่แน่ใจเกี่ยวกับวิทยาศาสตร์ที่อยู่เบื้องหลัง) ในการรับค่าพิกัดของแต่ละเซ็นทรอยด์ของพิกเซลเราต้องโหลดชุดย่อยละติจูดและลองจิจูด

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 ฉันจะอัปเดตส่วนที่สอง
Andrea Massetti

@astrosnapper ตอนนี้คำตอบควรตอบคำถามของคุณอย่างสมบูรณ์
Andrea Massetti
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.