概念¶
moraine 由哪些部分组成、它们怎样配合。这里的十分钟能省下翻参考手册的几小时。
一组函数,而不是一条固定的工作流¶
没有哪条工作流总能给出满意的 InSAR 结果:失相干、大气和强形变梯度总会在某处让固定的处理链失效。所以 moraine 是一组函数,每个函数实现一种技术(幅度离差指数、同质像元的统计检验、EMI 相位连接、深度学习滤波、最小费用流解缠……), 再加上围绕它们的数据基础设施。处理链由你自己组合;经过验证的示例 pipeline 是起点,不是唯一的路。
数据刻意保持简单:内存中是 numpy 或 cupy 数组,磁盘上是 zarr 数组。没有容器对象,没有工程文件;每个结果都是 任何工具都能打开的数组。
三层¶
| 层 | 命名空间 | 数据 | 一次调用处理 |
|---|---|---|---|
| API | moraine.*(import moraine as mr) |
内存中的 numpy(CPU,numba)或 cupy(GPU)数组;输出与输入同类 | 一个单元:整幅场景的一景影像或一个像对,或一块像元 / 点及其完整时间序列 |
| CLI | moraine.cli.*(import moraine.cli as mc) |
磁盘上的 zarr 数据集,可大于内存;由 moraine 自己的 worker 分块处理,CPU 上用线程,每块 GPU 一个进程 | 整个数据集 |
| 命令 | moraine COMMAND ...、moraine run FILE |
同样的 zarr 数据集 | 整个数据集,从 shell 或 pipeline 文件运行 |
CLI 函数不是 API 函数的简单封装:它把数据切成 API 函数能处理的单元,作为执行器的任务来运行(CPU 上是线程,每块 GPU 一个进程;决策 0033、0034),
再写回 zarr。每个 moraine.cli 函数都是 moraine 可执行程序的一条命令,帮助由 docstring 生成(决策 0005),
所以三层永远一致。help(mr.emi)、help(mc.emi) 和 moraine emi --help 说的是同一件事。
import moraine as mr
import moraine.cli as mc
ph = mr.emi(coh) # 内存中的一块点
mc.emi('ds/ds_can_coh.zarr', 'ds/ds_can_ph.zarr', cuda=True) # 整个数据集,在 GPU 上
栅格与点云¶
处理链里流动的数据集有两种(完整约定见数据约定,英文):
- 雷达网格上的栅格:形状
(nlines, width[, n]),方位向在前、距离向在后、堆栈维在最后。rslc 堆栈是(nlines, width, nimages)的 complex64;nan表示缺失数据。 - 选出像元(PS、DS)的点云:形状
(n_points, ...)的数组。点用网格索引gix(n_points, 2)(方位,距离) 或 hilbert 索引hix(n_points,)定位,点云按 hilbert 顺序存放,数组里相邻的点在地面上也相邻。pc-union、pc-intersect、pc-diff和pc-select-data是排好序的索引上的集合运算;ras2pc和pc2ras在两种数据之间搬运。
干涉数据是复数:像对 (ref, sec) 的干涉图是 ref * conj(sec),相位连接后的相位历史和滤波后的干涉图幅度为 1,
点云的相干性压缩存放(相干矩阵的上三角,(n_points, n_pairs)),解缠相位是 float32 弧度 (n_points, n_pairs)。
分块¶
zarr 数组按块存放,worker 并行处理各块;块的布局决定内存和速度。moraine 的约定(决策 0019)是:空间上分块,
每景影像(或每个像对)一个块,例如栅格堆栈 (lines_block, width_block, 1)、点云堆栈 (points_block, 1)。
按影像处理的步骤读整块,按空间块处理的步骤读每景影像的一块,都不需要重新分块。命令有 chunks(处理)和
out_chunks(存储)参数;块太小时间都花在调度上,太大则内存不够。栅格沿方位向而不是距离向切分。
处理链¶
示例 pipeline 实现了一条常见的处理链;每一步都是一条命令,都可以替换:
- 载入 GAMMA 结果到 zarr:去平去地形的 rslc 堆栈、坐标、视向量、元数据(01)。
- PS 候选点:幅度离差指数,以及 Noise2Fringe 滤波后干涉图的时间相干性(02)。
- DS:统计同质像元(KS 检验)、DS 候选点、相干矩阵、带自适应正则化的 EMI 相位连接,按加权时间相干性和 相干像对的连通性筛选 DS(03)。
- 合并与精化:PS 和 DS 合在一起,用 Noise2Fringe Transformer 滤波,按时间相干性保留(04)。
- 解缠:点的 Delaunay 网络上的最小费用流,逐幅干涉图(
mcf-pc)或冗余网络整体(emcf-pc)解缠, 按相位闭合校正解缠误差(05)。
Pipeline、续跑与 JSON¶
一条处理链就是一个 TOML 文件,由 moraine run FILE 运行(Pipeline 文件,英文)。
参数相同且输入没变的步骤会被跳过,所以出错或改了参数之后再运行一次文件即可。moraine run FILE --dry-run 显示
将要运行什么,moraine status FILE 显示状态。加 --json 后每条命令在 stdout 打印一个 JSON 对象,日志走 stderr
(JSON 输出):脚本和 AI agent 读的就是它。
GPU 还是 CPU¶
API 函数接受 numpy 或 cupy 数组,按类型分派(moraine.api.utils_.get_array_module);CLI 函数和命令用 cuda
参数(每块 GPU 一个 worker 进程,从 cupy 的内存池分配)。只有 CUDA_VISIBLE_DEVICES 列出了 GPU 才会用它。影像很多
(超过约 100 景)时,相位连接在多核 CPU 上可能比单块 GPU 更快;指南里有数字。