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

ATL03数据读取

H5是一种数据存储结构,读取原理就是按照该结构获取数据,这里给出两种读取方式。

ATL03的数据字典:ATL03 Product Data Dictionary (nsidc.org)

使用pandas

import warnings
import pandas as pd def read_hdf5_atl03_beam_pandas(filename, beam, verbose=False):
# 打开HDF5文件进行读取
h5_store = pd.HDFStore(filename, mode='r')
root = h5_store.root
# 为ICESat-2 ATL03变量和属性分配python字典
atl03_mds = {} # 读取文件中每个输入光束
# beams = [k for k in file_id.keys() if bool(re.match('gt\\d[lr]', k))]
beams = ['gt1l', 'gt1r', 'gt2l', 'gt2r', 'gt3l', 'gt3r']
if beam not in beams:
print('请填入正确的光束代码')
return atl03_mds['heights'] = {}
atl03_mds['geolocation'] = {} # -- 获取每个HDF5变量
with warnings.catch_warnings():
warnings.simplefilter("ignore")
# -- ICESat-2 Heights Group
heights_keys = ['dist_ph_across', 'dist_ph_along', 'h_ph', 'lat_ph', 'lon_ph', 'signal_conf_ph']
for key in heights_keys:
atl03_mds['heights'][key] = root[beam]['heights'][key][:] geolocation_keys = ['ref_elev', 'ph_index_beg', 'segment_id', 'segment_ph_cnt', 'segment_dist_x', 'segment_length']
# -- ICESat-2 Geolocation Group
for key in geolocation_keys:
atl03_mds['geolocation'][key] = root[beam]['geolocation'][key][:] h5_store.close()
return atl03_mds

使用h5py

import os
import h5py
import re def read_hdf5_atl03_beam_h5py(filename, beam, verbose=False):
"""
ATL03 原始数据读取
Args:
filename (str): h5文件路径
beam (str): 光束
verbose (bool): 输出HDF5信息 Returns:
返回ATL03光子数据的heights和geolocation信息
""" # 打开HDF5文件进行读取
file_id = h5py.File(os.path.expanduser(filename), 'r') # 输出HDF5文件信息
if verbose:
print(file_id.filename)
print(list(file_id.keys()))
print(list(file_id['METADATA'].keys())) # 为ICESat-2 ATL03变量和属性分配python字典
atl03_mds = {} # 读取文件中每个输入光束
beams = [k for k in file_id.keys() if bool(re.match('gt\\d[lr]', k))]
if beam not in beams:
print('请填入正确的光束代码')
return atl03_mds['heights'] = {}
atl03_mds['geolocation'] = {}
atl03_mds['bckgrd_atlas'] = {} # -- 获取每个HDF5变量
# -- ICESat-2 Measurement Group
for key, val in file_id[beam]['heights'].items():
atl03_mds['heights'][key] = val[:] # -- ICESat-2 Geolocation Group
for key, val in file_id[beam]['geolocation'].items():
atl03_mds['geolocation'][key] = val[:] for key, val in file_id[beam]['bckgrd_atlas'].items():
atl03_mds['bckgrd_atlas'][key] = val[:] return atl03_mds

重建沿轨道距离

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

  • ATL03每个分段内的光子都有一个沿轨道距离(dist_ph_along),该距离始于当前分段。

  • ATL03每个分段有一个沿轨道距离(segment_dist_x),该距离始于赤道交叉口,即真正的沿轨道距离。

  • 当前分段内每个光子的相对沿轨道距离 + 当前分段的沿轨道距离 = 每个光子的真正沿轨道距离。

代码如下:

import numpy as np

