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

542 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 并列方案:
```text
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 硬编码:
```text
_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。
建议模块:
```text
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
```
核心接口建议:
```python
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`
```json
{
"profile_code": "lt1_gamma_sbas",
"source_roots": [],
"orbit_roots": [],
"admin_region": "",
"discovery_mode": "strict",
"aoi_bbox": null
}
```
默认值为 `lt1_gamma_sbas`。这样老前端和老调用不受影响。
新增 Sentinel-1 时使用:
```json
{
"profile_code": "s1_gamma_sbas",
"source_roots": ["D:\\Sentinel1_Image_Pool_ZIP"],
"orbit_roots": ["D:\\Sentinel1_Orbit_Pool"],
"admin_region": "..."
}
```
### 6.2 配置项
新增配置建议:
```text
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
```text
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 描述结构至少包含:
```json
{
"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 条时,不应尝试自动修复,直接输出:
```text
status = NOT_READY_REQUIRES_STITCHING
```
或者拆成多个候选:
```text
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`
```text
stack geometry = relative orbit + direction + IW subswath + burst key
```
如果 AOI 跨多个 burst,系统给出多个独立候选。用户可以分别生产和查看,但系统不拼接。
这样牺牲覆盖范围,但能显著降低 TOPS 拼接、边界相位、burst overlap 和几何一致性的风险。
## 9. Sentinel-1 Workflow 阶段
新增 Sentinel-1 专用 workflow 模板,不修改 LT-1 模板。
建议阶段:
```text
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 精轨。
- S1ZIP/SAFE + EOF + TOPS/burst 选择。
后半段可复用 Gamma DIFF/IPTA 的思想,但脚本仍建议独立生成,避免 LT-1 和 S1 共用同一个 shell 模板。
## 10. 脚本隔离设计
LT-1 当前脚本路径保持不变:
```text
scripts/01_workspace_data.sh
scripts/02_import_lt1_slc.sh
...
```
Sentinel-1 使用独立命名:
```text
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` 中明确记录:
```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 标签:
```json
{
"catalog_name": "sbas_insar",
"product_family": "timeseries",
"processor_code": "gamma_ipta_sbas",
"profile_code": "s1_gamma_sbas",
"sensor_family": "S1"
}
```
核心资产仍保持现有约定:
```text
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 混在一起:
```text
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 选择:
```text
数据类型:
[ LT-1 Gamma SBAS ] [ Sentinel-1 Gamma SBAS ]
```
默认仍是 LT-1。
Sentinel-1 页面提示:
```text
当前 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 提交前校验
提交生产前必须全部通过:
```text
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 记录:
```text
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.json``stack_manifest.json``gamma_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.json``scripts/s1/*.sh`
5. 再进入 Gamma 实际执行阶段。