- add documentation governance and cleanup audit documents - update README and docs index to distinguish current vs historical sources - move superseded planning, SBAS, Gamma, and experiment notes into docs/archive - fix remaining archive text garbling in two documents
681 lines
13 KiB
Markdown
681 lines
13 KiB
Markdown
# SBAS InSAR 嵌入系统设计稿
|
||
|
||
更新日期:2026-04-06
|
||
|
||
## 1. 设计目标
|
||
|
||
目标不是把当前实验脚本“塞进系统”,而是把已经验证成功的 SBAS 路线变成系统内可提交、可跟踪、可复跑、可发布的正式能力。
|
||
|
||
设计必须同时满足四个约束:
|
||
|
||
- 不破坏现有 D-InSAR 生产
|
||
- 尽量复用现有 `task` / `job` / `workflow` / `result catalog` 骨架
|
||
- 以发布级 bundle 作为系统注册边界,而不是 MintPy 运行目录
|
||
- 保留 WSL + conda 的现实部署方式,但把路径和环境耦合收敛到专门层
|
||
|
||
## 2. 设计原则
|
||
|
||
### 2.1 规划层和生产层分离
|
||
|
||
现有:
|
||
|
||
- `find-ps-timeseries`
|
||
- `ps_task_batches`
|
||
- `ps_task_items`
|
||
|
||
这些应该继续保留,但它们只负责:
|
||
|
||
- 选片
|
||
- 栈定义
|
||
- 输入快照
|
||
|
||
它们不应该继续承担:
|
||
|
||
- 生产运行主记录
|
||
- 产物发布状态
|
||
- 重试与失败恢复
|
||
|
||
### 2.2 一个 SBAS 运行对应一个发布 bundle
|
||
|
||
不要把 SBAS 多个文件当成多个独立产品行。
|
||
|
||
推荐模型:
|
||
|
||
- 一个 `ps_timeseries_run`
|
||
- 对应一个 publish bundle
|
||
- 对应 `result_products` 中一条 `psinsar` 产品记录
|
||
- bundle 内部多个文件通过 `result_assets` 管理
|
||
|
||
这样最贴合当前系统的 `result_products -> result_assets` 结构。
|
||
|
||
### 2.3 发布边界固定为 `manifest.json`
|
||
|
||
系统不直接注册:
|
||
|
||
- `stack_work/`
|
||
- `mintpy_work/`
|
||
- `timeseries.h5`
|
||
- 任意临时中间目录
|
||
|
||
系统只注册:
|
||
|
||
- `publish/.../manifest.json`
|
||
|
||
原因:
|
||
|
||
- 这是当前实验里最稳定的对外契约
|
||
- 它天然适合作为 catalog rebuild 和产品详情入口
|
||
- 它把运行时目录与发布目录分开了
|
||
|
||
### 2.4 Phase 1 优先“隔离集成”,不优先“统一重构”
|
||
|
||
当前 `result_catalog_service` 明显偏 D-InSAR。
|
||
|
||
因此 Phase 1 不建议直接大改现有 D-InSAR catalog 服务为完全泛化版本。
|
||
|
||
更稳妥的做法是:
|
||
|
||
- 新增 `psinsar_catalog_service.py`
|
||
- 接口风格与 `result_catalog_service.py` 保持一致
|
||
- 底层继续复用 `result_products` / `result_assets` / `result_issues`
|
||
|
||
等 SBAS 生产链跑稳后,再提炼公共基类。
|
||
|
||
## 3. 目标架构
|
||
|
||
推荐分成五层。
|
||
|
||
### 3.1 规划层
|
||
|
||
复用现有:
|
||
|
||
- `POST /find-ps-timeseries`
|
||
- `POST /task-batches/ps`
|
||
|
||
职责:
|
||
|
||
- 根据 AOI 和筛选条件找到时间序列候选栈
|
||
- 生成一个可复用的 `ps_task_batch`
|
||
|
||
### 3.2 生产控制层
|
||
|
||
新增:
|
||
|
||
- `ps_timeseries_runs`
|
||
- `timeseries_production.py`
|
||
- `timeseries_service.py`
|
||
|
||
职责:
|
||
|
||
- 从一个 `ps_task_batch` 派生一次正式运行
|
||
- 固化参数、环境、输入路径、输出路径、DEM、轨道、水体掩膜策略
|
||
- 对接 `system_tasks` / `system_jobs` / `workflow_runs`
|
||
|
||
### 3.3 执行编排层
|
||
|
||
复用现有:
|
||
|
||
- `system_tasks`
|
||
- `system_jobs`
|
||
- `workflow_runs`
|
||
- `workflow_steps`
|
||
- `workflow_artifacts`
|
||
|
||
新增:
|
||
|
||
- `timeseries_workflow_factory.py`
|
||
- `mintpy_service.py`
|
||
- `isce2_stack_service.py`
|
||
|
||
职责:
|
||
|
||
- 把一次 SBAS 运行拆成多个受控步骤
|
||
- 每一步进入统一 worker
|
||
- 失败可定位到 step,而不是只看到“整条链失败”
|
||
|
||
### 3.4 发布与编目层
|
||
|
||
新增:
|
||
|
||
- `psinsar_catalog_service.py`
|
||
- `ps_products.py`
|
||
|
||
复用:
|
||
|
||
- `result_products`
|
||
- `result_assets`
|
||
- `result_issues`
|
||
- `result_catalog_states`
|
||
|
||
职责:
|
||
|
||
- 扫描和注册 `psinsar.publish.v1`
|
||
- 管理产品详情、预览、健康检查、重建
|
||
|
||
### 3.5 展示层
|
||
|
||
新增页面:
|
||
|
||
- `ps_production`
|
||
- `ps_products`
|
||
- `psinsar_results`
|
||
|
||
职责:
|
||
|
||
- 运行提交与监控
|
||
- 产品浏览与筛选
|
||
- 结果详情、预览和下载
|
||
|
||
## 4. 核心数据模型
|
||
|
||
## 4.1 新增业务表:`ps_timeseries_runs`
|
||
|
||
建议字段:
|
||
|
||
- `run_id`
|
||
- `batch_id`
|
||
- `run_name`
|
||
- `catalog_name`
|
||
- `mode`
|
||
- `sbas`
|
||
- `engine_code`
|
||
- `isce2`
|
||
- `processor_code`
|
||
- `isce2_stack_mintpy`
|
||
- `env_name`
|
||
- 例如 `isce2_mintpy_v1`
|
||
- `wsl_distro`
|
||
- 例如 `Ubuntu-24.04`
|
||
- `status`
|
||
- `PENDING` / `RUNNING` / `FAILED` / `COMPLETED` / `PUBLISHED`
|
||
- `workflow_run_id`
|
||
- `task_id`
|
||
- `direction`
|
||
- `stack_size`
|
||
- `reference_date`
|
||
- `water_mask_mode`
|
||
- `local` / `synthetic_fallback`
|
||
- `dem_path_windows`
|
||
- `dem_path_wsl`
|
||
- `orbit_pool_windows`
|
||
- `orbit_pool_wsl`
|
||
- `work_root_windows`
|
||
- `work_root_wsl`
|
||
- `publish_dir_windows`
|
||
- `publish_dir_wsl`
|
||
- `manifest_path_windows`
|
||
- `manifest_path_wsl`
|
||
- `params_json`
|
||
- `summary_json`
|
||
- `input_snapshot_json`
|
||
- `orbit_summary_json`
|
||
- `quality_summary_json`
|
||
- `error_message`
|
||
- `created_by`
|
||
- `created_at`
|
||
- `updated_at`
|
||
- `started_at`
|
||
- `ended_at`
|
||
|
||
### 4.2 不新增产品主表
|
||
|
||
继续使用:
|
||
|
||
- `result_products`
|
||
- `result_assets`
|
||
- `result_issues`
|
||
|
||
但对 `psinsar` 约定如下:
|
||
|
||
- `catalog_name = psinsar`
|
||
- `product_type = psinsar_bundle`
|
||
- `engine_code = isce2`
|
||
- `task_alias` 存运行展示名
|
||
- `run_key` 直接绑定 `ps_timeseries_runs.run_id`
|
||
|
||
原因:
|
||
|
||
- 当前系统的产品层本来就是“一个产品行 + 多资产”
|
||
- SBAS publish bundle 天然适合这种结构
|
||
|
||
### 4.3 `result_assets.asset_role` 约定
|
||
|
||
建议统一定义以下资产角色:
|
||
|
||
- `timeseries_cube`
|
||
- `velocity_h5`
|
||
- `velocity_geotiff`
|
||
- `temporal_coherence_h5`
|
||
- `temporal_coherence_geotiff`
|
||
- `quality_mask_h5`
|
||
- `quality_mask_geotiff`
|
||
- `preview_png`
|
||
- `diagnostic_png`
|
||
- `config`
|
||
- `quality_summary`
|
||
- `input_manifest`
|
||
|
||
### 4.4 精轨 provenance 建议
|
||
|
||
最小建议不是新表,而是先把运行级 summary 做扎实。
|
||
|
||
在 `ps_timeseries_runs.orbit_summary_json` 中记录:
|
||
|
||
- 每景影像日期
|
||
- 轨道 stem
|
||
- 轨道 XML 路径
|
||
- 来源
|
||
- `existing_xml` / `generated_from_txt`
|
||
- checksum
|
||
- 是否来自 ISCE2 pool
|
||
|
||
Phase 2 再考虑单独抽 `orbit_assets`。
|
||
|
||
## 5. 路径与目录设计
|
||
|
||
## 5.1 总原则
|
||
|
||
- 原始影像目录不复制
|
||
- 工作目录和发布目录必须分离
|
||
- 发布目录一旦注册,尽量不再原地改写
|
||
|
||
### 5.2 推荐目录结构
|
||
|
||
Windows 侧:
|
||
|
||
```text
|
||
<TIMESERIES_WORK_ROOT>\{run_id}\
|
||
input\
|
||
stack\
|
||
mintpy\
|
||
logs\
|
||
publish\
|
||
```
|
||
|
||
WSL 侧:
|
||
|
||
```text
|
||
/mnt/.../timeseries_work/{run_id}/
|
||
input/
|
||
stack/
|
||
mintpy/
|
||
logs/
|
||
publish/
|
||
```
|
||
|
||
正式发布根目录:
|
||
|
||
```text
|
||
<PSINSAR_PRODUCT_DIR>\{year}\{run_id}\
|
||
manifest.json
|
||
assets/
|
||
preview/
|
||
metadata/
|
||
```
|
||
|
||
### 5.3 路径服务
|
||
|
||
不要在 job handler、router、script wrapper 里反复手拼 `/mnt/z`。
|
||
|
||
新增:
|
||
|
||
- `timeseries_paths.py`
|
||
|
||
统一负责:
|
||
|
||
- Windows -> WSL 路径转换
|
||
- 运行目录分配
|
||
- 发布目录分配
|
||
- 产物入口路径解析
|
||
|
||
## 6. 工作流设计
|
||
|
||
推荐 workflow name:
|
||
|
||
- `isce2_sbas_mintpy_v1`
|
||
|
||
推荐步骤如下。
|
||
|
||
### Step 1 `prepare_stack_input`
|
||
|
||
输入:
|
||
|
||
- `batch_id`
|
||
- 运行参数
|
||
|
||
动作:
|
||
|
||
- 读取 `ps_task_items`
|
||
- 校验栈大小、方向一致性、日期连续性
|
||
- 固化 `input_snapshot_json`
|
||
- 解析 DEM、轨道池、输出路径
|
||
- 生成 stack manifest
|
||
|
||
产物:
|
||
|
||
- `stack_input_manifest.json`
|
||
- `source stack snapshot`
|
||
|
||
### Step 2 `materialize_stack_scenes`
|
||
|
||
动作:
|
||
|
||
- 复用现有实验脚本逻辑
|
||
- 为每景影像生成 `SLC/<date>/`
|
||
- 显式写入 `sensor.orbitFile`
|
||
|
||
产物:
|
||
|
||
- 物化后的 SLC
|
||
- `materialization_summary.json`
|
||
|
||
### Step 3 `run_isce2_stack`
|
||
|
||
动作:
|
||
|
||
- 运行 stripmapStack 预处理链
|
||
- 生成几何、配准、干涉网络基础产物
|
||
|
||
产物:
|
||
|
||
- stack work 目录
|
||
- run files
|
||
- log files
|
||
|
||
### Step 4 `run_mintpy_sbas`
|
||
|
||
动作:
|
||
|
||
- 运行 `smallbaselineApp`
|
||
- 生成 `timeseries.h5`、`velocity.h5`、`temporalCoherence.h5`
|
||
- 记录 MintPy 版本、参数模板、参考点信息
|
||
|
||
产物:
|
||
|
||
- MintPy work 目录
|
||
- inversion quality summary
|
||
|
||
### Step 5 `export_publish_bundle`
|
||
|
||
动作:
|
||
|
||
- 地理编码
|
||
- 导出 GeoTIFF
|
||
- 生成 preview
|
||
- 写出 `manifest.json`
|
||
|
||
产物:
|
||
|
||
- `publish/.../manifest.json`
|
||
- `assets/`
|
||
- `preview/`
|
||
- `metadata/`
|
||
|
||
### Step 6 `register_psinsar_product`
|
||
|
||
动作:
|
||
|
||
- 调用 `psinsar_catalog_service`
|
||
- 把 bundle 注册进 `result_products`
|
||
- 回填 `ps_timeseries_runs.manifest_path_*`
|
||
|
||
产物:
|
||
|
||
- `result_products` 一条记录
|
||
- `result_assets` 多条记录
|
||
|
||
### Step 7 `post_check`
|
||
|
||
动作:
|
||
|
||
- 校验关键资产是否存在
|
||
- 校验 `velocity.tif` / `geo_timeseries.h5` / `temporalCoherence.tif`
|
||
- 生成最终健康状态
|
||
|
||
## 7. 调度与任务设计
|
||
|
||
## 7.1 一个用户可见主任务
|
||
|
||
建议每次 SBAS 运行只创建一个主 `system_task`:
|
||
|
||
- `task_type = RUN_PSINSAR_PRODUCTION`
|
||
|
||
用户在 UI 上主要看这条任务。
|
||
|
||
### 7.2 一个工作流运行
|
||
|
||
创建:
|
||
|
||
- `workflow_run`
|
||
|
||
每个步骤单独入 `workflow_steps`。
|
||
|
||
worker 现有能力已经支持:
|
||
|
||
- job 完成后自动 `mark_step_completed`
|
||
- job 失败后自动 `mark_step_failed`
|
||
|
||
因此不需要再发明新的 step 状态机制。
|
||
|
||
### 7.3 建议 job types
|
||
|
||
- `TIMESERIES_PREP_STACK`
|
||
- `TIMESERIES_MATERIALIZE_STACK`
|
||
- `TIMESERIES_RUN_ISCE2_STACK`
|
||
- `TIMESERIES_RUN_MINTPY_SBAS`
|
||
- `TIMESERIES_EXPORT_PRODUCTS`
|
||
- `TIMESERIES_REGISTER_PRODUCTS`
|
||
- `TIMESERIES_POST_CHECK`
|
||
|
||
## 8. 环境设计
|
||
|
||
## 8.1 运行环境原则
|
||
|
||
不修改现有 D-InSAR 使用的 `isce2` 环境。
|
||
|
||
SBAS 生产使用独立统一环境:
|
||
|
||
- WSL distro:`Ubuntu-24.04`
|
||
- conda env:建议 `isce2_mintpy_v1`
|
||
|
||
这是当前实验已验证成功的路线。
|
||
|
||
### 8.2 配置隔离
|
||
|
||
不要直接复用所有 `ISCE2_*` 配置项来承载 SBAS。
|
||
|
||
建议新增:
|
||
|
||
- `TIMESERIES_ENABLED`
|
||
- `TIMESERIES_WSL_DISTRO`
|
||
- `TIMESERIES_PYTHON`
|
||
- `TIMESERIES_ENV_NAME`
|
||
- `TIMESERIES_WORK_ROOT`
|
||
- `TIMESERIES_PUBLISH_ROOT`
|
||
- `TIMESERIES_DEM_PATH`
|
||
- `TIMESERIES_ORBIT_POOL_ISCE2`
|
||
- `TIMESERIES_WATER_MASK_ROOT`
|
||
- `TIMESERIES_ALLOW_SYNTHETIC_WATER_MASK`
|
||
- `TIMESERIES_SMALLBASELINE_TEMPLATE`
|
||
|
||
其中可允许默认回退:
|
||
|
||
- `TIMESERIES_WSL_DISTRO -> ISCE2_WSL_DISTRO`
|
||
- `TIMESERIES_DEM_PATH -> ISCE2_DEM_PATH`
|
||
- `TIMESERIES_ORBIT_POOL_ISCE2 -> ORBIT_POOL_ISCE2`
|
||
|
||
## 9. 精轨、DEM、水体掩膜策略
|
||
|
||
## 9.1 精轨
|
||
|
||
直接复用现有:
|
||
|
||
- source orbit scan
|
||
- ENVI / ISCE2 orbit pool sync
|
||
- LT-1 orbit XML 解析/生成 helper
|
||
|
||
生产要求:
|
||
|
||
- 每景影像在运行前就解析到明确 orbit XML
|
||
- 运行记录中保存 orbit provenance
|
||
|
||
## 9.2 DEM
|
||
|
||
生产态不依赖在线下载。
|
||
|
||
要求:
|
||
|
||
- 本地 DEM 路径必须可读
|
||
- 运行记录中固定写入 DEM 路径与版本描述
|
||
|
||
## 9.3 水体掩膜
|
||
|
||
这里要区分实验和生产。
|
||
|
||
实验态:
|
||
|
||
- 允许 `synthetic waterMask fallback`
|
||
|
||
生产态建议:
|
||
|
||
- 优先本地水体数据源
|
||
- 若只能 synthetic fallback,则产品可生成,但 `health_status = WARN`
|
||
- UI 上必须显式标注“使用了 synthetic water mask”
|
||
|
||
## 10. `psinsar` 产品注册策略
|
||
|
||
## 10.1 产品行设计
|
||
|
||
`result_products` 一条记录代表一个 SBAS bundle,而不是单个文件。
|
||
|
||
推荐约定:
|
||
|
||
- `product_id = psinsar_<run_id>`
|
||
- `catalog_name = psinsar`
|
||
- `product_type = psinsar_bundle`
|
||
- `display_name = SBAS_<direction>_<reference_date>_<run_id short>`
|
||
- `source_primary_path = assets/geo_timeseries.h5`
|
||
- `primary_asset_path = assets/velocity.tif`
|
||
- `preview_path = preview/velocity_preview.png`
|
||
|
||
### 10.2 产品详情展示
|
||
|
||
产品详情页重点展示:
|
||
|
||
- 栈日期列表
|
||
- 参考日期
|
||
- 方向
|
||
- DEM
|
||
- 轨道来源
|
||
- 速度图预览
|
||
- 时间序列 cube 下载
|
||
- 质量图层下载
|
||
- 运行日志入口
|
||
|
||
## 11. API 设计
|
||
|
||
### 11.1 生产接口
|
||
|
||
- `POST /timeseries-production/runs`
|
||
- 基于 `batch_id` 提交一次 SBAS 运行
|
||
- `GET /timeseries-production/runs`
|
||
- 列表
|
||
- `GET /timeseries-production/runs/{run_id}`
|
||
- 详情
|
||
- `POST /timeseries-production/runs/{run_id}/retry-step`
|
||
- 重试单步
|
||
- `POST /timeseries-production/wsl-check`
|
||
- 环境检查
|
||
|
||
### 11.2 产品接口
|
||
|
||
- `GET /ps-products/catalog-status`
|
||
- `POST /ps-products/rebuild`
|
||
- `GET /ps-products`
|
||
- `GET /ps-products/{product_id}`
|
||
- `GET /ps-products/{product_id}/preview`
|
||
|
||
## 12. 前端页面设计
|
||
|
||
### 12.1 `ps_production`
|
||
|
||
页面模块:
|
||
|
||
- 选择已有 `ps_task_batch`
|
||
- 设定运行参数
|
||
- 提交运行
|
||
- 查看步骤进度
|
||
- 查看失败原因和重试按钮
|
||
|
||
### 12.2 `ps_products`
|
||
|
||
页面模块:
|
||
|
||
- 产品列表
|
||
- AOI / 时间 / 方向 / 状态筛选
|
||
- preview 缩略图
|
||
- 一键跳转到产品详情
|
||
|
||
### 12.3 `psinsar_results`
|
||
|
||
页面模块:
|
||
|
||
- 地图展示 `velocity.tif`
|
||
- 质量图层切换
|
||
- 时间序列主资产下载
|
||
- 后续再扩展点时序查询
|
||
|
||
## 13. 推荐实施顺序
|
||
|
||
### Phase A:最小生产主链
|
||
|
||
- 新增 `ps_timeseries_runs`
|
||
- 新增 `timeseries_production.py`
|
||
- 新增 workflow factory
|
||
- 先直接复用实验脚本作为受控 worker wrapper
|
||
|
||
目标:
|
||
|
||
- 系统能发起一次 SBAS 运行
|
||
- 能看到步骤状态
|
||
- 能落到 publish bundle
|
||
|
||
### Phase B:产品注册
|
||
|
||
- 新增 `psinsar_catalog_service.py`
|
||
- 新增 `ps_products.py`
|
||
- 注册 `psinsar.publish.v1`
|
||
|
||
目标:
|
||
|
||
- 发布 bundle 能在系统里被浏览和重建
|
||
|
||
### Phase C:稳定性与治理
|
||
|
||
- 增加 orbit provenance
|
||
- 增加 DEM / water mask 质量标记
|
||
- 增加 post-check 和 health-check
|
||
- 完善路径服务
|
||
|
||
### Phase D:UI 完善
|
||
|
||
- 补生产页
|
||
- 补产品页
|
||
- 补结果页
|
||
|
||
## 14. 最终建议
|
||
|
||
结合当前审计结果,最稳妥的路线不是“直接把 SBAS 纳入现有 D-InSAR 产品通道”,而是:
|
||
|
||
1. 继续复用 `ps_task_batches` 作为输入栈定义
|
||
2. 新增 `ps_timeseries_runs` 作为生产主记录
|
||
3. 复用现有任务、作业、工作流骨架
|
||
4. 以 publish bundle 为产品注册边界
|
||
5. 先独立实现 `psinsar_catalog_service`,避免影响现有 D-InSAR 生产
|
||
|
||
这样可以做到:
|
||
|
||
- 技术上最贴合现有系统
|
||
- 风险上最小
|
||
- 后续也最容易把实验链稳稳升级成正式生产链
|