Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pyramid-audit

Byte-exact verification that the multiscale pyramids in the Vesuvius Challenge open data are what they claim to be.

Every published volume ships a resolution pyramid. Downstream work — surface prediction, segmentation review, any browsing UI — reads the reduced levels rather than level 0, because level 0 is too large to touch. Nothing checks that those reduced levels are actually a faithful reduction of the data underneath them. A pyramid that silently disagrees with its own level 0 corrupts every result computed from it, and does so invisibly, because the reduced level still looks like plausible scroll data.

This tool checks it, over the whole published catalogue, without credentials.

volumes audited 71
volumes clean 70
volumes with a contract finding 1
chunk reductions compared byte-for-byte 1,410
of those that disagreed with the stated rule 0
chunks legitimately absent (sparse storage) 706
chunks not reachable after 4 retries 0
wall-clock for the full catalogue 574 s

The contract, which was not documented anywhere

Every level of every published pyramid satisfies, exactly:

level[N+1][z,y,x] == round_half_even( mean( level[N][2z:2z+2, 2y:2y+2, 2x:2x+2] ) )

with ceil for odd extents, and with a trailing partial block averaged over the voxels that actually exist rather than zero-padded.

That held for 1,410 of 1,410 compared reductions (100.00%). The rounding rule matters: it is round-half-to-even, not round-half-away-from-zero. Assuming the schoolbook rule instead disagrees on 6.25% of voxels by exactly 1 — which is the fraction of block means that land on a half. Anyone regenerating a level, or writing a reader that reduces on the fly, needs this to reproduce the published bytes.

The tool does not assume a rule. It fits one per store from {half-even, half-up, trunc}, reports which fits, and raises a contract violation only when no standard rule fits. It also flags a store that uses more than one rule internally.

What it checks

check class what it means
downsample contract a child chunk is the exact reduction of its parent region
catalog_shape contract the catalogue's declared volume shape equals the level-0 array shape
catalog_dtype contract the catalogue's declared data_format matches the array dtype
shape_relation contract each level's extent follows from its parent and the declared scale
declared_scale contract OME coordinateTransformations agree with real extents
uniformity contract dtype, chunking, order, fill value and codec agree across levels
sparsity_coherence contract a child chunk holding data has at least one present parent chunk
rounding_consistency contract one store does not mix rounding rules
coverage advisory what could not be verified, and why

A contract finding is machine-checkable and safe to gate automation on; the CLI exits 2. An advisory never fails a run.

Findings

1 contract finding(s):

PHercParis4 / 20230205180739-7.910um-54keV-masked.zarr

catalog_shape — catalog declares shape [14369, 7888, 8096] but level 0 array is [14258, 7888, 8096]. The same record's creation.metadata gives z_crop_start=0, z_crop_end=14257, which yields exactly 14258 planes (inclusive) and matches the array. The declared shape is the pre-crop extent and was not updated after the crop; a consumer sizing work from it overruns the array by 111 planes.

Run it

pip install numpy numcodecs        # numcodecs only for blosc-compressed stores
python -m pyramid_audit scan --samples 6 --workers 6 --out reports/scan.json
python -m pyramid_audit check PHerc0800/volumes/20250521135224-8.640um-1.2m-116keV-masked.zarr/
python -m tests.test_checks        # self-checks, no pytest needed

Exit status 0 clean, 2 contract violation, 1 tool error.

How it stays cheap

The uncompressed stores are C-ordered, so a range of leading-axis planes is one contiguous byte range. The tool verifies a 16-plane slab per chunk with an HTTP Range request, moving an eighth of the bytes of a full 128³ chunk. Because child chunk origins are multiples of 128, the corresponding parent range falls inside a single parent z-chunk, which halves the parent fetches as well. The comparison over the covered planes is exact; this reduces coverage, not rigour, and the covered plane count is recorded in every finding.

The whole catalogue audits in 574 seconds.

What this does not prove

  • It samples chunks; it does not compare every voxel of every level. Counts of what was compared are reported so the claim is bounded. --samples raises it.
  • A pyramid that is internally consistent can still be a faithful reduction of the wrong source. This tool checks self-consistency, not provenance.
  • It does not check ink detection, segmentation, meshes, or anything derived.
  • Whether the one catalogue-shape defect below has affected any published result has not been measured. It is reported because it is provable from the catalogue's own record, not because downstream damage is demonstrated.
  • Absent chunks are treated as fill, matching Zarr semantics. The tool does not attempt to distinguish "legitimately empty" from "lost".
  • It cannot see an oversized chunk. Reads use HTTP Range to fetch a slab of leading planes, so an object that is larger than its declared chunk size still returns exactly the expected slab and reshapes cleanly. A volume with chunks stored at 8x or 64x their declared size passes this audit untouched; that defect class is only visible from listing metadata, which is what fill-census checks. Found the hard way: PHerc0343P/20250521134555 has 555 such chunks and audits clean here at 60 samples per level pair.

Reproducing the numbers in this file

README.md is generated from reports/scan-full.json by make_readme.py. It cannot be edited into disagreement with the evidence:

python make_readme.py > README.md

Read-only throughout: anonymous HTTPS GETs, no credentials, no writes. MIT licensed.

About

Byte-exact multiscale pyramid verification for Vesuvius Challenge open data. Read-only, no credentials.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages