ASF(Alaska Satellite Facility) HyP3(音同 hype [haɪp]
, Hybrid Pluggable Processing Pipeline)是一项用于处理合成孔径雷达(SAR)影像的服务,可解决SAR数据用户的许多常见问题:
HyP3通过提供一项免费服务来解决这些问题,人们可以根据需要请求SAR处理。HyP3不要求用户在入门前具备大量的SAR处理知识;用户只需提交输入数据,并根据需要设置一些可选参数。
HyP3服务目前仅适用于Sentinel-1数据集,有三种请求HyP3处理产品的方法。
Web访问
ASF的数据搜索Vertex门户提供了一个丰富的界面,来探索Sentinel-1采集并查找图像以提交需求进行处理。它还提供了为InSAR分析选择对和叠加的工具。
程序访问
请求和下载产品也可以通过编程来完成:
本教程只展示使用 Python 操作 HyP3。
HyP3 SDK可以通过conda
进行安装:
conda install -c conda-forge hyp3_sdk -y
或者通过pip
进行安装
python -m pip install hyp3_sdk
HyP3 SDK 有3个主要的 python 类(class):
HyP3
: 执行HyP3操作(查找作业、刷新作业信息、提交新作业)Job
: 对单个作业执行操作(下载产品、检查状态)Batch
: 一次对多个作业执行操作(下载产品、检查状态)import hyp3_sdk as sdk
SDK将尝试从~/.netrc
中获取您的NASA Earthdata登录凭据。我们也可以直接传递登录凭据。
通过.netrc授权
通过.netrc
,不需要传递任何信息,程序会自动读取~/.netrc
文件获取登录凭证。
hyp3 = sdk.HyP3()
如果不太懂如何操作.netrc
,可以使用data-downloader
包来管理.netrc
。
安装 data-downloader
:
pip install data_downloader
使用 data_downloader
管理 .netrc
from data_downloader import downloadernetrc = downloader.Netrc()
# MyUsername,MyPassword分别为自己的 NASA 账号的用户名与密码
netrc.add('urs.earthdata.nasa.gov', 'MyUsername', 'MyPassword')
手动输入凭证授权
通过终端,自己手动输入用户名与密码。
hyp3 = sdk.HyP3(prompt=True)
直接指定凭证授权
直接将用户名与密码写到程序中。
# MyUsername,MyPassword分别为自己的 NASA 账号的用户名与密码
hyp3 = HyP3(username='MyUsername', password='MyPassword')
HyP3 SDK 有3种job类型:
RTC
: SAR数据集固有地包含几何和辐射失真。辐射地形校正(RTC)消除了这些失真,并生成了适用于GIS应用的分析的数据。RTC处理是许多基于振幅的SAR应用所需的第一步。InSAR
: 干涉合成孔径雷达( Interferometric SAR,InSAR )利用同一区域内重复经过的相位差来识别传感器与地球表面距离发生变化的区域。autoRIFT
: AutoRIFT利用NASA MEaSUREs ITS _ LIVE项目中开发的特征跟踪算法从观测运动中生成速度图。提交Sentinel-1 RTC jobs
Sentinel-1辐射地形校正(RTC)作业是使用 ESA granule IDs 提交的。下面的 示例 granule 可以在ASF搜索中查看。
granules = ['S1A_IW_SLC__1SDV_20210214T154835_20210214T154901_036588_044C54_8494','S1B_IW_SLC__1SDV_20210210T153131_20210210T153159_025546_030B48_B568','S1A_IW_SLC__1SDV_20210210T025526_20210210T025553_036522_0449E2_7769','S1A_IW_SLC__1SDV_20210210T025501_20210210T025528_036522_0449E2_3917','S1B_IW_SLC__1SDV_20210209T030255_20210209T030323_025524_030A8D_7E88','S1B_IW_SLC__1SDV_20210209T030227_20210209T030257_025524_030A8D_5BAF','S1A_IW_SLC__1SDV_20210202T154835_20210202T154902_036413_044634_01A1',
]rtc_jobs = sdk.Batch()
for g in granules:rtc_jobs += hyp3.submit_rtc_job(g, name='rtc-example')
print(rtc_jobs)
这里我们将每个作业命名为rtc-example
,稍后我们可以使用它来搜索这些作业。
HyP3.submit_rtc_job
还接受 关键字参数 来为您的应用程序定制生成的RTC产品。
提交Sentinel-1 InSAR jobs
SDK还可以提交Sentinel-1干涉合成孔径雷达(InSAR)作业,处理reference-secondary干涉对。
from tqdm.auto import tqdm # 用于生成进度条,第三方包,可以使用 pip install tqdm 进行安装insar_jobs = sdk.Batch()pairs = [('S1B_IW_SLC__1SSV_20170111T232556_20170111T232624_003807_0068BB_61D1','S1B_IW_SLC__1SSV_20170204T232555_20170204T232623_004157_00731B_FBFA'),('S1B_IW_SLC__1SSV_20170111T232556_20170111T232624_003807_0068BB_61D1','S1A_IW_SLC__1SDV_20170222T232637_20170222T232705_015403_019477_F04A'),('S1B_IW_SLC__1SSV_20170111T232556_20170111T232624_003807_0068BB_61D1','S1A_IW_SLC__1SDV_20170318T232638_20170318T232705_015753_019EF5_7A50'),('S1B_IW_SLC__1SSV_20170204T232555_20170204T232623_004157_00731B_FBFA','S1A_IW_SLC__1SDV_20170222T232637_20170222T232705_015403_019477_F04A'),('S1B_IW_SLC__1SSV_20170204T232555_20170204T232623_004157_00731B_FBFA','S1A_IW_SLC__1SDV_20170318T232638_20170318T232705_015753_019EF5_7A50')]for reference, secondary in tqdm(pairs):insar_jobs += hyp3.submit_insar_job(reference, secondary, name='insar-example',# 要求结果包含缠绕相位(相位减缠前)结果。默认是False, 不包含。include_wrapped_phase=True, # 要求结果包形变结果,包含了LOS形变与垂直形变,其中垂直形变是假设形变全部为垂直方向。默认是False, 不包含。include_displacement_maps=True)
与RTC作业一样,HyP3.submit_insar_job
接受关键字参数来为应用程序定制生成的insar产品。例如,本例中的include_wrapped_phase=True
与 include_displacement_maps=True
。
提交autoRIFT jobs
AutoRIFT支持处理 Sentinel-1
、Sentinel-2
或 Landsat-8 Collection 2
。
autorift_pairs = [# Sentinel-1 ESA granule IDs('S1A_IW_SLC__1SSH_20170221T204710_20170221T204737_015387_0193F6_AB07','S1B_IW_SLC__1SSH_20170227T204628_20170227T204655_004491_007D11_6654'),# Sentinel-2 ESA granule IDs('S2B_MSIL1C_20200612T150759_N0209_R025_T22WEB_20200612T184700','S2A_MSIL1C_20200627T150921_N0209_R025_T22WEB_20200627T170912'),# Landsat 8('LC08_L1TP_009011_20200703_20200913_02_T1','LC08_L1TP_009011_20200820_20200905_02_T1'),
]autorift_jobs = sdk.Batch()
for reference, secondary in autorift_pairs:autorift_jobs += hyp3.submit_autorift_job(reference, secondary, name='autorift-example')
print(autorift_jobs)
AutoRIFT目前不接受任何用于产品定制的关键字参数。
注意:
由于按需处理的日益普及,ASF决定从 2022 年 2 月开始, 处理配额将设置为每个用户每月 1000 个jobs。
一旦提交了一个作业,我们可以观察作业,直到它们完成。
我们可以使用刚才创建的作业类来观察,这需要保持终端一直在运行。一旦批处理中的某个作业完成,hyp3.watch()将返回一个刷新的批处理。
rtc_jobs = hyp3.watch(rtc_jobs)
如果终端不小心被关闭,我们也可以通过作业名字来手动查找并观察已经提交过的jobs。
rtc_jobs = hyp3.find_jobs(name='rtc-example')
rtc_jobs = hyp3.watch(rtc_jobs)
如果我们不需要持续观察jobs的进度,也可以刷新作业快照,并输出作业进度信息。Batches 是Jobs 的集合。它们提供了创建或上次刷新作业时作业状态的快照。要刷新Batches
的信息,可以执行:
print(insar_jobs)
insar_jobs = hyp3.refresh(insar_jobs)
print(insar_jobs)
Batches 可以加到一块
print(f'Number of Jobs:\n RTC:{len(rtc_jobs)}\n InSAR:{len(insar_jobs)}\n autoRIFT:{len(autorift_jobs)}')
all_jobs = rtc_jobs + insar_jobs + autorift_jobs
print(f'Total number of Jobs: {len(all_jobs)}')
你可以通过jobs的状态过滤jobs
succeeded_jobs = all_jobs.filter_jobs(succeeded=True, running=False, failed=False)
print(f'Number of succeeded jobs: {len(succeeded_jobs)}')
failed_jobs = all_jobs.filter_jobs(succeeded=False, running=False, failed=True)
print(f'Number of failed jobs: {len(failed_jobs)}')
batches中已经成功的文件可以下载到本地。
result_dir = r'D:\hyp3_result' # 指定下载到本地的文件夹
file_list = succeeded_jobs.download_files(result_dir)
也可以直接下载仍然有运行中的jobs的batches,代码会跳过未完成的jobs,并一直自动下载已经完成的jobs。
result_dir = r'D:\hyp3_result' # 指定下载到本地的文件夹
file_list = all_jobs.download_files(result_dir)
...
S1AA_20181015T232654_20181120T232654_VVP036_INT80_G_ueF_9433.zip: 100%|██████████| 172M/172M [07:48<00:00, 384kB/s]
S1AA_20181015T232654_20181108T232654_VVP024_INT80_G_ueF_5267.zip: 100%|██████████| 172M/172M [29:13<00:00, 103kB/s]
S1AA_20181015T232654_20181027T232654_VVP012_INT80_G_ueF_AEA3.zip: 100%|██████████| 167M/167M [11:09<00:00, 262kB/s]
S1AA_20181003T232654_20181108T232654_VVP036_INT80_G_ueF_EC6D.zip: 100%|██████████| 169M/169M [13:11<00:00, 224kB/s]73%|███████▎ | 422/582 [8:04:45<39:35:24, 890.78s/it]