Skip to content

Emit RFC-5 coordinate systems and transformations for OME-Zarr 0.6 - #244

Open
aliddell wants to merge 6 commits into
ome-version-selector-and-omerofrom
rfc5-structural-emission
Open

aliddell wants to merge 6 commits into
ome-version-selector-and-omerofrom
rfc5-structural-emission

Conversation

@aliddell

Copy link
Copy Markdown
Member

Second slice of the OME-NGFF expansion: emit RFC-5 coordinate systems and
transformations when the stream selects OME-Zarr 0.6.

Stacked on #240 — that PR adds the ome_version selector this one gates on.

What changes

MultiscaleArray::make_multiscales_metadata_() restructures the existing
per-level scale transform into the RFC-5 shape when ome_version == 0_6:

  • a coordinateSystems entry named "intrinsic", built from the visible axes
  • per-dataset scale transforms that name their input ({"path": "<level>"})
    and output ({"name": "intrinsic"})
  • no top-level axes in 0.6, which coordinateSystems supersedes

0.5 output is unchanged. No new user-facing API — richer transforms
(translation/affine/rotation/sequence, named systems) need one and come later.

Design notes and the resolved open questions are in
docs/design/rfc5-coordinate-transformations.md.

Notes

RFC-5 is still under review, so 0.6 stays opt-in and is pinned to 0.6.dev3.

Testing

  • tests/integration/stream-omero-and-ome-version.cpp asserts the 0.6 shape and
    keeps the 0.5 assertions as a regression guard
  • python/tests/test_stream.py::test_ome_version_selector

aliddell and others added 6 commits July 31, 2026 16:13
When ome_version is 0.6, restructure the multiscales metadata per RFC-5:
emit a named `coordinateSystems` array (the "intrinsic" physical system)
in place of the top-level `axes` key, and give each dataset scale
transform explicit `input` (the array coordinate system, i.e. the dataset
path) and `output` ("intrinsic"). 0.5 output is unchanged.

Pure emission change gated on ome_version; no new public API. Also adds
the RFC-5 design doc under docs/design/.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
RFC-5 coordinate transformations reference their input and output coordinate
systems as objects -- {"path": ...} for an array and {"name": ...} for a
named system -- not as bare strings.
MSVC resolves `json = { <json prvalue> }` to copy-assignment, so the datasets
key became the single dataset object rather than an array containing it, and
the next level's push_back threw type_error.308. Clang and GCC pick the
initializer-list constructor and produce the array, so this only broke the
MSVC build -- and PRs stacked on a non-main base get no CI at all, so nothing
caught it.

Use nlohmann::json::array() explicitly, which is unambiguous on both.
@nclack

nclack commented Aug 28, 2026

Copy link
Copy Markdown
Member

I worry about the approach on this one. Ideally, we wouldn't need to explicitly model every ngff feature.

For example, if the caller can just hand us a json string that we put in the right place (like an "omero" key), then we don't need to model hardly anything here. That way we don't need to change the code as much as the standard evolves.

This branch has not been deployed

No deployments
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.

2 participants