15 KiB
Sentinel-1 Gamma SBAS 无拼接接入设计
最后更新:2026-06-02
本文设计 sbas-insar-production 对 Sentinel-1 Gamma SBAS 的稳定接入方案。目标是复用现有 SBAS 生产管理框架,但不影响现有 LT-1 Gamma SBAS 链路;允许传感器专用逻辑冗余实现,以稳定性和可回退为第一优先级。
1. 术语说明
本文目标是 Sentinel-1 SAR 数据,不是 Sentinel-2。
Sentinel-2 是光学卫星,不具备 SAR 干涉相位,不能迁移到 Gamma SBAS-InSAR。如果后续业务说“哨兵2”,需要先确认是不是口误;系统实现应使用 Sentinel-1、S1、s1_gamma_sbas 这些明确命名,避免把 Sentinel-2 暗含进 InSAR 链路。
2. 设计结论
当前 Gamma SBAS 核心是 LT-1 专用实现,包含 LT-1 目录扫描、LT-1 元数据解析、LT-1 精轨脚本和 par_LT1_SLC 导入脚本。Sentinel-1 不应在这条链上硬改。
新增 Sentinel-1 支持时采用 profile 并列方案:
lt1_gamma_sbas # 现有链路,保持行为不变
s1_gamma_sbas # 新增链路,独立发现、独立脚本、独立校验
复用内容:
- API 路由和生产 Run 生命周期。
- Stack discovery / audit / create run 的外层流程。
- Workflow/job 调度、日志、状态机。
- Gamma 环境注入和 WSL runtime 管理。
- 产品发布、catalog、预览、监测点、下载接口。
不复用或只抽象复用的内容:
- 不复用 LT-1 场景扫描。
- 不复用 LT-1 SLC 导入脚本。
- 不复用 LT-1 精轨处理脚本。
- 不复用 LT-1 专家文档中的传感器专有命令。
- 不在 LT-1 脚本模板中加入 Sentinel-1 分支。
3. 目标与非目标
3.1 目标
- 新增 Sentinel-1 Gamma SBAS profile,入口可发现 Sentinel-1 候选 stack。
- Sentinel-1 使用 ZIP/SAFE + EOF 资产,不走 LT-1
tiff/meta.xml/txt orbit逻辑。 - 不支持拼接。第一阶段只支持单轨、同向、同 relative orbit、同 acquisition mode、同 polarization、同 subswath、同 burst 或同一稳定 burst key 的 stack。
- 对需要拼接才能覆盖 AOI 的数据,系统不自动拼接,改为拆成多个独立候选 stack 或直接标记为
NOT_READY_REQUIRES_STITCHING。 - LT-1 现有生产效果不变,默认入口仍可继续跑现有 LT-1 数据。
- Sentinel-1 先做严格、保守、可解释的生产链,允许代码冗余,避免为了共用而引入隐性耦合。
3.2 非目标
- 不支持 Sentinel-2 光学时序。
- 不支持跨轨、跨 relative orbit、升降轨混合。
- 不支持跨 swath 拼接。
- 不支持跨 burst 拼接。
- 不支持相邻 Sentinel-1 slice/frame 自动拼接。
- 不把多个独立 Sentinel-1 SBAS 结果镶嵌成一张最终产品。
- 不改现有 LT-1 专家文档脚本的含义和输出。
4. 当前 LT-1 链路中不能直接复用的点
当前实现里有多处 LT-1 硬编码:
_iter_lt1_scene_dirs
_looks_like_lt1_scene_dir
_parse_lt1_scene
par_LT1_SLC
LT1_precision_orbit.py
Prepare LT1 SLCs
LT1_GAMMA_SBAS_逐命令处理流程.docx
layout_source = LT1_GAMMA_SBAS_expert_document
allowed_operations = lt1_gamma_sbas_workflow / lt1_gamma_sbas_step
这些不应扩展成大量 if sensor == "S1" 分支。否则 LT-1 的稳定链路会被 Sentinel-1 的 TOPS/burst 复杂性污染。
5. 总体架构
新增一个传感器 profile 适配层。现有 SbasInsarProductionService 保持外层协调角色,传感器专有逻辑下沉到 adapter。
建议模块:
backend/app/services/sbas_profiles/
__init__.py
base.py
lt1_gamma_sbas_profile.py
s1_gamma_sbas_profile.py
backend/app/services/sbas_script_templates/
lt1_gamma_sbas_scripts.py
s1_gamma_sbas_scripts.py
核心接口建议:
class GammaSbasProfile:
profile_code: str
sensor_family: str
def discover_scenes(source_roots, orbit_roots, filters) -> SceneDiscoveryResult: ...
def group_stack_candidates(scenes, aoi, options) -> list[StackCandidate]: ...
def audit_stack(stack_id, context) -> StackAudit: ...
def build_run_manifest(stack, options) -> dict: ...
def build_workflow_manifest(run_dir, run_manifest, options) -> dict: ...
def materialize_scripts(run_dir, workflow_manifest) -> list[ScriptArtifact]: ...
def validate_no_stitch_policy(stack) -> list[Issue]: ...
LT-1 profile 可以先只是封装现有函数,不改变行为。Sentinel-1 profile 独立实现。
6. API 和配置
6.1 API 参数
现有接口保持兼容,新增可选 profile_code:
{
"profile_code": "lt1_gamma_sbas",
"source_roots": [],
"orbit_roots": [],
"admin_region": "",
"discovery_mode": "strict",
"aoi_bbox": null
}
默认值为 lt1_gamma_sbas。这样老前端和老调用不受影响。
新增 Sentinel-1 时使用:
{
"profile_code": "s1_gamma_sbas",
"source_roots": ["D:\\Sentinel1_Image_Pool_ZIP"],
"orbit_roots": ["D:\\Sentinel1_Orbit_Pool"],
"admin_region": "..."
}
6.2 配置项
新增配置建议:
GAMMA_SBAS_PROFILES=lt1_gamma_sbas,s1_gamma_sbas
GAMMA_SBAS_DEFAULT_PROFILE=lt1_gamma_sbas
GAMMA_SBAS_S1_ENABLED=false
GAMMA_SBAS_S1_SOURCE_ROOTS=D:\Sentinel1_Image_Pool_ZIP
GAMMA_SBAS_S1_ORBIT_ROOTS=D:\Sentinel1_Orbit_Pool
GAMMA_SBAS_S1_NO_STITCH=true
GAMMA_SBAS_S1_MIN_SCENES=8
GAMMA_SBAS_S1_DEFAULT_SUBSWATH=IW2
GAMMA_SBAS_S1_DEFAULT_POLARIZATION=VV
GAMMA_SBAS_S1_ENABLED 初始应为 false。完成样本验证后再开放。
6.3 Runtime 白名单
wsl_runtime_registry.py 需要新增 operation:
s1_gamma_sbas_workflow
s1_gamma_sbas_step
不要复用 lt1_gamma_sbas_workflow 的 operation 名称。
7. Sentinel-1 数据发现与分组
7.1 数据来源
优先复用资产库存层:
- Sentinel-1 ZIP / SAFE 源产品资产。
- Sentinel-1 EOF 精密轨道资产。
logical_product_uid关联 ZIP 和 SAFE。- EOF 使用 validity window 匹配 scene。
如果资产库存不可用,S1 profile 可提供只读目录扫描兜底,但目录扫描结果必须写入同样的 SceneDescriptor 结构。
7.2 SceneDescriptor
Sentinel-1 scene 描述结构至少包含:
{
"sensor_family": "S1",
"satellite": "S1A",
"product_type": "SLC",
"acquisition_mode": "IW",
"polarization": "VV",
"orbit_direction": "ASCENDING",
"relative_orbit": "40",
"absolute_orbit": "...",
"start_time_utc": "...",
"stop_time_utc": "...",
"source_archive_path": "...zip",
"safe_dir": "...SAFE",
"manifest_path": "...manifest.safe",
"orbit_file_path": "...EOF",
"footprint": {},
"available_subswaths": ["IW1", "IW2", "IW3"],
"burst_index_summary": {}
}
7.3 Stack 分组规则
Sentinel-1 stack candidate 必须满足:
- 同
sensor_family = S1。 - 同
acquisition_mode = IW。 - 同
orbit_direction。 - 同
relative_orbit。 - 同 polarization,第一阶段建议只支持
VV。 - 所有 scene 都有匹配 EOF。
- 所有 scene 与 AOI 有交集。
- 能解析出共同 subswath 和 burst key。
- 不需要跨 swath/burst/相邻 slice 拼接。
不满足第 8、9 条时,不应尝试自动修复,直接输出:
status = NOT_READY_REQUIRES_STITCHING
或者拆成多个候选:
s1_rel040_asc_iw2_burst_013
s1_rel040_asc_iw2_burst_014
每个候选独立生产,不做最终合成。
8. 无拼接策略
本文中的“不支持拼接”定义如下:
- 不把相邻 Sentinel-1 产品 slice 合成一个输入。
- 不把多个 subswath 合成一个输入。
- 不把多个 burst 的结果合成一个输出。
- 不把多个独立 SBAS run 的 GeoTIFF 合成一个产品。
第一阶段最稳策略是 single_subswath_single_burst:
stack geometry = relative orbit + direction + IW subswath + burst key
如果 AOI 跨多个 burst,系统给出多个独立候选。用户可以分别生产和查看,但系统不拼接。
这样牺牲覆盖范围,但能显著降低 TOPS 拼接、边界相位、burst overlap 和几何一致性的风险。
9. Sentinel-1 Workflow 阶段
新增 Sentinel-1 专用 workflow 模板,不修改 LT-1 模板。
建议阶段:
01_workspace_data
02_import_s1_slc
03_select_single_burst
04_reference_mli
05_baseline_audit
06_coregister_scenes
07_rdc_dem
08_diff_network
09_filter_unwrap
10_detrend_atm
11_sbas_inversion
12_publish_products
13_monitor_points
与 LT-1 的主要差异在前半段:
- LT-1:
par_LT1_SLC+ LT-1 txt 精轨。 - S1:ZIP/SAFE + EOF + TOPS/burst 选择。
后半段可复用 Gamma DIFF/IPTA 的思想,但脚本仍建议独立生成,避免 LT-1 和 S1 共用同一个 shell 模板。
10. 脚本隔离设计
LT-1 当前脚本路径保持不变:
scripts/01_workspace_data.sh
scripts/02_import_lt1_slc.sh
...
Sentinel-1 使用独立命名:
scripts/s1/01_workspace_data.sh
scripts/s1/02_import_s1_slc.sh
scripts/s1/03_select_single_burst.sh
scripts/s1/04_reference_mli.sh
...
run_manifest.json 中明确记录:
{
"profile_code": "s1_gamma_sbas",
"sensor_family": "S1",
"stitching_policy": "disabled",
"stack_geometry_policy": "single_subswath_single_burst"
}
11. 产物与 Catalog
Sentinel-1 产物仍进入 SBAS catalog,但必须带 profile 和 sensor 标签:
{
"catalog_name": "sbas_insar",
"product_family": "timeseries",
"processor_code": "gamma_ipta_sbas",
"profile_code": "s1_gamma_sbas",
"sensor_family": "S1"
}
核心资产仍保持现有约定:
publish/geotiff/los_rate_toward_m_per_year.tif
publish/geotiff/los_rate_away_m_per_year.tif
publish/geotiff/los_sigma_m_per_year.tif
publish/geotiff/los_rate_toward_m_per_year.hls.geo_preview.png
publish/geotiff/los_sigma_m_per_year.cc.geo_preview.png
publish/vectors/los_rate_points.geojson.gz
publish/monitor_points/*
产品目录建议按 profile 分层,避免和 LT-1 混在一起:
D:\production_results\timeseries\sbas
|-- lt1_gamma_sbas
| `-- <run_id>
`-- s1_gamma_sbas
`-- <run_id>
如果短期不改目录,也必须在 manifest/catalog 中保留 profile_code,前端筛选时不能只看 product family。
12. 前端设计
SBAS-InSAR Production 增加 profile 选择:
数据类型:
[ LT-1 Gamma SBAS ] [ Sentinel-1 Gamma SBAS ]
默认仍是 LT-1。
Sentinel-1 页面提示:
当前 Sentinel-1 Gamma SBAS 使用无拼接策略。
仅支持同轨同向、同 relative orbit、同 subswath、同 burst 的稳定候选序列。
跨 burst / 跨 subswath / 相邻 slice 自动拼接暂不支持。
候选列表增加字段:
- sensor family
- satellite
- acquisition mode
- relative orbit
- orbit direction
- polarization
- subswath
- burst key
- stitching policy
- missing EOF count
如果候选需要拼接,按钮置灰,原因显示为 需要拼接,当前策略不支持。
13. 稳定性护栏
13.1 不影响 LT-1 的护栏
- 默认 profile 不变。
- LT-1 常量、模板、脚本文件名不改。
- Sentinel-1 代码放到新 adapter 和新脚本模板中。
GAMMA_SBAS_S1_ENABLED=false时前端不展示 S1。- LT-1 的单元测试和脚本快照测试必须先通过。
13.2 Sentinel-1 提交前校验
提交生产前必须全部通过:
source ZIP/SAFE exists
EOF exists for every scene
same relative orbit
same orbit direction
same acquisition mode
same polarization
same subswath
same burst key
scene count >= minimum
no stitching required
DEM coverage exists
AOI intersects all selected scenes
任一失败,禁止提交 workflow job。
13.3 执行阶段校验
每阶段输出必须有 manifest 记录:
stage_status.json
stage stdout/stderr log
expected outputs
missing outputs
quality flags
Sentinel-1 首批样本不自动发布到正式 catalog。建议先生成 run artifact,人工确认后再开启 publish。
14. 实施阶段
Phase 0:文档和开关
- 新增本文档。
- 新增配置项设计。
- S1 默认关闭。
Phase 1:Profile 框架拆分
- 新增
GammaSbasProfile基类。 - 当前 LT-1 逻辑包一层
Lt1GammaSbasProfile。 - 保证 LT-1 行为不变。
- 增加 LT-1 脚本快照测试。
Phase 2:Sentinel-1 Discovery
- 实现
S1GammaSbasProfile.discover_scenes。 - 优先读取 source/orbit asset inventory。
- 输出 S1 stack candidates。
- 对需要拼接的候选输出
NOT_READY_REQUIRES_STITCHING。
Phase 3:Sentinel-1 Planning Run
- 能创建
s1_gamma_sbasplanning run。 - 能生成
run_manifest.json、stack_manifest.json、gamma_command_manifest.json。 - 只生成脚本,不执行 Gamma。
Phase 4:Sentinel-1 Script Dry Run
- 生成
scripts/s1/*.sh。 - 在样本数据上执行到导入和 reference MLI。
- 验证 no-stitch 限制是否真实有效。
Phase 5:Sentinel-1 Workflow 执行
- 执行 coreg、RDC DEM、diff、unwrap、detrend、IPTA。
- 先不自动发布正式 catalog。
- 输出质量报告和人工验收包。
Phase 6:Catalog 发布和前端展示
- Sentinel-1 样本通过后开启 publish。
- 前端结果页支持 profile/sensor 筛选。
- 产品详情显示
stitching_policy=disabled。
15. 验收标准
15.1 LT-1 回归
- LT-1 discovery 结果不变。
- LT-1 run manifest 关键字段不变。
- LT-1 脚本输出与改造前一致。
- LT-1 样本能继续跑通。
- LT-1 catalog 结果不受 S1 profile 影响。
15.2 Sentinel-1 最小可用
- 能发现 Sentinel-1 候选 stack。
- 能绑定 EOF。
- 能拒绝需要拼接的候选。
- 能生成 S1 planning run 和脚本。
- 能在一个单 subswath / 单 burst 样本上跑通 workflow。
- 输出标准 SBAS 产品资产。
- Catalog 中能按
profile_code=s1_gamma_sbas查询。
16. 风险与取舍
16.1 覆盖范围变小
不拼接意味着 AOI 覆盖能力会变弱。跨 burst 或跨 subswath 的区域不会自动合成,只能拆成多个独立结果查看。
这是稳定性优先的取舍。
16.2 Sentinel-1 TOPS 复杂度高
Sentinel-1 TOPS 的 burst、Doppler、coregistration 对脚本稳定性要求高。第一阶段不应追求通用覆盖,应先让单一稳定样本跑通。
16.3 Gamma 命令版本差异
Sentinel-1 导入和 TOPS 处理命令需要以生产服务器安装的 Gamma 版本为准。脚本模板中所有 Sentinel-1 命令必须经过样本数据验证后再开放。
16.4 不共享脚本导致代码冗余
本设计接受冗余。相比强行抽象共用,冗余脚本更容易保证 LT-1 不被影响,也更容易单独回滚 Sentinel-1。
17. 回滚策略
如果 Sentinel-1 profile 出现问题:
- 设置
GAMMA_SBAS_S1_ENABLED=false。 - 前端隐藏 Sentinel-1 profile。
- Runtime 白名单保留不影响 LT-1。
- 已生成的 S1 run 保留为实验记录,不进入正式 catalog。
- LT-1 profile 不需要回滚。
18. 推荐下一步
- 先实现 profile 拆分,但不改 LT-1 行为。
- 准备一个 Sentinel-1 最小样本集:同 relative orbit、同方向、同 polarization、同 subswath、同 burst key,至少 8 景。
- 只实现 discovery + planning run。
- 人工核对
gamma_command_manifest.json和scripts/s1/*.sh。 - 再进入 Gamma 实际执行阶段。