Skip to content

feat(registration): recover registration geometry without the reference volumes - #28

Merged
peter-grotz merged 2 commits into
devfrom
feat/registration-geometry
Sep 22, 2026
Merged

peter-grotz merged 2 commits into
devfrom
feat/registration-geometry

Conversation

@peter-grotz

Copy link
Copy Markdown
Owner

Part of #27. Adds registration.py.

The transform needs the geometry of the two volumes the CCF registration worked from, published at 1.4-1.8 GB each under ccf_alignment/registration_metadata/ — but only for some samples. Of 60 processed exaSPIM assets with a fused zarr, 40 have them; the rest cannot be transformed at all today.

Nothing reads their voxels: check_orientation needs input_img.shape, apply_transforms_to_points needs the resampled image's spacing/origin/direction. The only pixel consumer is the QC overlay, which this pipeline does not produce.

Two paths, because the samples split disjointly. Older samples publish the volumes but carry a v1 record with empty parameters; newer ones carry a full v2 record but no volumes.

Case Path Verified
volumes present read NIfTI headers from a 200 KB byte range 40/40 exact
rich record present derive from the zarr level + sample_scale it names structurally, on 826509
both derive and reconcile() the cross-check, when one appears

Three load-bearing details, each verified across the 40 and each silently wrong if missed:

  • the source is fused_ccf_ch.zarr, not fused.zarr — rules from the signal pyramid match 11-27 of 40, the CCF channel matches 40/40
  • resampled shapes need exact rationals: 0.0135/0.01 is 1.3499999999999999 in binary float, so a 1270-voxel axis rounds to 1714 where the registration produced 1715
  • the direction matrix is ANTs/ITK LPS, which negates the first two rows of the NIfTI RAS srow

Also recovers the template-to-CCF version the registration used, so a sample registered against v1.4 is not silently composed with v1.5 (826509 is such a case).

Honest gap: the derivation path cannot be cross-validated against the published volumes, because no sample currently has both. reconcile() exists to close that the moment one does.

Tests: 138 passed, 100% coverage, ruff and interrogate clean.

…ce volumes

The transform needs the geometry of the two volumes the CCF registration worked
from. Those are published under ccf_alignment/registration_metadata/ at 1.4-1.8
GB each, but only for some samples: of 60 processed exaSPIM assets with a fused
zarr, 40 have them. The rest cannot be transformed at all today.

Nothing in the transform reads their voxels -- check_orientation needs
input_img.shape and apply_transforms_to_points needs the resampled image's
spacing, origin and direction. The only pixel consumer is the QC overlay, which
this pipeline does not produce.

Two paths, because the samples split cleanly and disjointly. Older samples
publish the volumes but carry a v1 processing record with empty parameters;
newer ones carry a full v2 record but no volumes. Where the volumes exist their
headers are read from a 200 KB byte range rather than the whole file -- exact
on all 40. Where the record exists the geometry is derived from the zarr level
it names and the sample_scale it recorded. Where both exist, reconcile() checks
one against the other and fails rather than mis-registering.

Three details are load-bearing, each verified across the 40 and each silently
wrong if missed:

- the source is fused_ccf_ch.zarr, not fused.zarr; rules from the signal
  pyramid match 11-27 of 40, the CCF channel matches 40/40
- resampled shapes need exact rationals: 0.0135/0.01 is 1.3499999999999999 in
  binary float, so a 1270-voxel axis rounds to 1714 where the registration
  produced 1715
- the direction matrix is ANTs/ITK LPS, which negates the first two rows of the
  NIfTI RAS srow

The written spacing is sample_scale reversed, which does not correspond to the
array's physical axes -- the coarse value lands on axis 2 while the coarse axis
is z at index 1. Reproducing it is required: the transforms were fit in that
space.

Also recovers the template-to-CCF version the registration used, so a sample
registered against v1.4 is not silently composed with v1.5.
The resample stage no longer writes them, so the role has no source.
@peter-grotz
peter-grotz merged commit 45513dc into dev Sep 22, 2026
3 checks passed
@peter-grotz
peter-grotz deleted the feat/registration-geometry branch September 22, 2026 21:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant