Skip to content

spec: removed invalid mapAxis example#129

Open
jo-mueller wants to merge 1 commit into
ome:mainfrom
jo-mueller:remove-invalid-mapAxis
Open

spec: removed invalid mapAxis example#129
jo-mueller wants to merge 1 commit into
ome:mainfrom
jo-mueller:remove-invalid-mapAxis

Conversation

@jo-mueller
Copy link
Copy Markdown
Contributor

@jo-mueller jo-mueller commented May 18, 2026

@bogovicj I just realized that one of the mapAxis examples here were invalid against the spec. In the current spec text it says:

mapAxis transformations describe axis permutations as a transpose vector of integers.
Transformations MUST include a mapAxis field
whose value is an array of integers that specifies the new ordering in terms of indices of the old order.
The length of the array MUST equal the number of dimensions in both the input and output coordinate systems.
Each integer in the array MUST be a valid zero-based index into the input coordinate system's axes
(i.e., between 0 and N-1 for an N-dimensional input).
Each index MUST appear exactly once in the array.

The last statement is not reflected in the removed example - unless this usecase should be reflected somehow? 🤔 I will open another PR shortly to add a newAxis transform, which should solve the projection_up usecase, but I'm not sure how to do a projection from nD to (n-1)D here.

Related ome/ngff#499

@github-actions
Copy link
Copy Markdown

Automated Review URLs

@bogovicj
Copy link
Copy Markdown
Contributor

Thanks @jo-mueller,

mapAxis could have been useful to do up / down projections, but can't be used that way as written. A specific (common, I think) use case would be mapping a volume like xyzc to xyz.

But your proposed add/drop axis transformation would be more appropriate for that because if I map xyz to cxyz, presumably the output would have a fixed value of the c coordinate and we'd want to specify what that is, and doing that isn't possible with mapAxis.

I think mapping cxyz to xyz could be fine if the presumption is that the c coordinate is "dropped," but I may be assuming implementations treat channels in a special way...will have to think about this more.

My feeling at the moment:
It would be nice if mapAxis could be used in cases like this, in which case we should keep these examples. But if we decide mapAxis is missing something or that there are better ways to do it, then these examples should be removed and mapAxis does end up being a 1:1 axis permutation between space with the same number of axes.

@jo-mueller
Copy link
Copy Markdown
Contributor Author

@bogovicj thanks for chiming in here. It's true, we also had the discussion about how to treat the channel axis in terms of transforms. It's something that most implementations seem to get right intuitively, which doesn't change the fact that it's a bit of a blind spot in transforms land. I guess when RFC3 gets closer to the finish line we'll have to think about this harder because any new axis should somehow declare how it is supposed to be treated by transforms.

The reason why I am not 100% sold on the drop axis transform, is that you could express a dropaxis by its inverse, which would be a sequence of a addAxis and a translation (provided you have the image you're slicing out by the drop axis transform saved separately.

We discussed it yesterday in @ome/gerbi and came to the conclusion that the addAxis and dropAxis transforms is something we'd probably add in a post-0.6 version, for two reasons:

  • It's not pretty, but an affine can do the job of both the addAxis or dropAxis transforms, it's just less declarative about it
  • Timing-wise, I think adding more transforms or generally larger changes to the 0.6 spec will delay the release of 0.6 quite a bit, and I'm not 100% sure whether the declarative value of these new transforms justify the delay?

Alternatively, we could document the affine transform better towards this end? I.e., for a downprojection, you could use an affine of the form

$$ A = \begin{bmatrix} 1 & 0 & 0 & 0 \\\ 0 & 1 & 0 & 0 \\\ 0 & 0 & 0 & 1 \\\ \end{bmatrix} $$

and for an up-projection, you could use

$$ A = \begin{bmatrix} 1 & 0 & 0 \\\ 0 & 1 & 0 \\\ 0 & 0 & 0 \\\ 0 & 0 & 1 \\\ \end{bmatrix} $$

Additional translations can then do the job of controlling this behavior a bit more fine-grained.

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