docs: govern and archive superseded notes
- 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
This commit is contained in:
@@ -164,7 +164,7 @@ GET /api/ai-diagnosis?page=1&limit=20&result_id=123&risk_level=HIGH&sort=-create
|
||||
GET /api/ai-diagnosis/{id}
|
||||
```
|
||||
|
||||
**响��**:
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"id": 42,
|
||||
|
||||
@@ -0,0 +1,426 @@
|
||||
# D-InSAR 增强 Task 文档
|
||||
|
||||
更新日期:2026-03-13
|
||||
|
||||
## 1. 文档目的
|
||||
|
||||
这份文档用于统一管理本轮 D-InSAR 系统重构任务,覆盖以下两大方向:
|
||||
|
||||
- D-InSAR 多引擎生产系统增强
|
||||
- D-InSAR 结果管理系统增强
|
||||
|
||||
文档定位是“任务总表 + 实施边界 + 验收口径”,用于后续分阶段实施、联调和运维验收。
|
||||
|
||||
## 2. 背景
|
||||
|
||||
当前系统的 D-InSAR 生产能力主要绑定在 ENVI + SARscape 链路上,前端、后端任务模型、运行监控和结果入库都默认只有一个处理引擎。这会带来两个直接问题:
|
||||
|
||||
- 客户如果没有 ENVI/SARscape license,D-InSAR 核心生产能力会直接失效。
|
||||
- 后续接入 ISCE2、LANDSAR 时,只能继续堆在现有 IDL/ENVI 语义上,导致架构持续恶化。
|
||||
|
||||
同时,当前 D-InSAR 结果管理能力偏轻,更多是“结果浏览 + 缓存管理”,还不足以支撑多引擎、多版本、多产物、多轮生产的正式管理需求。
|
||||
|
||||
## 3. 本轮目标
|
||||
|
||||
### 3.1 生产系统目标
|
||||
|
||||
- 将 D-InSAR 生产系统升级为“多引擎生产中心”
|
||||
- 正式支持两类可执行引擎:
|
||||
- `sarscape`:ENVI + SARscape
|
||||
- `isce2`:WSL 内部署的 ISCE2
|
||||
- 预留第三类引擎:
|
||||
- `landsar`:仅保留接口和前端占位,不实现算法
|
||||
- 将运维自检升级为“系统级 + D-InSAR 专项级”双层检查
|
||||
|
||||
### 3.2 结果管理目标
|
||||
|
||||
- 将 D-InSAR 结果从“单文件记录”升级为“可追踪、可治理、可比对”的结果资产
|
||||
- 支持来源追踪、版本管理、多产物管理、审核状态和运维治理
|
||||
- 让结果管理适配多引擎场景,而不是继续依赖单一文件命名和单一路径假设
|
||||
|
||||
## 4. 范围与非范围
|
||||
|
||||
### 4.1 本轮范围
|
||||
|
||||
- 多引擎 D-InSAR 后端抽象层
|
||||
- 新 D-InSAR 生产中心前端架构
|
||||
- ENVI/SARscape 的兼容接入
|
||||
- ISCE2 的 WSL 环境校验与运行接口
|
||||
- 运维自检与 D-InSAR 专项健康检查
|
||||
- D-InSAR 结果管理增强
|
||||
|
||||
### 4.2 明确不在本轮范围
|
||||
|
||||
- LANDSAR 算法实现
|
||||
- 对现有配对算法本身做大幅重写
|
||||
- 对 AI 诊断能力做独立重构
|
||||
- 一次性替换全部旧接口
|
||||
|
||||
## 5. 现状要点
|
||||
|
||||
### 5.1 ENVI 现有处理模式
|
||||
|
||||
当前 ENVI 侧应明确建模为 `sarscape` 引擎下的两种 profile:
|
||||
|
||||
- `metatask`
|
||||
- `custom6`
|
||||
|
||||
其中 `custom6` 的 6 步链路为:
|
||||
|
||||
1. Interferogram Generation
|
||||
2. Filtering and Coherence
|
||||
3. Orbital Trend Removal
|
||||
4. Phase Unwrapping
|
||||
5. GCP Generation + Refinement
|
||||
6. Phase to Displacement + Geocoding
|
||||
|
||||
### 5.2 ISCE2 的特殊约束
|
||||
|
||||
ISCE2 不走本机 Windows 直接执行链路,默认按 WSL 方式部署与运行,因此必须把 WSL 环境校验设计成正式能力,而不是上线前人工检查事项。
|
||||
|
||||
### 5.3 当前结果管理主要短板
|
||||
|
||||
- 结果记录字段偏少,缺少引擎来源、运行来源、版本、产物类型等核心字段
|
||||
- 结果入库逻辑仍偏向单文件扫描,不适合多引擎多版本
|
||||
- 前端结果面板偏重展示,缺少治理、比对、版本和来源追踪能力
|
||||
- 运维自检尚未覆盖结果资产层面的异常
|
||||
|
||||
## 6. Task 总览
|
||||
|
||||
| Task ID | 主题 | 目标 |
|
||||
|---|---|---|
|
||||
| T1 | 多引擎生产基座 | 建立统一的 D-InSAR 引擎抽象、调度和兼容层 |
|
||||
| T2 | 前端生产中心 | 将现有 IDL 自动化面板升级为多引擎生产中心 |
|
||||
| T3 | SARSCAPE 兼容接入 | 将现有 ENVI 链路适配到新抽象层 |
|
||||
| T4 | ISCE2 + WSL 接入 | 建立 ISCE2 的 WSL 检查、运行和日志链路 |
|
||||
| T5 | 运维自检增强 | 增加多引擎专项健康检查和自愈入口 |
|
||||
| T6 | 结果管理增强 | 将 D-InSAR 结果升级为正式结果资产管理体系 |
|
||||
|
||||
## 7. 任务拆分
|
||||
|
||||
### T1. 多引擎生产基座
|
||||
|
||||
#### 目标
|
||||
|
||||
- 将 D-InSAR 生产从 `IDL/ENVI 单引擎假设` 中抽离
|
||||
- 为 `sarscape`、`isce2`、`landsar` 建立统一抽象
|
||||
|
||||
#### 关键任务
|
||||
|
||||
- 定义统一引擎接口
|
||||
- 建立引擎注册表
|
||||
- 建立统一运行记录模型
|
||||
- 建立统一产物收集与入库接口
|
||||
- 保留旧 `/idl/...` 路由兼容转发能力
|
||||
|
||||
#### 目标结构
|
||||
|
||||
- `dinsar_engines/base.py`
|
||||
- `dinsar_engines/registry.py`
|
||||
- `dinsar_engines/sarscape_engine.py`
|
||||
- `dinsar_engines/isce2_engine.py`
|
||||
- `dinsar_engines/landsar_engine.py`
|
||||
- `dinsar_orchestrator.py`
|
||||
|
||||
#### 验收标准
|
||||
|
||||
- 新生产调度层可按 `engine_code` 分发
|
||||
- `sarscape`、`isce2`、`landsar` 均可在注册表中查询到
|
||||
- 旧 ENVI 生产功能不回归
|
||||
|
||||
### T2. 前端生产中心
|
||||
|
||||
#### 目标
|
||||
|
||||
- 用统一生产中心替代当前单引擎 `IDLAutomationPanel`
|
||||
- 支持多引擎选择、运行监控、日志查看和结果入库操作
|
||||
|
||||
#### 前端信息架构
|
||||
|
||||
- 引擎状态区
|
||||
- SARSCAPE
|
||||
- ISCE2
|
||||
- LANDSAR
|
||||
- 生产提交区
|
||||
- 批次选择
|
||||
- 引擎选择
|
||||
- profile 选择
|
||||
- 输入/输出目录
|
||||
- 参数模板
|
||||
- 运行监控区
|
||||
- 当前任务
|
||||
- 步骤进度
|
||||
- 运行日志
|
||||
- 历史记录
|
||||
- 产物处理区
|
||||
- 提取
|
||||
- 入库
|
||||
- 重扫
|
||||
- 缓存重建
|
||||
|
||||
#### 关键任务
|
||||
|
||||
- 新建 `DinsarProductionPanel`
|
||||
- 废弃前端对 `/idl/...` 语义的直接依赖
|
||||
- 增加引擎状态卡和 WSL 状态卡
|
||||
- 运行记录中展示 `engine`、`profile`、`run_id`
|
||||
|
||||
#### 验收标准
|
||||
|
||||
- 前端可以清晰区分三类引擎状态
|
||||
- `landsar` 显示为预留,不可执行
|
||||
- 当 ENVI 不可用但 ISCE2 可用时,页面仍可提交 ISCE2 任务
|
||||
|
||||
### T3. SARSCAPE 兼容接入
|
||||
|
||||
#### 目标
|
||||
|
||||
- 将现有 ENVI 链路正式纳入新生产体系
|
||||
- 明确 `metatask` 与 `custom6` 是同一引擎下的两个 profile
|
||||
|
||||
#### 关键任务
|
||||
|
||||
- 封装现有 ENVI 运行逻辑为 `sarscape_engine`
|
||||
- 将 `metatask` 和 `custom6` 暴露为 profile
|
||||
- 保留进度文件、日志、超时监控和历史运行能力
|
||||
|
||||
#### 验收标准
|
||||
|
||||
- 旧 ENVI 作业仍可执行
|
||||
- 新系统中可选择 `sarscape/metatask` 与 `sarscape/custom6`
|
||||
- 原有任务状态、日志和结果提取行为保持兼容
|
||||
|
||||
### T4. ISCE2 + WSL 接入
|
||||
|
||||
#### 目标
|
||||
|
||||
- 建立 ISCE2 运行的正式环境检查、任务执行和输出接入能力
|
||||
|
||||
#### WSL 环境校验任务
|
||||
|
||||
- 检查 WSL 是否安装
|
||||
- 检查是否支持 WSL2
|
||||
- 检查目标 distro 是否存在
|
||||
- 检查目标 distro 是否可启动
|
||||
- 检查 `bash -lc` 是否可执行
|
||||
- 检查 Python 是否可执行
|
||||
- 检查 ISCE2 是否可 import
|
||||
- 检查目标入口命令是否可执行
|
||||
- 检查 DEM 路径在 WSL 内是否可读
|
||||
- 检查轨道目录在 WSL 内是否可读
|
||||
- 检查输出目录在 WSL 内是否可写
|
||||
- 检查 Windows 路径到 WSL 路径转换是否正确
|
||||
- 增加可选 smoke test
|
||||
|
||||
#### 建议配置项
|
||||
|
||||
- `ISCE2_ENABLED`
|
||||
- `ISCE2_WSL_DISTRO`
|
||||
- `ISCE2_PYTHON`
|
||||
- `ISCE2_PROFILE`
|
||||
- `ISCE2_DEM_PATH`
|
||||
- `ISCE2_ORBIT_DIR`
|
||||
- `ISCE2_WORK_ROOT`
|
||||
- `ISCE2_OUTPUT_ROOT`
|
||||
- `ISCE2_SMOKE_TEST_ENABLED`
|
||||
|
||||
#### 关键任务
|
||||
|
||||
- 新建 `wsl_service.py`
|
||||
- 新建 `isce2_engine.py`
|
||||
- 建立 WSL 执行和日志封装
|
||||
- 将 ISCE2 输出纳入统一结果收集和入库流程
|
||||
|
||||
#### 验收标准
|
||||
|
||||
- 前端可见 ISCE2 环境状态
|
||||
- WSL 校验结果可解释、可定位故障点
|
||||
- ISCE2 至少有一个正式 profile 可提交并跑通
|
||||
|
||||
### T5. 运维自检增强
|
||||
|
||||
#### 目标
|
||||
|
||||
- 将当前“系统健康检查”升级为“系统级 + D-InSAR 专项级”双层运维自检
|
||||
|
||||
#### 关键任务
|
||||
|
||||
- 保留现有 `/health` 简版接口
|
||||
- 增加管理员详细健康接口
|
||||
- 增加多引擎专项检查
|
||||
- 增加 WSL 专项检查
|
||||
- 增加 D-InSAR 队列、存储、结果一致性检查
|
||||
- 增加自愈动作入口
|
||||
|
||||
#### 专项健康检查项
|
||||
|
||||
- 核心服务状态
|
||||
- 数据库
|
||||
- schema
|
||||
- worker
|
||||
- queue
|
||||
- 引擎状态
|
||||
- `sarscape`
|
||||
- `isce2`
|
||||
- `landsar`
|
||||
- WSL 状态
|
||||
- DEM/轨道/输出目录可用性
|
||||
- D-InSAR 运行任务积压
|
||||
- stale run 检测
|
||||
- 输出未入库检测
|
||||
- 入库但源文件缺失检测
|
||||
- 缓存一致性检测
|
||||
|
||||
#### 自愈入口建议
|
||||
|
||||
- 重扫结果目录
|
||||
- 重建缓存
|
||||
- 重试入库
|
||||
- 重置 stale run
|
||||
- 标记失效结果
|
||||
|
||||
#### 验收标准
|
||||
|
||||
- 运维面板能区分系统级故障与引擎级故障
|
||||
- 当 ENVI 不可用但 ISCE2 可用时,总体 D-InSAR 服务状态应为 `degraded` 或 `ok`,不能直接判全系统失败
|
||||
- WSL 故障能定位到具体检查项
|
||||
|
||||
### T6. 结果管理增强
|
||||
|
||||
#### 目标
|
||||
|
||||
- 将 D-InSAR 结果从“扫描到的一条文件记录”升级为“正式结果资产”
|
||||
|
||||
#### 核心设计
|
||||
|
||||
- `Run`
|
||||
- 一次真实生产执行
|
||||
- `Artifact`
|
||||
- 一次运行产出的具体文件
|
||||
- `Managed Result`
|
||||
- 面向前端与业务的主结果对象
|
||||
|
||||
#### 关键任务
|
||||
|
||||
- 扩充结果模型字段
|
||||
- 增加结果来源追踪
|
||||
- 增加版本管理
|
||||
- 增加多产物管理
|
||||
- 增加结果生命周期状态
|
||||
- 增加批量治理能力
|
||||
- 增加多引擎结果对比能力
|
||||
|
||||
#### 结果管理能力清单
|
||||
|
||||
- 来源追踪
|
||||
- engine
|
||||
- profile
|
||||
- batch
|
||||
- pair
|
||||
- run
|
||||
- 版本管理
|
||||
- 当前版本
|
||||
- 历史版本
|
||||
- 最新成功版本
|
||||
- 多产物管理
|
||||
- disp
|
||||
- coherence
|
||||
- unwrapped phase
|
||||
- geotiff
|
||||
- browse
|
||||
- log
|
||||
- 生命周期管理
|
||||
- `NEW`
|
||||
- `INGESTED`
|
||||
- `QC_PENDING`
|
||||
- `QC_PASSED`
|
||||
- `QC_REJECTED`
|
||||
- `PUBLISHED`
|
||||
- `ARCHIVED`
|
||||
- 批量操作
|
||||
- 发布
|
||||
- 归档
|
||||
- 重扫
|
||||
- 重建缓存
|
||||
- 重绑定来源
|
||||
- 导出
|
||||
- 检索增强
|
||||
- 按引擎
|
||||
- 按批次
|
||||
- 按任务名
|
||||
- 按状态
|
||||
- 按 AOI
|
||||
- 按版本
|
||||
|
||||
#### 前端结果管理架构建议
|
||||
|
||||
- 结果列表视图
|
||||
- 结果详情视图
|
||||
- 来源与版本视图
|
||||
- 治理与运维视图
|
||||
|
||||
#### 运维治理项
|
||||
|
||||
- 入库记录存在但源文件缺失
|
||||
- run 存在但 artifact 缺失
|
||||
- 当前版本指针异常
|
||||
- 同名结果冲突
|
||||
- 缓存与主文件不一致
|
||||
- 已发布结果未完成审核
|
||||
|
||||
#### 验收标准
|
||||
|
||||
- 同一对影像允许保留多引擎结果
|
||||
- 同一任务允许保留多版本
|
||||
- 结果详情页能追踪到来源 run 和主产物列表
|
||||
- 运维面板可识别结果资产层异常
|
||||
|
||||
## 8. 实施顺序
|
||||
|
||||
### Phase 1
|
||||
|
||||
- 完成多引擎与结果管理设计冻结
|
||||
- 完成接口契约
|
||||
- 完成数据模型草案
|
||||
|
||||
### Phase 2
|
||||
|
||||
- 实现后端抽象层
|
||||
- 完成 SARSCAPE 兼容接入
|
||||
- 保持旧接口兼容
|
||||
|
||||
### Phase 3
|
||||
|
||||
- 实现新前端生产中心
|
||||
- 实现引擎状态、运行监控和运维自检增强
|
||||
|
||||
### Phase 4
|
||||
|
||||
- 接入 ISCE2 + WSL
|
||||
- 打通首条正式生产链
|
||||
|
||||
### Phase 5
|
||||
|
||||
- 实现结果管理增强
|
||||
- 补齐版本、来源、治理与自愈
|
||||
|
||||
## 9. 交付顺序建议
|
||||
|
||||
建议按照以下顺序落地:
|
||||
|
||||
1. 先重构生产抽象层,不先碰最终结果治理细节
|
||||
2. 先让 `sarscape` 在新体系下跑通
|
||||
3. 再接入 `isce2`
|
||||
4. 最后再把结果管理全面升级
|
||||
|
||||
这样可以避免在“生产链尚未稳定”时提前锁死结果模型细节。
|
||||
|
||||
## 10. 当前结论
|
||||
|
||||
本轮不应被理解为“给当前 ENVI 面板再加一个 ISCE2 按钮”,而应被理解为:
|
||||
|
||||
- D-InSAR 生产系统平台化
|
||||
- D-InSAR 结果资产化
|
||||
- 运维自检从系统健康升级为多引擎专项健康
|
||||
|
||||
后续所有开发任务、联调任务和运维验收,均以本 Task 文档为总入口。
|
||||
@@ -121,7 +121,7 @@
|
||||
|------|------|
|
||||
| `backend/app/services/envi_service.py` | ENVI 工作流核心(6 步流程、GCP 生成、文件稳定等待) |
|
||||
| `backend/app/services/envi_runner_cli.py` | 子进程入口(加载 .env、调用 run_workflow) |
|
||||
| `backend/app/services/job_handlers.py` | Job handler(子进程监控、keepalive、文件稳定检查��� |
|
||||
| `backend/app/services/job_handlers.py` | Job handler(子进程监控、keepalive、文件稳定检查) |
|
||||
| `backend/app/services/job_worker.py` | Worker 主循环(心跳、stale 检测) |
|
||||
| `backend/app/services/task_service.py` | Task 管理(僵尸检测在 get_active_tasks 中) |
|
||||
| `backend/app/routers/tasks.py` | Task API(含 force-cancel 端点) |
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
# GAMMA + WSL2 双引擎集成方案
|
||||
|
||||
## Context
|
||||
|
||||
当前系统使用 ENVI/SARscape 做 D-InSAR 处理,速度慢(单对处理需数十分钟到数小时)。用户有 GAMMA License,希望在 Windows 服务器的 WSL2 中部署 GAMMA 作为第二处理引擎。ENVI 保留不动,用户可在前端选择用哪个引擎。
|
||||
|
||||
GAMMA 通过 WSL2 调用完全可行:`subprocess.run(['wsl', '-d', 'Ubuntu', 'bash', '-c', 'gamma_cmd ...'])`,与现有 ENVI 的 subprocess 模式一致。
|
||||
|
||||
---
|
||||
|
||||
## 架构对比
|
||||
|
||||
```
|
||||
ENVI 链路(保留不动):
|
||||
POST /idl/jobs/dinsar (engine=envi)
|
||||
→ SystemJob(IDL_RUN_DINSAR) → envi_runner_cli 子进程
|
||||
→ envi_dinsar.run_dinsar_custom_workflow() → 6步 SARscape
|
||||
→ envipyengine → taskengine.exe
|
||||
|
||||
GAMMA 链路(新增):
|
||||
POST /idl/jobs/dinsar (engine=gamma)
|
||||
→ SystemJob(GAMMA_RUN_DINSAR) → gamma_runner_cli 子进程
|
||||
→ gamma_dinsar.run_dinsar_workflow() → 9步 GAMMA CLI
|
||||
→ subprocess.run(['wsl', ...]) → GAMMA 原生命令
|
||||
```
|
||||
|
||||
两条链路共享:SystemTask/SystemJob 任务队列、progress.json 进度机制、job_worker 监控逻辑。
|
||||
|
||||
---
|
||||
|
||||
## 新增文件
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `backend/app/services/gamma_service.py` | WSL2 执行器、路径转换(win↔wsl)、配置读取、环境检查、进度写入 |
|
||||
| `backend/app/services/gamma_dinsar.py` | GAMMA D-InSAR 9步工作流 |
|
||||
| `backend/app/services/gamma_runner_cli.py` | 子进程 CLI 入口(对标 envi_runner_cli.py) |
|
||||
| `backend/app/services/gamma_import.py` | LT-1 原始数据 → GAMMA SLC 格式导入 |
|
||||
| `scripts/check_gamma_wsl.py` | GAMMA + WSL2 环境诊断脚本 |
|
||||
|
||||
## 修改文件
|
||||
|
||||
| 文件 | 修改内容 |
|
||||
|------|----------|
|
||||
| `.env` | 新增 `GAMMA_ENABLED`、`GAMMA_WSL_DISTRO`、`GAMMA_HOME`、`GAMMA_ENV_SCRIPT`、`GAMMA_DEM_FILE` 等配置 |
|
||||
| `backend/app/config.py` | Settings 类新增 GAMMA 配置字段 |
|
||||
| `backend/app/services/job_handlers.py` | 新增 `GAMMA_RUN_DINSAR` handler,注册到 `_HANDLERS` |
|
||||
| `backend/app/routers/idl.py` | `DinsarJobRequest` 新增 `engine` 字段(envi/gamma),路由分发 |
|
||||
| `frontend/src/IDLAutomationPanel.jsx` | Step 2 新增引擎选择器(radio:ENVI / GAMMA),GAMMA 不可用时灰显 |
|
||||
| `frontend/src/api/idl.js` | `queueDinsarJob` payload 新增 `engine` |
|
||||
|
||||
---
|
||||
|
||||
## GAMMA D-InSAR 9步工作流
|
||||
|
||||
每步通过 `gamma_service.gamma_exec(cmd, work_dir)` → `wsl -d {distro} bash -c 'source gamma_env.sh && {cmd}'` 执行。
|
||||
|
||||
| 步骤 | GAMMA 命令 | 功能 | 对应 ENVI 步骤 |
|
||||
|------|-----------|------|---------------|
|
||||
| 1 | LT-1 导入(自定义) | 原始数据 → .slc + .slc.par | SARsImportLuTan1 |
|
||||
| 2 | `gc_map` | DEM 准备 + lookup table | (ENVI 内置在 Step1) |
|
||||
| 3 | `create_offset` + `offset_pwr` + `offset_fit` + `SLC_interp` | 配准 | InterferogramGeneration 内部 |
|
||||
| 4 | `SLC_intf` + `multi_look` | 干涉图生成 | InterferogramGeneration |
|
||||
| 5 | `adf` | 自适应滤波(Goldstein) | FilterAndCoherence |
|
||||
| 6 | `cc_wave` | 相干性估计 | FilterAndCoherence |
|
||||
| 7 | `mcf` | 相位解缠 | PhaseUnwrapping |
|
||||
| 8 | `dispmap` | 相位→位移 | PhaseToDisplacement |
|
||||
| 9 | `geocode_back` + `data2geotiff` | 地理编码 + 转 GeoTIFF | PhaseToDisplacement |
|
||||
|
||||
---
|
||||
|
||||
## 关键设计
|
||||
|
||||
### 路径转换
|
||||
```python
|
||||
def win_to_wsl(win_path: str) -> str:
|
||||
# Z:\Test_data\Task_001 → /mnt/z/Test_data/Task_001
|
||||
# D:\SRTM\dem.tif → /mnt/d/SRTM/dem.tif
|
||||
```
|
||||
|
||||
### 进度跟踪
|
||||
写入与 ENVI 完全相同格式的 `backend/runtime/idl_worker/job_{id}_progress.json`,job_handler 的 keepalive 无需修改。GAMMA 的 `total_steps=9`(ENVI 为 6),进度公式 `(pair_index-1+step/total)/total_pairs` 天然适配。
|
||||
|
||||
### 输出格式统一
|
||||
GAMMA 最终输出转为 GeoTIFF(`data2geotiff`),同时生成 ENVI `.hdr`,使 `extract_disp_results()` 和 D-InSAR 结果扫描能统一识别。
|
||||
|
||||
### 前端引擎选择
|
||||
页面加载时调 `GET /gamma/status` 检查 GAMMA 是否可用。可用时显示 radio 选择器,不可用时 GAMMA 选项灰显标注"(未配置)"。
|
||||
|
||||
---
|
||||
|
||||
## .env 配置项
|
||||
|
||||
```ini
|
||||
# ============ GAMMA + WSL2 配置 ============
|
||||
# 总开关(false 则前端不显示 GAMMA 选项)
|
||||
GAMMA_ENABLED=false
|
||||
|
||||
# WSL2 发行版名称(wsl -l -v 查看)
|
||||
GAMMA_WSL_DISTRO=Ubuntu-22.04
|
||||
|
||||
# GAMMA 安装路径(Linux 路径,WSL2 内部)
|
||||
GAMMA_HOME=/opt/GAMMA_SOFTWARE-20230101
|
||||
|
||||
# GAMMA 环境初始化脚本(source 此文件后 GAMMA 命令可用)
|
||||
GAMMA_ENV_SCRIPT=/opt/GAMMA_SOFTWARE-20230101/gamma_env.sh
|
||||
|
||||
# DEM 文件路径(Windows 路径,自动转为 WSL 路径)
|
||||
GAMMA_DEM_FILE=D:\SRTM30m\srtm_dem.tif
|
||||
|
||||
# 处理参数
|
||||
GAMMA_GEOCODE_PIXEL_SIZE_M=10.0
|
||||
GAMMA_ADF_WINDOW_SIZE=32
|
||||
GAMMA_MCF_COH_THRESHOLD=0.3
|
||||
GAMMA_RANGE_LOOKS=4
|
||||
GAMMA_AZIMUTH_LOOKS=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 分阶段实施
|
||||
|
||||
### Phase 1:基础设施 + 环境验证
|
||||
- `.env` / `config.py` 配置层
|
||||
- `gamma_service.py`:`win_to_wsl()`、`wsl_exec()`、`gamma_exec()`、`check_gamma_environment()`
|
||||
- `scripts/check_gamma_wsl.py` 诊断脚本
|
||||
- `GET /gamma/status` 端点
|
||||
- 手动验证:`wsl -d Ubuntu bash -c 'source gamma_env.sh && which par_S1_SLC'`
|
||||
|
||||
### Phase 2:LT-1 数据导入(技术风险最高)
|
||||
- `gamma_import.py`:解析 LT-1 `.meta.xml` → 构建 GAMMA `.slc.par` 参数文件
|
||||
- **关键验证**:对一个 Task_*/master/ 执行导入,检查 .slc.par 参数是否正确
|
||||
- 如果 GAMMA 内置 LT-1 支持,直接调用;否则需手工构建参数文件
|
||||
|
||||
### Phase 3:D-InSAR 核心工作流
|
||||
- `gamma_dinsar.py`:9步工作流
|
||||
- `gamma_runner_cli.py`:CLI 入口
|
||||
- 逐步调试,每步验证输入输出
|
||||
|
||||
### Phase 4:任务调度 + 前端集成
|
||||
- `job_handlers.py`:新增 GAMMA handler
|
||||
- `idl.py`:engine 字段分发
|
||||
- `IDLAutomationPanel.jsx`:引擎选择器
|
||||
- 端到端测试
|
||||
|
||||
---
|
||||
|
||||
## 风险点
|
||||
|
||||
1. **LT-1 导入**(最大风险):GAMMA 是否内置 LT-1 读取器需要安装后确认。Plan B:用 GDAL 读 TIFF + 手工构建 .slc.par
|
||||
2. **WSL2 跨文件系统 I/O**:`/mnt/z/` 比 WSL 原生文件系统慢 ~5x。初期可接受,后续可优化为先拷贝到 WSL 内部处理
|
||||
3. **GAMMA License**:WSL2 中需配置 FlexLM `LM_LICENSE_FILE`,在 `gamma_env.sh` 中统一设置
|
||||
|
||||
---
|
||||
|
||||
## 验证
|
||||
|
||||
1. `py_compile` 所有新增/修改的 .py 文件
|
||||
2. `npm run build` 前端构建通过
|
||||
3. `python scripts/check_gamma_wsl.py` 环境诊断通过
|
||||
4. 前端选 GAMMA 引擎 → 提交任务 → 进度正常更新 → 输出 GeoTIFF 位移图
|
||||
5. 前端选 ENVI 引擎 → 行为与改造前完全一致(回归测试)
|
||||
6. GAMMA 未配置时 → 前端 GAMMA 选项灰显,无法选择
|
||||
@@ -0,0 +1,85 @@
|
||||
# 历史文档索引
|
||||
|
||||
最后更新:2026-04-26
|
||||
|
||||
本页用于组织 `docs/archive/` 下的历史文档。
|
||||
|
||||
原则:
|
||||
|
||||
- 本目录中的材料默认不作为当前系统事实来源。
|
||||
- 它们保留用于追溯设计演进、阶段性判断和历史决策背景。
|
||||
- 当前真实规则优先看:
|
||||
- [../../README.md](../../README.md)
|
||||
- [../INDEX.md](../INDEX.md)
|
||||
- [../DOCUMENTATION_GOVERNANCE.md](../DOCUMENTATION_GOVERNANCE.md)
|
||||
|
||||
## 1. 2026-04-26 归档批次
|
||||
|
||||
### 1.1 旧 Gamma 直连方案
|
||||
|
||||
- [GAMMA_WSL2_INTEGRATION_PLAN.md](GAMMA_WSL2_INTEGRATION_PLAN.md)
|
||||
|
||||
说明:
|
||||
|
||||
- 这份文档描述的是旧的 `/idl/jobs/dinsar` + 独立 Gamma service / status 端点方案。
|
||||
- 当前代码和文档已经转向多引擎生产中心、共享 WSL 运行时和 `pyint`/Gamma 集成路径,因此该文档只保留历史参考价值。
|
||||
|
||||
### 1.2 旧配对重构计划与任务板
|
||||
|
||||
- [PAIRING_SYSTEM_REFACTOR_PLAN_20260413.md](PAIRING_SYSTEM_REFACTOR_PLAN_20260413.md)
|
||||
- [DINSAR_ENHANCEMENT_TASKS.md](DINSAR_ENHANCEMENT_TASKS.md)
|
||||
|
||||
说明:
|
||||
|
||||
- 这两份材料保留分阶段计划和当时边界判断的价值,但不再作为当前系统事实来源。
|
||||
- 当前 pairing 运行态事实以 `CURRENT_STATUS_20260425.md`、`DATABASE_SELF_MAINTENANCE_AUDIT_20260425.md` 和健康检查为准。
|
||||
- 当前 D-InSAR 生产设计以 `PRODUCTION_RESULTS_MULTI_ENGINE_DESIGN_20260423.md`、`ISCE2_MANAGED_DINSAR_IMPLEMENTATION_20260424.md`、`ISCE2_PRODUCTION_RELIABILITY_HARDENING_DESIGN_20260424.md` 为准。
|
||||
|
||||
## 2. 2026-04-25 归档批次
|
||||
|
||||
### 2.1 SBAS 阶段文档
|
||||
|
||||
- [SBAS_FRONTEND_UX_SPEC_20260406.md](SBAS_FRONTEND_UX_SPEC_20260406.md)
|
||||
- [SBAS_IMPLEMENTATION_TODO_20260406.md](SBAS_IMPLEMENTATION_TODO_20260406.md)
|
||||
- [SBAS_PROGRESS_STATUS_20260406.md](SBAS_PROGRESS_STATUS_20260406.md)
|
||||
- [SBAS_RESULT_MANAGEMENT_AND_DISPLAY_SPEC_20260406.md](SBAS_RESULT_MANAGEMENT_AND_DISPLAY_SPEC_20260406.md)
|
||||
- [SBAS_SYSTEM_CHANGE_RISK_ASSESSMENT_20260406.md](SBAS_SYSTEM_CHANGE_RISK_ASSESSMENT_20260406.md)
|
||||
- [SBAS_SYSTEM_EMBEDDING_DESIGN_20260406.md](SBAS_SYSTEM_EMBEDDING_DESIGN_20260406.md)
|
||||
- [SBAS_SYSTEM_INTEGRATION_AUDIT_20260406.md](SBAS_SYSTEM_INTEGRATION_AUDIT_20260406.md)
|
||||
- [SBAS_TASK_PATH_MODE_EVALUATION_20260406.md](SBAS_TASK_PATH_MODE_EVALUATION_20260406.md)
|
||||
|
||||
说明:
|
||||
|
||||
- 这批文档描述的是时序 InSAR / SBAS 接入初期的阶段方案。
|
||||
- 当前仍有效的时序主文档保留在 `docs/` 根目录:
|
||||
- [../ISCE2_SBAS_TIMESERIES_DESIGN.md](../ISCE2_SBAS_TIMESERIES_DESIGN.md)
|
||||
- [../ISCE2_SBAS_PRODUCT_SPEC.md](../ISCE2_SBAS_PRODUCT_SPEC.md)
|
||||
|
||||
### 2.2 旧集成方案与汇报材料
|
||||
|
||||
- [WSL2_ISCE2_MINTPY_SBAS_INTEGRATION_PLAN_20260412.md](WSL2_ISCE2_MINTPY_SBAS_INTEGRATION_PLAN_20260412.md)
|
||||
- [项目汇报.md](项目汇报.md)
|
||||
|
||||
### 2.3 PyINT 过程型材料
|
||||
|
||||
- [PYINT_GAMMA_IMPLEMENTATION_TODO_20260418.md](PYINT_GAMMA_IMPLEMENTATION_TODO_20260418.md)
|
||||
- [PYINT_LT1_COREG_ORBIT_HYPOTHESIS_EXPERIMENT_20260420.md](PYINT_LT1_COREG_ORBIT_HYPOTHESIS_EXPERIMENT_20260420.md)
|
||||
- [PYINT_LT1_DEM_GEOMETRY_CHAIN_EXPERIMENT_20260420.md](PYINT_LT1_DEM_GEOMETRY_CHAIN_EXPERIMENT_20260420.md)
|
||||
- [PYINT_LT1_DEM_SOURCE_EXPERIMENT_RESULTS_20260420.md](PYINT_LT1_DEM_SOURCE_EXPERIMENT_RESULTS_20260420.md)
|
||||
- [PYINT_LT1_PAIR_SELECTION_EXPERIMENT_20260421.md](PYINT_LT1_PAIR_SELECTION_EXPERIMENT_20260421.md)
|
||||
|
||||
说明:
|
||||
|
||||
- 这批文档保留实验和实施过程价值,但不再放在主导航中。
|
||||
- 当前仍有导航价值的 PyINT 文档保留在 `docs/` 根目录。
|
||||
|
||||
## 3. 更早的历史文档
|
||||
|
||||
本目录还保留以下较早批次的历史材料:
|
||||
|
||||
- 安全审计与修复过程
|
||||
- 热修复记录
|
||||
- 旧版 AI / ENVI / 日志管理设计
|
||||
- 历史 TODO 与阶段性工作单
|
||||
|
||||
如需判断它们是否仍然有效,以 `docs/INDEX.md` 的“当前有效”区为准。
|
||||
@@ -0,0 +1,867 @@
|
||||
# InSAR 配对系统重构方案
|
||||
|
||||
更新日期:2026-04-13
|
||||
状态:待实施
|
||||
适用范围:`Z:\Code\Insar_management_system_v2` 当前代码基线
|
||||
|
||||
## 1. 文档目标
|
||||
|
||||
这份文档不是抽象算法说明,而是基于当前系统现状给出的可落地重构方案,目标是:
|
||||
|
||||
- 重构 D-InSAR 配对内核,解决当前正确性、稳定性和可维护性问题
|
||||
- 尽量复用现有数据库自动维护、root/cursor 自维护、manifest inventory、自检面板
|
||||
- 明确开发机条件下的迁移策略
|
||||
- 为后续实现提供分阶段执行顺序、表设计、接口边界和验收口径
|
||||
|
||||
## 2. 当前系统基础与约束
|
||||
|
||||
### 2.1 当前可直接复用的系统能力
|
||||
|
||||
当前系统已经具备以下基础设施,重构应直接接入,而不是另起一套平行机制:
|
||||
|
||||
- 数据库启动自维护
|
||||
- `backend/app/db_maintenance.py`
|
||||
- `ensure_database_ready()` 会在启动时创建表、补缺列、应用 SQL migration,并可在开发机上按环境变量执行整库 schema reset
|
||||
- root 与 cursor 自维护
|
||||
- `backend/app/services/root_registry_service.py`
|
||||
- 启动时会根据 `.env` 自动同步 `managed_roots` 与 `scan_cursors`
|
||||
- manifest inventory 自维护
|
||||
- `backend/app/services/manifest_inventory_service.py`
|
||||
- 会维护 `path_inventory`、`scan_cursors.last_seen_*`、fingerprint 与 root 缺失状态
|
||||
- 结果目录自维护
|
||||
- `backend/app/services/dinsar_scan_service.py`
|
||||
- D-InSAR 统一扫描链路已经是“发布 -> manifest inventory -> catalog rebuild -> compat sync”
|
||||
- 健康检查和一致性检查
|
||||
- `backend/app/services/health_service.py`
|
||||
- `frontend/src/HealthCheckPanel.jsx`
|
||||
- 当前自检已包含:数据库 schema、worker、catalog、source roots、D-InSAR bridge、一致性统计、系统维护入口
|
||||
|
||||
### 2.2 当前配对系统的核心问题
|
||||
|
||||
现有配对系统的主要问题不是功能不够多,而是核心语义不稳定:
|
||||
|
||||
- SQL 路径和 Python fallback 路径不是同一算法
|
||||
- 同日影像会出现反向重复配对
|
||||
- `start_date` 在 SQL 主路径上已失效,但接口仍保留
|
||||
- `star` 策略没有固定参考像角色
|
||||
- `sequential` 对同日多景不稳定
|
||||
- `all` 策略排序与前端描述不一致
|
||||
- `aoi_overlap_threshold=0` 的语义前后端不一致
|
||||
- 当前任务命名与配对唯一性混在一起,业务主键不稳定
|
||||
|
||||
### 2.3 当前系统约束
|
||||
|
||||
- 当前扫描模式是 manual-only,调度器默认关闭
|
||||
- `backend/app/scheduler.py`
|
||||
- `radar_data` 是当前源影像事实表,配对系统必须以它为唯一源
|
||||
- `dinsar_task_batches` / `dinsar_task_items` 已经是生产任务落地表
|
||||
- `result_products` / `dinsar_product_profiles` 已经承担结果资产追踪
|
||||
- 健康检查和统计接口已上线,新增配对系统状态应并入现有面板
|
||||
|
||||
## 3. 重构总目标
|
||||
|
||||
本轮重构的目标不是继续修补 `find_dinsar_pairs_v2`,而是将配对系统改造成四层结构:
|
||||
|
||||
1. 影像事实层
|
||||
2. 配对指标缓存层
|
||||
3. 网络选择层
|
||||
4. 任务物化层
|
||||
|
||||
核心原则:
|
||||
|
||||
- 候选对生成与网络选择分层
|
||||
- 所有策略共享同一候选池
|
||||
- 所有配对方向统一规范化
|
||||
- 所有结果可追溯到策略版本、参数快照和候选边来源
|
||||
- 不再保留“算法不等价的 fallback”
|
||||
|
||||
## 4. 目标架构
|
||||
|
||||
### 4.1 Layer A:影像事实层
|
||||
|
||||
沿用现有 `radar_data` 表作为唯一源影像事实表。
|
||||
|
||||
重构要求:
|
||||
|
||||
- `radar_data.id` 继续作为数据库主键
|
||||
- 引入明确的场景业务键 `scene_uid`
|
||||
- 优先复用 `radar_data.unique_id`
|
||||
- 若历史数据存在 `unique_id` 缺失或不稳定,启动时执行一次回填
|
||||
- 回填规则:`hash(normalized file_path)`,并写入新列或标准化字段
|
||||
- 所有配对相关对象都基于 `scene_uid` 或 `radar_data.id` 建立引用
|
||||
|
||||
建议:
|
||||
|
||||
- 本轮实现阶段直接在 `radar_data` 上新增:
|
||||
- `scene_uid`
|
||||
- `scene_signature`
|
||||
- `pairing_eligible`
|
||||
- `pairing_updated_at`
|
||||
- 如果希望减少变更面,也可以只新增 `scene_uid` 与 `pairing_updated_at`
|
||||
|
||||
### 4.2 Layer B:配对指标缓存层
|
||||
|
||||
这是本次重构的核心。
|
||||
|
||||
目标:
|
||||
|
||||
- 将“任意两个影像是否可配、其基础指标是什么”从请求时临时计算,改为可维护的持久化缓存
|
||||
- 缓存只保存与 AOI 无关的基础指标
|
||||
- AOI 相关指标在请求时动态叠加计算
|
||||
|
||||
建议新增表:
|
||||
|
||||
#### `pairing_metric_cache`
|
||||
|
||||
一行代表一个规范化后的影像对。
|
||||
|
||||
建议字段:
|
||||
|
||||
- `id`
|
||||
- `master_scene_ref_id`
|
||||
- `slave_scene_ref_id`
|
||||
- `master_scene_uid`
|
||||
- `slave_scene_uid`
|
||||
- `pair_uid`
|
||||
- `metric_version`
|
||||
- `orientation_rule_version`
|
||||
- `time_baseline_days`
|
||||
- `spatial_baseline_meters`
|
||||
- `scene_overlap_ratio`
|
||||
- `orbit_direction`
|
||||
- `same_satellite`
|
||||
- `same_imaging_mode`
|
||||
- `same_polarization`
|
||||
- `master_imaging_date`
|
||||
- `slave_imaging_date`
|
||||
- `master_satellite`
|
||||
- `slave_satellite`
|
||||
- `master_imaging_mode`
|
||||
- `slave_imaging_mode`
|
||||
- `master_polarization`
|
||||
- `slave_polarization`
|
||||
- `master_file_path`
|
||||
- `slave_file_path`
|
||||
- `status`
|
||||
- `computed_at`
|
||||
|
||||
唯一约束:
|
||||
|
||||
- `unique(master_scene_ref_id, slave_scene_ref_id, metric_version)`
|
||||
|
||||
关键约定:
|
||||
|
||||
- `master/slave` 不是请求期可变概念,而是规范化方向
|
||||
- 规范化规则:
|
||||
- 早时间 = master
|
||||
- 同时间时,较小 `scene_uid` 或较小 `id` = master
|
||||
|
||||
### 4.3 Layer C:缓存状态与脏队列
|
||||
|
||||
为了接入现有“自动维护 + 健康检查”体系,建议新增两张状态表。
|
||||
|
||||
#### `pairing_cache_state`
|
||||
|
||||
建议设计为单例表或按 `cache_scope='global'` 管理。
|
||||
|
||||
字段建议:
|
||||
|
||||
- `id`
|
||||
- `cache_scope`
|
||||
- `metric_version`
|
||||
- `status`
|
||||
- `scene_count`
|
||||
- `pair_count`
|
||||
- `dirty_scene_count`
|
||||
- `last_full_rebuild_at`
|
||||
- `last_incremental_reconcile_at`
|
||||
- `last_error`
|
||||
- `updated_at`
|
||||
|
||||
状态建议:
|
||||
|
||||
- `READY`
|
||||
- `DIRTY`
|
||||
- `REBUILDING`
|
||||
- `DEGRADED`
|
||||
- `FAILED`
|
||||
|
||||
#### `pairing_dirty_scenes`
|
||||
|
||||
用于增量维护。
|
||||
|
||||
字段建议:
|
||||
|
||||
- `id`
|
||||
- `scene_ref_id`
|
||||
- `scene_uid`
|
||||
- `reason`
|
||||
- `marked_at`
|
||||
- `resolved_at`
|
||||
- `status`
|
||||
|
||||
唯一约束建议:
|
||||
|
||||
- `unique(scene_ref_id, status='PENDING')` 或代码层去重
|
||||
|
||||
### 4.4 Layer D:网络选择层
|
||||
|
||||
网络选择层不直接查 `radar_data`,而是查 `pairing_metric_cache`。
|
||||
|
||||
建议新增:
|
||||
|
||||
#### `pairing_network_runs`
|
||||
|
||||
代表一次配对请求或一次已保存的网络。
|
||||
|
||||
字段建议:
|
||||
|
||||
- `id`
|
||||
- `network_run_id`
|
||||
- `strategy`
|
||||
- `policy_version`
|
||||
- `request_hash`
|
||||
- `request_params_json`
|
||||
- `aoi_source`
|
||||
- `aoi_hash`
|
||||
- `aoi_summary_json`
|
||||
- `candidate_count`
|
||||
- `selected_edge_count`
|
||||
- `warning_count`
|
||||
- `status`
|
||||
- `fallback_used`
|
||||
- `created_by`
|
||||
- `created_at`
|
||||
|
||||
#### `pairing_network_edges`
|
||||
|
||||
代表某个网络 run 选中的边。
|
||||
|
||||
字段建议:
|
||||
|
||||
- `id`
|
||||
- `network_run_ref_id`
|
||||
- `metric_cache_ref_id`
|
||||
- `edge_rank`
|
||||
- `selection_reason`
|
||||
- `selection_score`
|
||||
- `selection_meta_json`
|
||||
- `is_reference_edge`
|
||||
- `created_at`
|
||||
|
||||
唯一约束:
|
||||
|
||||
- `unique(network_run_ref_id, metric_cache_ref_id)`
|
||||
|
||||
### 4.5 Layer E:任务物化层
|
||||
|
||||
当前 `dinsar_task_batches` / `dinsar_task_items` 可继续保留。
|
||||
|
||||
但建议增加可追溯字段:
|
||||
|
||||
在 `dinsar_task_items` 上新增:
|
||||
|
||||
- `network_run_id`
|
||||
- `network_edge_id`
|
||||
- `policy_version`
|
||||
- `selection_strategy`
|
||||
- `scene_pair_uid`
|
||||
|
||||
在结果侧建议同步补充:
|
||||
|
||||
- `result_products.pair_key` 继续保留
|
||||
- 在 `dinsar_product_profiles` 或 `params_json` 中补充:
|
||||
- `network_run_id`
|
||||
- `network_edge_id`
|
||||
- `policy_version`
|
||||
- `master_scene_uid`
|
||||
- `slave_scene_uid`
|
||||
|
||||
这样最终可以把:
|
||||
|
||||
- 配对网络
|
||||
- 任务项
|
||||
- 生产结果
|
||||
|
||||
串成一条可追踪链路。
|
||||
|
||||
## 5. 配对算法设计
|
||||
|
||||
### 5.1 候选对生成
|
||||
|
||||
候选对生成只负责回答:
|
||||
|
||||
- 这两个场景在基础事实上是否可配
|
||||
- 基础指标是什么
|
||||
|
||||
不负责回答:
|
||||
|
||||
- 用什么策略选
|
||||
- 最后是否进入任务
|
||||
|
||||
基础硬约束:
|
||||
|
||||
- `master != slave`
|
||||
- 方向规范化后只保留一个方向
|
||||
- 同轨向
|
||||
- 日期格式合法
|
||||
- 几何相交
|
||||
|
||||
基础指标:
|
||||
|
||||
- `time_baseline_days`
|
||||
- `spatial_baseline_meters`
|
||||
- `scene_overlap_ratio`
|
||||
|
||||
注意:
|
||||
|
||||
- `same_satellite`
|
||||
- `same_imaging_mode`
|
||||
- `same_polarization`
|
||||
|
||||
只作为缓存事实,不在缓存层提前删边,以便不同请求复用同一缓存。
|
||||
|
||||
### 5.2 请求期过滤
|
||||
|
||||
请求期过滤发生在 `pairing_metric_cache` 之上:
|
||||
|
||||
- `time_baseline_min/max`
|
||||
- `spatial_baseline_max_meters`
|
||||
- `overlap_threshold`
|
||||
- `allowed_satellites`
|
||||
- `cross_satellite_pairing`
|
||||
- `require_same_imaging_mode`
|
||||
- `require_same_polarization`
|
||||
- `master_date_from/to`
|
||||
- `slave_date_from/to`
|
||||
- `aoi_overlap_threshold`
|
||||
|
||||
AOI 处理原则:
|
||||
|
||||
- AOI 不进入持久化 pair cache 主键
|
||||
- AOI 相关 overlap 在请求时动态计算
|
||||
- `0` 不再表示数值阈值,而统一转成 `null`
|
||||
- 前后端统一语义:
|
||||
- `null` = 不启用 AOI 覆盖阈值
|
||||
- `0 < x <= 1` = 启用阈值
|
||||
|
||||
### 5.3 四种策略的正式定义
|
||||
|
||||
#### `all`
|
||||
|
||||
- 返回全部合法候选边
|
||||
- 排序统一为稳定顺序:
|
||||
- `master_imaging_date`
|
||||
- `slave_imaging_date`
|
||||
- `selection_score desc`
|
||||
- `pair_uid`
|
||||
|
||||
不再使用“数据库返回顺序”作为结果语义。
|
||||
|
||||
#### `sequential`
|
||||
|
||||
- 基于稳定时间序列排序构图
|
||||
- 排序键:
|
||||
- `acquisition_time_utc`
|
||||
- 无则 `imaging_date`
|
||||
- 再无则 `scene_uid`
|
||||
- 每景连接后续 `N` 景
|
||||
- 同日多景必须稳定,不允许受候选池原始顺序影响
|
||||
|
||||
#### `star`
|
||||
|
||||
- 参考像必须固定角色
|
||||
- 本系统建议统一采用:
|
||||
- 参考像始终为 `master`
|
||||
- 若物理上参考像日期晚于目标像,则在选择层进行拒绝或显式反转并记录相位方向规则
|
||||
|
||||
本轮建议:
|
||||
|
||||
- 为降低复杂度,先采用“参考像必须是 master”的严格规则
|
||||
- 如果用户选择的参考像晚于部分场景,则这些边不入网,并给出 warning
|
||||
|
||||
#### `sbas`
|
||||
|
||||
本轮不采用“简单按 overlap 贪心去重”的旧实现。
|
||||
|
||||
建议目标:
|
||||
|
||||
- 图连通
|
||||
- 每景至少达到最小连接数
|
||||
- 时间覆盖尽量连续
|
||||
- 每景度数受控,避免过密
|
||||
- AOI 覆盖尽量多样
|
||||
|
||||
可落地实现:
|
||||
|
||||
1. 从合法候选边中先构造基础时间邻接骨架
|
||||
2. 保证每个场景至少连接前后最近邻
|
||||
3. 再按综合评分补边
|
||||
4. 每补一条边,对已覆盖区域施加惩罚
|
||||
5. 达到目标连通性和最大边数后停止
|
||||
|
||||
综合评分建议:
|
||||
|
||||
`selection_score = w_time * time_score + w_spatial * spatial_score + w_overlap * overlap_score + w_aoi * aoi_gain - w_redundancy * redundancy_penalty`
|
||||
|
||||
### 5.4 删除旧 fallback 的原则
|
||||
|
||||
本轮不再保留“Python 语义独立 fallback”。
|
||||
|
||||
替代方案:
|
||||
|
||||
- 候选边缓存是主路径
|
||||
- 如果缓存不存在或脏数据过多:
|
||||
- 返回明确的 `DEGRADED` / `DIRTY` 状态
|
||||
- 允许管理员触发重建
|
||||
- 或在安全阈值内自动执行增量重建
|
||||
|
||||
也就是说:
|
||||
|
||||
- 可以有“降级状态”
|
||||
- 不能再有“悄悄换算法”
|
||||
|
||||
## 6. 与现有扫描和自动维护机制的集成
|
||||
|
||||
### 6.1 源影像扫描后的集成点
|
||||
|
||||
当前源影像扫描入口:
|
||||
|
||||
- `backend/app/services/data_service.py::scan_radar_data`
|
||||
- `backend/app/scheduler.py::scan_data_job`
|
||||
|
||||
建议改造:
|
||||
|
||||
在 `scan_radar_data()` 中,对新增、更新、删除的 `radar_data` 记录执行:
|
||||
|
||||
1. 标记 `pairing_dirty_scenes`
|
||||
2. 更新 `pairing_cache_state.status = DIRTY`
|
||||
3. 根据变更规模决定是否立即增量重建
|
||||
|
||||
建议阈值:
|
||||
|
||||
- 变更场景数 `<= SMALL_RECONCILE_LIMIT`
|
||||
- 扫描结束后直接执行增量 reconcile
|
||||
- 变更场景数 `> SMALL_RECONCILE_LIMIT`
|
||||
- 仅标脏,不在扫描链路内同步重建
|
||||
- 由管理员在自检面板手动触发
|
||||
|
||||
这与当前 manual-only 模式兼容,不依赖后台常驻调度器。
|
||||
|
||||
### 6.2 启动期自维护
|
||||
|
||||
当前启动期会执行:
|
||||
|
||||
- `ensure_database_ready()`
|
||||
- `root_registry_service.sync_from_settings()`
|
||||
- `manifest_inventory_service.sync_manifest_roots()`
|
||||
- catalog bootstrap
|
||||
- health check
|
||||
|
||||
建议新增启动动作:
|
||||
|
||||
- `pairing_service.bootstrap_pairing_cache_state()`
|
||||
|
||||
只做轻量检查:
|
||||
|
||||
- 新表是否存在
|
||||
- 是否有缓存状态行
|
||||
- `metric_version` 是否匹配当前版本
|
||||
- dirty scene 是否堆积
|
||||
|
||||
不建议启动即全量重建,避免启动时间失控。
|
||||
|
||||
### 6.3 数据库自动维护策略
|
||||
|
||||
当前数据库自维护具备两个模式:
|
||||
|
||||
- 常规模式:建表、补列、应用 migration
|
||||
- 开发机强制 reset 模式:整库 schema reset
|
||||
|
||||
由于本轮是配对内核重构,且当前是开发机,推荐采用:
|
||||
|
||||
#### 推荐落地策略
|
||||
|
||||
第一轮实施时直接执行一次开发机 schema reset。
|
||||
|
||||
原因:
|
||||
|
||||
- 旧配对 SQL 函数与新缓存设计语义完全不同
|
||||
- 旧任务表中的配对数据没有保留价值
|
||||
- 旧结果可以通过 manifest inventory 和结果 catalog 重建
|
||||
- 源影像可以重新扫描
|
||||
|
||||
具体方式:
|
||||
|
||||
- 合并新 ORM 与 migration 后
|
||||
- 启动前临时设置:
|
||||
- `DB_SCHEMA_RESET_ON_MISMATCH=true`
|
||||
- `DB_SCHEMA_RESET_CONFIRM=true`
|
||||
- 启动一次后让 `ensure_database_ready()` 重建 schema
|
||||
- 启动完成后恢复这两个环境变量为 `false`
|
||||
|
||||
### 6.4 migration 文件策略
|
||||
|
||||
当前 `db_maintenance.py` 中 migration 顺序为:
|
||||
|
||||
- `001_st_intersection_agg.sql`
|
||||
- `002_spatial_functions.sql`
|
||||
- `003_pairing_enhancement.sql`
|
||||
|
||||
建议新增:
|
||||
|
||||
- `004_pairing_refactor.sql`
|
||||
|
||||
该 migration 负责:
|
||||
|
||||
- 创建新 pairing 表
|
||||
- 创建必要索引
|
||||
- 创建候选边计算函数或 SQL helper view
|
||||
- 如有需要,保留旧函数为 deprecated wrapper
|
||||
|
||||
建议:
|
||||
|
||||
- 不要在 `004` 里继续强化 `find_dinsar_pairs_v2`
|
||||
- 将旧函数标记 deprecated,仅作为过渡壳
|
||||
- 新逻辑直接走新 service + 新表
|
||||
|
||||
## 7. 自检与一致性检测升级
|
||||
|
||||
### 7.1 Health 接口扩展
|
||||
|
||||
当前健康检查聚合点:
|
||||
|
||||
- `backend/app/services/health_service.py::get_health_status`
|
||||
|
||||
建议新增检查项:
|
||||
|
||||
#### `pairing_system`
|
||||
|
||||
字段建议:
|
||||
|
||||
- `ok`
|
||||
- `status`
|
||||
- `metric_version`
|
||||
- `scene_count`
|
||||
- `pair_count`
|
||||
- `dirty_scene_count`
|
||||
- `network_run_count_last_7d`
|
||||
- `last_full_rebuild_at`
|
||||
- `last_incremental_reconcile_at`
|
||||
- `last_error`
|
||||
- `duplicate_reverse_pair_count`
|
||||
- `orphan_metric_scene_ref_count`
|
||||
- `task_without_network_ref_count`
|
||||
- `result_without_pair_trace_count`
|
||||
|
||||
判定规则建议:
|
||||
|
||||
- `READY` 且无关键异常 -> `ok=true`
|
||||
- `DIRTY` 但 dirty 数量较少 -> `ok=false`,级别 `warn`
|
||||
- 存在重复反向边、孤儿引用、版本漂移 -> `ok=false`,级别 `error`
|
||||
|
||||
### 7.2 Health 面板扩展
|
||||
|
||||
当前 `HealthCheckPanel.jsx` 已能展示结构化卡片。
|
||||
|
||||
建议新增卡片:
|
||||
|
||||
- `配对系统`
|
||||
|
||||
展示内容:
|
||||
|
||||
- 缓存状态
|
||||
- 指标版本
|
||||
- 场景数 / 缓存对数
|
||||
- dirty scene 数
|
||||
- 最近全量 / 增量时间
|
||||
- 关键错误数
|
||||
|
||||
操作按钮建议:
|
||||
|
||||
- `增量修复配对缓存`
|
||||
- `全量重建配对缓存`
|
||||
- `清理旧网络记录`
|
||||
|
||||
### 7.3 Statistics 接口扩展
|
||||
|
||||
当前 `/statistics` 已承担一致性统计角色。
|
||||
|
||||
建议追加:
|
||||
|
||||
- `pairing_consistency`
|
||||
|
||||
字段建议:
|
||||
|
||||
- `metric_cache_count`
|
||||
- `duplicate_reverse_pair_count`
|
||||
- `invalid_orientation_count`
|
||||
- `network_edge_orphan_count`
|
||||
- `task_orphan_count`
|
||||
- `result_trace_missing_count`
|
||||
|
||||
## 8. API 重构计划
|
||||
|
||||
### 8.1 后端接口
|
||||
|
||||
当前接口:
|
||||
|
||||
- `POST /api/find-pairs`
|
||||
|
||||
建议分两阶段改造。
|
||||
|
||||
#### Phase 1:保持前端可用
|
||||
|
||||
保留:
|
||||
|
||||
- `POST /api/find-pairs`
|
||||
|
||||
但内部改为:
|
||||
|
||||
- 从 `pairing_metric_cache` 查询
|
||||
- 选择网络
|
||||
- 返回 `network_run_id + pairs`
|
||||
|
||||
#### Phase 2:正式 API
|
||||
|
||||
新增:
|
||||
|
||||
- `POST /api/pairing/preview`
|
||||
- `POST /api/pairing/networks/{network_run_id}/materialize-batch`
|
||||
- `POST /api/pairing/reconcile-dirty`
|
||||
- `POST /api/pairing/rebuild-cache`
|
||||
- `GET /api/pairing/health`
|
||||
- `GET /api/pairing/networks/{network_run_id}`
|
||||
|
||||
### 8.2 请求模型
|
||||
|
||||
`PairingRequest` 应清理为正式语义:
|
||||
|
||||
- 删除 `start_date`
|
||||
- `aoi_overlap_threshold` 前端空值统一传 `null`
|
||||
- `strategy` 继续保留:
|
||||
- `all`
|
||||
- `sequential`
|
||||
- `star`
|
||||
- `sbas`
|
||||
- `reference_image_id` 仅在 `star` 时有效
|
||||
|
||||
### 8.3 返回模型
|
||||
|
||||
建议新增返回字段:
|
||||
|
||||
- `network_run_id`
|
||||
- `policy_version`
|
||||
- `candidate_count`
|
||||
- `selected_edge_count`
|
||||
- `degraded`
|
||||
- `warnings`
|
||||
|
||||
## 9. 前端改造计划
|
||||
|
||||
涉及文件:
|
||||
|
||||
- `frontend/src/components/PairingModal.jsx`
|
||||
- `frontend/src/hooks/usePairingLogic.js`
|
||||
- `frontend/src/store/pairingStore.js`
|
||||
|
||||
改造原则:
|
||||
|
||||
- 前端不再承载配对语义补丁
|
||||
- 所有“0 表示不限”“默认排序说明”等语义统一交回后端协议
|
||||
- 结果列表显示:
|
||||
- `network_run_id`
|
||||
- `strategy`
|
||||
- `policy_version`
|
||||
- warning
|
||||
|
||||
界面调整建议:
|
||||
|
||||
- `all` 策略文案改为“全部合法候选边,按稳定顺序展示”
|
||||
- `star` 明确说明“参考像固定为主像”
|
||||
- `sequential` 明确说明“同日多景按稳定键排序”
|
||||
- AOI 覆盖阈值为空时传 `null`
|
||||
|
||||
## 10. 旧代码处理策略
|
||||
|
||||
### 10.1 可以删除的内容
|
||||
|
||||
在新缓存路径稳定后,可以删除:
|
||||
|
||||
- `spatial_service.find_dinsar_pairs()` 中当前 Python fallback
|
||||
- 旧 `_apply_star_strategy()` 非固定角色实现
|
||||
- 旧 `start_date` 兼容逻辑
|
||||
|
||||
### 10.2 需要保留过渡一段时间的内容
|
||||
|
||||
- 旧前端 `find-pairs` 调用入口
|
||||
- 旧 `task_alias / pair_key` 命名辅助
|
||||
|
||||
但注意:
|
||||
|
||||
- 命名只能作为展示与兼容字段
|
||||
- 不能继续作为算法主键
|
||||
|
||||
## 11. 实施阶段划分
|
||||
|
||||
### Phase 0:开发机切换准备
|
||||
|
||||
- 确认当前开发机允许 DB reset
|
||||
- 记录 `.env` 中路径配置
|
||||
- 保留现有 `managed_roots` / `path_inventory` / manifest publish 目录,不做文件层清理
|
||||
- 准备新 migration 与 ORM
|
||||
|
||||
验收:
|
||||
|
||||
- 可以安全启动一次 schema reset
|
||||
|
||||
### Phase 1:数据模型落地
|
||||
|
||||
- 新增 pairing 相关 ORM
|
||||
- 新增 `004_pairing_refactor.sql`
|
||||
- 接入 `ensure_database_ready()`
|
||||
- 建立 `pairing_cache_state` 初始化逻辑
|
||||
|
||||
验收:
|
||||
|
||||
- 后端启动后新表自动创建
|
||||
- 健康检查不报 schema 错
|
||||
|
||||
### Phase 2:候选缓存引擎
|
||||
|
||||
- 实现 `pairing_metric_cache` 全量构建
|
||||
- 实现 `pairing_dirty_scenes`
|
||||
- 在 `scan_radar_data()` 中接入 dirty 标记
|
||||
|
||||
验收:
|
||||
|
||||
- 能从 `radar_data` 构建稳定 pair cache
|
||||
- 同日反向重复为 0
|
||||
|
||||
### Phase 3:网络选择器
|
||||
|
||||
- 重写 `all / sequential / star / sbas`
|
||||
- 删除算法不等价 fallback
|
||||
- 为 `find-pairs` 接口切换到新内核
|
||||
|
||||
验收:
|
||||
|
||||
- 同一输入重复请求结果稳定
|
||||
- `star` 固定参考像角色
|
||||
- `sequential` 同日多景稳定
|
||||
|
||||
### Phase 4:任务物化与结果追踪
|
||||
|
||||
- `dinsar_task_items` 增加 network trace 字段
|
||||
- 结果 manifest / product profile 补充配对追踪字段
|
||||
|
||||
验收:
|
||||
|
||||
- 任一结果可追溯到 network edge
|
||||
|
||||
### Phase 5:自维护与自检
|
||||
|
||||
- 健康检查新增 `pairing_system`
|
||||
- Health 面板新增配对卡片与修复按钮
|
||||
- Statistics 新增 pairing consistency
|
||||
|
||||
验收:
|
||||
|
||||
- 能显示 dirty scene 数、缓存状态、重复边异常
|
||||
- 能从 UI 触发增量修复与全量重建
|
||||
|
||||
### Phase 6:清理旧逻辑
|
||||
|
||||
- 删除旧 fallback
|
||||
- 删除 `start_date`
|
||||
- 下线旧语义说明
|
||||
|
||||
验收:
|
||||
|
||||
- 配对链路只剩单一语义实现
|
||||
|
||||
## 12. 测试矩阵
|
||||
|
||||
本轮至少补以下自动化测试:
|
||||
|
||||
### 12.1 候选缓存层
|
||||
|
||||
- 同日双景只生成单方向边
|
||||
- 同日多景生成顺序稳定
|
||||
- 不同轨向不生成边
|
||||
- 时间基线越界不入缓存
|
||||
|
||||
### 12.2 请求过滤层
|
||||
|
||||
- `allowed_satellites` 生效
|
||||
- `cross_satellite_pairing=false` 生效
|
||||
- `require_same_imaging_mode/polarization` 生效
|
||||
- `aoi_overlap_threshold=null` 与 `0.2` 行为不同
|
||||
|
||||
### 12.3 策略层
|
||||
|
||||
- `all` 顺序稳定
|
||||
- `sequential` 连接数正确
|
||||
- `star` 参考像固定为 master
|
||||
- `sbas` 至少满足基础连通性
|
||||
|
||||
### 12.4 集成层
|
||||
|
||||
- 扫描新增源影像后 dirty scene 正确增加
|
||||
- 执行增量 reconcile 后 dirty scene 清零
|
||||
- `find-pairs` 返回 `network_run_id`
|
||||
- `materialize-batch` 后任务项带 network trace
|
||||
|
||||
### 12.5 自检层
|
||||
|
||||
- 重复边异常能被 health 检出
|
||||
- 孤儿网络边能被 health 检出
|
||||
- 任务无 network trace 能被 statistics 检出
|
||||
|
||||
## 13. 风险与取舍
|
||||
|
||||
### 13.1 本轮明确接受的取舍
|
||||
|
||||
- 开发机允许整库 reset
|
||||
- 不迁移旧配对记录
|
||||
- 不保留旧 fallback
|
||||
|
||||
### 13.2 需要重点控制的风险
|
||||
|
||||
- 首轮全量构建 pair cache 可能较慢
|
||||
- `radar_data.unique_id` 可能不稳定,需要一次性规范
|
||||
- 旧结果如果缺少 trace 字段,需要通过 manifest/profile 尽可能补齐
|
||||
- 若前端仍传 `0`,后端必须做强制归一化,不能再依赖 UI 自觉
|
||||
|
||||
## 14. 推荐实施顺序
|
||||
|
||||
建议严格按下面顺序推进:
|
||||
|
||||
1. 先落表和缓存状态,不先改前端
|
||||
2. 再实现候选缓存和增量脏标记
|
||||
3. 再重写四种策略
|
||||
4. 再接任务物化追踪
|
||||
5. 最后接健康检查与自修复入口
|
||||
|
||||
不要反过来做:
|
||||
|
||||
- 不要先改 UI 文案
|
||||
- 不要先修补 `find_dinsar_pairs_v2`
|
||||
- 不要保留旧 fallback 到最后
|
||||
|
||||
## 15. 本轮结论
|
||||
|
||||
在当前代码基线上,最合理的重构路线不是继续维护“实时 SQL + Python fallback”模式,而是:
|
||||
|
||||
- 用 `radar_data` 作为唯一事实层
|
||||
- 用 `pairing_metric_cache` 承载稳定候选对
|
||||
- 用 `pairing_network_runs / edges` 承载策略结果
|
||||
- 用 `pairing_cache_state / dirty_scenes` 承接自维护
|
||||
- 用现有 `HealthCheckPanel` 和 `/statistics` 承接自检
|
||||
|
||||
这样做的直接收益是:
|
||||
|
||||
- 正确性可锁定
|
||||
- 结果可追溯
|
||||
- 与现有 DB 自维护、扫描链路、自检体系自然对接
|
||||
- 后续再接 SBAS、跨卫星和多引擎生产时不会继续堆积配对债务
|
||||
@@ -0,0 +1,390 @@
|
||||
# PyINT + Gamma 实施清单
|
||||
|
||||
更新日期:2026-04-18
|
||||
|
||||
关联设计文档:
|
||||
|
||||
- [PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md](PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md)
|
||||
|
||||
## 当前落地进度
|
||||
|
||||
- [x] 已完成第一批 `PyINT` 生产引擎接入:配置、引擎注册、任务队列、WSL 包装脚本、生产面板入口。
|
||||
- [x] 已完成 `PyINT` 运行目录规范化输出:生成 `.dinsar_run.json` 与 `pyint_run_summary.json`。
|
||||
- [x] 已完成 `PyINT` 基础环境检查:WSL、Python、`PYINT_HOME`、`pyintApp.py`、Gamma 命令可达性。
|
||||
- [x] 已将 `PyINT` 代码收编到仓库内 `third_party/PyINT`,不再依赖默认外部绝对路径。
|
||||
- [ ] 尚未完成 `PyINT` 结果目录自动发布兼容。当前原生输出已保存,但现有结果 catalog 仍主要面向 ENVI / ISCE2 栅格产物。
|
||||
- [ ] 尚未开始 `Gamma` 精配对后端与前端集成。
|
||||
|
||||
## 1. 文档定位
|
||||
|
||||
这份清单用于把 `PyINT` 生产引擎接入和 `Gamma` 精配对接入拆成可执行任务,作为后续实施顺序、联调顺序和验收顺序的统一依据。
|
||||
|
||||
本清单按以下原则编排:
|
||||
|
||||
- 一期优先打通 `PyINT` 生产引擎
|
||||
- 二期再做 `Gamma` 精配对 MVP
|
||||
- 一期不强制改数据库主结构
|
||||
- 运维自检只加状态,不把主要操作堆回健康页
|
||||
|
||||
## 2. 实施总顺序
|
||||
|
||||
推荐顺序:
|
||||
|
||||
1. 先确认环境基线和配置项
|
||||
2. 先打通 `PyINT` 后端引擎与任务执行
|
||||
3. 再补结果归一化与目录扫描兼容
|
||||
4. 再补前端生产入口
|
||||
5. 然后做 `Gamma` 精配对 MVP
|
||||
6. 最后补健康检查、烟测和治理
|
||||
|
||||
不建议顺序:
|
||||
|
||||
- 先改数据库再写主流程
|
||||
- 先做健康页大改
|
||||
- 先把 `PyINT` 全部高级参数暴露到前端
|
||||
|
||||
## 3. Phase 0:环境基线确认
|
||||
|
||||
目标:
|
||||
|
||||
- 确认当前机器上的 `PyINT + Gamma + WSL` 具备最小可执行条件
|
||||
- 把配置字段定清楚,但不把敏感信息写入仓库文档
|
||||
|
||||
### 任务
|
||||
|
||||
- [ ] 确认 `D:\Code\PyINT` 的实际可执行入口路径
|
||||
- [ ] 确认当前唯一 WSL distro 名称,默认与 `ISCE2_WSL_DISTRO` 对齐
|
||||
- [ ] 确认 WSL 中 `PyINT` 可用 Python 路径
|
||||
- [ ] 确认 `GAMMA_ENV_SCRIPT` 的实际路径
|
||||
- [ ] 确认 `base_calc` 在 WSL 中可执行
|
||||
- [ ] 确认 `pyintApp.py` 在 WSL 中可执行
|
||||
- [ ] 确认 `SCRATCHDIR` / `TEMPLATEDIR` / `DEMDIR` 对应的系统托管目录方案
|
||||
- [ ] 确认 PyINT 一期只支持的业务范围,建议锁定 `LT-1 + Gamma D-InSAR`
|
||||
|
||||
### 涉及文件
|
||||
|
||||
- [ ] `backend/app/config.py`
|
||||
- [ ] `.env.example`
|
||||
- [ ] 根 `.env` 本机配置对照,不入库敏感值
|
||||
|
||||
### 阶段验收
|
||||
|
||||
- [ ] 可以给出完整的 PyINT 运行必需配置字段列表
|
||||
- [ ] 可以在 WSL 内成功跑通最小烟测命令
|
||||
- [ ] 不需要把管理员密码、邮箱密码、sudo 密码写入代码或文档
|
||||
|
||||
## 4. Phase 1:PyINT 后端引擎接入
|
||||
|
||||
目标:
|
||||
|
||||
- 把 `PyINT` 作为新的 D-InSAR 引擎正式接入现有多引擎体系
|
||||
|
||||
### 4.1 配置层
|
||||
|
||||
- [ ] 在 `backend/app/config.py` 新增 `PYINT_*` 配置
|
||||
- [ ] 增加默认继承逻辑:`PYINT_WSL_DISTRO` 默认跟随 `ISCE2_WSL_DISTRO`
|
||||
- [ ] 增加默认继承逻辑:`PYINT_WSL_PYTHON` 默认跟随 `ISCE2_PYTHON`
|
||||
- [ ] 增加系统托管目录默认值:
|
||||
- [ ] `PYINT_TEMPLATE_ROOT`
|
||||
- [ ] `PYINT_WORK_ROOT`
|
||||
- [ ] `PYINT_OUTPUT_ROOT`
|
||||
- [ ] 在 `validate_runtime_config()` 中加入 PyINT 基础校验
|
||||
- [ ] 在 `.env.example` 中补齐非敏感 PyINT 配置示例
|
||||
|
||||
### 4.2 服务层
|
||||
|
||||
- [ ] 新增 `backend/app/services/pyint_service.py`
|
||||
- [ ] 封装 WSL 执行逻辑,复用现有 `wsl_service.py`
|
||||
- [ ] 实现 Windows 路径到 WSL 路径转换
|
||||
- [ ] 实现 PyINT 工作区目录初始化
|
||||
- [ ] 实现模板文件生成
|
||||
- [ ] 实现运行参数到模板字段的映射
|
||||
- [ ] 实现运行摘要 JSON 输出
|
||||
- [ ] 实现 PyINT 烟测函数
|
||||
|
||||
### 4.3 引擎层
|
||||
|
||||
- [ ] 新增 `backend/app/dinsar_engines/pyint_engine.py`
|
||||
- [ ] 实现 `DinsarEngine` 接口
|
||||
- [ ] 定义 `engine_code=pyint`
|
||||
- [ ] 定义一期唯一 profile,建议为 `lt1_gamma_dinsar`
|
||||
- [ ] 定义最小参数 schema,避免一开始暴露过多 PyINT 原生参数
|
||||
- [ ] 实现 `check_available()`
|
||||
- [ ] 实现 `run()`
|
||||
|
||||
### 4.4 注册与任务调度
|
||||
|
||||
- [ ] 在 `backend/app/dinsar_engines/registry.py` 注册 `PyINT`
|
||||
- [ ] 在 `backend/app/services/job_handlers.py` 增加 `JOB_TYPE_PYINT_RUN`
|
||||
- [ ] 新增对应 handler
|
||||
- [ ] 在 `backend/app/routers/dinsar_production.py` 允许 `engine_code=pyint`
|
||||
- [ ] 让生产提交逻辑按 `pyint` 分派到新 job type
|
||||
|
||||
### 4.5 WSL 包装脚本
|
||||
|
||||
- [ ] 新增 `backend/app/pyint_pipeline/run_lt1_pyint_pipeline.py`
|
||||
- [ ] 负责把系统任务目录映射为 PyINT 项目目录
|
||||
- [ ] 负责设置 `SCRATCHDIR` / `TEMPLATEDIR` / `DEMDIR`
|
||||
- [ ] 负责调用 `pyintApp.py` 或必要的细粒度 PyINT 脚本
|
||||
- [ ] 负责收集输出路径和运行摘要
|
||||
|
||||
### 涉及文件
|
||||
|
||||
- [ ] `backend/app/config.py`
|
||||
- [ ] `backend/app/dinsar_engines/registry.py`
|
||||
- [ ] `backend/app/dinsar_engines/pyint_engine.py`
|
||||
- [ ] `backend/app/services/pyint_service.py`
|
||||
- [ ] `backend/app/services/job_handlers.py`
|
||||
- [ ] `backend/app/routers/dinsar_production.py`
|
||||
- [ ] `backend/app/pyint_pipeline/run_lt1_pyint_pipeline.py`
|
||||
- [ ] `.env.example`
|
||||
|
||||
### 阶段验收
|
||||
|
||||
- [ ] `/dinsar-production/engines` 能返回 `pyint`
|
||||
- [ ] `PyINT` 引擎可在后端被识别为可用/不可用
|
||||
- [ ] 可以成功提交一个 `pyint` 生产任务到队列
|
||||
- [ ] 任务日志、任务状态、错误信息可通过现有任务体系查看
|
||||
|
||||
## 5. Phase 2:PyINT 结果归一化与结果治理兼容
|
||||
|
||||
目标:
|
||||
|
||||
- 保证 `PyINT` 输出能进入现有结果扫描、发布和 catalog 体系
|
||||
|
||||
### 任务
|
||||
|
||||
- [ ] 定义 PyINT 结果工作区与正式输出区的边界
|
||||
- [ ] 统一输出 bundle 元数据格式
|
||||
- [ ] 输出 engine/profile/run_key/task_name/pair trace 元数据
|
||||
- [ ] 补齐 pair 相关元数据:
|
||||
- [ ] `pair_uid`
|
||||
- [ ] `network_run_id`
|
||||
- [ ] `network_edge_id`
|
||||
- [ ] `policy_version`
|
||||
- [ ] 让现有 `dinsar_scan_service` 可以识别 PyINT 结果
|
||||
- [ ] 验证现有 `result_catalog_service` 可处理 PyINT 产物
|
||||
- [ ] 验证桥接一致性逻辑不会把 PyINT 结果识别坏
|
||||
|
||||
### 涉及文件
|
||||
|
||||
- [ ] `backend/app/services/pyint_service.py`
|
||||
- [ ] `backend/app/services/dinsar_scan_service.py`
|
||||
- [ ] `backend/app/services/result_catalog_service.py`
|
||||
- [ ] 可能涉及现有结果元数据写入辅助模块
|
||||
|
||||
### 阶段验收
|
||||
|
||||
- [ ] 跑完 PyINT 后可被系统扫描到
|
||||
- [ ] 可进入结果目录索引
|
||||
- [ ] 不影响现有 SARscape/ISCE2 结果扫描
|
||||
|
||||
## 6. Phase 3:前端生产页接入 PyINT
|
||||
|
||||
目标:
|
||||
|
||||
- 在现有生产页中把 `PyINT` 作为正式引擎展示和提交
|
||||
|
||||
### 任务
|
||||
|
||||
- [ ] 在 `frontend/src/DinsarProductionPanel.jsx` 中显示 `PyINT` 引擎卡片
|
||||
- [ ] 补充 `ENGINE_LABEL` / `TASK_TYPE_LABEL`
|
||||
- [ ] 根据 `PyINT` profile 渲染参数输入项
|
||||
- [ ] 对不可用状态显示明确原因
|
||||
- [ ] 提交成功后沿用现有任务监控
|
||||
- [ ] 验证运行列表中能正确显示 `pyint`
|
||||
|
||||
### 涉及文件
|
||||
|
||||
- [ ] `frontend/src/DinsarProductionPanel.jsx`
|
||||
- [ ] `frontend/src/api/dinsarProduction.js`
|
||||
- [ ] `frontend/src/utils/dinsarEngines.js` 如需要
|
||||
|
||||
### 阶段验收
|
||||
|
||||
- [ ] 前端可看到 `PyINT`
|
||||
- [ ] 可提交 `PyINT` 任务
|
||||
- [ ] 可看到任务状态和日志
|
||||
- [ ] 不影响现有 SARscape/ISCE2 提交
|
||||
|
||||
## 7. Phase 4:Gamma 精配对 MVP
|
||||
|
||||
目标:
|
||||
|
||||
- 在现有配对规划体系上实现一版可用的 `Gamma` 精配对
|
||||
|
||||
### 7.1 后端能力
|
||||
|
||||
- [ ] 新增 `backend/app/services/pairing_refinement_service.py`
|
||||
- [ ] 新增 `backend/app/services/gamma_pairing_service.py` 或同等职责模块
|
||||
- [ ] 实现基于现有 `network_run_id` 的场景集提取
|
||||
- [ ] 实现 PyINT/Gamma 配对工作区构建
|
||||
- [ ] 调用 `select_pairs.py` / `base_calc`
|
||||
- [ ] 解析 `ifgram_list.txt` / baseline 输出
|
||||
- [ ] 生成新的 refined `network_run_id`
|
||||
- [ ] 将精配对结果写入:
|
||||
- [ ] `pairing_network_runs`
|
||||
- [ ] `pairing_network_edges`
|
||||
- [ ] `selection_meta_json`
|
||||
|
||||
### 7.2 接口层
|
||||
|
||||
- [ ] 在 `backend/app/routers/pairing.py` 增加 `POST /pairing/refine-gamma`
|
||||
- [ ] 设计请求体和响应体
|
||||
- [ ] 设计运行告警返回字段
|
||||
- [ ] 如需要,增加 refined artifacts 查询接口
|
||||
|
||||
### 7.3 存储策略
|
||||
|
||||
- [ ] 明确一期不改 `pairing_metric_cache` 语义
|
||||
- [ ] 明确只在 run/edge JSON 中落精配对元数据
|
||||
- [ ] 保留粗配对网络和精配对网络双轨并存
|
||||
|
||||
### 涉及文件
|
||||
|
||||
- [ ] `backend/app/routers/pairing.py`
|
||||
- [ ] `backend/app/services/spatial_service.py` 如需复用
|
||||
- [ ] `backend/app/services/pairing_refinement_service.py`
|
||||
- [ ] `backend/app/services/gamma_pairing_service.py`
|
||||
- [ ] `backend/app/models/schemas.py`
|
||||
|
||||
### 阶段验收
|
||||
|
||||
- [ ] 可基于一个已有 `network_run_id` 发起精配对
|
||||
- [ ] 返回新的 refined `network_run_id`
|
||||
- [ ] 精配对结果可通过现有 network 查询接口查看
|
||||
- [ ] 不破坏原粗配对结果
|
||||
|
||||
## 8. Phase 5:前端配对规划页接入 Gamma 精配对
|
||||
|
||||
目标:
|
||||
|
||||
- 在配对规划页提供精配对入口和结果摘要
|
||||
|
||||
### 任务
|
||||
|
||||
- [ ] 在 `frontend/src/panels/PairPlanningPanel.jsx` 新增 `Gamma 精配对` 区块
|
||||
- [ ] 展示当前粗配对网络摘要
|
||||
- [ ] 增加发起精配对按钮
|
||||
- [ ] 展示精配对结果摘要
|
||||
- [ ] 展示粗配对与精配对差异提示
|
||||
- [ ] 增加“采用哪一版网络继续生产”的状态表达
|
||||
|
||||
### 涉及文件
|
||||
|
||||
- [ ] `frontend/src/panels/PairPlanningPanel.jsx`
|
||||
- [ ] `frontend/src/api/pairing.js`
|
||||
|
||||
### 阶段验收
|
||||
|
||||
- [ ] 管理员可在配对规划页发起精配对
|
||||
- [ ] 能看到 refined 结果摘要
|
||||
- [ ] 不需要进入健康检查页做配对操作
|
||||
|
||||
## 9. Phase 6:运维自检与烟测补齐
|
||||
|
||||
目标:
|
||||
|
||||
- 让 PyINT/Gamma 的环境状态可被健康检查观察
|
||||
|
||||
### 任务
|
||||
|
||||
- [ ] 在 `backend/app/services/health_service.py` 中纳入 PyINT 检查
|
||||
- [ ] 检查项至少包括:
|
||||
- [ ] `PYINT_ENABLED`
|
||||
- [ ] distro 可访问
|
||||
- [ ] WSL Python 可执行
|
||||
- [ ] `pyintApp.py` 存在
|
||||
- [ ] `GAMMA_ENV_SCRIPT` 存在
|
||||
- [ ] `base_calc` 可执行
|
||||
- [ ] 模板目录可读
|
||||
- [ ] 工作目录可写
|
||||
- [ ] 增加管理员烟测接口
|
||||
- [ ] 前端健康页只展示状态摘要,不加复杂操作区
|
||||
|
||||
### 涉及文件
|
||||
|
||||
- [ ] `backend/app/services/health_service.py`
|
||||
- [ ] `backend/app/routers/dinsar_production.py`
|
||||
- [ ] `frontend/src/HealthCheckPanel.jsx`
|
||||
|
||||
### 阶段验收
|
||||
|
||||
- [ ] 健康页可看到 PyINT 状态
|
||||
- [ ] 可区分“引擎不可用”和“系统整体故障”
|
||||
- [ ] 不把精配对主操作入口放回健康页
|
||||
|
||||
## 10. Phase 7:可选数据库结构化增强
|
||||
|
||||
目标:
|
||||
|
||||
- 只有在业务确认需要更强的历史与运维管理时才进入本阶段
|
||||
|
||||
### 进入条件
|
||||
|
||||
- [ ] 需要独立查询精配对历史
|
||||
- [ ] 需要统计精配对失败率
|
||||
- [ ] 需要管理精配对 artifacts 生命周期
|
||||
- [ ] 需要构建更完整的后台管理页
|
||||
|
||||
### 任务
|
||||
|
||||
- [ ] 设计 `pairing_refinement_runs` 等新表
|
||||
- [ ] 新增迁移文件,例如 `007_pyint_gamma_integration.sql`
|
||||
- [ ] 在 `backend/app/db_maintenance.py` 中加入迁移列表
|
||||
- [ ] 验证 `ensure_database_ready()` 启动自动迁移
|
||||
- [ ] 验证幂等执行
|
||||
|
||||
### 阶段验收
|
||||
|
||||
- [ ] 新表结构不破坏现有 pairing 逻辑
|
||||
- [ ] 启动时可自动应用迁移
|
||||
- [ ] 老数据和老接口保持兼容
|
||||
|
||||
## 11. 联调与验收矩阵
|
||||
|
||||
### 后端
|
||||
|
||||
- [ ] `py_compile` 或等价语法检查通过
|
||||
- [ ] 新增路由可正常注册
|
||||
- [ ] 新增引擎可正常列出
|
||||
- [ ] 任务队列能执行 `PyINT`
|
||||
- [ ] 精配对接口能生成 refined network
|
||||
|
||||
### 前端
|
||||
|
||||
- [ ] `npm run build` 通过
|
||||
- [ ] 生产页能显示 `PyINT`
|
||||
- [ ] 配对规划页能显示 `Gamma 精配对`
|
||||
- [ ] 健康页能显示 PyINT 状态
|
||||
|
||||
### 集成
|
||||
|
||||
- [ ] `PyINT` 单任务最小链路跑通
|
||||
- [ ] 结果能被系统扫描
|
||||
- [ ] 精配对 MVP 跑通
|
||||
- [ ] 现有 SARscape/ISCE2 不回归
|
||||
|
||||
## 12. 当前明确不做
|
||||
|
||||
- [ ] 一期不把 PyINT 的全部模板参数开放到前端
|
||||
- [ ] 一期不接入 GACOS 自动邮箱下载链路
|
||||
- [ ] 一期不接入 POT、phase bias、完整时序 MintPy 流程
|
||||
- [ ] 一期不改写现有 `pairing_metric_cache` 字段语义
|
||||
- [ ] 一期不在健康检查页增加主操作面板
|
||||
- [ ] 一期不做多 WSL distro 管理
|
||||
|
||||
## 13. 当前建议的首批落地包
|
||||
|
||||
建议第一轮直接落以下内容:
|
||||
|
||||
- [ ] `config.py` + `.env.example` 的 `PYINT_*` 配置
|
||||
- [ ] `pyint_service.py`
|
||||
- [ ] `pyint_engine.py`
|
||||
- [ ] `registry.py` 注册
|
||||
- [ ] `job_handlers.py` 的 `JOB_TYPE_PYINT_RUN`
|
||||
- [ ] `dinsar_production.py` 的 `pyint` 提交分派
|
||||
- [ ] `run_lt1_pyint_pipeline.py`
|
||||
- [ ] `DinsarProductionPanel.jsx` 的 `PyINT` 引擎展示与提交
|
||||
|
||||
这批完成后,再进入 `Gamma` 精配对 MVP。
|
||||
@@ -0,0 +1,343 @@
|
||||
# PyINT LT-1 `coreg` 失败轨道假设验证实验
|
||||
|
||||
**日期**: 2026-04-20
|
||||
**状态**: 实验设计
|
||||
**目标问题**: 验证当前 LT-1 在 PyINT/Gamma 中 `coreg/init_offsetm` 失败,是否主要由 `par_LT1_SLC` 导入后的 orbit/state vector 处理缺失导致
|
||||
|
||||
## 1. 结论先行
|
||||
|
||||
这次实验不再重复验证配对逻辑,也不再重复验证 `Task_*` 路径组织、DEM 来源或多景输入形态。
|
||||
|
||||
本实验只回答一个更窄的问题:
|
||||
|
||||
> 在保持同一批 LT-1 影像、同一 master、同一 DEM、同一 `coreg` 参数不变的前提下,只改变 `.slc.par` 中的 state vector 处理方式,是否会显著改变 `coreg/init_offsetm` 的失败行为。
|
||||
|
||||
如果答案是“会”,则当前问题主要集中在 LT-1 导入后的轨道几何链条。
|
||||
如果答案是“不会”,则需要把排查重点转回 LT-1 导入本身的几何建模或 `MLI/SLC` 生成环节。
|
||||
|
||||
## 2. 已知事实
|
||||
|
||||
当前已经有一个可复现的 3 景隔离实验环境:
|
||||
|
||||
- 实验根目录: `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.6_N45.0_3scene`
|
||||
- master: `20230726`
|
||||
- slave:
|
||||
- `20230624`
|
||||
- `20230920`
|
||||
- 已确认成功的阶段:
|
||||
- `down2slc_all`
|
||||
- `makedem_pyint`
|
||||
- `generate_rdc_dem`
|
||||
- 已确认失败的阶段:
|
||||
- `coreg_gamma_all`
|
||||
- 当前稳定失败特征:
|
||||
- `init_offsetm failed`
|
||||
- `ERROR: number of zero values ... exceeds threshold: 32768`
|
||||
|
||||
这说明:
|
||||
|
||||
1. 输入组织已经足够让 PyINT 跑到 `coreg`。
|
||||
2. DEM 不构成这轮失败的主因。
|
||||
3. 问题更像是 `coreg` 所依赖的几何输入有问题,尤其是 `.slc.par` 的 orbit/state vector 链条。
|
||||
|
||||
## 3. 实验假设
|
||||
|
||||
### H1: 当前主假设
|
||||
|
||||
`par_LT1_SLC` 导入后的 `.slc.par` 还需要额外的 orbit/state vector 处理。
|
||||
|
||||
这个处理至少可能包括两类:
|
||||
|
||||
1. 对现有 state vectors 做平滑/过滤
|
||||
2. 用系统已有 LT-1 精密轨道 TXT 重写 state vectors,再做校验
|
||||
|
||||
### H0: 零假设
|
||||
|
||||
即使对 state vectors 做上述处理,`coreg/init_offsetm` 的失败模式也基本不变。
|
||||
若如此,则缺陷更可能位于:
|
||||
|
||||
- LT-1 导入后的几何参数生成
|
||||
- `MLI` 生成质量
|
||||
- `deskew` / 时序 / 采样参数
|
||||
- 或 `par_LT1_SLC` 本身不适用于当前这批数据
|
||||
|
||||
## 4. 实验原则
|
||||
|
||||
本实验必须严格控制变量,避免再把多种问题混在一起。
|
||||
|
||||
固定不变的部分:
|
||||
|
||||
- 同一批 3 景 LT-1 数据
|
||||
- 同一个 master: `20230726`
|
||||
- 同一套 `range_looks=2`, `azimuth_looks=2`
|
||||
- 同一个 DEM 数据源
|
||||
- 同一个 `coreg_gamma.py`
|
||||
- 同一个 PyINT/Gamma 环境
|
||||
|
||||
唯一允许变化的部分:
|
||||
|
||||
- `.slc.par` 内 state vector 的处理方式
|
||||
|
||||
不在本轮变化范围内:
|
||||
|
||||
- 不切换配对策略
|
||||
- 不切换 DEM
|
||||
- 不改 `coreg rescue`
|
||||
- 不改 `select_pairs`
|
||||
- 不重做新的场景池选择
|
||||
|
||||
## 5. 分组设计
|
||||
|
||||
### A 组: 基线组
|
||||
|
||||
目的: 复现当前失败,作为所有对照的基准。
|
||||
|
||||
处理方式:
|
||||
|
||||
- 使用 `par_LT1_SLC` 当前直接生成的 `.slc.par`
|
||||
- 不做任何 orbit/state vector 改写
|
||||
- 重新执行:
|
||||
- `generate_rdc_dem`
|
||||
- `coreg` 到每个 slave
|
||||
|
||||
预期:
|
||||
|
||||
- 与现有日志一致
|
||||
- 两个 slave 都在 `init_offsetm` 附近失败
|
||||
|
||||
### B 组: 仅做 Gamma orbit filter
|
||||
|
||||
目的: 验证“问题是否只是 state vector 需要过滤/平滑,而不一定需要外部精轨替换”。
|
||||
|
||||
处理方式:
|
||||
|
||||
- 在 A 组同源 `.slc.par` 副本上,仅对 state vectors 做 Gamma orbit filtering
|
||||
- 不引入系统外部 LT-1 精密轨道 TXT
|
||||
- 之后重新执行:
|
||||
- `generate_rdc_dem`
|
||||
- `coreg`
|
||||
|
||||
判定意义:
|
||||
|
||||
- 如果 B 组明显优于 A 组,说明 `par_LT1_SLC` 的原始 state vectors 质量不足,但问题可能主要是“需要轨道过滤”
|
||||
- 如果 B 组与 A 组几乎一样失败,则仅做过滤不够
|
||||
|
||||
### C 组: 精密轨道重写组
|
||||
|
||||
目的: 验证“问题是否是导入后缺少外部精密轨道替换”。
|
||||
|
||||
处理方式:
|
||||
|
||||
- 使用系统已有 LT-1 精密轨道 TXT
|
||||
- 通过 [apply_lt1_precise_orbit.py](/D:/Code/Insar_management_system_v2/backend/app/pyint_pipeline/apply_lt1_precise_orbit.py) 重写 `.slc.par` 的 `state_vector_*`
|
||||
- 插值目标时间栅格沿用 `.slc.par` 自身:
|
||||
- `number_of_state_vectors`
|
||||
- `time_of_first_state_vector`
|
||||
- `state_vector_interval`
|
||||
- 重写后重新执行:
|
||||
- `generate_rdc_dem`
|
||||
- `coreg`
|
||||
|
||||
判定意义:
|
||||
|
||||
- 如果 C 组明显优于 A 组,而 B 组没有明显改善,则说明问题更偏向“缺少精密轨道重写”
|
||||
- 如果 C 组和 B 组都改善,则说明“导入后的轨道链条不完整”成立,但是否必须引入外部精轨还需进一步量化
|
||||
|
||||
### D 组: 精密轨道重写后校验组
|
||||
|
||||
目的: 观察“精轨重写后,Gamma 自身的 spline 校验是否仍给出大修正量”。
|
||||
|
||||
处理方式:
|
||||
|
||||
- 先执行 C 组重写
|
||||
- 再调用 `ORB_filt_spline.py` 生成验证副本
|
||||
- 不一定把验证副本作为正式输入使用,先记录校验结果
|
||||
|
||||
判定意义:
|
||||
|
||||
- 如果校验修正量很小,说明 C 组重写后的 state vectors 与 Gamma 的平滑约束基本一致
|
||||
- 如果校验修正量仍然很大,说明即使引入精轨,state vector 时间栅格或插值方式仍可能有问题
|
||||
|
||||
## 6. 实验执行路径
|
||||
|
||||
推荐直接复用现有 3 景实验目录,不重新拷贝数据:
|
||||
|
||||
- 基础目录: `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.6_N45.0_3scene`
|
||||
- 现有日志目录: `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.6_N45.0_3scene\logs`
|
||||
- 现有 SLC 目录: `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.6_N45.0_3scene\pyint_stage\SLC`
|
||||
|
||||
推荐把每个实验组做成并列工作副本,例如:
|
||||
|
||||
```text
|
||||
D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.6_N45.0_3scene_cases\
|
||||
case_A_baseline\
|
||||
case_B_orb_filt\
|
||||
case_C_precise_orbit_rewrite\
|
||||
case_D_precise_orbit_validate\
|
||||
```
|
||||
|
||||
每个 case 必须从同一份 `down2slc_all` 完成后的结果拷贝出来,避免导入过程本身再次引入差异。
|
||||
|
||||
## 7. 每组执行顺序
|
||||
|
||||
### Step 1: 冻结基线输入
|
||||
|
||||
先选取一个共同起点:
|
||||
|
||||
- `down2slc_all` 已完成
|
||||
- `makedem_pyint` 已完成
|
||||
- `coreg` 尚未执行,或清理已有 `coreg` 中间产物
|
||||
|
||||
这样所有 case 都基于同一份:
|
||||
|
||||
- `SLC/*.slc`
|
||||
- `SLC/*.slc.par`
|
||||
- `MLI`
|
||||
- `DEM`
|
||||
|
||||
### Step 2: 仅修改 `.slc.par`
|
||||
|
||||
按分组分别对 `.slc.par` 做处理:
|
||||
|
||||
- A 组: 不改
|
||||
- B 组: 仅 filter
|
||||
- C 组: 精轨重写
|
||||
- D 组: 精轨重写后再做 Gamma 校验
|
||||
|
||||
注意:
|
||||
|
||||
- 不要重新导入原始压缩包
|
||||
- 不要改模板参数
|
||||
- 不要改 `ifgram_list`
|
||||
|
||||
### Step 3: 重做 `generate_rdc_dem`
|
||||
|
||||
因为 `rdc_dem` 与几何参数耦合,改完 `.slc.par` 后必须重做一次。
|
||||
|
||||
### Step 4: 单独跑每个 slave 的 `coreg`
|
||||
|
||||
推荐不要一开始就跑 `coreg_gamma_all.py`,而是先分别跑:
|
||||
|
||||
- `20230624`
|
||||
- `20230920`
|
||||
|
||||
这样更容易判断某个处理是否对所有 slave 都有效。
|
||||
|
||||
### Step 5: 收集指标
|
||||
|
||||
每个 case 对每个 slave 都产出独立日志,并汇总到统一表格。
|
||||
|
||||
## 8. 观测指标
|
||||
|
||||
本实验不能只看“是否跑通”,还要看失败形态是否发生了有意义的变化。
|
||||
|
||||
核心指标:
|
||||
|
||||
1. `coreg` 是否成功进入下一阶段
|
||||
2. `init_offsetm` 是否仍失败
|
||||
3. 报错中的 zero-value patch 数量
|
||||
4. 失败位置是否仍固定在 `init_offsetm`
|
||||
5. 是否产生有效的 `RSLC`
|
||||
|
||||
轨道相关指标:
|
||||
|
||||
1. 每个 `.slc.par` 改写前后的 state vector 位置差范数
|
||||
2. 每个 `.slc.par` 改写前后的 state vector 速度差范数
|
||||
3. `ORB_filt_spline.py` 若运行成功,其输出副本相对输入的修正量
|
||||
|
||||
结果质量指标:
|
||||
|
||||
1. 如果 `coreg` 成功,后续 `diff/cor` 是否仍全 0
|
||||
2. `diff_filt.zero_ratio`
|
||||
3. `cor.zero_ratio`
|
||||
|
||||
## 9. 判定标准
|
||||
|
||||
### 支持主假设的证据
|
||||
|
||||
以下任一情况都可视为强支持:
|
||||
|
||||
1. B 组或 C 组能让两个 slave 中至少一个从 `init_offsetm` 失败变成成功
|
||||
2. B 组或 C 组虽然仍失败,但 zero-value patch 数量显著下降
|
||||
3. C 组优于 B 组,说明外部精轨重写比单纯过滤更关键
|
||||
|
||||
### 反对主假设的证据
|
||||
|
||||
以下情况说明当前假设不足:
|
||||
|
||||
1. A/B/C/D 四组都在同一位置、以近似相同错误失败
|
||||
2. 改写前后 state vector 差异很大,但 `coreg` 行为几乎不变
|
||||
3. `ORB_filt_spline.py` 校验显示修正量不大,但 `coreg` 仍完全失败
|
||||
|
||||
若出现这些情况,下一轮应优先排查:
|
||||
|
||||
- `par_LT1_SLC` 生成的几何字段是否本身错误
|
||||
- `MLI` 数据中大面积零值的真实来源
|
||||
- LT-1 导入后的采样/deskew/时序链条
|
||||
|
||||
## 10. 推荐的最小可执行版本
|
||||
|
||||
如果想尽快验证,不必一次把四组都跑全,先做最小闭环:
|
||||
|
||||
1. A 组: 当前基线
|
||||
2. C 组: 精密轨道重写
|
||||
3. D 组: 精密轨道重写后做 `ORB_filt_spline.py` 校验
|
||||
|
||||
理由:
|
||||
|
||||
- A 组已经稳定存在
|
||||
- C 组最直接验证“外部精轨重写是否必要”
|
||||
- D 组可以帮助判断“即便重写了,Gamma 仍不认可的程度有多大”
|
||||
|
||||
B 组可以作为补充组,用来区分“只需过滤”还是“必须引入精轨”。
|
||||
|
||||
## 11. 执行前提
|
||||
|
||||
执行本实验前,需要确认:
|
||||
|
||||
1. WSL 中可调用 Gamma 工具
|
||||
2. `apply_lt1_precise_orbit.py` 可以访问本次实验所需的 LT-1 精密轨道 TXT
|
||||
3. `ORB_filt_spline.py` 如 shebang 不可用,则通过明确的 Python 解释器调用
|
||||
4. 每个 case 使用独立日志目录,避免覆盖
|
||||
|
||||
## 12. 风险与注意事项
|
||||
|
||||
1. 不能在同一个 `SLC` 目录上反复覆盖做多组实验,否则会污染基线
|
||||
2. 改写 `.slc.par` 后如果不重做 `generate_rdc_dem`,实验结论不可靠
|
||||
3. 这轮实验只验证“轨道处理是不是主因”,不等于验证“最终科学结果已经正确”
|
||||
4. 即使某组 `coreg` 成功,也必须继续检查后续 `diff/cor` 是否仍然全 0
|
||||
|
||||
## 13. 实验产出物
|
||||
|
||||
建议每组最终至少保留:
|
||||
|
||||
- 处理后的 `.slc.par`
|
||||
- `generate_rdc_dem` 日志
|
||||
- 每个 slave 的 `coreg` 日志
|
||||
- 一个汇总 JSON 或 Markdown 表
|
||||
|
||||
建议的汇总字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"case": "case_C_precise_orbit_rewrite",
|
||||
"master": "20230726",
|
||||
"slave": "20230920",
|
||||
"state_vector_mode": "precise_orbit_rewrite",
|
||||
"coreg_success": false,
|
||||
"failed_stage": "init_offsetm",
|
||||
"zero_patch_count": 190155,
|
||||
"rslc_exists": false,
|
||||
"orb_validation_status": "not_run"
|
||||
}
|
||||
```
|
||||
|
||||
## 14. 推荐下一步
|
||||
|
||||
推荐按下面顺序执行:
|
||||
|
||||
1. 先在现有 3 景实验目录上做 A/C/D 三组
|
||||
2. 如果 C 组明显改善,再补 B 组区分“过滤”与“精轨重写”的贡献
|
||||
3. 如果 A/B/C/D 全部失败,再正式转向 `par_LT1_SLC` 输出几何字段和 `MLI` 零值来源排查
|
||||
|
||||
这轮实验的价值不在于立刻修好流程,而在于把问题边界收窄到“轨道链条”还是“导入几何链条”。
|
||||
@@ -0,0 +1,308 @@
|
||||
# PyINT LT-1 DEM 几何链定位实验
|
||||
|
||||
**日期**: 2026-04-20
|
||||
**状态**: 实验设计
|
||||
**目标问题**: 验证 LT-1 在 PyINT/Gamma 中 `coreg/init_offsetm` 失败,是否由 DEM 本体问题引起,还是由 DEM 参与的几何映射链条引起
|
||||
|
||||
## 1. 结论先行
|
||||
|
||||
这轮实验不再直接回答“轨道是不是问题”,而是专门回答下面这个问题:
|
||||
|
||||
> `init_offsetm` 报错里的大量 `zero values in MLI1 image patch`,究竟是 DEM 文件本身有问题,还是 `DEM -> rdc_trans -> geocode -> mli0` 这一条几何映射链条有问题。
|
||||
|
||||
当前更值得优先验证的是:
|
||||
|
||||
1. `HGTSIM` 是否本身就存在异常空洞或覆盖错误
|
||||
2. `lt0` 是否把参考图映射到了错误位置
|
||||
3. `mli0` 的中心 `512 x 512` patch 是否天然就是大面积 0
|
||||
4. `mli0` 与 `Samp` 的有效重叠区是否根本不在图像中心
|
||||
|
||||
## 2. 已知事实
|
||||
|
||||
当前 `coreg_gamma.py` 的关键顺序是:
|
||||
|
||||
- `rdc_trans`
|
||||
- `geocode`
|
||||
- `create_diff_par`
|
||||
- `init_offsetm mli0 Samp diff0 1 1`
|
||||
|
||||
也就是说,`init_offsetm` 当前比较的是:
|
||||
|
||||
- `MLI1 = mli0`
|
||||
- `MLI2 = Samp`
|
||||
|
||||
而不是直接比较 DEM。
|
||||
|
||||
已完成的 A/C/D 轨道实验说明:
|
||||
|
||||
1. 只改 state vector,`init_offsetm` 的 zero-count 会下降
|
||||
2. 但下降后仍然失败
|
||||
3. `ORB_filt_spline.py` 已经基本认可重写后的轨道
|
||||
|
||||
这说明:
|
||||
|
||||
- 轨道确实影响几何
|
||||
- 但当前失败不太像“只有轨道问题”
|
||||
- DEM 相关的几何映射链条值得单独定位
|
||||
|
||||
## 3. 三类假设
|
||||
|
||||
### H1: DEM 本体问题
|
||||
|
||||
DEM 文件本身有问题,例如:
|
||||
|
||||
- 覆盖范围不对
|
||||
- 裁剪窗口不对
|
||||
- sidecar / 投影信息不对
|
||||
- 高程值大面积异常或空洞
|
||||
|
||||
若 H1 成立,则更换 DEM 源后应显著改变 `HGTSIM` 和 `mli0` 的空洞模式。
|
||||
|
||||
### H2: DEM 几何链问题
|
||||
|
||||
DEM 文件本身可用,但 LT-1 导入几何、轨道或 `generate_rdc_dem` 中间步骤有问题,导致:
|
||||
|
||||
- `rdc_trans` 查找表偏移
|
||||
- `geocode` 后的 `mli0` 被映射到错误位置
|
||||
- `mli0` 中心 patch 与 `Samp` 根本不重叠
|
||||
|
||||
若 H2 成立,则即使更换 DEM,本质失败形态也可能不变;但改变轨道或几何参数时,`mli0` 的零值分布会跟着变化。
|
||||
|
||||
### H3: patch 选取问题
|
||||
|
||||
`mli0` 与 `Samp` 不是完全不重叠,而是图像中心不是有效重叠区。
|
||||
|
||||
若 H3 成立,则:
|
||||
|
||||
- 全图并非都坏
|
||||
- 换 `rpos/azpos` 后,`init_offsetm` 可能在其他 patch 上能工作
|
||||
|
||||
## 4. 实验原则
|
||||
|
||||
这轮实验尽量不跑整条生产链,只盯 `init_offsetm` 之前的中间产物。
|
||||
|
||||
固定不变:
|
||||
|
||||
- 同一批 3 景 LT-1 数据
|
||||
- 同一个 master: `20230726`
|
||||
- 同一套 looks 参数
|
||||
- 同一份 PyINT/Gamma 环境
|
||||
|
||||
允许变化:
|
||||
|
||||
- DEM 来源
|
||||
- 是否启用精轨重写
|
||||
- `init_offsetm` 的 patch 位置
|
||||
|
||||
优先观测对象:
|
||||
|
||||
- `HGTSIM`
|
||||
- `lt0`
|
||||
- `mli0`
|
||||
- `Samp`
|
||||
- `diff0`
|
||||
|
||||
## 5. 分层实验设计
|
||||
|
||||
### Layer 1: 不改 DEM,先看中间产物
|
||||
|
||||
目的: 判断当前 DEM 链条到底在哪一步开始“空掉”。
|
||||
|
||||
#### 组 L1-A: 基线组
|
||||
|
||||
使用当前已经失败的 case,导出并统计:
|
||||
|
||||
- `HGTSIM`
|
||||
- `lt0`
|
||||
- `mli0`
|
||||
- `Samp`
|
||||
|
||||
对每个文件都做:
|
||||
|
||||
1. 全图零值比例
|
||||
2. 中心 `512 x 512` patch 零值比例
|
||||
3. 中心 patch 的最小值、最大值、均值
|
||||
4. 快速可视化图
|
||||
|
||||
判定意义:
|
||||
|
||||
- 如果 `HGTSIM` 自身就明显异常,优先怀疑 DEM 或 `generate_rdc_dem`
|
||||
- 如果 `HGTSIM` 正常而 `mli0` 异常,优先怀疑 `lt0/geocode`
|
||||
- 如果 `mli0` 正常但中心 patch 不在有效重叠区,优先怀疑 patch 选取
|
||||
|
||||
#### 组 L1-B: 精轨重写对照组
|
||||
|
||||
复用已经跑过的精轨重写 case,只比较:
|
||||
|
||||
- `HGTSIM`
|
||||
- `mli0`
|
||||
- `Samp`
|
||||
|
||||
判定意义:
|
||||
|
||||
- 如果只改轨道,`mli0` 的零值分布就跟着变,说明问题不在 DEM 文件本体
|
||||
- 如果 `HGTSIM` 也明显变化,说明 DEM 映射结果强依赖 `.slc.par` 几何
|
||||
|
||||
### Layer 2: 改 DEM 源,固定几何
|
||||
|
||||
目的: 判断 DEM 文件本身是否是主因。
|
||||
|
||||
#### 组 L2-A: 当前 DEM
|
||||
|
||||
使用当前 `prepared_dem_source`,作为基线。
|
||||
|
||||
#### 组 L2-B: 替代 DEM
|
||||
|
||||
推荐优先选一个同区域、同分辨率级别、不同来源的 DEM,例如:
|
||||
|
||||
- 已有的另一份系统 DEM
|
||||
- 或成功 ENVI/IDL 任务中使用过的 DEM
|
||||
|
||||
要求:
|
||||
|
||||
- 不改 `.slc.par`
|
||||
- 不改轨道
|
||||
- 只重跑 `makedem_pyint -> generate_rdc_dem`
|
||||
|
||||
判定意义:
|
||||
|
||||
- 如果换 DEM 后 `HGTSIM/mli0` 明显改善,DEM 本体有嫌疑
|
||||
- 如果几乎不变,DEM 本体不是主因
|
||||
|
||||
#### 组 L2-C: 合成平坦 DEM
|
||||
|
||||
用一个覆盖相同区域、常数高程的测试 DEM。
|
||||
|
||||
这组不是为了出正确结果,而是为了测试:
|
||||
|
||||
- 失败是否强依赖真实地形起伏
|
||||
- 还是只要进入几何映射链就已经错位
|
||||
|
||||
判定意义:
|
||||
|
||||
- 如果平坦 DEM 仍在同一位置失败,说明不是高程细节导致
|
||||
- 如果平坦 DEM 反而明显改善,则真实 DEM 参与的映射可能存在投影或裁剪问题
|
||||
|
||||
### Layer 3: 不改 DEM,扫描 patch 位置
|
||||
|
||||
目的: 判断中心 patch 是否只是选错了地方。
|
||||
|
||||
方法:
|
||||
|
||||
- 保持 `mli0`、`Samp`、`diff0` 不变
|
||||
- 只改变 `init_offsetm` 的:
|
||||
- `rpos`
|
||||
- `azpos`
|
||||
- 在图像中心周围做稀疏网格扫描
|
||||
|
||||
推荐:
|
||||
|
||||
- 先做 `5 x 5` 或 `7 x 7` 网格
|
||||
- patch 大小仍保持默认 `512`
|
||||
|
||||
每个点记录:
|
||||
|
||||
- 是否报 zero-patch 错误
|
||||
- zero-count
|
||||
- 是否能进入下一步
|
||||
|
||||
判定意义:
|
||||
|
||||
- 如果某些位置能通过,说明不是整幅图都坏,而是中心 patch 选取不对
|
||||
- 如果所有位置都报大面积 0,更像几何链整体错位
|
||||
|
||||
## 6. 关键观测指标
|
||||
|
||||
### DEM 相关
|
||||
|
||||
1. `HGTSIM` 是否生成成功
|
||||
2. `HGTSIM` 的全图与中心 patch 零值比例
|
||||
3. `HGTSIM` 是否存在明显空洞、条带或边界错切
|
||||
|
||||
### 几何映射相关
|
||||
|
||||
1. `lt0` 是否可用
|
||||
2. `mli0` 的全图与中心 patch 零值比例
|
||||
3. `mli0` 与 `Samp` 的有效像元重叠比例
|
||||
4. `mli0` 与 `Samp` 是否在中心 patch 上具有相似纹理
|
||||
|
||||
### `init_offsetm` 相关
|
||||
|
||||
1. 是否仍失败在同一位置
|
||||
2. zero-count 是否显著下降
|
||||
3. 换 patch 位置后是否存在可工作区域
|
||||
|
||||
## 7. 推荐输出物
|
||||
|
||||
每轮实验至少产出:
|
||||
|
||||
- 中间产物清单
|
||||
- 每个文件的统计 JSON
|
||||
- 快速可视化 PNG/TIF
|
||||
- 一张对照表
|
||||
|
||||
推荐的统计字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"case": "L1-A_baseline",
|
||||
"file": "mli0",
|
||||
"width": 0,
|
||||
"lines": 0,
|
||||
"global_zero_ratio": 0.0,
|
||||
"center_patch_zero_ratio": 0.0,
|
||||
"center_patch_size": 512,
|
||||
"nonzero_overlap_with_samp": 0.0
|
||||
}
|
||||
```
|
||||
|
||||
## 8. 判定标准
|
||||
|
||||
### 支持“DEM 本体问题”的证据
|
||||
|
||||
1. 更换 DEM 后,`HGTSIM` 和 `mli0` 的空洞模式大幅变化
|
||||
2. 同一套几何下,只有某一份 DEM 会触发大面积零值
|
||||
3. 合成平坦 DEM 能显著改善中心 patch
|
||||
|
||||
### 支持“DEM 几何链问题”的证据
|
||||
|
||||
1. `HGTSIM` 看起来基本正常,但 `mli0` 大面积为 0
|
||||
2. 只改轨道或 `.slc.par`,`mli0` 零值分布就发生变化
|
||||
3. 换 DEM 后失败模式基本不变
|
||||
|
||||
### 支持“patch 选取问题”的证据
|
||||
|
||||
1. 中心 patch 失败,但偏移后的 patch 可以工作
|
||||
2. `mli0` 与 `Samp` 在全图上存在局部重叠区,只是中心不对
|
||||
|
||||
## 9. 推荐的最小闭环
|
||||
|
||||
不建议一上来就换很多 DEM。最小闭环应按这个顺序:
|
||||
|
||||
1. 先做 Layer 1
|
||||
- 对现有基线 case 和精轨重写 case 提取 `HGTSIM/lt0/mli0/Samp` 统计和快视图
|
||||
2. 再做 Layer 3
|
||||
- 扫描 `init_offsetm` 的 `rpos/azpos`
|
||||
3. 只有在 Layer 1/3 仍无法判断时,再做 Layer 2 换 DEM
|
||||
|
||||
原因:
|
||||
|
||||
- 这能先区分“DEM 文件坏了”与“中心 patch 选错了”
|
||||
- 也能避免过早把问题全部甩给 DEM
|
||||
|
||||
## 10. 推荐下一步
|
||||
|
||||
推荐直接执行两个子实验:
|
||||
|
||||
1. 中间产物审计实验
|
||||
- 把 A 组和 C 组的 `HGTSIM/lt0/mli0/Samp` 取出来做零值统计和快视图
|
||||
2. `init_offsetm` patch 扫描实验
|
||||
- 在同一 case 上只扫描 `rpos/azpos`
|
||||
|
||||
如果这两步做完后发现:
|
||||
|
||||
- `mli0` 全图都坏,再优先查 `generate_rdc_dem` 和 LT-1 导入几何
|
||||
- 只有中心 patch 坏,再优先查 patch 选取
|
||||
- 换 DEM 才有明显改善,再回到 DEM 本体问题
|
||||
|
||||
这轮实验的目的不是立刻修好 `coreg`,而是把“DEM 文件问题”和“DEM 几何链问题”从概念判断变成可测的证据链。
|
||||
@@ -0,0 +1,158 @@
|
||||
# PyINT LT-1 DEM Source Experiment Results
|
||||
|
||||
**日期**: 2026-04-20
|
||||
**状态**: 已执行
|
||||
**目标问题**: `init_offsetm` 失败是否主要由 DEM 本体来源导致
|
||||
|
||||
## 1. 前置结论
|
||||
|
||||
在这轮 DEM 源对照之前,已经完成 `init_offsetm` patch 扫描。
|
||||
|
||||
- 基线 run root:
|
||||
- `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.6_N45.0_3scene_cases\run_20260420T093322Z`
|
||||
- 扫描结论:
|
||||
- 更换 `rpos/azpos` 可以把中心 patch 的零值数从 `184099/190155` 降到约 `168322/166114`
|
||||
- 但仍远高于 `32768` 阈值
|
||||
- 没有任何候选 patch 通过 `init_offsetm`
|
||||
|
||||
因此,这里把“中心 patch 选错”降级为次要因素,继续验证 DEM 源本体是否主导失败。
|
||||
|
||||
## 2. 实验设计
|
||||
|
||||
固定条件:
|
||||
|
||||
- 同一组 3 景 LT-1 数据
|
||||
- 同一 master: `20230726`
|
||||
- 同一 baseline orbit 几何
|
||||
- 同一 PyINT/Gamma 处理链
|
||||
|
||||
只更换 DEM 来源:
|
||||
|
||||
1. `COPDEM`
|
||||
- `prepared_dem_source=/mnt/d/DEM/COPDEM_GLO30_China_4326_DEM`
|
||||
2. `GMTED2010`
|
||||
- `prepared_dem_source=/mnt/d/DEM/GMTED2010.jp2`
|
||||
3. `OpenTopography SRTMGL1`
|
||||
- 走 PyINT 默认下载路径
|
||||
|
||||
执行链路:
|
||||
|
||||
- `makedem_pyint`
|
||||
- `generate_rdc_dem`
|
||||
- `coreg_gamma`
|
||||
- `audit_lt1_dem_geometry_chain.py`
|
||||
|
||||
## 3. 实验目录
|
||||
|
||||
本地 DEM 对照:
|
||||
|
||||
- run root:
|
||||
- `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.6_N45.0_3scene_dem_cases\run_20260420T152607Z`
|
||||
- 审计输出:
|
||||
- `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.6_N45.0_3scene_dem_cases\run_20260420T152607Z\audit_dem_geometry`
|
||||
|
||||
OpenTopography SRTMGL1:
|
||||
|
||||
- 首次尝试:
|
||||
- `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.6_N45.0_3scene_dem_cases\run_20260420T170406Z`
|
||||
- 失败原因: WSL `isce2` 环境缺少 `rasterio`
|
||||
- 安装 `rasterio` 后重跑:
|
||||
- `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.6_N45.0_3scene_dem_cases\run_20260420T220524Z`
|
||||
- 审计输出:
|
||||
- `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.6_N45.0_3scene_dem_cases\run_20260420T220524Z\audit_dem_geometry`
|
||||
|
||||
## 4. 结果摘要
|
||||
|
||||
### 4.1 `coreg/init_offsetm` zero-count
|
||||
|
||||
`20230624`:
|
||||
|
||||
- `COPDEM`: `184099`
|
||||
- `GMTED2010`: `262033`
|
||||
- `SRTMGL1`: `183582`
|
||||
|
||||
`20230920`:
|
||||
|
||||
- `COPDEM`: `190155`
|
||||
- `GMTED2010`: `262070`
|
||||
- `SRTMGL1`: `189571`
|
||||
|
||||
阈值均为 `32768`。
|
||||
|
||||
### 4.2 `HGTSIM` / `lt0` / `mli0_samp_overlap`
|
||||
|
||||
`COPDEM`:
|
||||
|
||||
- `hgtsim zero_ratio`: `0.967266`
|
||||
- `lt0 valid_pair_ratio`: `0.032734`
|
||||
- `20230624 center overlap`: `0.297718`
|
||||
- `20230920 center overlap`: `0.274616`
|
||||
|
||||
`GMTED2010`:
|
||||
|
||||
- `hgtsim zero_ratio`: `0.999964`
|
||||
- `lt0 valid_pair_ratio`: `0.000036`
|
||||
- `20230624 center overlap`: `0.000423`
|
||||
- `20230920 center overlap`: `0.000282`
|
||||
|
||||
`SRTMGL1`:
|
||||
|
||||
- `hgtsim zero_ratio`: `0.967264`
|
||||
- `lt0 valid_pair_ratio`: `0.032736`
|
||||
- `20230624 center overlap`: `0.299690`
|
||||
- `20230920 center overlap`: `0.276844`
|
||||
|
||||
## 5. 结论
|
||||
|
||||
### 5.1 当前 `COPDEM` 不是主要故障源
|
||||
|
||||
`SRTMGL1` 作为更接近原始 PyINT 默认路径的下载 DEM,跑出来的几何指标与当前 `COPDEM` 几乎一致:
|
||||
|
||||
- `hgtsim zero_ratio` 基本相同
|
||||
- `lt0 valid_pair_ratio` 基本相同
|
||||
- `mli0_samp_overlap` 基本相同
|
||||
- `init_offsetm zero-count` 只改善了几百个像素,量级上没有本质变化
|
||||
|
||||
这说明:
|
||||
|
||||
- 把当前系统 DEM 替换成原始 PyINT 默认下载 DEM
|
||||
- 并不能把问题从 `184k/190k` 拉到 `32768` 阈值附近
|
||||
|
||||
### 5.2 更差的 DEM 会进一步恶化问题
|
||||
|
||||
`GMTED2010` 把几何链几乎压成全零:
|
||||
|
||||
- `hgtsim zero_ratio` 逼近 `1.0`
|
||||
- `lt0 valid_pair_ratio` 下降到 `0.000036`
|
||||
- `init_offsetm zero-count` 直接升到 `262k`
|
||||
|
||||
这说明 DEM 源会影响结果,但当前问题不是“现有 DEM 明显坏掉”,而是:
|
||||
|
||||
- 当前几何链本来就已经非常稀疏
|
||||
- 更粗或不合适的 DEM 只会让它更差
|
||||
|
||||
### 5.3 当前最可疑的位置继续落在 LT-1 几何导入链
|
||||
|
||||
综合 patch 扫描和 DEM 源对照,当前更像是以下链路问题,而不是 DEM 文件本体问题:
|
||||
|
||||
- `par_LT1_SLC / LT-1 导入几何`
|
||||
- `generate_rdc_dem`
|
||||
- `coreg_gamma` 中基于 DEM 的几何映射链
|
||||
|
||||
## 6. 补充记录
|
||||
|
||||
为完成 `OpenTopography SRTMGL1` 对照,已在 WSL `isce2` 环境安装:
|
||||
|
||||
- `rasterio==1.4.4`
|
||||
|
||||
安装原因不是业务修复,而是 PyINT 下载 DEM 路径在当前环境里依赖该包做分块 tif 校验与合并。
|
||||
|
||||
## 7. 建议下一步
|
||||
|
||||
下一轮不建议继续反复更换 DEM。
|
||||
|
||||
更值得做的是:
|
||||
|
||||
1. 对比 `COPDEM` 与 `SRTMGL1` 生成出来的 `pyint_stage.dem.par`、`UTMDEMpar`、`UTM2RDC/UTMTORDC` 是否几乎一致
|
||||
2. 回到 LT-1 导入链,核查 `.slc.par` 中被 `gc_map1 / geocode / init_offsetm` 直接消费的几何字段
|
||||
3. 如果需要继续做 DEM 类实验,优先做“同一 DEM 下替换导入几何参数”,而不是继续换 DEM 本体
|
||||
@@ -0,0 +1,145 @@
|
||||
# PyINT LT-1 Pair Selection Experiment
|
||||
|
||||
**日期**: 2026-04-21
|
||||
**状态**: 已执行
|
||||
**目标问题**: 之前 `init_offsetm` 失败是否只是当前任务配对选得不好
|
||||
|
||||
## 1. 实验思路
|
||||
|
||||
上一轮根因定位主要围绕这一组 2023 年 SYC 数据:
|
||||
|
||||
- `2023-06-24`
|
||||
- `2023-07-26`
|
||||
- `2023-09-20`
|
||||
|
||||
其中:
|
||||
|
||||
- `2023-06-24 -> 2023-07-26`
|
||||
- `2023-07-26 -> 2023-09-20`
|
||||
|
||||
两对都失败,且 `2023-06-24 -> 2023-07-26` 已经是较短时基。
|
||||
|
||||
为了验证是不是“只是这几对碰巧不行”,本轮换了一组新的、同条带同中心点的 2024 年三景,并改用中间时相作为 master。
|
||||
|
||||
## 2. 实验数据
|
||||
|
||||
实验根目录:
|
||||
|
||||
- `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.4_N45.0_3scene_2024`
|
||||
|
||||
从影像库复制的三景:
|
||||
|
||||
1. `LT1A_MONO_SYC_STRIP1_012583_E129.4_N45.0_20240520_SLC_HH_S2A_0000402579`
|
||||
2. `LT1A_MONO_SYC_STRIP1_013416_E129.4_N45.0_20240715_SLC_HH_S2A_0000454453`
|
||||
3. `LT1A_MONO_SYC_STRIP1_014249_E129.4_N45.0_20240909_SLC_HH_S2A_0000505340`
|
||||
|
||||
配置:
|
||||
|
||||
- `masterDate=20240715`
|
||||
- `startDate=20240501`
|
||||
- `endDate=20240930`
|
||||
- DEM 仍使用:
|
||||
- `/mnt/d/DEM/COPDEM_GLO30_China_4326_DEM`
|
||||
|
||||
## 3. 执行链路
|
||||
|
||||
执行脚本:
|
||||
|
||||
- 复制实验根:
|
||||
- `D:\Code\Insar_management_system_v2\.codex_tmp\setup_lt1_pool_multiscene_experiment.ps1`
|
||||
- 跑三景最小链路:
|
||||
- `D:\Code\Insar_management_system_v2\.codex_tmp\run_lt1_pool_multiscene_generic.sh`
|
||||
- 审计几何中间产物:
|
||||
- `D:\Code\Insar_management_system_v2\.codex_tmp\audit_lt1_pool_multiscene_root.py`
|
||||
|
||||
实际运行结果:
|
||||
|
||||
- `down2slc_all`: 成功
|
||||
- `makedem_pyint`: 成功
|
||||
- `generate_rdc_dem`: 成功
|
||||
- `coreg_gamma_all`: 失败
|
||||
|
||||
由于 `coreg_gamma_all` 在第一对失败后停止,又额外补跑了:
|
||||
|
||||
- `coreg_20240909`
|
||||
|
||||
这样两对都拿到了独立结果。
|
||||
|
||||
## 4. 结果
|
||||
|
||||
### 4.1 `init_offsetm` 失败情况
|
||||
|
||||
`20240520 <- 20240715(master)`:
|
||||
|
||||
- `zero_count = 197702`
|
||||
- `threshold = 32768`
|
||||
|
||||
`20240909 <- 20240715(master)`:
|
||||
|
||||
- `zero_count = 196712`
|
||||
- `threshold = 32768`
|
||||
|
||||
对应日志:
|
||||
|
||||
- `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.4_N45.0_3scene_2024\logs\coreg_gamma_all.stderr.log`
|
||||
- `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.4_N45.0_3scene_2024\logs\coreg_20240909.stderr.log`
|
||||
|
||||
### 4.2 中间产物审计
|
||||
|
||||
审计汇总:
|
||||
|
||||
- `D:\PyINT_POOL_TEST\LT1A_MONO_SYC_STRIP1_E129.4_N45.0_3scene_2024\audit_dem_geometry\audit_summary.tsv`
|
||||
|
||||
关键指标:
|
||||
|
||||
- `hgtsim zero_ratio = 0.974356`
|
||||
- `lt0 valid_pair_ratio = 0.025644`
|
||||
- `20240520 center overlap = 0.245827`
|
||||
- `20240909 center overlap = 0.249603`
|
||||
|
||||
## 5. 与 2023 年那组三景对比
|
||||
|
||||
2023 年 `E129.6_N45.0` 那组基线结果:
|
||||
|
||||
- `20230624`: `zero_count = 184099`
|
||||
- `20230920`: `zero_count = 190155`
|
||||
- `hgtsim zero_ratio = 0.967266`
|
||||
- `lt0 valid_pair_ratio = 0.032734`
|
||||
|
||||
2024 年 `E129.4_N45.0` 新组三景结果:
|
||||
|
||||
- `20240520`: `zero_count = 197702`
|
||||
- `20240909`: `zero_count = 196712`
|
||||
- `hgtsim zero_ratio = 0.974356`
|
||||
- `lt0 valid_pair_ratio = 0.025644`
|
||||
|
||||
## 6. 结论
|
||||
|
||||
这轮实验不支持“只是当前 pair 选坏了”这个解释。
|
||||
|
||||
原因很直接:
|
||||
|
||||
1. 换了一整组三景
|
||||
2. 换了 master
|
||||
3. 两对 slave 都单独跑到了 `init_offsetm`
|
||||
4. 结果仍然失败
|
||||
5. 而且零值规模没有改善,反而比 2023 那组更差
|
||||
|
||||
因此当前更合理的判断是:
|
||||
|
||||
- 问题不是单纯 pair selection
|
||||
- 也不是只集中在 `2023-07-26` 这一景
|
||||
- 更像 LT-1 在 PyINT/Gamma 下的导入几何链存在系统性问题
|
||||
|
||||
## 7. 建议下一步
|
||||
|
||||
下一步不建议继续只靠“再换几对”来试。
|
||||
|
||||
更有价值的是继续往几何链前面查:
|
||||
|
||||
1. 对比不同实验根生成的 `.slc.par` 几何字段
|
||||
2. 对比 `generate_rdc_dem` 产生的:
|
||||
- `*.utm.dem.par`
|
||||
- `*.UTM_TO_RDC`
|
||||
- `*.rdc.dem`
|
||||
3. 重点核查 LT-1 导入程序和 Gamma 实际消费字段之间是否存在系统性偏差
|
||||
@@ -0,0 +1,232 @@
|
||||
# SBAS 前端设计说明
|
||||
|
||||
更新日期:2026-04-06
|
||||
|
||||
## 1. 设计目标
|
||||
|
||||
SBAS 前端必须解决四个问题:
|
||||
|
||||
- 让用户知道“匹配结果”和“正式生产运行”不是一回事
|
||||
- 让用户能从已有 PS 批次发起正式运行
|
||||
- 让用户能查看 `psinsar` 成果,而不是只看实验目录
|
||||
- 让用户能逐步过渡到更复杂的时序成果浏览,而不是一次性堆满功能
|
||||
|
||||
## 2. 导航结构
|
||||
|
||||
当前建议保留现有导航层级,只把占位页替换成真实页面。
|
||||
|
||||
### 2.1 生产规划组
|
||||
|
||||
- `ps_results`
|
||||
- 匹配结果浏览与批次创建
|
||||
- `ps_production`
|
||||
- 正式生产入口
|
||||
- `ps_products`
|
||||
- 成果编目与产品管理
|
||||
|
||||
### 2.2 InSAR 变形分析组
|
||||
|
||||
- `psinsar_results`
|
||||
- 以成果浏览为主的只读结果页
|
||||
- `psinsar_analysis`
|
||||
- 后续时序分析页,当前可继续保留占位
|
||||
|
||||
## 3. 页面一:`ps_production`
|
||||
|
||||
## 3.1 页面目标
|
||||
|
||||
从已有 `ps_task_batches` 中选择一个 stack,提交一次正式 SBAS 运行,并查看最近运行状态。
|
||||
|
||||
## 3.2 页面布局
|
||||
|
||||
建议分成三块:
|
||||
|
||||
- 运行说明卡
|
||||
- 新建运行表单
|
||||
- 最近运行列表
|
||||
|
||||
## 3.3 新建运行表单字段
|
||||
|
||||
必填字段:
|
||||
|
||||
- `batch_id`
|
||||
|
||||
可选字段:
|
||||
|
||||
- `run_name`
|
||||
- `reference_date`
|
||||
- `water_mask_mode`
|
||||
- `notes`
|
||||
|
||||
只读展示字段:
|
||||
|
||||
- `direction`
|
||||
- `stack_size`
|
||||
- `with_orbit_count`
|
||||
- `missing_orbit_count`
|
||||
|
||||
## 3.4 提交后反馈
|
||||
|
||||
提交后需要立刻给出:
|
||||
|
||||
- `task_id`
|
||||
- `run_id`
|
||||
- 当前状态
|
||||
|
||||
当前 Phase 1 仅执行 prepare,因此状态建议为:
|
||||
|
||||
- `PENDING`
|
||||
- `RUNNING`
|
||||
- `PREPARED`
|
||||
- `FAILED`
|
||||
|
||||
## 3.5 最近运行列表
|
||||
|
||||
每个运行卡片至少展示:
|
||||
|
||||
- `run_name`
|
||||
- `run_id`
|
||||
- `batch_id`
|
||||
- `reference_date`
|
||||
- `stack_size`
|
||||
- `status`
|
||||
- `created_at`
|
||||
|
||||
详情展开建议展示:
|
||||
|
||||
- DEM 路径
|
||||
- 轨道池路径
|
||||
- 生成的 stack manifest 路径
|
||||
- 输入日期列表
|
||||
- 质量/预检查摘要
|
||||
|
||||
## 4. 页面二:`ps_products`
|
||||
|
||||
## 4.1 页面目标
|
||||
|
||||
承接管理员视角的产物目录维护。
|
||||
|
||||
能力包括:
|
||||
|
||||
- 查看 `psinsar` catalog 状态
|
||||
- 手动重建 catalog
|
||||
- 浏览产品列表
|
||||
- 查看产品详情
|
||||
|
||||
## 4.2 页面布局
|
||||
|
||||
建议分成三块:
|
||||
|
||||
- catalog 状态卡
|
||||
- 管理操作区
|
||||
- 产品列表与详情区
|
||||
|
||||
## 4.3 catalog 状态卡
|
||||
|
||||
展示字段:
|
||||
|
||||
- `catalog_name`
|
||||
- `storage_root`
|
||||
- `status`
|
||||
- `needs_rebuild`
|
||||
- `manifest_count`
|
||||
- `db_count`
|
||||
- `issue_count`
|
||||
- `last_full_rebuild_at`
|
||||
|
||||
## 4.4 产品列表
|
||||
|
||||
每个产品卡片建议展示:
|
||||
|
||||
- `display_name`
|
||||
- `product_id`
|
||||
- `run_key`
|
||||
- `reference_date`
|
||||
- `stack_size`
|
||||
- `status`
|
||||
- `published_at`
|
||||
|
||||
优先展示缩略图:
|
||||
|
||||
- `preview/velocity_preview.png`
|
||||
|
||||
## 4.5 产品详情
|
||||
|
||||
详情建议包含:
|
||||
|
||||
- 基本信息
|
||||
- 时序信息
|
||||
- 质量摘要
|
||||
- 资产列表
|
||||
- 问题列表
|
||||
|
||||
资产列表首屏优先顺序:
|
||||
|
||||
- `velocity_geotiff`
|
||||
- `timeseries_cube`
|
||||
- `temporal_coherence_geotiff`
|
||||
- `quality_mask_geotiff`
|
||||
- `preview_png`
|
||||
- 其他辅助资产
|
||||
|
||||
## 5. 页面三:`psinsar_results`
|
||||
|
||||
## 5.1 页面目标
|
||||
|
||||
承接业务用户视角的成果浏览,不承担目录维护操作。
|
||||
|
||||
## 5.2 与 `ps_products` 的区别
|
||||
|
||||
- `ps_products` 偏运维和管理
|
||||
- `psinsar_results` 偏展示和检索
|
||||
|
||||
## 5.3 当前 Phase 1 能力
|
||||
|
||||
- 浏览产品列表
|
||||
- 查看缩略图
|
||||
- 查看资产清单
|
||||
- 查看质量摘要
|
||||
|
||||
## 5.4 后续 Phase 2/3 扩展
|
||||
|
||||
- 地图叠加 `velocity.tif`
|
||||
- 按 AOI 或时间筛选
|
||||
- 像元点位时序查询
|
||||
- 专题统计与热点识别
|
||||
|
||||
## 6. 交互原则
|
||||
|
||||
- 生产和结果页面必须分开
|
||||
- 管理操作只出现在管理页
|
||||
- 结果页优先展示 `velocity.tif` 对应预览
|
||||
- 但详情页必须强调主科学产物是 `geo_timeseries.h5`
|
||||
|
||||
## 7. 前端阶段性实施建议
|
||||
|
||||
### Phase 1
|
||||
|
||||
- `ps_production`:真实可提交 prepare 任务
|
||||
- `ps_products`:真实 catalog 管理页
|
||||
- `psinsar_results`:复用 catalog 浏览能力做只读页
|
||||
|
||||
### Phase 2
|
||||
|
||||
- 地图叠加 `velocity.tif`
|
||||
- 结果筛选
|
||||
- 与 run 详情联动
|
||||
|
||||
### Phase 3
|
||||
|
||||
- `geo_timeseries.h5` 点查询
|
||||
- 时间曲线图
|
||||
- 多产品对比
|
||||
|
||||
## 8. 当前结论
|
||||
|
||||
前端第一阶段不应追求“一口气把时序分析全做完”,而应优先做三件事:
|
||||
|
||||
- 让 SBAS 生产有正式入口
|
||||
- 让 SBAS 结果有正式目录
|
||||
- 让用户在系统里能看到真正的 `psinsar` 成果
|
||||
|
||||
这三件事完成后,系统才算真正开始承接 SBAS 能力。
|
||||
@@ -0,0 +1,102 @@
|
||||
# SBAS 系统实施 TODO
|
||||
|
||||
更新日期:2026-04-06
|
||||
|
||||
## Phase 1:低侵入落地
|
||||
|
||||
目标:
|
||||
|
||||
- 不影响 D-InSAR
|
||||
- 让系统开始承接 SBAS 生产记录与结果目录
|
||||
|
||||
### 后端模型
|
||||
|
||||
- [x] 新增 `PsTimeseriesRunORM`
|
||||
- [x] 新增 `PsTimeseriesRun` schema
|
||||
- [x] 为 `settings` 增加 `TIMESERIES_*` / `PSINSAR_PRODUCT_DIR` 配置
|
||||
|
||||
### 后端服务
|
||||
|
||||
- [x] 新增 `timeseries_service.py`
|
||||
- [x] 新增 `psinsar_catalog_service.py`
|
||||
- [x] 增加 SBAS prepare 任务处理逻辑
|
||||
|
||||
### 后端路由
|
||||
|
||||
- [x] 新增 `timeseries_production.py`
|
||||
- [x] 新增 `ps_products.py`
|
||||
- [x] 注册新路由
|
||||
|
||||
### 前端
|
||||
|
||||
- [x] 新增 `TimeseriesProductionPanel.jsx`
|
||||
- [x] 新增 `PsinsarCatalogPanel.jsx`
|
||||
- [x] 新增 `timeseriesProduction.js`
|
||||
- [x] 新增 `psinsarProducts.js`
|
||||
- [x] 替换 `ps_production` 占位页
|
||||
- [x] 替换 `ps_products` 占位页
|
||||
- [x] 替换 `psinsar_results` 占位页
|
||||
|
||||
### 校验
|
||||
|
||||
- [x] 后端语法检查
|
||||
- [x] 前端 build 检查
|
||||
- [ ] 验证 D-InSAR 页面未受影响
|
||||
|
||||
## Phase 2:串接实验处理链
|
||||
|
||||
目标:
|
||||
|
||||
- 在系统内真正触发 SBAS 处理
|
||||
|
||||
### 处理链
|
||||
|
||||
- [x] `prepare` 生成标准 stack manifest
|
||||
- [x] `materialize` 生成 stack 工作目录
|
||||
- [ ] 接入 ISCE2 stack 执行
|
||||
- [ ] 接入 MintPy SBAS 执行
|
||||
- [ ] 接入 geocode/export/publish
|
||||
|
||||
### 任务编排
|
||||
|
||||
- [x] 新增 workflow steps
|
||||
- [ ] 新增失败重试策略
|
||||
- [x] 增加运行日志归集
|
||||
|
||||
## Phase 3:结果展示增强
|
||||
|
||||
目标:
|
||||
|
||||
- 从“结果存在”升级到“结果可分析”
|
||||
|
||||
### 展示
|
||||
|
||||
- [ ] 地图叠加 `velocity.tif`
|
||||
- [ ] 按 AOI/时间筛选产品
|
||||
- [ ] 结果与 run 联动查看
|
||||
|
||||
### 分析
|
||||
|
||||
- [ ] `geo_timeseries.h5` 点位查询
|
||||
- [ ] 时间曲线图
|
||||
- [ ] 质量掩膜联动
|
||||
- [ ] 热点区域分析
|
||||
|
||||
## 当前阶段实施顺序
|
||||
|
||||
推荐顺序:
|
||||
|
||||
1. 文档补齐
|
||||
2. 运行记录模型
|
||||
3. prepare 任务
|
||||
4. `psinsar` catalog
|
||||
5. 前端生产页
|
||||
6. 前端结果页
|
||||
7. 静态校验
|
||||
|
||||
## 当前不做
|
||||
|
||||
- [ ] 不重构现有 D-InSAR 结果服务为完全通用框架
|
||||
- [ ] 不改现有配对算法
|
||||
- [ ] 不继续保留 SBAS 使用 `*_envi_import` 的旧逻辑
|
||||
- [ ] 不在当前 D-InSAR 生产环境中直接做依赖升级
|
||||
@@ -0,0 +1,124 @@
|
||||
# SBAS 系统改造当前状态
|
||||
|
||||
更新日期:2026-04-06
|
||||
|
||||
## 1. 当前结论
|
||||
|
||||
截至本轮,SBAS / PS-InSAR 已经完成第一阶段的“低侵入接入”改造:
|
||||
|
||||
- 已能在系统内创建正式 `ps_timeseries_runs`
|
||||
- 已能把现有 PS 匹配结果转换为 `stack_input_manifest.json`
|
||||
- 已能把实验产物 `psinsar.publish.v1` bundle 注册到系统结果目录
|
||||
- 已能在前端查看 SBAS 运行记录与 `psinsar` 产品目录
|
||||
- 已补齐 `psinsar` catalog 的启动期 bootstrap 与健康检查接入
|
||||
|
||||
这意味着系统已经不再只是“影像管理口”,而是具备了 SBAS 正式生产入口的骨架。当前已经串起实验级四步链:
|
||||
|
||||
- `prepare`
|
||||
- `stack_prep_initial`
|
||||
- `materialize`
|
||||
- `stack_prep_refresh`
|
||||
|
||||
但仍未接入真正的 ISCE2 stack / MintPy / geocode / publish 自动执行链。
|
||||
|
||||
## 2. 已完成范围
|
||||
|
||||
### 2.1 后端
|
||||
|
||||
- 新增 `ps_timeseries_runs` 运行记录模型
|
||||
- 新增 `timeseries_service.py`
|
||||
- 新增 `psinsar_catalog_service.py`
|
||||
- 新增 `timeseries_production.py`
|
||||
- 新增 `ps_products.py`
|
||||
- 作业系统已支持:
|
||||
- `TIMESERIES_PREPARE`
|
||||
- `TIMESERIES_STACK_PREP`
|
||||
- `TIMESERIES_MATERIALIZE`
|
||||
- `timeseries_service.py` 已补齐 workflow 驱动的:
|
||||
- `create_run`
|
||||
- `prepare_run`
|
||||
- `build_stack_prep`
|
||||
- `materialize_run`
|
||||
- `list_runs`
|
||||
- `get_run_detail`
|
||||
- 运行详情已可返回 `workflow.steps`
|
||||
- 启动阶段已同时检查 `dinsar` 与 `psinsar` 两套 catalog
|
||||
- `/health` 已保留原有 `result_catalog` 兼容字段,并新增:
|
||||
- `dinsar_result_catalog`
|
||||
- `psinsar_result_catalog`
|
||||
- `catalogs`
|
||||
|
||||
### 2.2 前端
|
||||
|
||||
- 已接入 `TimeseriesProductionPanel`
|
||||
- 已接入 `PsinsarCatalogPanel`
|
||||
- 已替换 `ps_production`、`ps_products`、`psinsar_results` 占位页
|
||||
- `TimeseriesProductionPanel` 已补充 Phase 2 状态色和 workflow 步骤展示
|
||||
|
||||
### 2.3 文档
|
||||
|
||||
已形成以下系统设计与风险文档:
|
||||
|
||||
- `SBAS_SYSTEM_INTEGRATION_AUDIT_20260406.md`
|
||||
- `SBAS_SYSTEM_EMBEDDING_DESIGN_20260406.md`
|
||||
- `SBAS_TASK_PATH_MODE_EVALUATION_20260406.md`
|
||||
- `SBAS_SYSTEM_CHANGE_RISK_ASSESSMENT_20260406.md`
|
||||
- `SBAS_RESULT_MANAGEMENT_AND_DISPLAY_SPEC_20260406.md`
|
||||
- `SBAS_FRONTEND_UX_SPEC_20260406.md`
|
||||
- `SBAS_IMPLEMENTATION_TODO_20260406.md`
|
||||
|
||||
## 3. 本轮验证结果
|
||||
|
||||
### 3.1 已通过
|
||||
|
||||
- 前端 `npm run build` 已通过
|
||||
- WSL `Ubuntu-24.04` 下,`isce2` 环境对本轮修改后的后端文件执行 `py_compile` 通过
|
||||
- 启动日志已补充 `PSInSAR-Catalog` 状态输出
|
||||
|
||||
### 3.2 当前验证边界
|
||||
|
||||
本轮在 WSL `isce2` 环境做后端“导入级冒烟测试”时失败,失败原因不是本轮代码语法问题,而是该环境缺少系统后端依赖:
|
||||
|
||||
- `ModuleNotFoundError: No module named 'fastapi'`
|
||||
|
||||
这说明当前 `isce2` 环境可以作为 SBAS 处理链环境使用,也可以做后端源码级语法校验,但还不能直接作为系统后端完整运行环境。
|
||||
|
||||
## 4. 当前缺口
|
||||
|
||||
### 4.1 处理链缺口
|
||||
|
||||
系统尚未自动执行以下步骤:
|
||||
|
||||
- ISCE2 stack 执行
|
||||
- MintPy SBAS 执行
|
||||
- geocode / export / publish
|
||||
- 产物自动注册收口
|
||||
|
||||
### 4.2 环境缺口
|
||||
|
||||
若目标是“统一环境”,则还需要复制一份稳定的 ISCE2 环境并补齐系统依赖,形成一个既能跑:
|
||||
|
||||
- ISCE2 / MintPy
|
||||
- 又能支撑 FastAPI 后端依赖
|
||||
|
||||
的独立统一环境。当前不建议直接污染现有 D-InSAR 正在使用的生产环境。
|
||||
|
||||
## 5. 下一步建议
|
||||
|
||||
建议按以下顺序继续:
|
||||
|
||||
1. 保持当前 Phase 2 bridge 收口,不继续扩散系统侧改动,先把 `prepare -> stack_prep -> materialize -> refresh` 稳定住。
|
||||
2. 在实验层继续推进 `isce2_stack -> mintpy -> export_publish` 分步脚本与统一环境验证。
|
||||
3. 单独复制一份 WSL `isce2` 环境,做“统一环境”安装实验,不动现有 D-InSAR 生产环境。
|
||||
4. 统一环境验证稳定后,再把真正的 stack / MintPy / publish 接回系统作业编排。
|
||||
|
||||
## 6. 当前判断
|
||||
|
||||
当前路线是成立的。
|
||||
|
||||
成立点不在于“已经跑通全系统自动 SBAS”,而在于:
|
||||
|
||||
- 系统边界已经切对
|
||||
- D-InSAR 老链路基本保持隔离
|
||||
- SBAS 已有正式运行记录、结果目录和前端入口
|
||||
- 后续只需要继续往中间补处理链,而不是推倒重来
|
||||
@@ -0,0 +1,236 @@
|
||||
# SBAS 结果管理与展示规范
|
||||
|
||||
更新日期:2026-04-06
|
||||
|
||||
## 1. 管理目标
|
||||
|
||||
SBAS 结果进入系统后,必须满足三个层面的要求:
|
||||
|
||||
- 可登记
|
||||
- 可追溯
|
||||
- 可展示
|
||||
|
||||
当前推荐的管理边界不是 MintPy 运行目录,而是发布级 bundle。
|
||||
|
||||
唯一注册入口:
|
||||
|
||||
- `publish/.../manifest.json`
|
||||
|
||||
## 2. 结果层级
|
||||
|
||||
### 2.1 运行层
|
||||
|
||||
运行层记录在:
|
||||
|
||||
- `ps_timeseries_runs`
|
||||
|
||||
职责:
|
||||
|
||||
- 记录一次正式处理运行的业务身份
|
||||
- 记录输入、参数、DEM、轨道、掩膜、目录与状态
|
||||
|
||||
### 2.2 产品层
|
||||
|
||||
产品层继续复用:
|
||||
|
||||
- `result_products`
|
||||
- `result_assets`
|
||||
- `result_issues`
|
||||
|
||||
约定:
|
||||
|
||||
- `catalog_name = psinsar`
|
||||
- `product_type = psinsar_bundle`
|
||||
- `run_key = ps_timeseries_runs.run_id`
|
||||
|
||||
### 2.3 资产层
|
||||
|
||||
资产层由 `result_assets` 管理。
|
||||
|
||||
建议角色:
|
||||
|
||||
- `timeseries_cube`
|
||||
- `velocity_map`
|
||||
- `velocity_geotiff`
|
||||
- `temporal_coherence`
|
||||
- `temporal_coherence_geotiff`
|
||||
- `quality_mask`
|
||||
- `quality_mask_geotiff`
|
||||
- `preview_png`
|
||||
- `diagnostic_png`
|
||||
- `config`
|
||||
- `quality_summary`
|
||||
|
||||
## 3. 发布级 bundle 约束
|
||||
|
||||
标准目录:
|
||||
|
||||
```text
|
||||
<PSINSAR_PRODUCT_DIR>/<year>/<run_id>/
|
||||
manifest.json
|
||||
assets/
|
||||
preview/
|
||||
metadata/
|
||||
```
|
||||
|
||||
最低要求:
|
||||
|
||||
- `manifest.json`
|
||||
- `assets/geo_timeseries.h5`
|
||||
- `assets/velocity.tif`
|
||||
- `preview/velocity_preview.png`
|
||||
|
||||
建议同时保留:
|
||||
|
||||
- `assets/geo_velocity.h5`
|
||||
- `assets/temporalCoherence.tif`
|
||||
- `assets/maskTempCoh.tif`
|
||||
- `preview/numTriNonzeroIntAmbiguity.png`
|
||||
- `metadata/source_quality_summary.json`
|
||||
|
||||
## 4. 产品主文件定义
|
||||
|
||||
### 4.1 科学主产物
|
||||
|
||||
- `assets/geo_timeseries.h5`
|
||||
|
||||
这是系统证明“具备时序处理能力”的核心文件。
|
||||
|
||||
### 4.2 展示主产物
|
||||
|
||||
- `assets/velocity.tif`
|
||||
|
||||
这是结果首屏展示、地图浏览、预览生成的主文件。
|
||||
|
||||
### 4.3 质量主产物
|
||||
|
||||
- `assets/temporalCoherence.tif`
|
||||
- `assets/maskTempCoh.tif`
|
||||
|
||||
## 5. manifest 解析要求
|
||||
|
||||
系统应支持:
|
||||
|
||||
- `schema_version = psinsar.publish.v1`
|
||||
|
||||
系统应从 manifest 中提取:
|
||||
|
||||
- 基础身份
|
||||
- `catalog_name`
|
||||
- `mode`
|
||||
- `engine_code`
|
||||
- `processor_code`
|
||||
- 时序信息
|
||||
- `reference_date`
|
||||
- `stack_dates`
|
||||
- 资产信息
|
||||
- `artifacts[]`
|
||||
- 质量信息
|
||||
- `quality`
|
||||
- 辅助摘要
|
||||
- `summaries`
|
||||
|
||||
如 manifest 缺少显式 bbox,可从 `summaries.*.attrs` 中推导:
|
||||
|
||||
- `X_FIRST`
|
||||
- `Y_FIRST`
|
||||
- `X_STEP`
|
||||
- `Y_STEP`
|
||||
- `WIDTH`
|
||||
- `LENGTH`
|
||||
|
||||
## 6. 展示规范
|
||||
|
||||
## 6.1 列表页
|
||||
|
||||
优先展示:
|
||||
|
||||
- 产品名称
|
||||
- 运行标识
|
||||
- 参考日期
|
||||
- 影像数量
|
||||
- 发布时间
|
||||
- 缩略图
|
||||
|
||||
## 6.2 详情页
|
||||
|
||||
详情页应至少展示:
|
||||
|
||||
- 运行信息
|
||||
- 时间序列日期列表
|
||||
- 质量摘要
|
||||
- 资产清单
|
||||
- 问题清单
|
||||
|
||||
## 6.3 地图展示优先级
|
||||
|
||||
当前优先级:
|
||||
|
||||
1. `velocity.tif`
|
||||
2. `temporalCoherence.tif`
|
||||
3. `maskTempCoh.tif`
|
||||
|
||||
不建议当前阶段直接做:
|
||||
|
||||
- `geo_timeseries.h5` 全量地图服务化
|
||||
|
||||
## 7. 结果与运行的关联
|
||||
|
||||
必须能从结果反查运行。
|
||||
|
||||
推荐方式:
|
||||
|
||||
- `result_products.run_key = ps_timeseries_runs.run_id`
|
||||
|
||||
这样可以回答:
|
||||
|
||||
- 这个结果来自哪个 batch
|
||||
- 用了哪些日期
|
||||
- DEM 和轨道来自哪里
|
||||
- 使用了什么水体掩膜策略
|
||||
|
||||
## 8. 目录与数据库职责边界
|
||||
|
||||
目录是事实源:
|
||||
|
||||
- `manifest.json`
|
||||
- `assets/*`
|
||||
- `preview/*`
|
||||
|
||||
数据库是索引层:
|
||||
|
||||
- 产品列表
|
||||
- 检索字段
|
||||
- 资产索引
|
||||
- 问题索引
|
||||
|
||||
因此不应让数据库替代目录事实源,也不应让前端直接依赖实验运行目录。
|
||||
|
||||
## 9. Phase 1 / Phase 2 边界
|
||||
|
||||
### Phase 1
|
||||
|
||||
- 支持 bundle 扫描与登记
|
||||
- 支持产品列表和详情
|
||||
- 支持缩略图展示
|
||||
|
||||
### Phase 2
|
||||
|
||||
- 支持地图叠加 velocity
|
||||
- 支持 run 与 product 联动
|
||||
- 支持更多质量视图
|
||||
|
||||
### Phase 3
|
||||
|
||||
- 支持 `geo_timeseries.h5` 点位时序查询
|
||||
- 支持图表和专题分析
|
||||
|
||||
## 10. 当前结论
|
||||
|
||||
SBAS 结果管理的核心不是“把很多文件存起来”,而是把下面三件事稳定下来:
|
||||
|
||||
- 用 `manifest.json` 定义结果边界
|
||||
- 用 `result_products/result_assets` 登记 bundle
|
||||
- 用 `run_key` 把结果和运行记录连起来
|
||||
|
||||
这三件事一旦成立,系统就具备了承接 SBAS 成果的基础能力。
|
||||
@@ -0,0 +1,219 @@
|
||||
# SBAS 系统改造风险评估
|
||||
|
||||
更新日期:2026-04-06
|
||||
|
||||
## 1. 目标
|
||||
|
||||
本次改造的目标不是把实验脚本直接搬进系统,而是在尽量不影响现有 D-InSAR 生产链的前提下,为系统增加一条独立的 SBAS/PS-InSAR 生产与结果管理能力。
|
||||
|
||||
约束条件:
|
||||
|
||||
- 现有 D-InSAR 生产逻辑必须保持可用
|
||||
- 现有匹配逻辑先保持不动
|
||||
- SBAS 生产只基于原始影像,不再沿用 `*_envi_import`
|
||||
- 结果必须最终落到系统内可管理、可展示、可追踪的发布级 bundle
|
||||
- 统一环境实验优先,但不能污染当前 D-InSAR 使用的 `isce2` 生产环境
|
||||
|
||||
## 2. 风险分级总览
|
||||
|
||||
### P0 高风险
|
||||
|
||||
- 误改现有 D-InSAR 生产入口、目录契约或作业类型,导致原有生产失败
|
||||
- 把 SBAS 直接套进现有 `master/slave` 双景输入模型,导致设计方向错误
|
||||
- 结果编目直接改写现有 `result_catalog_service.py` 的 D-InSAR 语义,造成历史产品异常
|
||||
- 在当前生产 `isce2` 环境内直接安装新依赖,破坏现有运行稳定性
|
||||
|
||||
### P1 中风险
|
||||
|
||||
- SBAS 运行记录、任务记录、结果记录之间关系不清,后期无法追溯
|
||||
- Windows/WSL 双路径继续散落在多个服务中,后续维护成本继续升高
|
||||
- 前端直接绑定运行时目录结构,导致实验目录变化后页面失效
|
||||
- 结果展示只展示 `velocity.tif`,忽略 `geo_timeseries.h5`,造成“有图无时序能力”的误判
|
||||
|
||||
### P2 低风险
|
||||
|
||||
- 字段命名不统一,后续扩展时需要补充适配
|
||||
- 初期前端只做结果浏览,不做像元级时序查询
|
||||
- 先不接入健康检查总览,短期不会阻断主流程
|
||||
|
||||
## 3. 风险清单
|
||||
|
||||
### 3.1 生产链串扰风险
|
||||
|
||||
风险:
|
||||
|
||||
- 新增 SBAS 能力时误复用或改写 D-InSAR 路由、作业类型、拷贝逻辑、结果目录逻辑
|
||||
|
||||
触发点:
|
||||
|
||||
- 修改 `backend/app/routers/dinsar_production.py`
|
||||
- 修改 `backend/app/copier.py` 中现有 D-InSAR 行为
|
||||
- 在 `result_catalog_service.py` 中直接硬改通用逻辑
|
||||
|
||||
影响:
|
||||
|
||||
- D-InSAR 生产失败
|
||||
- 历史产物目录重建异常
|
||||
|
||||
控制策略:
|
||||
|
||||
- Phase 1 新增独立入口:
|
||||
- `timeseries_production.py`
|
||||
- `ps_products.py`
|
||||
- `psinsar_catalog_service.py`
|
||||
- 不修改 D-InSAR 的路由路径和任务类型
|
||||
- 不复用 `copy-ps-stack` 作为 SBAS 生产输入准备
|
||||
|
||||
### 3.2 输入契约错误风险
|
||||
|
||||
风险:
|
||||
|
||||
- 继续沿用 D-InSAR 的 `Task_*/master + slave` 输入目录契约
|
||||
|
||||
影响:
|
||||
|
||||
- SBAS 处理逻辑被错误建模为“双景处理”
|
||||
- 后续 prepare/materialize/stack workflow 无法自然落地
|
||||
|
||||
控制策略:
|
||||
|
||||
- 明确采用 `Stack_<group_key>` / `stack_input_manifest.json` 契约
|
||||
- 生产入口接收 `batch_id`,由系统生成 stack 级 manifest
|
||||
- 匹配层继续保留,生产层单独增加 prepare
|
||||
|
||||
### 3.3 环境污染风险
|
||||
|
||||
风险:
|
||||
|
||||
- 在当前 D-InSAR 使用的 `isce2` 运行环境内直接安装 MintPy 或其他依赖
|
||||
|
||||
影响:
|
||||
|
||||
- 现有 D-InSAR 生产不可复现
|
||||
- 环境漂移,难以排查
|
||||
|
||||
控制策略:
|
||||
|
||||
- 当前系统 Phase 1 仅记录并使用 `TIMESERIES_*` 独立配置
|
||||
- 当前实验优先对接已经验证过的统一环境或桥接环境
|
||||
- 保留现有 D-InSAR `isce2` 环境不动
|
||||
|
||||
### 3.4 数据身份与结果归档风险
|
||||
|
||||
风险:
|
||||
|
||||
- 只有批次,没有正式“运行记录”
|
||||
- 只有实验目录,没有系统级产品登记
|
||||
|
||||
影响:
|
||||
|
||||
- 无法回答“某次 SBAS 运行用的 DEM、轨道、参考日期、掩膜策略是什么”
|
||||
- 无法稳定展示和管理结果
|
||||
|
||||
控制策略:
|
||||
|
||||
- 新增 `ps_timeseries_runs`
|
||||
- 结果仍复用 `result_products` / `result_assets` / `result_issues`
|
||||
- `run_key` 绑定 `ps_timeseries_runs.run_id`
|
||||
- 发布边界固定为 `manifest.json`
|
||||
|
||||
### 3.5 前端误导风险
|
||||
|
||||
风险:
|
||||
|
||||
- 仅提供一个“PS 生产占位页”,但用户无法区分:
|
||||
- 规划批次
|
||||
- 正式生产运行
|
||||
- 结果目录
|
||||
- 成果展示
|
||||
|
||||
影响:
|
||||
|
||||
- 操作路径混乱
|
||||
- 误以为已有生产能力
|
||||
|
||||
控制策略:
|
||||
|
||||
- 生产页和结果页分离
|
||||
- 生产页展示:
|
||||
- 可选批次
|
||||
- 运行参数
|
||||
- 最近运行
|
||||
- 当前准备状态
|
||||
- 结果页展示:
|
||||
- 编目状态
|
||||
- 产品列表
|
||||
- 产品详情
|
||||
- 资产列表
|
||||
- 质量摘要
|
||||
|
||||
## 4. 本次推荐改造范围
|
||||
|
||||
## 4.1 必做
|
||||
|
||||
- 新增 `ps_timeseries_runs` 业务表
|
||||
- 新增 `timeseries_production` 路由
|
||||
- 新增 SBAS prepare 任务
|
||||
- 新增 `psinsar_catalog_service`
|
||||
- 新增 `ps_products` 路由
|
||||
- 新增前端 `TimeseriesProductionPanel`
|
||||
- 新增前端 `PsinsarCatalogPanel`
|
||||
|
||||
## 4.2 暂缓
|
||||
|
||||
- 不改现有 `find-ps-timeseries` 匹配算法
|
||||
- 不改现有 D-InSAR 生产入口
|
||||
- 不把 SBAS 直接接进 `copy-ps-stack`
|
||||
- 不做像元级 `geo_timeseries.h5` 在线查询
|
||||
- 不做地图服务化切片发布
|
||||
|
||||
## 5. 回滚策略
|
||||
|
||||
回滚必须满足“删新不伤旧”。
|
||||
|
||||
可回滚对象:
|
||||
|
||||
- 新增路由
|
||||
- 新增 ORM 表
|
||||
- 新增前端面板
|
||||
- 新增 `psinsar` 编目服务
|
||||
|
||||
不应触碰回滚的对象:
|
||||
|
||||
- 现有 D-InSAR 路由
|
||||
- 现有 `system_jobs` / `system_tasks` 表结构语义
|
||||
- 现有 D-InSAR 结果目录
|
||||
|
||||
推荐回滚方式:
|
||||
|
||||
1. 先停用前端入口
|
||||
2. 再停用新路由注册
|
||||
3. 保留数据库表,不做破坏性删除
|
||||
4. 保留已发布 `psinsar` bundle,必要时仅停止 catalog rebuild
|
||||
|
||||
## 6. 验收标准
|
||||
|
||||
### 6.1 低风险验收
|
||||
|
||||
- D-InSAR 现有页面正常打开
|
||||
- D-InSAR 现有生产入口不报错
|
||||
- D-InSAR 现有结果目录查询不受影响
|
||||
|
||||
### 6.2 SBAS Phase 1 验收
|
||||
|
||||
- 可以从已有 `ps_task_batch` 创建一个正式 `ps_timeseries_run`
|
||||
- 系统能为该 run 生成 stack 级 manifest
|
||||
- 系统能记录 work/publish 目录、参考日期、轨道统计和输入快照
|
||||
- 系统可以扫描 `psinsar.publish.v1` bundle 并登记到结果目录
|
||||
- 前端能查看运行记录与产品详情
|
||||
|
||||
## 7. 当前结论
|
||||
|
||||
本次改造最重要的不是“尽快把 SBAS 跑起来”,而是先把系统边界做对:
|
||||
|
||||
- 规划层不动
|
||||
- 生产层新增
|
||||
- 结果层隔离接入
|
||||
- D-InSAR 旧链路不碰
|
||||
|
||||
按这个边界推进,风险可控,且后续可以逐步把实验能力提升为正式生产能力。
|
||||
@@ -0,0 +1,680 @@
|
||||
# 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 生产
|
||||
|
||||
这样可以做到:
|
||||
|
||||
- 技术上最贴合现有系统
|
||||
- 风险上最小
|
||||
- 后续也最容易把实验链稳稳升级成正式生产链
|
||||
@@ -0,0 +1,359 @@
|
||||
# SBAS 系统集成与数据管理审计报告
|
||||
|
||||
更新日期:2026-04-06
|
||||
|
||||
## 1. 审计范围
|
||||
|
||||
本次审计聚焦三件事:
|
||||
|
||||
- 当前 ISCE2 SBAS 实验是否已经真实读取并使用精密轨道
|
||||
- 现有系统的数据管理方案是否适合承接 SBAS/PS-InSAR 生产口
|
||||
- 如果后续要把实验方案嵌入系统,推荐怎样分阶段落地
|
||||
|
||||
本报告基于当前仓库实现与已成功的实验产物,不涉及对现有 D-InSAR 生产链的破坏性修改。
|
||||
|
||||
## 2. 结论摘要
|
||||
|
||||
- 结论 1:当前 SBAS 实验已经真实读取并使用精密轨道,不只是“数据库里有轨道路径”。
|
||||
- 结论 2:当前系统可以完成 PS/SBAS 选片和实验产物生成,但还不能把 `psinsar` 产物作为正式生产结果注册、编目、健康检查和发布。
|
||||
- 结论 3:当前数据管理整体偏“路径驱动”,原始数据身份、存储位置、运行产物三层边界不够清晰,因此用户会感到“数据管理比较松散”。
|
||||
- 结论 4:轨道管理反而是当前较完整的一块,已经具备源目录扫描、池同步、一致性检查和数据库状态统计能力。
|
||||
|
||||
## 3. 审计发现
|
||||
|
||||
### P0 / 高优先级
|
||||
|
||||
#### 3.1 结果编目和发布入口仍然是 D-InSAR 专用,`psinsar` 实验产物无法直接接入系统
|
||||
|
||||
证据:
|
||||
|
||||
- `backend/app/services/result_catalog_service.py:707-713`
|
||||
- `_load_manifest()` 只接受 `product_type == dinsar`
|
||||
- `backend/app/services/result_catalog_service.py:750-753`
|
||||
- 即使读入 manifest,也把 `product_type` 固定写成 `dinsar`
|
||||
- `backend/app/routers/dinsar_products.py:107-140`
|
||||
- 现有编目 API 和后台任务只暴露 `/dinsar-products/*`
|
||||
- `backend/app/services/health_service.py:124-170`
|
||||
- 结果目录健康检查只统计 `catalog_name == dinsar`
|
||||
- `experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/publish/mintpy_sbas_unified_v1/manifest.json:2-9`
|
||||
- 当前实验成功产物的 manifest 是 `schema_version = psinsar.publish.v1`,`catalog_name = psinsar`
|
||||
|
||||
影响:
|
||||
|
||||
- 实验已经能产出发布级 bundle,但系统当前不会把它识别为正式产品
|
||||
- 不能复用现有结果页、目录重建、健康检查、产品详情接口
|
||||
- 后续如果直接“硬塞”进 D-InSAR 目录,会污染现有 D-InSAR 语义
|
||||
|
||||
建议:
|
||||
|
||||
- Phase 1 不要新建一套完全独立的产品表,继续复用 `result_products` / `result_assets`
|
||||
- 但必须让 catalog 服务显式支持 `catalog_name = psinsar`
|
||||
- 最小可行改造是新增 `psinsar` manifest 解析路径,或把当前 catalog service 抽象成多 catalog 分发器
|
||||
|
||||
#### 3.2 `ps_task_batches` / `ps_task_items` 目前只是选片快照,不是生产记录
|
||||
|
||||
证据:
|
||||
|
||||
- `backend/app/models/orm.py:516-550`
|
||||
- `PsTaskBatchORM` / `PsTaskItemORM` 只保存批次、`file_path`、日期、极化、是否有轨道和状态
|
||||
- `backend/app/routers/task_batches.py:281-320`
|
||||
- 创建 `/task-batches/ps` 时只是把选中的影像元数据写入 `ps_task_items`
|
||||
- `backend/app/routers/pairing.py:124-147`
|
||||
- 现有 `find-ps-timeseries` 只负责找 stack
|
||||
- `backend/app/services/spatial_service.py:444-481`
|
||||
- `find_ps_timeseries_data()` 只返回按轨道方向分组的影像栈
|
||||
- `backend/app/services/job_handlers.py:306-321`
|
||||
- 对 `PS_STACK` 的后台处理目前只是复制选中的影像路径
|
||||
|
||||
影响:
|
||||
|
||||
- 系统里没有“某次 SBAS 生产运行”的业务主记录
|
||||
- 无法稳定记录 `work_dir`、`publish_dir`、运行环境、参数版本、DEM、轨道来源、水体掩膜来源
|
||||
- 无法形成真正可追溯、可重跑、可审计的生产口
|
||||
|
||||
建议:
|
||||
|
||||
- 新增业务表 `ps_timeseries_runs`
|
||||
- 保留 `ps_task_batches` 作为“输入栈定义”
|
||||
- 把真正的处理运行、产物发布、失败重试、步骤状态全部挂到 `ps_timeseries_runs + workflow_runs`
|
||||
|
||||
#### 3.3 数据身份与存储路径耦合过深,迁移和重构成本偏高
|
||||
|
||||
证据:
|
||||
|
||||
- `backend/app/models/orm.py:22-40`
|
||||
- `RadarDataORM` 直接保存 `file_path`、`orbit_file_path`、`preview_cache_path`
|
||||
- `backend/app/models/orm.py:82-101`
|
||||
- `ResultProductORM` 直接保存 `publish_dir`、`manifest_path`、`source_primary_path`、`primary_asset_path`
|
||||
- `backend/app/models/orm.py:182-195`
|
||||
- `ResultAssetORM` 保存 `absolute_path`
|
||||
- `backend/app/services/data_service.py:621-668`
|
||||
- `unique_id` 通过 `os.path.relpath()` 生成,并按 `unique_id` 做 upsert
|
||||
|
||||
影响:
|
||||
|
||||
- 数据身份会受存储根目录变化影响
|
||||
- Windows 根目录变更、WSL 路径调整、NAS 迁移时,数据库主身份和存储位置语义混在一起
|
||||
- 产物迁移到正式发布目录后,历史绝对路径会变成系统耦合点
|
||||
|
||||
建议:
|
||||
|
||||
- 把“数据身份”和“存储位置”拆开
|
||||
- 原始影像层至少补充稳定的 `scene_uid` 或 `product_uid`
|
||||
- 结果层至少补充稳定的 `run_id` / `product_id` 业务主键,把绝对路径退化为可替换的存储定位信息
|
||||
|
||||
### P1 / 中优先级
|
||||
|
||||
#### 3.4 原始影像与轨道的关联粒度偏粗,缺少轨道版本与来源追踪
|
||||
|
||||
证据:
|
||||
|
||||
- `backend/app/services/data_service.py:611-612`
|
||||
- 影像是否有轨道仅按 `(satellite, imaging_date)` 关联
|
||||
- `backend/app/services/data_service.py:688-692`
|
||||
- 后续补关联时也是按同一键更新
|
||||
|
||||
影响:
|
||||
|
||||
- 当同一天存在多个候选轨道版本时,数据库层无法区分来源和版本
|
||||
- 无法在结果层明确回答“本次 SBAS 用的是哪份轨道文件、其 checksum 是多少、来自 source 目录还是 ISCE2 pool”
|
||||
|
||||
建议:
|
||||
|
||||
- 最小可行做法:在 `RadarDataORM` 或新表中增加
|
||||
- `orbit_stem`
|
||||
- `orbit_checksum`
|
||||
- `orbit_source_type`
|
||||
- `orbit_pool_path`
|
||||
- 更完整做法:单独建 `orbit_assets` / `orbit_bindings`
|
||||
|
||||
#### 3.5 数据扫描服务职责过重,扫描、轨道同步、预览缓存、数据库写入耦合在一起
|
||||
|
||||
证据:
|
||||
|
||||
- `backend/app/services/data_service.py:426-463`
|
||||
- 扫描原始轨道并同步 ENVI / ISCE2 池
|
||||
- `backend/app/services/data_service.py:568-699`
|
||||
- 同一流程里完成影像元数据读取、轨道关联、数据库 upsert
|
||||
- `backend/app/services/data_service.py:709-739`
|
||||
- 后面又继续做缓存重建候选收集
|
||||
|
||||
影响:
|
||||
|
||||
- 这个服务变成“总装配间”,测试和回归都更困难
|
||||
- 后续要引入 SBAS 生产口时,很容易继续把更多责任塞进同一个服务
|
||||
|
||||
建议:
|
||||
|
||||
- 拆分为至少四块:
|
||||
- `radar_inventory_service`
|
||||
- `orbit_inventory_service`
|
||||
- `radar_catalog_service`
|
||||
- `preview_cache_service`
|
||||
|
||||
#### 3.6 Windows/WSL 双路径模型是当前现实,但需要收口到专门的路径层
|
||||
|
||||
证据:
|
||||
|
||||
- `backend/app/config.py:150-186`
|
||||
- 同时维护 Windows 轨道池、DEM、IDL、WSL distro、WSL Python 等配置
|
||||
- `experiments/isce2_sbas_timeseries/scripts/build_lt1_stack_prep.py:140-149`
|
||||
- 实验准备阶段会解析 orbit XML
|
||||
- `experiments/isce2_sbas_timeseries/scripts/build_lt1_stack_prep.py:171-193`
|
||||
- 同时生成 Windows 路径和 WSL 路径
|
||||
- `experiments/isce2_sbas_timeseries/scripts/materialize_lt1_stack_scenes.py:98-103`
|
||||
- 物化阶段直接把 orbit XML 传给 ISCE2 sensor
|
||||
|
||||
影响:
|
||||
|
||||
- 当前方案能跑通,但如果没有统一的路径转换层,后续每个服务都可能自己拼接 `/mnt/*`
|
||||
- 这会继续加重“数据管理松散”的体感
|
||||
|
||||
建议:
|
||||
|
||||
- 保留当前双路径现实,不要硬回避
|
||||
- 但把路径转换统一收敛到 `timeseries_paths.py` 或类似组件
|
||||
- 生产口只暴露业务字段,不让上层 UI 和业务逻辑直接感知 `/mnt/z` 与 `F:\`
|
||||
|
||||
### P2 / 正向发现
|
||||
|
||||
#### 3.7 轨道管理是当前系统里相对成熟的一块
|
||||
|
||||
证据:
|
||||
|
||||
- `backend/app/services/data_service.py:426-463`
|
||||
- 已有源目录扫描与 ENVI / ISCE2 轨道池同步
|
||||
- `backend/app/routers/orbit.py:27-108`
|
||||
- 已有数据库统计、池一致性检查、缺口汇总
|
||||
|
||||
结论:
|
||||
|
||||
- 不需要为 SBAS 重新发明一套轨道管理
|
||||
- 更合理的方向是复用现有轨道池和一致性检查能力,再补生产级 provenance
|
||||
|
||||
## 4. 关于“现在实验读取精密轨道了吗”
|
||||
|
||||
答案:是,已经读取,而且已进入实际处理链。
|
||||
|
||||
证据链如下:
|
||||
|
||||
1. 轨道解析入口:
|
||||
- `backend/app/isce2_pipeline/lt1_input_resolver.py:165-201`
|
||||
- `ensure_lt1_orbit_xml()` 会优先取已有 XML,找不到才从 LT-1 轨道 txt 生成 XML
|
||||
2. Stack 准备阶段:
|
||||
- `experiments/isce2_sbas_timeseries/scripts/build_lt1_stack_prep.py:140-149`
|
||||
- 每景影像都调用 `ensure_lt1_orbit_xml()`
|
||||
3. Stack 物化阶段:
|
||||
- `experiments/isce2_sbas_timeseries/scripts/materialize_lt1_stack_scenes.py:98-103`
|
||||
- `sensor.orbitFile = orbit_xml`
|
||||
4. 实验 manifest 证据:
|
||||
- `experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/stack_input_manifest.json:92-95`
|
||||
- `experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/stack_input_manifest.json:123-126`
|
||||
- `experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/stack_input_manifest.json:154-157`
|
||||
- manifest 已明确记录 `D:\\orbit_pools\\isce2\\LT1A_GpsData_GAS_C_*.xml`
|
||||
5. 运行日志证据:
|
||||
- `experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/stack_work/logs/run_01_reference.log:18`
|
||||
- `experiments/isce2_sbas_timeseries/scratch/lt1a_strip1_hh_descending_e123p3_n46p1/stack_work/logs/run_03_geo2rdr_coarseResamp.log:6`
|
||||
- 日志中已出现 `Orbit interpolation method: hermite`
|
||||
|
||||
结论补充:
|
||||
|
||||
- 当前 SBAS 实验使用的是 ISCE2 轨道池中的 XML 精轨
|
||||
- 因此“精轨是否已读入”这件事在实验层已经成立
|
||||
- 真正缺的不是“有没有轨道”,而是“系统如何把这次运行及其轨道 provenance 规范地登记为生产记录”
|
||||
|
||||
## 5. 集成设计建议
|
||||
|
||||
### 5.1 集成边界
|
||||
|
||||
当前最合理的系统集成边界不是 MintPy 运行目录,而是发布级 bundle:
|
||||
|
||||
- 入口文件:`manifest.json`
|
||||
- 目录结构:`assets/`、`preview/`、`metadata/`
|
||||
|
||||
这与现有产品规范一致:
|
||||
|
||||
- `docs/ISCE2_SBAS_PRODUCT_SPEC.md:69-88`
|
||||
|
||||
因此:
|
||||
|
||||
- 不要直接注册 `stack_work/mintpy_sbas_*`
|
||||
- 要注册 `publish/.../manifest.json` 所代表的一整个 bundle
|
||||
|
||||
### 5.2 推荐最小落地架构
|
||||
|
||||
#### 层 1:规划层,继续复用现有能力
|
||||
|
||||
- 继续使用 `find-ps-timeseries`
|
||||
- 继续使用 `ps_task_batches` / `ps_task_items`
|
||||
- 其职责只保留为“选片与栈定义”
|
||||
|
||||
#### 层 2:生产层,新增业务主记录
|
||||
|
||||
新增 `ps_timeseries_runs`,至少包含:
|
||||
|
||||
- `run_id`
|
||||
- `batch_id`
|
||||
- `catalog_name`
|
||||
- `engine_code`
|
||||
- `processor_code`
|
||||
- `env_name`
|
||||
- `wsl_distro`
|
||||
- `work_dir`
|
||||
- `publish_dir`
|
||||
- `manifest_path`
|
||||
- `reference_date`
|
||||
- `direction`
|
||||
- `params_json`
|
||||
- `summary_json`
|
||||
- `orbit_summary_json`
|
||||
- `dem_path`
|
||||
- `water_mask_source`
|
||||
- `status`
|
||||
- `error_message`
|
||||
- `started_at`
|
||||
- `ended_at`
|
||||
|
||||
#### 层 3:编目层,扩展现有结果目录
|
||||
|
||||
不要单独再造一套产品表,继续复用:
|
||||
|
||||
- `result_products`
|
||||
- `result_assets`
|
||||
- `result_issues`
|
||||
|
||||
但要新增 `psinsar` catalog 入口,支持:
|
||||
|
||||
- 解析 `psinsar.publish.v1`
|
||||
- 注册 `catalog_name = psinsar`
|
||||
- 单独的 catalog status / rebuild / health-check
|
||||
|
||||
#### 层 4:接口层
|
||||
|
||||
建议新增:
|
||||
|
||||
- `POST /timeseries-production/runs`
|
||||
- `GET /timeseries-production/runs`
|
||||
- `GET /timeseries-production/runs/{run_id}`
|
||||
- `POST /timeseries-production/runs/{run_id}/retry-step`
|
||||
- `GET /ps-products`
|
||||
- `GET /ps-products/{product_id}`
|
||||
- `POST /ps-products/rebuild-catalog`
|
||||
|
||||
### 5.3 与当前设计文档的一致性
|
||||
|
||||
当前仓库里的 SBAS 设计文档已经提前写出了这条路线:
|
||||
|
||||
- `docs/ISCE2_SBAS_TIMESERIES_DESIGN.md:227`
|
||||
- 建议新增 `ps_timeseries_runs`
|
||||
- `docs/ISCE2_SBAS_TIMESERIES_DESIGN.md:292-296`
|
||||
- 建议新增 SBAS 相关 job types
|
||||
- `docs/ISCE2_SBAS_TIMESERIES_DESIGN.md:306-313`
|
||||
- 建议新增 `timeseries_production` / `ps_products` / `psinsar_catalog_service`
|
||||
- `docs/ISCE2_SBAS_TIMESERIES_DESIGN.md:563-575`
|
||||
- TODO 中已明确列出 ORM、路由、job handler、catalog 扩展和健康检查
|
||||
|
||||
所以本次审计的判断不是与现有设计冲突,而是说明:
|
||||
|
||||
- 实验层已经坐实
|
||||
- 代码现实也证明下一步确实该进入“生产层与 catalog 层补齐”
|
||||
|
||||
## 6. 建议 TODO
|
||||
|
||||
### 6.1 立即做
|
||||
|
||||
- [ ] 新增 `ps_timeseries_runs` ORM / schema / migration
|
||||
- [ ] 新增 `timeseries_production` router
|
||||
- [ ] 新增 `PUBLISH_PSINSAR_PRODUCTS` 及相关 job handlers
|
||||
- [ ] 让 catalog 服务支持 `psinsar.publish.v1`
|
||||
- [ ] 把 `publish/.../manifest.json` 作为唯一注册入口
|
||||
|
||||
### 6.2 紧接着做
|
||||
|
||||
- [ ] 给 `ps_timeseries_runs` 记录 DEM、轨道、水体掩膜、运行环境版本
|
||||
- [ ] 给轨道绑定补 provenance 字段或单独轨道资产表
|
||||
- [ ] 把 Windows/WSL 路径转换收敛到独立路径服务
|
||||
- [ ] 为 `psinsar` 增加 catalog health-check 与 rebuild
|
||||
|
||||
### 6.3 暂缓做
|
||||
|
||||
- [ ] 不要现在就改动现有 D-InSAR 生产链
|
||||
- [ ] 不要把 SBAS 运行目录直接暴露为产品目录
|
||||
- [ ] 不要为了 SBAS 先拆掉现有 `result_products`
|
||||
|
||||
## 7. 审计结论
|
||||
|
||||
如果现在问“SBAS 能不能开始往系统里接”,答案是:
|
||||
|
||||
- 能,但应该先接“发布 bundle + 生产记录 + psinsar catalog”
|
||||
- 不能直接把实验目录粗暴塞进现有 D-InSAR 产品体系
|
||||
|
||||
如果现在问“系统的数据管理为什么显得松散”,核心原因是:
|
||||
|
||||
- 原始数据身份、物理存储路径、生产产物目录三层目前还没有彻底分开
|
||||
|
||||
如果现在问“下一步最值得做什么”,答案是:
|
||||
|
||||
- 先把 `ps_timeseries_runs + psinsar catalog` 这两个缺口补上
|
||||
|
||||
这样既不会动坏现有 D-InSAR 生产,又能把已经验证成功的 SBAS 实验稳稳接成系统能力。
|
||||
@@ -0,0 +1,319 @@
|
||||
# SBAS 是否可复用现有 D-InSAR Task 路径生产模式
|
||||
|
||||
更新日期:2026-04-06
|
||||
|
||||
## 1. 结论
|
||||
|
||||
结论分两层:
|
||||
|
||||
- 可以复用“以标准输入目录作为生产入口”的模式
|
||||
- 不能直接复用现有 D-InSAR 的 `Task_x/master + slave` 目录协议和 `copy-ps-stack` 实现
|
||||
|
||||
也就是说:
|
||||
|
||||
- 可以借用 D-InSAR 的生产思想
|
||||
- 不能照搬 D-InSAR 的输入结构
|
||||
|
||||
## 2. 现有 D-InSAR 生产模式是什么
|
||||
|
||||
当前 D-InSAR 的 ISCE2 生产模式,本质上是:
|
||||
|
||||
1. 先把一对影像整理成标准任务目录
|
||||
2. 每个任务目录固定包含:
|
||||
- `master/`
|
||||
- `slave/`
|
||||
- `.dinsar_pair.json`
|
||||
3. 生产入口只接收一个 `root_dir`
|
||||
4. 引擎自行扫描这个 `root_dir`
|
||||
- 要么它本身就是一个 task 目录
|
||||
- 要么它下面有多个 `Task_*` 子目录
|
||||
5. 每个 task 目录独立产出一个 pair result
|
||||
|
||||
关键实现:
|
||||
|
||||
- `backend/app/dinsar_engines/isce2_engine.py:314-361`
|
||||
- `validate_root_dir()` 要求:
|
||||
- 单个 task 目录必须有 `master` 和 `slave`
|
||||
- 或父目录下有多个合法 `Task_*`
|
||||
- `backend/app/copier.py:178-218`
|
||||
- D-InSAR 复制时会构建:
|
||||
- `<dest>/<task_alias>/master`
|
||||
- `<dest>/<task_alias>/slave`
|
||||
- `.dinsar_pair.json`
|
||||
- `backend/app/isce2_pipeline/run_lt1_dinsar_pipeline.py:262-298`
|
||||
- pipeline 运行时明确按 `master` / `slave` 两景读取
|
||||
|
||||
所以这是一套“面向影像对”的输入协议。
|
||||
|
||||
## 3. 现有 PS/SBAS 选片算法能不能找出时序队列
|
||||
|
||||
可以,但当前更准确地说,它是:
|
||||
|
||||
- 一个“候选栈发现器”
|
||||
- 还不是一个“生产级栈定义器”
|
||||
|
||||
现有实现:
|
||||
|
||||
- `backend/app/services/spatial_service.py:414-481`
|
||||
|
||||
当前逻辑会:
|
||||
|
||||
- 先选出与 AOI 初始重叠比例满足阈值的影像
|
||||
- 按轨道方向分组
|
||||
- 求每个方向的公共重叠区
|
||||
- 再筛出对公共区覆盖比例满足阈值的影像
|
||||
- 最终按日期排序返回
|
||||
|
||||
这对 SBAS 是有价值的,因为它已经能给出:
|
||||
|
||||
- 同轨方向
|
||||
- 共享公共覆盖区
|
||||
- 时间排序后的影像列表
|
||||
|
||||
但它当前还缺少若干生产级约束:
|
||||
|
||||
- 没有显式要求 `has_orbit_data = True`
|
||||
- 没有显式要求相同 `imaging_mode`
|
||||
- 没有显式要求相同 `polarization`
|
||||
- 没有最小栈规模规则
|
||||
- 没有最大时间间隔或参考影像策略
|
||||
- 没有把结果固化为“一个稳定的 stack identity”
|
||||
|
||||
所以答案是:
|
||||
|
||||
- 用来找 SBAS 候选时序队列,可以
|
||||
- 直接当生产入口,不够
|
||||
|
||||
## 4. 为什么 D-InSAR 的 task 路径模式不能原样套给 SBAS
|
||||
|
||||
### 4.1 D-InSAR 是二元输入,SBAS 是栈输入
|
||||
|
||||
D-InSAR 当前 pipeline 只解析两个角色:
|
||||
|
||||
- `master`
|
||||
- `slave`
|
||||
|
||||
见:
|
||||
|
||||
- `backend/app/isce2_pipeline/run_lt1_dinsar_pipeline.py:262-298`
|
||||
|
||||
而 SBAS 至少需要:
|
||||
|
||||
- 一个有序场景集合
|
||||
- 栈级别的公共参数
|
||||
- 栈级别的参考日期
|
||||
- 栈级别的输出目录约定
|
||||
|
||||
因此 SBAS 的输入目录协议必须是“stack contract”,不是“pair contract”。
|
||||
|
||||
### 4.2 当前 `copy-ps-stack` 是平铺复制,不会生成栈元数据
|
||||
|
||||
现有 PS 复制逻辑:
|
||||
|
||||
- `backend/app/copier.py:45-115`
|
||||
|
||||
它的行为是:
|
||||
|
||||
- 从 `PsTaskItemORM.file_path` 取路径
|
||||
- 优先复制 `original_path + "_envi_import"`
|
||||
- 否则复制原路径
|
||||
- 直接平铺复制到 `dest_dir/<basename>`
|
||||
|
||||
它不会生成:
|
||||
|
||||
- 栈 manifest
|
||||
- 日期排序
|
||||
- 参考日期
|
||||
- 轨道清单
|
||||
- DEM / water mask / publish 约定
|
||||
|
||||
因此这套复制结果目前更像“把选中的影像搬过去”,不是“形成一个可投产的 SBAS 输入包”。
|
||||
|
||||
### 4.3 当前 PS 批次模型保存的信息不够
|
||||
|
||||
现有:
|
||||
|
||||
- `backend/app/models/orm.py:532-550`
|
||||
- `backend/app/routers/task_batches.py:303-312`
|
||||
|
||||
`PsTaskItemORM` 只保存:
|
||||
|
||||
- `file_path`
|
||||
- `satellite`
|
||||
- `imaging_date`
|
||||
- `polarization`
|
||||
- `has_orbit_data`
|
||||
|
||||
没有保存:
|
||||
|
||||
- `orbit_direction`
|
||||
- `imaging_mode`
|
||||
- 稳定 `group_key`
|
||||
- 公共覆盖区
|
||||
- 参考影像策略
|
||||
|
||||
这说明 PS 批次目前还是“输入快照”,不是“可直接投产的 stack contract”。
|
||||
|
||||
## 5. 哪部分可以直接复用
|
||||
|
||||
可以直接复用的,不少。
|
||||
|
||||
### 5.1 生产入口模式
|
||||
|
||||
复用思路:
|
||||
|
||||
- 一个 `root_dir`
|
||||
- 引擎自己扫描这个目录
|
||||
- 支持“单个 stack 目录”或“父目录下多个 stack 目录”
|
||||
|
||||
这点可以直接仿照:
|
||||
|
||||
- `backend/app/dinsar_engines/isce2_engine.py:314-361`
|
||||
|
||||
只是把目录判定从:
|
||||
|
||||
- `master + slave`
|
||||
|
||||
换成:
|
||||
|
||||
- `stack_input_manifest.json` 或 `.ps_stack.json`
|
||||
|
||||
### 5.2 作业提交模式
|
||||
|
||||
可以直接复用 D-InSAR 当前的:
|
||||
|
||||
- router 提交任务
|
||||
- `task_service.create_task()`
|
||||
- `job_queue_service.create_job()`
|
||||
- worker 执行
|
||||
- 返回单次运行状态
|
||||
|
||||
### 5.3 目录驱动执行
|
||||
|
||||
这部分思想也可以复用:
|
||||
|
||||
- 输入目录是唯一入口
|
||||
- engine 不依赖前端临时状态
|
||||
- 只要目录契约稳定,就可以重复运行
|
||||
|
||||
这对 SBAS 是对的。
|
||||
|
||||
## 6. SBAS 推荐的“task 路径模式”
|
||||
|
||||
建议做一个 SBAS 版输入目录协议,而不是复用 D-InSAR 的 `Task_*` 结构。
|
||||
|
||||
推荐:
|
||||
|
||||
```text
|
||||
Stack_<group_key>/
|
||||
stack_input_manifest.json
|
||||
scenes/
|
||||
20250118/
|
||||
source_scene.json
|
||||
<raw scene or link>
|
||||
20250315/
|
||||
source_scene.json
|
||||
<raw scene or link>
|
||||
20250510/
|
||||
source_scene.json
|
||||
<raw scene or link>
|
||||
inputs/
|
||||
dem/
|
||||
logs/
|
||||
```
|
||||
|
||||
后续运行阶段再生成:
|
||||
|
||||
```text
|
||||
Stack_<group_key>/
|
||||
stack_input_manifest.json
|
||||
scenes/
|
||||
SLC/
|
||||
stack_work/
|
||||
publish/
|
||||
logs/
|
||||
```
|
||||
|
||||
## 7. 推荐的 `stack_input_manifest.json` 最小字段
|
||||
|
||||
至少应包含:
|
||||
|
||||
- `group_key`
|
||||
- `batch_id`
|
||||
- `mode`
|
||||
- `sbas`
|
||||
- `direction`
|
||||
- `reference_date`
|
||||
- `stack_dates`
|
||||
- `scene_count`
|
||||
- `dem_path_windows`
|
||||
- `dem_path_wsl`
|
||||
- `orbit_pool_windows`
|
||||
- `orbit_pool_wsl`
|
||||
- `publish_dir_windows`
|
||||
- `publish_dir_wsl`
|
||||
- `water_mask_mode`
|
||||
- `scenes[]`
|
||||
- `date`
|
||||
- `file_path`
|
||||
- `satellite`
|
||||
- `imaging_mode`
|
||||
- `polarization`
|
||||
- `orbit_direction`
|
||||
- `orbit_xml_path`
|
||||
- `has_orbit_data`
|
||||
|
||||
这个文件对 SBAS 的作用,等价于 D-InSAR 里的 `.dinsar_pair.json`,但它描述的是一个栈,不是一对。
|
||||
|
||||
## 8. 物理复制要不要照搬 D-InSAR
|
||||
|
||||
不建议原样照搬。
|
||||
|
||||
原因:
|
||||
|
||||
- SBAS 常常是 5 景、10 景甚至更多
|
||||
- 全量复制原始影像会放大 IO 和存储成本
|
||||
- 你当前原始数据已经在 WSL 可见路径下,不一定需要再复制一遍
|
||||
|
||||
更合理的 Phase 1 做法:
|
||||
|
||||
- 保留“输入目录”概念
|
||||
- 但目录里优先存:
|
||||
- manifest
|
||||
- sidecar metadata
|
||||
- 规范化链接或原路径引用
|
||||
- 仅在必要时物化最小运行所需文件
|
||||
|
||||
也就是说:
|
||||
|
||||
- 推荐“目录驱动”
|
||||
- 不推荐“全量复制驱动”
|
||||
|
||||
## 9. 最终判断
|
||||
|
||||
如果你的问题是:
|
||||
|
||||
- “现有匹配算法能不能找出 SBAS 需要的时序影像队列?”
|
||||
|
||||
答案是:
|
||||
|
||||
- 可以作为候选栈发现器
|
||||
- 但还需要补生产级校验和栈固化
|
||||
|
||||
如果你的问题是:
|
||||
|
||||
- “能不能沿用 D-InSAR 生产时的输入 task 路径模式?”
|
||||
|
||||
答案是:
|
||||
|
||||
- 可以沿用这个模式的思想
|
||||
- 不能沿用现有 D-InSAR 的具体目录协议和复制实现
|
||||
|
||||
最推荐的落地方式是:
|
||||
|
||||
1. 保留“目录作为生产入口”
|
||||
2. 为 SBAS 定义独立的 `Stack_*` 输入契约
|
||||
3. 用 `stack_input_manifest.json` 替代 `.dinsar_pair.json`
|
||||
4. 用 stack-aware 的 prepare/materialize 步骤替代当前 `copy-ps-stack` 平铺复制
|
||||
|
||||
这样既能继承现有系统的生产模式,又不会把 SBAS 错套成二景 D-InSAR。
|
||||
@@ -0,0 +1,393 @@
|
||||
# WSL2 + ISCE2 + MintPy SBAS 集成方案
|
||||
|
||||
Updated: 2026-04-12
|
||||
|
||||
## 1. 背景
|
||||
|
||||
当前仓库已经具备 SBAS/PS-InSAR 的部分系统骨架:
|
||||
|
||||
- 已有 `ps_timeseries_runs` 业务表与基础 API
|
||||
- 已有 `prepare -> stack_prep_initial -> materialize -> stack_prep_refresh` 四步 workflow
|
||||
- 已有 `psinsar.publish.v1` manifest 解析与 `psinsar` catalog
|
||||
- 已有 `ps_production`、`ps_products`、`psinsar_results` 前端入口
|
||||
|
||||
同时,实验层已经验证:
|
||||
|
||||
- LT-1 stack 可以在 WSL2 `Ubuntu-24.04` 下跑通到 `run_08_igram`
|
||||
- MintPy SBAS 可以产出 `timeseries.h5`、`velocity.h5`
|
||||
- geocode/export 可以产出 `psinsar.publish.v1` publish bundle
|
||||
- 统一环境 `isce2_mintpy_v1` 可以同时导入 `isce` 与 `mintpy`
|
||||
|
||||
因此当前最合理的工作不是重写处理算法,而是把已经验证过的 WSL2 运行链稳定接入现有系统。
|
||||
|
||||
## 2. 本机环境核对
|
||||
|
||||
本方案基于 2026-04-12 的本机实际核对结果。
|
||||
|
||||
### 2.1 WSL2 发行版
|
||||
|
||||
- 可见发行版:
|
||||
- `Ubuntu`
|
||||
- `Ubuntu-24.04`
|
||||
- SBAS 集成目标发行版:
|
||||
- `Ubuntu-24.04`
|
||||
|
||||
### 2.2 已确认 conda 环境
|
||||
|
||||
- `isce2`
|
||||
- Python:
|
||||
- `/home/administrator/miniconda3/envs/isce2/bin/python`
|
||||
- 可导入:
|
||||
- `isce`
|
||||
- `mintpy`
|
||||
- Python:
|
||||
- `/home/administrator/miniconda3/envs/mintpy/bin/python`
|
||||
- 可导入:
|
||||
- `mintpy`
|
||||
- `isce2_mintpy_v1`
|
||||
- Python:
|
||||
- `/home/administrator/miniconda3/envs/isce2_mintpy_v1/bin/python`
|
||||
- 可导入:
|
||||
- `isce`
|
||||
- `mintpy`
|
||||
|
||||
### 2.3 当前判断
|
||||
|
||||
- `isce2_mintpy_v1` 已满足“单环境跑 stack + MintPy”的基础条件
|
||||
- 现有 `isce2` 环境仍应保留给当前 D-InSAR 生产链
|
||||
- 运行时不应依赖交互式 `sudo`
|
||||
- 所有系统依赖、conda 环境、脚本权限应在部署阶段一次性准备完成
|
||||
|
||||
## 3. 设计结论
|
||||
|
||||
### 3.1 主方案
|
||||
|
||||
SBAS 系统集成默认采用:
|
||||
|
||||
- WSL distro:
|
||||
- `Ubuntu-24.04`
|
||||
- runtime env:
|
||||
- `isce2_mintpy_v1`
|
||||
|
||||
### 3.2 备用方案
|
||||
|
||||
保留实验期的双环境桥接链路作为 fallback:
|
||||
|
||||
- `isce2`
|
||||
- 负责 ISCE2 stack
|
||||
- `mintpy`
|
||||
- 负责 MintPy SBAS
|
||||
|
||||
但 fallback 不应作为系统默认路径,只在统一环境故障时使用。
|
||||
|
||||
### 3.3 产品边界
|
||||
|
||||
系统正式接入边界固定为 publish bundle:
|
||||
|
||||
- `manifest.json`
|
||||
- `assets/`
|
||||
- `preview/`
|
||||
- `metadata/`
|
||||
|
||||
系统不直接把以下目录视为正式产品:
|
||||
|
||||
- `stack_work/`
|
||||
- `mintpy_sbas_*`
|
||||
- `Igrams/`
|
||||
- 其他中间目录
|
||||
|
||||
## 4. 现状与缺口
|
||||
|
||||
### 4.1 已完成
|
||||
|
||||
- 运行记录模型:
|
||||
- `ps_timeseries_runs`
|
||||
- 基础生产 API:
|
||||
- `timeseries-production`
|
||||
- 基础产品 API:
|
||||
- `ps-products`
|
||||
- `psinsar` catalog 解析与重建
|
||||
- 前端生产页、产品页、结果页入口
|
||||
|
||||
### 4.2 未完成
|
||||
|
||||
当前系统还没有把下面四步接入正式 workflow:
|
||||
|
||||
1. `run_isce2_stack`
|
||||
2. `run_mintpy_sbas`
|
||||
3. `export_publish_bundle`
|
||||
4. `register_psinsar_product`
|
||||
|
||||
这意味着当前系统是“桥接层已接入”,但还不是“完整自动生产闭环”。
|
||||
|
||||
## 5. 目标架构
|
||||
|
||||
```text
|
||||
Windows FastAPI / Worker
|
||||
-> submit run / record metadata / monitor progress
|
||||
-> dispatch WSL jobs
|
||||
-> register publish bundle into psinsar catalog
|
||||
-> serve API to frontend
|
||||
|
||||
WSL2 Ubuntu-24.04
|
||||
-> ISCE2 stripmapStack execution
|
||||
-> MintPy SBAS inversion
|
||||
-> geocode / export / preview generation
|
||||
-> build manifest.json
|
||||
|
||||
Formal Product Boundary
|
||||
-> PSINSAR_PRODUCT_DIR/<product_id>/
|
||||
manifest.json
|
||||
assets/
|
||||
preview/
|
||||
metadata/
|
||||
```
|
||||
|
||||
设计原则:
|
||||
|
||||
- 系统负责编排,不负责重计算
|
||||
- WSL2 负责执行,不负责业务登记
|
||||
- 正式产品只认 publish bundle
|
||||
- D-InSAR 与 SBAS 运行时保持隔离
|
||||
|
||||
## 6. 推荐 workflow
|
||||
|
||||
### 6.1 Phase 1 已有步骤
|
||||
|
||||
1. `prepare_stack_input`
|
||||
2. `build_stack_prep_initial`
|
||||
3. `materialize_stack_scenes`
|
||||
4. `refresh_stack_ready`
|
||||
|
||||
### 6.2 需要新增的正式步骤
|
||||
|
||||
5. `run_isce2_stack`
|
||||
- 在 `Ubuntu-24.04` 中执行生成的 `run_01` 至 `run_08_igram`
|
||||
- 产出 `Igrams/`、`geom_reference/`、`baselines/`
|
||||
|
||||
6. `run_mintpy_sbas`
|
||||
- 在 `isce2_mintpy_v1` 中执行 MintPy SBAS
|
||||
- 产出:
|
||||
- `timeseries.h5`
|
||||
- `velocity.h5`
|
||||
- `temporalCoherence.h5`
|
||||
- `maskTempCoh.h5`
|
||||
|
||||
7. `export_publish_bundle`
|
||||
- geocode
|
||||
- GeoTIFF 导出
|
||||
- 生成预览图
|
||||
- 生成 `manifest.json`
|
||||
|
||||
8. `register_psinsar_product`
|
||||
- 将 publish bundle 复制或落到正式 `PSINSAR_PRODUCT_DIR`
|
||||
- 增量登记到 `psinsar` catalog
|
||||
|
||||
## 7. 后端设计
|
||||
|
||||
### 7.1 配置项
|
||||
|
||||
建议显式配置以下参数,不再依赖默认继承:
|
||||
|
||||
```dotenv
|
||||
TIMESERIES_ENABLED=true
|
||||
TIMESERIES_WSL_DISTRO=Ubuntu-24.04
|
||||
TIMESERIES_ENV_NAME=isce2_mintpy_v1
|
||||
TIMESERIES_PYTHON=/home/administrator/miniconda3/envs/isce2_mintpy_v1/bin/python
|
||||
TIMESERIES_WORK_ROOT=<windows path>
|
||||
TIMESERIES_DEM_PATH=<windows path>
|
||||
TIMESERIES_ORBIT_POOL_ISCE2=<windows path>
|
||||
TIMESERIES_EXPERIMENT_ROOT=<repo>/experiments/isce2_sbas_timeseries
|
||||
TIMESERIES_STACK_PREP_SCRIPT=<repo>/experiments/isce2_sbas_timeseries/scripts/build_lt1_stack_prep.py
|
||||
TIMESERIES_MATERIALIZE_SCRIPT=<repo>/experiments/isce2_sbas_timeseries/scripts/materialize_lt1_stack_scenes.py
|
||||
PSINSAR_PRODUCT_DIR=<formal publish root>
|
||||
```
|
||||
|
||||
关键要求:
|
||||
|
||||
- `TIMESERIES_ENV_NAME` 与 `TIMESERIES_PYTHON` 必须指向同一环境
|
||||
- 不再让 `TIMESERIES_PYTHON` 默认继承 `ISCE2_PYTHON`
|
||||
|
||||
### 7.2 模块拆分
|
||||
|
||||
建议新增或补强以下模块:
|
||||
|
||||
- `timeseries_paths.py`
|
||||
- 统一维护 Windows/WSL 路径转换
|
||||
- 统一生成 work/publish/logs 路径
|
||||
|
||||
- `timeseries_runtime_service.py`
|
||||
- 统一执行 WSL 命令
|
||||
- 统一处理 timeout、stdout/stderr、返回码
|
||||
|
||||
- `isce2_stack_runtime_service.py`
|
||||
- 封装 `run_01` 至 `run_08_igram` 执行
|
||||
|
||||
- `mintpy_runtime_service.py`
|
||||
- 封装 MintPy SBAS 运行
|
||||
- 封装统一环境 runner
|
||||
|
||||
- `psinsar_publish_service.py`
|
||||
- 封装 export/publish bundle 生成
|
||||
- 封装产品落库前的目录检查
|
||||
|
||||
### 7.3 建议新增 job types
|
||||
|
||||
- `TIMESERIES_ISCE2_STACK_RUN`
|
||||
- `TIMESERIES_MINTPY_SBAS_RUN`
|
||||
- `TIMESERIES_EXPORT_PUBLISH`
|
||||
- `TIMESERIES_REGISTER_PRODUCT`
|
||||
|
||||
当前已有:
|
||||
|
||||
- `TIMESERIES_PREPARE`
|
||||
- `TIMESERIES_STACK_PREP`
|
||||
- `TIMESERIES_MATERIALIZE`
|
||||
|
||||
### 7.4 运行记录要求
|
||||
|
||||
`ps_timeseries_runs` 至少应稳定记录:
|
||||
|
||||
- `wsl_distro`
|
||||
- `env_name`
|
||||
- `python_path`
|
||||
- `work_root`
|
||||
- `publish_dir`
|
||||
- `manifest_path`
|
||||
- `reference_date`
|
||||
- `stack_dates`
|
||||
- `dem_path`
|
||||
- `orbit_pool`
|
||||
- `water_mask_mode`
|
||||
- `step logs`
|
||||
- `quality summary`
|
||||
- `command snapshots`
|
||||
|
||||
目标不是“只知道跑过”,而是“知道当时用什么环境、什么 DEM、什么 orbit、怎么跑出来的”。
|
||||
|
||||
## 8. 结果目录与 catalog 策略
|
||||
|
||||
### 8.1 正式产品目录
|
||||
|
||||
正式产品目录统一使用:
|
||||
|
||||
- `PSINSAR_PRODUCT_DIR`
|
||||
|
||||
实验目录:
|
||||
|
||||
- `experiments/.../publish/...`
|
||||
|
||||
只作为验证来源,不应继续充当正式产品根目录。
|
||||
|
||||
### 8.2 推荐策略
|
||||
|
||||
第一阶段先支持两种接入方式:
|
||||
|
||||
1. `import_experiment_bundle`
|
||||
- 将已有实验成功 bundle 导入正式产品目录
|
||||
- 用于快速验证 catalog 和前端显示
|
||||
|
||||
2. `publish_from_workflow`
|
||||
- 由 workflow 自动生成 bundle 并注册
|
||||
- 作为正式闭环目标
|
||||
|
||||
### 8.3 catalog 设计要求
|
||||
|
||||
`psinsar_catalog_service` 建议补充:
|
||||
|
||||
- 单 manifest 增量注册
|
||||
- 单产品刷新
|
||||
- publish 目录健康检查
|
||||
- run_id 到 product_id 的稳定关联
|
||||
|
||||
## 9. 前端设计
|
||||
|
||||
### 9.1 `ps_production`
|
||||
|
||||
第一阶段重点不是分析,而是运维可用:
|
||||
|
||||
- 显示 WSL/环境状态
|
||||
- 显示 workflow 步骤状态
|
||||
- 显示 stdout/stderr 日志位置
|
||||
- 失败后支持步骤级重试
|
||||
- 成功后跳转到产品详情
|
||||
|
||||
### 9.2 `ps_products`
|
||||
|
||||
第一阶段重点:
|
||||
|
||||
- list/filter
|
||||
- 查看 manifest
|
||||
- 查看 preview
|
||||
- 手动 rebuild catalog
|
||||
- 从 run 跳到 product
|
||||
|
||||
### 9.3 `psinsar_results`
|
||||
|
||||
第一阶段继续复用 catalog 只读视图即可。
|
||||
|
||||
### 9.4 `psinsar_analysis`
|
||||
|
||||
继续预留,不在当前阶段展开。
|
||||
|
||||
## 10. 稳定性约束
|
||||
|
||||
必须遵守以下边界:
|
||||
|
||||
- 不修改当前 D-InSAR 的默认 `ISCE2_PYTHON`
|
||||
- 不把当前 D-InSAR 脚本改指向 `isce2_mintpy_v1`
|
||||
- 不让业务层代码直接拼 `/mnt/z`
|
||||
- 不把 `MintPy` 工作目录直接暴露为正式产品
|
||||
- 不依赖交互式 `sudo`
|
||||
|
||||
## 11. 推荐实施顺序
|
||||
|
||||
### Phase A
|
||||
|
||||
先做“实验成果纳入系统”:
|
||||
|
||||
- 支持导入已有 experiment publish bundle
|
||||
- 落到正式 `PSINSAR_PRODUCT_DIR`
|
||||
- 让 catalog 和前端先可见
|
||||
|
||||
### Phase B
|
||||
|
||||
再做“完整 WSL2 自动执行闭环”:
|
||||
|
||||
- 接入 `run_isce2_stack`
|
||||
- 接入 `run_mintpy_sbas`
|
||||
- 接入 `export_publish_bundle`
|
||||
- 接入 `register_psinsar_product`
|
||||
|
||||
### Phase C
|
||||
|
||||
最后做“生产级稳定化”:
|
||||
|
||||
- 失败重试
|
||||
- 恢复执行
|
||||
- 健康检查
|
||||
- 环境快照
|
||||
- provenance 补齐
|
||||
|
||||
## 12. 验收标准
|
||||
|
||||
达到以下条件后,才算 SBAS 正式接入完成:
|
||||
|
||||
1. 系统可从一个已有 `PS stack batch` 发起 SBAS 运行。
|
||||
2. Worker 可在 `Ubuntu-24.04` 中自动驱动 ISCE2 stack。
|
||||
3. Worker 可在 `isce2_mintpy_v1` 中自动驱动 MintPy。
|
||||
4. 系统可自动生成 publish bundle。
|
||||
5. bundle 可自动注册到 `psinsar` catalog。
|
||||
6. 前端可查看运行状态、产品列表、preview 和 manifest。
|
||||
7. 失败步骤可重试,且不会污染现有 D-InSAR 生产链。
|
||||
|
||||
## 13. 当前推荐
|
||||
|
||||
当前最稳的方向是:
|
||||
|
||||
- 继续以 `isce2_mintpy_v1` 作为 SBAS 主运行时
|
||||
- 保留 `isce2` 与 `mintpy` 双环境桥接链路作为 fallback
|
||||
- 先把 experiment publish bundle 纳入正式系统
|
||||
- 再补自动执行后四步
|
||||
|
||||
这条路线最符合当前仓库状态,也最符合“稳定优先、不破坏现有 D-InSAR”的约束。
|
||||
@@ -0,0 +1,403 @@
|
||||
# InSAR 管理系统项目汇报
|
||||
|
||||
版本日期:2026-03-13
|
||||
|
||||
## 一、汇报目的
|
||||
|
||||
本文用于项目汇报和方案评审,重点说明三件事:
|
||||
|
||||
1. 当前 InSAR 管理系统的建设内容和系统价值。
|
||||
2. 系统在 D-InSAR 生产侧已经形成的技术架构与扩展能力。
|
||||
3. 如何将 LANDSAR 系统作为第三个 D-InSAR 生产核心嵌入本系统,以及这件事对采购方案的直接影响。
|
||||
|
||||
本文是单独汇报材料,强调整体把握、系统边界、实施路径和采购判断,不展开到底层代码细节。
|
||||
|
||||
## 二、项目总体定位
|
||||
|
||||
本项目不是单一的数据展示平台,而是一个面向 InSAR 业务的综合管理与生产支撑平台,核心目标是把“数据入库、生产组织、结果管理、运行监控、质量分析”放到同一套系统中统一管理。
|
||||
|
||||
从业务定位看,系统承担了以下角色:
|
||||
|
||||
1. 数据管理平台:统一管理雷达源数据、轨道数据、D-InSAR 结果、水体监测结果等。
|
||||
2. 生产组织平台:支持配对、批次管理、任务下发、后台处理、结果回收。
|
||||
3. 运维监控平台:支持健康检查、任务状态、日志、鉴权、许可证控制。
|
||||
4. 分析辅助平台:支持 AI 质量分析、AI 诊断、统计看板、地图可视化。
|
||||
|
||||
因此,这个项目的价值不只是“能不能跑一次处理”,而是把整个业务流程固化为可持续运行的平台能力。
|
||||
|
||||
## 三、当前系统建设情况
|
||||
|
||||
### 3.1 技术架构
|
||||
|
||||
当前系统采用前后端分离架构:
|
||||
|
||||
1. 前端:React + Vite,使用 Leaflet 负责地图展示,Chart.js 负责统计图表,Zustand 负责状态管理。
|
||||
2. 后端:FastAPI 提供 REST API,SQLAlchemy 负责 ORM,Pydantic 负责数据模型校验。
|
||||
3. 数据库:PostgreSQL + PostGIS,用于业务数据存储和空间能力支撑。
|
||||
4. 后台任务:独立 Job Worker 进程,负责执行扫描、生产、AI、解包等异步任务。
|
||||
5. 部署入口:Nginx 负责前端静态资源和反向代理。
|
||||
6. 外部能力:可选接入 ENVI/SARscape、ISCE2、Ollama 等外部组件。
|
||||
|
||||
### 3.2 主要功能模块
|
||||
|
||||
系统目前已经具备较完整的业务模块:
|
||||
|
||||
1. 雷达数据管理
|
||||
支持监控目录扫描、元数据解析、预览图生成、空间范围展示、检索和分页浏览。
|
||||
2. 轨道数据管理
|
||||
支持轨道文件关联和本地轨道池同步,为生产链路提供基础输入。
|
||||
3. 配对与批次管理
|
||||
支持 D-InSAR 配对策略、批量任务组织、批次项管理和后续复制导出。
|
||||
4. D-InSAR 生产中心
|
||||
已经从单引擎思路升级为多引擎生产中心,支持统一查看引擎状态、提交任务、查看运行记录。
|
||||
5. D-InSAR 结果管理
|
||||
支持结果扫描入库、地图展示、缓存、导出、AI 评分与人工标注。
|
||||
6. AI 能力
|
||||
支持质量模型训练、质量预测、影像诊断、报告生成。
|
||||
7. 水体监测
|
||||
已形成相对独立的处理链路和界面。
|
||||
8. 运维与权限
|
||||
包含健康检查、任务管理、审计日志、用户管理、登录限流、许可证控制等。
|
||||
|
||||
### 3.3 当前系统成熟度判断
|
||||
|
||||
从工程状态看,项目已经不是原型阶段,而是进入“可持续扩展的平台阶段”:
|
||||
|
||||
1. 业务边界已明确。
|
||||
2. 前后端结构已稳定。
|
||||
3. 后台任务与数据库模型已成体系。
|
||||
4. 多引擎 D-InSAR 生产框架已经搭起来。
|
||||
5. 系统具备继续接入第三方生产核心的基础。
|
||||
|
||||
这意味着后续采购不应再按“买一个孤立的软件工具”来考虑,而应按“纳入统一生产平台的外部生产核心”来考虑。
|
||||
|
||||
## 四、系统运行主线
|
||||
|
||||
从全流程看,当前系统的主线可以概括为:
|
||||
|
||||
1. 数据进入系统
|
||||
扫描雷达目录、轨道目录、结果目录,完成入库和索引。
|
||||
2. 用户在前端组织任务
|
||||
选择 AOI、筛选源数据、执行配对、形成批次、下发生产任务。
|
||||
3. 后端进入异步处理模式
|
||||
系统创建任务记录和作业记录,由 Worker 执行具体处理。
|
||||
4. 外部引擎执行生产
|
||||
当前已支持 ENVI/SARscape 和 ISCE2 两类生产能力。
|
||||
5. 结果回流系统
|
||||
产物落地后可扫描入库、生成缓存、展示到地图和列表,并进入后续分析。
|
||||
6. 运维与质量闭环
|
||||
通过健康检查、日志、审计、AI 分析和人工核查,形成可运维闭环。
|
||||
|
||||
这一主线决定了本系统天然适合接入多个生产引擎,只要外部引擎能被标准化调用。
|
||||
|
||||
## 五、D-InSAR 生产体系现状
|
||||
|
||||
### 5.1 已形成的多引擎框架
|
||||
|
||||
当前项目已经不再把 D-InSAR 生产写死在某一套工具链上,而是抽象成统一的“生产引擎”框架。对每个引擎,系统要求至少具备三类能力:
|
||||
|
||||
1. 可用性检查:系统要知道该引擎当前能不能用。
|
||||
2. Profile 列表:系统要知道该引擎支持哪些处理链路。
|
||||
3. 统一运行入口:系统要能按同样的方式下发任务并接收结果。
|
||||
|
||||
在这个框架下,系统现在已有三类引擎标识:
|
||||
|
||||
1. `sarscape`
|
||||
已可运行,对接现有 ENVI/SARscape 流程。
|
||||
2. `isce2`
|
||||
已可运行,通过 WSL 调用 ISCE2 链路。
|
||||
3. `landsar`
|
||||
目前仅做接口预留和前端占位,尚未真正接入生产能力。
|
||||
|
||||
### 5.2 当前已落地的两个生产核心
|
||||
|
||||
#### 1. ENVI / SARscape
|
||||
|
||||
这是当前系统最成熟的生产核心,主要特点:
|
||||
|
||||
1. 与现有历史流程兼容度高。
|
||||
2. 支持 `metatask` 和 `custom6` 两种 profile。
|
||||
3. 已具备运行、日志、结果回收和健康检查能力。
|
||||
4. 适合作为当前生产主力链路。
|
||||
|
||||
#### 2. ISCE2
|
||||
|
||||
这是当前系统第二个生产核心,主要特点:
|
||||
|
||||
1. 通过 WSL 方式运行,避免强依赖本机 Windows 图形环境。
|
||||
2. 已具备环境检查、路径转换、脚本调用、任务执行能力。
|
||||
3. 适合承接 LT-1 等标准化链路。
|
||||
4. 为系统后续接入更多异构引擎提供了样板。
|
||||
|
||||
### 5.3 LANDSAR 当前状态
|
||||
|
||||
这一点在汇报和采购中必须明确说明:
|
||||
|
||||
截至 2026-03-13,`LANDSAR` 在本项目中属于“架构已预留、能力未接入”的状态,具体表现为:
|
||||
|
||||
1. 后端已存在 `landsar` 引擎占位。
|
||||
2. 前端生产中心已预留 `LANDSAR` 状态卡位置。
|
||||
3. 健康检查体系已将 `LANDSAR` 视为可纳入统一监控的引擎类型。
|
||||
4. 轨道池体系中已预留 `ORBIT_POOL_LANDSAR` 的配置位置。
|
||||
5. 但任务提交、执行、日志、结果回收尚未真正实现。
|
||||
6. 当前生产提交接口实际仍只支持已落地的引擎,`LANDSAR` 还不能像现有生产核心那样直接投入运行。
|
||||
|
||||
这意味着:系统架构已经准备好接纳 LANDSAR,但采购后的接入工作仍需要正式实施,不能误判为“买来即可无缝运行”。
|
||||
|
||||
## 六、为什么要把 LANDSAR 作为第三个生产核心
|
||||
|
||||
从平台演进角度,引入 LANDSAR 的意义主要有四点:
|
||||
|
||||
1. 降低对单一商业引擎的依赖。
|
||||
2. 提升不同场景下的处理适配能力。
|
||||
3. 形成多引擎并行的生产格局,增强方案弹性。
|
||||
4. 使采购的软件能力真正纳入平台统一调度,而不是形成新的信息孤岛。
|
||||
|
||||
如果 LANDSAR 只是作为独立软件单独运行,那么它对现有系统的价值有限,最终仍然会回到“人工切换工具、人工导入结果、人工追踪过程”的旧模式。只有把它嵌入本系统,成为第三个生产核心,采购价值才能最大化。
|
||||
|
||||
## 七、LANDSAR 接入的目标定位
|
||||
|
||||
本项目对 LANDSAR 的目标定位不是“重写 LANDSAR 算法”,而是“把 LANDSAR 系统现有 D-InSAR 生产服务纳入统一调度平台”。
|
||||
|
||||
因此,推荐的定位是:
|
||||
|
||||
1. 本系统负责任务组织、权限控制、日志审计、状态展示、结果入库和运维闭环。
|
||||
2. LANDSAR 系统负责实际 D-InSAR 生产处理。
|
||||
3. 双方通过标准接口交互,而不是把两边代码强行揉成一体。
|
||||
|
||||
这也是最符合采购落地的模式,因为它对供应商最明确,对我方平台风险最可控。
|
||||
|
||||
## 八、LANDSAR 与本系统的推荐交互模式
|
||||
|
||||
### 8.1 推荐模式:服务嵌入式接入
|
||||
|
||||
建议将 LANDSAR 以“外部生产服务”的方式接入本系统,而不是以人工操作方式接入。
|
||||
|
||||
推荐架构如下:
|
||||
|
||||
1. 用户仍然只在本系统前端操作。
|
||||
2. 用户在 D-InSAR 生产中心中选择 `LANDSAR` 作为引擎。
|
||||
3. 本系统后端创建标准任务和作业记录。
|
||||
4. `landsar` 适配引擎把任务参数发送给 LANDSAR 生产服务。
|
||||
5. LANDSAR 返回运行编号并执行处理。
|
||||
6. 本系统轮询任务状态,或者接收 LANDSAR 回调通知。
|
||||
7. 处理完成后,产物输出到约定目录,或由本系统拉取到指定目录。
|
||||
8. 本系统完成结果扫描、入库、展示和后续分析。
|
||||
|
||||
这样做的最大好处是:对用户来说,LANDSAR 不是另一套系统,而是本系统中的第三个生产核心。
|
||||
|
||||
### 8.2 不推荐模式:纯人工导入导出
|
||||
|
||||
如果采购的 LANDSAR 只能做到“人工打开软件、手工点运行、手工拷贝结果”,则它不能真正成为第三个生产核心,只能成为一个外部工具。这样会带来以下问题:
|
||||
|
||||
1. 无法统一任务状态。
|
||||
2. 无法统一日志与审计。
|
||||
3. 无法统一批次管理。
|
||||
4. 无法纳入健康检查。
|
||||
5. 无法形成稳定的生产闭环。
|
||||
|
||||
因此,采购时必须把“可集成、可调用、可监控”作为硬条件。
|
||||
|
||||
## 九、LANDSAR 接入后的业务流程
|
||||
|
||||
建议将接入流程设计为以下八步:
|
||||
|
||||
1. 任务组织
|
||||
用户在本系统完成配对、批次选择、AOI 约束和参数选择。
|
||||
2. 任务提交
|
||||
本系统向 LANDSAR 服务提交标准化请求,包括输入目录、输出目录、profile、处理参数、任务编号等。
|
||||
3. 运行登记
|
||||
本系统保存本地任务 ID 和 LANDSAR 侧运行 ID 的映射关系。
|
||||
4. 执行监控
|
||||
本系统通过轮询接口或回调机制获取进度、状态和错误信息。
|
||||
5. 日志采集
|
||||
本系统读取 LANDSAR 返回的执行日志摘要,必要时保留完整日志文件地址。
|
||||
6. 产物回收
|
||||
LANDSAR 将产物输出到双方约定目录,或通过下载接口交给本系统。
|
||||
7. 结果入库
|
||||
本系统对产物进行扫描、索引、缓存生成和结果入库。
|
||||
8. 统一展示
|
||||
用户在现有结果管理界面中查看 LANDSAR 结果,与其他引擎结果统一管理。
|
||||
|
||||
## 十、LANDSAR 作为第三核心时的系统改造点
|
||||
|
||||
从本系统角度,真正需要做的改造不是推倒重来,而是在现有多引擎框架上补全 `landsar` 适配层。
|
||||
|
||||
### 10.1 后端改造点
|
||||
|
||||
1. 完成 `landsar_engine.py`
|
||||
目前这个文件只是占位,需要实现真正的可用性检查、profile 获取和运行逻辑。
|
||||
2. 增加 LANDSAR 任务处理器
|
||||
可以新增独立 `JOB_TYPE_LANDSAR_RUN`,也可以复用统一外部引擎作业模式。
|
||||
3. 增加运行状态映射
|
||||
需要把 LANDSAR 的状态映射到本系统统一状态,如 `PENDING`、`RUNNING`、`COMPLETED`、`FAILED`。
|
||||
4. 增加日志采集与错误归一化
|
||||
要保证前端看到的日志和错误信息可理解、可追踪。
|
||||
5. 增加结果回收逻辑
|
||||
需要把 LANDSAR 输出目录纳入结果扫描与入库体系。
|
||||
6. 补充轨道池适配
|
||||
当前系统已预留 `ORBIT_POOL_LANDSAR`,采购后需明确 LANDSAR 轨道格式和同步策略。
|
||||
|
||||
### 10.2 前端改造点
|
||||
|
||||
1. 让 `LANDSAR` 状态卡从“预留”变成“可选可提交”。
|
||||
2. 展示 LANDSAR 专属 profile 和参数项。
|
||||
3. 在运行历史中显示 `engine=landsar`。
|
||||
4. 在结果列表和详情中标识结果来源于 LANDSAR。
|
||||
|
||||
### 10.3 运维改造点
|
||||
|
||||
1. 增加 LANDSAR 服务健康检查。
|
||||
2. 增加供应商服务连通性检查。
|
||||
3. 增加回调鉴权或调用鉴权。
|
||||
4. 增加 LANDSAR 结果目录一致性检查。
|
||||
|
||||
## 十一、采购时必须明确的接口要求
|
||||
|
||||
这一部分是采购方案的核心。若这些能力得不到保障,LANDSAR 就无法真正嵌入平台。
|
||||
|
||||
### 11.1 必须具备的调用方式
|
||||
|
||||
供应商至少应提供以下三种方式之一,优先级从高到低如下:
|
||||
|
||||
1. HTTP/REST 服务接口
|
||||
最推荐,最适合平台接入。
|
||||
2. 命令行接口(CLI)
|
||||
可作为次优方案,但需要明确返回码、日志和输出目录约定。
|
||||
3. Python/SDK 接口
|
||||
也可接受,但后续部署和版本兼容成本通常更高。
|
||||
|
||||
如果三者都没有,只提供 GUI 操作,则不建议作为“第三生产核心”采购。
|
||||
|
||||
### 11.2 必须具备的最小接口能力
|
||||
|
||||
若采用服务接口,建议采购时要求至少提供以下能力:
|
||||
|
||||
1. 提交任务接口
|
||||
输入参数包括任务编号、profile、输入目录、输出目录、处理参数。
|
||||
2. 查询任务状态接口
|
||||
能返回排队、运行中、完成、失败、取消等状态。
|
||||
3. 查询进度接口
|
||||
能返回百分比或阶段性进度。
|
||||
4. 查询日志接口
|
||||
至少能返回日志摘要,最好支持完整日志文件。
|
||||
5. 查询产物接口
|
||||
能返回主产物、辅产物、日志文件、质量文件等路径或下载地址。
|
||||
6. 健康检查接口
|
||||
能返回服务可用性、许可证状态、核心依赖状态。
|
||||
7. 能力枚举接口
|
||||
能列出当前支持的 profile、版本、约束条件。
|
||||
|
||||
### 11.3 必须明确的数据约定
|
||||
|
||||
采购时要和供应商约定清楚以下数据边界:
|
||||
|
||||
1. 输入目录结构由谁负责准备。
|
||||
2. 输出目录结构是否固定。
|
||||
3. 主结果文件命名规则是否稳定。
|
||||
4. 日志文件命名规则和保存期限。
|
||||
5. 失败任务是否保留中间文件。
|
||||
6. 轨道文件格式和目录组织方式。
|
||||
7. 坐标系、DEM、投影和元数据约定。
|
||||
|
||||
没有这些约定,后续集成必然出现反复沟通和返工。
|
||||
|
||||
## 十二、建议的采购技术条款
|
||||
|
||||
为了确保 LANDSAR 真正能嵌入本系统,建议采购文件中写入如下技术条款。
|
||||
|
||||
### 12.1 必选条款
|
||||
|
||||
1. 供应商须提供可编程调用接口,不得仅提供人工图形界面。
|
||||
2. 供应商须提供任务提交、状态查询、日志查询、结果获取的完整接口说明。
|
||||
3. 供应商须支持与第三方业务系统进行集成,并配合联调。
|
||||
4. 供应商须提供稳定的版本管理和升级兼容说明。
|
||||
5. 供应商须明确许可证机制对服务化调用的限制条件。
|
||||
6. 供应商须配合完成至少一个标准 D-InSAR 生产 profile 的端到端联调验收。
|
||||
|
||||
### 12.2 强烈建议条款
|
||||
|
||||
1. 支持回调通知机制,减少轮询压力。
|
||||
2. 支持独立健康检查接口。
|
||||
3. 支持 profile 枚举和参数模板查询。
|
||||
4. 支持输出标准化目录结构。
|
||||
5. 支持服务部署在内网服务器环境。
|
||||
6. 支持批量任务执行和失败重试。
|
||||
|
||||
### 12.3 验收建议
|
||||
|
||||
建议把验收拆成两个层次:
|
||||
|
||||
1. 集成验收
|
||||
能在本系统中完成 LANDSAR 任务提交、状态查看、日志查看、结果入库。
|
||||
2. 业务验收
|
||||
能稳定完成至少一个真实生产样例,并在前端完成统一展示。
|
||||
|
||||
### 12.4 采购方案分级建议
|
||||
|
||||
为了避免采购完成后无法嵌入现有系统,建议把采购方案分成三档判断:
|
||||
|
||||
1. 推荐方案
|
||||
采购“LANDSAR 服务接口版 + 联调实施服务 + 服务化许可”。
|
||||
该方案要求供应商提供 API 或等价服务接口,并配合完成与本系统的任务、状态、日志、结果联通。这是最符合“第三生产核心”目标的方案。
|
||||
2. 可接受方案
|
||||
采购“LANDSAR CLI/SDK 版 + 本地部署支持 + 接口适配支持”。
|
||||
该方案在没有标准服务接口时仍可落地,但后续部署、升级、兼容和运维成本会明显高于推荐方案。
|
||||
3. 不建议方案
|
||||
仅采购“LANDSAR 桌面 GUI 单机版”。
|
||||
该方案无法稳定嵌入本系统,只能形成独立工具,难以支撑统一任务管理、日志审计和结果治理,不建议作为本项目采购目标。
|
||||
|
||||
## 十三、LANDSAR 接入对采购决策的影响
|
||||
|
||||
这一点需要在汇报中重点强调:
|
||||
|
||||
采购 LANDSAR,不是单纯采购一个处理软件,而是在采购本系统的第三个生产核心。
|
||||
|
||||
因此,采购判断应从以下维度展开:
|
||||
|
||||
1. 不只是看算法效果,还要看是否可集成。
|
||||
2. 不只是看桌面端能不能跑,还要看服务端能不能调。
|
||||
3. 不只是看一次能不能出结果,还要看能否纳入长期运维。
|
||||
4. 不只是看供应商交付软件,还要看是否交付接口和联调能力。
|
||||
|
||||
如果采购时忽略这些条件,后续极有可能出现“软件买到了,但无法嵌入现有平台”的情况,导致采购价值被打折。
|
||||
|
||||
## 十四、建议的实施路径
|
||||
|
||||
建议分两步推进:
|
||||
|
||||
### 第一阶段:完成服务嵌入
|
||||
|
||||
目标是让 LANDSAR 先成为“可调度、可监控、可回收”的第三生产核心。
|
||||
|
||||
重点工作:
|
||||
|
||||
1. 完成接口对接。
|
||||
2. 完成任务状态联通。
|
||||
3. 完成日志与结果回流。
|
||||
4. 完成前端选择与展示。
|
||||
|
||||
### 第二阶段:完成深度治理
|
||||
|
||||
目标是把 LANDSAR 结果纳入更完整的统一治理体系。
|
||||
|
||||
重点工作:
|
||||
|
||||
1. 结果版本管理。
|
||||
2. 多引擎结果对比。
|
||||
3. 质量评价与复核闭环。
|
||||
4. 更细粒度的运行审计和运维检查。
|
||||
|
||||
这样推进的好处是先把采购价值尽快落地,再逐步做深,而不是一开始就把目标定得过重。
|
||||
|
||||
## 十五、结论
|
||||
|
||||
综合判断如下:
|
||||
|
||||
1. 当前 InSAR 管理系统已经具备平台化能力,适合承接第三方 D-InSAR 生产核心。
|
||||
2. 系统的多引擎架构已经形成,`LANDSAR` 不是从零开始接,而是在既有框架中补齐适配层。
|
||||
3. 截至目前,`LANDSAR` 在系统中仍是预留状态,尚未真正接入生产执行。
|
||||
4. 因此,采购方案必须把“可编程调用、可集成、可监控、可回收”写成明确要求。
|
||||
5. 最推荐的采购与实施方式,是将 LANDSAR 以外部生产服务的形式嵌入本系统,作为第三个 D-InSAR 生产核心统一调度。
|
||||
|
||||
一句话概括:本项目当前已经具备“接入第三生产核心”的平台基础,下一步采购是否成功,关键不在于是否购买到一个能跑的工具,而在于是否购买到一个能够被本系统稳定接入的服务化能力。
|
||||
Reference in New Issue
Block a user