ICESat-2 ATL03光子数据读取

打印 上一主题 下一主题

主题 998|帖子 998|积分 2994

ICESat-2数据处理的方式一般为将光子数据投影到沿轨隔断和高程的二维空间。如下图:

ATL03数据读取

H5是一种数据存储布局,读取原理就是按照该布局获取数据,这里给出两种读取方式。
ATL03的数据字典:ATL03 Product Data Dictionary (nsidc.org)
使用pandas
  1. import warnings
  2. import pandas as pd
  3. def read_hdf5_atl03_beam_pandas(filename, beam, verbose=False):
  4.     # 打开HDF5文件进行读取
  5.     h5_store = pd.HDFStore(filename, mode='r')
  6.     root = h5_store.root
  7.     # 为ICESat-2 ATL03变量和属性分配python字典
  8.     atl03_mds = {}
  9.     # 读取文件中每个输入光束
  10.     # beams = [k for k in file_id.keys() if bool(re.match('gt\\d[lr]', k))]
  11.     beams = ['gt1l', 'gt1r', 'gt2l', 'gt2r', 'gt3l', 'gt3r']
  12.     if beam not in beams:
  13.         print('请填入正确的光束代码')
  14.         return
  15.     atl03_mds['heights'] = {}
  16.     atl03_mds['geolocation'] = {}
  17.     # -- 获取每个HDF5变量
  18.     with warnings.catch_warnings():
  19.         warnings.simplefilter("ignore")
  20.         # -- ICESat-2 Heights Group
  21.         heights_keys = ['dist_ph_across', 'dist_ph_along', 'h_ph', 'lat_ph', 'lon_ph', 'signal_conf_ph']
  22.         for key in heights_keys:
  23.             atl03_mds['heights'][key] = root[beam]['heights'][key][:]
  24.         geolocation_keys = ['ref_elev', 'ph_index_beg', 'segment_id', 'segment_ph_cnt', 'segment_dist_x', 'segment_length']
  25.         # -- ICESat-2 Geolocation Group
  26.         for key in geolocation_keys:
  27.             atl03_mds['geolocation'][key] = root[beam]['geolocation'][key][:]
  28.     h5_store.close()
  29.     return atl03_mds
复制代码
使用h5py
  1. import os
  2. import h5py
  3. import re
  4. def read_hdf5_atl03_beam_h5py(filename, beam, verbose=False):
  5.     """
  6.     ATL03 原始数据读取
  7.     Args:
  8.         filename (str): h5文件路径
  9.         beam (str): 光束
  10.         verbose (bool): 输出HDF5信息
  11.     Returns:
  12.         返回ATL03光子数据的heights和geolocation信息
  13.     """
  14.     # 打开HDF5文件进行读取
  15.     file_id = h5py.File(os.path.expanduser(filename), 'r')
  16.     # 输出HDF5文件信息
  17.     if verbose:
  18.         print(file_id.filename)
  19.         print(list(file_id.keys()))
  20.         print(list(file_id['METADATA'].keys()))
  21.     # 为ICESat-2 ATL03变量和属性分配python字典
  22.     atl03_mds = {}
  23.     # 读取文件中每个输入光束
  24.     beams = [k for k in file_id.keys() if bool(re.match('gt\\d[lr]', k))]
  25.     if beam not in beams:
  26.         print('请填入正确的光束代码')
  27.         return
  28.     atl03_mds['heights'] = {}
  29.     atl03_mds['geolocation'] = {}
  30.     atl03_mds['bckgrd_atlas'] = {}
  31.     # -- 获取每个HDF5变量
  32.     # -- ICESat-2 Measurement Group
  33.     for key, val in file_id[beam]['heights'].items():
  34.         atl03_mds['heights'][key] = val[:]
  35.     # -- ICESat-2 Geolocation Group
  36.     for key, val in file_id[beam]['geolocation'].items():
  37.         atl03_mds['geolocation'][key] = val[:]
  38.     for key, val in file_id[beam]['bckgrd_atlas'].items():
  39.         atl03_mds['bckgrd_atlas'][key] = val[:]
  40.     return atl03_mds
复制代码
重建沿轨道隔断

在读取ICESat-2 ATL03数据后,我们必要根据分段信息重建每个光子的沿轨道隔断,已知数据如下:

  • ATL03每个分段内的光子都有一个沿轨道隔断(dist_ph_along),该隔断始于当前分段。
  • ATL03每个分段有一个沿轨道隔断(segment_dist_x),该隔断始于赤道交叉口,即真正的沿轨道隔断。
  • 当前分段内每个光子的相对沿轨道隔断 + 当前分段的沿轨道隔断 = 每个光子的真正沿轨道隔断。
