diff --git a/.gitignore b/.gitignore index 89502188..3fadeb08 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ _build _bikeshed .tox .vscode +.venv \ No newline at end of file diff --git a/latest/index.bs b/latest/index.bs index 26e27b3c..86c3ecf3 100644 --- a/latest/index.bs +++ b/latest/index.bs @@ -77,7 +77,7 @@ Images {#image-layout} The following layout describes the expected Zarr hierarchy for images with multiple levels of resolutions and optionally associated labels. -Note that the number of dimensions is variable between 2 and 5 and that axis names are arbitrary, see [[#multiscale-md]] for details. +Note that the number of dimensions is variable and that axis names are arbitrary, see [[#multiscale-md]] for details. For this example we assume an image with 5 dimensions and axes called `t,c,z,y,x`.
@@ -98,8 +98,8 @@ For this example we assume an image with 5 dimensions and axes called `t,c,z,y,x ├── n # The name of the array is arbitrary with the ordering defined by │ │ # by the "multiscales" metadata, but is often a sequence starting at 0. │ │ - │ ├── .zarray # All image arrays must be up to 5-dimensional - │ │ # with the axis of type time before type channel, before spatial axes. + │ ├── .zarray + │ │ │ │ │ └─ t # Chunks are stored with the nested directory layout. │ └─ c # All but the last chunk element are stored as directories. @@ -298,21 +298,18 @@ The transformations in the list are applied sequentially and in order. "multiscales" metadata {#multiscale-md} --------------------------------------- -Metadata about an image can be found under the "multiscales" key in the group-level metadata. 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. +Metadata about an image can be found under the "multiscales" key in the group-level metadata. Images are stored in a multiple resolution representation. "multiscales" contains a list of dictionaries where each entry describes a multiscale image. Each "multiscales" dictionary MUST contain the field "axes", see [[#axes-md]]. -The length of "axes" must be between 2 and 5 and MUST be equal to the dimensionality of the zarr arrays storing the image data (see "datasets:path"). -The "axes" MUST contain 2 or 3 entries of "type:space" and MAY contain one additional entry of "type:time" and MAY contain one additional entry of "type:channel" or a null / custom type. -The order of the entries MUST correspond to the order of dimensions of the zarr arrays. In addition, the entries MUST be ordered by "type" where the "time" axis must come first (if present), followed by the "channel" or custom axis (if present) and the axes of type "space". -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". - +The length of "axes" must be equal to the dimensionality of the zarr arrays storing the image data (see "datasets:path"). +The order of the entries MUST correspond to the order of dimensions of the zarr arrays. +Axis names MUST be unique: no two elements of "axes" can have the same "name" attribute. Each "multiscales" dictionary MUST contain the field "datasets", which is a list of dictionaries describing the arrays storing the individual resolution levels. Each dictionary in "datasets" MUST contain the field "path", whose value contains the path to the array for this resolution relative -to the current zarr group. The "path"s MUST be ordered from largest (i.e. highest resolution) to smallest. +to the current zarr group. The "path"s MUST be ordered from largest (i.e. highest resolution) to smallest. All arrays denoted by a "path" field MUST have the same number of dimensions. The number of dimensions of each array must match the length of the "axes" metadata. -Each "datasets" dictionary MUST have the same number of dimensions 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", which contains a list of transformations that map the data coordinates to the physical coordinates (as specified by "axes") for this resolution level. The transformations are defined according to [[#trafo-md]]. The transformation MUST only be of type `translation` or `scale`. They MUST contain exactly one `scale` transformation that specifies the pixel size in physical units or time duration. If scaling information is not available or applicable for one of the axes, the value MUST express the scaling factor between the current resolution and the first resolution for the given axis, defaulting to 1.0 if there is no downsampling along the axis. @@ -565,6 +562,22 @@ were added before this was adopted, but they should be updated in due course. Implementations {#implementations} ================================== +Partial support {#partial-support} +---------------------------------- + +Inevitably, some software libraries and applications will not support this entire specification, but rather some of it. +How should partial implementations respond to data defined via unsupported parts of the specification? This specification does not answer this question in general, but it does provide guidance for a specific scenario: +if a partial implementation normalizes input data, e.g. by converting that data to a form consistent with the subset of the specification supported by the implementation, then +the implementation SHOULD provide a clear indication to users and developers when such data normalization occurs. + +For example, suppose an implementation can only represent 3-dimensional images, and additionally that implementation reads 2-dimensional images by converting them internally to a 3-dimensional representation; +In this case, the implementation SHOULD make a reasonable effort to inform users that this transformation is occurring, e.g. by displaying an alert message or warning, or by printing relevant information to logs. + +This allows implementations flexibility to implement a subset of the specification, while also protecting users from surprising data transformations. + +List of implementations {#list-of-implementations} +-------------------------------------------------- + Projects which support reading and/or writing OME-NGFF data include: