Skip to content

Resolve spatial queries from NGFF metadata - #162

Open
nclack wants to merge 3 commits into
indexed-queriesfrom
ngff-resolution
Open

nclack wants to merge 3 commits into
indexed-queriesfrom
ngff-resolution

Conversation

@nclack

@nclack nclack commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Spatial queries can now resolve a fixed output grid against OME-Zarr 0.5 metadata before chunk planning. Resolution chooses a source level using the full affine sampling scale, including rotation and anisotropy. Aligned crops run on either CPU or CUDA; queries that still require resampling fail explicitly when submitted. This PR does not implement a resampler.

Load an immutable NgffImage through an injected metadata reader, then call image.resolve(query, shape=output.shape). Resolution performs no I/O and depends only on the requested sample shape. Batching, output allocation, and dtype conversion remain downstream. Each query carries its full-rank transform, sampler, boundary behavior, and automatic or explicit level choice.

Results own their source URI and geometry independently of the image. Python returns one immutable, serializable value that can be pushed directly. C fills a caller-owned damacy_spatial_resolution with directly readable fields and a clear() operation; the existing sample conversion is the compatibility bridge to C submission.

Public coordinates use reference-level voxel corners, with identity matching integer crops. NGFF center coordinates are converted at metadata loading. Validation checks consumed fields needed for array layout and coordinate interpretation, including ambiguous duplicate fields and finite transforms. Unused metadata, shared transforms that cancel in reference coordinates, and trailing content are left uninterpreted.

See the spatial query API and contracts for C/Python examples, coordinate conversion, level selection, ownership, and the next executor operation.

Stacked on #161 (indexed-queries).

Validation:

  • CPU: 25/25 CTest targets passed; final spatial Python tests: 62 passed, 7 CUDA cases skipped.
  • L40: native spatial tests and all 69 Python spatial tests passed; all 7 CUDA memory-check cases passed with zero sanitizer errors.
  • ASan/UBSan: JSON and spatial tests passed, including C result ownership and cleanup.
  • Ruff, Pyright for the package and spatial tests, strict documentation build, and C example syntax passed.
  • Regression coverage includes NGFF center/corner conversion, anisotropic level selection, interpolation bounds, permissive handling of unused metadata, invalid consumed fields, result serialization and ownership, fixed output shapes, 128 collapsed transforms, and large differences in sampling scale.

@codecov

codecov Bot commented Sep 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 54.97487% with 448 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.35%. Comparing base (029677b) to head (e0720fa).

Files with missing lines Patch % Lines
src/ngff/metadata.c 40.81% 138 Missing and 65 partials ⚠️
python/damacy/_spatial.c 0.00% 175 Missing ⚠️
src/ngff/load.c 73.49% 11 Missing and 11 partials ⚠️
src/query/spatial.c 91.21% 6 Missing and 12 partials ⚠️
python/damacy/_spatial.py 91.53% 11 Missing ⚠️
src/util/json.c 69.44% 5 Missing and 6 partials ⚠️
python/damacy/_components.c 0.00% 2 Missing ⚠️
python/damacy/_native.c 0.00% 2 Missing ⚠️
src/damacy_status.c 0.00% 2 Missing ⚠️
src/store/metadata_store_async.c 81.81% 1 Missing and 1 partial ⚠️

❌ Your patch check has failed because the patch coverage (54.97%) is below the target coverage (70.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@                 Coverage Diff                 @@
##           indexed-queries     #162      +/-   ##
===================================================
- Coverage            59.66%   59.35%   -0.32%     
===================================================
  Files                   75       80       +5     
  Lines                11799    12789     +990     
  Branches              2056     2295     +239     
===================================================
+ Hits                  7040     7591     +551     
- Misses                3906     4252     +346     
- Partials               853      946      +93     
Flag Coverage Δ
unittests 59.35% <54.97%> (-0.32%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
python/damacy/__init__.py 96.18% <100.00%> (+0.29%) ⬆️
python/damacy/_api.c 0.00% <ø> (ø)
python/damacy/_components.c 0.00% <0.00%> (ø)
python/damacy/_native.c 0.00% <0.00%> (ø)
src/damacy_status.c 13.79% <0.00%> (-1.03%) ⬇️
src/store/metadata_store_async.c 63.37% <81.81%> (+0.79%) ⬆️
python/damacy/_spatial.py 91.53% <91.53%> (ø)
src/util/json.c 66.21% <69.44%> (+1.27%) ⬆️
src/query/spatial.c 91.21% <91.21%> (ø)
src/ngff/load.c 73.49% <73.49%> (ø)
... and 2 more

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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