def get_atl03_x_atc(atl03_mds):
val = atl03_mds # 初始化
val['heights']['x_atc'] = np.zeros_like(val['heights']['h_ph']) + np.NaN
val['heights']['y_atc'] = np.zeros_like(val['heights']['h_ph']) + np.NaN
val['geolocation']['ref_elev_all'] = np.zeros_like(val['heights']['h_ph']) # -- ATL03 Segment ID
segment_id = val['geolocation']['segment_id']
# -- 分段中的第一个光子(转换为基于0的索引)
segment_index_begin = val['geolocation']['ph_index_beg'] - 1
# -- 分段中的光子事件数
segment_pe_count = val['geolocation']['segment_ph_cnt']
# -- 每个ATL03段的沿轨道距离
segment_distance = val['geolocation']['segment_dist_x']
# -- 每个ATL03段的轨道长度
segment_length = val['geolocation']['segment_length'] # -- 对ATL03段进行迭代,以计算40m的平均值
# -- 在ATL03中基于1的索引:无效==0
# -- 此处为基于0的索引:无效==-1
segment_indices, = np.nonzero((segment_index_begin[:-1] >= 0) &
(segment_index_begin[1:] >= 0))
for j in segment_indices:
# -- j 段索引
idx = segment_index_begin[j]
# -- 分段中的光子数(使用2个ATL03分段)
c1 = np.copy(segment_pe_count[j])
c2 = np.copy(segment_pe_count[j + 1])
cnt = c1 + c2 # -- 沿轨道和跨轨道距离
# -- 获取当前段光子列表,idx当前段(j)第一个光子数量,c1当前段光子数量,idx+c1当前段长度
distance_along_x = np.copy(val['heights']['dist_ph_along'][idx: idx + cnt])
ref_elev = np.copy(val['geolocation']['ref_elev'][j])
# -- 给当前段的光子加上当前段沿轨道距离
distance_along_x[:c1] += segment_distance[j]
distance_along_x[c1:] += segment_distance[j + 1]
distance_along_y = np.copy(val['heights']['dist_ph_across'][idx: idx + cnt]) val['heights']['x_atc'][idx: idx + cnt] = distance_along_x
val['heights']['y_atc'][idx: idx + cnt] = distance_along_y
val['geolocation']['ref_elev_all'][idx: idx + c1] += ref_elev

ATL03数据截取

在处理ATL03时,我们一般都会获取经过研究区域内的光子数据,因此需要对数据进行截取操作,代码如下:

from glob import glob

from readers.get_ATL03_x_atc import get_atl03_x_atc
from readers.read_HDF5_ATL03 import read_hdf5_atl03_beam, read_hdf5_atl03_coordinate def 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'] <= max(mask_lat))
if mask_lon is not None:
if mask_lon[0] is not None and mask_lon[1] is None:
subset1 = subset1 & (d3['heights']['x_atc'] >= mask_lon[0])
elif mask_lon[0] is None and mask_lon[1] is not None:
subset1 = subset1 & (d3['heights']['x_atc'] <= mask_lon[1])
else:
subset1 = subset1 & (d3['heights']['x_atc'] >= min(mask_lon)) & (d3['heights']['x_atc'] <= max(mask_lon))
x_act = d3['heights']['x_atc'][subset1]
h = d3['heights']['h_ph'][subset1]
signal_conf_ph = d3['heights']['signal_conf_ph'][subset1]
lat = d3['heights']['lat_ph'][subset1]
lon = d3['heights']['lon_ph'][subset1]
ref_elev = d3['geolocation']['ref_elev_all'][subset1] del d3, subset1
return x_act, h, signal_conf_ph, lat, lon, ref_elev def read_all_beam_coordinate(filepath, mask_lat, mask_lon):
"""
读取所有波束的数据
:param filepath:
:param mask_lat:
:param mask_lon:
:return:
"""
atl03_file = glob(filepath)
is2_atl03_mds = read_hdf5_atl03_coordinate(atl03_file[0]) # 禁止加载全部数据
# if mask_lat is None or len(mask_lat) == 0 or mask_lon is None or len(mask_lon) == 0:
# return False d3 = is2_atl03_mds
if mask_lon is None and mask_lat is None:
# 加载全部数据
return d3
for beam in is2_atl03_mds.keys():
subset1 = (d3[beam]['lat'] >= min(mask_lat)) & (d3[beam]['lat'] <= max(mask_lat))
subset1 = subset1 & (d3[beam]['lon'] >= min(mask_lon)) & (d3[beam]['lon'] <= max(mask_lon))
d3[beam]['lat'] = d3[beam]['lat'][subset1]
d3[beam]['lon'] = d3[beam]['lon'][subset1]
return d3

