Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 55 additions & 34 deletions rfc/3/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,25 +335,30 @@ document, taking as base the current development version:

2. The following lines are *added* to "multiscales metadata":

> 0. The length of the axis names MUST match the number of axes of the array.
> 1. *If* a dataset contains exactly 2 spatial dimensions, those dimensions
> SHOULD be named `y` and `x`, except where rule 4 applies.
> 2. *If* a dataset contains exactly 3 spatial dimensions, those dimensions
> SHOULD be named 'z', 'y', and 'x', except where rule 4 applies.
> 3. *If* a dataset contains exactly 1 time dimension, it should be named `t`.
> 4. When image data axes map straightforwardly to axes with common names in
> 1. The length of the axis names MUST match the number of axes of the array.
> 2. *If* a dataset contains exactly 2 spatial dimensions, those dimensions
> SHOULD be named 'y' and 'x', and have type "space", except where rule 5
> applies.
> 3. *If* a dataset contains exactly 3 spatial dimensions, those dimensions
> SHOULD be named 'z', 'y', and 'x', and have type "space", except where
> rule 5 applies.
> 4. *If* a dataset contains exactly 1 time dimension, it SHOULD be named 't'
> and have type "time", except where rule 5 applies.
> 5. When image data axes map straightforwardly to axes with common names in
> the relevant field of practice, those axes SHOULD be named according to
> such conventions. For example, spatial frequency axes resulting from a
> Fourier transformation of `z', 'y', and 'x' SHOULD be named 'w', 'v', and
> Fourier transformation of 'z', 'y', and 'x' SHOULD be named 'w', 'v', and
> `u`, respectively. Similarly, a temporal frequency axis resulting from
> a Fourier transformation of the `t` axis SHOULD be named `w` or `ω`.
> 5. Axis names MUST NOT be repeated within a dataset, and SHOULD NOT be
> different only by upper/lower-case. For example, the same dataset SHOULD
> NOT have both an `X` and an `x` axis.
> 6. The order of the axes MUST match their ordering within the data if
> applicable. For example, if the axes are ordered as `DZYX`, where `D` is a
> field of displacement vectors, then the vectors must be ordered as `ZYX`
> within the array.
> a Fourier transformation of a time axis SHOULD be named 'w' or, if 'w' is
> already in use in the given dataset, 'ω'. (See Rule 6.)
> 6. Axis names MUST NOT be repeated within a coordinate system, and SHOULD NOT
> be different only by upper/lower-case. For example, the same dataset
> SHOULD NOT have both an 'X' and an 'x' axis.
> 7. The order of the axes MUST match their ordering within the data if
> applicable. For example, when representing a vector field representing
> particle if the axes are ordered as 'DZYX', where 'D' contains vector
> coordinates representing particle or fluid motion, then the vectors must
> be ordered as 'ZYX' within the array.

3. The following lines are amended as noted:

Expand All @@ -370,7 +375,11 @@ document, taking as base the current development version:
> Every Zarr array referred to by a path MUST have the same number of
> dimensions and datatype.~~, and MUST NOT have more than 5 dimensions.~~

No further changes to the specification document are proposed by this RFC.
Examples in the schema text will also be updated to match the above descriptive
changes, including any notes that prescribe a specific axis ordering.

Further, axis and transformation schemas will be updated to remove the
restrictions on number, type, and order.

## Stakeholders

Expand Down Expand Up @@ -400,13 +409,12 @@ This should be a small amount of work in most cases.

## Forward Compatibility

A draft proposal for [coordinate transformations][trafo spec] already includes
most of the changes proposed here, so we envision that this RFC is compatible
with future plans for the format. The proposal does currently limit the number
of dimensions of type "space" to at most 3, but that limit [could be
removed][space dims comment]. If this RFC is approved, the transformation
specification would need to be updated to reflect this. However, that is an easy
change and there seems to be sufficient support in the community for this idea.
An earlier version of this proposal described RFC-5 as a future change. As it
happens, RFC-5 was accepted before this one and this section (detailing how
RFC-5 would need to be modified) is no longer relevant: all the relevant
changes are included in this RFC.

We have identified no further forward compatibility concerns.

## Drawbacks, risks, alternatives, and unknowns

Expand Down Expand Up @@ -459,12 +467,15 @@ time.

## Testing

Datasets conforming to the new specification can be found at:
Datasets conforming to the proposed specification can be found at:

https://github.com/clbarnes/ome-zarr-rfc3-data

This includes three synthetic datasets and (in progress, pull request #1) two
real (subsampled) datasets.
which provides three synthetic datasets, and

https://github.com/image-coop/ome-zarr-data

which includes two real-world downsampled datasets.

HTTP access to the datasets is currently available at:

Expand All @@ -478,11 +489,20 @@ https://test-bucket.image.coop/rfc3/flim-tmr31-3-reduced64.ome.zarr
https://test-bucket.image.coop/rfc3/CP-Ti-abnormal-grains.zarr
```

