diff --git a/examples/multiscales_strict/multiscales_example.json b/examples/multiscales_strict/multiscales_example.json
index d6201f5b..0d16fde9 100644
--- a/examples/multiscales_strict/multiscales_example.json
+++ b/examples/multiscales_strict/multiscales_example.json
@@ -21,40 +21,40 @@
],
"datasets": [
{
- "path": "0",
+ "path": "s0",
"coordinateTransformations": [
{
// the voxel size for the first scale level (0.5 micrometer)
// and the time unit (0.1 milliseconds), which is the same for each scale level
"type": "scale",
"scale": [0.1, 1.0, 0.5, 0.5, 0.5],
- "input": "0",
+ "input": "s0",
"output": "intrinsic"
}
]
},
{
- "path": "1",
+ "path": "s1",
"coordinateTransformations": [
{
// the voxel size for the second scale level (downscaled by a factor of 2 -> 1 micrometer)
// and the time unit (0.1 milliseconds), which is the same for each scale level
"type": "scale",
"scale": [0.1, 1.0, 1.0, 1.0, 1.0],
- "input": "1",
+ "input": "s1",
"output": "intrinsic"
}
]
},
{
- "path": "2",
+ "path": "s2",
"coordinateTransformations": [
{
// the voxel size for the third scale level (downscaled by a factor of 4 -> 2 micrometer)
// and the time unit (0.1 milliseconds), which is the same for each scale level
"type": "scale",
"scale": [0.1, 1.0, 2.0, 2.0, 2.0],
- "input": "2",
+ "input": "s2",
"output": "intrinsic"
}
]
diff --git a/examples/multiscales_strict/multiscales_example_relative.json b/examples/multiscales_strict/multiscales_example_relative.json
index aa1456cb..bc51998c 100644
--- a/examples/multiscales_strict/multiscales_example_relative.json
+++ b/examples/multiscales_strict/multiscales_example_relative.json
@@ -38,23 +38,23 @@
}]
},
{
- "path": "1",
+ "path": "s1",
"coordinateTransformations": [{
- // the second scale level (downscaled by a factor of 2 relative to "0" in zyx)
+ // the second scale level (downscaled by a factor of 2 relative to "s0" in zyx)
"type": "scale",
"scale": [1, 1, 2, 2, 2],
- "input" : "/1",
- "output" : "array_0"
+ "input" : "s1",
+ "output" : "intrinsic"
}]
},
{
- "path": "2",
+ "path": "s2",
"coordinateTransformations": [{
- // the third scale level (downscaled by a factor of 4 relative to "0" in zyx)
+ // the third scale level (downscaled by a factor of 4 relative to "s0" in zyx)
"type": "scale",
"scale": [1, 1, 4, 4, 4],
- "input" : "/2",
- "output" : "array_0"
+ "input" : "s2",
+ "output" : "intrinsic"
}]
}
],
diff --git a/examples/multiscales_strict/multiscales_transformations.json b/examples/multiscales_strict/multiscales_transformations.json
index 94a35ec6..49876785 100644
--- a/examples/multiscales_strict/multiscales_transformations.json
+++ b/examples/multiscales_strict/multiscales_transformations.json
@@ -40,12 +40,12 @@
],
"datasets": [
{
- "path": "0",
+ "path": "s0",
"coordinateTransformations": [
{
"scale": [1, 1],
"type": "scale",
- "input": "0",
+ "input": "s0",
"output": "intrinsic"
}
]
diff --git a/examples/subspace/subspaceMultidim.json b/examples/subspace/subspaceMultidim.json
index b2200a47..6f381685 100644
--- a/examples/subspace/subspaceMultidim.json
+++ b/examples/subspace/subspaceMultidim.json
@@ -1,44 +1,87 @@
{
- "coordinateSystems": [
- {
- "name": "in",
- "axes": [
- { "name": "0", "type": "array" },
- { "name": "1", "type": "array" },
- { "name": "2", "type": "array" },
- { "name": "3", "type": "array" },
- { "name": "4", "type": "array" }
- ]
- },
- {
- "name": "out",
- "axes": [
- { "name": "x", "type": "space" },
- { "name": "y", "type": "space" },
- { "name": "z", "type": "space" }
- ]
- }
- ],
- "coordinateTransformations": [
- {
- "type": "byDimension",
- "name": "5D-to-3D-not-contiguous",
- "input": "in",
- "output": "out",
- "transformations": [
- {
- "type": "mapAxis",
- "mapAxis": { "0": "x", "2": "z" },
- "input_axes": [ "0", "2" ],
- "output_axes": [ "x", "z" ]
- },
+ "zarr_format": 3,
+ "node_type": "group",
+ "attributes": {
+ "ome": {
+ "version": "0.6.dev3",
+ "multiscales": [
{
- "type": "scale",
- "scale": [ 2 ],
- "input_axes": [ "1" ],
- "output_axes": [ "y" ]
+ "name": "multiscales",
+ "coordinateSystems": [
+ {
+ "name": "physical",
+ "axes": [
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ },
+ {
+ "name": "array_coordinates",
+ "axes": [
+ {
+ "type": "array",
+ "name": "dim_0",
+ "discrete": true
+ },
+ {
+ "type": "array",
+ "name": "dim_1",
+ "discrete": true
+ }
+ ]
+ }
+ ],
+ "datasets": [
+ {
+ "path": "array",
+ "coordinateTransformations": [
+ {
+ "type": "byDimension",
+ "output": "physical",
+ "input": "array",
+ "transformations": [
+ {
+ "type": "scale",
+ "output_axes": [
+ "x"
+ ],
+ "input_axes": [
+ "dim_1"
+ ],
+ "scale": [
+ 2
+ ]
+ },
+ {
+ "type": "translation",
+ "output_axes": [
+ "y"
+ ],
+ "input_axes": [
+ "dim_0"
+ ],
+ "translation": [
+ -10
+ ]
+ }
+ ],
+ "name": "transform-name"
+ }
+ ]
+ }
+ ]
}
]
}
- ]
-}
+ }
+}
\ No newline at end of file
diff --git a/examples/subspace/subspacePermute.json b/examples/subspace/subspacePermute.json
index 4594e8c7..7051b6a3 100644
--- a/examples/subspace/subspacePermute.json
+++ b/examples/subspace/subspacePermute.json
@@ -1,26 +1,71 @@
{
- "coordinateSystems" : [
- { "name" : "in", "axes" : [ {"name" : "i"}, {"name" : "j" } ]},
- { "name" : "out", "axes" : [ {"name" : "x"}, {"name" : "y" } ]}
- ],
- "coordinateTransformations" : [
- {
- "type" : "byDimension",
- "input" : "in",
- "output" : "out",
- "transformations" : [
+ "zarr_format": 3,
+ "node_type": "group",
+ "attributes": {
+ "ome": {
+ "version": "0.6.dev3",
+ "multiscales": [
{
- "type": "identity",
- "input_axes" : ["j"],
- "output_axes" : ["x"]
- },
- {
- "type": "scale",
- "scale" : [2],
- "input_axes" : ["i"],
- "output_axes" : ["y"]
+ "name": "multiscales",
+ "coordinateSystems": [
+ {
+ "name": "physical",
+ "axes": [
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ },
+ {
+ "name": "array_coordinates",
+ "axes": [
+ {
+ "type": "array",
+ "name": "dim_0",
+ "discrete": true
+ },
+ {
+ "type": "array",
+ "name": "dim_1",
+ "discrete": true
+ }
+ ]
+ }
+ ],
+ "datasets": [
+ {
+ "path": "array",
+ "coordinateTransformations": [
+ {
+ "type": "scale",
+ "output": "array_coordinates",
+ "input": "array",
+ "name": "default-scale",
+ "scale": [1, 1]
+ }
+ ]
+ }
+ ],
+ "coordinateTransformations": [
+ {
+ "type": "mapAxis",
+ "output": "physical",
+ "input": "array_coordinates",
+ "name": "transform-name",
+ "mapAxis": [1, 0]
+ }
+ ]
}
]
}
- ]
-}
+ }
+}
\ No newline at end of file
diff --git a/examples/transformations/inverseOf.json b/examples/transformations/inverseOf.json
deleted file mode 100644
index 4c77e9ea..00000000
--- a/examples/transformations/inverseOf.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "coordinateSystems" : [
- { "name" : "moving", "axes" : [{"name" : "y-moving"}, {"name":"x-moving"}] },
- { "name" : "fixed", "axes" : [{"name" : "y-fixed"}, {"name":"x-fixed"}] }
- ],
- "coordinateTransformations" : [
- {
- "type": "inverseOf",
- "transformation" : {
- "type": "displacements",
- "path": "path/to/displacements"
- },
- "input" : "moving",
- "output" : "fixed"
- }
- ]
-}
diff --git a/examples/transformations/mapAxis1.json b/examples/transformations/mapAxis1.json
index 6aeeca52..9bdb2883 100644
--- a/examples/transformations/mapAxis1.json
+++ b/examples/transformations/mapAxis1.json
@@ -8,14 +8,14 @@
{
"name": "equivalent to identity",
"type": "mapAxis",
- "mapAxis": { "x":"i", "y":"j" },
+ "mapAxis": [0, 1],
"input": "in",
"output": "out1"
},
{
"name": "permutation",
"type": "mapAxis",
- "mapAxis": { "y":"i", "x":"j" },
+ "mapAxis": [1, 0],
"input": "in",
"output": "out2"
}
diff --git a/examples/transformations/mapAxis2.json b/examples/transformations/mapAxis2.json
index 0c008475..db214a00 100644
--- a/examples/transformations/mapAxis2.json
+++ b/examples/transformations/mapAxis2.json
@@ -8,14 +8,14 @@
{
"name": "projection down",
"type": "mapAxis",
- "mapAxis": { "x": "b" },
+ "mapAxis": [1],
"input": "in",
"output": "out_down"
},
{
"name": "projection up",
"type": "mapAxis",
- "mapAxis": { "z": "b", "y": "b", "x": "a" },
+ "mapAxis": [1, 1, 0],
"input": "in",
"output": "out_up"
}
diff --git a/index.md b/index.md
index f0c74082..c58d87f1 100644
--- a/index.md
+++ b/index.md
@@ -139,6 +139,39 @@ A well group SHOULD NOT be present if there are no images in the well.
└── ... # Other rows
```
+### Scene
+(scene-format)=
+
+The following specification describes the hierarchy of Zarr groups for a scene dataset.
+The group above the images defines a scene, which is a collection of images that share a spatial relationship with each other (see [coordinate transformations metadata](#coord-trafo-md)).
+It MUST implement the [scene specification](#scene-md).
+
+For transformations that store data or parameters in a Zarr array,
+those Zarr arrays SHOULD be stored in a Zarr group on the same level as images called "coordinateTransformations".
+
+
+store.zarr # One scene dataset
+│
+├── zarr.json # coordinate transformations describing the relationship between two image coordinate systems
+│ # are stored in the "scene" dictionary here.
+│ # I.e., transformations between coordinate systems in the 'volume' and 'crop' multiscale images are stored here.
+│
+├── coordinateTransformations # transformations that use array storage for their parameters should go in a Zarr group named "coordinateTransformations".
+│ └── displacements # for example, a Zarr array containing a displacement field
+│ └── zarr.json
+│
+├── volume
+│ ├── zarr.json # group level attributes (multiscales)
+│ └── 0 # a group containing the 0th scale
+│ └── image # a Zarr array
+│ └── zarr.json # physical coordinate system and transformations here
+└── crop
+ ├── zarr.json # group level attributes (multiscales)
+ └── 0 # a group containing the 0th scale
+ └── image # a Zarr array
+ └── zarr.json # physical coordinate system and transformations here
+
+
## OME-Zarr Metadata
(metadata)=
@@ -200,14 +233,14 @@ refer to different physical entities and therefore should not be analyzed jointl
Tasks that require images, annotations, regions of interest, etc.,
SHOULD ensure that they are in the same coordinate system (same name and location within the Zarr hierarchy, with identical axes)
or can be transformed to the same coordinate system before doing analysis.
-See the [example below](#spec:example:coordinate_transformation).
+See the [example below](spec:example:coordinate_transformation).
#### "axes" metadata
`axes` describes the dimensions of a coordinate systems
and adds an interpretation to the samples along that dimension.
-It is a list of dictionaries,
+It is an array of dictionaries,
where each dictionary describes a dimension (axis) and:
- MUST contain the field `name` that gives the name for this dimension.
The values MUST be unique across all `name` fields in the same coordinate system.
@@ -226,8 +259,6 @@ where each dictionary describes a dimension (axis) and:
The value MUST be a string,
and can provide a longer name or description of an axis and its properties.
-The length of `axes` MUST be equal to the number of dimensions of the arrays that contain the image data.
-
Arrays are inherently discrete (see Array coordinate systems, below)
but are often used to store discrete samples of a continuous variable.
The continuous values "in between" discrete samples can be retrieved using an *interpolation* method.
@@ -275,7 +306,7 @@ As with all coordinate systems, the dimension names must be unique and non-null.
```
For example, if 0/zarr.json contains:
-```jsonc
+```json
{
"zarr_format": 3,
"node_type": "array",
@@ -288,7 +319,7 @@ Then `dim_0` has length 4, `dim_1` has length 3, and `dim_2` has length 5.
:::
-The axes and their order align with the shape of the corresponding zarr array,
+The axes and their order align with the shape of the corresponding Zarr array,
and whose data depends on the byte order used to store chunks.
As described in the [Zarr array metadata](https://zarr.readthedocs.io/en/stable/spec/v3.html#arrays),
the last dimension of an array in "C" order are stored contiguously on disk or in-memory when directly loaded.
@@ -407,27 +438,25 @@ They:
- MUST contain the field `type` (string).
- MUST contain any other fields required by the given `type` (see table below).
- MUST contain the field `output` (string),
- unless part of a `sequence` or `inverseOf` (see details).
+ unless part of a wrapper transform (, i.e., [`sequence`](#sequence-md), [`bijection`](#bijection-md), [`byDimension`](#bydimension-md), see details).
- MUST contain the field `input` (string),
- unless part of a `sequence` or `inverseOf` (see details).
+ unless part of a wrapper transform (, i.e., [`sequence`](#sequence-md), [`bijection`](#bijection-md), [`byDimension`](#bydimension-md), see details).
- MAY contain the field `name` (string).
- Its value MUST be unique across all `name` fields for coordinate transformations.
+ Its value MUST be unique across all `name` fields for all coordinate transformations in the same list.
- Parameter values MUST be compatible with input and output space dimensionality (see details).
-
The following transformations are supported:
| Type | Fields | Description |
|------|--------|-------------|
| [`identity`](#identity-md) | | The identity transformation is the do-nothing transformation and is typically not explicitly defined. |
| [`mapAxis`](#mapaxis-md) | `"mapAxis":List[number]` | an axis permutation as a transpose array of integer indices that refer to the ordering of the axes in the respective coordinate system. |
-| [`translation`](#translation-md) | one of:
`"translation":List[number]`,
`"path":str` | Translation vector, stored either as a list of numbers (`"translation"`) or as a zarr array at a location in this container (`path`). |
-| [`scale`](#scale-md) | one of:
`"scale":List[number]`,
`"path":str` | Scale vector, stored either as a list of numbers (`scale`) or as a zarr array at a location in this container (`path`). |
-| [`affine`](#affine-md) | one of:
`"affine":List[List[number]]`,
`"path":str` | 2D affine transformation matrix stored either with JSON (`affine`) or as a zarr array at a location in this container (`path`). |
-| [`rotation`](#rotation-md) | one of:
`"rotation":List[List[number]]`,
`"path":str` | 2D rotation transformation matrix stored as an array stored either with json (`rotation`) or as a zarr array at a location in this container (`path`).|
+| [`translation`](#translation-md) | one of:
`"translation":List[number]`,
`"path":str` | Translation vector, stored either as an array of numbers (`"translation"`) or as a Zarr array at a location in this container (`path`). |
+| [`scale`](#scale-md) | one of:
`"scale":List[number]`,
`"path":str` | Scale vector, stored either as an array of numbers (`scale`) or as a Zarr array at a location in this container (`path`). |
+| [`affine`](#affine-md) | one of:
`"affine":List[List[number]]`,
`"path":str` | 2D affine transformation matrix stored either with JSON (`affine`) or as a Zarr array at a location in this container (`path`). |
+| [`rotation`](#rotation-md) | one of:
`"rotation":List[List[number]]`,
`"path":str` | 2D rotation transformation matrix stored as an array stored either with json (`rotation`) or as a Zarr array at a location in this container (`path`).|
| [`sequence`](#sequence-md) | `"transformations":List[Transformation]` | sequence of transformations. Applying the sequence applies the composition of all transforms in the list, in order. |
-| [`displacements`](#coordinates-displacements-md) | `"path":str`
`"interpolation":str` | Displacement field transformation located at `path`. |
-| [`coordinates`](#coordinates-displacements-md) | `"path":str`
`"interpolation":str` | Coordinate field transformation located at `path`. |
-| [`inverseOf`](#inverseof-md) | `"transformation":Transformation` | The inverse of a transformation. Useful if a transform is not closed-form invertible. See forward and inverse of [bijections](#bijection-md) for details and examples. |
+| [`displacements`](#coordinates-displacements-md) | `"path":str` | Displacement field transformation located at `path`. |
+| [`coordinates`](#coordinates-displacements-md) | `"path":str` | Coordinate field transformation located at `path`. |
| [`bijection`](#bijection-md) | `"forward":Transformation`
`"inverse":Transformation` | An invertible transformation providing an explicit forward transformation and its inverse. |
| [`byDimension`](#bydimension-md) | `"transformations":List[Transformation]`,
`"input_axes": List[str]`,
`"output_axes": List[str]` | A high dimensional transformation using lower dimensional transformations on subsets of dimensions. |
@@ -472,161 +501,101 @@ Conforming readers:
- SHOULD be able to apply transformations to points;
- SHOULD be able to apply transformations to images;
-Coordinate transformations can be stored in multiple places to reflect different usecases.
+Coordinate transformations can be stored in multiple places to reflect different use cases.
-- Transformations in individual multiscale datasets represent a special case of transformations
- and are explained [below](#multiscales-md).
-- Additional transformations for single multiscale images MUST be stored under a field `coordinateTransformations`
- in the multiscales dictionaries.
- This `coordinateTransformations` field MUST contain a list of valid [transformations](#trafo-types-md).
-- Transformations between two or more images MUST be stored in the attributes of a parent zarr group.
- For transformations that store data or parameters in a zarr array,
- those zarr arrays SHOULD be stored in a zarr group called `coordinateTransformations`.
-
+- **Inside `multiscales > datasets`**: `coordinateTransformations` herein MUST be restricted
+ to a single `scale`, `identity` or `sequence` of a scale followed by a translation transformation.
+ For more information, see [multiscales section below](#multiscales-md).
+- **Inside `multiscales > coordinateTransformations`**: Additional transformations for single multiscale images MAY be stored here.
+ The `coordinateTransformations` field MUST contain an array of valid [transformations](#trafo-types-md).
+ The input to every one of these transformations MUST be the intrinsic coordinate system.
+ The output can be another coordinate system defined under `multiscales > coordinateSystems`.
+
+- **Inside `scene > coordinateTransformations`**: Transformations between two or more images
+ MUST be stored in the attributes of a [`scene` dictionary](#scene-md) in a [scene Zarr group](#scene-format).
+ In this case, the `input` and `output` values are dictionaries
+ that refer to coordinate systems in the same zarr.json or in the metadata of multiscale image subgroups.
+
+This separation of transformations (inside `multiscales > datasets`, under `multiscales > coordinateTransformations` and under `scene > coordinateTransformations`) provides flexibility for different use cases while still maintaining a level of rigidity for implementations.
-
-store.zarr # Root folder of the zarr store
-│
-├── zarr.json # coordinate transformations describing the relationship between two image coordinate systems
-│ # are stored in the attributes of their parent group.
-│ # transformations between coordinate systems in the 'volume' and 'crop' multiscale images are stored here.
-│
-├── coordinateTransformations # transformations that use array storage for their parameters should go in a zarr group named "coordinateTransformations".
-│ └── displacements # for example, a zarr array containing a displacement field
-│ └── zarr.json
-│
-├── volume
-│ ├── zarr.json # group level attributes (multiscales)
-│ └── 0 # a group containing the 0th scale
-│ └── image # a zarr array
-│ └── zarr.json # physical coordinate system and transformations here
-└── crop
- ├── zarr.json # group level attributes (multiscales)
- └── 0 # a group containing the 0th scale
- └── image # a zarr array
- └── zarr.json # physical coordinate system and transformations here
-
+#### Additional details
-:::{dropdown} Example
-(spec:example:coordinate_transformation)=
-Two instruments simultaneously image the same sample from two different angles,
-and the 3D data from both instruments are calibrated to "micrometer" units.
-An analysis of sample A requires measurements from images taken from both instruments at certain points in space.
-Suppose a region of interest (ROI) is determined from the image obtained from instrument 2,
-but quantification from that region is needed for instrument 1.
-Since measurements were collected at different angles,
-a measurement by instrument 1 at the point with image array coordinates (x,y,z)
-may not correspond to the measurement at the same array coordinates in instrument 2
-(i.e., it may not be the same physical location in the sample).
-To analyze both images together, they must be transformed to a common coordinate system.
+**Omitting `input`/`output`**: Coordinate transformations MUST specify their input and output coordinate systems
+using the `input` and `output` fields.
+These fields MUST correspond to the name of a coordinate system or the path to a multiscales group.
+Exceptions are if the coordinate transformation is wrapped in another transformation,
+e.g. as part of a `sequence`, `byDimension` or `bijection`.
+In these cases, the `input` and `output` fields MAY be omitted or null.
-The set of coordinate transformations encodes relationships between coordinate systems,
-specifically, how to convert points from one coordinate system to another.
-Implementations can apply the coordinate transform to images or points
-in coordinate system `sampleA_instrument2` to bring them into the `sampleA_instrument1` coordinate system.
-In this case, image data within the ROI defined in image2 should be transformed to the `sampleA_instrument1` coordinate system,
-then used for quantification with the instrument 1 image.
+**Graph connectedness**: The coordinate systems defined in the [multiscales metadata](#multiscales-md)
+and the [`scene` metadata](#scene-md) combined with the coordinate transformations form a transformations graph.
+In this graph, coordinate systems represent nodes and coordinate transformations represent edges.
+The graph MUST be fully connected in the sense that any two coordinate systems in the metadata
+MUST be connected by a sequence of edges represented by coordinate transformations.
+Coordinate systems that are connected by a non-invertible transformation count as connected in this sense, even though graph traversal may not be closed-form computable in every direction.
-The `coordinateTransformations` in the parent-level metadata would contain the following data.
-The transformation parameters are stored in a separate zarr-group
-under `coordinateTransformations/sampleA_instrument2-to-instrument1` as shown above.
+Coordinate transformations are functions of *points* in the input space to *points* in the output space.
+We call this the "forward" direction.
+Points are ordered lists of coordinates,
+where a coordinate is the location/value of that point along its corresponding axis.
+The indexes of axis dimensions correspond to indexes into transformation parameter arrays (see examples).
+
+**Image rendering**: When rendering transformed images and interpolating,
+implementations may need the "inverse" transformation - from the fixed
+image's to the source image's coordinate system. This transformation may
+not explicitly exist, but might be the require computing the inverse
+(in closed form) of an explicitly specified forward transformation.
+
+Inverse transformations used for image rendering may be specified
+by specifying the inverse transform directly - with the `input` referring
+to the the fixed image's coordinate system and the `output` referring to
+the the source image's coordinate system. If an operation is requested
+that requires the inverse of a transformation that can not be inverted in
+closed-form, implementations MAY estimate an inverse, or MAY output a warning
+that the requested operation is unsupported.
-```json
-"coordinateTransformations": [
- {
- "type": "affine",
- "path": "coordinateTransformations/sampleA_instrument2-to-instrument1",
- "input": "sampleA_instrument2",
- "output": "sampleA_instrument1"
- }
-]
-```
+:::{dropdown} Example
-And the image at the path `sampleA_instrument1` would have the following as the first coordinate system:
+Implementations SHOULD be able to compute and apply the inverse of some coordinate
+transformations when they are computable in closed-form (as the
+[Transformation types](#trafo-types-md) section below indicates).
+Implementations should be able to render the moving image into the fixed
+image by computing the inverse of this transformation.
```json
-"coordinateSystems": [
- {
- "name": "sampleA-instrument1",
- "axes": [
- {"name": "z", "type": "space", "unit": "micrometer"},
- {"name": "y", "type": "space", "unit": "micrometer"},
- {"name": "x", "type": "space", "unit": "micrometer"}
- ]
- },
-]
+{
+ "type": "",
+ "input": "moving image",
+ "output": "fixed image"
+}
```
-The image at path `sampleA_instrument2` would have this as the first listed coordinate system:
+Software libraries that perform image registration often return the transformation
+from fixed image coordinates to moving image coordinates, because this "inverse"
+transformation is most often required when rendering the transformed moving image.
+Implementations should be able to render the moving image into the fixed image by
+applying this transformation directly.
```json
-[
- {
- "name": "sampleA-instrument2",
- "axes": [
- {"name": "z", "type": "space", "unit": "micrometer"},
- {"name": "y", "type": "space", "unit": "micrometer"},
- {"name": "x", "type": "space", "unit": "micrometer"}
- ]
- }
-],
+{
+ "type": "",
+ "input": "fixed image",
+ "output": "moving image"
+}
```
-:::
-
-#### Additional details
-Most coordinate transformations MUST specify their input and output coordinate systems
-using `input` and `output` with a string value
-that MUST correspond to the name of a coordinate system or the path to a multiscales group.
-Exceptions are if the coordinate transformation is wrapped in another transformation,
-e.g. as part of a `transformations` list of a `sequence` or
-as `transformation` of an `inverseOf` transformation.
-In these two cases input and output could, in some cases, be omitted (see below for details).
-If unused, the `input` and `output` fields MAY be null.
-
-If used in a parent-level zarr-group, the `input` and `output` fields
-can be the name of a `coordinateSystem` in the same parent-level group or the path to a multiscale image group.
-If either `input` or `output` is a path to a multiscale image group,
-the authoritative coordinate system for the respective image is the first `coordinateSystem` defined therein.
-If the names of `input` or `output` correspond to both an existing path to a multiscale image group
-and the name of a `coordinateSystem` defined in the same metadata document,
-the `coordinateSystem` MUST take precedent.
-
-For usage in multiscales, see [the multiscales section](#multiscales-md) for details.
-
-Coordinate transformations are functions of *points* in the input space to *points* in the output space.
-We call this the "forward" direction.
-Points are ordered lists of coordinates,
-where a coordinate is the location/value of that point along its corresponding axis.
-The indexes of axis dimensions correspond to indexes into transformation parameter arrays.
-
-When rendering transformed images and interpolating,
-implementations may need the "inverse" transformation -
-from the output to the input coordinate system.
-Inverse transformations will not be explicitly specified
-when they can be computed in closed form from the forward transformation.
-Inverse transformations used for image rendering may be specified using
-the `inverseOf` transformation type, for example:
+Implementations are not expected to be able to to render the moving image
+into the fixed image given this transformation. They may attempt
+to do so by estimating the transformations' inverse if they choose to.
```json
{
- "type": "inverseOf",
- "transformation" : {
- "type": "displacements",
- "path": "/path/to/displacements",
- },
- "input": "input_image",
- "output": "output_image",
+ "type": "",
+ "input": "moving image",
+ "output": "fixed image"
}
```
-
-Implementations SHOULD be able to compute and apply
-the inverse of some coordinate transformations when they are computable
-in closed-form (as the [Transformation types](#trafo-types-md) section below indicates).
-If an operation is requested that requires
-the inverse of a transformation that can not be inverted in closed-form,
-implementations MAY estimate an inverse,
-or MAY output a warning that the requested operation is unsupported.
+:::
#### Matrix transformations
(matrix-trafo-md)=
@@ -634,45 +603,11 @@ or MAY output a warning that the requested operation is unsupported.
Two transformation types ([affine](#affine-md) and [rotation](#rotation-md)) are parametrized by matrices.
Matrices are applied to column vectors that represent points in the input coordinate system.
The first and last axes in a coordinate system correspond to the top and bottom entries in the column vector, respectively.
-Matrices are stored as two-dimensional arrays, either as json or in a zarr array.
-When stored as a 2D zarr array, the first dimension indexes rows and the second dimension indexes columns
+Matrices are stored as two-dimensional arrays, either as json or in a Zarr array.
+When stored as a 2D Zarr array, the first dimension indexes rows and the second dimension indexes columns
(e.g., an array of `"shape":[3,4]` has 3 rows and 4 columns).
When stored as a 2D json array, the inner array contains rows (e.g. `[[1,2,3], [4,5,6]]` has 2 rows and 3 columns).
-:::{dropdown} Example
-
-For matrix transformations, points in the coordinate system:
-
-```json
-{
- "name" : "in",
- "axes" : [
- {"name" : "z"},
- {"name" : "y"},
- {"name":"x"}
- ]
-},
-```
-
-are represented as column vectors:
-
-```
-[z]
-[y]
-[x]
-```
-
-As a result, transforming the point `[z,y,x]=[1,2,3]` with the matrix `[[0,1,0],[-1,0,0],[0,0,-1]]` results in the point `[2,-1,3]`
-because it is computed with the matrix-vector multiplication:
-
-```
-[ 0 1 0] [1] [ 2]
-[-1 0 0] [2] = [-1]
-[ 0 0 -1] [3] [-3]
-```
-
-:::
-
#### Transformation types
(trafo-types-md)=
@@ -690,11 +625,7 @@ The position of the i-th axis of the output coordinate system
is set to the position of the ith axis of the input coordinate system.
`identity` transformations are invertible.
-The `input` and `output` fields MAY be omitted if wrapped in another transformation that provides `input`/`output`
-(e.g., [`sequence`](#sequence-md), [`inverseOf`](#inverseof-md), ['byDimension](#bydimension-md) or [`bijection`](#bijection-md)).
-
:::{dropdown} Example
-:animate: fade-in
```{literalinclude} examples/transformations/identity.json
:language: json
@@ -722,12 +653,11 @@ Each index MUST appear exactly once in the array.
The value at position `i` in the array indicates which input axis becomes the `i`-th output axis.
`mapAxis` transforms are invertible.
-The `input` and `output` fields MAY be omitted if wrapped in another transformation that provides `input`/`output`
-(e.g., [`sequence`](#sequence-md), [`inverseOf`](#inverseof-md), ['byDimension](#bydimension-md) or [`bijection`](#bijection-md)).
+**mapAxis**
+: The axis permutation stored as a JSON array of integers.
:::{dropdown} Example 1
-:animate: fade-in
```{literalinclude} examples/transformations/mapAxis1.json
:language: json
@@ -750,7 +680,6 @@ y = i
:::
:::{dropdown} Example 2
-:animate: fade-in
```{literalinclude} examples/transformations/mapAxis2.json
:language: json
@@ -780,19 +709,11 @@ Input and output dimensionality MUST be identical
and MUST equal the the length of the "translation" array (N).
`translation` transformations are invertible.
-The `input` and `output` fields MAY be omitted if wrapped in another transformation that provides `input`/`output`
-(e.g., [`sequence`](#sequence-md), [`inverseOf`](#inverseof-md), ['byDimension](#bydimension-md) or [`bijection`](#bijection-md)).
-
-path
-: The path to a zarr-array containing the translation parameters.
-The array at this path MUST be 1D, and its length MUST be `N`.
-
-translation
-: The translation parameters stored as a JSON list of numbers.
-The list MUST have length `N`.
+**translation**
+: The translation parameters stored as a JSON array of numbers.
+The array MUST have length `N`.
:::{dropdown} Example
-:animate: fade-in
```{literalinclude} examples/transformations/translation.json
:language: json
@@ -816,19 +737,11 @@ and MUST equal the the length of the "scale" array (N).
Values in the `scale` array SHOULD be non-zero;
in that case, `scale` transformations are invertible.
-The `input` and `output` fields MAY be omitted if wrapped in another transformation that provides `input`/`output`
-(e.g., [`sequence`](#sequence-md), [`inverseOf`](#inverseof-md), [`byDimension`](#bydimension-md) or [`bijection`](#bijection-md)).
-
-path
-: The path to a zarr-array containing the scale parameters.
-The array at this path MUST be 1D, and its length MUST be `N`.
-
-scale
-: The scale parameters are stored as a JSON list of numbers.
-The list MUST have length `N`.
+**scale**
+: The scale parameters are stored as a JSON array of numbers.
+The array MUST have length `N`.
:::{dropdown} Example 1
-:animate: fade-in
```{literalinclude} examples/transformations/scale.json
:language: json
@@ -845,7 +758,6 @@ i.e., the mapping from the first input axis to the first output axis is determin
:::
:::{dropdown} Example 2
-:animate: fade-in
If the data contains discrete axes (e.g., channels),
these axes are typically not transformed, but must be represented in the scale parameters.
@@ -863,22 +775,18 @@ They are represented as the upper `(M)x(N+1)` sub-matrix of a `(M+1)x(N+1)` matr
coordinates](https://en.wikipedia.org/wiki/Homogeneous_coordinates) (see examples).
This transformation type may be (but is not necessarily) invertible
when `N` equals `M`.
-The matrix MUST be stored as a 2D array either as json or as a zarr array.
+The matrix MUST be stored as a 2D array either as json or as a Zarr array.
-The `input` and `output` fields MAY be omitted if wrapped in another transformation that provides `input`/`output`
-(e.g., [`sequence`](#sequence-md), [`inverseOf`](#inverseof-md), ['byDimension](#bydimension-md) or [`bijection`](#bijection-md)).
-
-path
-: The path to a zarr-array containing the affine parameters.
+**path**
+: The path to a Zarr-array containing the affine parameters.
The array at this path MUST be 2D whose shape MUST be `(M)x(N+1)`.
-affine
+**affine**
: The affine parameters stored in JSON.
The matrix MUST be stored as 2D nested array (an array of arrays of numbers)
where the outer array MUST be length `M` and the inner arrays MUST be length `N+1`.
:::{dropdown} Example 1
-:animate: fade-in
A 2D-2D example:
```{literalinclude} examples/transformations/affine2d2d.json
@@ -905,7 +813,6 @@ where the last row `[0 0 1]` is omitted in the JSON representation.
:::
:::{dropdown} Example 2
-:animate: fade-in
An example with two dimensional inputs and three dimensional outputs.
The affine transformation adds a translation by 1 along the new z-axis.
@@ -939,7 +846,6 @@ where the last row `[0 0 1]` is omitted in the JSON representation.
:::
:::{dropdown} Example 3
-:animate: fade-in
If the image data contains discrete axes (e.g., channels),
these axes are typically not transformed, but must be represented in the transformation matrix.
@@ -956,23 +862,19 @@ When possible, a rotation transformation SHOULD be used instead of an equivalent
Input and output dimensionality (N) MUST be identical.
Rotations are stored as `NxN` matrices, see below,
and MUST have determinant equal to one, with orthonormal rows and columns.
-The matrix MUST be stored as a 2D array either as json or in a zarr array.
+The matrix MUST be stored as a 2D array either as json or in a Zarr array.
`rotation` transformations are invertible.
-The `input` and `output` fields MAY be omitted if wrapped in another transformation that provides `input`/`output`
-(e.g., [`sequence`](#sequence-md), [`inverseOf`](#inverseof-md), ['byDimension](#bydimension-md) or [`bijection`](#bijection-md)).
-
-path
+**path**
: The path to an array containing the affine parameters.
The array at this path MUST be 2D whose shape MUST be `N x N`.
-rotation
+**rotation**
: The parameters stored in JSON.
The matrix MUST be stored as a 2D nested array (an array of arrays of numbers) where the outer array MUST be length `N`
and the inner arrays MUST be length `N`.
:::{dropdown} Example
-:animate: fade-in
A 2D example
```{literalinclude} examples/transformations/rotation.json
@@ -987,37 +889,6 @@ y = 1*i + 0*j
```
:::
-##### inverseOf
-(inverseOf-md)=
-
-An `inverseOf` transformation contains another transformation (often non-linear),
-and indicates that transforming points from output to input coordinate systems
-is possible using the contained transformation.
-Transforming points from the input to the output coordinate systems
-requires the inverse of the contained transformation (if it exists).
-
-The `input` and `output` fields MAY be omitted for `inverseOf` transformations
-if those fields may be omitted for the transformation it wraps.
-
-```{note}
-Software libraries that perform image registration
-often return the transformation from fixed image coordinates to moving image coordinates,
-because this "inverse" transformation is most often required
-when rendering the transformed moving image.
-Results such as this may be enclosed in an `inverseOf` transformation.
-This enables the "outer" coordinate transformation to specify the moving image coordinates
-as `input` and fixed image coordinates as `output`,
-a choice that many users and developers find intuitive.
-```
-
-:::{dropdown} Example
-:animate: fade-in
-
-```{literalinclude} examples/transformations/inverseOf.json
-:language: json
-```
-:::
-
##### sequence
(sequence-md)=
@@ -1025,15 +896,12 @@ A `sequence` transformation consists of an ordered array of coordinate transform
and is invertible if every coordinate transform in the array is invertible
(though could be invertible in other cases as well).
To apply a sequence transformation to a point in the input coordinate system,
-apply the first transformation in the list of transformations.
+apply the first transformation in the array of transformations.
Next, apply the second transformation to the result.
Repeat until every transformation has been applied.
The output of the last transformation is the result of the sequence.
-A sequence transformation MUST NOT be part of another sequence transformation.
-The `input` and `output` fields MUST be included for sequence transformations.
-
-transformations
+**transformations**
: A non-empty array of transformations.
:::{note}
@@ -1051,7 +919,6 @@ f2(f1(f0(x)))
:::
:::{dropdown} Example
-:animate: fade-in
This sequence:
@@ -1085,9 +952,6 @@ These transformation types refer to an array at location specified by the `path`
The input and output coordinate systems for these transformations (`input` / `output` coordinate systems)
constrain the array size and the coordinate system metadata for the array (field `coordinateSystem`).
-The `input` and `output` fields MAY be omitted if wrapped in another transformation that provides `input`/`output`
-(e.g., [`sequence`](#sequence-md), [`inverseOf`](#inverseof-md), [`byDimension`](#bydimension-md) or [`bijection`](#bijection-md)).
-
* If the input coordinate system has `N` axes,
the array at location path MUST have `N+1` dimensions
* The field coordinate system MUST contain an axis identical to every axis
@@ -1105,20 +969,8 @@ of the `i`th output axis. See the example below.
but implementations MAY approximate their inverses.
Metadata for these coordinate transforms have the following fields:
-
- - path
- - The location of the coordinate array in this (or another) container.
- - interpolation
- - The
interpolation attributes MAY be provided.
- Its value indicates the interpolation to use
- if transforming points not on the array's discrete grid.
- Values could be:
-
- linear (default)
- nearest
- cubic
-
-
+**path**
+: The location of the coordinate array in this (or another) container.
For both `coordinates` and `displacements`,
@@ -1142,10 +994,9 @@ For `displacements`:
* `coordinateSystem` metadata MUST have exactly one axis with `"type" : "displacement"`
* the shape of the array along the "displacement" axis must be exactly `N`
-* `input` and `output` MUST have an equal number of dimensions.
+* input and output coordinate systems MUST have an equal number of dimensions.
:::{dropdown} Example 1
-:animate: fade-in
For example, in 1D:
```json
{
@@ -1192,7 +1043,6 @@ x =
:::
:::{dropdown} Example 2
-:animate: fade-in
A 1D example displacement field:
```json
{
@@ -1240,7 +1090,6 @@ hence the output is `1.0 + (-0.5) = 0.5`.
:::
:::{dropdown} Example 3
-:animate: fade-in
In this example, the array located at `displacementField` MUST have three dimensions.
One dimension MUST correspond to an axis with `type : displacement` (in this example, the last dimension),
@@ -1288,24 +1137,20 @@ I.e. the y-displacement is first, because the y-axis is the first element of the
`byDimension` transformations build a high dimensional transformation
using lower dimensional transformations on subsets of dimensions.
-The `input` and `output` fields MUST always be included for this transformations type.
-
-
- - transformations
- - Each child transformation MUST contain
input_axes and output_axes fields
- whose values are arrays of strings.
- Every axis name in a child transformation's input_axes
- MUST correspond to a name of some axis in this parent object's input coordinate system.
- Every axis name in the parent byDimension's output coordinate system
- MUST appear in exactly one child transformation's output_axes array.
- Each child transformation's input_axes and output_axes arrays
- MUST have the same length as that transformation's parameter arrays.
-
-
+**transformations**
+: MUST be an array of wrapped transformations.
+ Each item MUST contain `input_axes`, `output_axes` and `transformation` fields.
+ The values of `input_axes` and `output_axes` are arrays of integers.
+ The integer values in these arrays correspond to the axis indices in the `byDimension`'s or its parent's
+ `input` and `output` coordinate systems, respectively.
+ The value of `transformation` is a valid transformation object.
+ Every axis index in the parent byDimension's `output` coordinate system
+ MUST appear in exactly one child transformation's `output_axes` array.
+ The `input_axes` and `output_axes` arrays of each item
+ MUST have the same length as that transformation's parameter arrays.
:::{dropdown} Example 1
-:animate: fade-in
A valid `byDimension` transformation:
@@ -1315,7 +1160,6 @@ A valid `byDimension` transformation:
:::
:::{dropdown} Example 2
-:animate: fade-in
Another valid `byDimension` transformation:
@@ -1325,7 +1169,6 @@ Another valid `byDimension` transformation:
:::
:::{dropdown} Example 3
-:animate: fade-in
This is an **invalid** `byDimension` transform:
@@ -1340,7 +1183,6 @@ Second, the `x` axis of the `output` does not appear in the `output` of any chil
:::
:::{dropdown} Example 4
-:animate: fade-in
Another **invalid** `byDimension` transform:
@@ -1366,15 +1208,17 @@ in which case the `forward` transformation's `input` and `output` are understood
and the `inverse` transformation's `input` (`output`) matches the bijection's `output` (`input`),
see the example below.
-The `input` and `output` fields MAY be omitted for `bijection` transformations
-if the fields may be omitted for both its `forward` and `inverse` transformations
-
Practically, non-invertible transformations have finite extents,
so bijection transforms should only be expected to be correct / consistent for points that fall within those extents.
It may not be correct for any point of appropriate dimensionality.
+**forward**
+: The forward transformation.
+
+**inverse**
+: The inverse transformation.
+
:::{dropdown} Example
-:animate: fade-in
```{literalinclude} examples/transformations/bijection.json
:language: json
@@ -1395,15 +1239,11 @@ Here, "image" refers to 2 to 5 dimensional data representing image
or volumetric data with optional time or channel axes.
It is stored in a multiple resolution representation.
-`multiscales` contains a list of dictionaries where each entry describes a multiscale image.
+`multiscales` contains an array of dictionaries where each entry describes a multiscale image.
Each `multiscales` dictionary MUST contain the field "coordinateSystems",
whose value is an array containing coordinate system metadata
(see [coordinate systems](#coordinate-systems-md)).
-The last entry of this array is the "intrinsic" coordinate system
-and MUST contain axis information pertaining to physical coordinates.
-It should be used for viewing and processing unless a use case dictates otherwise.
-It will generally be a representation of the image in its native physical coordinate system.
The following MUST hold for all coordinate systems inside multiscales metadata.
The length of `axes` must be between 2 and 5
@@ -1417,7 +1257,7 @@ If there are three spatial axes where two correspond to the image plane (`yx`)
and images are stacked along the other (anisotropic) axis (`z`),
the spatial axes SHOULD be ordered as `zyx`.
Each `multiscales` dictionary MUST contain the field `datasets`,
-which is a list of dictionaries describing the arrays storing the individual resolution levels.
+which is an array of dictionaries describing the arrays storing the individual resolution levels.
Each dictionary in `datasets` MUST contain the field `path`,
whose value is a string containing the path to the Zarr array for this resolution relative to the current Zarr group.
The `path`s MUST be ordered from largest (i.e. highest resolution) to smallest.
@@ -1426,17 +1266,18 @@ and MUST NOT have more than 5 dimensions.
The number of dimensions and order MUST correspond to number and order of `axes`.
Each dictionary in `datasets` MUST contain the field `coordinateTransformations`,
-whose value is a list of dictionaries that define a transformation
-that maps Zarr array coordinates for this resolution level to the "intrinsic" coordinate system
-(the last entry of the `coordinateSystems` array).
+whose value is an array of dictionaries that define a transformation
+that maps Zarr array coordinates for this resolution level to the "intrinsic" coordinate system.
The transformation is defined according to [transformations metadata](#trafo-types-md).
The transformation MUST take as input points in the array coordinate system
corresponding to the Zarr array at location `path`.
The value of `input` MUST equal the value of `path`,
implementations should always treat the value of `input` as if it were equal to the value of `path`.
-The value of the transformation’s `output` MUST be the name of the "intrinsic" [coordinate system](#coordinate-systems-md).
+The value of the transformation’s `output` coordinate system MUST be the same for every dataset in a single multiscales.
+This coordinate system (the "intrinsic" coordinate system) will generally be a representation of the image in its native physical coordinate system.
+It should be used for viewing and processing unless a use case dictates otherwise.
-This transformation MUST be one of the following:
+The transformation MUST be one of the following:
* A single scale or identity transformation
* A sequence transformation containing one scale and one translation transformation.
@@ -1465,7 +1306,6 @@ which contains a dictionary with additional information about the downscaling me
:::{dropdown} Example
-:animate: fade-in
A complete example of json-file for a 5D (TCZYX) multiscales with 3 resolution levels could look like this:
```{literalinclude} examples/multiscales_strict/multiscales_example.json
@@ -1735,6 +1575,144 @@ The first field is part of the first acquisition, and the second field is part o
```
:::
+### "scene" metadata
+(scene-md)=
+
+For images that share a spatial relationship,
+the `scene` metadata layout can be used to describe the relationship between images.
+
+The `scene` dictionary MUST contain the field `coordinateTransformations`,
+whose value MUST be an array of valid [transformations](#trafo-types-md).
+It MAY contain the field `coordinateSystems`,
+whose values MUST be an array of valid [coordinate systems](#coordinate-systems-md).
+
+If used inside "scene" metadata, the `input` and `output` fields of `coordinateTransformations` MUST contain a json object,
+which MUST contain either the `path` or the `name` field, or both.
+The value of the `path` field is the path to a multiscale image subgroup.
+The value of the `name` field is the name of a `coordinateSystem` either in the multiscale image subgroup specified by the path,
+or within the `scene` dictionary itself.
+If `name` refers to a coordinate system in the `scene` dictionary,
+the `path` value MAY be omitted or null.
+If `name` refers to a coordinate system in the multiscale image subgroup specified by `path`,
+both `path` and `name` MUST be provided.
+
+:::{dropdown} Example 1: Multiview fusion
+Two instruments simultaneously image the same sample from two different angles,
+and the 3D data from both instruments are calibrated to "micrometer" units.
+An analysis of sample A requires measurements from images taken from both instruments at certain points in space.
+Suppose a region of interest (ROI) is determined from the image obtained from instrument 2,
+but quantification from that region is needed for instrument 1.
+Since measurements were collected at different angles,
+a measurement by instrument 1 at the point with image array coordinates (x,y,z)
+may not correspond to the measurement at the same array coordinates in instrument 2
+(i.e., it may not be the same physical location in the sample).
+To analyze both images together, they must be transformed to a common coordinate system.
+
+The set of coordinate transformations encodes relationships between coordinate systems,
+specifically, how to convert points from one coordinate system to another.
+Implementations can apply the coordinate transform to images or points
+in coordinate system "sampleA_instrument2" to bring them into the "sampleA_instrument1" coordinate system.
+In this case, image data within the ROI defined in image2 should be transformed to the "sampleA_image1" coordinate system,
+then used for quantification with the instrument 1 image.
+
+The `coordinateTransformations` in the "scene" metadata would contain the following data.
+The transformation parameters are stored in a separate Zarr-group
+under `coordinateTransformations/sampleA_instrument2-to-instrument1` as shown above.
+
+```json
+"scene": {
+ "coordinateTransformations": [
+ {
+ "type": "affine",
+ "path": "coordinateTransformations/sampleA_instrument2-to-instrument1",
+ "input": {
+ "path": "sampleA_instrument2",
+ "name": "physical_instrument2"
+ },
+ "output": {
+ "path": "sampleA_instrument1",
+ "name": "physical_instrument1"
+ }
+ }
+ ]
+}
+```
+
+And the image at the path `sampleA_instrument1` would have the following as coordinate system:
+
+```json
+"coordinateSystems": [
+ {
+ "name": "physical_instrument1",
+ "axes": [
+ {"name": "z", "type": "space", "unit": "micrometer"},
+ {"name": "y", "type": "space", "unit": "micrometer"},
+ {"name": "x", "type": "space", "unit": "micrometer"}
+ ]
+ },
+]
+```
+
+The image at path `sampleA_instrument2` would have this as coordinate system:
+
+```json
+"coordinateSystems": [
+ {
+ "name": "physical_instrument2",
+ "axes": [
+ {"name": "z", "type": "space", "unit": "micrometer"},
+ {"name": "y", "type": "space", "unit": "micrometer"},
+ {"name": "x", "type": "space", "unit": "micrometer"}
+ ]
+ }
+],
+```
+:::
+
+:::{dropdown} Example 2: Multi-hop transformations
+Consider three instruments with strongly differing optical resolutions acquriring images of the same sample.
+The fields of view (FOV) of all instruments may differ by orders of magnitude.
+In this case, the FOV of instrument 1 (low-resolution) may entirely contain the FOVs of the other modalities. However, the alignment of instrument 3 with instrument 1 may be hard due to the lack of common landmark features.
+In such a case, it may be easier to align instrument 2 (medium-resolution) with instrument 1, and then instrument 3 with instrument 2.
+
+In this case, the "scene" metadata would contain the following coordinate transformations:
+
+```json
+"scene": {
+ "coordinateTransformations": [
+ {
+ "type": "affine",
+ "input": {
+ "path": "instrument1",
+ "name": "physical"
+ },
+ "output": {
+ "path": "instrument2",
+ "name": "physical"
+ },
+ "affine": [ [ ... ], [ ... ], [ ... ]] // 4x3 matrix stored in json
+ },
+ {
+ "type": "affine",
+ "input": {
+ "path": "instrument3",
+ "name": "physical"
+ },
+ "output": {
+ "path": "instrument2",
+ "name": "physical"
+ },
+ "affine": [ [ ... ], [ ... ], [ ... ] ] // 4x3 matrix stored in json
+ }
+ ]
+}
+```
+Both transformations (from instrument1 to instrument2, and from instrument3 to instrument2) refer to the "physical" coordinate systems of the respective images,
+which are defined in the `multiscales` attributes of the respective image groups.
+A transformation from instrument3 to instrument1 can be obtained
+by composing the two transformations above.
+:::
+
## Specification naming style
(naming-style)=
diff --git a/schemas/coordinate_systems_and_transforms.schema b/schemas/coordinate_systems_and_transforms.schema
deleted file mode 100644
index f52f7816..00000000
--- a/schemas/coordinate_systems_and_transforms.schema
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "$schema": "https://json-schema.org/draft/2020-12/schema",
- "$id": "https://ngff.openmicroscopy.org/0.6.dev3/schemas/coordinate_systems_and_transforms.schema",
- "title": "Coordinate Systems and Transforms",
- "description": "OME-Zarr coordinate systems and transforms.",
- "type": "object",
- "properties": {
- "coordinateSystems": {
- "$ref": "coordinate_systems.schema",
- "description": "Coordinate systems to combine with transforms to define spatial relationships"
- },
- "coordinateTransformations": {
- "$ref": "coordinate_transformations.schema",
- "description": "Coordinate transformations defining spatial relationships between coordinate systems"
- },
- "arrayCoordinateSystem": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "description": "Name of coordinate space"
- },
- "axes": {
- "allOf": [
- {
- "$ref": "axes.schema"
- },
- {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "type": {
- "const": "array"
- }
- }
- }
- }
- ]
- }
- },
- "required": [
- "axes"
- ]
- }
- }
-}
diff --git a/schemas/coordinate_transformations.schema b/schemas/coordinate_transformations.schema
index 6ee39a8c..bfd1e666 100644
--- a/schemas/coordinate_transformations.schema
+++ b/schemas/coordinate_transformations.schema
@@ -1,8 +1,8 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ngff.openmicroscopy.org/0.6.dev3/schemas/coordinate_transformations.schema",
- "title": "Coordinate Systems and Transforms",
- "description": "OME-Zarr Coordinate Systems and transforms.",
+ "title": "Coordinate Transformations",
+ "description": "OME-Zarr Coordinate transforms.",
"type": "array",
"uniqueItems": true,
"minItems": 1,
@@ -15,10 +15,40 @@
"type": "object",
"properties": {
"input": {
- "type": "string"
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ }
+ }
+ }
+ ]
},
"output": {
- "type": "string"
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ }
+ }
+ }
+ ]
}
},
"required": [
@@ -66,9 +96,6 @@
{
"$ref": "#/$defs/rotation"
},
- {
- "$ref": "#/$defs/inverseOf"
- },
{
"$ref": "#/$defs/bijection"
},
@@ -123,11 +150,14 @@
"type": {
"const": "identity"
}
- }
+ },
+ "title": "Identity Transformation",
+ "description": "Identity transformation that maps input coordinates directly to output coordinates without modification."
},
"mapAxis": {
"type": "object",
- "description": "Permute axes by name",
+ "title": "Map Axis Transformation",
+ "description": "Permute axes by mapping input axes to output axes.",
"properties": {
"type": {
"const": "mapAxis"
@@ -138,83 +168,55 @@
"type": "integer"
},
"description": "An array of integers representing the new axis order as zero-based indices of the input axes."
- },
- "required": [
- "mapAxis"
- ]
- }
+ }
+ },
+ "required": [
+ "mapAxis"
+ ]
},
"scale": {
"type": "object",
+ "title": "Scale Transformation",
+ "description": "Scale transformation that scales coordinates by specified factors along each axis.",
"properties": {
"type": {
"const": "scale"
- }
- },
- "oneOf": [
- {
- "properties": {
- "path": {
- "type": "string",
- "description": "Path to a zarr array containing the scale factors."
- }
- },
- "required": [
- "path"
- ]
},
- {
- "properties": {
- "scale": {
- "type": "array",
- "items": {
- "type": "number",
- "exclusiveMinimum": 0
- }
- }
- },
- "required": [
- "scale"
- ]
+ "scale": {
+ "type": "array",
+ "items": {
+ "type": "number",
+ "exclusiveMinimum": 0
+ }
}
+ },
+ "required": [
+ "scale"
]
},
"translation": {
"type": "object",
+ "title": "Translation Transformation",
+ "description": "Translation transformation that shifts coordinates by specified offsets along each axis.",
"properties": {
"type": {
"const": "translation"
- }
- },
- "oneOf": [
- {
- "properties": {
- "path": {
- "type": "string",
- "description": "Path to a zarr array containing the translation vectors."
- }
- },
- "required": [
- "path"
- ]
},
- {
- "properties": {
- "translation": {
- "type": "array",
- "items": {
- "type": "number"
- }
- }
- },
- "required": [
- "translation"
- ]
- }
+ "translation": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ }
+ }
+ },
+ "required": [
+ "translation"
]
},
"affine": {
"type": "object",
+ "title": "Affine Transformation",
+ "description": "Affine transformation represented by a transformation matrix.",
"properties": {
"type": {
"const": "affine"
@@ -252,6 +254,8 @@
},
"rotation": {
"type": "object",
+ "title": "Rotation Transformation",
+ "description": "Rotation transformation represented by a rotation matrix.",
"properties": {
"type": {
"const": "rotation"
@@ -287,23 +291,10 @@
}
]
},
- "inverseOf": {
- "type": "object",
- "properties": {
- "type": {
- "const": "inverseOf"
- },
- "transformation": {
- "$ref": "#/$defs/coordinateTransformation"
- }
- },
- "required": [
- "transformation"
- ],
- "description": "The inverse of another coordinate transformation."
- },
"bijection": {
"type": "object",
+ "title": "Bijection Transformation",
+ "description": "A pair of forward and inverse coordinate transformations.",
"properties": {
"type": {
"const": "bijection"
@@ -317,11 +308,11 @@
},
"required": [
"forward", "inverse"
- ],
- "description": "A pair of forward and inverse coordinate transformations."
+ ]
},
"sequence": {
- "description": "A sequence of transformations",
+ "title": "Sequence Transformation",
+ "description": "A sequence of transformations applied in order.",
"type": "object",
"properties": {
"type": { "const": "sequence" },
@@ -338,6 +329,8 @@
},
"byDimension": {
"type": "object",
+ "title": "By Dimension Transformation",
+ "description": "A set of transformations applied independently to each dimension.",
"properties": {
"type": { "const": "byDimension" },
"transformations": {
@@ -349,11 +342,12 @@
},
"required": [
"transformations"
- ],
- "description": "A set of transformations applied independently to each dimension."
+ ]
},
"displacements": {
"type": "object",
+ "title": "Displacement Field Transformation",
+ "description": "Transformation defined by a displacement field stored in a zarr array.",
"properties": {
"type": { "const": "displacements" },
"path": {
@@ -373,6 +367,8 @@
},
"coordinates": {
"type": "object",
+ "title": "Coordinate Field Transformation",
+ "description": "Transformation defined by a coordinate field stored in a zarr array.",
"properties": {
"type": { "const": "coordinates" },
"path": {
diff --git a/schemas/image.schema b/schemas/image.schema
index 0907d253..a5c2bab3 100644
--- a/schemas/image.schema
+++ b/schemas/image.schema
@@ -51,7 +51,7 @@
"type": "array",
"uniqueItems": true,
"items": {
- "$ref": "https://ngff.openmicroscopy.org/0.6.dev3/schemas/image.schema#/$defs/multiscale_coordinateTransformations"
+ "$ref": "#/$defs/multiscale_coordinateTransformations"
},
"minItems": 1,
"maxItems": 1
@@ -79,7 +79,8 @@
}
},
"required": [
- "datasets", "coordinateSystems"
+ "datasets",
+ "coordinateSystems"
]
},
"minItems": 1,
@@ -89,6 +90,7 @@
"description": "OME-NGFF coordinate transformation for multiscale resolution level datasets (only scale or scale & translate).",
"oneOf": [
{"$ref": "https://ngff.openmicroscopy.org/0.6.dev3/schemas/coordinate_transformations.schema#/$defs/scale"},
+ {"$ref": "https://ngff.openmicroscopy.org/0.6.dev3/schemas/coordinate_transformations.schema#/$defs/identity"},
{
"type": "object",
"properties": {
@@ -105,7 +107,8 @@
"maxItems": 2
},
"input": {"type": "string"},
- "output": {"type": "string"}
+ "output": {"type": "string"},
+ "name": {"type": "string"}
},
"required": ["type", "transformations", "input", "output"]
}
diff --git a/schemas/ome_zarr.schema b/schemas/ome_zarr.schema
index c7381be4..71a5b115 100644
--- a/schemas/ome_zarr.schema
+++ b/schemas/ome_zarr.schema
@@ -21,6 +21,9 @@
},
{
"$ref": "https://ngff.openmicroscopy.org/0.6.dev3/schemas/well.schema"
+ },
+ {
+ "$ref": "https://ngff.openmicroscopy.org/0.6.dev3/schemas/scene.schema"
}
]
}
diff --git a/schemas/scene.schema b/schemas/scene.schema
new file mode 100644
index 00000000..7eec7a6b
--- /dev/null
+++ b/schemas/scene.schema
@@ -0,0 +1,94 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://ngff.openmicroscopy.org/0.6.dev3/schemas/scene.schema",
+ "title": "Scene",
+ "description": "Scene metadata combining coordinate systems and coordinate transformations to define spatial relationships",
+ "type": "object",
+ "properties": {
+ "ome": {
+ "type": "object",
+ "properties": {
+ "scene":{
+ "properties": {
+ "coordinateSystems": {
+ "$ref": "coordinate_systems.schema",
+ "description": "Coordinate systems to combine with transforms to define spatial relationships"
+ },
+ "coordinateTransformations": {
+ "$comment": "Merge general coordinate transformations with constraints for scene metadata",
+ "allOf": [
+ {
+ "$ref": "coordinate_transformations.schema",
+ "description": "General coordinate transformations defining spatial relationships between coordinate systems"
+ },
+ {
+ "type": "array",
+ "items": {
+ "allOf": [
+ {
+ "properties": {
+ "input": {
+ "type": "object",
+ "properties": {
+ "name": {"type": "string"},
+ "path": {"type": "string"}
+ },
+ "required": ["name"]
+ },
+ "output": {
+ "type": "object",
+ "properties": {
+ "name": {"type": "string"},
+ "path": {"type": "string"}
+ },
+ "required": ["name"]
+ }
+ }
+ }
+ ]
+ },
+ "description": "Constrained input/output for coordinate transformations in scene metadata"
+ }
+ ]
+
+ },
+ "arrayCoordinateSystem": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Name of coordinate space"
+ },
+ "axes": {
+ "allOf": [
+ {
+ "$ref": "axes.schema"
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "array"
+ }
+ }
+ }
+ }
+ ]
+ }
+ },
+ "required": [
+ "axes"
+ ]
+ }
+ },
+ "type": "object",
+ "required": ["coordinateTransformations"]
+ }
+ },
+ "required": ["scene"]
+ }
+ },
+ "required": ["ome"]
+}
diff --git a/tests/attributes/spec/invalid/image/duplicate_axes.json b/tests/attributes/spec/invalid/image/duplicate_axes.json
index 48e41522..a001d0a5 100644
--- a/tests/attributes/spec/invalid/image/duplicate_axes.json
+++ b/tests/attributes/spec/invalid/image/duplicate_axes.json
@@ -42,6 +42,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/duplicate_scale.json b/tests/attributes/spec/invalid/image/duplicate_scale.json
index 714dd770..89958d9b 100644
--- a/tests/attributes/spec/invalid/image/duplicate_scale.json
+++ b/tests/attributes/spec/invalid/image/duplicate_scale.json
@@ -51,6 +51,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/empty_transformations.json b/tests/attributes/spec/invalid/image/empty_transformations.json
index 708e9a9f..4cb1de0e 100644
--- a/tests/attributes/spec/invalid/image/empty_transformations.json
+++ b/tests/attributes/spec/invalid/image/empty_transformations.json
@@ -32,6 +32,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/invalid_axes_count.json b/tests/attributes/spec/invalid/image/invalid_axes_count.json
index 98891124..7cdca157 100644
--- a/tests/attributes/spec/invalid/image/invalid_axes_count.json
+++ b/tests/attributes/spec/invalid/image/invalid_axes_count.json
@@ -37,6 +37,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/invalid_axis_type.json b/tests/attributes/spec/invalid/image/invalid_axis_type.json
index 15e5cb33..4d0f268d 100644
--- a/tests/attributes/spec/invalid/image/invalid_axis_type.json
+++ b/tests/attributes/spec/invalid/image/invalid_axis_type.json
@@ -42,6 +42,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/invalid_channels_color.json b/tests/attributes/spec/invalid/image/invalid_channels_color.json
index e3d0fa8b..f1ba1125 100644
--- a/tests/attributes/spec/invalid/image/invalid_channels_color.json
+++ b/tests/attributes/spec/invalid/image/invalid_channels_color.json
@@ -59,6 +59,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/invalid_channels_window.json b/tests/attributes/spec/invalid/image/invalid_channels_window.json
index 9f1ea7f3..3059606c 100644
--- a/tests/attributes/spec/invalid/image/invalid_channels_window.json
+++ b/tests/attributes/spec/invalid/image/invalid_channels_window.json
@@ -59,6 +59,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/invalid_multiscales_transformations.json b/tests/attributes/spec/invalid/image/invalid_multiscales_transformations.json
index e6b0cac9..ffe3bc3b 100644
--- a/tests/attributes/spec/invalid/image/invalid_multiscales_transformations.json
+++ b/tests/attributes/spec/invalid/image/invalid_multiscales_transformations.json
@@ -50,6 +50,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/invalid_path.json b/tests/attributes/spec/invalid/image/invalid_path.json
index bbb9281b..9525b905 100644
--- a/tests/attributes/spec/invalid/image/invalid_path.json
+++ b/tests/attributes/spec/invalid/image/invalid_path.json
@@ -42,6 +42,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/invalid_transformation_type.json b/tests/attributes/spec/invalid/image/invalid_transformation_type.json
index 0a39cf8e..873bc614 100644
--- a/tests/attributes/spec/invalid/image/invalid_transformation_type.json
+++ b/tests/attributes/spec/invalid/image/invalid_transformation_type.json
@@ -42,6 +42,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/missing_axes.json b/tests/attributes/spec/invalid/image/missing_axes.json
index 3b130f26..7b754439 100644
--- a/tests/attributes/spec/invalid/image/missing_axes.json
+++ b/tests/attributes/spec/invalid/image/missing_axes.json
@@ -25,6 +25,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/missing_axes_name.json b/tests/attributes/spec/invalid/image/missing_axes_name.json
index 7cbbf2c1..41831d53 100644
--- a/tests/attributes/spec/invalid/image/missing_axes_name.json
+++ b/tests/attributes/spec/invalid/image/missing_axes_name.json
@@ -40,6 +40,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/missing_datasets.json b/tests/attributes/spec/invalid/image/missing_datasets.json
index 56680770..f7ca44d7 100644
--- a/tests/attributes/spec/invalid/image/missing_datasets.json
+++ b/tests/attributes/spec/invalid/image/missing_datasets.json
@@ -26,6 +26,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/missing_path.json b/tests/attributes/spec/invalid/image/missing_path.json
index a02dc3e3..f2426c52 100644
--- a/tests/attributes/spec/invalid/image/missing_path.json
+++ b/tests/attributes/spec/invalid/image/missing_path.json
@@ -41,6 +41,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/missing_scale.json b/tests/attributes/spec/invalid/image/missing_scale.json
index 84f0e0d7..9ed91ab3 100644
--- a/tests/attributes/spec/invalid/image/missing_scale.json
+++ b/tests/attributes/spec/invalid/image/missing_scale.json
@@ -42,6 +42,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/missing_space_axes.json b/tests/attributes/spec/invalid/image/missing_space_axes.json
index fd148c83..4b0c0040 100644
--- a/tests/attributes/spec/invalid/image/missing_space_axes.json
+++ b/tests/attributes/spec/invalid/image/missing_space_axes.json
@@ -40,6 +40,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/missing_transformations.json b/tests/attributes/spec/invalid/image/missing_transformations.json
index 71f98e08..602ed5fa 100644
--- a/tests/attributes/spec/invalid/image/missing_transformations.json
+++ b/tests/attributes/spec/invalid/image/missing_transformations.json
@@ -31,6 +31,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/multiscales_transform_forbidden.json b/tests/attributes/spec/invalid/image/multiscales_transform_forbidden.json
new file mode 100644
index 00000000..7ab54ea6
--- /dev/null
+++ b/tests/attributes/spec/invalid/image/multiscales_transform_forbidden.json
@@ -0,0 +1,72 @@
+{
+ "ome": {
+ "version": "0.6.dev3",
+ "multiscales": [
+ {
+ "name": "multiscales",
+ "coordinateSystems": [
+ {
+ "name": "physical",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ }
+ ],
+ "datasets": [
+ {
+ "path": "array",
+ "coordinateTransformations": [
+ {
+ "type": "sequence",
+ "output": "physical",
+ "input": "array",
+ "transformations": [
+ {
+ "type": "rotation",
+ "rotation": [
+ [1, 0, 0],
+ [0, 1, 0],
+ [0, 0, 1]
+ ]
+ },
+ {
+ "type": "translation",
+ "translation": [
+ 30,
+ 20,
+ 10
+ ]
+ }
+ ],
+ "name": "transform-name"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "_conformance": {
+ "schema": {
+ "id": "schemas/image.schema"
+ },
+ "valid": false
+ }
+}
diff --git a/tests/attributes/spec/invalid/image/multiscales_transform_missing_params.json b/tests/attributes/spec/invalid/image/multiscales_transform_missing_params.json
new file mode 100644
index 00000000..09f92ffc
--- /dev/null
+++ b/tests/attributes/spec/invalid/image/multiscales_transform_missing_params.json
@@ -0,0 +1,99 @@
+{
+ "ome": {
+ "version": "0.6.dev3",
+ "multiscales": [
+ {
+ "name": "multiscales",
+ "coordinateSystems": [
+ {
+ "name": "physical",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ },
+ {
+ "name": "output",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ }
+ ],
+ "datasets": [
+ {
+ "path": "array",
+ "coordinateTransformations": [
+ {
+ "type": "sequence",
+ "input": "array",
+ "output": "physical",
+ "transformations": [
+ {
+ "type": "scale",
+ "scale": [1, 1, 1]
+ },
+ {
+ "type": "translation",
+ "translation": [
+ 30,
+ 20,
+ 10
+ ]
+ }
+ ],
+ "name": "transform-name"
+ }
+ ]
+ }
+ ],
+ "coordinateTransformations": [
+ {
+ "type": "affine",
+ "name": "some_additional_transform",
+ "input": "physical",
+ "output": "output"
+ }
+ ]
+ }
+ ]
+ },
+ "_conformance": {
+ "schema": {
+ "id": "schemas/image.schema"
+ },
+ "valid": false
+ }
+}
diff --git a/tests/attributes/spec/invalid/image/multiscales_transform_no_input_output.json b/tests/attributes/spec/invalid/image/multiscales_transform_no_input_output.json
new file mode 100644
index 00000000..185c1ce5
--- /dev/null
+++ b/tests/attributes/spec/invalid/image/multiscales_transform_no_input_output.json
@@ -0,0 +1,70 @@
+{
+ "ome": {
+ "version": "0.6.dev3",
+ "multiscales": [
+ {
+ "name": "multiscales",
+ "coordinateSystems": [
+ {
+ "name": "physical",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ }
+ ],
+ "datasets": [
+ {
+ "path": "array",
+ "coordinateTransformations": [
+ {
+ "type": "sequence",
+ "transformations": [
+ {
+ "type": "rotation",
+ "rotation": [
+ [1, 0, 0],
+ [0, 1, 0],
+ [0, 0, 1]
+ ]
+ },
+ {
+ "type": "translation",
+ "translation": [
+ 30,
+ 20,
+ 10
+ ]
+ }
+ ],
+ "name": "transform-name"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "_conformance": {
+ "schema": {
+ "id": "schemas/image.schema"
+ },
+ "valid": false
+ }
+}
diff --git a/tests/attributes/spec/invalid/image/multiscales_transform_no_input_output2.json b/tests/attributes/spec/invalid/image/multiscales_transform_no_input_output2.json
new file mode 100644
index 00000000..3d9ba788
--- /dev/null
+++ b/tests/attributes/spec/invalid/image/multiscales_transform_no_input_output2.json
@@ -0,0 +1,79 @@
+{
+ "ome": {
+ "version": "0.6.dev3",
+ "multiscales": [
+ {
+ "name": "multiscales",
+ "coordinateSystems": [
+ {
+ "name": "physical",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ }
+ ],
+ "datasets": [
+ {
+ "path": "array",
+ "coordinateTransformations": [
+ {
+ "type": "sequence",
+ "input": "array",
+ "output": "physical",
+ "transformations": [
+ {
+ "type": "rotation",
+ "rotation": [
+ [1, 0, 0],
+ [0, 1, 0],
+ [0, 0, 1]
+ ]
+ },
+ {
+ "type": "translation",
+ "translation": [
+ 30,
+ 20,
+ 10
+ ]
+ }
+ ],
+ "name": "transform-name"
+ }
+ ]
+ }
+ ],
+ "coordinateTransformations": [
+ {
+ "type": "translation",
+ "translation": [1, 1, 1],
+ "name": "some_additional_transform"
+ }
+ ]
+ }
+ ]
+ },
+ "_conformance": {
+ "schema": {
+ "id": "schemas/image.schema"
+ },
+ "valid": false
+ }
+}
diff --git a/tests/attributes/spec/invalid/image/no_axes.json b/tests/attributes/spec/invalid/image/no_axes.json
index 1681a6ba..81fe930f 100644
--- a/tests/attributes/spec/invalid/image/no_axes.json
+++ b/tests/attributes/spec/invalid/image/no_axes.json
@@ -26,6 +26,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/no_datasets.json b/tests/attributes/spec/invalid/image/no_datasets.json
index 3fafed8b..8d7f4b63 100644
--- a/tests/attributes/spec/invalid/image/no_datasets.json
+++ b/tests/attributes/spec/invalid/image/no_datasets.json
@@ -27,6 +27,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/no_multiscales.json b/tests/attributes/spec/invalid/image/no_multiscales.json
index 4f805a5b..6d07623e 100644
--- a/tests/attributes/spec/invalid/image/no_multiscales.json
+++ b/tests/attributes/spec/invalid/image/no_multiscales.json
@@ -6,6 +6,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/one_space_axes.json b/tests/attributes/spec/invalid/image/one_space_axes.json
index 0d5fe47d..8fe15450 100644
--- a/tests/attributes/spec/invalid/image/one_space_axes.json
+++ b/tests/attributes/spec/invalid/image/one_space_axes.json
@@ -45,6 +45,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/too_many_axes.json b/tests/attributes/spec/invalid/image/too_many_axes.json
index 9b565e8a..4afeec0d 100644
--- a/tests/attributes/spec/invalid/image/too_many_axes.json
+++ b/tests/attributes/spec/invalid/image/too_many_axes.json
@@ -60,6 +60,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/image/too_many_space_axes.json b/tests/attributes/spec/invalid/image/too_many_space_axes.json
index b764d233..f01f9ae5 100644
--- a/tests/attributes/spec/invalid/image/too_many_space_axes.json
+++ b/tests/attributes/spec/invalid/image/too_many_space_axes.json
@@ -50,6 +50,7 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/label/colors_duplicate.json b/tests/attributes/spec/invalid/label/colors_duplicate.json
index c729d61c..9e57f851 100644
--- a/tests/attributes/spec/invalid/label/colors_duplicate.json
+++ b/tests/attributes/spec/invalid/label/colors_duplicate.json
@@ -28,6 +28,7 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/label/colors_no_label_value.json b/tests/attributes/spec/invalid/label/colors_no_label_value.json
index 98f9f74f..09c9b506 100644
--- a/tests/attributes/spec/invalid/label/colors_no_label_value.json
+++ b/tests/attributes/spec/invalid/label/colors_no_label_value.json
@@ -18,6 +18,7 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/label/colors_rgba_length.json b/tests/attributes/spec/invalid/label/colors_rgba_length.json
index 537a8754..3ed45168 100644
--- a/tests/attributes/spec/invalid/label/colors_rgba_length.json
+++ b/tests/attributes/spec/invalid/label/colors_rgba_length.json
@@ -18,6 +18,7 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/label/colors_rgba_type.json b/tests/attributes/spec/invalid/label/colors_rgba_type.json
index 55077532..1006052e 100644
--- a/tests/attributes/spec/invalid/label/colors_rgba_type.json
+++ b/tests/attributes/spec/invalid/label/colors_rgba_type.json
@@ -19,6 +19,7 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/label/empty_colors.json b/tests/attributes/spec/invalid/label/empty_colors.json
index c7dc04d4..10ba8c86 100644
--- a/tests/attributes/spec/invalid/label/empty_colors.json
+++ b/tests/attributes/spec/invalid/label/empty_colors.json
@@ -9,6 +9,7 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/label/empty_properties.json b/tests/attributes/spec/invalid/label/empty_properties.json
index 03f6ff92..1b0d3f75 100644
--- a/tests/attributes/spec/invalid/label/empty_properties.json
+++ b/tests/attributes/spec/invalid/label/empty_properties.json
@@ -9,6 +9,7 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/label/properties_no_label_value.json b/tests/attributes/spec/invalid/label/properties_no_label_value.json
index 9b2153e5..f7041a51 100644
--- a/tests/attributes/spec/invalid/label/properties_no_label_value.json
+++ b/tests/attributes/spec/invalid/label/properties_no_label_value.json
@@ -13,6 +13,7 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/acquisition_negative_starttime.json b/tests/attributes/spec/invalid/plate/acquisition_negative_starttime.json
index 655c6ab5..a039314e 100644
--- a/tests/attributes/spec/invalid/plate/acquisition_negative_starttime.json
+++ b/tests/attributes/spec/invalid/plate/acquisition_negative_starttime.json
@@ -31,6 +31,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/acquisition_noninteger_endtime.json b/tests/attributes/spec/invalid/plate/acquisition_noninteger_endtime.json
index 2b982d9c..8ab83ce1 100644
--- a/tests/attributes/spec/invalid/plate/acquisition_noninteger_endtime.json
+++ b/tests/attributes/spec/invalid/plate/acquisition_noninteger_endtime.json
@@ -31,6 +31,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/acquisition_noninteger_starttime.json b/tests/attributes/spec/invalid/plate/acquisition_noninteger_starttime.json
index 8a273caa..c647bfcb 100644
--- a/tests/attributes/spec/invalid/plate/acquisition_noninteger_starttime.json
+++ b/tests/attributes/spec/invalid/plate/acquisition_noninteger_starttime.json
@@ -31,6 +31,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/acquisition_zero_maximumfieldcount.json b/tests/attributes/spec/invalid/plate/acquisition_zero_maximumfieldcount.json
index 518d74cc..8e93acc3 100644
--- a/tests/attributes/spec/invalid/plate/acquisition_zero_maximumfieldcount.json
+++ b/tests/attributes/spec/invalid/plate/acquisition_zero_maximumfieldcount.json
@@ -31,6 +31,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/duplicate_columns.json b/tests/attributes/spec/invalid/plate/duplicate_columns.json
index fb4e5bb9..e69d2117 100644
--- a/tests/attributes/spec/invalid/plate/duplicate_columns.json
+++ b/tests/attributes/spec/invalid/plate/duplicate_columns.json
@@ -28,6 +28,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/duplicate_rows-2.json b/tests/attributes/spec/invalid/plate/duplicate_rows-2.json
index 92ca3ea8..7ac69862 100644
--- a/tests/attributes/spec/invalid/plate/duplicate_rows-2.json
+++ b/tests/attributes/spec/invalid/plate/duplicate_rows-2.json
@@ -33,6 +33,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/duplicate_rows.json b/tests/attributes/spec/invalid/plate/duplicate_rows.json
index 36c903ee..cce4b2bf 100644
--- a/tests/attributes/spec/invalid/plate/duplicate_rows.json
+++ b/tests/attributes/spec/invalid/plate/duplicate_rows.json
@@ -28,6 +28,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/empty_columns.json b/tests/attributes/spec/invalid/plate/empty_columns.json
index 11df185c..eab327e9 100644
--- a/tests/attributes/spec/invalid/plate/empty_columns.json
+++ b/tests/attributes/spec/invalid/plate/empty_columns.json
@@ -21,6 +21,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/empty_rows.json b/tests/attributes/spec/invalid/plate/empty_rows.json
index eb810ed2..ea7b86df 100644
--- a/tests/attributes/spec/invalid/plate/empty_rows.json
+++ b/tests/attributes/spec/invalid/plate/empty_rows.json
@@ -21,6 +21,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/empty_wells.json b/tests/attributes/spec/invalid/plate/empty_wells.json
index 4db2f924..2635134b 100644
--- a/tests/attributes/spec/invalid/plate/empty_wells.json
+++ b/tests/attributes/spec/invalid/plate/empty_wells.json
@@ -19,6 +19,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/missing_acquisition_id.json b/tests/attributes/spec/invalid/plate/missing_acquisition_id.json
index 5e087fd1..bf6a5c42 100644
--- a/tests/attributes/spec/invalid/plate/missing_acquisition_id.json
+++ b/tests/attributes/spec/invalid/plate/missing_acquisition_id.json
@@ -30,6 +30,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/missing_column_name.json b/tests/attributes/spec/invalid/plate/missing_column_name.json
index e2d30353..4b08239e 100644
--- a/tests/attributes/spec/invalid/plate/missing_column_name.json
+++ b/tests/attributes/spec/invalid/plate/missing_column_name.json
@@ -25,6 +25,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/missing_columns.json b/tests/attributes/spec/invalid/plate/missing_columns.json
index 7c68c662..e858a135 100644
--- a/tests/attributes/spec/invalid/plate/missing_columns.json
+++ b/tests/attributes/spec/invalid/plate/missing_columns.json
@@ -20,6 +20,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/missing_row_name.json b/tests/attributes/spec/invalid/plate/missing_row_name.json
index 4b23f96e..32020e98 100644
--- a/tests/attributes/spec/invalid/plate/missing_row_name.json
+++ b/tests/attributes/spec/invalid/plate/missing_row_name.json
@@ -25,6 +25,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/missing_rows.json b/tests/attributes/spec/invalid/plate/missing_rows.json
index ae0dd276..9b1e31d6 100644
--- a/tests/attributes/spec/invalid/plate/missing_rows.json
+++ b/tests/attributes/spec/invalid/plate/missing_rows.json
@@ -20,6 +20,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/missing_well_columnIndex.json b/tests/attributes/spec/invalid/plate/missing_well_columnIndex.json
index 0f5b3769..dfa6d40d 100644
--- a/tests/attributes/spec/invalid/plate/missing_well_columnIndex.json
+++ b/tests/attributes/spec/invalid/plate/missing_well_columnIndex.json
@@ -24,6 +24,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/missing_well_path.json b/tests/attributes/spec/invalid/plate/missing_well_path.json
index 33ded0ed..dfeea132 100644
--- a/tests/attributes/spec/invalid/plate/missing_well_path.json
+++ b/tests/attributes/spec/invalid/plate/missing_well_path.json
@@ -24,6 +24,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/missing_well_rowIndex.json b/tests/attributes/spec/invalid/plate/missing_well_rowIndex.json
index 37f1951d..2a76b648 100644
--- a/tests/attributes/spec/invalid/plate/missing_well_rowIndex.json
+++ b/tests/attributes/spec/invalid/plate/missing_well_rowIndex.json
@@ -24,6 +24,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/missing_wells.json b/tests/attributes/spec/invalid/plate/missing_wells.json
index ea437dbc..e408735a 100644
--- a/tests/attributes/spec/invalid/plate/missing_wells.json
+++ b/tests/attributes/spec/invalid/plate/missing_wells.json
@@ -18,6 +18,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/negative_acquisition_id.json b/tests/attributes/spec/invalid/plate/negative_acquisition_id.json
index f91d3a58..c3c133c4 100644
--- a/tests/attributes/spec/invalid/plate/negative_acquisition_id.json
+++ b/tests/attributes/spec/invalid/plate/negative_acquisition_id.json
@@ -30,6 +30,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/negative_endtime.json b/tests/attributes/spec/invalid/plate/negative_endtime.json
index a539cb4d..0f05671c 100644
--- a/tests/attributes/spec/invalid/plate/negative_endtime.json
+++ b/tests/attributes/spec/invalid/plate/negative_endtime.json
@@ -31,6 +31,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/non_alphanumeric_column.json b/tests/attributes/spec/invalid/plate/non_alphanumeric_column.json
index 52d78821..f4e49105 100644
--- a/tests/attributes/spec/invalid/plate/non_alphanumeric_column.json
+++ b/tests/attributes/spec/invalid/plate/non_alphanumeric_column.json
@@ -25,6 +25,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/non_integer_acquisition_id.json b/tests/attributes/spec/invalid/plate/non_integer_acquisition_id.json
index d4c0e4bb..29a730d6 100644
--- a/tests/attributes/spec/invalid/plate/non_integer_acquisition_id.json
+++ b/tests/attributes/spec/invalid/plate/non_integer_acquisition_id.json
@@ -30,6 +30,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/non_integer_acquisition_maximumfieldcount.json b/tests/attributes/spec/invalid/plate/non_integer_acquisition_maximumfieldcount.json
index 267f24ee..5b5a9d45 100644
--- a/tests/attributes/spec/invalid/plate/non_integer_acquisition_maximumfieldcount.json
+++ b/tests/attributes/spec/invalid/plate/non_integer_acquisition_maximumfieldcount.json
@@ -31,6 +31,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/well_1group.json b/tests/attributes/spec/invalid/plate/well_1group.json
index bbd969c1..b98f69de 100644
--- a/tests/attributes/spec/invalid/plate/well_1group.json
+++ b/tests/attributes/spec/invalid/plate/well_1group.json
@@ -24,6 +24,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/well_3groups.json b/tests/attributes/spec/invalid/plate/well_3groups.json
index 577f8d02..d603fae8 100644
--- a/tests/attributes/spec/invalid/plate/well_3groups.json
+++ b/tests/attributes/spec/invalid/plate/well_3groups.json
@@ -24,6 +24,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/plate/zero_field_count.json b/tests/attributes/spec/invalid/plate/zero_field_count.json
index 15509019..2ba27e23 100644
--- a/tests/attributes/spec/invalid/plate/zero_field_count.json
+++ b/tests/attributes/spec/invalid/plate/zero_field_count.json
@@ -26,6 +26,7 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/scene/scene_input_output_not_object.json b/tests/attributes/spec/invalid/scene/scene_input_output_not_object.json
new file mode 100644
index 00000000..251acdfe
--- /dev/null
+++ b/tests/attributes/spec/invalid/scene/scene_input_output_not_object.json
@@ -0,0 +1,75 @@
+{
+ "ome": {
+ "version": "0.6.dev3",
+ "scene": {
+ "coordinateTransformations": [
+ {
+ "type": "translation",
+ "output": "world",
+ "input": {"path": "tile_0", "name": "physical"},
+ "translation": [
+ 0,
+ 0
+ ],
+ "name": "tile_0_mm to world"
+ },
+ {
+ "type": "translation",
+ "output": "world",
+ "input": {"path": "tile_1", "name": "physical"},
+ "translation": [
+ 0,
+ 348
+ ],
+ "name": "tile_1_mm to world"
+ },
+ {
+ "type": "translation",
+ "output": "world",
+ "input": {"path": "tile_2", "name": "physical"},
+ "translation": [
+ 276,
+ 0
+ ],
+ "name": "tile_2_mm to world"
+ },
+ {
+ "type": "translation",
+ "output": "world",
+ "input": {"path": "tile_3", "name": "physical"},
+ "translation": [
+ 276,
+ 348
+ ],
+ "name": "tile_3_mm to world"
+ }
+ ],
+ "coordinateSystems": [
+ {
+ "name": "world",
+ "axes": [
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "_conformance": {
+ "schema": {
+ "id": "schemas/scene.schema"
+ },
+ "description": "Tests for the scene JSON schema: ",
+ "valid": false
+ }
+}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/well/duplicate_images.json b/tests/attributes/spec/invalid/well/duplicate_images.json
index 3978b0a1..d4a6e751 100644
--- a/tests/attributes/spec/invalid/well/duplicate_images.json
+++ b/tests/attributes/spec/invalid/well/duplicate_images.json
@@ -13,6 +13,7 @@
"schema": {
"id": "schemas/well.schema"
},
- "description": "Tests for the well JSON schema: "
+ "description": "Tests for the well JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/well/empty_images.json b/tests/attributes/spec/invalid/well/empty_images.json
index ef0ccce1..b4eb93e4 100644
--- a/tests/attributes/spec/invalid/well/empty_images.json
+++ b/tests/attributes/spec/invalid/well/empty_images.json
@@ -6,6 +6,7 @@
"schema": {
"id": "schemas/well.schema"
},
- "description": "Tests for the well JSON schema: "
+ "description": "Tests for the well JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/invalid/well/non_integer_acquisition_id.json b/tests/attributes/spec/invalid/well/non_integer_acquisition_id.json
index c3855a3f..8193e214 100644
--- a/tests/attributes/spec/invalid/well/non_integer_acquisition_id.json
+++ b/tests/attributes/spec/invalid/well/non_integer_acquisition_id.json
@@ -11,6 +11,7 @@
"schema": {
"id": "schemas/well.schema"
},
- "description": "Tests for the well JSON schema: "
+ "description": "Tests for the well JSON schema: ",
+ "valid": false
}
}
\ No newline at end of file
diff --git a/tests/attributes/spec/valid/image/custom_type_axes.json b/tests/attributes/spec/valid/image/custom_type_axes.json
index 4561cc96..f4938ea0 100644
--- a/tests/attributes/spec/valid/image/custom_type_axes.json
+++ b/tests/attributes/spec/valid/image/custom_type_axes.json
@@ -1,6 +1,6 @@
{
"ome": {
- "version": "0.6.dev32",
+ "version": "0.6.dev3",
"multiscales": [
{
"coordinateSystems": [
diff --git a/tests/attributes/spec/valid/image/multiscales_transform_additional_affine.json b/tests/attributes/spec/valid/image/multiscales_transform_additional_affine.json
new file mode 100644
index 00000000..2ab29911
--- /dev/null
+++ b/tests/attributes/spec/valid/image/multiscales_transform_additional_affine.json
@@ -0,0 +1,103 @@
+{
+ "ome": {
+ "version": "0.6.dev3",
+ "multiscales": [
+ {
+ "name": "multiscales",
+ "coordinateSystems": [
+ {
+ "name": "physical",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ },
+ {
+ "name": "output",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ }
+ ],
+ "datasets": [
+ {
+ "path": "array",
+ "coordinateTransformations": [
+ {
+ "type": "sequence",
+ "input": "array",
+ "output": "physical",
+ "transformations": [
+ {
+ "type": "scale",
+ "scale": [1, 1, 1]
+ },
+ {
+ "type": "translation",
+ "translation": [
+ 30,
+ 20,
+ 10
+ ]
+ }
+ ],
+ "name": "transform-name"
+ }
+ ]
+ }
+ ],
+ "coordinateTransformations": [
+ {
+ "type": "affine",
+ "affine": [
+ [1, 1, 0, 0],
+ [0, 1, 0, 0],
+ [0, 0, 1, 0]
+ ],
+ "name": "some_additional_transform",
+ "input": "physical",
+ "output": "output"
+ }
+ ]
+ }
+ ]
+ },
+ "_conformance": {
+ "schema": {
+ "id": "schemas/image.schema"
+ }
+ }
+}
diff --git a/tests/attributes/spec/valid/image/multiscales_transform_additional_affine_path.json b/tests/attributes/spec/valid/image/multiscales_transform_additional_affine_path.json
new file mode 100644
index 00000000..1c1fa186
--- /dev/null
+++ b/tests/attributes/spec/valid/image/multiscales_transform_additional_affine_path.json
@@ -0,0 +1,99 @@
+{
+ "ome": {
+ "version": "0.6.dev3",
+ "multiscales": [
+ {
+ "name": "multiscales",
+ "coordinateSystems": [
+ {
+ "name": "physical",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ },
+ {
+ "name": "output",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ }
+ ],
+ "datasets": [
+ {
+ "path": "array",
+ "coordinateTransformations": [
+ {
+ "type": "sequence",
+ "input": "array",
+ "output": "physical",
+ "transformations": [
+ {
+ "type": "scale",
+ "scale": [1, 1, 1]
+ },
+ {
+ "type": "translation",
+ "translation": [
+ 30,
+ 20,
+ 10
+ ]
+ }
+ ],
+ "name": "transform-name"
+ }
+ ]
+ }
+ ],
+ "coordinateTransformations": [
+ {
+ "type": "affine",
+ "path": "some_path_to_affine_matrix",
+ "name": "some_additional_transform",
+ "input": "physical",
+ "output": "output"
+ }
+ ]
+ }
+ ]
+ },
+ "_conformance": {
+ "schema": {
+ "id": "schemas/image.schema"
+ }
+ }
+}
diff --git a/tests/attributes/spec/valid/image/multiscales_transform_additional_translation.json b/tests/attributes/spec/valid/image/multiscales_transform_additional_translation.json
new file mode 100644
index 00000000..c6e4f907
--- /dev/null
+++ b/tests/attributes/spec/valid/image/multiscales_transform_additional_translation.json
@@ -0,0 +1,99 @@
+{
+ "ome": {
+ "version": "0.6.dev3",
+ "multiscales": [
+ {
+ "name": "multiscales",
+ "coordinateSystems": [
+ {
+ "name": "physical",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ },
+ {
+ "name": "output",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ }
+ ],
+ "datasets": [
+ {
+ "path": "array",
+ "coordinateTransformations": [
+ {
+ "type": "sequence",
+ "input": "array",
+ "output": "physical",
+ "transformations": [
+ {
+ "type": "scale",
+ "scale": [1, 1, 1]
+ },
+ {
+ "type": "translation",
+ "translation": [
+ 30,
+ 20,
+ 10
+ ]
+ }
+ ],
+ "name": "transform-name"
+ }
+ ]
+ }
+ ],
+ "coordinateTransformations": [
+ {
+ "type": "translation",
+ "translation": [1, 1, 1],
+ "name": "some_additional_transform",
+ "input": "physical",
+ "output": "output"
+ }
+ ]
+ }
+ ]
+ },
+ "_conformance": {
+ "schema": {
+ "id": "schemas/image.schema"
+ }
+ }
+}
diff --git a/tests/attributes/spec/valid/image/multiscales_transform_sequence.json b/tests/attributes/spec/valid/image/multiscales_transform_sequence.json
new file mode 100644
index 00000000..cd45168c
--- /dev/null
+++ b/tests/attributes/spec/valid/image/multiscales_transform_sequence.json
@@ -0,0 +1,71 @@
+{
+ "ome": {
+ "version": "0.6.dev3",
+ "multiscales": [
+ {
+ "name": "multiscales",
+ "coordinateSystems": [
+ {
+ "name": "physical",
+ "axes": [
+ {
+ "type": "space",
+ "name": "z",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ }
+ ],
+ "datasets": [
+ {
+ "path": "array",
+ "coordinateTransformations": [
+ {
+ "type": "sequence",
+ "output": "physical",
+ "input": "array",
+ "transformations": [
+ {
+ "type": "scale",
+ "scale": [
+ 4,
+ 3,
+ 2
+ ]
+ },
+ {
+ "type": "translation",
+ "translation": [
+ 30,
+ 20,
+ 10
+ ]
+ }
+ ],
+ "name": "transform-name"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "_conformance": {
+ "schema": {
+ "id": "schemas/image.schema"
+ }
+ }
+}
diff --git a/tests/attributes/spec/valid/scene/tile_stitching.json b/tests/attributes/spec/valid/scene/tile_stitching.json
new file mode 100644
index 00000000..aa641667
--- /dev/null
+++ b/tests/attributes/spec/valid/scene/tile_stitching.json
@@ -0,0 +1,74 @@
+{
+ "ome": {
+ "version": "0.6.dev3",
+ "scene":{
+ "coordinateTransformations": [
+ {
+ "type": "translation",
+ "output": {"name": "world"},
+ "input": {"path": "tile_0", "name": "physical"},
+ "translation": [
+ 0,
+ 0
+ ],
+ "name": "tile_0_mm to world"
+ },
+ {
+ "type": "translation",
+ "output": {"name": "world"},
+ "input": {"path": "tile_1", "name": "physical"},
+ "translation": [
+ 0,
+ 348
+ ],
+ "name": "tile_1_mm to world"
+ },
+ {
+ "type": "translation",
+ "output": {"name": "world"},
+ "input": {"path": "tile_2", "name": "physical"},
+ "translation": [
+ 276,
+ 0
+ ],
+ "name": "tile_2_mm to world"
+ },
+ {
+ "type": "translation",
+ "output": {"name": "world"},
+ "input": {"path": "tile_3", "name": "physical"},
+ "translation": [
+ 276,
+ 348
+ ],
+ "name": "tile_3_mm to world"
+ }
+ ],
+ "coordinateSystems": [
+ {
+ "name": "world",
+ "axes": [
+ {
+ "type": "space",
+ "name": "x",
+ "unit": "micrometer",
+ "discrete": false
+ },
+ {
+ "type": "space",
+ "name": "y",
+ "unit": "micrometer",
+ "discrete": false
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "_conformance": {
+ "schema": {
+ "id": "schemas/scene.schema"
+ },
+ "description": "Tests for the scene JSON schema: "
+ }
+}
\ No newline at end of file
diff --git a/tests/attributes/strict/invalid/label/no_colors.json b/tests/attributes/strict/invalid/label/no_colors.json
index 39d29f4b..29239c71 100644
--- a/tests/attributes/strict/invalid/label/no_colors.json
+++ b/tests/attributes/strict/invalid/label/no_colors.json
@@ -7,6 +7,8 @@
"schema": {
"id": "schemas/strict_label.schema"
},
- "description": "Tests for the strict image-label JSON schema: "
+ "description": "Tests for the strict image-label JSON schema: ",
+ "valid": false,
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/invalid/plate/missing_acquisition_maximumfieldcount.json b/tests/attributes/strict/invalid/plate/missing_acquisition_maximumfieldcount.json
index 1de76dcf..7df1c663 100644
--- a/tests/attributes/strict/invalid/plate/missing_acquisition_maximumfieldcount.json
+++ b/tests/attributes/strict/invalid/plate/missing_acquisition_maximumfieldcount.json
@@ -32,6 +32,8 @@
"schema": {
"id": "schemas/strict_plate.schema"
},
- "description": "Tests for the strict plate JSON schema: "
+ "description": "Tests for the strict plate JSON schema: ",
+ "valid": false,
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/invalid/plate/missing_acquisition_name.json b/tests/attributes/strict/invalid/plate/missing_acquisition_name.json
index b0fe45ff..ce300f14 100644
--- a/tests/attributes/strict/invalid/plate/missing_acquisition_name.json
+++ b/tests/attributes/strict/invalid/plate/missing_acquisition_name.json
@@ -32,6 +32,8 @@
"schema": {
"id": "schemas/strict_plate.schema"
},
- "description": "Tests for the strict plate JSON schema: "
+ "description": "Tests for the strict plate JSON schema: ",
+ "valid": false,
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/invalid/plate/missing_name.json b/tests/attributes/strict/invalid/plate/missing_name.json
index 7385c889..d88f4abb 100644
--- a/tests/attributes/strict/invalid/plate/missing_name.json
+++ b/tests/attributes/strict/invalid/plate/missing_name.json
@@ -25,6 +25,8 @@
"schema": {
"id": "schemas/strict_plate.schema"
},
- "description": "Tests for the strict plate JSON schema: "
+ "description": "Tests for the strict plate JSON schema: ",
+ "valid": false,
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/valid/image/image.json b/tests/attributes/strict/valid/image/image.json
index d68dfd0c..99e46715 100644
--- a/tests/attributes/strict/valid/image/image.json
+++ b/tests/attributes/strict/valid/image/image.json
@@ -47,6 +47,7 @@
"_conformance": {
"schema": {
"id": "schemas/strict_image.schema"
- }
+ },
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/valid/image/image_metadata.json b/tests/attributes/strict/valid/image/image_metadata.json
index f4613cf2..6f105f81 100644
--- a/tests/attributes/strict/valid/image/image_metadata.json
+++ b/tests/attributes/strict/valid/image/image_metadata.json
@@ -58,6 +58,7 @@
"_conformance": {
"schema": {
"id": "schemas/strict_image.schema"
- }
+ },
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/valid/image/image_omero.json b/tests/attributes/strict/valid/image/image_omero.json
index 682168ee..319b8247 100644
--- a/tests/attributes/strict/valid/image/image_omero.json
+++ b/tests/attributes/strict/valid/image/image_omero.json
@@ -161,6 +161,7 @@
"_conformance": {
"schema": {
"id": "schemas/strict_image.schema"
- }
+ },
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/valid/image/multiscales_example.json b/tests/attributes/strict/valid/image/multiscales_example.json
index 254726fb..b64ae1b6 100644
--- a/tests/attributes/strict/valid/image/multiscales_example.json
+++ b/tests/attributes/strict/valid/image/multiscales_example.json
@@ -147,6 +147,7 @@
"_conformance": {
"schema": {
"id": "schemas/strict_image.schema"
- }
+ },
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/valid/image/multiscales_transformations.json b/tests/attributes/strict/valid/image/multiscales_transformations.json
index d0878f0d..53b943a6 100644
--- a/tests/attributes/strict/valid/image/multiscales_transformations.json
+++ b/tests/attributes/strict/valid/image/multiscales_transformations.json
@@ -73,6 +73,7 @@
"_conformance": {
"schema": {
"id": "schemas/strict_image.schema"
- }
+ },
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/valid/plate/strict_acquisitions.json b/tests/attributes/strict/valid/plate/strict_acquisitions.json
index ae7dfe38..10876241 100644
--- a/tests/attributes/strict/valid/plate/strict_acquisitions.json
+++ b/tests/attributes/strict/valid/plate/strict_acquisitions.json
@@ -33,6 +33,7 @@
"schema": {
"id": "schemas/strict_plate.schema"
},
- "description": "Tests for the strict plate JSON schema: "
+ "description": "Tests for the strict plate JSON schema: ",
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/valid/plate/strict_no_acquisitions.json b/tests/attributes/strict/valid/plate/strict_no_acquisitions.json
index 4aee1c58..bd64f5fd 100644
--- a/tests/attributes/strict/valid/plate/strict_no_acquisitions.json
+++ b/tests/attributes/strict/valid/plate/strict_no_acquisitions.json
@@ -26,6 +26,7 @@
"schema": {
"id": "schemas/strict_plate.schema"
},
- "description": "Tests for the strict plate JSON schema: "
+ "description": "Tests for the strict plate JSON schema: ",
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/valid/well/strict_acquisitions.json b/tests/attributes/strict/valid/well/strict_acquisitions.json
index 59fd1314..cdf4039d 100644
--- a/tests/attributes/strict/valid/well/strict_acquisitions.json
+++ b/tests/attributes/strict/valid/well/strict_acquisitions.json
@@ -14,6 +14,7 @@
"schema": {
"id": "schemas/strict_well.schema"
},
- "description": "Tests for the strict well JSON schema: "
+ "description": "Tests for the strict well JSON schema: ",
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/attributes/strict/valid/well/strict_no_acquisitions.json b/tests/attributes/strict/valid/well/strict_no_acquisitions.json
index 6a7decef..63da7e38 100644
--- a/tests/attributes/strict/valid/well/strict_no_acquisitions.json
+++ b/tests/attributes/strict/valid/well/strict_no_acquisitions.json
@@ -13,6 +13,7 @@
"schema": {
"id": "schemas/strict_well.schema"
},
- "description": "Tests for the strict well JSON schema: "
+ "description": "Tests for the strict well JSON schema: ",
+ "strict": true
}
}
\ No newline at end of file
diff --git a/tests/test_attributes.py b/tests/test_attributes.py
new file mode 100644
index 00000000..8e1e51b1
--- /dev/null
+++ b/tests/test_attributes.py
@@ -0,0 +1,72 @@
+from pathlib import Path
+from typing import Any
+import json
+
+import pytest
+
+from jsonschema import RefResolver, Draft202012Validator as Validator
+from jsonschema.exceptions import ValidationError
+
+here = Path(__file__).resolve().parent
+schema_dir = here.parent.joinpath("schemas")
+attrs_dir = here / "attributes"
+
+schema_store = {}
+version = None
+for schema_path in schema_dir.glob("*.schema*"):
+ schema = json.loads(schema_path.read_text())
+ schema_store[schema["$id"]] = schema
+ if schema_path.stem == "_version":
+ version = schema["enum"][0]
+
+assert version is not None
+
+GENERIC_SCHEMA = schema_store[
+ f"https://ngff.openmicroscopy.org/{version}/schemas/ome_zarr.schema"
+]
+STRICT_SCHEMA = schema_store[
+ f"https://ngff.openmicroscopy.org/{version}/schemas/strict_ome_zarr.schema"
+]
+
+case_fnames = sorted(attrs_dir.rglob("*.json"))
+
+xfails = set()
+
+
+def fname_to_id(fpath: Path) -> str:
+ return str(fpath.relative_to(attrs_dir).with_suffix(""))
+
+
+@pytest.mark.parametrize("case_fname", case_fnames, ids=fname_to_id)
+def test_attributes(case_fname: Path):
+ if fname_to_id(case_fname) in xfails:
+ pytest.xfail("known JSON Schema limitation")
+
+ case_obj: dict[str, Any] = json.loads(case_fname.read_text())
+
+ conformance = case_obj.get("_conformance", {})
+ valid = conformance.get("valid", True)
+ strict = conformance.get("strict", False)
+
+ if strict:
+ schema = STRICT_SCHEMA
+ else:
+ schema = GENERIC_SCHEMA
+
+ resolver = RefResolver.from_schema(
+ schema,
+ store=schema_store,
+ )
+
+ validator_cls = Validator
+
+ validator = validator_cls(
+ schema,
+ resolver=resolver,
+ )
+
+ if valid:
+ validator.validate(case_obj)
+ else:
+ with pytest.raises(ValidationError):
+ validator.validate(case_obj)
diff --git a/tests/test_validation.py b/tests/test_validation.py
index 1d9ac02f..53364240 100644
--- a/tests/test_validation.py
+++ b/tests/test_validation.py
@@ -9,12 +9,16 @@
from jsonschema import RefResolver, Draft202012Validator as Validator
from jsonschema.exceptions import ValidationError
+from pathlib import Path
+
+os.chdir(Path(__file__).parent.parent)
schema_store = {}
for schema_filename in glob.glob("schemas/*"):
- with open(schema_filename) as f:
- schema = json.load(f)
- schema_store[schema["$id"]] = schema
+ if schema_filename.endswith('.schema'):
+ with open(schema_filename) as f:
+ schema = json.load(f)
+ schema_store[schema["$id"]] = schema
GENERIC_SCHEMA = schema_store[
"https://ngff.openmicroscopy.org/0.6.dev3/schemas/ome_zarr.schema"
@@ -124,3 +128,7 @@ def test_example_configs():
missing.append(subdir[0])
if missing:
raise Exception(f"Directories missing configs: {missing}")
+
+
+if __name__ == '__main__':
+ pytest.main([__file__])
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/duplicate_axes.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/duplicate_axes.ome.zarr/zarr.json
index 3981c5bd..a5899e65 100644
--- a/tests/zarr/spec/invalid/image/duplicate_axes.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/duplicate_axes.ome.zarr/zarr.json
@@ -45,7 +45,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/duplicate_scale.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/duplicate_scale.ome.zarr/zarr.json
index a144322a..e123d349 100644
--- a/tests/zarr/spec/invalid/image/duplicate_scale.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/duplicate_scale.ome.zarr/zarr.json
@@ -54,7 +54,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/empty_transformations.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/empty_transformations.ome.zarr/zarr.json
index c2073565..10069652 100644
--- a/tests/zarr/spec/invalid/image/empty_transformations.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/empty_transformations.ome.zarr/zarr.json
@@ -35,7 +35,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/invalid_axes_count.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/invalid_axes_count.ome.zarr/zarr.json
index 1aaf1b4e..6f5c28f0 100644
--- a/tests/zarr/spec/invalid/image/invalid_axes_count.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/invalid_axes_count.ome.zarr/zarr.json
@@ -40,7 +40,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/invalid_axis_type.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/invalid_axis_type.ome.zarr/zarr.json
index abb6b6d0..1c3aae3c 100644
--- a/tests/zarr/spec/invalid/image/invalid_axis_type.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/invalid_axis_type.ome.zarr/zarr.json
@@ -45,7 +45,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/invalid_channels_color.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/invalid_channels_color.ome.zarr/zarr.json
index 1ec5864b..6bd472d7 100644
--- a/tests/zarr/spec/invalid/image/invalid_channels_color.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/invalid_channels_color.ome.zarr/zarr.json
@@ -62,7 +62,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/invalid_channels_window.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/invalid_channels_window.ome.zarr/zarr.json
index f23a5759..324da16e 100644
--- a/tests/zarr/spec/invalid/image/invalid_channels_window.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/invalid_channels_window.ome.zarr/zarr.json
@@ -62,7 +62,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/invalid_multiscales_transformations.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/invalid_multiscales_transformations.ome.zarr/zarr.json
index 42c35651..66e48f04 100644
--- a/tests/zarr/spec/invalid/image/invalid_multiscales_transformations.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/invalid_multiscales_transformations.ome.zarr/zarr.json
@@ -53,7 +53,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/invalid_path.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/invalid_path.ome.zarr/zarr.json
index 6d3db2bd..36ed1e0e 100644
--- a/tests/zarr/spec/invalid/image/invalid_path.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/invalid_path.ome.zarr/zarr.json
@@ -45,7 +45,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/invalid_transformation_type.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/invalid_transformation_type.ome.zarr/zarr.json
index f0b8dea2..59582152 100644
--- a/tests/zarr/spec/invalid/image/invalid_transformation_type.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/invalid_transformation_type.ome.zarr/zarr.json
@@ -45,7 +45,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/missing_axes.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/missing_axes.ome.zarr/zarr.json
index 459eee76..42db08f9 100644
--- a/tests/zarr/spec/invalid/image/missing_axes.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/missing_axes.ome.zarr/zarr.json
@@ -28,7 +28,8 @@
"_conformance": {
"schema": {
"id": "age.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/missing_axes_name.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/missing_axes_name.ome.zarr/zarr.json
index 550f6fe8..68663bf6 100644
--- a/tests/zarr/spec/invalid/image/missing_axes_name.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/missing_axes_name.ome.zarr/zarr.json
@@ -43,7 +43,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/missing_datasets.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/missing_datasets.ome.zarr/zarr.json
index 7866baf9..f2318fe0 100644
--- a/tests/zarr/spec/invalid/image/missing_datasets.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/missing_datasets.ome.zarr/zarr.json
@@ -29,7 +29,8 @@
"_conformance": {
"schema": {
"id": "age.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/missing_path.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/missing_path.ome.zarr/zarr.json
index 5bfacfac..3929b8b4 100644
--- a/tests/zarr/spec/invalid/image/missing_path.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/missing_path.ome.zarr/zarr.json
@@ -44,7 +44,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/missing_scale.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/missing_scale.ome.zarr/zarr.json
index cd0b5515..f80f18d4 100644
--- a/tests/zarr/spec/invalid/image/missing_scale.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/missing_scale.ome.zarr/zarr.json
@@ -45,7 +45,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/missing_space_axes.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/missing_space_axes.ome.zarr/zarr.json
index c3c23c0a..b62ceb18 100644
--- a/tests/zarr/spec/invalid/image/missing_space_axes.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/missing_space_axes.ome.zarr/zarr.json
@@ -43,7 +43,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/missing_transformations.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/missing_transformations.ome.zarr/zarr.json
index de9f2f2a..179cad70 100644
--- a/tests/zarr/spec/invalid/image/missing_transformations.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/missing_transformations.ome.zarr/zarr.json
@@ -34,7 +34,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/no_axes.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/no_axes.ome.zarr/zarr.json
index 609ba137..e9fb2237 100644
--- a/tests/zarr/spec/invalid/image/no_axes.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/no_axes.ome.zarr/zarr.json
@@ -29,7 +29,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/no_datasets.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/no_datasets.ome.zarr/zarr.json
index 407110f7..0b03543f 100644
--- a/tests/zarr/spec/invalid/image/no_datasets.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/no_datasets.ome.zarr/zarr.json
@@ -30,7 +30,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/no_multiscales.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/no_multiscales.ome.zarr/zarr.json
index 32be6622..99f541e2 100644
--- a/tests/zarr/spec/invalid/image/no_multiscales.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/no_multiscales.ome.zarr/zarr.json
@@ -9,7 +9,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/one_space_axes.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/one_space_axes.ome.zarr/zarr.json
index 42e7d70b..6b83c41b 100644
--- a/tests/zarr/spec/invalid/image/one_space_axes.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/one_space_axes.ome.zarr/zarr.json
@@ -48,7 +48,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/too_many_axes.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/too_many_axes.ome.zarr/zarr.json
index 7cf4a9a1..16521f0c 100644
--- a/tests/zarr/spec/invalid/image/too_many_axes.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/too_many_axes.ome.zarr/zarr.json
@@ -63,7 +63,8 @@
"_conformance": {
"schema": {
"id": "age.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/image/too_many_space_axes.ome.zarr/zarr.json b/tests/zarr/spec/invalid/image/too_many_space_axes.ome.zarr/zarr.json
index 3d7c209a..85ab4990 100644
--- a/tests/zarr/spec/invalid/image/too_many_space_axes.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/image/too_many_space_axes.ome.zarr/zarr.json
@@ -53,7 +53,8 @@
"_conformance": {
"schema": {
"id": "schemas/image.schema"
- }
+ },
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/label/colors_duplicate.ome.zarr/zarr.json b/tests/zarr/spec/invalid/label/colors_duplicate.ome.zarr/zarr.json
index eae55d47..8199ac9d 100644
--- a/tests/zarr/spec/invalid/label/colors_duplicate.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/label/colors_duplicate.ome.zarr/zarr.json
@@ -31,7 +31,8 @@
"schema": {
"id": "bel.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/label/colors_no_label_value.ome.zarr/zarr.json b/tests/zarr/spec/invalid/label/colors_no_label_value.ome.zarr/zarr.json
index efc993f8..419292b0 100644
--- a/tests/zarr/spec/invalid/label/colors_no_label_value.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/label/colors_no_label_value.ome.zarr/zarr.json
@@ -21,7 +21,8 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/label/colors_rgba_length.ome.zarr/zarr.json b/tests/zarr/spec/invalid/label/colors_rgba_length.ome.zarr/zarr.json
index 50966238..ab624c62 100644
--- a/tests/zarr/spec/invalid/label/colors_rgba_length.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/label/colors_rgba_length.ome.zarr/zarr.json
@@ -21,7 +21,8 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/label/colors_rgba_type.ome.zarr/zarr.json b/tests/zarr/spec/invalid/label/colors_rgba_type.ome.zarr/zarr.json
index 60631f49..38077b54 100644
--- a/tests/zarr/spec/invalid/label/colors_rgba_type.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/label/colors_rgba_type.ome.zarr/zarr.json
@@ -22,7 +22,8 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/label/empty_colors.ome.zarr/zarr.json b/tests/zarr/spec/invalid/label/empty_colors.ome.zarr/zarr.json
index 1367d0bc..5d4e5c7b 100644
--- a/tests/zarr/spec/invalid/label/empty_colors.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/label/empty_colors.ome.zarr/zarr.json
@@ -12,7 +12,8 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/label/empty_properties.ome.zarr/zarr.json b/tests/zarr/spec/invalid/label/empty_properties.ome.zarr/zarr.json
index 5026f4d7..13002825 100644
--- a/tests/zarr/spec/invalid/label/empty_properties.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/label/empty_properties.ome.zarr/zarr.json
@@ -12,7 +12,8 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/label/properties_no_label_value.ome.zarr/zarr.json b/tests/zarr/spec/invalid/label/properties_no_label_value.ome.zarr/zarr.json
index 5be47bb9..78312b48 100644
--- a/tests/zarr/spec/invalid/label/properties_no_label_value.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/label/properties_no_label_value.ome.zarr/zarr.json
@@ -16,7 +16,8 @@
"schema": {
"id": "schemas/label.schema"
},
- "description": "Tests for the image-label JSON schema: "
+ "description": "Tests for the image-label JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/acquisition_negative_starttime.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/acquisition_negative_starttime.ome.zarr/zarr.json
index d08ebc0f..10668bb7 100644
--- a/tests/zarr/spec/invalid/plate/acquisition_negative_starttime.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/acquisition_negative_starttime.ome.zarr/zarr.json
@@ -34,7 +34,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/acquisition_noninteger_endtime.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/acquisition_noninteger_endtime.ome.zarr/zarr.json
index 42de8897..9965a61d 100644
--- a/tests/zarr/spec/invalid/plate/acquisition_noninteger_endtime.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/acquisition_noninteger_endtime.ome.zarr/zarr.json
@@ -34,7 +34,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/acquisition_noninteger_starttime.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/acquisition_noninteger_starttime.ome.zarr/zarr.json
index d88b42ac..2995f0ec 100644
--- a/tests/zarr/spec/invalid/plate/acquisition_noninteger_starttime.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/acquisition_noninteger_starttime.ome.zarr/zarr.json
@@ -34,7 +34,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/acquisition_zero_maximumfieldcount.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/acquisition_zero_maximumfieldcount.ome.zarr/zarr.json
index c8055d99..93531d52 100644
--- a/tests/zarr/spec/invalid/plate/acquisition_zero_maximumfieldcount.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/acquisition_zero_maximumfieldcount.ome.zarr/zarr.json
@@ -34,7 +34,8 @@
"schema": {
"id": "ate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/duplicate_columns.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/duplicate_columns.ome.zarr/zarr.json
index b9156949..5e7272f0 100644
--- a/tests/zarr/spec/invalid/plate/duplicate_columns.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/duplicate_columns.ome.zarr/zarr.json
@@ -31,7 +31,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/duplicate_rows-2.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/duplicate_rows-2.ome.zarr/zarr.json
index dc1fe5e4..c64e9479 100644
--- a/tests/zarr/spec/invalid/plate/duplicate_rows-2.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/duplicate_rows-2.ome.zarr/zarr.json
@@ -36,7 +36,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/duplicate_rows.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/duplicate_rows.ome.zarr/zarr.json
index 84303e2f..69466a54 100644
--- a/tests/zarr/spec/invalid/plate/duplicate_rows.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/duplicate_rows.ome.zarr/zarr.json
@@ -31,7 +31,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/empty_columns.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/empty_columns.ome.zarr/zarr.json
index 3715dc49..5542ff09 100644
--- a/tests/zarr/spec/invalid/plate/empty_columns.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/empty_columns.ome.zarr/zarr.json
@@ -24,7 +24,8 @@
"schema": {
"id": "ate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/empty_rows.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/empty_rows.ome.zarr/zarr.json
index 9b723efd..c0b73f13 100644
--- a/tests/zarr/spec/invalid/plate/empty_rows.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/empty_rows.ome.zarr/zarr.json
@@ -24,7 +24,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/empty_wells.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/empty_wells.ome.zarr/zarr.json
index 0dd1670d..ec4ab043 100644
--- a/tests/zarr/spec/invalid/plate/empty_wells.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/empty_wells.ome.zarr/zarr.json
@@ -22,7 +22,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/missing_acquisition_id.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/missing_acquisition_id.ome.zarr/zarr.json
index cb80c599..017dd654 100644
--- a/tests/zarr/spec/invalid/plate/missing_acquisition_id.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/missing_acquisition_id.ome.zarr/zarr.json
@@ -33,7 +33,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/missing_column_name.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/missing_column_name.ome.zarr/zarr.json
index 57d395b6..9d3d9d99 100644
--- a/tests/zarr/spec/invalid/plate/missing_column_name.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/missing_column_name.ome.zarr/zarr.json
@@ -28,7 +28,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/missing_columns.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/missing_columns.ome.zarr/zarr.json
index 4b2262a5..202fa5b5 100644
--- a/tests/zarr/spec/invalid/plate/missing_columns.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/missing_columns.ome.zarr/zarr.json
@@ -23,7 +23,8 @@
"schema": {
"id": "ate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/missing_row_name.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/missing_row_name.ome.zarr/zarr.json
index fee7d718..0f8e55b4 100644
--- a/tests/zarr/spec/invalid/plate/missing_row_name.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/missing_row_name.ome.zarr/zarr.json
@@ -28,7 +28,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/missing_rows.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/missing_rows.ome.zarr/zarr.json
index 5a8d8551..974022ba 100644
--- a/tests/zarr/spec/invalid/plate/missing_rows.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/missing_rows.ome.zarr/zarr.json
@@ -23,7 +23,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/missing_well_columnIndex.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/missing_well_columnIndex.ome.zarr/zarr.json
index 675a1332..09b40722 100644
--- a/tests/zarr/spec/invalid/plate/missing_well_columnIndex.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/missing_well_columnIndex.ome.zarr/zarr.json
@@ -27,7 +27,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/missing_well_path.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/missing_well_path.ome.zarr/zarr.json
index 78e23bf0..b2fcb6b1 100644
--- a/tests/zarr/spec/invalid/plate/missing_well_path.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/missing_well_path.ome.zarr/zarr.json
@@ -27,7 +27,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/missing_well_rowIndex.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/missing_well_rowIndex.ome.zarr/zarr.json
index d2bbb36a..5470a610 100644
--- a/tests/zarr/spec/invalid/plate/missing_well_rowIndex.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/missing_well_rowIndex.ome.zarr/zarr.json
@@ -27,7 +27,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/missing_wells.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/missing_wells.ome.zarr/zarr.json
index a99d3e71..eb9b0f3f 100644
--- a/tests/zarr/spec/invalid/plate/missing_wells.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/missing_wells.ome.zarr/zarr.json
@@ -21,7 +21,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/negative_acquisition_id.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/negative_acquisition_id.ome.zarr/zarr.json
index e965f1e4..4f8933e6 100644
--- a/tests/zarr/spec/invalid/plate/negative_acquisition_id.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/negative_acquisition_id.ome.zarr/zarr.json
@@ -33,7 +33,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/negative_endtime.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/negative_endtime.ome.zarr/zarr.json
index 01d6b3e0..e2043dae 100644
--- a/tests/zarr/spec/invalid/plate/negative_endtime.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/negative_endtime.ome.zarr/zarr.json
@@ -34,7 +34,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/non_alphanumeric_column.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/non_alphanumeric_column.ome.zarr/zarr.json
index 1c0eea6f..ab784ee4 100644
--- a/tests/zarr/spec/invalid/plate/non_alphanumeric_column.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/non_alphanumeric_column.ome.zarr/zarr.json
@@ -28,7 +28,8 @@
"schema": {
"id": ""
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/non_integer_acquisition_id.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/non_integer_acquisition_id.ome.zarr/zarr.json
index f8a49cfd..dadfe585 100644
--- a/tests/zarr/spec/invalid/plate/non_integer_acquisition_id.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/non_integer_acquisition_id.ome.zarr/zarr.json
@@ -33,7 +33,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/non_integer_acquisition_maximumfieldcount.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/non_integer_acquisition_maximumfieldcount.ome.zarr/zarr.json
index 78dc6976..0b6eeb2c 100644
--- a/tests/zarr/spec/invalid/plate/non_integer_acquisition_maximumfieldcount.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/non_integer_acquisition_maximumfieldcount.ome.zarr/zarr.json
@@ -34,7 +34,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/well_1group.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/well_1group.ome.zarr/zarr.json
index 84e6bac5..224e1715 100644
--- a/tests/zarr/spec/invalid/plate/well_1group.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/well_1group.ome.zarr/zarr.json
@@ -27,7 +27,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/well_3groups.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/well_3groups.ome.zarr/zarr.json
index c14e7dde..4fe5f1fc 100644
--- a/tests/zarr/spec/invalid/plate/well_3groups.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/well_3groups.ome.zarr/zarr.json
@@ -27,7 +27,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/plate/zero_field_count.ome.zarr/zarr.json b/tests/zarr/spec/invalid/plate/zero_field_count.ome.zarr/zarr.json
index f7c71abc..3ff39e28 100644
--- a/tests/zarr/spec/invalid/plate/zero_field_count.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/plate/zero_field_count.ome.zarr/zarr.json
@@ -29,7 +29,8 @@
"schema": {
"id": "schemas/plate.schema"
},
- "description": "Tests for the plate JSON schema: "
+ "description": "Tests for the plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/well/duplicate_images.ome.zarr/zarr.json b/tests/zarr/spec/invalid/well/duplicate_images.ome.zarr/zarr.json
index e673272c..1d643118 100644
--- a/tests/zarr/spec/invalid/well/duplicate_images.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/well/duplicate_images.ome.zarr/zarr.json
@@ -16,7 +16,8 @@
"schema": {
"id": "schemas/well.schema"
},
- "description": "Tests for the well JSON schema: "
+ "description": "Tests for the well JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/well/empty_images.ome.zarr/zarr.json b/tests/zarr/spec/invalid/well/empty_images.ome.zarr/zarr.json
index e76374be..8b5bacb9 100644
--- a/tests/zarr/spec/invalid/well/empty_images.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/well/empty_images.ome.zarr/zarr.json
@@ -9,7 +9,8 @@
"schema": {
"id": "schemas/well.schema"
},
- "description": "Tests for the well JSON schema: "
+ "description": "Tests for the well JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/spec/invalid/well/non_integer_acquisition_id.ome.zarr/zarr.json b/tests/zarr/spec/invalid/well/non_integer_acquisition_id.ome.zarr/zarr.json
index 48e25dc6..45fcf75d 100644
--- a/tests/zarr/spec/invalid/well/non_integer_acquisition_id.ome.zarr/zarr.json
+++ b/tests/zarr/spec/invalid/well/non_integer_acquisition_id.ome.zarr/zarr.json
@@ -14,7 +14,8 @@
"schema": {
"id": "schemas/well.schema"
},
- "description": "Tests for the well JSON schema: "
+ "description": "Tests for the well JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/strict/invalid/label/no_colors.ome.zarr/zarr.json b/tests/zarr/strict/invalid/label/no_colors.ome.zarr/zarr.json
index 5c1a00d2..672cb513 100644
--- a/tests/zarr/strict/invalid/label/no_colors.ome.zarr/zarr.json
+++ b/tests/zarr/strict/invalid/label/no_colors.ome.zarr/zarr.json
@@ -10,7 +10,8 @@
"schema": {
"id": "schemas/strict_label.schema"
},
- "description": "Tests for the strict image-label JSON schema: "
+ "description": "Tests for the strict image-label JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/strict/invalid/plate/missing_acquisition_maximumfieldcount.ome.zarr/zarr.json b/tests/zarr/strict/invalid/plate/missing_acquisition_maximumfieldcount.ome.zarr/zarr.json
index 1401fc0d..59d215d1 100644
--- a/tests/zarr/strict/invalid/plate/missing_acquisition_maximumfieldcount.ome.zarr/zarr.json
+++ b/tests/zarr/strict/invalid/plate/missing_acquisition_maximumfieldcount.ome.zarr/zarr.json
@@ -35,7 +35,8 @@
"schema": {
"id": "schemas/strict_plate.schema"
},
- "description": "Tests for the strict plate JSON schema: "
+ "description": "Tests for the strict plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/strict/invalid/plate/missing_acquisition_name.ome.zarr/zarr.json b/tests/zarr/strict/invalid/plate/missing_acquisition_name.ome.zarr/zarr.json
index 3994a02c..271344d5 100644
--- a/tests/zarr/strict/invalid/plate/missing_acquisition_name.ome.zarr/zarr.json
+++ b/tests/zarr/strict/invalid/plate/missing_acquisition_name.ome.zarr/zarr.json
@@ -35,7 +35,8 @@
"schema": {
"id": "schemas/strict_plate.schema"
},
- "description": "Tests for the strict plate JSON schema: "
+ "description": "Tests for the strict plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/tests/zarr/strict/invalid/plate/missing_name.ome.zarr/zarr.json b/tests/zarr/strict/invalid/plate/missing_name.ome.zarr/zarr.json
index 85330424..334f73ec 100644
--- a/tests/zarr/strict/invalid/plate/missing_name.ome.zarr/zarr.json
+++ b/tests/zarr/strict/invalid/plate/missing_name.ome.zarr/zarr.json
@@ -28,7 +28,8 @@
"schema": {
"id": "schemas/strict_plate.schema"
},
- "description": "Tests for the strict plate JSON schema: "
+ "description": "Tests for the strict plate JSON schema: ",
+ "valid": false
}
}
}
\ No newline at end of file
diff --git a/version_history.md b/version_history.md
index 6cc7b943..1e42091b 100644
--- a/version_history.md
+++ b/version_history.md
@@ -12,10 +12,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
+- Implemented feedback from Hackathon:
+ - BREAKING CHANGE: Renamed top-level group for transformations to "Scene"
+ - BREAKING CHANGE: Transformations in scene metadata must be object with fields "name" and "path"
+ - BREAKING CHANGE: Made syntax of `mapAxis` and `byDimension` transforms consistent with other transforms
+ - BREAKING CHANGE: Zarr parameter storage no longer allowed for scale/translation
+ - For detailed set of changes see [complete overview](https://ngff.openmicroscopy.org/rfc/5/responses/2/index.html)
- Updated version keys from `0.6.dev2` to `0.6.dev3` everywhere
### Removed
+- BREAKING CHANGE: Removed `inverseOf` transformation
- Removed `version` field from `multiscales` metadata in the image schema (`schemas/image.schema`) since it is already required at `ome > version`
## [0.6.dev2] - 2025-12-02