数据可视化

使用沿轨道距离和高程数据绘制散点图,示例代码如下:

def save2file(act, h, conf, lat, lon):
"""
保存研究区域的一下数据
:param act: act,沿轨道距离
:param h: h,高程
:param conf: 置信度
:param lat: 维度
:param lon: 经度
"""
points = list(zip(act, h, lat, lon, conf))
data = pd.DataFrame(points, columns=['沿轨道距离', '高程', '维度', '经度', '置信度'])
data.to_csv('result/points_origin.csv', mode='w', index=False) if __name__ == '__main__':
filepath = r'D:\Users\SongW\Downloads\ATL03_20190222135159_08570207_005_01.h5'
beam = 'gt3l'
mask_lat = [16.533, 16.550]
act, h, conf, lat, lon, ref_elev = read_data(filepath, beam, mask_lat, None)
save2file(act, h, conf, lat, lon)
plt.scatter(act, h)
plt.show()

输出图像如下:

项目源码

sx-code - icesat-2-atl03 (github.com)

ICESat-2 ATL03光子数据读取的更多相关文章

  1. OleDbDataReader快速数据读取方式

    查询得到OleDbDataReader后,有三种方式支持数据读取,如下: //方法一**速度中等 OleDbDataReader reader = command.ExecuteReader(); w ...

  2. DataTable to Excel(使用NPOI、EPPlus将数据表中的数据读取到excel格式内存中)

    /// <summary> /// DataTable to Excel(将数据表中的数据读取到excel格式内存中) /// </summary> /// <param ...

  3. geotrellis使用(二)geotrellis-chatta-demo以及geotrellis框架数据读取方式初探

    在上篇博客(geotrellis使用初探)中简单介绍了geotrellis-chatta-demo的大致工作流程,但是有一个重要的问题就是此demo如何调取数据进行瓦片切割分析处理等并未说明,经过几天 ...

  4. GPS数据读取与处理

    GPS数据读取与处理 GPS模块简介 SiRF芯片在2004年发布的最新的第三代芯片SiRFstar III(GSW 3.0/3.1),使得民用GPS芯片在性能方面登上了一个顶峰,灵敏度比以前的产品大 ...

  5. 【原】Learning Spark (Python版) 学习笔记(二)----键值对、数据读取与保存、共享特性

    本来应该上周更新的,结果碰上五一,懒癌发作,就推迟了 = =.以后还是要按时完成任务.废话不多说,第四章-第六章主要讲了三个内容:键值对.数据读取与保存与Spark的两个共享特性(累加器和广播变量). ...

  6. MATLAB对于文本文件(txt)数据读取的技巧总结(经典中的经典)

    振动论坛原版主eight的经典贴http://www.chinavib.com/thread-45622-1-1.html MATLAB对于文本文件(txt)进行数据读取的技巧总结(经典中的经典)由于 ...

  7. TableInputFormat分片及分片数据读取源码级分析

    我们在MapReduce中TextInputFormat分片和读取分片数据源码级分析 这篇中以TextInputFormat为例讲解了InputFormat的分片过程以及RecordReader读取分 ...

  8. Extjs的数据读取器store和后台返回类型简单解析

    工作中用到了Extjs,从后台获取数据的时候,用到了extjs自己的Ext.data.store方法,然后封装了ExtGridReturn方法, 目的:前台用到Ext.data.store读取从后台传 ...

  9. Java学习-028-JSON 之二 -- 数据读取

    JSON数据由 JSONObject.JSONArray.key_value 组合而成.通常来说,JSONObject 可以包含 JSONObject.JSONArray.key_value:JSON ...

  10. [原创]SSIS-WMI 数据读取器任务:监控物理磁盘空间

    背景:       随着时间的推移,我们的DW会越来越大,也就意味着磁盘空间会越来越小,那如果哪一天留意不当,就会造成磁盘空间的不足而导致ETL失败,最终影响我们的系统的数据正确性和使用,更严重的有可 ...

