Add Gamma SBAS production workflow

This commit is contained in:
2026-05-21 04:53:39 +08:00
parent 9000feeee8
commit cc22b9ac2d
46 changed files with 11386 additions and 332 deletions
@@ -0,0 +1,515 @@
# 洪涝模块 GeoTIFF 化与 GAMMA 前处理评估
更新日期:2026-05-15
## 1. 结论
洪涝模块后续应把业务算法全部下放到标准 GeoTIFF 层:
```text
原始 SAR 数据
-> 可插拔前处理器:GAMMA 优先,其他处理器兜底
-> 分析级 GeoTIFF
-> Python 水体提取 / 洪涝检测 / 套合分析 / 产品生成
```
ENVI/SARscape 不再作为洪涝算法主线。它可以短期保留为历史兼容处理器,但不应继续决定数据模型、接口命名和算法逻辑。
GAMMA 适合作为第一候选前处理底座,原因是当前项目已经具备 WSL、PyINT、GAMMA 环境注入、DEM、`geocode_back``data2geotiff` 和 D-InSAR 生产发布经验。但现有 GAMMA/PyINT 接入是 D-InSAR pair 流程,不是洪涝需要的“单景分析级 GeoTIFF 预处理服务”。因此不能直接把 `lt1_gamma_dinsar``s1_gamma_dinsar` 原样接到洪涝预处理按钮上,必须新增单景前处理适配层。
## 2. 当前真实情况
### 2.1 洪涝模块当前仍绑定 ENVI/SARscape
当前 `/flood/preprocess` 最终仍执行旧的 `water_service.run_geocoding_workflow()`,内部流程是:
```text
SARsImportLuTan1
-> SARsBasicMultilooking
-> SARsBasicGeocoding
```
输出写入 `SARSceneGeoORM.geo_path`,语义是 SARscape 地理编码 dB 影像 base path,不是标准 GeoTIFF 交付物。
当前 `/flood/detections` 后台任务仍调用 `water_service.run_flood_detection()`,内部流程是:
```text
SARsBasicFeFloodingClassification
-> 可选 SARsBasicFeFloodingClassificationRefinement
-> rasterio 统计分类结果面积
```
分类值约定是:
```text
0 = 无数据 / 背景
1 = 稳定水体
2 = 洪涝 / 新增水体
3 = 高散射点
4 = 非水体
```
这说明当前“洪涝检测算法”实际是 SARscape 黑盒,不是平台自有算法。
### 2.2 已经接近目标形态的部分
以下部分已经更接近“标准栅格 + Python 算法”的目标:
```text
水体提取:
water_extraction_service -> water_detect_service
Otsu + DEM/坡度约束 + 形态学 + 连通分量过滤
套合分析:
flood_overlay_service
读取 classified 栅格,class=2 转矢量,套合灾害点、DInSAR 产品和 AOI
GF3
gf3_service
Python/GDAL 完成 L1A -> L2:辐射定标 + RPC 几何校正
```
其中 GF3 路线虽然不走 GAMMA,但输出理念已经是“处理到 GeoTIFF 后进入平台算法”。它应该作为 `external/gdal` 前处理器接入统一 Scene,而不是继续挂在 `/water/gf3-process` 下。
### 2.3 当前 GAMMA/PyINT 接入情况
当前仓库里的 GAMMA/PyINT 能力主要服务 D-InSAR 生产:
```text
backend/app/dinsar_engines/pyint_engine.py
- lt1_gamma_dinsar
- s1_gamma_dinsar
backend/app/pyint_pipeline/run_lt1_pyint_pipeline.py
- LT-1 托管 runner
- geocode_gamma.py
- data2geotiff
- 标准产品发布
backend/app/pyint_pipeline/run_s1_pyint_pipeline.py
- Sentinel-1 runner
- 复用 LT-1 runner 的日志、发布和质量检查框架
deploy/wsl/profiles/gamma_env.sh
- 注入 GAMMA_HOME
- 注入 GAMMA 各模块 bin/scripts
- 注入 third_party/PyINT/pyint
```
当前 `.env` 中 PyINT/GAMMA 是启用状态:
```text
PYINT_ENABLED=true
PYINT_WSL_DISTRO=Ubuntu-24.04
PYINT_WSL_PYTHON=/home/administrator/miniconda3/envs/insar_wsl_v1/bin/python
PYINT_DEM_MODE=prepared_file
PYINT_PREPARED_DEM_PATH=D:\DEM\SRTMDEM_RSP_SARscape.wgs84
PYINT_GEO_INTERP=1
PYINT_GAMMA_NODATA_VALUE=-9999.0
```
需要注意一个不一致点:`pyint_engine.py` 已经暴露 `s1_gamma_dinsar`,但 `wsl_runtime_registry.py` 当前允许的 PyINT operation 仍只有 `lt1_gamma_dinsar``gamma_refine`。如果后续洪涝或生产任务走 WSL Broker,需要同步补齐允许列表。
### 2.4 GAMMA 现有输出与洪涝需求的差距
现有 D-InSAR GAMMA 链已经能导出 GeoTIFF,但输出重点是 pair 产品:
```text
disp.tif
disp_unmasked.tif
coh.tif
wrapped_phase.tif
vertical displacement
look vector
```
`hyp3format_gamma.py` 也能把 `geocode_gamma.py` 产生的 geocoded GAMMA 二进制导出为 GeoTIFF,包含:
```text
amp
corr
dem
unw_phase
wrapped_phase
los_disp
vert_disp
lv_theta
lv_phi
```
但洪涝模块真正需要的是单景产品:
```text
analysis_ready.tif
- 单景后向散射强度
- 明确单位:sigma0_db / gamma0_db / power_db
- 明确极化:VV / VH / HH / HV
- 明确 CRS、分辨率、nodata、覆盖范围
- 可与另一景重采样到同一网格
```
当前没有一个独立的 `gamma_single_scene_preprocess` 服务稳定地产出上述文件。现有 D-InSAR 流程里的 `geo_<master>_*.amp` 可以证明 GAMMA 有地理编码 MLI/AMP 的能力,但它嵌在 pair 配准和干涉流程中,不能直接作为洪涝单景预处理接口。
## 3. 目标数据契约
后续洪涝模块不再以 `geo_path` 表示模糊的“地理编码产物”,而应引入明确的分析级 Scene 产物语义。
建议模型命名:
```text
SarAnalysisScene / AnalysisReadyScene
```
最小字段:
```text
id
radar_data_id
engine # gamma / gf3_gdal / snap / envi_legacy / external
engine_profile # lt1_gamma_scene / s1_gamma_scene / gf3_rpc_l2
analysis_tif_path # 主分析 GeoTIFF
preview_path
coverage_polygon
satellite
satellite_family # LT1 / S1 / GF3 / ...
imaging_date
polarization
orbit_direction
relative_orbit
backscatter_unit # sigma0_db / gamma0_db / power_db / unknown
crs
pixel_size_x
pixel_size_y
nodata_value
grid_id # 同网格配对时使用
dem_path
incidence_angle_tif_path # 可选
layover_shadow_mask_path # 可选
quality_json
lineage_json
status
error_msg
created_at
updated_at
```
输出文件要求:
```text
analysis_ready.tif:
- GeoTIFF,优先 COG
- float32
- nodata = -9999
- 推荐值域为 dB
- rasterio/GDAL 可直接读取
preview.png:
- 仅用于地图快视
metadata.json:
- 记录处理器、命令、输入资产、DEM、参数、软件版本、质量检查
```
## 4. 目标流水线
### 4.1 前处理器只负责到 GeoTIFF 为止
前处理器接口建议统一为:
```text
submit_scene_preprocess(radar_data_id, engine="gamma", profile="auto")
```
处理器职责:
```text
1. 识别输入资产和传感器类型。
2. 导入原始产品到处理器内部格式。
3. 做必要的辐射定标。
4. 做多视 / 滤波 / speckle 控制。
5. 使用 DEM 做地形校正或地理编码。
6. 导出 analysis_ready.tif。
7. 生成 coverage、preview、metadata、quality。
8. 注册 SarAnalysisScene。
```
处理器不负责:
```text
1. 水体提取。
2. 洪涝分类。
3. 洪涝矢量化。
4. 灾害点套合。
5. 报告生成。
```
### 4.2 洪涝算法只认 GeoTIFF
水体提取:
```text
analysis_ready.tif
-> 读取 dB 栅格
-> 有效像元 / nodata / DEM / 坡度约束
-> Otsu 或自适应阈值
-> 形态学与连通域过滤
-> water_mask.tif + water_vector.geojson
```
洪涝检测:
```text
pre analysis_ready.tif
post analysis_ready.tif
-> 检查 CRS / 分辨率 / 极化 / 覆盖范围
-> 重采样到同一网格
-> 分别生成 pre_water_mask / post_water_mask
-> post_water && !pre_water = 洪涝 / 新增水体
-> pre_water && post_water = 稳定水体
-> 结合 dB 差值、DEM 坡度、连通域和面积阈值过滤
-> classified.tif
```
建议分类值继续沿用现有约定,降低前端和套合分析改动量:
```text
0 = nodata
1 = stable_water
2 = flood
3 = high_scatter_or_uncertain
4 = non_water
```
套合分析:
```text
classified.tif
-> class=2 转矢量
-> 灾害点命中
-> 近洪涝风险点
-> DInSAR 产品 footprint 相交
-> AOI / 行政区面积统计
```
## 5. GAMMA 适配性判断
| 能力项 | 当前情况 | 适配判断 |
| --- | --- | --- |
| WSL/GAMMA 环境 | 已有 `gamma_env.sh`,能注入 GAMMA 与 PyINT 路径 | 可复用 |
| LT-1 导入 | 已有 `down2slc_LT1_*` 与精轨桥接,历史上处理过几何问题 | 可作为第一批验证对象,但需专项 QA |
| Sentinel-1 导入 | PyINT 脚本支持 ZIP、EOF、burst、TOPS 相关流程,项目已有 `s1_gamma_dinsar` runner | 可做第二批,但 runtime operation 白名单需补齐 |
| GF3 | 当前项目已有 Python/GDAL L1A->L2,不依赖 GAMMA | 不建议强行走 GAMMA,先走 `gf3_gdal` 处理器 |
| 地理编码 | 已有 `geocode_gamma.py``geocode_back`、DEM 生成链 | 可复用思想和部分脚本 |
| GeoTIFF 导出 | 已有 `data2geotiff`、HyP3/标准产品导出经验 | 可复用 |
| 单景分析级输出 | 当前没有独立服务,D-InSAR 中只顺带产出 master amp | 需要新建 |
| 辐射定标语义 | Sentinel-1 导入使用 calibration XMLLT-1/GF3 各有差异 | 必须在 metadata 中明确单位,不能含糊写 dB |
| 生产稳定性 | 当前 D-InSAR runner 已有日志、repair、quality、manifest | 可复用框架,但不能复用 pair 假设 |
结论:GAMMA 适合做洪涝模块的优先前处理引擎,但第一阶段目标应是:
```text
LT-1 单景 -> GAMMA -> analysis_ready.tif
```
跑通并验证后再扩展:
```text
Sentinel-1 ZIP -> GAMMA -> analysis_ready.tif
GF3 L1A -> gf3_gdal -> analysis_ready.tif
```
## 6. 不应采用的方案
### 6.1 不应继续以 ENVI/SARscape 作为洪涝主线
原因:
```text
1. 数据格式和任务对象绑定 SARscape。
2. 洪涝分类是黑盒,难以解释和调参。
3. 服务器部署依赖重。
4. 后续多源数据扩展会反复补导入适配器。
5. 输出不天然适合平台统一发布。
```
### 6.2 不应把洪涝算法绑定到 GAMMA
GAMMA 应只负责把原始 SAR 处理成标准 GeoTIFF。洪涝算法不能依赖 GAMMA 中间二进制,也不能要求输入来自 GAMMA。否则只是把“绑定 ENVI”换成“绑定 GAMMA”。
正确边界是:
```text
GAMMA / GF3_GDAL / SNAP / ISCE / external
-> analysis_ready.tif
-> 同一套 Python 洪涝算法
```
### 6.3 不应直接复用 D-InSAR pair profile 做单景预处理
现有 `lt1_gamma_dinsar` / `s1_gamma_dinsar` 是 pair 生产 profile,包含:
```text
master/slave
coreg
diff
unwrap
geocode pair products
disp/coh export
```
洪涝单景预处理只需要:
```text
single scene import
radiometric calibration
multilook/filter
terrain correction/geocoding
GeoTIFF export
QA/register
```
两者不能混成一个 profile。
## 7. 建议实施阶段
### Phase 1:建立 GeoTIFF 数据契约
```text
1. 新建或扩展 Scene 表,明确 analysis_tif_path。
2. 保留旧 SARSceneGeoORM.geo_path 兼容字段。
3. /flood/scenes 改为优先返回 analysis_tif_path。
4. 前端把“可处理”判断改为是否存在 analysis_ready scene。
```
### Phase 2:先把洪涝检测改成 Python GeoTIFF 算法
```text
1. 新建 flood_detection_service.py。
2. 输入 pre_scene.analysis_tif_path 和 post_scene.analysis_tif_path。
3. 对齐网格。
4. 复用水体提取算法生成 pre/post water mask。
5. 输出 classified.tif。
6. 统计 flood_area_km2 和 stable_water_area_km2。
```
这一步可以先用 ENVI 现有 geocode 结果或 GF3 L2 GeoTIFF 做输入测试,目的是先解除洪涝分类对 SARscape 的依赖。
### Phase 3:新增 GAMMA LT-1 单景前处理器
建议新增:
```text
backend/app/services/sar_scene_preprocess_service.py
backend/app/services/gamma_scene_preprocess_service.py
backend/app/pyint_pipeline/run_gamma_scene_preprocess.py
```
最小 runner
```text
1. stage LT-1 输入资产。
2. 调用 LT-1 导入脚本,产出 SLC。
3. multi_look 生成 MLI/AMP。
4. generate_rdc_dem 或等价 DEM 几何。
5. geocode_back 把 AMP 映射到地理网格。
6. data2geotiff 输出 analysis_ready.tif。
7. 可选转 COG。
8. rasterio 质量检查。
```
### Phase 4:接 Sentinel-1 和 GF3
Sentinel-1
```text
1. 复用 Sentinel-1 ZIP/SAFE/EOF 管理设计。
2. 新增 s1_gamma_scene profile。
3. 不走 diff/unwrap,只产出单景 analysis_ready.tif。
4. 修正 WSL runtime operation 白名单。
```
GF3
```text
1. 保留 gf3_service.py 的 GDAL/RPC 路线。
2. 输出注册为 analysis_ready scene。
3. 不强行改成 GAMMA。
```
### Phase 5:退役 ENVI 洪涝主线
```text
1. `/flood/detections` 默认使用 GeoTIFF 算法。
2. ENVI/SARscape 作为 `envi_legacy` 处理器保留一段时间。
3. 新任务不再默认创建 SARscape 洪涝分类。
4. 文档、界面和部署说明移除“ENVI 是洪涝必须项”的表述。
```
## 8. 验收标准
### 8.1 Scene 前处理
```text
1. 任意一个完成的 analysis_ready.tif 可以被 rasterio 打开。
2. CRS、bounds、transform、nodata 完整。
3. 有效像元比例达到阈值。
4. dB 值域在合理范围内。
5. metadata.json 能追溯输入资产、处理器、DEM、命令和版本。
6. preview 和 coverage 能在地图上显示和清除。
```
### 8.2 洪涝检测
```text
1. pre/post 两个 GeoTIFF 可自动对齐到同一网格。
2. classified.tif 只依赖 Python/rasterio/numpy/scipy/skimage,不调用 ENVI/SARscape。
3. class=1/2 面积统计稳定。
4. 套合分析可直接读取 classified.tif。
5. 同一算法能跑 GAMMA TIF、GF3 L2 TIF 和其他外部 TIF。
```
### 8.3 GAMMA 适配
```text
1. LT-1 单景 GAMMA 前处理能稳定产出 analysis_ready.tif。
2. 失败时有明确阶段日志,不出现“任务成功但全 0”的假成功。
3. data2geotiff 输出通过 GDAL/rasterio 质量检查。
4. 处理器输出不要求后续算法知道 GAMMA 中间目录结构。
```
## 9. 对部署的影响
Git 可以提供平台代码、Python 算法、任务编排、数据库迁移和前端能力,但不能内置 GAMMA 商业软件本体。另一台服务器部署时必须额外满足:
```text
1. WSL 或 Linux 环境可用。
2. GAMMA 安装路径可被 gamma_env.sh 发现,或配置 PYINT_GAMMA_HOME/GAMMA_HOME。
3. PyINT 代码随仓库存在。
4. WSL Python/conda 环境具备 rasterio、GDAL、numpy、scipy、skimage 等依赖。
5. DEM、轨道池和源数据池路径在 .env 中配置。
```
如果目标服务器没有 GAMMA,系统仍应允许:
```text
1. 使用已经存在的 analysis_ready.tif。
2. 使用 GF3_GDAL 处理器。
3. 后续接 SNAP/ISCE/external 处理器。
4. 继续执行水体提取、洪涝检测、套合分析和产品生成。
```
这也是把算法下放到 GeoTIFF 层的核心价值。
## 2026-05-16 implementation note
The first code pass now implements LT1 and GF3 as analysis-ready scene preprocessors:
- New config roots: `SAR_ANALYSIS_READY_ROOT`, `SAR_ANALYSIS_WORK_ROOT`, `SAR_ANALYSIS_PREVIEW_ROOT`.
- `sar_scene_geo` now stores `analysis_tif_path`, `analysis_dir`, preview path, engine/profile, backscatter unit, nodata, metadata and quality JSON.
- `/flood/preprocess` routes GF3 scenes to `gf3_gdal` standardization and LT1 scenes to `lt_gamma` single-scene preprocessing.
- GF3 uses the existing GDAL/RPC L1A->L2 result, then registers the selected L2 GeoTIFF under `SAR_ANALYSIS_READY_ROOT`.
- LT1 uses a new Gamma/PyINT runner that stops at single-scene geocoded MLI GeoTIFF and does not write into D-InSAR product directories.
- Water extraction, flood detection and scene previews now prefer `analysis_tif_path` and fall back to legacy `geo_path`.
- Startup database maintenance now treats Alembic `0004` as the managed head, can auto-add missing ORM columns/indexes, and records the `alembic_version` marker after the schema is healthy.
- `/health?full=true&refresh=true` now includes `sar_analysis_ready` root and scene-path checks.
This keeps D-InSAR product publication isolated from flood/water analysis inputs.
+693
View File
@@ -0,0 +1,693 @@
# 洪涝监测模块整改实施方案
> 日期:2026-05-14
> 目标:将当前分散的水体监测、洪涝检测、GF3 处理和结果管理,收敛为可部署、可维护、可扩展的洪涝灾害分析流水线。
## 1. 总体原则
1. 新业务统一走 `/flood/*`
2. “水体监测”不再作为独立业务模块出现,只作为“洪涝灾害分析 -> 水体提取”步骤存在。
3. `/water/*` 暂时保留兼容窗口,但标记 deprecated,不再新增功能。
4. 数据库优先新增表和回填数据,避免直接破坏旧表。
5. 每个阶段独立提交,保证任一阶段都能构建、部署和回滚。
## 2. 目标流水线
```text
场景准备 Scene
-> 水体提取 WaterExtraction
-> 洪涝检测 FloodDetection
-> 套合分析 FloodOverlay
-> 洪涝产品 FloodProduct / Report
```
其中水体提取是洪涝分析的前置步骤,不再和洪涝灾害分析并列成两个业务入口。
## 3. 阶段 1:收敛 API 契约
目标:先消灭“前端调用不存在接口”的问题,避免部署后出现静默 404。
修改范围:
```text
frontend/src/api/flood.js
backend/app/routers/flood.py
docs/FLOOD_MODULE_REFACTOR_PLAN_20260514.md
```
处理方式:
- `frontend/src/api/flood.js` 只暴露后端当前真实支持的接口。
- 暂时移除或注释未实现接口,例如 `/flood/sources``/flood/ready-products``/flood/pairs` 保存删除、`/flood/reports``/flood/results`
- 后端 `/flood` 路由继续保留现有功能,但接口命名统一为 `preprocess``scenes``water-extractions``pairs/search``detections``detections/{id}/preview/{layer}`
验收标准:
```text
npm run build 通过
前端 flood API 文件中没有明显会 404 的已导出函数
/flood 主流程现有功能不退化
```
## 4. 阶段 2:新增数据模型
目标:建立洪涝流水线需要的数据承载,不直接破坏旧表。
新增模型:
```text
WaterExtractionORM -> water_extractions
FloodOverlayORM -> flood_overlays
FloodProductORM -> flood_products
```
关键取舍:
- 保留旧 `WaterDetectionORM -> water_detections`
- 新表 `water_extractions` 从旧表回填。
- 后续新任务写入 `water_extractions`
- 旧接口读旧表或兼容映射,等稳定后再清理。
建议字段:
```text
water_extractions:
id
scene_id
processor
task_id
input_path
output_path
preview_path
vector_path
water_area_km2
water_pixel_count
threshold_value
metadata_json
status
error_msg
created_at
updated_at
flood_overlays:
id
detection_id
flood_vector_path
hazard_points_hit
hazard_points_near
hazard_points_total
dinsar_products_intersecting
affected_area_km2
summary_json
created_at
flood_products:
id
product_id
detection_id
overlay_id
display_name
status
publish_dir
manifest_path
summary_json
created_at
```
验收标准:
```text
alembic upgrade head 成功
旧 water_detections 数据可迁移到 water_extractions
模型 import 正常
```
## 5. 阶段 3:抽离 Service
目标:让 `/flood` 成为真正的业务路由,而不是代理 `water.py` 的壳。
新增服务:
```text
backend/app/services/flood_analysis_service.py
backend/app/services/water_extraction_service.py
backend/app/services/flood_product_service.py
backend/app/services/flood_overlay_service.py
```
职责划分:
```text
flood_analysis_service.py
场景列表、预处理提交、配对搜索、洪涝检测提交、检测列表
water_extraction_service.py
Otsu 水体提取、ENVI/SARscape 水体提取
flood_product_service.py
产品列表、manifest、产品包生成
flood_overlay_service.py
分类栅格矢量化、灾害点/DInSAR/AOI 套合
```
完成后:
- `backend/app/routers/flood.py` 不再 `import water as water_compat`
- `backend/app/routers/water.py` 标记 deprecated,后续可反向调用新 service。
- `water_detect_service.py` 逐步迁移到 `water_extraction_service.py`
验收标准:
```text
flood.py 不再 import water.py
/water/* 旧接口仍可用
/flood/* 主接口可用
```
## 6. 阶段 4:补齐产品端点
目标:让“结果与任务”视图有真实后端数据。
主接口建议使用 `products`,避免和 DInSAR result/product 概念混淆:
```text
POST /flood/detections/{id}/products
GET /flood/products
GET /flood/products/{id}
GET /flood/products/{id}/manifest
```
兼容别名可选:
```text
GET /flood/results
GET /flood/results/{id}
GET /flood/results/{id}/manifest
```
验收标准:
```text
前端结果视图能展示真实产品
manifest 能返回 JSON
没有空接口或静默失败
```
## 7. 阶段 5:实现套合分析
目标:把洪涝模块从检测工具提升为灾害分析模块。
新增接口:
```text
POST /flood/detections/{id}/overlay
GET /flood/detections/{id}/impact
```
处理逻辑:
```text
1. 读取 flood_detections.classified_path
2. 提取 class=2 洪涝区域
3. 栅格转矢量
4. 写 flood_overlays.flood_vector_path
5. 查询灾害点命中
6. 查询近邻风险点
7. 查询相交 DInSAR 产品
8. 查询 AI 诊断摘要
9. 写 summary_json
```
注意:
- AOI、PostGIS、DInSAR 产品几何不完整时,不让整个任务失败。
- 返回部分结果,并在 `summary_json.warnings` 中说明缺失项。
验收标准:
```text
POST overlay 能生成 flood_overlays 记录
GET impact 返回结构化 JSON
没有数据时返回空数组而不是 500
```
## 8. 阶段 6:前端重整
目标:只保留一个洪涝灾害分析工作台。
新增目录:
```text
frontend/src/components/flood/
```
建议组件:
```text
FloodStatusBadge.jsx
FloodButton.jsx
FloodSceneRow.jsx
FloodWaterExtractionRow.jsx
FloodDetectionRow.jsx
FloodOverlayPanel.jsx
FloodProductPanel.jsx
```
界面改成四站式:
```text
1. 场景准备
2. 水体提取
3. 洪涝检测
4. 套合与产品
```
处理方式:
- `WaterMonitorPanel.jsx` 加弃用提示。
- 左侧导航只引导用户进入洪涝灾害分析。
- `api/water.js``api/gf3.js` 标记 deprecated。
- 新功能只接入 `api/flood.js`
验收标准:
```text
左侧导航只引导用户进入洪涝灾害分析
水体提取不再作为独立业务重复出现
套合分析和产品视图接真实接口
npm run build 通过
```
## 9. 阶段 7:报告生成壳
目标:先形成 Markdown 报告能力,再扩展 PDF。
新增接口:
```text
POST /flood/reports
GET /flood/reports/{id}
```
第一版报告包含:
```text
灾前/灾后场景信息
洪涝面积
灾害点命中
DInSAR 产品关联
AI 诊断摘要
套合统计
```
## 10. 推荐提交顺序
```text
1. refactor flood api contract
2. add flood pipeline orm models
3. extract flood analysis services
4. add flood product endpoints
5. implement flood overlay impact analysis
6. consolidate flood frontend workspace
7. scaffold flood report generation
```
核心思路:先稳住接口和数据,再拆服务,再补业务能力,最后整理 UI。这样 Git 中的代码、迁移、前端调用和部署环境是闭合的,另一台服务器拉取后不会出现关键页面依赖未实现接口的问题。
## 11. 2026-05-15 补充设计:水体提取、灾害配对与套合展示
本节根据最新审阅意见补充。结论:洪涝工作台不应该继续以“手动选日期范围 + 查配对”为核心,而应该改成“灾害事件驱动”:
```text
灾害时间 + 灾害位置
-> 过滤可用 SAR 场景匹配池
-> 推荐灾前/灾后配对
-> 执行洪涝检测
-> 套合分析
-> 结果展示与产品导出
```
### 11.1 水体提取视图复用管理页能力
当前管理页面已经具备三类能力,洪涝模块应复用,而不是重新做一套弱化版:
1. 雷达数据查询能力:`/radar-data/search` 已支持成像日期、成像模式、极化方式、产品级别、行政区 AOI、上传 AOI 文件。
2. 地图能力:`App.jsx` 中已经有源影像 footprint 上图、源影像预览缓存 `radar-data/{id}/thumb`、地图定位和图层开关逻辑。
3. 行政区 AOI 能力:`/aoi/regions/children``/aoi/regions/{treeId}/geometry` 已可用于按省/市范围查询和定位。
因此水体提取界面调整为:
```text
左侧:场景匹配池
- 灾害位置 / AOI
- 成像日期范围
- 卫星、模式、极化、产品级别
- 只显示有 footprint 的数据
- 可显示源影像预览图
- 显示成像时间、极化方式、成像模式、产品级别
右侧:已完成地理编码场景 / 水体提取结果
- 场景 footprint 上图
- 水体提取掩膜上图
- 与源影像预览可叠加对比
```
前端复用建议:
```text
复用 buildRadarSearchFormData / normalizeRadarSearchCriteria
复用 UnifiedDatePicker
复用 RadarDataRow 的预览状态表达
复用 App.jsx 中 updateRadarPreviewVisibility 的源影像预览图层逻辑
复用行政区 AOI 选择和地图定位逻辑
```
需要新增的洪涝专用组件:
```text
FloodSourceSearchPanel.jsx
封装灾害位置、日期、极化、模式、产品级别过滤。
FloodSourceSceneRow.jsx
显示源影像:成像时间、极化方式、模式、产品级别、预览状态、上图按钮。
FloodWaterExtractionRow.jsx
显示水体提取结果:面积、状态、输入场景、上图按钮、错误信息。
```
地图图层约定:
```text
source_preview:{radar_data_id} 源影像预览
source_footprint:{radar_data_id} 源影像覆盖范围
scene_footprint:{scene_id} 地理编码场景范围
water_mask:{water_extraction_id} 水体提取掩膜
```
### 11.2 洪涝检测配对改为灾害事件驱动
当前 `/flood/pairs/search` 只接收灾前/灾后日期区间和 overlap 阈值,实际使用体验不够:用户通常知道的是“灾害发生时间”和“灾害位置”,不是一开始就知道灾前灾后影像窗口。
新的配对入口应改为:
```text
灾害名称 disaster_name 可选
灾害时间 disaster_date 必填
灾害位置 disaster_aoi 必填,来自行政区 / 地图框选 / 上传 SHP / GeoJSON
灾前窗口 pre_window_days 默认 30 天
灾后窗口 post_window_days 默认 30 天
最小 AOI 覆盖率 min_aoi_coverage_ratio 默认 0.3
最小两景重叠率 min_pair_overlap_ratio 默认 0.5
是否要求同极化 require_same_polarization 默认 true
是否要求同成像模式 require_same_imaging_mode 默认 false
卫星过滤 satellites 可选
极化过滤 polarization 可选
```
前端交互:
```text
1. 用户选择灾害日期
2. 用户选择灾害位置
- 行政区:省 / 市
- 地图框选:后续实现
- 上传 SHP/GeoJSON:沿用现有 AOI 解析
3. 系统自动推导:
- 灾前窗口:disaster_date - pre_window_days 至 disaster_date - 1
- 灾后窗口:disaster_date 至 disaster_date + post_window_days
4. 后端返回:
- pre_pool
- post_pool
- candidate_pairs
- warnings
5. 用户在候选配对中选择一组提交洪涝检测
```
推荐新增接口:
```text
POST /flood/disaster-pairs/search
```
请求格式:
```json
{
"disaster_name": "汶川洪涝",
"disaster_date": "20260715",
"aoi_geojson": {},
"region_tree_id": "510000",
"pre_window_days": 30,
"post_window_days": 30,
"min_aoi_coverage_ratio": 0.3,
"min_pair_overlap_ratio": 0.5,
"require_same_polarization": true,
"require_same_imaging_mode": false,
"satellites": ["LT-1", "GF3"],
"polarization": "VV"
}
```
返回格式:
```json
{
"disaster": {
"name": "汶川洪涝",
"date": "20260715",
"pre_range": ["20260615", "20260714"],
"post_range": ["20260715", "20260814"]
},
"aoi": {
"source": "region",
"name": "汶川县",
"aoi_geojson": {}
},
"pre_pool": [],
"post_pool": [],
"candidate_pairs": [
{
"pre": {
"scene_id": 1,
"radar_data_id": 10,
"imaging_date": "20260701",
"satellite": "LT-1",
"polarization": "VV",
"imaging_mode": "SM",
"aoi_coverage_ratio": 0.82,
"coverage_polygon": []
},
"post": {
"scene_id": 2,
"radar_data_id": 11,
"imaging_date": "20260718",
"satellite": "LT-1",
"polarization": "VV",
"imaging_mode": "SM",
"aoi_coverage_ratio": 0.79,
"coverage_polygon": []
},
"pair_overlap_ratio": 0.91,
"pre_delta_days": 14,
"post_delta_days": 3,
"score": 0.86,
"warnings": []
}
],
"warnings": []
}
```
排序建议:
```text
score =
pair_overlap_ratio * 0.35
+ min(pre_aoi_coverage, post_aoi_coverage) * 0.30
+ time_score * 0.20
+ same_polarization_bonus * 0.10
+ same_mode_bonus * 0.05
```
后端实现建议:
```text
1. 复用 radar search 的 AOI 解析能力,避免重复解析行政区和 SHP。
2. 查询 sar_scene_geo.status=DONE 的场景,并 join radar_data。
3. 按 disaster_date 自动构造灾前/灾后窗口。
4. 用 PostGIS 计算单景 AOI 覆盖率。
5. 用 footprint 相交面积计算 pair_overlap_ratio。
6. 返回匹配池和候选配对,而不是只返回最终 pairs。
```
兼容处理:
```text
旧接口 POST /flood/pairs/search 保留,但只作为手动日期模式。
新工作台默认使用 POST /flood/disaster-pairs/search。
```
### 11.3 套合分析结果展示逻辑
套合分析不能只是一个“运行按钮”。它应展示“为什么这个洪涝结果重要”:
```text
洪涝范围
灾害点命中
近洪涝风险点
DInSAR 产品关联
行政区影响统计
结果图层
产品/报告入口
```
前端 `FloodOverlayPanel.jsx` 设计:
```text
顶部摘要:
- 洪涝面积
- 命中灾害点数量
- 近洪涝风险点数量
- 关联 DInSAR 产品数量
- warnings 数量
中部地图控制:
- 洪涝分类图
- 洪涝矢量范围
- 命中灾害点
- 近洪涝风险点
- DInSAR 产品 footprint
下部结果表:
- 灾害点列表:名称、类型、行政区、距离、是否命中
- DInSAR 产品列表:product_id、engine、形变量、AI 风险等级、预览/详情
- AOI 统计:行政区、洪涝面积、占比
```
后端 `GET /flood/detections/{id}/impact` 应保证即使没有运行套合,也返回稳定结构:
```json
{
"detection_id": 1,
"flood_area_km2": 12.5,
"hazard_points": {
"inside_flood": [],
"near_flood": [],
"total_in_scene": 0
},
"dinsar_products": [],
"affected_aois": [],
"map_layers": {
"classified_preview": true,
"flood_vector_path": null,
"hazard_points": true,
"dinsar_footprints": true
},
"warnings": []
}
```
需要新增或完善的地图层约定:
```text
flood_classified:{detection_id} 洪涝分类栅格预览
flood_vector:{overlay_id} 洪涝矢量面
hazard_inside:{overlay_id} 洪涝范围内灾害点
hazard_near:{overlay_id} 近洪涝风险点
dinsar_intersect:{overlay_id} 相交 DInSAR 产品 footprint
```
### 11.4 前端整改顺序调整
基于以上补充,前端整改顺序调整为:
```text
1. 抽 FloodSourceSearchPanel,复用管理页雷达搜索/AOI 查询。
2. 水体提取页增加源影像预览图、成像时间、极化方式、模式、产品级别。
3. 洪涝检测页改为灾害事件输入:灾害时间 + 灾害位置。
4. 新增 /flood/disaster-pairs/search 后接入候选池和推荐配对。
5. 套合分析页接入 /flood/detections/{id}/overlay 和 /impact。
6. 结果与任务页从 flood_detections 过渡到 flood_products。
```
验收标准补充:
```text
水体提取:
- 能按行政区/上传 AOI 查询源影像
- 能显示源影像预览图
- 列表中显示成像日期、极化方式、成像模式、产品级别
- 水体提取结果可叠加到地图
洪涝检测:
- 用户只需输入灾害时间和灾害位置即可获得匹配池
- 返回 pre_pool/post_pool/candidate_pairs
- 推荐配对可在地图上预览灾前/灾后 footprint
- 配对结果显示时间差、AOI 覆盖率、两景重叠率、极化一致性
套合分析:
- 运行后能看到摘要指标
- 能看到灾害点命中和近邻风险点列表
- 能看到关联 DInSAR 产品列表
- warnings 可见,不静默失败
```
## 12. 2026-05-15 第一轮落地记录
本轮先闭合三条可直接使用的业务链路,不把报告生成和完整产品包导出放进同一次改动。
### 12.1 已落地
后端:
```text
1. 新增 POST /flood/disaster-pairs/search。
输入 disaster_date + region_tree_id/aoi_geojson + 灾前灾后窗口。
输出 pre_pool、post_pool、candidate_pairs、summary、warnings。
2. 水体提取列表补充源影像元数据。
/flood/scenes 与 /flood/water-extractions 现在返回 imaging_date、polarization、
imaging_mode、product_level、coverage_polygon、min/max lon/lat。
3. 套合分析接口保持并接入前端。
POST /flood/detections/{id}/overlay
GET /flood/detections/{id}/impact
```
前端:
```text
1. 洪涝灾害分析 / 水体提取页:
- 复用 AOI 行政区索引。
- 支持按行政区筛选雷达源影像。
- 雷达结果行增加“覆盖”和“源影像”上图。
- 场景/水体结果行显示成像日期、极化方式、模式、产品级别。
2. 洪涝检测页:
- 从手工填写灾前/灾后日期,改为输入灾害名称、灾害发生日期、灾害位置。
- 自动根据窗口期生成灾前池和灾后池。
- 候选配对展示评分、AOI 覆盖率、两景重叠率、灾前/灾后时间差、极化方式。
3. 套合分析页:
- 可运行 overlay。
- 可刷新并展示 impact。
- 展示洪涝面积、命中灾害点、近洪涝风险点、关联 DInSAR 产品和 warnings。
```
### 12.2 当前保留的兼容点
```text
1. GET/POST /water/* 暂未删除,旧页面仍可过渡使用。
2. 旧 POST /flood/pairs/search 保留为手工日期兼容接口,但新工作台默认使用 /flood/disaster-pairs/search。
3. 水体提取任务底层仍写 water_detectionswater_extractions 新表和正式迁移已建模,但任务处理器尚未完全切换。
4. AOI 只先复用行政区查询;上传 SHP/GeoJSON 到洪涝工作台可作为下一步补充。
```
### 12.3 下一轮建议
```text
1. 把水体提取 job handler 从 WaterDetectionORM 切到 WaterExtractionORM。
2. 给候选配对增加地图 footprint 预览按钮,辅助人工确认灾前/灾后覆盖。
3. 把 overlay 生成的 flood_vector_path 也作为地图矢量层显示。
4. 套合分析补行政区受影响面积统计。
5. 结果与任务页开始接 flood_products,而不是只列 flood_detections。
```
@@ -0,0 +1,128 @@
# 洪涝模块整改进展记录
## 2026-05-15 第二轮:水体提取表切换
本轮目标是把洪涝工作台里的水体提取正式从旧 `water_detections`
迁到新 `water_extractions`,同时保留旧 `/water/*` 兼容窗口。
### 已完成
```text
1. 新增 backend/app/services/water_extraction_service.py。
- run_otsu_water_extraction 复用旧 Otsu 实现。
- 对外使用 extraction/processor/threshold_value 命名。
- run_envi_water_extraction 暂留占位,后续接 ENVI/SARscape。
2. /flood/water-extractions 新提交任务开始写 water_extractions。
- 任务 payload 使用 extraction_id。
- WaterExtractionORM.processor 默认 otsu。
- task_id、threshold_value、metadata_json 随任务更新。
3. WATER_DETECT job handler 支持双轨兼容。
- 新 payload: extraction_id -> 写 water_extractions。
- 旧 payload: detection_id -> 继续写 water_detections。
- 如果旧 detection_id 已经被 alembic 0003 回填到 water_extractions
handler 会同步更新同 ID 的新表记录,避免迁移期状态卡住。
4. /flood/water-extractions 列表改读 water_extractions。
- 旧数据依赖 alembic 0003 从 water_detections 回填。
- preview 优先读 WaterExtractionORM,找不到时回退 WaterDetectionORM。
```
### 仍保留
```text
1. 旧 /water/detect 仍创建 water_detections。
这是兼容窗口内的刻意保留,不再作为洪涝工作台主链路。
2. ENVI/SARscape 精密水体提取还没有接入任务队列。
3. 如果部署环境已有旧 PENDING water_detections 任务,
需要先执行 alembic 0003,再启动 worker。
```
### 下一步
```text
1. 给候选洪涝配对增加灾前/灾后 footprint 地图预览。
2. 把 flood_vector_path 作为矢量图层上图。
3. 套合分析补行政区受影响面积统计。
4. 结果与任务页接 flood_products。
```
## 2026-05-15 第三轮:地图闭环与产品页
### 已完成
```text
1. 候选洪涝配对支持地图预览。
- 灾前 footprint 蓝色。
- 灾后 footprint 绿色。
- 配对行增加“预览覆盖”。
2. 套合结果支持洪涝矢量上图。
- GET /flood/detections/{id}/impact 返回 overlay_id、flood_vector_path、flood_vector_geojson。
- 前端套合分析页增加“加载洪涝矢量”。
3. 套合分析补行政区影响统计。
- overlay 运行时读取 AOI 行政区边界索引。
- 返回 affected_aois,包含 tree_id、name、level、flood_area_km2。
- 前端展示影响行政区数量和前 5 个行政区。
4. 结果与任务页接 flood_products。
- 洪涝结果行增加“生成产品”。
- 结果页增加“产品”tab。
- 产品行展示 product_id、洪涝面积、影响面积、生成时间。
- Manifest 按钮读取 /flood/products/{id}/manifest。
```
### 当前可集中测试的链路
```text
1. 水体提取:
入库影像查询 -> 行政区筛选 -> 源影像上图 -> 提交预处理 -> 提交水体提取 -> 水体结果上图。
2. 洪涝检测:
输入灾害时间 + 灾害位置 -> 推荐配对 -> 预览覆盖 -> 提交洪涝检测 -> 分类图上图。
3. 套合分析:
选择 DONE 洪涝结果 -> 运行套合分析 -> 加载洪涝矢量 -> 查看灾害点、DInSAR、行政区统计。
4. 产品:
DONE 洪涝结果 -> 生成产品 -> 产品 tab 查看 -> 读取 manifest。
```
## 2026-05-15 第四轮:GeoTIFF 化技术决策
本轮根据新的产品判断调整洪涝模块技术路线:不再把 ENVI/SARscape
作为洪涝算法主线,后续水体提取、洪涝检测、套合分析全部运行在标准
GeoTIFF 层。原始 SAR 到 GeoTIFF 的部分做成可插拔前处理器,优先评估
GAMMAGAMMA 覆盖不了的传感器使用 GF3_GDAL、SNAP、ISCE 或 external
处理器兜底。
### 已完成
```text
1. 新增 docs/FLOOD_GEOTIFF_GAMMA_PREPROCESS_DESIGN_20260515.md。
- 总结当前洪涝模块仍绑定 ENVI/SARscape 的真实状态。
- 梳理当前 GAMMA/PyINT 在项目中的能力和边界。
- 明确 GAMMA 适合作为 TIF 前处理候选,但不能把 D-InSAR pair profile
直接复用为洪涝单景预处理。
- 定义 analysis_ready.tif / SarAnalysisScene 数据契约。
- 给出 Python GeoTIFF 洪涝检测和 GAMMA 单景前处理分阶段方案。
2. 更新 docs/INDEX.md。
- 将 GeoTIFF 化设计列入当前执行中的核心设计。
- 标明 2026-05-14 旧洪涝设计中的 ENVI/SARscape 主线表述已被新设计取代。
```
### 当前判断
```text
1. 洪涝算法应先从 SARscape 黑盒迁出,改成 pre/post GeoTIFF 上的 Python 算法。
2. GAMMA 适合优先做 LT-1/Sentinel-1 的 analysis_ready.tif 生产器。
3. 当前 GAMMA 接入已有 geocode/data2geotiff 能力,但缺少独立单景预处理服务。
4. GF3 已有 Python/GDAL L1A->L2 路线,不应强行改走 GAMMA。
5. 另一台服务器部署时,Git 能提供平台代码和算法;GAMMA 本体、DEM、轨道池、
conda/WSL 运行时仍是外部部署前提。
```
+4 -4
View File
@@ -68,9 +68,8 @@ This is a workspace group, not a multi-tab planning tree.
生产管理
└─ 生产管理 (`production_management`)
├─ D-InSAR运行 (`dinsar_runs`)
├─ 时序InSAR运行 (`timeseries_runs`)
─ D-InSAR产物 (`dinsar_products`)
└─ 时序InSAR产物 (`timeseries_products`)
├─ SBAS-InSAR Production (`sbas_insar_production`)
─ D-InSAR产物 (`dinsar_products`)
```
Notes:
@@ -78,7 +77,8 @@ Notes:
- The left navigation contains only one tab for this group: `production_management`.
- Internal workspace views are controlled by `PRODUCTION_WORKSPACE_VIEWS`.
- Route alias mapping is controlled by `PRODUCTION_WORKSPACE_ENTRY_TO_VIEW`.
- Legacy route tabs such as `dinsar_production` and `ps_products` map into this workspace and should not be treated as standalone left-nav entries.
- Legacy route tabs such as `dinsar_production`, `ps_production`, and `ps_products` map into this workspace and should not be treated as standalone left-nav entries.
- The old ISCE2/MintPy `timeseries_runs` and `timeseries_products` workspace views are deprecated and hidden; SBAS production is handled by the Gamma `sbas_insar_production` view.
### 3.3 InSAR形变分析
@@ -0,0 +1,551 @@
# Gamma IPTA LT1 SBAS Trial Runbook
Date: 2026-05-18
## Goal
Validate whether the current local LT1 data pool and WSL Gamma installation can produce one usable SBAS/IPTA trial result with the official Gamma toolchain.
This is not yet a production integration design. The immediate goal is to run one conservative stack, inspect failures and product quality, then decide what should be productized in the system.
Actual trial root used in this repository:
```text
D:\Code\Insar_management_system_v2\backend\runtime\gamma_ipta_trials\lt1b_r114_e1312_n438_20240516_20251002
```
## Current Environment
- WSL distro configured by the project: `Ubuntu-24.04`.
- Gamma install found in WSL: `/usr/local/GAMMA_SOFTWARE-20240627`.
- Installed package name present on disk: `GAMMA_SOFTWARE-20240627_MSP_ISP_DIFF_IPTA.linux64_ubuntu2404.tar.gz`.
- Installed Gamma modules include `MSP`, `ISP`, `DIFF`, `DISP`, and `IPTA`.
- `GEO` is not a separate directory in this install, but DIFF contains the relevant geocoding tools, including `gc_map`, `geocode`, and `geocode_back`.
- Project Gamma environment script: `deploy/wsl/profiles/gamma_env.sh`.
- Project WSL Python: `/home/administrator/miniconda3/envs/insar_wsl_v1/bin/python`.
Important command checks already performed:
- `IPTA/bin/ts_rate` runs and prints usage. No license-denied error observed.
- `IPTA/bin/multi_def_pt` runs and prints usage. No license-denied error observed.
- `ISP/bin/par_LT1_SLC` exists and prints LT1 SLC conversion usage.
- `ISP/scripts/LT1_precision_orbit.py` runs with the project conda Python and prints usage.
## Data Pool Findings
Configured LT1 source pool:
- `D:\LuTan1_Image_Pool`
Configured LT1 precise orbit pool:
- `D:\orbit_pools\envi\LT1A`
- `D:\orbit_pools\envi\LT1B`
High-level inventory:
- LT1 scene directories found: `1500`.
- LT1A orbit TXT files found: `896`, spanning `20230508` to `20251219`.
- LT1B orbit TXT files found: `858`, spanning `20230510` to `20251219`.
Metadata caveat:
- `*.meta.xml` and `*_Check.xml` are not safe to parse as whole XML documents in PowerShell because many files contain malformed Chinese text near the tail, for example bad `usePreciseOrbit` closing text.
- The needed `productInfo` block is structurally valid. For stack discovery, parse only `<productInfo>...</productInfo>`.
- Gamma `par_LT1_SLC` should still use the original `.meta.xml`; do not rewrite source metadata unless a Gamma run proves the malformed tail is a blocker.
## Candidate Stack
First trial should use a narrow single-center stack, not the broad system time-series grouping.
Recommended trial stack:
- Satellite: `LT1B`
- Relative orbit: `114`
- Direction: `DESCENDING`
- Imaging mode: `STRIP1`
- Polarization: `HH`
- Approximate center: `E131.2 / N43.8`
- Scene count at this center: `7`
- Scenes with precise orbit TXT currently present: `5`
Use the 5 scenes with available precise orbit first:
| Date | Orbit TXT | Scene |
| --- | --- | --- |
| 20240516 | yes | `LT1B_MONO_SYC_STRIP1_012047_E131.2_N43.8_20240516_SLC_HH_S2A_0000399289` |
| 20240711 | yes | `LT1B_MONO_SYC_STRIP1_012880_E131.2_N43.8_20240711_SLC_HH_S2A_0000450956` |
| 20240905 | yes | `LT1B_MONO_SYC_STRIP1_013713_E131.2_N43.8_20240905_SLC_HH_S2A_0000501650` |
| 20250417 | yes | `LT1B_MONO_SYC_STRIP1_017045_E131.2_N43.8_20250417_SLC_HH_S2A_0000713375` |
| 20251002 | yes | `LT1B_MONO_SYC_STRIP1_019544_E131.2_N43.8_20251002_SLC_HH_S2A_0000891257` |
Do not include these two in the first run unless the missing orbits are added:
| Date | Orbit TXT | Scene |
| --- | --- | --- |
| 20250612 | no | `LT1B_MONO_SYC_STRIP1_017878_E131.2_N43.8_20250612_SLC_HH_S2A_0000772122` |
| 20250807 | no | `LT1B_MONO_SYC_STRIP1_018711_E131.2_N43.8_20250807_SLC_HH_S2A_0000831367` |
Common bounding box across the broader 13-scene `LT1B relOrbit 114 / E131-N44` candidate:
- lon: `130.8615 .. 131.1638`
- lat: `43.7127 .. 44.0987`
For the narrow `E131.2/N43.8` trial stack, overlap is visually/metadata-wise much tighter:
- Each scene center is around `131.20E, 43.79N`.
- Each scene bbox is roughly `130.81..131.62E`, `43.48..44.10N`.
Secondary candidate if the first stack fails:
- `LT1B relOrbit 114 DESCENDING STRIP1 HH`, center `E130.8/N43.9`.
- 5 dates, 4 with orbit: `20250425`, `20250620`, `20250815`, `20251010`.
- One scene is `MONO_MH1` while the others are `MONO_SYC`; keep it as secondary, not first choice.
## Current System Pairing Limitations
The current time-series stack selection is useful for broad discovery but is too coarse for Gamma IPTA production.
Observed code behavior:
- LT1A/LT1B are normalized into the same satellite family `LT1`.
- The compatibility key only uses direction, satellite family, imaging mode, and polarization.
- Relative orbit, absolute track family, scene center/strip identity, receiving station, and detailed LT1 product variant are not hard grouping keys.
- The stable-stack selector tries to recover by common AOI overlap and pairwise network connectivity.
- The SBAS network selector uses time-baseline, center-distance and overlap thresholds, but does not use Gamma-derived perpendicular baseline at planning time.
- Time-series processors currently accepted by the service are only `isce2_stack_mintpy` and `sarscape_sbas`; there is no `gamma_ipta_sbas` processor code yet.
For the Gamma IPTA trial, do not rely on the current automatic PS stack plan as the source of truth. Use a manually audited stack manifest first.
## Trial Run Checklist
### 1. Create Isolated Work Directory
Actual root:
```text
D:\Code\Insar_management_system_v2\backend\runtime\gamma_ipta_trials\lt1b_r114_e1312_n438_20240516_20251002
```
Keep these subdirectories:
```text
input\scenes
input\orbits
gamma\slc
gamma\mli
gamma\diff
gamma\ipta
logs
publish
```
For the first trial, prefer symlinks or a manifest that points to source scenes. Avoid duplicating large TIFF files unless Gamma scripts require local flat layout.
### 2. Build Scene Manifest
For each selected scene, record:
- scene directory
- `.tiff`
- `.meta.xml`
- precise orbit TXT
- date
- relative orbit
- direction
- mode
- polarization
- center lon/lat
- bbox
This manifest becomes the hand-audited truth for the trial.
### 3. Convert LT1 Products To Gamma SLC
For each selected scene:
```bash
source /mnt/d/Code/Insar_management_system_v2/deploy/wsl/profiles/gamma_env.sh
par_LT1_SLC <scene.tiff> <scene.meta.xml> <yyyymmdd>.slc.par <yyyymmdd>.slc
```
Then apply precise orbit:
```bash
/home/administrator/miniconda3/envs/insar_wsl_v1/bin/python \
/usr/local/GAMMA_SOFTWARE-20240627/ISP/scripts/LT1_precision_orbit.py \
<yyyymmdd>.slc.par <orbit_txt_or_orbit_folder>
```
### 4. Build SLC/MLI Tables
Create Gamma tables for the stack:
```text
SLC_tab
RMLI_tab
```
Use multilook settings conservative enough for a first run. The goal is robustness and fast feedback, not final product resolution.
### 5. Baseline And Pair Network
Use Gamma baseline tools first, not the system's center-distance approximation:
- `base_init`
- `base_perp`
- IPTA baseline tools such as `base_orbit_pt`, `base_par_pt`, `base_ls_pt` as needed by the official IPTA path.
For the first 5-scene stack, start with a simple connected small-baseline network:
- adjacent pairs by time
- add one or two skip pairs only if coherence and baseline look acceptable
Expected adjacent temporal intervals:
- `20240516 -> 20240711`: 56 days
- `20240711 -> 20240905`: 56 days
- `20240905 -> 20250417`: 224 days
- `20250417 -> 20251002`: 168 days
The large seasonal gaps are acceptable for a trial only if perpendicular baseline and coherence are reasonable. If they are poor, switch to a denser 2025-only or 2024-only local test, even with fewer dates.
### 6. Differential Interferograms
Use official Gamma DIFF commands/scripts for:
- coregistration
- interferogram generation
- simulated topographic phase
- differential phase
- filtering
- coherence
- unwrapping if needed by the chosen IPTA path
Do not implement custom SBAS inversion in the management system.
### 7. IPTA Processing
Use Gamma IPTA commands for point/stack time-series processing. Confirm exact command sequence against the installed:
```text
/usr/local/GAMMA_SOFTWARE-20240627/IPTA/html/IPTA_users_guide.pdf
```
Commands observed in the local IPTA module include:
- `multi_def_pt`
- `ts_rate`
- `ts_rate_pt`
- `base_ls_pt`
- `base_par_pt`
- `ph_base_pt`
- `atm_mod_pt`
- `pt2geo`
- `dis_ipta`
### 8. Review Outputs
Minimum acceptance checks for the first run:
- every selected scene converts to SLC
- precise orbit update succeeds for every SLC
- all intended pairs generate interferograms
- coherence is not uniformly poor
- unwrapping or IPTA point solution is not globally unstable
- one geocoded velocity or displacement-rate raster/vector product can be inspected
- logs and command manifests are complete enough to reproduce the run
## Trial Progress On 2026-05-18
### Files Created For This Trial
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/input/scene_manifest.json`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/01_prepare_slc.sh`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/02_mli_and_baseline.sh`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/03_coreg_one_pair.sh`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/04_cc_stats.py`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/05_coreg_adjacent_pairs.sh`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/06_prepare_rdc_dem.sh`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/07_coreg_common_ref_stack.sh`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/08_diff_unwrap_common_ref.sh`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/09_mb_ts_rate.sh`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/10_float_stats.py`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/11_make_timeseries_previews.sh`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/12_geocode_export_timeseries.sh`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/13_phase_to_los.py`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/14_build_trial_summary.py`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/15_make_los_velocity_maps.sh`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/16_plot_monitor_point_timeseries.py`
- `backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002/scripts/17_make_geocoded_web_previews.sh`
### Completed
- Created a hand-audited 5-scene LT1B manifest for `relOrbit 114 / DESCENDING / STRIP1 / HH / E131.2 N43.8`.
- Converted all 5 LT1 TIFF products with Gamma `par_LT1_SLC`.
- Applied precise orbit updates with Gamma `LT1_precision_orbit.py`.
- Built `gamma/slc/SLC_tab`.
- Built 8x8 multilooked MLI products with Gamma `multi_look`.
- Built `gamma/mli/RMLI_tab`.
- Generated all-pair and adjacent-pair baseline tables with Gamma `base_calc`.
- Ran adjacent-pair coregistration for all 4 selected adjacent pairs using Gamma `SLC_coreg.py`.
- Generated 4 interferograms and coherence products using Gamma `create_offset`, `SLC_intf`, and `cc_wave`.
- Generated browse previews using Gamma `rasmph` and `raspwr`.
- Computed coherence statistics for each adjacent pair.
- Reused the existing Copernicus30 DEM cache covering `E131.2/N43.8`.
- Generated a reference-geometry RDC DEM for `20240905` using Gamma `gc_map1`, `geocode`, and `gc_map_fine`.
- Built a common-reference RSLC/RMLI stack in `20240905` geometry.
- Generated common-reference differential interferograms with Gamma `phase_sim_orb` and `SLC_diff_intf`.
- Filtered common-reference differential interferograms with Gamma `adf`.
- Unwrapped common-reference differential interferograms with Gamma `mcf`.
- Ran Gamma IPTA `mb` to solve the image-based phase time-series.
- Ran Gamma IPTA `ts_rate` to estimate a linear phase-rate map.
- Generated Gamma preview rasters for `ts_rate`, `sigma_rate`, and `hgt_correction`.
- Exported phase-rate, sigma, height-correction, and LOS-rate rasters to EPSG:4326 GeoTIFF.
- Generated explicit LOS velocity maps in `mm/year` for both away-from-radar-positive and toward-radar-positive conventions.
- Generated one example monitoring-point LOS displacement curve as PNG, CSV, and metadata JSON.
- Generated north-up WGS84 web preview PNGs from the geocoded LOS GeoTIFF products.
### Key Outputs
- SLC stack: `gamma/slc/SLC_tab`
- MLI stack: `gamma/mli/RMLI_tab`
- All-pair baseline table: `gamma/diff/bperp_all_pairs.txt`
- Adjacent-pair table: `gamma/diff/itab_adjacent`
- Pair-specific RSLC products: `gamma/rslc/*_to_*.rslc`
- Pair-specific quality reports: `gamma/rslc/*_to_*.rslc.coreg_quality`
- Adjacent interferograms: `gamma/int/*.int`
- Adjacent coherence rasters: `gamma/int/*.cc`
- Adjacent interferogram previews: `gamma/int/*.int.bmp`
- Adjacent coherence previews: `gamma/int/*.cc.bmp`
- Coherence statistics: `logs/*_cc_stats.txt`
- Reference RDC DEM: `gamma/dem/20240905_8rlks.rdc.dem`
- Common-reference stack tables: `gamma/common_20240905/SLC_tab`, `gamma/common_20240905/RMLI_tab`
- Common-reference differential stack: `gamma/common_20240905/diff/*/*_8rlks.diff_filt.unw`
- Gamma `mb` time-series list: `gamma/common_20240905/timeseries/diff_ts.tab`
- Gamma `mb` phase time-series: `gamma/common_20240905/timeseries/diff_ts_*.diff`
- Gamma `mb` residual sigma: `gamma/common_20240905/timeseries/sigma_ts`
- Gamma `mb` height correction: `gamma/common_20240905/timeseries/hgt_correction`
- Gamma `ts_rate` output: `gamma/common_20240905/timeseries/ts_rate`
- Gamma `ts_rate` sigma output: `gamma/common_20240905/timeseries/sigma_rate`
- Preview rasters: `gamma/common_20240905/timeseries/*.bmp`
- Geocoded GeoTIFF exports: `publish/geotiff/*.tif`
- Explicit LOS velocity previews: `publish/geotiff/los_rate_toward_mm_per_year.bmp`, `publish/geotiff/los_rate_away_mm_per_year.bmp`
- Geocoded web previews: `publish/geotiff/los_rate_toward_mm_per_year.geo_preview.png`, `publish/geotiff/los_sigma_mm_per_year.geo_preview.png`
- Monitoring-point curve: `publish/monitor_points/auto_low_sigma_high_rate_timeseries.png`
- Monitoring-point values: `publish/monitor_points/auto_low_sigma_high_rate_timeseries.csv`
- Trial summary: `publish/trial_summary.json`
### Baseline Notes
`base_calc` generated 10 all-pair entries. The adjacent temporal network is:
| Pair | Delta days | Bperp from `base_calc` |
| --- | ---: | ---: |
| 20240516 -> 20240711 | 56 | 646.09670 |
| 20240711 -> 20240905 | 56 | -236.76960 |
| 20240905 -> 20250417 | 224 | 249.35880 |
| 20250417 -> 20251002 | 168 | 59.18150 |
The first validated pair was `20240711 -> 20240905` because it has a 56-day interval and moderate perpendicular baseline in this stack.
### Adjacent-Pair Quality
Final `SLC_coreg.py` quality-test summaries:
| Pair | Accepted offsets | Final std range | Final std azimuth |
| --- | ---: | ---: | ---: |
| 20240516 -> 20240711 | 2476 / 2688 | 0.0861 | 0.1120 |
| 20240711 -> 20240905 | 2483 / 2656 | 0.0370 | 0.1245 |
| 20240905 -> 20250417 | 2322 / 2688 | 0.0487 | 0.0617 |
| 20250417 -> 20251002 | 2274 / 2688 | 0.0304 | 0.0533 |
Coherence statistics from Gamma big-endian float files:
| Pair | valid `[0,1]` | p25 | median | p75 | p99 | Comment |
| --- | ---: | ---: | ---: | ---: | ---: | --- |
| 20240516 -> 20240711 | 100% | 0.127489 | 0.212285 | 0.323520 | 0.649398 | Weakest pair; high Bperp and low coherence |
| 20240711 -> 20240905 | 100% | 0.629307 | 0.733220 | 0.802884 | 0.909973 | Strong pair |
| 20240905 -> 20250417 | 100% | 0.339094 | 0.485239 | 0.612798 | 0.833928 | Usable trial pair |
| 20250417 -> 20251002 | 100% | 0.394165 | 0.582921 | 0.734878 | 0.932300 | Usable trial pair |
All adjacent pairs generated expected Gamma products. The full 5-scene chain can continue, but the first pair is a quality risk for unwrapping/IPTA. A more conservative follow-up is to run the 4-scene sub-stack from `20240711` to `20251002`, or keep the 5-scene stack but down-weight or exclude `20240516 -> 20240711` if later unwrapping/IPTA residuals are poor.
Implementation note:
- `SLC_coreg.py` writes the refined offset parameter file to a secondary-date path such as `gamma/slc/20240711.slc.off`.
- Trial scripts copy that file to pair-specific paths such as `gamma/rslc/20240711_to_20240905.rslc.off`.
- Future skip-pair or non-adjacent networks must use pair-specific offset files to avoid accidental reuse after the same secondary scene is coregistered to another reference.
### Common-Reference Time-Series Trial
The image-based Gamma IPTA path was also run using a common `20240905` reference geometry. This is closer to the official `mb -> ts_rate` time-series chain than the first adjacent-pair wrapped interferogram check.
Common-reference inputs and products:
- reference geometry: `20240905`
- DEM source: existing Copernicus30 cache under `backend/runtime/pyint_dem_cache`
- RDC DEM: `gamma/dem/20240905_8rlks.rdc.dem`
- common-reference SLC table: `gamma/common_20240905/SLC_tab`
- common-reference MLI table: `gamma/common_20240905/RMLI_tab`
- common-reference differential ITAB:
```text
1 3 1 1
2 3 2 1
3 4 3 1
3 5 4 1
```
Filtered differential coherence statistics:
| Pair | valid `[0,1]` | p25 | median | p75 | p99 |
| --- | ---: | ---: | ---: | ---: | ---: |
| 20240516 -> 20240905 | 100% | 0.497369 | 0.884586 | 0.945308 | 0.980583 |
| 20240711 -> 20240905 | 100% | 0.919149 | 0.968188 | 0.979449 | 0.990185 |
| 20240905 -> 20250417 | 100% | 0.366279 | 0.790519 | 0.909991 | 0.978094 |
| 20240905 -> 20251002 | 100% | 0.193104 | 0.815562 | 0.917209 | 0.972355 |
Gamma `mb` outputs:
- `gamma/common_20240905/timeseries/diff_ts_001.diff` through `diff_ts_005.diff`
- `gamma/common_20240905/timeseries/diff_ts.tab`
- `gamma/common_20240905/timeseries/itab_ts`
- `gamma/common_20240905/timeseries/sigma_ts`
- `gamma/common_20240905/timeseries/hgt_correction`
Gamma `ts_rate` outputs:
- `gamma/common_20240905/timeseries/ts_rate`
- `gamma/common_20240905/timeseries/ts_const`
- `gamma/common_20240905/timeseries/sigma_rate`
- `gamma/common_20240905/timeseries/ts_rate.bmp`
- `gamma/common_20240905/timeseries/sigma_rate.bmp`
- `gamma/common_20240905/timeseries/hgt_correction.bmp`
GeoTIFF exports:
- `publish/geotiff/ts_rate_rad_per_year.tif`
- `publish/geotiff/sigma_rate_rad_per_year.tif`
- `publish/geotiff/sigma_ts_rad.tif`
- `publish/geotiff/hgt_correction_m.tif`
- `publish/geotiff/los_rate_m_per_year.tif`
- `publish/geotiff/los_sigma_m_per_year.tif`
- `publish/geotiff/los_rate_away_mm_per_year.tif`
- `publish/geotiff/los_rate_toward_mm_per_year.tif`
- `publish/geotiff/los_sigma_mm_per_year.tif`
- `publish/geotiff/los_rate_toward_mm_per_year.geo_preview.png`
- `publish/geotiff/los_sigma_mm_per_year.geo_preview.png`
- `publish/trial_summary.json`
Float output statistics using Gamma big-endian float:
| File | Non-zero pixels | p25 | median | p75 | p99 |
| --- | ---: | ---: | ---: | ---: | ---: |
| `ts_rate` | 8,868,956 | -1.663257 | -0.271621 | 0.869116 | 2.787572 |
| `sigma_rate` | 8,868,956 | 0.396037 | 0.677578 | 1.010539 | 2.298520 |
| `sigma_ts` | 8,892,237 | 0.000704 | 0.001557 | 0.002535 | 0.518188 |
| `hgt_correction` | 8,892,250 | -16.989384 | 7.596325 | 36.411520 | 98.636933 |
Explicit LOS velocity output statistics in `mm/year`:
| File | Non-zero pixels | p01 | p25 | median | p75 | p99 |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| `los_rate_toward_mm_per_year.rdc` | 8,868,956 | -52.779640 | -16.455760 | 5.142855 | 31.491957 | 84.590944 |
| `los_sigma_mm_per_year.rdc` | 8,868,956 | 0.530715 | 7.498536 | 12.829198 | 19.133450 | 43.519972 |
This is a successful first local Gamma official-chain time-series trial. It is still a technical validation run, not a production-grade SBAS product: the stack has only 5 dates, the network is minimal, and reference region and unwrapping masks were conservative defaults.
The exported GeoTIFFs are EPSG:4326, `2222 x 2237`, Float32, LZW-compressed Cloud Optimized GeoTIFFs with `NoData=0`.
The `*.bmp` files generated by Gamma `rasdt_pwr` are RDC processing-geometry browse images. They are useful for quick processing QA but are not map products and should not be used as the default UI map preview. The UI/default web preview should use the `*.geo_preview.png` files generated from the EPSG:4326 GeoTIFF products.
### LOS Sign Convention
Gamma `ts_rate` is a phase-rate raster in `rad/year`. Converting phase rate to LOS displacement rate requires a sign convention:
- `los_rate_away_mm_per_year = phase_rate * wavelength / (4*pi) * 1000`
- `los_rate_toward_mm_per_year = -phase_rate * wavelength / (4*pi) * 1000`
Gamma `dispmap` documents two conventions:
- `sflg=0`, the default: motion away from radar is negative, so motion toward radar is positive; deformation and unwrapped phase have opposite signs.
- `sflg=1`: motion away from radar is positive; deformation and unwrapped phase have the same sign.
For system productization, use explicit names and prefer `los_rate_toward_mm_per_year` as the default display product because it matches Gamma `dispmap` default `sflg=0`. Keep the away-positive version available when another downstream convention requires direct phase-sign products.
### Monitoring Point Curve
An example monitoring point was selected automatically from low-sigma, high-rate, non-edge pixels:
- radar pixel: range `336`, azimuth `2290`
- approximate lon/lat: `131.4340324903`, `43.8008322757`
- reference date in the plotted time series: `20240711`
- LOS convention: toward radar positive, away from radar negative
- fitted LOS velocity: `50.1085 mm/year`
- fitted LOS velocity sigma: `0.0063 mm/year`
Generated outputs:
- `publish/monitor_points/auto_low_sigma_high_rate_timeseries.png`
- `publish/monitor_points/auto_low_sigma_high_rate_timeseries.csv`
- `publish/monitor_points/auto_low_sigma_high_rate_metadata.json`
The plotted values are:
| Date | LOS displacement, toward-positive mm |
| --- | ---: |
| 20240516 | -7.673957 |
| 20240711 | 0.000000 |
| 20240905 | 7.673922 |
| 20250417 | 38.412669 |
| 20251002 | 61.464305 |
This is a single example point only. It is not a validated monitoring-point network and should not be interpreted as a representative area-wide deformation curve. The automatic selection favors a non-edge pixel with relatively high absolute velocity and low fitted sigma so the curve is visually inspectable. Production monitoring points need one of these inputs:
- user-clicked map lon/lat
- imported engineering monitoring-point layer
- a configured regular grid or point-of-interest set
- a quality-filtered automatic point sampler with spacing, coherence/sigma thresholds, and manual review
Until that is implemented, the single curve is a capability demonstration and should be labeled as such in the UI.
### Current Open Items
- Review the `ts_rate.bmp`, `sigma_rate.bmp`, `hgt_correction.bmp`, LOS velocity BMPs, monitoring-point PNG, and exported GeoTIFFs visually in GIS.
- Tune reference region, coherence thresholds, and pair network before treating the result as production.
- Decide whether to keep the weak/long 2025 pair, add skip-pairs, or use a denser data sequence when more LT1 precise orbits are available.
- Keep system integration as orchestration around Gamma commands; do not implement custom SBAS inversion in application code.
## Productization Decisions After Trial
If the 5-scene trial succeeds, add a new managed processor instead of bending existing ISCE/SARscape flows:
```text
processor_code = gamma_ipta_sbas
engine_code = gamma
workflow = gamma_ipta_sbas
```
Required system changes:
- Add a Gamma IPTA stack manifest builder.
- Add LT1-specific hard grouping keys:
- satellite platform, not only family, unless cross-satellite LT1A/LT1B is explicitly validated
- relative orbit
- orbit direction
- imaging mode
- polarization
- scene strip/center bucket
- product variant or station/submode where it affects compatibility
- Add a Gamma baseline audit step before final pair network selection.
- Persist selected Gamma pair network separately from the coarse planning graph.
- Keep system code as orchestration only; Gamma remains the processing authority.
## Current Recommendation
Use the manual audited `LT1B relOrbit 114 DESCENDING STRIP1 HH / E131.2 N43.8` stack and the trial scripts as the reference path for productization.
Do not start Gamma IPTA production from the current automatic time-series plan. It can be used for discovery, but production stack selection needs the hard grouping keys and Gamma baseline audit described above.
For the next engineering step, add a managed `gamma_ipta_sbas` processor that orchestrates the Gamma commands rather than reimplementing SBAS inversion in application code.
+15 -8
View File
@@ -36,8 +36,11 @@
- [PRODUCTION_RESULTS_MULTI_ENGINE_DESIGN_20260423.md](PRODUCTION_RESULTS_MULTI_ENGINE_DESIGN_20260423.md)
多引擎结果目录、发布结构和 catalog 治理设计。
- [FLOOD_GEOTIFF_GAMMA_PREPROCESS_DESIGN_20260515.md](FLOOD_GEOTIFF_GAMMA_PREPROCESS_DESIGN_20260515.md)
洪涝模块 GeoTIFF 化与 GAMMA 前处理评估,定义“原始数据到分析级 TIF 由可插拔处理器完成,水体/洪涝算法只运行在 GeoTIFF 层”的当前技术决策。
- [FLOOD_DISASTER_ANALYSIS_SYSTEM_DESIGN_20260514.md](FLOOD_DISASTER_ANALYSIS_SYSTEM_DESIGN_20260514.md)
洪涝灾害分析独立系统设计,定义多源 SAR 数据、ENVI/SARscape 洪涝流程、标准产品包和矢量套合分析边界
洪涝灾害分析独立系统早期设计,保留工作台、产品包和矢量套合分析边界;其中 ENVI/SARscape 作为洪涝主线的表述已被 2026-05-15 GeoTIFF 化设计取代
- [WSL_RUNTIME_REFACTOR_DESIGN_20260422.md](WSL_RUNTIME_REFACTOR_DESIGN_20260422.md)
WSL 共享运行时和 Broker 设计。
@@ -50,15 +53,18 @@
## 3. 时序 InSAR / SBAS
- [ISCE2_SBAS_TIMESERIES_DESIGN.md](ISCE2_SBAS_TIMESERIES_DESIGN.md)
- [ISCE2_SBAS_PRODUCT_SPEC.md](ISCE2_SBAS_PRODUCT_SPEC.md)
- [ISCE2_SBAS_ENGINEERING_DESIGN_20260428.md](ISCE2_SBAS_ENGINEERING_DESIGN_20260428.md)
Current-phase engineering design for the managed ISCE2 + MintPy SBAS route.
- [SBAS_INSAR_PRODUCTION_PIPELINE_DESIGN_20260519.md](SBAS_INSAR_PRODUCTION_PIPELINE_DESIGN_20260519.md)
Gamma/LT1 SBAS-InSAR 独立生产页面与统一流水线收口设计。
- [TIMESERIES_LEGACY_DEPRECATION_20260521.md](TIMESERIES_LEGACY_DEPRECATION_20260521.md)
ISCE2/MintPy 时序生产链路停用记录,定义当前入口隐藏、配置默认关闭和后续物理删除条件。
- [GAMMA_IPTA_LT1_SBAS_TRIAL_RUNBOOK_20260518.md](GAMMA_IPTA_LT1_SBAS_TRIAL_RUNBOOK_20260518.md)
Gamma 官方 DIFF + IPTA 路径处理 LT1 数据的本地试验记录、产物和符号约定。
说明:
- 当前前端顶级显示名已经统一为“时序 InSAR”
- 当前默认接入仍然是 SBAS 路径,因此这两份文档仍然有效
- 当前 SBAS-InSAR 生产主线是 Gamma 独立生产页面,不再使用旧 ISCE2/MintPy 时序生产页作为入口
- `timeseries-production` 后端、旧前端面板和 `ps_timeseries_runs` 相关结构暂时保留兼容,但默认关闭
- `ISCE2_SBAS_TIMESERIES_DESIGN.md``ISCE2_SBAS_PRODUCT_SPEC.md``ISCE2_SBAS_ENGINEERING_DESIGN_20260428.md` 仅作为历史参考,不再作为当前生产事实依据。
- `SBAS_*` 命名的一批旧文档已经归档,只保留历史追溯价值。
## 4. 配对与前端导航
@@ -130,4 +136,5 @@
- 已归档的 `项目汇报.md`
- 已归档的各类 `*_EXPERIMENT_*` / `*_PROGRESS_*` / `*_TODO_*`
最后更新:2026-05-12
最后更新:2026-05-15
最近修订:2026-05-21
@@ -0,0 +1,439 @@
# SBAS-InSAR Production Pipeline Design
Date: 2026-05-19
## Decision
SBAS-InSAR production becomes an independent production workflow and page. It must not depend on the existing coarse time-series pairing layer as its production authority.
The old time-series pairing code may remain temporarily for compatibility and candidate discovery, but the new SBAS-InSAR page and backend API should bypass it by default. Deletion should happen only after the new workflow can create, run, publish, and browse Gamma SBAS/IPTA products end to end.
The legacy ISCE2/MintPy time-series production chain is disabled by default. The `timeseries-production` backend code and old catalog pages may remain as compatibility code, but they are no longer exposed as production-management subpages. The active SBAS production route is `/api/sbas-insar-production` and the active UI view is `sbas_insar_production`.
## Scope
Initial production target:
- Sensor: LT1 SLC
- Engine: Gamma
- Workflow: Gamma DIFF + IPTA `mb` + `ts_rate`
- Processor code: `gamma_ipta_sbas`
- Default display product: LOS velocity toward radar positive
Out of scope for the first implementation slice:
- custom SBAS inversion in application code
- direct reuse of the current PS/time-series pair graph as final Gamma `itab`
- full automatic stack approval without a Gamma baseline and quality audit
- cross-satellite LT1A/LT1B stack mixing
## Product Contract
Every successful SBAS-InSAR production run should publish:
- `product_summary.json`
- `stack_manifest.json`
- `gamma_command_manifest.json`
- `pair_network.json`
- `quality_summary.json`
- `los_rate_toward_mm_per_year.tif`
- `los_rate_toward_mm_per_year.geo_preview.png`
- `los_rate_toward_mm_per_year.rdc_preview.bmp`
- `los_rate_away_mm_per_year.tif`
- `los_rate_away_mm_per_year.rdc_preview.bmp`
- `los_sigma_mm_per_year.tif`
- `los_sigma_mm_per_year.geo_preview.png`
- `los_sigma_mm_per_year.rdc_preview.bmp`
- `ts_rate_rad_per_year.tif`
- `sigma_rate_rad_per_year.tif`
- monitoring-point time-series `png/csv/json`
- raw logs for each Gamma stage
The current trial product remains the reference implementation:
```text
backend/runtime/gamma_ipta_trials/lt1b_r114_e1312_n438_20240516_20251002
```
Preview rule:
- UI default map previews must be rendered from geocoded EPSG:4326 GeoTIFFs.
- RDC/RMLI BMP browse images are processing QA artifacts only.
- Product names should make coordinate state explicit: `geo_preview` for map previews and `rdc_preview` for radar-geometry previews.
## LOS Sign Convention
Gamma `ts_rate` outputs phase rate in `rad/year`. The system must store both sign conventions explicitly:
```text
los_rate_away_mm_per_year = phase_rate * wavelength / (4*pi) * 1000
los_rate_toward_mm_per_year = -phase_rate * wavelength / (4*pi) * 1000
```
Default UI display:
```text
LOS toward radar positive
```
This matches Gamma `dispmap` default `sflg=0`: motion away from radar is negative, motion toward radar is positive.
## Page Design
Add a separate production view:
```text
Production Management
- D-InSAR Runs
- SBAS-InSAR Production
- D-InSAR Products
```
The SBAS page is operational, not a marketing landing page. First screen should show:
- runtime capability: Gamma install, WSL distro, workflow support
- available SBAS stacks or trial runs
- selected run summary
- LOS velocity geocoded preview
- product file list
- monitoring-point curve
- quality metrics
- stage checklist
The current old "time-series run" and "time-series products" views are hidden from the production workspace. Legacy route aliases such as `ps_production` and `ps_products` should redirect to the SBAS-InSAR production view rather than opening the old ISCE2/MintPy workflow.
## Backend API
Initial read-only API:
```text
GET /api/sbas-insar-production/capabilities
GET /api/sbas-insar-production/trial-runs
GET /api/sbas-insar-production/trial-runs/{trial_id}
GET /api/sbas-insar-production/trial-runs/{trial_id}/artifacts/{relative_path}
```
Stack discovery and hard-constraint audit API:
```text
POST /api/sbas-insar-production/stacks/discover
POST /api/sbas-insar-production/stacks/{stack_id}/audit
```
`stacks/discover` scans LT1 source roots directly and groups scenes by:
- platform, for example `LT1A` or `LT1B`
- satellite mode, for example `MONO`
- receiving station
- relative orbit
- orbit direction
- imaging mode
- polarization
- center bucket, for example `E131.2_N43.8`
It also checks LT1 precise orbit TXT availability against `PYINT_ORBIT_POOL_TXT` / `ORBIT_POOL_ENVI`.
`stacks/{stack_id}/audit` writes a reproducible manifest under:
```text
backend/runtime/sbas_insar_production/stack_manifests/{stack_id}/
```
The manifest status is `READY_FOR_GAMMA_BASELINE_AUDIT` only after hard grouping, minimum scene count, precise orbit availability, and an initial adjacent temporal network are satisfied. Gamma `base_calc` remains the next required audit before final `itab` approval.
Writable production planning API:
```text
POST /api/sbas-insar-production/stacks/{stack_id}/runs
GET /api/sbas-insar-production/runs
GET /api/sbas-insar-production/runs/{run_id}
GET /api/sbas-insar-production/runs/{run_id}/artifacts/{relative_path}
```
The current `runs` submission is a dry-run planning submission. It writes:
```text
backend/runtime/sbas_insar_production/runs/{run_id}/run_manifest.json
backend/runtime/sbas_insar_production/runs/{run_id}/stack_manifest.json
backend/runtime/sbas_insar_production/runs/{run_id}/pair_network.json
backend/runtime/sbas_insar_production/runs/{run_id}/gamma_command_manifest.json
backend/runtime/sbas_insar_production/runs/{run_id}/monitor_points.json
```
The created run status is:
```text
PLANNED_GAMMA_BASELINE_AUDIT
```
This is intentionally not a Gamma execution trigger yet. The next runnable slice should add:
```text
POST /api/sbas-insar-production/runs/{run_id}/baseline-audit
POST /api/sbas-insar-production/runs/{run_id}/itab-decision
POST /api/sbas-insar-production/runs/{run_id}/coregistration
POST /api/sbas-insar-production/runs/{run_id}/coregistration/jobs
POST /api/sbas-insar-production/runs/{run_id}/monitor-points
POST /api/sbas-insar-production/runs/{run_id}/retry-stage
```
`baseline-audit` currently supports:
- script-only mode: generate/reparse `scripts/01_baseline_audit.sh` and existing outputs
- execution mode: run Gamma `par_LT1_SLC`, `LT1_precision_orbit.py`, `multi_look`, and `base_calc`
- output parsing: write `baseline_audit_summary.json` and `pair_network_baseline_audit.json`
`itab-decision` is the current production gate:
- `approve`: copies Gamma `work/gamma/diff/itab_adjacent` to `work/gamma/diff/itab_approved`, writes `itab_decision.json`, moves the run to `ITAB_APPROVED`, and makes `coregistration` the next stage
- `reject`: writes `itab_decision.json`, moves the run to `ITAB_REJECTED`, and blocks further Gamma stages until the pair network is revised
`coregistration` supports script generation. It writes:
```text
backend/runtime/sbas_insar_production/runs/{run_id}/scripts/02_coreg_common_ref.sh
backend/runtime/sbas_insar_production/runs/{run_id}/coregistration_plan.json
```
The generated script consumes `work/gamma/diff/itab_approved` as the approval gate, uses the stack reference date as common geometry, and prepares Gamma `SLC_coreg.py` calls for every non-reference date.
`coregistration/jobs` submits the generated script to the existing `SystemTask` + `SystemJob` background queue as job type `SBAS_COREGISTRATION`. The job runs Gamma `SLC_coreg.py`, writes `coregistration_summary.json`, updates the run manifest to `COREGISTRATION_READY` or `COREGISTRATION_FAILED`, and advances the next stage to `rdc_dem` only when all expected RSLC/RMLI outputs and common tab files exist.
## Backend Services
First slice:
```text
sbas_insar_production_service.py
- discover local Gamma IPTA trial summaries
- normalize products and artifact URLs
- expose sign convention and product metadata
- serve safe artifacts from trial roots
```
Second slice:
```text
gamma_ipta_stack_planner.py
- hard group LT1 scenes by platform, relative orbit, direction, mode, polarization, center bucket
- require precise orbit availability
- emit stack_manifest.json
gamma_ipta_pair_planner.py
- build initial temporal network
- run Gamma baseline audit
- emit pair_network.json and Gamma itab
gamma_ipta_job_runner.py
- execute official Gamma commands stage by stage
- write command manifests and logs
sbas_insar_product_publisher.py
- publish GeoTIFF/BMP/CSV/JSON products
- register products into unified result catalog
```
## Future Database Model
Use unified pipeline tables rather than adding many one-off SBAS tables:
```text
pipeline_runs
pipeline_stages
pipeline_products
pipeline_quality_metrics
pipeline_logs
```
Minimum fields for `pipeline_runs`:
- `run_id`
- `workflow_code = sbas_insar`
- `processor_code = gamma_ipta_sbas`
- `engine_code = gamma`
- `status`
- `stack_manifest_path`
- `work_root`
- `publish_root`
- `created_by`
- `created_at`
- `started_at`
- `ended_at`
- `summary_json`
For the first slice, use filesystem discovery only. Do not add migrations until the run submission workflow is ready.
## Gamma Stage Contract
The managed runner should preserve the successful trial chain:
1. `par_LT1_SLC`
2. `LT1_precision_orbit.py`
3. `multi_look`
4. `base_calc`
5. `SLC_coreg.py`
6. `gc_map1` / `geocode` / `gc_map_fine`
7. `phase_sim_orb`
8. `SLC_diff_intf`
9. `adf`
10. `mcf`
11. `mb`
12. `ts_rate`
13. `geocode_back`
14. `data2geotiff`
15. LOS sign conversion and preview generation
16. monitoring-point time-series extraction
The application is an orchestrator. Gamma remains the processing authority.
## Migration Plan
Phase 1: read-only SBAS production page
- add design document
- add backend API for existing Gamma trial discovery
- add page entry and product preview
- keep old time-series page available as legacy
Phase 2: managed run submission
- add stack discovery and audit endpoints
- add planned-run submission endpoint
- write production run manifest, command manifest, and monitor-point config
- add Gamma runner skeleton
- queue job with stage updates
Phase 3: unified pipeline management
- add generic pipeline tables
- move Gamma SBAS run records into pipeline tables
- register products through the unified product catalog
Phase 4: remove old SBAS/time-series pairing dependency
- hide old SBAS entry completely
- keep any reusable discovery functions as internal utilities
- delete obsolete UI and API routes after dependency audit
## Acceptance Criteria For Phase 1
- SBAS-InSAR production appears as its own production workspace view.
- Existing Gamma IPTA trial can be listed from the backend API.
- The selected trial shows LOS velocity preview, sigma/GeoTIFF products, monitor-point curve, and quality summary.
- Artifact serving is constrained to the trial root.
- No existing D-InSAR, flood, or legacy time-series routes are broken.
## Implementation Progress On 2026-05-19
Implemented:
- read-only SBAS-InSAR production page
- trial product browser for the local Gamma IPTA validation run
- artifact API constrained to published trial outputs
- LT1 filesystem stack discovery independent of the old time-series pairing layer
- hard grouping by platform, satellite mode, receiving station, relative orbit, orbit direction, imaging mode, polarization, and center bucket
- precise orbit TXT availability check against the configured Gamma/PyINT orbit pool
- stack manifest and initial adjacent pair-network JSON generation
- geocoded web previews generated from `los_rate_toward_mm_per_year.tif` and `los_sigma_mm_per_year.tif`
- planned SBAS production run creation from a READY stack manifest
- filesystem production run browser and artifact download API
- Gamma stage plan manifest with execution disabled until baseline audit runner is attached
- monitoring-point config contract with explicit placeholder status for `auto_low_sigma_high_rate`
- Gamma baseline audit script generation and output parser
- baseline audit result display in the SBAS production page
- itab approval/rejection API and page controls
- common-reference coregistration script generation and page summary
- queued `SBAS_COREGISTRATION` background job submission through the existing task/job queue
- coregistration execution summary parser and manifest status update to `COREGISTRATION_READY` / `COREGISTRATION_FAILED`
Local verification:
- scanned `1500` LT1 scene directories from the local data pool
- found READY candidates with all required precise orbit TXT files
- generated one manifest at:
```text
backend/runtime/sbas_insar_production/stack_manifests/sbas_2e6301f64a10/20260519T122146Z_stack_manifest.json
```
- created one dry-run production plan at:
```text
backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/run_manifest.json
```
The dry-run production plan uses the local LT1B relOrbit `114` stack around `E129.2_N44.1`, with `7` scenes and `6` initial adjacent temporal pairs.
- baseline audit script:
```text
backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/scripts/01_baseline_audit.sh
```
- baseline audit summary:
```text
backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/baseline_audit_summary.json
```
The baseline audit ran Gamma 20240627 `par_LT1_SLC`, `LT1_precision_orbit.py`, `multi_look`, and `base_calc` against all 7 LT1B scenes. It completed with status `BASELINE_AUDIT_READY` after the outer terminal command timed out, because the WSL process continued to completion in the background.
Gamma `base_calc` adjacent-network result:
- all-pair count: `21`
- adjacent-pair count: `6`
- max absolute perpendicular baseline: `731.9957 m`
- max temporal gap: `224 days`
The current adjacent network is connected, but several Bperp values are large enough that a human baseline/quality review is still required before using this `itab` for the full SBAS inversion.
The current run has been approved for the next controlled trial step:
```text
status = ITAB_APPROVED
next_stage = coregistration
approved itab = backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/work/gamma/diff/itab_approved
decision record = backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/itab_decision.json
```
The common-reference co-registration script has been generated:
```text
backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/scripts/02_coreg_common_ref.sh
backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/coregistration_plan.json
```
Current status before executing the queued job:
```text
status = COREGISTRATION_SCRIPT_READY
next_stage = execute_coregistration
common reference date = 20241007
```
The actual `SLC_coreg.py` execution is now wired as a background job endpoint and page action, but has not been production-tested in this pass. It consumes `itab_approved`, not the pre-audit or unapproved pair plan.
Expected post-job outputs:
```text
backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/coregistration_summary.json
backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/work/gamma/common_20241007/SLC_tab
backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/work/gamma/common_20241007/RMLI_tab
backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/work/gamma/common_20241007/rslc/*.rslc
backend/runtime/sbas_insar_production/runs/sbas_ab96afabead5/work/gamma/common_20241007/rmli/*.mli
```
After the job succeeds:
```text
status = COREGISTRATION_READY
next_stage = rdc_dem
```
Open product-display decisions:
- the current Gamma `*.bmp` previews are RDC processing-geometry products; keep them visible only as QA artifacts
- the first UI map preview should use `los_rate_toward_mm_per_year.geo_preview.png`
- the first sigma preview should use `los_sigma_mm_per_year.geo_preview.png`
- the current monitoring-point curve is a single automatic sample point, not a monitoring network
- production monitoring curves need user-selected lon/lat points, imported monitoring points, or a quality-filtered automatic sampler before they can be treated as formal outputs
@@ -0,0 +1,184 @@
# Legacy Time-Series InSAR Deprecation Record
Date: 2026-05-21
## Background
The project previously kept an ISCE2 + MintPy time-series/SBAS production path under:
```text
experiments/isce2_sbas_timeseries
```
That experiment directory has been removed. The active SBAS-InSAR direction is now the independent Gamma production workflow documented in:
```text
docs/SBAS_INSAR_PRODUCTION_PIPELINE_DESIGN_20260519.md
docs/GAMMA_IPTA_LT1_SBAS_TRIAL_RUNBOOK_20260518.md
```
Before this cleanup, startup validation still generated warnings for missing legacy paths:
```text
TIMESERIES_EXPERIMENT_ROOT
TIMESERIES_STACK_PREP_SCRIPT
TIMESERIES_MATERIALIZE_SCRIPT
TIMESERIES_PREPARE_DEM_SCRIPT
TIMESERIES_STACK_RUNNER_SCRIPT
TIMESERIES_MINTPY_SBAS_SCRIPT
TIMESERIES_EXPORT_PUBLISH_SCRIPT
```
Those warnings were misleading because they referred to the abandoned ISCE2/MintPy line, not the current Gamma SBAS-InSAR production line.
## Decision
The ISCE2/MintPy time-series production chain is deprecated and disabled by default.
The current SBAS-InSAR production authority is:
```text
Frontend view: sbas_insar_production
Backend route: /api/sbas-insar-production
Engine: Gamma
Workflow: DIFF + IPTA SBAS
```
The legacy code is not physically deleted yet. It remains only as compatibility and historical-reference code until the Gamma SBAS workflow can be tested end to end and historical result access is confirmed.
## Changes Made
Backend configuration:
- `backend/app/config.py`
- `TIMESERIES_ENABLED` default changed from `true` to `false`.
- Legacy `TIMESERIES_*` experiment/script defaults are now populated only when `TIMESERIES_ENABLED=true`.
- `ensure_dirs()` no longer creates `TIMESERIES_WORK_ROOT` unless the legacy chain is explicitly enabled.
- Runtime validation now reports an info line instead of warning about missing legacy experiment scripts when the chain is disabled.
Environment example:
- `.env.example`
- `TIMESERIES_ENABLED=false`
- `TIMESERIES_EXPERIMENT_ROOT=` is blank.
- `TIMESERIES_DEFAULT_PROCESSOR_CODE=legacy_isce2_stack_mintpy`
Frontend production management:
- `frontend/src/config/appConstants.js`
- Removed production workspace views:
- `timeseries_runs`
- `timeseries_products`
- Legacy route aliases now map to the Gamma SBAS page:
- `ps_production -> sbas_insar_production`
- `ps_products -> sbas_insar_production`
- `frontend/src/ProductionWorkspace.jsx`
- Removed lazy imports and render branches for:
- `TimeseriesProductionPanel`
- production-management `PsinsarCatalogPanel`
- Updated production workspace text to describe Gamma SBAS as an independent entry.
- `frontend/src/components/app/AppSidePanel.jsx`
- Updated production-management description to state that the old ISCE2/MintPy time-series entry is disabled.
Documentation:
- `docs/SBAS_INSAR_PRODUCTION_PIPELINE_DESIGN_20260519.md`
- Added the legacy-chain deprecation decision.
- `docs/FRONTEND_NAVIGATION_ARCHITECTURE.md`
- Updated production-management internal views to:
- `dinsar_runs`
- `sbas_insar_production`
- `dinsar_products`
## Current Behavior
After backend restart, deployment validation should no longer warn about the removed `experiments/isce2_sbas_timeseries` path.
Expected validation line:
```text
[INFO] Legacy ISCE2/MintPy timeseries pipeline is disabled; current SBAS-InSAR production uses the Gamma /sbas-insar-production workflow.
```
The production-management page should show:
```text
D-InSAR 运行
SBAS-InSAR Production
D-InSAR 产物
```
It should no longer expose:
```text
时序InSAR 运行
时序InSAR 产物
```
## Verification
Completed on 2026-05-21:
- Frontend build passed:
```text
npm run build
```
- Runtime configuration check passed:
```text
scripts/check_runtime_config.py
```
Observed output included:
```text
[INFO] Legacy ISCE2/MintPy timeseries pipeline is disabled; current SBAS-InSAR production uses the Gamma /sbas-insar-production workflow.
[OK] Deployment configuration check passed.
```
- Backend config syntax was checked with Python AST parsing.
`python -m py_compile backend/app/config.py` was not used as the final check because Windows denied replacement of an existing `__pycache__` file. This was a local cache-permission issue, not a syntax failure.
## Retained Compatibility Code
The following code is intentionally retained for now:
```text
backend/app/routers/timeseries_production.py
backend/app/services/timeseries_service.py
frontend/src/TimeseriesProductionPanel.jsx
frontend/src/api/timeseriesProduction.js
frontend/src/components/PsinsarCatalogPanel.jsx
```
Database tables and historical product catalog structures such as `ps_timeseries_runs` are also retained.
`PsinsarCatalogPanel` may still be useful outside production management, especially for analysis/result browsing. Do not delete it until those usages are audited.
## Re-Enabling Legacy Chain
Re-enabling the legacy ISCE2/MintPy chain is not part of the current production plan.
If it must be revived for a controlled comparison, the operator must explicitly set:
```text
TIMESERIES_ENABLED=true
```
and provide valid values for all legacy experiment/script paths. The removed `experiments/isce2_sbas_timeseries` directory is no longer assumed to exist.
## Follow-Up Cleanup Criteria
Physical deletion of the legacy chain should wait until all of the following are true:
- Gamma SBAS production has completed an end-to-end run from stack discovery to published LOS velocity/sigma products.
- Historical `ps_timeseries_runs` and old time-series product records have a clear migration or read-only archival plan.
- Frontend navigation, route aliases, and analysis pages have been audited for remaining dependencies.
- Backend callers of `/api/timeseries-production` have either been removed or explicitly marked as legacy-only.
- Test coverage or manual regression notes confirm that D-InSAR production, SBAS production, product browsing, and task monitoring still work.