Closed will-moore closed 1 year ago
Thanks @will-moore. Is this staging anywhere otherwise I believe we should get this merged.
Interestingly what is missing at the moment is the fact the transformation for 13457537.zarr
should be considered as relative to the coordinate system of 13457227.zarr
.
Two related thoughts:
idr0101
as an example when entering the evaluation of the specification and its implementationsbioformats2raw.layout
group would allow to express this relationship.See also discussion at https://github.com/ome/ngff/pull/139#issuecomment-1277541235
(omeropy) sbesson@Sebastiens-MacBook-Pro-2 ~ % curl https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0101A/13457537.zarr/.zattrs
{
"_creator": {
"name": "omero-zarr",
"version": "0.1.dev314+g33e42b1"
},
"multiscales": [
{
"axes": [
{
"name": "t",
"type": "time"
},
{
"name": "c",
"type": "channel"
},
{
"name": "z",
"type": "space",
"units": "micrometer"
},
{
"name": "y",
"type": "space",
"units": "micrometer"
},
{
"name": "x",
"type": "space",
"units": "micrometer"
}
],
"datasets": [
{
"coordinateTransformations": [
{
"scale": [
1.0,
1.0,
0.4,
0.108335,
0.108335
],
"type": "scale"
},
{
"translation": [
0,
0,
1.2,
52.109135,
60.88427
],
"type": "translation"
}
],
"path": "0"
},
{
"coordinateTransformations": [
{
"scale": [
1.0,
1.0,
0.4,
0.21667,
0.21667
],
"type": "scale"
}
],
"path": "1"
},
{
"coordinateTransformations": [
{
"scale": [
1.0,
1.0,
0.4,
0.43334,
0.43334
],
"type": "scale"
}
],
"path": "2"
}
],
"version": "0.4"
}
],
"omero": {
"channels": [
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 1",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 2",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 3",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 4",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "0000FF",
"family": "linear",
"inverted": false,
"label": "DAPI",
"window": {
"end": 5000.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FF0000",
"family": "linear",
"inverted": false,
"label": "Hyb probe",
"window": {
"end": 100.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
}
],
"id": 1,
"rdefs": {
"defaultT": 0,
"defaultZ": 9,
"model": "color"
},
"version": "0.4"
}
}
Echoing Norman's question, I definitely feel that either the translation should be factorized at the multiscales
level or defined for each multiscale dataset.
I don't disagree, but playing devil's advocate... I wonder if this exposes an expectation of the spec that each dataset dict has the same list of coordinateTransformations
?
Currently, for v0.4 every one has to have scale
, and the only other option is translation
, so there's limited scope for divergence. But with v0.5 it will be possible to have lots of different transformations.
Probably in this case, we really should be applying the translation
at the multiscales
level. In fact, I assume the same is true for most transformations except scale
, since it would be unexpected for different resolutions of a pyramid to have different translation
or other transformations?
cc @bogovicj
@sbesson I've added translation
to the other dataasets for https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0101A/13457537.zarr
Also added https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0101A/13457539.zarr which instead has coordinateTransformation on the multiscales dict instead of the datasets. Strange that this MUST also have scale in order to be valid, even though I don't want to scale - so I added a no-op scale of 1,1,1,1,1
. See https://ome.github.io/ome-ngff-validator/?source=https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0101A/13457539.zarr
% curl https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0101A/13457537.zarr/.zattrs
{
"_creator": {
"name": "omero-zarr",
"version": "0.1.dev314+g33e42b1"
},
"multiscales": [
{
"axes": [
{
"name": "t",
"type": "time"
},
{
"name": "c",
"type": "channel"
},
{
"name": "z",
"type": "space",
"units": "micrometer"
},
{
"name": "y",
"type": "space",
"units": "micrometer"
},
{
"name": "x",
"type": "space",
"units": "micrometer"
}
],
"datasets": [
{
"coordinateTransformations": [
{
"scale": [
1.0,
1.0,
0.4,
0.108335,
0.108335
],
"type": "scale"
},
{
"translation": [
0,
0,
1.2,
52.109135,
60.88427
],
"type": "translation"
}
],
"path": "0"
},
{
"coordinateTransformations": [
{
"scale": [
1.0,
1.0,
0.4,
0.21667,
0.21667
],
"type": "scale"
},
{
"translation": [
0,
0,
1.2,
52.109135,
60.88427
],
"type": "translation"
}
],
"path": "1"
},
{
"coordinateTransformations": [
{
"scale": [
1.0,
1.0,
0.4,
0.43334,
0.43334
],
"type": "scale"
},
{
"translation": [
0,
0,
1.2,
52.109135,
60.88427
],
"type": "translation"
}
],
"path": "2"
}
],
"version": "0.4"
}
],
"omero": {
"channels": [
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 1",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 2",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 3",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 4",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "0000FF",
"family": "linear",
"inverted": false,
"label": "DAPI",
"window": {
"end": 5000.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FF0000",
"family": "linear",
"inverted": false,
"label": "Hyb probe",
"window": {
"end": 100.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
}
],
"id": 1,
"rdefs": {
"defaultT": 0,
"defaultZ": 9,
"model": "color"
},
"version": "0.4"
}
}
and
% curl https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0101A/13457539.zarr/.zattrs
{
"_creator": {
"name": "omero-zarr",
"version": "0.1.dev314+g33e42b1"
},
"multiscales": [
{
"axes": [
{
"name": "t",
"type": "time"
},
{
"name": "c",
"type": "channel"
},
{
"name": "z",
"type": "space",
"units": "micrometer"
},
{
"name": "y",
"type": "space",
"units": "micrometer"
},
{
"name": "x",
"type": "space",
"units": "micrometer"
}
],
"coordinateTransformations": [
{
"scale": [
1,
1,
1,
1,
1
],
"type": "scale"
},
{
"translation": [
0,
0,
1.2,
161.59,
176.44
],
"type": "translation"
}
],
"datasets": [
{
"coordinateTransformations": [
{
"scale": [
1.0,
1.0,
0.4,
0.108335,
0.108335
],
"type": "scale"
}
],
"path": "0"
},
{
"coordinateTransformations": [
{
"scale": [
1.0,
1.0,
0.4,
0.21667,
0.21667
],
"type": "scale"
}
],
"path": "1"
}
],
"version": "0.4"
}
],
"omero": {
"channels": [
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 1",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 2",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 3",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FFFFFF",
"family": "linear",
"inverted": false,
"label": "cy 4",
"window": {
"end": 1200.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "0000FF",
"family": "linear",
"inverted": false,
"label": "DAPI",
"window": {
"end": 5000.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
},
{
"active": true,
"coefficient": 1.0,
"color": "FF0000",
"family": "linear",
"inverted": false,
"label": "Hyb probe",
"window": {
"end": 100.0,
"max": 65535.0,
"min": 0.0,
"start": 0.0
}
}
],
"id": 1,
"rdefs": {
"defaultT": 0,
"defaultZ": 9,
"model": "color"
},
"version": "0.4"
}
}
Thanks @will-moore. Very useful to have representative samples capturing the different variants of the coordinateTransformations
defined in the OME-NGFF specification.
Strange that this MUST also have scale in order to be valid, even though I don't want to scale - so I added a no-op scale of 1,1,1,1,1.
Interesting. I had forgotten about this requirement and also confused at first as well. I suspect it comes the from strict semantics in https://ngff.openmicroscopy.org/0.4/#trafo-md that mandates that Each "multiscales" dictionary MAY contain the field "coordinateTransformations", describing transformations that are applied to all resolution levels in the same manner. The transformations MUST follow the same rules about allowed types, order, etc. as in "datasets:coordinateTransformations" and are applied after them.
.
Rather than using the no-op 1, 1, 1, 1, 1
scale transformation, I could imaging an alternate representation would be to store the scaling of the first resolution in physical units at the multiscales
level i.e.
{
"scale": [
1.0,
1.0,
0.4,
0.108335,
0.108335
],
"type": "scale"
},
{
"translation": [
0,
0,
1.2,
161.59,
176.44
],
"type": "translation"
}
and then the scale of the different datasets could be simply expressed as 1,1,1,1,1
, 1,1,2,2,2
, 1,1,1,4,4,4
...
@will-moore
Probably in this case, we really should be applying the translation at the multiscales level.
I agree - that's also how I would do it. But also think one should be allowed to put the translation in every dataset in the multiscales if that's what they want.
since it would be unexpected for different resolutions of a pyramid to have different translation or other transformations?
One common case where different levels should really have different translations is if the downsampling simply averages adjacent pixels.
Numbers indicate the coordinate of the center of the pixel, then averaging pixels with coordinates 0 and 1 gives a pixel with center 0.5.
| 0.0 | 1.0 |
| 0.5 |
But with v0.5 it will be possible to have lots of different transformations.
This is also a good point, I'd consider adding the restriction : different multiscale levels must be related to each other only through scale
and translation
transformations. Other transformations have to happen at the multiscales level. I don't know of anyone doing otherwise.
@sbesson Fixed https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0101A/13457539.zarr/.zattrs to have datasets scale of 1,1,1,1,1,
, 1,1,1,2,2
and apply pixel size scaling at the multiscales level.
@sbesson Could you merge this if you're happy with it, thanks.
Adds 2 images from https://github.com/ome/napari-ome-zarr/pull/32 This is the first example of coordinateTransforms
translate
, at the dataset level. Added this to keywords.