随机推荐

  1. 【Insights直播】华为帐号服务,打造全场景安全帐号体系

    在App运营过程中,如何保持用户增长和提升用户体验始终是开发者关注的问题,而作为用户使用体验感知的第一环节--帐号注册登录环节是不可忽视,且有很大提升空间的.如何提升帐号的注册登录体验?如何保证用户在 ...

  2. 使用谷歌浏览器打开PDF文件,怎么关闭缩略图

    我们在使用谷歌浏览器浏览PDF文件时,总是会出现章节预览缩略图和工具栏,我们可以使用 参数来控制浏览器不显示出工具栏 #scrollbars=0&toolbar=0&statusbar ...

  3. 用HarmonyOS做一个可以手势控制的电子相册应用(ArkTS)

    介绍 本篇 Codelab 介绍了如何实现一个简单的电子相册应用,主要功能包括: 1.  实现首页顶部的轮播效果. 2.  实现页面多种布局方式. 3.  实现通过手势控制图片的放大.缩小.左右滑动查 ...

  4. 如何在报表中绘制 SVG 统计图

    SVG 作为一种矢量图形,具有任意缩放不失真.可被高质量打印.文件较小.交互性强等优势,正逐渐成为一种主流的图片格式.润乾报表一方面可以生成 SVG 格式的统计图,另一方面也可以在 HTML5 中直接 ...

  5. c# 反编译对比(旧)

    前言 旧的都是我以前博客的迁移. 我们写代码有时候遇到一些问题,或者我们想优化我们的代码,我们想要看编译后的运行情况,那么反编译是必须要做的一件事. 正文 在此我自己使用的是reflector和ILS ...

  6. WPF随笔收录-RestSharp下载文件406问题

    一.前言 在项目开发过程中,涉及到通过http下载文件的需求,最近遇到一个406问题,由于第一次接触这个问题,也被问题卡了好久,在网上风暴了很久才找到解决办法: 二.解决方法 解决的办法就是在requ ...

  7. KubeVela v1.2 发布:你要的图形化操作控制台 VelaUX 终于来了!

    ​简介:时间来到 2022 年,KubeVela 也正式进入了第四个阶段,在原先核心控制器 API 基本稳定的基础上,我们以插件的形式增加了一系列开箱即用的功能.让开发者可以通过 UI 控制台的方式, ...

  8. 云上技术 | 混合云管理平台多Region架构

    简介: 随着现代化进程加速,企业业务规模和迭代速度也今非昔比,在已具备一定规模的中大型电力系统中,会面临着数字化升级的压力,包括复杂组织架构管理.计算资源弹性扩展.IT运维提效等需求.基于电力行业属性 ...

  9. Dubbo-Admin 正式支持 3.0 服务治理

    ​简介:Dubbo 相信大家并不陌生,是一款微服务开发框架,它提供了 RPC 通信与微服务治理两大关键能力.大家在日常开发中更多使用的是 Dubbo 提供的 RPC 通信这一部分能力,而对其提供的服务 ...

  10. [GPT] 同为 nodejs 库的 Puppeteer 和 cheerio 的区别是什么

    Puppeteer 和 cheerio 是两个完全不同的库,用途和功能也截然不同. Puppeteer 是一个 Node.js 库,它使用 Chrome 或 Chromium 浏览器作为渲染引擎,通过 ...