Implementations may check their compliance with this RFC using these datasets.
As a reminder, this RFC explicitly takes the position that partial
implementations are OK, and software is considered compliant if it provides
an informative error message (e.g. "The given dataset contains an unknown axis
'U', which is not supported by this viewer.").
Implementations may check their compatibility with the proposed changes using
the above datasets.

Partial implementations that cannot support all the changes in this RFC are
explicitly allowed, but they should provide an informative error message when
rejecting a dataset; for example: "The given dataset contains an unknown axis
'U', which is not supported by this viewer."

Additional valid and invalid metadata JSONs can be found in versions [0.9.dev1]
and the upcoming [0.9.dev2] (prospective link; not yet tagged) of [ngff-spec].

[0.9.dev1]: https://github.com/ome/ngff-spec/releases/tag/0.9.dev1
[0.9.dev2]: https://github.com/ome/ngff-spec/releases/tag/0.9.dev2
[ngff-spec]: https://github.com/ome/ngff-spec

## License

Expand Down Expand Up @@ -521,5 +541,6 @@ This RFC is placed in the public domain.

| Date | Description | Link |
| ---------- | ---------------------------- | ---------------------------------------------------------------------------- |
| 2024-10-08 | RFC assigned and published | [https://github.com/ome/ngff/pull/239](https://github.com/ome/ngff/pull/239) |
| 2026-07-04 | Updated to address comments, elaborate on use cases, include specific changes to spec doc, and add test data | [https://github.com/ome/ngff/pull/560](https://github.com/ome/ngff/pull/560) |
| 2024-10-08 | RFC assigned and published | [ome/ngff#239](https://github.com/ome/ngff/pull/239) |
| 2026-07-04 | Updated to address comments, elaborate on use cases, include specific changes to spec doc, and add test data | [ome/ngff#560](https://github.com/ome/ngff/pull/560) |
| 2026-09-16 | Updated to address review 2: fix inconsistencies, clarify some recommendations, and update outdated text. | [ome/ngff#614](https://github.com/ome/ngff/pull/614) |
102 changes: 102 additions & 0 deletions rfc/3/responses/1/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# RFC-3: Response 1

## Summary of Changes

In response to review 2, RFC-3 has been updated to clarify certain
recommendations and add new ones, to help implementers make decisions.

## Review feedback

[Review 2](rfcs:rfc3:review2) provided a convenient checklist of all the
recommendations. It is included below for cross-reference, with responses or
resulting changes noted inline.

### Minor changes

- [ ] Add a statement that, if present, `t`, `c`, `z`, `y`, `x` axes SHOULD
occur in that order.
- We disagree with this recommendation, as one of the key motivations of
RFC is freedom to reorder these axes when acquiring data, or when
performing different analyses that may require different access
patterns. While the recommended ordering is optimal in many scenarios,
we continue to stress that documentation is the right place for this
recommendation, not the NGFF specification.
Comment on lines +18 to +23

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe also worth mentioning that in zarr v3, there is no fixed relationship between axis order and memory layout. so even recommending a particular axis order would not achieve what the authors want (a consistent memory layout)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that request more informed by coordinate transformations. In many viewer tools, passing an array along with an affine transformation matrix to a viewer will almost certainly require stripping out the channel dimension from the affine matrix. This affine-wrestling (especially when transforming from coordinate systems with channel dimension into a coordinate system without channel dimension) is tricky. Having the channel always be the lead dimension (for instance) would simplify things a bit.

That's just to say the affine wrangling is annoying, but entirely possible and maybe the solution would rather be to not have a coordinate vector concern itself with transforms at all (which would be the way we are discussing over at #580).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then we have very different reads on what the authors were concerned about 😆 I thought they wanted to ensure that the default in-memory layout of decoded chunks was amenable to spatial algorithms like smoothing by packing spatial dimensions close together in decoded memory. But this is not something you can declare in zarr metadata.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe also worth mentioning that in zarr v3, there is no fixed relationship between axis order and memory layout. so even recommending a particular axis order would not achieve what the authors want (a consistent memory layout)

Are you referring to the RFC authors or the review authors? 😅

Also, I trust your statement here but I don't fully grok it. Can you construct me a pathological example with code in which the axis ordering is tczyx but the data is contiguous in t? A concrete example would help the conversation, I think.

Either way, this seems like it is a broader discussion that should not (imho) hold up the RFC. It can always be added later.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I trust your statement here but I don't fully grok it. Can you construct me a pathological example with code in which the axis ordering is tczyx but the data is contiguous in t? A concrete example would help the conversation, I think.

this gist illustrates part of the point: https://gist.github.com/d-v-b/f53c0e3b6fb1fe2b1314500cc969f0e8

it shows that zarr, the python lib, can decode the exact same chunk bytes into C or F contiguous memory, depending on a runtime configuration flag. This shows that memory order of decoded chunks is an implementation degree of freedom.

and C / F order is just one point in a bigger space of memory layouts that are possible. I would like to support decoding into sparse arrays, which don't have a contiguous memory layout at all.

this can be a hard part of the spec to internalize (I know because it took me a while to have the "a ha" moment), because numpy-style "arrays ARE contiguous sequences of bytes in memory" thinking is so sticky. But for the Zarr format, the memory layout of decoded arrays is outside the spec. Implementations can use C, F, morton, sparse, unordered, whatever. So OME-Zarr can't make any assumptions or statements about the in-memory representation about arrays, unless you want to be stricter than the language in the Zarr spec.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the authors have a valid concern, but I'd vote for keeping the SHOULD. The wording still allows other ordering, just requires that decision to not be taken without thinking about it. From rfc2119:

SHOULD This word, or the adjective "RECOMMENDED", mean that there
may exist valid reasons in particular circumstances to ignore a
particular item, but the full implications must be understood and
carefully weighed before choosing a different course.

I am also hesitant to write SHOULDs in the documentation elsewhere without a clear reference point in the spec

- [x] Carry the `type` recommendation into rules 1 to 3 and provide guidance
and examples on how and what to name custom types.
- Done in 848519d. Note that we have renumbered rules to start from 1, so
these are now 2 to 4.
- [x] Resolve the naming collision between the spatial and temporal frequency
axes in rule 4 so that rules 4 and 5 can both be satisfied.
- Done in f8e094e.
- [x] Use `SHOULD` in rule 3.
- Done in eea5035.
- [x] Say "within the same coordinate system" in rule 5, or state and reconcile
the stronger scope.
- Done in 92b1a37.
- [x] Scope rule 6 to axes whose component semantics the specification defines,
or reword it so the MUST can be checked.
- Rule 6 (now 7) includes the phrase "if applicable". Because we can't
anticipate all the data types where it would apply, we intentionally
leave room for interpretation. Having said that, the reviewers
correctly pointed out that the recommendation for displacement fields
was redundant with RFC-5. However, the recommendation applies more
generally than in the context of coordinate transformations. We have
therefore changed the example to a vector field representing particle
or fluid motion.
- [x] Make the list of specification changes exhaustive (hierarchy comment,
RFC-5 vector-axis placement wording, schema limits), or remove the "no
further changes" sentence and enumerate the known edits.
- Done in b469cc1.
- [x] Update Forward Compatibility to the 0.6rc0 and RFC-5 state and name the
remaining dimensional assumptions.
- Done in 0923718.
- [x] Distinguish dataset conformance from partial implementation support, and
cover the new MUST rules in the shared ngff-spec conformance cases, with
checks outside the schema for name uniqueness and rule 0.
- I have clarified the text in the testing section (de7093d). Additional
test cases in ome-ngff will be added after the 0.9.dev2 cleanup
([ome/ngff-spec#201](https://github.com/ome/ngff-spec/pull/201)).

### Not critical, but suggestions

- [ ] Clarify when `c` is appropriate.
- For the moment, I prefer to leave this question open, since the answer
will be dependent on the use case, and may be refined in future RFCs
(such as a proposed visualization metadata RFC).
- [ ] Provide worked OME-Zarr examples for Zeiss CZI and Leica datasets
(including axis `type` values) and for DTI and frequency-domain (e.g.,
MRI k-space) images.
- Although these would be nice to have, we consider that this work can
happen outside of this RFC.
- [ ] Consider name hygiene for the now unrestricted axis names: NFC-normalized
Unicode, no leading or trailing whitespace, no `/` or ASCII control
characters.
- It turns out that axis names are not currently restricted: they have
only been limited to tczyx by convention! (See [ome/ngff-spec#180].)
Therefore, the issue of name sanitisation predates this RFC and should
be handled separately.

[ome/ngff-spec#180]: https://github.com/ome/ngff-spec/issues/180

### Additional comments / questions

- Overlapping labels with an instance axis

> Is the intent to allow `projectAxis` in that link, or to store such
masks as a separate multiscales image? Not a blocker.

The RFC-3 doesn't take a position on this. RFC-8 explicitly allows for
standalone label images, which renders this question moot. A future RFC may
eliminate the required minimal set of transformations between labels and
images.

- 'omero' 'channels' metadata

> `omero` describes `channels` as "Array matching the c dimension size" and
> has `defaultT` and `defaultZ`. With several `channel` or `time` axes it is
> unclear which axis these refer to. A sentence stating that it applies to
> datasets with at most one channel and one time axis would suffice.

Since axes have unique names, this case is already covered.


Loading