SuperAPI AI 工具集

zarr-multiscales

数据与分析

查看项目

更新于 10-16 09:03

技能介绍

Zarr Multiscales 是一个用于为已有 Zarr 存储添加多尺度金字塔(概览层)的技能,面向瓦片服务与 Web 流式传输场景。它假设 CRS / CF / grid_mapping 等地理参考层已由 geozarr 技能处理,本技能专注于金字塔本身。

用途

为已发布的 Zarr 存储追加多尺度概览,使查看器能够逐级缩小到整个数据集,同时不破坏原始第 0 层数据。

主要能力

按数据语义选择重采样算子。这是最关键的决策:类别概率 / softmax(和为 1)用平均,因为各向量之和为 1 的均值仍为 1;单概率或连续数据(反射率、NDVI、高程)用平均以减少混叠;类别标签(土地覆盖、argmax 输出)用众数,因为对标签整数取平均没有意义;二值掩膜用平均保留覆盖比例,或用众数保留多数类;计数 / 人口用求和以保持总量;后续要阈值化的数据先平均、读取时再阈值。连续或概率数据的概览不应使用最近邻,它会严重混叠,使细小特征在不同缩放级别闪烁。若同时有概率和 argmax,建议从概率构建金字塔、读取时再取 argmax。

平均池化的两个正确性细节。一是跨“向量”维度的联合有效性掩膜:对带跨波段不变量的多波段数据,像素只有在所有波段都有效时才参与,否则各波段在不同像素集上平均,粗尺度向量会偏离单纯形。二是 nodata 感知归约:块只对其有效单元求平均,全 nodata 块保持 nodata。实现上建议用显式 sum/count 而非 np.nanmean,因为后者在全 nodata 块上告警,静默告警需修改全局状态且非线程安全。

级联降采样。从原始构建 2 级、从 2 级构建 4 级、从 4 级构建 8 级,每遍只读上一级的四分之一,整个尾部成本约为一次不可避免的全分辨率读取的 33%,而每级都从 0 级构建则约为 N 倍。代价是层级间产生依赖,需配合完整性门禁。

输出分片对齐输入分片。让一个输入分片映射为整数个输出分片(理想为一对一),可避免写竞争与读改写,任务可独立重试,工作单元即一个输出分片,便于条带划分与续跑。分片内部再切小 chunk(256–512 px)以服务瓦片读取。

按列表剪枝空区域。稀疏存储(海洋、AOI 外瓦片)会省略 chunk,先列出分片键再推导工作列表。文中示例将全球 10 m 存储的 188,160 个朴素任务剪枝到 84,870 个真实任务,55% 的网格为全 nodata 海洋,从未被读取。

跨工作进程条带划分。先对稳定任务列表分区,再按续跑过滤,顺序不可颠倒。错误顺序下并发工作进程在不同时刻列出“已完成”,各自得到不同长度的过滤列表,tasks[i::N] 不再是分区,子集重叠且部分任务无人认领,且不会报错。文中给出真实案例:某级报告写入 22353、跳过 0,六个批处理数组任务均报成功,但 22,482 个对象中仅存在 14,974 个,下一级在其上构建出 nodata 空洞。

层级间完整性门禁。作业成功不等于数据完整,调度依赖链、dask future 完成、退出码 0 都只证明进程结束。应以真实对象计数为门禁:若 have != want 则抛错,要求先完成父级。因为每个对象恰好对应一个必需任务,count == target 即足以证明无缺口,无需读取数据。

长期任务的凭证与续跑。临时 S3/STS 凭证常远短于作业时长(source.coop 默认约 40 分钟),应请求最大时长并定期重开存储以获取新令牌。续跑须为对象级,--skip-existing 检查对象是否存在;但“存在”不等于“正确”,仅当写入该分片时父级完整才成立。若某级曾在部分父级上运行,应删除该级 chunk 前缀重建。任务异常应向上传播,让调度器重试,捕获并记录会在金字塔中留下永久空洞。

并发通常是瓶颈。面向对象存储的金字塔构建是网络受限而非 CPU 受限。文中案例:单流持续 19 MB/s,48 个并发流达 1.8 GB/s,约 90 倍差异。应扩展工作进程 / 线程数而非核心数,并重新测量聚合吞吐以检查服务端限流。

元数据追加且不破坏第 0 层。将每级写为同级组(2x、4x… 或 0、1、2…),各自为独立数据集,带自己的坐标数组与 CRS 变量,可单独打开。仅在根添加 multiscales 属性,第 0 层保持为根数组。重新合并元数据使一次请求即可服务整个金字塔。先备份根元数据,因为添加属性会重写 zarr.json。逐字节比对每个第 0 层节点元数据与备份,确认根的唯一变化是新增属性。

金字塔深度。当最粗级别约为一个瓦片(长边几百像素)时停止,使查看器可缩放到整个数据集。尾部级别几乎免费,每级为上一级的四分之一。文中示例:4M 像素宽的全球 10 m 网格在因子 8192 时约为 490x192,即 13 级。

验证清单。不要凭作业退出码宣布完成,按成本递增检查:计数(每级对象数等于清单目标)、元数据(形状、dtype、维度名、分片/chunk 形状、grid_mapping、CRS 属性、坐标长度/间距、单元中心偏移、GeoTransform 像素大小缩放且原点不变、北向上时 y 递减)、真实数据不变量(采样分片的值域、nodata 掩膜跨波段一致、语义不变量如和为 1)、重新推导(从父级重算采样分片并比对,确定性归约应逐位相等)、条带感知采样(检查每条条带的首/中/尾,而非随机分片)、覆盖合理性(最粗级别的有效数据比例应与源占用率一致)、客户端往返(匿名打开已发布 URL,确认每级 CRS/分辨率/边界)。

参考文件

scripts/downsample.py:线程安全的 nodata 感知平均与众数归约器 scripts/manifest.py:分片键列表与清单剪枝任务生成 scripts/verify.py:完整性/元数据/数据/条带验证工具 scripts/test_striping.py:分区回归测试(含防退化测试) references/pitfalls.md:失败目录,含症状与修复

适用场景

需要为地理空间 Zarr 存储提供多分辨率瓦片服务的场景,尤其是全球或大区域、含大量 nodata 的稀疏存储,以及需要在不影响已发布第 0 层的前提下追加概览的场合。

限制

本技能不处理 CRS / CF / grid_mapping 层,需配合 geozarr 技能。文中未提供具体安装命令、收费或价格信息。