代码如下:
  1. import numpy as np
  2. def get_atl03_x_atc(atl03_mds):
  3.     val = atl03_mds
  4.     # 初始化
  5.     val['heights']['x_atc'] = np.zeros_like(val['heights']['h_ph']) + np.NaN
  6.     val['heights']['y_atc'] = np.zeros_like(val['heights']['h_ph']) + np.NaN
  7.     val['geolocation']['ref_elev_all'] = np.zeros_like(val['heights']['h_ph'])
  8.     # -- ATL03 Segment ID
  9.     segment_id = val['geolocation']['segment_id']
  10.     # -- 分段中的第一个光子(转换为基于0的索引)
  11.     segment_index_begin = val['geolocation']['ph_index_beg'] - 1
  12.     # -- 分段中的光子事件数
  13.     segment_pe_count = val['geolocation']['segment_ph_cnt']
  14.     # -- 每个ATL03段的沿轨道距离
  15.     segment_distance = val['geolocation']['segment_dist_x']
  16.     # -- 每个ATL03段的轨道长度
  17.     segment_length = val['geolocation']['segment_length']
  18.     # -- 对ATL03段进行迭代,以计算40m的平均值
  19.     # -- 在ATL03中基于1的索引:无效==0
  20.     # -- 此处为基于0的索引:无效==-1
  21.     segment_indices, = np.nonzero((segment_index_begin[:-1] >= 0) &
  22.                                   (segment_index_begin[1:] >= 0))
  23.     for j in segment_indices:
  24.         # -- j 段索引
  25.         idx = segment_index_begin[j]
  26.         # -- 分段中的光子数(使用2个ATL03分段)
  27.         c1 = np.copy(segment_pe_count[j])
  28.         c2 = np.copy(segment_pe_count[j + 1])
  29.         cnt = c1 + c2
  30.         # -- 沿轨道和跨轨道距离
  31.         # -- 获取当前段光子列表,idx当前段(j)第一个光子数量,c1当前段光子数量,idx+c1当前段长度
  32.         distance_along_x = np.copy(val['heights']['dist_ph_along'][idx: idx + cnt])
  33.         ref_elev = np.copy(val['geolocation']['ref_elev'][j])
  34.         # -- 给当前段的光子加上当前段沿轨道距离
  35.         distance_along_x[:c1] += segment_distance[j]
  36.         distance_along_x[c1:] += segment_distance[j + 1]
  37.         distance_along_y = np.copy(val['heights']['dist_ph_across'][idx: idx + cnt])
  38.         val['heights']['x_atc'][idx: idx + cnt] = distance_along_x
  39.         val['heights']['y_atc'][idx: idx + cnt] = distance_along_y
  40.         val['geolocation']['ref_elev_all'][idx: idx + c1] += ref_elev
复制代码
ATL03数据截取

在处理ATL03时,我们一般都会获取经过研究区域内的光子数据,因此必要对数据举行截取操纵,代码如下:
[code]from glob import globfrom readers.get_ATL03_x_atc import get_atl03_x_atcfrom readers.read_HDF5_ATL03 import read_hdf5_atl03_beam, read_hdf5_atl03_coordinatedef read_data(filepath, beam, mask_lat, mask_lon):    """    读取数据,返回沿轨道隔断和高程隔断    :param filepath: h5文件路径    :param beam: 轨道光束    :param mask_lat: 维度范围    :param mask_lon: 经度范围    :return:    """    atl03_file = glob(filepath)    is2_atl03_mds = read_hdf5_atl03_beam(atl03_file[0], beam=beam, verbose=False)    # 添加沿轨道隔断到数据中    get_atl03_x_atc(is2_atl03_mds)    # 选择范围    d3 = is2_atl03_mds    subset1 = (d3['heights']['lat_ph'] >= min(mask_lat)) & (d3['heights']['lat_ph'] = mask_lon[0])        elif mask_lon[0] is None and mask_lon[1] is not None:            subset1 = subset1 & (d3['heights']['x_atc'] = min(mask_lon)) & (d3['heights']['x_atc'] = min(mask_lat)) & (d3[beam]['lat'] = min(mask_lon)) & (d3[beam]['lon']

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王海鱼

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表