Files
insar-management-system-v2/docs/SENTINEL1_GAMMA_SBAS_NO_STITCH_DESIGN.md
T

15 KiB
Raw Blame History

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-1S1s1_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 目标

  1. 新增 Sentinel-1 Gamma SBAS profile,入口可发现 Sentinel-1 候选 stack。
  2. Sentinel-1 使用 ZIP/SAFE + EOF 资产,不走 LT-1 tiff/meta.xml/txt orbit 逻辑。
  3. 不支持拼接。第一阶段只支持单轨、同向、同 relative orbit、同 acquisition mode、同 polarization、同 subswath、同 burst 或同一稳定 burst key 的 stack。
  4. 对需要拼接才能覆盖 AOI 的数据,系统不自动拼接,改为拆成多个独立候选 stack 或直接标记为 NOT_READY_REQUIRES_STITCHING
  5. LT-1 现有生产效果不变,默认入口仍可继续跑现有 LT-1 数据。
  6. Sentinel-1 先做严格、保守、可解释的生产链,允许代码冗余,避免为了共用而引入隐性耦合。

3.2 非目标

  1. 不支持 Sentinel-2 光学时序。
  2. 不支持跨轨、跨 relative orbit、升降轨混合。
  3. 不支持跨 swath 拼接。
  4. 不支持跨 burst 拼接。
  5. 不支持相邻 Sentinel-1 slice/frame 自动拼接。
  6. 不把多个独立 Sentinel-1 SBAS 结果镶嵌成一张最终产品。
  7. 不改现有 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 必须满足:

  1. sensor_family = S1
  2. acquisition_mode = IW
  3. orbit_direction
  4. relative_orbit
  5. 同 polarization,第一阶段建议只支持 VV
  6. 所有 scene 都有匹配 EOF。
  7. 所有 scene 与 AOI 有交集。
  8. 能解析出共同 subswath 和 burst key。
  9. 不需要跨 swath/burst/相邻 slice 拼接。

不满足第 8、9 条时,不应尝试自动修复,直接输出:

status = NOT_READY_REQUIRES_STITCHING

或者拆成多个候选:

s1_rel040_asc_iw2_burst_013
s1_rel040_asc_iw2_burst_014

每个候选独立生产,不做最终合成。

8. 无拼接策略

本文中的“不支持拼接”定义如下:

  1. 不把相邻 Sentinel-1 产品 slice 合成一个输入。
  2. 不把多个 subswath 合成一个输入。
  3. 不把多个 burst 的结果合成一个输出。
  4. 不把多个独立 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-1par_LT1_SLC + LT-1 txt 精轨。
  • S1ZIP/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 的护栏

  1. 默认 profile 不变。
  2. LT-1 常量、模板、脚本文件名不改。
  3. Sentinel-1 代码放到新 adapter 和新脚本模板中。
  4. GAMMA_SBAS_S1_ENABLED=false 时前端不展示 S1。
  5. 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 1Profile 框架拆分

  • 新增 GammaSbasProfile 基类。
  • 当前 LT-1 逻辑包一层 Lt1GammaSbasProfile
  • 保证 LT-1 行为不变。
  • 增加 LT-1 脚本快照测试。

Phase 2Sentinel-1 Discovery

  • 实现 S1GammaSbasProfile.discover_scenes
  • 优先读取 source/orbit asset inventory。
  • 输出 S1 stack candidates。
  • 对需要拼接的候选输出 NOT_READY_REQUIRES_STITCHING

Phase 3Sentinel-1 Planning Run

  • 能创建 s1_gamma_sbas planning run。
  • 能生成 run_manifest.jsonstack_manifest.jsongamma_command_manifest.json
  • 只生成脚本,不执行 Gamma。

Phase 4Sentinel-1 Script Dry Run

  • 生成 scripts/s1/*.sh
  • 在样本数据上执行到导入和 reference MLI。
  • 验证 no-stitch 限制是否真实有效。

Phase 5Sentinel-1 Workflow 执行

  • 执行 coreg、RDC DEM、diff、unwrap、detrend、IPTA。
  • 先不自动发布正式 catalog。
  • 输出质量报告和人工验收包。

Phase 6Catalog 发布和前端展示

  • Sentinel-1 样本通过后开启 publish。
  • 前端结果页支持 profile/sensor 筛选。
  • 产品详情显示 stitching_policy=disabled

15. 验收标准

15.1 LT-1 回归

  1. LT-1 discovery 结果不变。
  2. LT-1 run manifest 关键字段不变。
  3. LT-1 脚本输出与改造前一致。
  4. LT-1 样本能继续跑通。
  5. LT-1 catalog 结果不受 S1 profile 影响。

15.2 Sentinel-1 最小可用

  1. 能发现 Sentinel-1 候选 stack。
  2. 能绑定 EOF。
  3. 能拒绝需要拼接的候选。
  4. 能生成 S1 planning run 和脚本。
  5. 能在一个单 subswath / 单 burst 样本上跑通 workflow。
  6. 输出标准 SBAS 产品资产。
  7. 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 出现问题:

  1. 设置 GAMMA_SBAS_S1_ENABLED=false
  2. 前端隐藏 Sentinel-1 profile。
  3. Runtime 白名单保留不影响 LT-1。
  4. 已生成的 S1 run 保留为实验记录,不进入正式 catalog。
  5. LT-1 profile 不需要回滚。

18. 推荐下一步

  1. 先实现 profile 拆分,但不改 LT-1 行为。
  2. 准备一个 Sentinel-1 最小样本集:同 relative orbit、同方向、同 polarization、同 subswath、同 burst key,至少 8 景。
  3. 只实现 discovery + planning run。
  4. 人工核对 gamma_command_manifest.jsonscripts/s1/*.sh
  5. 再进入 Gamma 实际执行阶段。