ngff icon indicating copy to clipboard operation
ngff copied to clipboard

RFC5: a clearer structure for `byDimension`

Open dstansby opened this issue 2 months ago • 4 comments

Currently in RFC5 byDimension metadata looks like this:

{
  "type": "byDimension",
  "input": "high_dimensional_coordinatesystem_A",
  "output": "high_dimensional_coordinatesystem_B", 
  "transformations": [
    {
      "type": "scale",
      "input_axes": ["x", "y"],
      "output_axes": ["x", "y"],
      "scale": [0.5, 0.5]
    },
    {
      "type": "translation", 
      "input_axes": ["z"],
      "output_axes": ["z"],
      "translation": [10.0]
    }
  ]
}

There are two potential ways I can see to change this a bit to make it more consistent with how other transforms are defined:

  1. Currently, it's not possible to apply this transform to a coordinate given by a list of coordinate values. This is because the transform references named axes, which also need coordinate systems metadata to be interpreted (ie, a lookup into which axis name representes which axis index). I raised this for other transforms in my comment , and in response transpose was modified to remove references to named axes. For the same reasons I think it would be good to do the same for byDimension. Concretely, that would look like this:
{
  "type": "byDimension",
  "input": "high_dimensional_coordinatesystem_A",
  "output": "high_dimensional_coordinatesystem_B", 
  "transformations": [
    {
      "type": "scale",
      "input_axes": [0, 1],
      "output_axes": [0, 1],
      "scale": [0.5, 0.5]
    },
    {
      "type": "translation", 
      "input_axes": [2],
      "output_axes": [2],
      "translation": [10.0]
    }
  ]
}
  1. Transforms inside byDimension need fields not present on other transform objects, input_axes and output_axes. When implementing this means either building another object that specifically represents a transfrom inside byDimension, or adding two new optional fields (input_axes, output_axes) to the general transform type, and implementing validation to make sure these are only set inside when inside byDimension. Instead I'd propose that a mapping from transforms to input/output axes is stored in byDimension, like this:
{
  "type": "byDimension",
  "input": "high_dimensional_coordinatesystem_A",
  "output": "high_dimensional_coordinatesystem_B", 
  "input_axes": [["x", "y"], ["z"]],
  "output_axes": [["x", "y"], ["z"]],
  "transformations": [
    {
      "type": "scale",
      "scale": [0.5, 0.5]
    },
    {
      "type": "translation", 
      "translation": [10.0]
    }
  ]
}

This would also make validation simpler, because checking for unique input/output axes for each transform doesn't require traversing transformations. In reply to my original comment the only reason against this was given as

would require complicated mappings to subsets of coordinate systems.

but I don't think this more complicated, and as demonstrated above from an implementors point of view it's much less complicated to store the axes that each transformation acts on in byDimension instead of on each individual transform.

dstansby avatar Nov 02 '25 18:11 dstansby

Duplicate of #351?

jo-mueller avatar Nov 03 '25 09:11 jo-mueller

Nope, #351 concerns inverseOf, this concerns byDimension.

dstansby avatar Nov 03 '25 09:11 dstansby

Oh right. Sorry - heavy case of Monday 😅

jo-mueller avatar Nov 03 '25 09:11 jo-mueller

For the second point, another suggestion is:

{
  "type": "byDimension",
  "input": "high_dimensional_coordinatesystem_A",
  "output": "high_dimensional_coordinatesystem_B",
  "transformations": [
    {
      "input_axes": [0, 1],
      "output_axes": [0, 1],
      "transform": {
        "type": "scale",
        "scale": [0.5, 0.5]
      }
    },
    {
      "input_axes": [2],
      "output_axes": [2],
      "transform": {
        "type": "translation",
        "scale": [2]
      }
    }
  ]
}

dstansby avatar Nov 12 '25 15:11 dstansby