Conversation
Introduce ZarrOMEVersion (0.5 default, 0.6 opt-in) on ZarrStreamSettings and per-image "omero" rendering metadata (ZarrOMERenderingSettings) on ZarrArraySettings. Presence of omero promotes an array to an OME image group, so it gains a multiscales block plus the omero block. - C API: ZarrOMEVersion enum, omero structs, channel-array alloc/free helpers. - Core: ome.version driven by the selector; omero emitted in group metadata. HCS plate/well sub-spec versions left at 0.5 (independent). - Config files: YAML/JSON load, dump, and free round-trip for both. - Python: OMEVersion enum and OMEWindow/OMEChannel/OMERenderingDefs/ OMERenderingSettings classes with in-place mutation (opaque channels vector, shared_ptr-held nullable objects). - Tests: C++ integration (omero + version, config round-trip) and Python settings/stream coverage. First PR in a series adding newer OME-NGFF feature support. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The omero id is an image identifier that every other producer writes as a JSON integer, so model it as uint32_t + has_id rather than a string. Reject settings that would emit unusable rendering metadata: an omero block with no channels, a channel count that disagrees with the Channel dimension, and a zero-initialized window (which would write a blank display range).
Loaded arrays were allocated with malloc/calloc but the public ZarrXxx_create_*_array helpers use new[], so a caller replacing one with the other crossed allocators. Use new[]/delete[] on both paths. An unquoted YAML scalar like 'ome_version: 0.6' decodes as a double, which as_string rejected; accept floats via dump() for the shortest round-trip form.
RFC-2 moved the OME-Zarr metadata version up to a single ome.version key; the 0.5 prose that still required a version inside the plate and well dicts was a spec bug, removed upstream in ome/ngff-spec#84 (see ome/ngff#309). The 0.5 schemas and normative examples carry no inner version key. The group-level ome.version must be consistent within a hierarchy, so plate and well groups now emit the stream's selected version instead of a hardcoded 0.5.
The HCS integration tests assert the exact number of fields in the plate dict, which is now 6 rather than 7.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First PR in a series adding support for newer OME-NGFF features. This one adds:
ZarrOMEVersion(0.5default,0.6opt-in) onZarrStreamSettings, driving the emittedome.version.0.5output is unchanged by default.omerorendering metadata — per-imageZarrOMERenderingSettings(channels: label/color/window/active/family/coefficient/inverted, plusrdefsandid/name) onZarrArraySettings, emitted asome.omeroso viewers (napari, vizarr, neuroglancer) render channels correctly.Details
zarr.types.h,acquire.zarr.h,acquire.zarr.cpp): the enum, omero structs, andZarrOMERenderingSettings_create/destroy_channel_arrayhelpers.array.base.*,zarr.stream.*,multiscale.array.cpp): version threaded throughArrayConfig;omerocopied to an internal representation and emitted in group metadata. Presence ofomeropromotes an otherwise-flat array to an OME image group (single-levelmultiscales+omero), so the metadata isn't silently dropped; existing flat-array output is unchanged. HCS plate/well sub-spec versions are intentionally left at0.5(independently versioned).settings.io.cpp): YAML/JSON load, dump, and free round-trip for both new fields.acquire-zarr-py.cpp,__init__.pyi):OMEVersionenum andOMEWindow/OMEChannel/OMERenderingDefs/OMERenderingSettingsclasses. Nested objects are mutable in place (opaque channels vector;shared_ptr-held nullable objects), soarray.omero.channels[0].label = "x",.channels.append(...), and.window.max = ...all persist.Test plan
stream-omero-and-ome-version(omero emission +0.5/0.6selection) and extendedstream-from-config-file(omero +ome_versionround-trip through YAML/JSON dump→reload).test_settings.py(config round-trip, in-place mutation, optional/identity) andtest_stream.py(omero metadata + version selector).Relying on CI to confirm the full build across platforms.
Follow-ups (series)
Phase 1b (labels/image-label), 1c (translation transforms), then Phase 2 (RFC-5 coordinate systems & transformations,
0.6).🤖 Generated with Claude Code