ASF HyP3 Python接口使用教程

1. HyP3简介

ASF(Alaska Satellite Facility) HyP3(音同 hype [haɪp], Hybrid Pluggable Processing Pipeline)是一项用于处理合成孔径雷达(SAR)影像的服务,可解决SAR数据用户的许多常见问题:

  • 大多数SAR数据集需要一些处理来消除畸变,然后才能进行分析
  • SAR处理是计算密集型的
  • SAR处理软件使用起来十分复杂,或过于昂贵
  • 处理SAR数据有一个陡峭的学习曲线,存在入门障碍

HyP3通过提供一项免费服务来解决这些问题,人们可以根据需要请求SAR处理。HyP3不要求用户在入门前具备大量的SAR处理知识;用户只需提交输入数据,并根据需要设置一些可选参数。

HyP3服务目前仅适用于Sentinel-1数据集,有三种请求HyP3处理产品的方法。

Web访问

ASF的数据搜索Vertex门户提供了一个丰富的界面,来探索Sentinel-1采集并查找图像以提交需求进行处理。它还提供了为InSAR分析选择对和叠加的工具。

程序访问

请求和下载产品也可以通过编程来完成:

本教程只展示使用 Python 操作 HyP3。

2. HyP3 SDK for Python 安装

HyP3 SDK可以通过conda进行安装:

conda install -c conda-forge hyp3_sdk -y

或者通过pip进行安装

python -m pip install hyp3_sdk

3. 使用

HyP3 SDK 有3个主要的 python 类(class):

  • HyP3: 执行HyP3操作(查找作业、刷新作业信息、提交新作业)
  • Job: 对单个作业执行操作(下载产品、检查状态)
  • Batch: 一次对多个作业执行操作(下载产品、检查状态)

3.1. 导入hyp3_sdk 包

import hyp3_sdk as sdk

3.2. 登录授权

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 downloader

netrc = downloader.Netrc()
# 添加登录信息到netrc文件中。MyUsername,MyPassword分别为自己的 NASA 账号的用户名与密码
netrc.add('urs.earthdata.nasa.gov', 'MyUsername', 'MyPassword')

# 查看.netrc中的信息
print(netrc)

手动输入凭证授权

通过终端,自己手动输入用户名与密码。

hyp3 = sdk.HyP3(prompt=True)

直接指定凭证授权

直接将用户名与密码写到程序中。

# MyUsername,MyPassword分别为自己的 NASA 账号的用户名与密码
hyp3 = HyP3(username='MyUsername', password='MyPassword')

3.3. 提交Jobs

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',
        # 要求结果包含DEM文件。默认是False, 不包含。使用Mintpy需改为True
        include_dem=True,
        # 要求结果包含角度theta和phi文件。默认是False, 不包含。使用Mintpy需改为True
        include_look_vectors=True,
        # 要求结果包含缠绕相位(相位减缠前)结果。默认是False, 不包含。
        include_wrapped_phase=True, 
        # 要求结果包形变结果,包含了LOS形变与垂直形变,其中垂直形变是假设形变全部为垂直方向。默认是False, 不包含。
        include_displacement_maps=True) 

与RTC作业一样,HyP3.submit_insar_job接受关键字参数来为应用程序定制生成的insar产品。例如,本例中的include_wrapped_phase=Trueinclude_displacement_maps=True

提交autoRIFT jobs

AutoRIFT支持处理 Sentinel-1Sentinel-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。

3.4 监控与操作 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的进度,也可以刷新作业快照,并输出作业进度信息。BatchesJobs 的集合。它们提供了创建或上次刷新作业时作业状态的快照。要刷新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)}')

3.4 下载文件

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]

目前,hyp3_sdk 不能自动跳过下载完成的文件。如果下载被迫中断,需要重新下载,想自动跳过已经下载过的文件,可以使用data_downloader 包。

result_dir = r'D:\hyp3_result' # 指定下载到本地的文件夹

for job in tqdm(succeeded_jobs.jobs):
    for file in job.files:
        download_url = file['url']
        downloader.download_data(download_url,folder=result_dir)

猜你喜欢

转载自blog.csdn.net/qq_27386899/article/details/128169755
今日推荐