Apply current workspace changes

This commit is contained in:
2026-04-22 01:52:21 +08:00
parent cf34b9a8ed
commit cb518b431f
449 changed files with 92252 additions and 321 deletions
+15
View File
@@ -28,6 +28,16 @@
配对能力增强设计。属于未完全落地的专项设计文档。
- **[GAMMA_WSL2_INTEGRATION_PLAN.md](GAMMA_WSL2_INTEGRATION_PLAN.md)**
GAMMA + WSL2 双引擎方案。属于后续扩展规划,不是当前默认运行链路。
- **[PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md](PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md)**
PyINT 生产引擎与 Gamma 精配对总体设计。明确现有多引擎架构下的接入边界、配置管理、数据库策略、运维自检扩展与前端入口分布。
- **[PYINT_GAMMA_IMPLEMENTATION_TODO_20260418.md](PYINT_GAMMA_IMPLEMENTATION_TODO_20260418.md)**
PyINT 生产引擎与 Gamma 精配对实施清单。按阶段拆分后端、前端、接口、运维与可选数据库任务,作为后续落地执行顺序。
- **[PYINT_INPUT_ASSET_ADAPTATION_DESIGN_20260419.md](PYINT_INPUT_ASSET_ADAPTATION_DESIGN_20260419.md)**
PyINT 输入资产适配设计。聚焦 `Task_*` 路径如何映射到 PyINT 工作区,以及 DEM、LT-1 精密轨道、运维自检和前端入口应如何纳入系统托管治理。
- **[PYINT_LT1_COREG_ORBIT_HYPOTHESIS_EXPERIMENT_20260420.md](PYINT_LT1_COREG_ORBIT_HYPOTHESIS_EXPERIMENT_20260420.md)**
LT-1 在 PyINT/Gamma 中 `coreg` 失败的轨道假设验证实验设计。固定输入和 DEM,只改变 `.slc.par` 的 state vector 处理方式,对照验证问题是否集中在导入后的轨道几何链条。
- **[PYINT_LT1_DEM_GEOMETRY_CHAIN_EXPERIMENT_20260420.md](PYINT_LT1_DEM_GEOMETRY_CHAIN_EXPERIMENT_20260420.md)**
LT-1 在 PyINT/Gamma 中 `init_offsetm` 失败的 DEM 几何链定位实验。聚焦 `HGTSIM / lt0 / mli0 / Samp` 的中间产物,区分 DEM 本体问题、DEM 几何映射链问题和中心 patch 选取问题。
- **[WSL2_ISCE2_MINTPY_SBAS_INTEGRATION_PLAN_20260412.md](WSL2_ISCE2_MINTPY_SBAS_INTEGRATION_PLAN_20260412.md)**
基于本机 `Ubuntu-24.04` WSL2、`isce2` / `mintpy` / `isce2_mintpy_v1` 实际环境核对后的 SBAS 集成落地方案,明确推荐运行时、workflow 补全顺序和正式产品边界。
- **[ISCE2_SBAS_TIMESERIES_DESIGN.md](ISCE2_SBAS_TIMESERIES_DESIGN.md)**
@@ -91,6 +101,11 @@
4. [ISCE2_SBAS_TIMESERIES_DESIGN.md](ISCE2_SBAS_TIMESERIES_DESIGN.md)
5. [WSL2_ISCE2_MINTPY_SBAS_INTEGRATION_PLAN_20260412.md](WSL2_ISCE2_MINTPY_SBAS_INTEGRATION_PLAN_20260412.md)
6. [GAMMA_WSL2_INTEGRATION_PLAN.md](GAMMA_WSL2_INTEGRATION_PLAN.md)
7. [PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md](PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md)
8. [PYINT_GAMMA_IMPLEMENTATION_TODO_20260418.md](PYINT_GAMMA_IMPLEMENTATION_TODO_20260418.md)
9. [PYINT_INPUT_ASSET_ADAPTATION_DESIGN_20260419.md](PYINT_INPUT_ASSET_ADAPTATION_DESIGN_20260419.md)
10. [PYINT_LT1_COREG_ORBIT_HYPOTHESIS_EXPERIMENT_20260420.md](PYINT_LT1_COREG_ORBIT_HYPOTHESIS_EXPERIMENT_20260420.md)
11. [PYINT_LT1_DEM_GEOMETRY_CHAIN_EXPERIMENT_20260420.md](PYINT_LT1_DEM_GEOMETRY_CHAIN_EXPERIMENT_20260420.md)
## 4. 后续维护规则
+74
View File
@@ -0,0 +1,74 @@
# PyINT + Gamma A/B 排查结论
更新时间:2026-04-20
## 1. 排查目标
验证当前仓库内改过的 `PyINT/Gamma` 流程,是否只是“流程层修改”而没有影响科学结果;尤其要定位为什么同一组 LT-1 `Task` 在 ENVI/IDL 核心可产出结果,而当前 PyINT 结果为空。
本轮对照任务:
- 任务目录:`D:\Task_Pool\DInSAR\Task_260416_Gamma_PyINT\Task_20230602_20230720`
- DEM`D:\DEM\COPDEM_GLO30_China_4326_DEM`
- 实验根目录:`D:\PyINT_AB`
- 生产链 Python`/home/administrator/miniconda3/envs/isce2/bin/python`
## 2. 对照实验
### Case A:当前代码 + 轨道桥接开启 + rescue 开启
- case`D:\PyINT_AB\current_orbit_rescue`
- 结果:流程可跑完到 `diff`
- 但关键中间结果全 0
- `diff_filt.zero_ratio = 1.0`
- `cor.zero_ratio = 1.0`
### Case B:当前代码 + 轨道桥接关闭 + rescue 开启
- case`D:\PyINT_AB\no_orbit_rescue`
- 结果:流程同样可跑完到 `diff`
- 关键中间结果仍然全 0
- `diff_filt.zero_ratio = 1.0`
- `cor.zero_ratio = 1.0`
结论:轨道桥接开关不是这次“全 0 结果”的主责任点。
### Case C:轨道桥接开启 + 去掉 rescue
- case`D:\PyINT_AB\orbit_no_rescue`
- 结果:流程直接死在 `coreg`
- 关键报错:
- `init_offsetm failed`
- `ERROR: number of zero values 195367 in MLI1 image patch exceeds threshold: 32768`
结论:当前仓库里的 `coreg rescue` 确实在掩盖真实失败。它让一个本应失败的配准任务继续往后执行,最终产生“流程成功但科学结果全 0”的假成功。
## 3. 直接结论
1. 不能再说“我们现在的改动只改流程、不影响结果”。当前实现已经改变了失败语义,导致无效结果被当成成功结果收口。
2. 这次任务的主要问题点在 `coreg`,不是 GeoTIFF 导出,不是地理编码,也不是解缠。
3. LT-1 精密轨道桥接不是这次空结果的主责任点;更深层的根因仍然要继续排查 LT-1 导入 / 配准链路与 ENVI/IDL 核心之间的差异。
## 4. 已落实的代码策略
为避免系统继续产出“成功但全 0”的无效结果,当前仓库已做两项收敛:
1. `third_party/PyINT/pyint/coreg_gamma.py`
- 去掉两个 rescue/fallback
- `init_offsetm/offset_pwrm/offset_fitm/gc_map_fine` 失败时不再复制 `lt0 -> lt1`
- offset refinement 失败时不再把 `Srslc0` 直接提升为最终 `RSLC`
- 改为失败即退出
2. `backend/app/pyint_pipeline/run_lt1_pyint_pipeline.py`
- 增加产物有效性检查
- 如果 `diff_filt` / `coh` / `unw` / `geo_unw` / `geo_los` 出现“文件存在但二进制全 0”,直接判定此次运行失败
- 运行失败时附带阶段错误日志路径,例如 `coreg_gamma_all.err`
## 5. 后续真正要解决的问题
这次代码收敛只解决“假成功”问题,还没有解决“为什么 LT-1 在 PyINT/Gamma 下配不准”这个根因。下一阶段建议继续做以下对照:
1. 对比 ENVI/IDL 成功任务与 PyINT 导入后的 `.slc.par`、多视幅度、DEM 配准输入是否一致。
2. 对比 LT-1 导入脚本生成的 `SLC/MLI` 几何参数,尤其是时序、PRF、采样间隔、deskew、状态矢量相关字段。
3. 对比 `mli0` 与目标 `Samp` 的重叠区域,确认 `init_offsetm` 为什么会在中心 patch 上出现大量 0 值。
当前判断:真正的科学问题仍在 LT-1 导入 / coreg 前置几何链路,而不是后面的 unwrap / geocode。
@@ -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 1PyINT 后端引擎接入
目标:
-`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 2PyINT 结果归一化与结果治理兼容
目标:
- 保证 `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 4Gamma 精配对 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,601 @@
# PyINT + Gamma 集成总体设计
**日期**: 2026-04-18
**状态**: 总体设计
**范围**: D-InSAR 生产引擎接入、Gamma 精配对接入、配置管理、数据库策略、运维自检、前端入口
## 1. 结论
本次集成建议采用两条并行但相互衔接的路线:
1.`PyINT` 作为新的 D-InSAR 生产引擎接入现有多引擎框架,统一走现有任务队列、运行日志、结果登记与结果目录治理链路。
2.`Gamma` 配对能力接入现有“配对基础 -> 配对规划 -> 生产执行”链路,作为数据库粗配对结果之上的精化步骤,而不是替换当前配对基础缓存。
核心判断如下:
- `PyINT` 更适合作为“受控外部引擎”集成,而不是直接作为后端内部 Python 库深度嵌入。
- `Gamma` 精配对是可集成的,但更适合针对“已经筛出的场景集合/网络运行”做二次优化,不适合直接取代当前全库候选对缓存。
- 一期集成建议不强制修改数据库主结构;优先复用现有 `pairing_network_runs` / `pairing_network_edges` 的 JSON 承载精配对元数据。
- 如果二期需要对 Gamma 精配对历史做独立检索、统计和运维闭环,再引入单独迁移文件,并通过现有数据库自维护机制自动落库。
## 2. 现状与约束
### 2.1 当前系统已有基础
- 已有 D-InSAR 多引擎抽象:`backend/app/dinsar_engines/base.py`
- 已有引擎注册表:`backend/app/dinsar_engines/registry.py`
- 已有生产任务接口与队列:`backend/app/routers/dinsar_production.py`
- 已有配对基础缓存、网络运行与边追踪:
- `backend/app/models/orm.py`
- `backend/app/services/pairing_cache_service.py`
- `backend/app/services/pairing_state_service.py`
- `backend/app/services/spatial_service.py`
- 已有数据库自维护与 SQL 迁移自动执行:`backend/app/db_maintenance.py`
- 已有运维自检面板与健康检查汇总:`backend/app/services/health_service.py``frontend/src/HealthCheckPanel.jsx`
- 已有生产页与配对规划页:
- `frontend/src/DinsarProductionPanel.jsx`
- `frontend/src/panels/PairPlanningPanel.jsx`
### 2.2 PyINT 项目特征
`D:\Code\PyINT` 现状看,`PyINT` 不是干净的 SDK,而是以模板和脚本为中心的流程编排层:
- 主入口为 `pyint/pyintApp.py`
- 配对能力入口为 `pyint/select_pairs.py`
- 严重依赖环境变量:
- `SCRATCHDIR`
- `TEMPLATEDIR`
- `DEMDIR`
- 运行方式偏 Linux / WSL,广泛调用外部命令与 GAMMA CLI
- 更适合作为“流程执行器”被调用,而不是被后端直接 import 后逐步复用内部函数
### 2.3 明确约束
- 本机只有一个 WSL 环境,不需要设计多 distro 调度系统。
- 系统级 Windows Python 解释器已经在根 `.env` 中维护,可复用,不应再为 PyINT 额外复制一套 Windows Python 配置。
- 管理员口令不应进入设计文档、代码或 `.env.example`。权限控制继续复用现有登录态与管理员角色校验。
- 现有运维自检面板已经较重,PyINT/Gamma 的“操作入口”不应继续堆在健康检查页里。
## 3. 总体集成架构
### 3.1 总体原则
- 不新建平行子系统,优先复用现有引擎、作业、配对、结果目录与目录扫描体系。
- 不改变现有 `pairing_metric_cache.spatial_baseline_meters` 的语义。
- 不把 Gamma 精配对结果直接覆盖数据库粗配对缓存。
- 运维页只看状态,实际操作放在生产页与配对规划页。
### 3.2 架构分层
#### A. 生产引擎层
新增 `pyint` 引擎,挂到现有 `registry` 中,与 `sarscape` / `isce2` / `landsar` 并列。
#### B. WSL 执行适配层
新增受控执行服务,负责:
- 读取 `.env` 配置
- 复用现有 WSL 命令执行与路径转换能力
- 组装 `PyINT` 所需环境变量
- 生成模板文件和运行目录
- 执行 `PyINT` 包装脚本
- 将输出归一化到系统现有结果结构
#### C. 配对精化层
保留现有数据库候选对缓存与网络运行。
在此基础上新增“Gamma 精配对”步骤:
1. 先由当前配对接口生成候选网络
2. 再将该网络对应场景集送入 Gamma / PyINT 配对流程
3. 生成新的精化网络结果
4. 前端允许用户查看并选择使用精化后的网络结果
#### D. 结果治理层
PyINT/Gamma 原始工作目录不直接作为系统正式结果。
必须经过适配层输出统一结果包,保证继续兼容:
- 结果目录扫描
- 结果目录发布
- 结果目录桥接一致性
- 预览图/缩略图生成
- AI 诊断与 catalog 追踪
## 4. PyINT 生产引擎设计
### 4.1 目标
目标不是把 `PyINT` 原封不动暴露给用户,而是把它包装成当前系统理解的“一个可选生产引擎”。
### 4.2 推荐实现方式
新增以下后端组件:
- `backend/app/dinsar_engines/pyint_engine.py`
- `backend/app/services/pyint_service.py`
- `backend/app/pyint_pipeline/run_lt1_pyint_pipeline.py`
职责划分:
- `pyint_engine.py`
- 实现 `DinsarEngine`
- 暴露 `engine_code=pyint`
- 提供可用性检查、处理 profile、参数 schema
- `pyint_service.py`
- WSL 执行
- 路径转换
- 模板写入
- 环境变量组装
- 烟测检查
- `run_lt1_pyint_pipeline.py`
- 作为受控包装脚本在 WSL 中运行
- 负责把系统已有 `Task_*` / 配对任务目录映射成 PyINT 项目工作区
- 调用 `pyintApp.py` 或更细粒度子脚本
- 收集输出并生成系统结果清单
### 4.3 与当前生产链路的关系
沿用现有生产链路:
`前端生产页 -> /dinsar-production/run -> job queue -> pyint_engine.run() -> WSL -> PyINT -> 统一结果包 -> catalog/scan`
这样做的收益:
- 不需要新增独立任务中心
- 不需要新增另一套运行日志
- 不需要新增另一套前端生产入口
- 与当前 `DinsarProductionPanel.jsx` 的多引擎 UI 完全兼容
### 4.4 输入与工作区组织
建议一期仍以当前系统已有的任务目录为输入,不要求用户先手工构造原生 PyINT 项目。
推荐工作区结构:
- 系统输入根目录:沿用当前生产面板 `root_dir`
- PyINT 工作根目录:系统管理目录,例如 `backend/runtime/pyint_work`
- 模板目录:系统管理目录,例如 `backend/runtime/pyint_templates`
- 每次运行独立 `run_key`
- 每个 pair/task 独立 workspace,避免相互污染
### 4.5 结果输出策略
PyINT 原始输出不能直接作为系统正式结果目录暴露。
推荐新增“输出归一化”步骤,将 PyINT/Gamma 输出转为系统现有 bundle 约定,至少包含:
- 结果主清单
- 关键输出文件路径
- 运行元数据
- pair trace 信息
- engine/profile 信息
必须保证与现有结果目录扫描机制兼容。
### 4.6 Profile 设计建议
一期建议只开放一个稳定 profile:
- `lt1_gamma_dinsar`
不建议一开始把 `PyINT` 全部开关都暴露到前端。应只暴露对当前业务必要的参数,例如:
- 是否强制重跑
- 多视参数
- 相干阈值
- geocode 开关
- unwrap 开关
- 超时
其余细节由模板生成器按系统默认值填充。
## 5. Gamma 精配对设计
### 5.1 目标定位
Gamma 精配对不替代当前数据库候选对缓存,而是建立在现有候选网络之上的二次精化机制。
推荐定位为:
- 当前数据库配对:全库级、粗筛级、可快速响应
- Gamma 精配对:项目级、网络级、精筛级、可生成更可靠的时空基线网络
### 5.2 推荐流程
1. 用户在现有配对规划页完成粗配对查询
2. 后端返回 `network_run_id`
3. 用户在“Gamma 精配对”区域发起精化
4. 系统根据该网络运行对应的场景集合,构建 PyINT/Gamma 工作区
5. 调用 `select_pairs.py` / `base_calc` 生成精配对网络
6. 后端将结果落回系统网络结果表示
7. 前端展示“粗配对结果”和“Gamma 精配对结果”的对比摘要
8. 用户选择使用哪一版网络继续生产
### 5.3 为什么不能直接覆盖当前 pairing cache
当前 `pairing_metric_cache` 里的 `spatial_baseline_meters` 已经在系统内承担既有语义与下游用途。
Gamma 计算出的垂直基线/网络属性与当前字段不等价,直接覆盖会带来语义混乱和回归风险。
因此必须坚持:
- 现有缓存保留原语义
- Gamma 精配对结果单独存储
- 精配对结果仅作为网络选择依据,不回写粗配对主缓存
### 5.4 一期存储策略
一期推荐不新建强结构化表,优先复用:
- `pairing_network_runs.request_params_json`
- `pairing_network_edges.selection_meta_json`
建议约定写入内容:
- `refinement_engine: gamma_pyint`
- `refinement_source_run_id`
- `gamma_bperp_m`
- `gamma_tbase_days`
- `gamma_rank`
- `gamma_ifgram_list_path`
- `gamma_artifact_dir`
- `gamma_selection_reason`
同时新增一个新的 `network_run_id`,把“精配对结果”作为新的网络运行保存,而不是修改原粗配对运行。
这样做的收益:
- 一期可不改数据库结构
- 保留粗配对和精配对双轨结果,便于审计与回退
- 复用现有 network run / edge 追踪模型
### 5.5 二期可选扩展
如果后续有以下需求,再引入数据库迁移:
- 精配对历史独立检索
- 精配对任务状态长期统计
- 精配对工作区清理与资产追踪
- 精配对失败类型聚合运维
二期建议新增表,例如:
- `pairing_refinement_runs`
- `pairing_refinement_artifacts`
但这不是一期必须项。
## 6. 配置与运行管理方案
### 6.1 配置原则
- Windows 侧解释器继续复用根 `.env` 中已有的 `PYTHON_PATH`
- WSL 侧只维护 PyINT/Gamma 运行必须配置
- 因为本机只有一个 WSL 环境,`PyINT``ISCE2` 默认共用 distro
### 6.2 建议新增配置项
建议在 `.env` / `.env.example` / `backend/app/config.py` 中新增:
```ini
PYINT_ENABLED=false
PYINT_WSL_DISTRO=
PYINT_WSL_PYTHON=
PYINT_HOME=
PYINT_APP_SCRIPT=
PYINT_TEMPLATE_ROOT=
PYINT_WORK_ROOT=
PYINT_OUTPUT_ROOT=
PYINT_DEM_ROOT=
PYINT_GAMMA_ENV_SCRIPT=
PYINT_DEFAULT_TIMEOUT_SECONDS=43200
PYINT_SMOKE_TEST_ENABLED=false
PAIRING_GAMMA_ENABLED=false
PAIRING_GAMMA_WORK_ROOT=
PAIRING_GAMMA_TEMPLATE_ROOT=
PAIRING_GAMMA_TIMEOUT_SECONDS=7200
```
默认策略建议:
- `PYINT_WSL_DISTRO` 为空时,默认取 `ISCE2_WSL_DISTRO`
- `PYINT_WSL_PYTHON` 为空时,默认取 `ISCE2_PYTHON`
- `PYINT_APP_SCRIPT` 指向 `pyintApp.py`
- `PYINT_WORK_ROOT` / `PAIRING_GAMMA_WORK_ROOT` 使用系统托管目录,不直接让用户任意指定
### 6.3 不建议写入设计或配置的内容
- 管理员明文密码
- ASF/GACOS 邮箱密码
- WSL sudo 密码
这些信息如确需使用,也应通过运行时安全注入或机器本地安全配置处理,不写入仓库文档。
### 6.4 管理与治理策略
建议增加以下治理规则:
- 所有 PyINT/Gamma 工作目录按 `run_key``network_run_id` 分目录
- 所有运行都必须写运行摘要 JSON
- 所有正式产物必须进入统一结果发布目录
- 中间工作区可按保留策略定期清理
- 清理动作仅允许管理员执行
## 7. 数据库与数据库自维护策略
### 7.1 一期结论
一期建议:
- `PyINT` 生产引擎接入不强制改库
- `Gamma` 精配对接入不强制改库
- 优先复用现有 run/edge JSON 元数据承载扩展信息
### 7.2 二期改库触发条件
当满足以下任意条件时,再进入改库:
- 需要独立查询 Gamma 精配对运行历史
- 需要单独统计 Gamma 精配对失败率
- 需要把精配对资产纳入长期运维对象
- 需要做更细粒度的后台管理界面
### 7.3 改库时的落地方式
如果二期改库,必须沿用现有数据库自维护机制:
1.`backend/migrations/` 新增 SQL 迁移文件,例如 `007_pyint_gamma_integration.sql`
2.`backend/app/db_maintenance.py``MIGRATION_FILES` 中追加文件名
3.`ensure_database_ready()` 在启动时自动执行迁移
约束:
- 不修改既有字段语义
- 不破坏现有 `pairing_metric_cache` / `pairing_network_*` 查询逻辑
- 迁移必须支持重复执行幂等
## 8. 运维自检与健康检查设计
### 8.1 设计原则
运维自检页继续只做“状态观察”,不做主操作入口。
PyINT/Gamma 的正式操作入口放在:
- 生产页
- 配对规划页
### 8.2 健康检查应新增的内容
建议在引擎可用性检查中加入 PyINT 项:
- `PYINT_ENABLED`
- WSL distro 可访问
- WSL Python 可执行
- `PYINT_HOME` 存在
- `pyintApp.py` 存在
- `GAMMA_ENV_SCRIPT` 可 source
- 关键命令如 `base_calc` 可执行
- 模板目录可读
- 工作目录可写
- DEM 根目录可读
### 8.3 健康页展示策略
不建议在 `HealthCheckPanel.jsx` 再新增一大块复杂操作区。
建议只保留两类展示:
1. 在现有 `D-InSAR 引擎` 卡片中自然显示 `PyINT`
2. 在健康详情或备注中显示 PyINT/Gamma 的简要检查摘要
不建议:
- 在健康页提供精配对执行按钮
- 在健康页提供模板编辑入口
- 在健康页堆叠大量结果目录说明
### 8.4 运维修复入口位置
- 引擎级问题:在生产页提示不可用原因
- 配对级问题:在配对规划页处理
- 只有“环境诊断/烟测”可以保留在运维页
## 9. 后端接口设计
### 9.1 生产接口
现有 `/dinsar-production/engines``/dinsar-production/run` 可继续复用。
需要做的只是:
- 在引擎注册表中加入 `pyint`
- `list_engines()` 自动返回 PyINT
- `submit_run()` 允许 `engine_code=pyint`
### 9.2 配对接口
建议新增以下接口:
- `POST /pairing/refine-gamma`
- 输入:`network_run_id` 或明确场景列表
- 输出:新的精配对 `network_run_id`、摘要、警告、产物位置
- `GET /pairing/networks/{network_run_id}`
- 继续复用现有接口查看粗配对/精配对网络详情
- 可选:`GET /pairing/refine-gamma/{network_run_id}/artifacts`
- 用于查看 artifact 摘要,不建议一期必做
### 9.3 管理接口
建议增加一个轻量管理接口用于 PyINT/Gamma 环境烟测,例如:
- `POST /dinsar-production/engines/pyint/smoke-check`
用途仅限管理员环境校验,不参与正式生产提交。
## 10. 前端入口与交互布局
### 10.1 生产页
位置:`frontend/src/DinsarProductionPanel.jsx`
建议改动:
- 新增 `PyINT` 引擎卡片
- 显示 PyINT 可用性状态
- 根据 profile 展示少量必要参数
- 保留当前“根目录 + 参数 + 提交任务”交互,不新造独立页面
### 10.2 配对规划页
位置:`frontend/src/panels/PairPlanningPanel.jsx`
建议新增一个独立区域:
- 标题:`Gamma 精配对`
- 放置位置:`配对基础` 卡片下方,`结果与刷新` 卡片上方
该区域建议包含:
- 粗配对网络摘要
- 发起 Gamma 精配对按钮
- 精配对结果摘要
- 粗配对 / 精配对差异提示
- 选择采用哪一版网络继续生产
不建议把精配对塞进现有健康检查页。
### 10.3 健康检查页
位置:`frontend/src/HealthCheckPanel.jsx`
建议只做最小改动:
-`D-InSAR 引擎` 卡片中自动出现 `PyINT`
- 如需要,增加一条 PyINT/Gamma 环境说明
不增加复杂控制区,避免界面继续变重。
## 11. 涉及改动位置
### 11.1 后端
- `backend/app/dinsar_engines/registry.py`
- `backend/app/dinsar_engines/pyint_engine.py` 新增
- `backend/app/services/pyint_service.py` 新增
- `backend/app/pyint_pipeline/run_lt1_pyint_pipeline.py` 新增
- `backend/app/routers/dinsar_production.py`
- `backend/app/routers/pairing.py`
- `backend/app/services/health_service.py`
- `backend/app/config.py`
- `.env.example`
### 11.2 前端
- `frontend/src/DinsarProductionPanel.jsx`
- `frontend/src/panels/PairPlanningPanel.jsx`
- `frontend/src/HealthCheckPanel.jsx`
- `frontend/src/api/dinsarProduction.js`
- `frontend/src/api/pairing.js`
### 11.3 数据库
一期可不改。
二期若改,涉及:
- `backend/migrations/007_pyint_gamma_integration.sql` 新增
- `backend/app/db_maintenance.py`
## 12. 分阶段实施建议
### Phase 1: PyINT 引擎接入
- 新增 `pyint_engine`
- 完成 WSL 可用性检查
- 完成模板生成与工作目录治理
- 完成生产页引擎选择
- 完成结果归一化与目录扫描兼容
### Phase 2: Gamma 精配对 MVP
- 新增 `/pairing/refine-gamma`
- 基于现有 `network_run_id` 做精化
- 精配对结果复用现有 network run / edge 模型表达
- 前端在配对规划页增加精配对区块
### Phase 3: 运维与治理补齐
- 增加烟测接口
- 增加工作区清理策略
- 增加 artifact 摘要与失败类型归档
### Phase 4: 二期结构化增强
- 若业务确认需要,再加数据库迁移
- 把精配对历史与资产纳入更细粒度可检索对象
## 13. 风险与规避
### 13.1 PyINT 代码稳定性
风险:
- 模板字段和脚本依赖较多
- 对目录命名和环境变量较敏感
规避:
- 不做深度 import 复用
- 使用受控包装脚本
- 限制一期只开放一个稳定 profile
### 13.2 WSL 与路径问题
风险:
- Windows 路径和 WSL 路径混用
- 工作区权限与可写性问题
规避:
- 所有路径统一通过适配层转换
- 工作目录和模板目录由系统托管
### 13.3 配对语义污染
风险:
- 把 Gamma 垂直基线直接混写进现有粗配对缓存字段
规避:
- 明确不覆盖 `pairing_metric_cache` 语义
- 精配对结果单独落在网络运行元数据中
### 13.4 前端继续膨胀
风险:
- 把运维、配对、生产操作继续堆到健康检查页
规避:
- 健康页只显示状态
- 生产操作只放生产页
- 配对操作只放配对规划页
## 14. 最终建议
建议按以下判断执行:
- `PyINT` 生产引擎接入:必要,且应尽快按现有多引擎架构落地。
- `Gamma` 精配对接入:可行,但应作为“粗配对之后的精化层”落地。
- 数据库:一期不强制改库;二期若需更强管理能力,再走数据库自维护迁移。
- 运维自检:只加状态,不加大块操作区。
- 前端入口:生产页接 `PyINT`,配对规划页接 `Gamma 精配对`
@@ -0,0 +1,554 @@
# PyINT 输入资产适配设计
**日期**: 2026-04-19
**状态**: 总体设计
**范围**: `Task_*` 路径适配、PyINT DEM 管理、LT-1 精密轨道治理、Gamma 配对前置条件、运维自检与前端入口
## 1. 结论
本次设计的核心结论如下:
1. 用户侧继续沿用现有的 `Task_*` 输入模式,不要求手工准备原生 PyINT 项目目录,也不允许直接把任意外部路径当作长期运行依赖。
2. 需要在现有 `pyint_engine -> run_lt1_pyint_pipeline.py` 之间补一层“输入资产适配层”,把 `Task_*`、DEM、精密轨道统一解析为系统托管的运行输入。
3. DEM 可以在一期做到“系统托管且真实参与计算”,推荐优先走“本地 FABDEM/DEM 瓦片源 + PyINT 本地生成 DEM 产物”的方案,而不是直接复用 ISCE2 的 `.wgs84` 成品 DEM。
4. LT-1 精密轨道在当前 PyINT 原生 LT-1 导入链路里,还没有现成的“接入系统轨道池并直接参与计算”的钩子。一期先做“治理级校验 + 按任务解析 + 随跑记录 + 可选准入阻断”,二期再补“真正参与 PyINT/Gamma 计算”的桥接。
5. 一期不必改数据库结构,先把输入资产记录写入 `.dinsar_run.json``pyint_run_summary.json` 和结果 manifest 的扩展摘要。二期只有在需要按 DEM/轨道版本检索历史时才改库,并且必须走现有数据库自维护迁移机制。
6. 前端主入口应放在现有 D-InSAR 生产面板的 PyINT 引擎区域;运维自检面板只保留状态摘要,不再堆叠新的操作区。
## 2. 现状与缺口
### 2.1 已经具备的部分
- `PyINT` 代码已经收编到仓库内 `third_party/PyINT`,不再依赖仓库外绝对路径。
- 当前后端已经支持:
- `root_dir` 为单个任务目录,或为包含多个 `Task_*` 子目录的父目录
- 对每个任务递归发现 `master/``slave/` 下的 `LT1*.tar.gz`
- 自动生成 `ifgram_list.txt`
- 自动生成 PyINT template
-`backend/runtime/pyint_work` 下构造 PyINT 工作区并调用 `pyintApp.py`
- 当前系统已有成型的精轨治理链路:
- `MONITOR_ORBIT_DIR` 作为源目录
- `ORBIT_POOL_ENVI` 作为 LT-1 `.txt` 精轨池
- `ORBIT_POOL_ISCE2` 作为 ISCE2 `.xml` 精轨池
- `orbit_converter.py` 已支持同步、修复、隔离和一致性检查
- 当前系统已有成型的健康检查和目录治理链路:
- `health_service.py`
- `root_registry_service.py`
- 结果目录扫描和 manifest catalog
### 2.2 目前还没有解决的部分
- 当前 PyINT 集成只解决了“`Task_*` 到 PyINT 工作区”的映射,没有解决“系统托管 DEM / 系统托管精轨资产如何进入 PyINT”。
- 当前 `PYINT_DEM_ROOT` 只是 PyINT 的运行目录或缓存目录,不等价于“系统已经为本次任务解析好了 DEM 输入策略”。
- 当前 LT-1 PyINT 导入脚本并没有直接消费系统里的 `LT1*_GpsData_GAS_C_YYYYMMDD.txt` 精轨池。
- 当前前端也没有给 PyINT 提供“提交前资产预检/预览”的位置。
### 2.3 一个必须明确的现实约束
当前 vendored `PyINT` 的 LT-1 流程里:
- DEM 侧已有明确入口,`makedem_pyint.py` 可以走本地 `fabdem_dir` 或 OpenTopography。
- 精轨侧对 LT-1 没有现成的“使用系统 `.txt` 精轨池”的显式接口,现有 LT-1 导入脚本更接近“从压缩包和 XML 元数据生成 SLC 参数”。
因此本方案必须分两层描述精轨:
1. 治理层接入:系统知道本次任务应该使用哪份精轨,能阻断缺失任务,能把依赖记录下来。
2. 计算层接入:该精轨是否真的被 PyINT/Gamma 的 LT-1 导入过程消费。
一期只能承诺第一层,第二层需要专门桥接。
## 3. 总体方案
### 3.1 新增一层输入资产适配服务
建议在 `pyint_service.py` 旁边新增或内聚出一层输入资产适配职责,例如:
- `resolve_pyint_tasks(root_dir)`
- `resolve_pyint_dem_asset(task_context)`
- `resolve_pyint_orbit_assets(task_context)`
- `materialize_pyint_input_assets(run_context)`
- `build_pyint_input_preview(root_dir)`
其职责不是替代 PyINT,而是在系统生产语义和 PyINT 原生语义之间做转换。
### 3.2 总体执行链路
建议链路如下:
`前端生产面板 root_dir`
-> `validate_pyint_root_dir()`
-> `PyINT 输入资产适配层`
-> `每个 Task_* 解析任务身份、DEM、精轨`
-> `运行目录 materialize`
-> `run_lt1_pyint_pipeline.py`
-> `PyINT / Gamma`
-> `pyint_run_summary.json + .dinsar_run.json`
-> `结果发布 / catalog`
### 3.3 不再要求用户准备 PyINT 原生目录
用户仍然只需要提供:
- 单个 `Task_YYYYMMDD_YYYYMMDD`
- 或者一个包含多个 `Task_*` 的批次根目录
系统内部自行生成:
- `project_name`
- `template`
- `DOWNLOAD/`
- `ifgram_list.txt`
- `input_assets/`
- `native output`
这保证 PyINT 继续是“受控执行器”,不是“要求用户手工维护目录结构的第二套系统”。
## 4. 与现有 `Task_*` 路径的配合方式
### 4.1 用户输入模式
沿用当前模式,不新增新的路径输入方式:
- 模式 A:直接选一个 `Task_*`
- 模式 B:选一个包含多个 `Task_*` 的父目录
任务目录仍要求至少满足:
- `master/`
- `slave/`
- 目录下可递归发现 `LT1*.tar.gz`
可选但推荐继续保留:
- `.dinsar_pair.json`
### 4.2 任务解析规则
建议继续沿用当前逻辑,并把它明确固化为正式约束:
1. `Task_*` 是业务输入根,不是 PyINT 工作区。
2. `master/``slave/` 下面允许多层子目录,但最终必须能发现原始压缩包。
3. 任务身份优先从 `.dinsar_pair.json` 读取。
4. 缺失时再从任务目录名和压缩包文件名推导:
- `task_alias`
- `pair_key`
- `master_date`
- `slave_date`
### 4.3 运行期目录建议
建议把每次运行的托管结构固定为:
```text
backend/runtime/pyint_work/<pair_key>/<run_key>/
input_assets/
task_manifest.json
orbits/
dem/
<project_name>/
DOWNLOAD/
ifgram_list.txt
...
backend/runtime/pyint_templates/<pair_key>/<run_key>/
<project_name>.template
backend/runtime/pyint_output/<pair_key>/<run_key>/native/
pyint_run_summary.json
.dinsar_run.json
ifgrams/
...
```
原则:
- 原始 `Task_*` 只读,不回写。
- 每次运行独立目录,避免不同 run 相互污染。
- DEM、轨道、任务解析结果要在 `input_assets/` 下留痕。
## 5. DEM 方案
### 5.1 不建议直接把 ISCE2 DEM 方案硬套给 PyINT
当前系统已有 `ISCE2_DEM_PATH`,它对应的是 ISCE2 直接消费的成品 DEM。
但当前 PyINT 的 DEM 处理逻辑更接近:
- 先根据 master SLC 范围解析 DEM 覆盖区域
- 再通过 `makedem_pyint.py`
- 结合 `fabdem_dir` 或 OpenTopography
-`DEMDIR` 下生成 PyINT / Gamma 所需的 DEM 产物
因此一期不建议把 `PYINT_DEM_SOURCE` 简单绑定为 `ISCE2_DEM_PATH`
### 5.2 推荐的 DEM 分层
建议把 PyINT 的 DEM 分成三层:
1. DEM 源
- 本地 FABDEM/DEM 瓦片根目录
- 或 OpenTopography 在线源
2. DEM 运行缓存
- 即当前 `PYINT_DEM_ROOT`
3. 本次任务解析后的 DEM 产物
- 位于 `PYINT_DEM_ROOT/<project_name>/...`
-`generate_rdc_dem.py``geocode_gamma.py` 等步骤消费
### 5.3 推荐配置
建议新增或明确以下配置:
```ini
PYINT_DEM_MODE=local_fabdem|opentopo
PYINT_FABDEM_ROOT=
PYINT_OPENTOPO_DEM_TYPE=SRTMGL1
PYINT_DEM_ROOT=
PYINT_DEM_STRICT=true
```
说明:
- `PYINT_DEM_MODE=local_fabdem` 为推荐默认值。
- `PYINT_FABDEM_ROOT` 指向本机统一维护的 FABDEM/DEM 瓦片目录。
- `PYINT_DEM_ROOT` 继续作为 PyINT DEM 运行缓存根。
- 若后续确实验证可直接复用某个成品 DEM,再新增单独模式,不要和一期混在一起。
### 5.4 运行时行为
当用户提交 PyINT 任务时:
1. 适配层先解析 DEM 模式。
2. 若为 `local_fabdem`
-`fabdem_dir` 写入本次运行生成的 template
- `DEMDIR` 指向本次受控缓存根
3. 若为 `opentopo`
- 只在运行时注入 API key,不把敏感值写入仓库文档或 `.env.example`
4. 运行完成后记录:
- DEM 模式
- DEM 源根目录
- 生成产物目录
- 关键 DEM 文件是否生成成功
### 5.5 DEM 与前端的关系
不建议在前端让用户手工输入单次 DEM 路径。
推荐做法是:
- 前端只展示“当前 DEM 策略”
- 例如:
- `本地 FABDEM`
- `OpenTopography`
- `未配置`
- 如果 DEM 不可用,则在 PyINT 引擎区阻断提交
## 6. 精密轨道方案
### 6.1 一期目标不是“假装已经真正进计算”
当前 LT-1 PyINT 原生脚本没有明确消费系统精轨池的接口,因此一期要把目标定义准确:
- 系统必须能按任务解析 master/slave 对应的精轨文件
- 系统必须能知道精轨是否缺失
- 系统必须把这次运行实际匹配到的精轨记录下来
- 系统必须能根据策略决定“警告放行”还是“阻断提交”
但不能在未完成桥接前,对外宣称“精轨已经真实参与 LT-1 PyINT 计算”。
### 6.2 一期建议的精轨策略
建议精轨配置分为:
```ini
PYINT_ORBIT_POLICY=validate_only|require_txt|stage_txt
PYINT_ORBIT_POOL_TXT=
PYINT_RECORD_INPUT_ASSETS=true
```
默认建议:
- `PYINT_ORBIT_POOL_TXT` 为空时默认继承 `ORBIT_POOL_ENVI`
- `PYINT_ORBIT_POLICY=require_txt`
三种策略含义:
- `validate_only`
- 找得到则记录
- 找不到只警告
- `require_txt`
- 找不到直接阻断运行
- `stage_txt`
- 除了要求存在,还把匹配到的轨道文件复制或硬链接到本次运行目录
### 6.3 轨道解析规则
对每个 task,按如下顺序解析:
1.`.dinsar_pair.json`、原始压缩包文件名或元数据确定:
- 卫星 `LT1A/LT1B`
- `master_date`
- `slave_date`
2. 到系统轨道池中查找:
- `LT1A_GpsData_GAS_C_YYYYMMDD.txt`
- `LT1B_GpsData_GAS_C_YYYYMMDD.txt`
3. 分别解析 master/slave 结果
4. 形成本次运行的轨道摘要
### 6.4 与现有轨道治理链路的关系
PyINT 不应新建第二套精轨目录。
应直接复用现有治理链路:
- 源目录:`MONITOR_ORBIT_DIR`
- 运行池:`ORBIT_POOL_ENVI`
- 一致性修复:`orbit_converter.py`
- 健康检查:`health_service.py`
也就是说:
- PyINT 的精轨输入来源仍应是系统托管的轨道池
- 不是让用户每次在前端再手工填一条轨道路径
### 6.5 一期的落地方式
建议每次运行都在 `input_assets/orbits/` 下落盘一个轨道摘要,例如:
```json
{
"policy": "require_txt",
"pool_root": "D:\\orbit_pools\\envi",
"master": {
"date": "20250112",
"satellite": "LT1A",
"path": "D:\\orbit_pools\\envi\\LT1A\\LT1A_GpsData_GAS_C_20250112.txt",
"staged_path": "...\\input_assets\\orbits\\LT1A_GpsData_GAS_C_20250112.txt",
"resolved": true
},
"slave": {
"date": "20250309",
"satellite": "LT1A",
"path": "D:\\orbit_pools\\envi\\LT1A\\LT1A_GpsData_GAS_C_20250309.txt",
"staged_path": "...\\input_assets\\orbits\\LT1A_GpsData_GAS_C_20250309.txt",
"resolved": true
}
}
```
这一步先解决:
- 任务是否可跑
- 运行可追溯
- 后续桥接可复用
### 6.6 二期的“真正参与计算”桥接
如果要让系统精轨真实参与 LT-1 PyINT/Gamma 计算,建议单独做一个技术 Spike,候选方向有两个:
1. 修改或包装 PyINT 的 LT-1 导入步骤
-`down2slc_LT1.py` / `LT1_import_SLC_from_zipfiles1` 前后插入系统精轨桥接步骤
2. 在 PyINT 前增加一个 LT-1 预处理适配器
- 先把系统精轨和原始场景解析成更稳定的中间输入
- 再把中间输入交给 PyINT 后续流程
建议优先方向是第 1 种,因为它改动面更小。
但在明确 Gamma 对 LT-1 外部精轨的实际消费方式之前,不建议直接承诺实现周期。
## 7. Gamma 配对集成的关系
`select_pairs.py` / Gamma 精配对本身是可集成的,但它不应绕开输入资产治理。
建议关系如下:
1. 生产引擎侧先把 PyINT 的 DEM / 轨道输入治理打通。
2. Gamma 精配对继续作为“配对规划之后的精化步骤”存在。
3. 精配对任务默认继承同一套:
- WSL 环境
- PyINT vendored 代码
- 轨道治理配置
4. 前端入口仍放在 `PairPlanningPanel`,不放进运维自检。
换句话说:
- “生产引擎接入”是必要前置。
- “Gamma 配对接入”是可行的,但它应复用同一套输入资产治理,而不是另起一套路径和配置。
## 8. 运行元数据、结果治理与数据库策略
### 8.1 一期不改数据库主结构
一期建议不改库,原因是:
- 当前已有 `.dinsar_run.json`
- 当前已有 `pyint_run_summary.json`
- 当前已有结果 manifest / catalog
这些已经足够承载输入资产摘要。
### 8.2 一期建议记录的内容
建议把以下信息写入运行元数据:
- `input_assets.task_source`
- `root_dir`
- `task_dir`
- `archives.master[]`
- `archives.slave[]`
- `input_assets.dem`
- `mode`
- `source_root`
- `cache_root`
- `resolved_output_dir`
- `key_outputs`
- `input_assets.orbits`
- `policy`
- `pool_root`
- `master`
- `slave`
- `stage_mode`
### 8.3 二期改库触发条件
只有出现以下需求时再改库:
- 需要按 DEM 版本检索历史 PyINT 结果
- 需要按轨道版本检索历史 PyINT 结果
- 需要统计“某批结果使用了哪套轨道/DEM”
- 需要把 PyINT 输入资产做成后台长期查询对象
### 8.4 如果改库,必须走现有数据库自维护机制
如果进入二期改库,必须:
1.`backend/migrations/` 新增 SQL 迁移文件
2.`backend/app/db_maintenance.py` 的迁移列表中登记
3. 让现有数据库自维护机制自动执行
不允许手工改表绕过现有机制。
## 9. 健康检查、接口与前端位置
### 9.1 运维自检面板只做状态,不做主操作入口
当前健康页已经比较重,因此新增内容应控制在“状态摘要”层面:
- `PyINT enabled`
- `PyINT home`
- `PyINT WSL`
- `PyINT DEM strategy`
- `PyINT orbit policy`
- `PYINT_FABDEM_ROOT` 可读
- `PYINT_ORBIT_POOL_TXT` / `ORBIT_POOL_ENVI` 可读
不建议新增:
- 手工触发 PyINT 任务按钮
- 手工填 DEM 路径
- 手工填轨道路径
### 9.2 生产页的建议位置
`DinsarProductionPanel` 的 PyINT 引擎区域增加“输入资产预检摘要”,展示:
- 识别到的任务数
- 无效任务数
- DEM 策略
- 轨道策略
- 已解析轨道数量
- 缺失轨道数量
- 是否允许提交
### 9.3 建议新增一个轻量预检接口
建议新增:
- `POST /dinsar-production/engines/pyint/preview-input-assets`
返回:
- 任务解析结果
- DEM 配置状态
- 轨道解析状态
- 阻断原因
- 警告列表
这样前端可以在正式提交前给出明确反馈,而不是等任务进入队列后才失败。
### 9.4 PairPlanning 页的位置
Gamma 精配对仍建议放在 `PairPlanningPanel`
- 先显示已有粗配对网络
- 再提供 Gamma 精配对入口
- 不把它塞回健康检查页
## 10. 推荐实施顺序
### Phase 1:输入资产适配层
- 固化 `Task_*` 路径解析规则
- 新增输入资产预检模型
- 生成 `task_manifest.json`
- 生成 `input_assets/orbits/``input_assets/dem/` 目录
### Phase 2DEM 正式接入
- 增加 `PYINT_DEM_MODE`
- 增加 `PYINT_FABDEM_ROOT`
- 在 template 生成时注入 `fabdem_dir` / `opentopo_*`
- 把 DEM 解析摘要写入 run metadata
### Phase 3:精轨治理接入
- 增加 `PYINT_ORBIT_POLICY`
- 复用 `ORBIT_POOL_ENVI`
- 运行前做 master/slave 精轨解析
- 缺失时按策略阻断
- 把轨道文件 staging 到运行目录
### Phase 4:前端预检入口
- 生产面板显示资产预检摘要
- 健康页只增加状态项
### Phase 5:精轨计算桥接 Spike
- 研究 LT-1 PyINT/Gamma 当前导入链路如何真正消费外部精轨
- 决定是补包装步骤还是补脚本修改
### Phase 6Gamma 精配对集成
- 在配对规划页复用同一套 PyINT/Gamma 环境和资产治理策略
## 11. 最终建议
对于你提出的三个问题,建议明确回答如下:
1. `Task_*` 路径怎么配合
继续沿用现在的任务目录,不改用户输入方式;系统内部新增适配层把任务目录转换为 PyINT 工作区。
2. DEM 怎么处理
一期就做系统托管,推荐以本地 FABDEM/DEM 源目录为标准输入,由 PyINT 在受控 `DEMDIR` 下生成本次任务真正使用的 DEM 产物。
3. 精密轨道怎么处理
一期先接入系统精轨池做校验、阻断、记录和 staging;二期再补“真实参与 LT-1 PyINT/Gamma 计算”的桥接。当前实现还不能直接把这一步视为已经完成。
基于当前代码现状,最稳妥的方向不是“删掉 Task_* 模式重新发明一套 PyINT 路径”,而是“把 Task_* 保留为业务输入,把 DEM/精轨补成系统托管资产适配层”。
## 补充:现有 DEM 复用实现(2026-04-19
当前代码已补充 `PYINT_DEM_MODE=prepared_file`,用于复用系统现有 DEM 资产。
- `PYINT_PREPARED_DEM_PATH` 可显式指定现有 DEM 基础文件。
- 若该值为空,运行时会按顺序回退解析 `ISCE2_DEM_PATH``IDL_DINSAR_DEM_BASE_FILE`
- 如果目标文件同名存在 `.par`,则视为现成的 Gamma DEM,直接写入 PyINT 模板中的 `DEM=...`
- 如果目标文件没有 `.par`,但同名存在 `.xml``.hdr``.vrt`,则视为系统现有源 DEM。
- 对“系统现有源 DEM”,PyINT 在 `makedem_pyint.py` 中会根据 `master``SLC_par` 覆盖范围先裁剪局部窗口,再转换为本次任务使用的 Gamma DEM。
- 这样可以复用系统已经维护的中国区或全局 DEM,不必强制切回 FABDEM 或重新在线下载。
这个实现的约束也需要明确:
- 现有源 DEM 仍必须是可被 GDAL 打开的本地文件。
- 运行环境里仍需要 `gdal_translate` 可用,因为裁剪发生在 WSL/PyINT 侧。
- 该模式的本质不是“直接把 ISCE2 DEM 原样交给 Gamma”,而是“把系统现有 DEM 当作受控源,再为每次 PyINT 任务生成 Gamma 可消费的局部 DEM 产物”。
@@ -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,405 @@
# PyINT LT-1 精密轨道桥接设计
**日期**: 2026-04-19
**状态**: 方案设计
**范围**: LT-1 精密轨道真正参与 PyINT / Gamma 计算、与现有 `Task_*` 输入模式协同、前后端与运维落点、分阶段实施
## 1. 结论
当前仓库已经完成了 LT-1 轨道 TXT 的治理级接入,但还没有完成“精密轨道真实参与 PyINT / Gamma 计算”这一层。
本次设计的核心结论如下:
1. 不能把系统轨道池里的 `LT1*_GpsData_GAS_C_YYYYMMDD.txt` 简单当成 `par_LT1_SLC` 的直接输入,因为当前 PyINT / Gamma 的 LT-1 导入链并没有暴露这样的接口。
2. 正确的桥接点是 LT-1 导入完成后生成的 `.slc.par` / `.slc.update.par` 里的 `state_vector_*` 段,而不是当前外层 `run_lt1_pyint_pipeline.py` 的任务参数层。
3. 推荐方案是在现有 Windows 侧轨道治理不变的前提下,在 WSL 侧新增一个 LT-1 精轨桥接 helper,把系统选中的精轨 TXT 重采样到 Gamma 参数文件已有的时间栅格,再回写 `.slc.par`
4. 桥接动作必须发生在 LT-1 导入之后、DEM / coreg / 干涉处理之前;只做“提交前预检”或“运行记录留痕”是不够的。
5. 一期先不改数据库,先把桥接结果写进 `input_assets``pyint_run_summary.json`、结果 manifest 和运行日志;只有在后续确实需要跨运行检索、统计、追责时,再通过现有数据库自维护机制补迁移。
## 2. 现状与依据
### 2.1 当前本地代码链路
现有 vendored PyINT 的 LT-1 流程为:
`pyintApp.py`
-> `down2slc_LT1_all.py`
-> `down2slc_LT1.py``down2slc_cat_LT1.py`
-> `LT1_import_SLC_from_zipfiles1`
-> `par_LT1_SLC` / `par_LT1_SLC_YSLi`
-> 生成 `.slc.par` / `.slc.update.par`
已确认的关键事实:
- [pyintApp.py](/D:/Code/Insar_management_system_v2/third_party/PyINT/pyint/pyintApp.py) 会先执行 LT-1 `raw2slc`,然后再进入 DEM、coreg、差分干涉。
- [down2slc_LT1.py](/D:/Code/Insar_management_system_v2/third_party/PyINT/pyint/down2slc_LT1.py) 与 [down2slc_cat_LT1.py](/D:/Code/Insar_management_system_v2/third_party/PyINT/pyint/down2slc_cat_LT1.py) 是当前 LT-1 Python 入口。
- [LT1_import_SLC_from_zipfiles1](/D:/Code/Insar_management_system_v2/third_party/PyINT/pyint/LT1_import_SLC_from_zipfiles1) 已经显式处理 `state_vector_*`,说明轨道状态向量确实是 LT-1 导入链中的有效控制点。
- [20210110.slc.par](/D:/Code/Insar_management_system_v2/third_party/PyINT/pyint/20210110.slc.par) 展示了 Gamma 参数文件中的状态向量布局,包括:
- `number_of_state_vectors`
- `time_of_first_state_vector`
- `state_vector_interval`
- `state_vector_position_i`
- `state_vector_velocity_i`
### 2.2 当前系统已有能力
仓库已经具备以下基础:
- [pyint_input_assets_service.py](/D:/Code/Insar_management_system_v2/backend/app/services/pyint_input_assets_service.py) 已能从 `ORBIT_POOL_ENVI` / `PYINT_ORBIT_POOL_TXT` 解析 master/slave 对应的 LT-1 精轨 TXT。
- [run_lt1_pyint_pipeline.py](/D:/Code/Insar_management_system_v2/backend/app/pyint_pipeline/run_lt1_pyint_pipeline.py) 已能把 `Task_*` 目录物化成 PyINT 工作区,并记录 `orbit_policy``input_assets`
- [DinsarProductionPanel.jsx](/D:/Code/Insar_management_system_v2/frontend/src/DinsarProductionPanel.jsx) 已经有 PyINT 输入资产预检入口,能够把“轨道是否齐全”提前暴露给用户。
- ISCE2 侧已经有 LT-1 轨道 TXT 解析链,可复用 [convert_lt1_orbit_to_isce_xml.py](/D:/Code/Insar_management_system_v2/backend/app/isce2_pipeline/convert_lt1_orbit_to_isce_xml.py) 与 [lt1_input_resolver.py](/D:/Code/Insar_management_system_v2/backend/app/isce2_pipeline/lt1_input_resolver.py) 中的 `parse_orbit_file`、时间窗口解析等逻辑。
### 2.3 Gamma 官方文档给出的关键约束
用户提供的 Gamma 官方文档是:
- <https://www.gamma-rs.ch/uploads/media/2023-1_TR_China_LT1_Support_in_GAMMA.pdf>
其中与本设计直接相关的结论有两点:
1. 在 LT-1 repeat-pass DInSAR 流程中,Gamma 文档明确说明,`par_LT1_SLC` 导入后需要立即检查并过滤 orbit state vectors,并使用 `ORB_filt_spline.py` 做校验。
2. 在 LT-1 tandem single-pass 流程中,文档同样建议“读入数据后立刻检查/过滤状态向量”,以确保后续 MLI 参数和几何步骤使用的是修正后的状态向量。
这意味着桥接点必须放在“LT-1 导入完成之后立刻执行”,而不是只在外层运行摘要里记录轨道来源。
## 3. 当前缺口
当前实现还缺以下一层:
1. 系统已经知道“这次任务应该用哪份精轨 TXT”,但 PyINT / Gamma 还不知道。
2. 预检面板只能阻断“轨道缺失”的任务,不能保证“轨道已进入计算”。
3. 只改外层 `run_lt1_pyint_pipeline.py` 不够,因为 PyINT 内部会自己完成 `raw2slc -> dem -> coreg` 连续流程,桥接必须插在内部 `raw2slc` 之后。
4. `cat` 场景不能只更新单个 `.slc.par`。当前 [down2slc_cat_LT1.py](/D:/Code/Insar_management_system_v2/third_party/PyINT/pyint/down2slc_cat_LT1.py) 最终拼接依赖 `*.slc.update.par`,所以方案必须覆盖:
- 每个分片导入后的参数文件
- 最终拼接得到的 `<date>.slc.par`
## 4. 目标与非目标
### 4.1 目标
- 保留当前 `Task_*` 输入模式,不要求用户维护第二套 PyINT 原生目录。
- 让 LT-1 精轨 TXT 真正参与 PyINT / Gamma 计算,而不是只做治理留痕。
- 同时覆盖单场景和多分片 `cat` 场景。
- 与现有 DEM 策略、结果目录、运行日志、预检面板兼容。
- 为后续 Gamma 配对集成保留复用路径。
### 4.2 非目标
- 一期不修改数据库主结构。
- 一期不在运维自检页新增复杂操作区。
- 一期不承诺完成 LT1A/LT1B tandem 单通道单程干涉生产链,只保证当前 repeat-pass PyINT 流程的精轨桥接。
- 一期不让用户在前端手工输入单次轨道路径。
## 5. 推荐总体方案
### 5.1 分层思路
推荐把方案拆成“控制面”和“计算面”两层。
#### A. 控制面,继续由现有后端负责
控制面继续沿用现有资产治理链路:
-`Task_*` 解析 master/slave 的卫星与日期
-`PYINT_ORBIT_POOL_TXT``ORBIT_POOL_ENVI` 定位精轨 TXT
-`input_assets/orbits/` 下留痕
- 在预检接口中返回“是否可提交”
这部分由现有 [pyint_input_assets_service.py](/D:/Code/Insar_management_system_v2/backend/app/services/pyint_input_assets_service.py) 继续承担。
#### B. 计算面,新增 WSL 侧精轨桥接 helper
新增一个 helper,例如:
- `backend/app/pyint_pipeline/apply_lt1_precise_orbit.py`
其职责是:
1. 读取当前任务已解析好的 orbit manifest / staged TXT。
2. 读取目标 `.slc.par``.slc.update.par`
3. 复用现有 LT-1 TXT 解析逻辑,解析精轨状态向量。
4. 以 Gamma 当前参数文件已有的时间栅格为目标,进行插值和回写。
5. 备份原始参数文件。
6. 可选调用 `ORB_filt_spline.py` 做二次校验或残差诊断。
7. 输出 `orbit_bridge_summary.json`
### 5.2 为什么目标时间栅格要复用 `.slc.par` 自身
推荐不要自己发明新的状态向量数量和时间间隔,而是直接复用当前 `.slc.par` 中已有的:
- `number_of_state_vectors`
- `time_of_first_state_vector`
- `state_vector_interval`
然后把系统精轨 TXT 插值到这个时间栅格上。
这样做的收益是:
- 不改变 Gamma 已经生成的参数文件结构。
- 不引入新的向量个数假设。
- 更容易和 `ORB_filt_spline.py`、后续 DEM / coreg 步骤兼容。
-`cat` 场景、已有模板和下游脚本影响最小。
### 5.3 插值策略
推荐优先使用“基于位置和速度的 Hermite 插值”,原因是 LT-1 TXT 同时提供了位置和速度。
最小实现要求如下:
- 先复用 [convert_lt1_orbit_to_isce_xml.py](/D:/Code/Insar_management_system_v2/backend/app/isce2_pipeline/convert_lt1_orbit_to_isce_xml.py) 的 `parse_orbit_file` 解析状态向量。
- 根据 `.slc.par` 的采样时间点计算目标 UTC 时间序列。
- 对目标时间序列进行状态向量重采样。
- 回写 `state_vector_position_i``state_vector_velocity_i`
如果一期为了稳妥,不想一次性引入更复杂的插值器,也可以先做:
- 线性插值作为第一落地版
- `ORB_filt_spline.py` 作为强校验
但长期建议还是切到 Hermite,以减少轨道形状失真。
## 6. 推荐挂接点
### 6.1 不推荐只改最外层 wrapper
不推荐只在 [run_lt1_pyint_pipeline.py](/D:/Code/Insar_management_system_v2/backend/app/pyint_pipeline/run_lt1_pyint_pipeline.py) 里做轨道处理,因为它在 PyINT 看来只是外层启动器,无法插入到内部 `raw2slc``makedem` 之间。
### 6.2 推荐挂接点
推荐优先修改以下 vendored Python 脚本:
- [down2slc_LT1.py](/D:/Code/Insar_management_system_v2/third_party/PyINT/pyint/down2slc_LT1.py)
- [down2slc_cat_LT1.py](/D:/Code/Insar_management_system_v2/third_party/PyINT/pyint/down2slc_cat_LT1.py)
推荐执行时机:
1. 每次 `LT1_import_SLC_from_zipfiles1` 完成后:
- 对当前生成的 `.slc.par`
- 对当前生成的 `.slc.update.par`
执行一次桥接
2. `SLC_cat_list.py` 生成最终 `<date>.slc.par` 后:
- 再对最终参数文件执行一次桥接或至少一次强校验
这样可以同时满足:
- 符合 Gamma 文档“导入后立即检查/过滤状态向量”的原则
- 覆盖单片和多分片场景
- 避免只在最终产物上补丁而遗漏拼接过程
`LT1_import_SLC_from_zipfiles1` 本身先不作为一期主改点,除非后续验证发现必须把逻辑进一步下沉到 shell 层才能完全覆盖。
## 7. 运行时流程
推荐的整体执行顺序如下:
1. 用户在生产面板选择 PyINT 引擎并填写 `root_dir`
2. 后端调用 PyINT 输入资产预检
3. 系统为每个 `Task_*` 解析:
- master/slave 日期
- master/slave 卫星
- 对应精轨 TXT
- DEM 策略
4. `run_lt1_pyint_pipeline.py` 物化:
- `input_assets/orbits/`
- `task_manifest.json`
- PyINT 工作区和模板
5. 外层 wrapper 将 orbit manifest 路径、helper 路径和桥接开关注入 WSL 环境
6. PyINT 执行 `down2slc_LT1.py` / `down2slc_cat_LT1.py`
7. 每个 LT-1 导入步骤完成后,调用 `apply_lt1_precise_orbit.py`
8. helper 回写 `.slc.par`
9. PyINT 继续执行 DEM、coreg、差分干涉、解缠、地理编码
10. 系统输出:
- `orbit_bridge_summary.json`
- `pyint_run_summary.json`
- 结果 manifest 摘要
## 8. 建议新增配置
当前已有:
```ini
PYINT_ORBIT_POLICY=require_txt
PYINT_ORBIT_POOL_TXT=
```
建议新增或明确以下配置:
```ini
PYINT_LT1_PRECISE_ORBIT_ENABLED=true
PYINT_LT1_PRECISE_ORBIT_MODE=replace_and_validate
PYINT_LT1_PRECISE_ORBIT_STRICT=true
PYINT_LT1_PRECISE_ORBIT_MARGIN_SECONDS=120
PYINT_LT1_PRECISE_ORBIT_VALIDATE_WITH_ORB_FILT=true
PYINT_LT1_PRECISE_ORBIT_BACKUP=true
```
建议含义如下:
- `PYINT_LT1_PRECISE_ORBIT_ENABLED`
- 是否启用真实桥接
- `PYINT_LT1_PRECISE_ORBIT_MODE`
- `replace_and_validate` 为推荐默认值
- 后续也可扩展 `validate_only`
- `PYINT_LT1_PRECISE_ORBIT_STRICT`
- 桥接失败时是否阻断任务
- `PYINT_LT1_PRECISE_ORBIT_MARGIN_SECONDS`
- 对场景时间窗口额外扩展的秒数
- `PYINT_LT1_PRECISE_ORBIT_VALIDATE_WITH_ORB_FILT`
- 是否调用 `ORB_filt_spline.py` 做残差校验
- `PYINT_LT1_PRECISE_ORBIT_BACKUP`
- 是否在回写前备份原始 `.slc.par`
## 9. 元数据与落盘策略
一期建议不改数据库,先把桥接痕迹记录到运行产物里。
### 9.1 `input_assets` 侧
建议在 `input_assets/orbits/` 下保留:
- 解析到的 master/slave 精轨 TXT
- `orbit_resolution.json`
- `orbit_bridge_request.json`
### 9.2 运行摘要侧
建议在 `pyint_run_summary.json` 中新增:
```json
{
"orbit_bridge": {
"enabled": true,
"mode": "replace_and_validate",
"status": "applied",
"master": {
"orbit_txt": "..."
},
"slave": {
"orbit_txt": "..."
},
"applied_files": [
{
"path": ".../20250309.slc.par",
"role": "slave",
"vector_count": 15,
"validated": true
}
]
}
}
```
### 9.3 结果 manifest 侧
结果 manifest 只保留摘要,不重复放大块明细,建议记录:
- 是否启用精轨桥接
- 桥接状态
- master/slave 轨道来源 stem
- 是否通过 `ORB_filt_spline.py` 校验
### 9.4 数据库策略
一期不改数据库。
如果后续明确需要:
- 按轨道版本检索历史运行
- 统计桥接失败原因
- 审计某次产品到底使用了哪份精轨
再通过现有 [db_maintenance.py](/D:/Code/Insar_management_system_v2/backend/app/db_maintenance.py) 机制新增迁移。
## 10. 前端与运维落点
### 10.1 前端
前端主入口继续放在现有 PyINT 生产区域,不新增独立页面。
建议在 [DinsarProductionPanel.jsx](/D:/Code/Insar_management_system_v2/frontend/src/DinsarProductionPanel.jsx) 的 PyINT 输入资产预检卡中增加两类信息:
- 全局级:
- `精轨桥接: 已启用 / 仅治理 / 未启用`
- `桥接模式`
- 任务级:
- master/slave 是否已解析精轨
- 本次是否满足真实桥接前置条件
不要让用户手工输入 orbit 路径。
### 10.2 运维自检
运维自检页不再承载新的操作区,只保留状态摘要。
建议在引擎健康或 PyINT 健康项里补充:
- `PYINT_LT1_PRECISE_ORBIT_ENABLED`
- helper 脚本是否存在
- `PYINT_ORBIT_POOL_TXT` / `ORBIT_POOL_ENVI` 是否可读
- `ORB_filt_spline.py` 是否可调用
不建议把桥接按钮堆进现有 [HealthCheckPanel.jsx](/D:/Code/Insar_management_system_v2/frontend/src/HealthCheckPanel.jsx)。
## 11. 与 Gamma 配对集成的关系
这套桥接不是只服务 D-InSAR 生产,也是在为后续 Gamma 配对打基础。
原因是:
- 如果后续要把 Gamma / PyINT 配对结果真正纳入系统,配对阶段对 baseline 和场景几何的一致性要求会更高。
- 只做“轨道存在性预检”仍然不够,仍然需要一条“导入后立即修正状态向量”的内部链路。
因此推荐把本次 helper 设计成通用能力:
- 当前用于 `pyintApp.py` 的 LT-1 `raw2slc`
- 后续也可复用于 `select_pairs.py` 前的 LT-1 导入准备
## 12. 风险与未决问题
当前仍有几项需要在实现阶段验证:
1. LT-1 TXT 的时间系统与 `.slc.par``date + seconds-of-day` 是否存在跨日边界问题。
2. `ORB_filt_spline.py` 更适合用于“替换后校验”还是“替换后再执行一次修正”,需要先做小样本验证。
3. `SLC_cat_list.py` 当前并未 vendored 到仓库中,实现阶段要进一步确认它对输入 `.par` 的依赖细节。
4. 当前 repeat-pass 流程与 LT1A/LT1B tandem single-pass 流程并不完全等价,后者需要单独设计。
5. 如果发现某些场景的 Gamma 原始导入时间栅格明显不合理,可能需要从“复用现有时间栅格”升级到“按 scene window 重新构造时间栅格”。
## 13. 分阶段实施建议
### Phase 1
- 新增 `apply_lt1_precise_orbit.py`
- 复用现有 LT-1 TXT 解析器
- 实现 `.slc.par` 读取、备份、状态向量回写
- 产出 `orbit_bridge_summary.json`
### Phase 2
- 修改 `down2slc_LT1.py``down2slc_cat_LT1.py`
- 在导入后与最终拼接后调用 helper
- 跑通单任务 smoke test
### Phase 3
- 在运行摘要和结果 manifest 中纳入桥接信息
- 在生产面板预检区域增加“精轨桥接已启用”可见性
- 在 health 中增加最小状态摘要
### Phase 4
- 用真实 LT-1 样本比较桥接前后:
- `ORB_filt_spline.py` 残差
- 后续 coreg 质量
- 干涉相位整体趋势
- 评估是否为 Gamma 配对链复用相同 helper
## 14. 最终建议
推荐按以下原则推进:
1. 继续保留现有 `Task_*` 输入模式和轨道治理链。
2. 把 LT-1 精轨接入点明确落到 `.slc.par``state_vector_*` 回写,不再停留在治理层。
3. 一期先实现“桥接 helper + vendored LT-1 raw2slc 挂接 + 运行元数据留痕”。
4. 数据库先不动,运维面板先不扩张。
5. 桥接 helper 从第一天起就按“未来可复用于 Gamma 配对”来设计接口。