From 3e15c0569e2a83aa836de542e7f84bab45a350b4 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 10 Jun 2024 19:54:05 +0000 Subject: [PATCH] chore(rebuild): RFC-1: note explicit step of needing to adjust Status of RFC upon draft merge To avoid fixup PRs like - https://github.com/ome/ngff/pull/244 SHA: a71832a7eac60e29192c01276e5116711e774025 Reason: push, by @yarikoptic Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- 0.1/index.html | 275 ++++- 0.1/schemas/plate.schema | 112 ++ 0.1/schemas/strict_image.schema | 1 + 0.1/schemas/well.schema | 47 + 0.2/index.html | 277 ++++- 0.2/schemas/plate.schema | 119 +++ 0.2/schemas/well.schema | 47 + 0.3/index.html | 271 ++++- 0.3/schemas/plate.schema | 119 +++ 0.3/schemas/strict_image.schema | 1 + 0.3/schemas/well.schema | 47 + 0.4/index.html | 1010 +++++++++++++++--- 0.4/schemas/image.schema | 2 +- 0.4/schemas/label.schema | 77 ++ 0.4/schemas/plate.schema | 140 +++ 0.4/schemas/strict_label.schema | 18 + 0.4/schemas/strict_plate.schema | 28 + 0.4/schemas/strict_well.schema | 17 + 0.4/schemas/well.schema | 47 + latest/index.html | 1549 ++++++++++++++++++++-------- latest/schemas/image.schema | 10 +- latest/schemas/label.schema | 77 ++ latest/schemas/plate.schema | 140 +++ latest/schemas/strict_label.schema | 18 + latest/schemas/strict_plate.schema | 28 + latest/schemas/strict_well.schema | 17 + latest/schemas/well.schema | 47 + 27 files changed, 3800 insertions(+), 741 deletions(-) create mode 100644 0.1/schemas/plate.schema create mode 100644 0.1/schemas/well.schema create mode 100644 0.2/schemas/plate.schema create mode 100644 0.2/schemas/well.schema create mode 100644 0.3/schemas/plate.schema create mode 100644 0.3/schemas/well.schema create mode 100644 0.4/schemas/label.schema create mode 100644 0.4/schemas/plate.schema create mode 100644 0.4/schemas/strict_label.schema create mode 100644 0.4/schemas/strict_plate.schema create mode 100644 0.4/schemas/strict_well.schema create mode 100644 0.4/schemas/well.schema create mode 100644 latest/schemas/label.schema create mode 100644 latest/schemas/plate.schema create mode 100644 latest/schemas/strict_label.schema create mode 100644 latest/schemas/strict_plate.schema create mode 100644 latest/schemas/strict_well.schema create mode 100644 latest/schemas/well.schema diff --git a/0.1/index.html b/0.1/index.html index a94cced8..3b69c69e 100644 --- a/0.1/index.html +++ b/0.1/index.html @@ -1238,14 +1238,15 @@ grid-column: 2; width: auto; margin-right: 1rem; + border-bottom: 3px solid transparent; + margin-bottom: -3px; } #toc .content:hover, #toc .content:focus { background: rgba(75%, 75%, 75%, .25); background: var(--a-hover-bg); - border-bottom: 3px solid #054572; - border-bottom: 3px solid var(--toclink-underline); - margin-bottom: -3px; + border-bottom-color: #054572; + border-bottom-color: var(--toclink-underline); } #toc li li li .content { margin-left: 1rem; @@ -1487,11 +1488,11 @@ } } - + - - - + - + - + - - + -
OME logo (6 circles in a hexagon)

Next-generation file formats (NGFF)

-

Final Community Group Report,

+

Final Community Group Report,

This version: @@ -1839,7 +2033,7 @@

-
@@ -1891,7 +2085,6 @@

Table of Contents

Conformance
  1. Document conventions -
  2. Conformant Algorithms
  • Index @@ -1939,8 +2132,8 @@

    1 parallelization.

    As a result, a number of formats have been developed more recently which provide the basic data structure of an HDF5 file, but do so in a more cloud-friendly way. -In the PyData community, the Zarr [zarr] format was developed -for easily storing collections of NumPy arrays. In the ImageJ community, N5 [n5] was developed to work around +In the PyData community, the Zarr [zarr] format was developed +for easily storing collections of NumPy arrays. In the ImageJ community, N5 [n5] was developed to work around the limitations of HDF5 ("N5" was originally short for "Not-HDF5"). Both of these formats permit storing individual chunks of data either locally in separate files or in cloud-based object stores as separate keys.

    @@ -1954,7 +2147,7 @@

    1 binary containers. Eventually, we hope, the moniker "next-generation" will no longer be applicable, and this will simply be the most efficient, common, and useful representation of bioimaging data, whether during acquisition or sharing in the cloud.

    -

    Note: The following text makes use of OME-Zarr [ome-zarr-py], the current prototype implementation, +

    Note: The following text makes use of OME-Zarr [ome-zarr-py], the current prototype implementation, for all examples.

    2. On-disk (or in-cloud) layout

    An overview of the layout of an OME-Zarr fileset should make @@ -1987,15 +2180,15 @@

    dimension_size / chunk_size</code>. + │ # will be `dimension_size / chunk_size`. │ └── labels │ ├── .zgroup # The labels group is a container which holds a list of labels to make the objects easily discoverable │ - ├── .zattrs # All labels will be listed in <code data-opaque bs-autolink-syntax='`.zattrs`'>.zattrs</code> e.g. <code data-opaque bs-autolink-syntax='`{ &quot;labels&quot;: [ &quot;original/0&quot; ] }`'>{ "labels": [ "original/0" ] }</code> - │ # Each dimension of the label <code data-opaque bs-autolink-syntax='`(t, c, z, y, x)`'>(t, c, z, y, x)</code> should be either the same as the - │ # corresponding dimension of the image, or <code data-opaque bs-autolink-syntax='`1`'>1</code> if that dimension of the label + ├── .zattrs # All labels will be listed in `.zattrs` e.g. `{ "labels": [ "original/0" ] }` + │ # Each dimension of the label `(t, c, z, y, x)` should be either the same as the + │ # corresponding dimension of the image, or `1` if that dimension of the label │ # is irrelevant. │ └── original # Intermediate folders are permitted but not necessary and currently contain no extra metadata. @@ -2181,7 +2374,7 @@

    3 MUST contain a path key identifying the path to the well subgroup.

    For example the following JSON object defines a plate with two acquisition and -6 wells (2 rows and 3 columns), containing up 2 fields of view per acquistion.

    +6 wells (2 rows and 3 columns), containing up 2 fields of view per acquisition.

    "plate": {
         "acquisitions": [
             {
    @@ -2301,9 +2494,9 @@ 

    OME2020 Workshop. Mouseover the blackboxes representing the implementations above to get a quick tip on how to use them.

    -

    Note: If you would like to see your project listed, please open an issue or PR on the ome/ngff repository.

    +

    Note: If you would like to see your project listed, please open an issue or PR on the ome/ngff repository.

    5. Citing

    -

    Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. J. Moore, et al. Editors. Open Microscopy Environment Consortium, 20 November 2020. +

    Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. J. Moore, et al. Open Microscopy Environment Consortium, 20 November 2020. This edition of the specification is https://ngff.openmicroscopy.org/0.1/. The latest edition is available at https://ngff.openmicroscopy.org/latest/. (doi:10.5281/zenodo.4282107)

    6. Version History

    @@ -2348,7 +2541,7 @@

    [RFC2119]

    + except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

    Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", @@ -2361,21 +2554,7 @@

    , like this:

    -

    Note, this is an informative note.

    -

    Conformant Algorithms

    -

    Requirements phrased in the imperative as part of algorithms - (such as "strip any leading space characters" - or "return false and abort these steps") - are to be interpreted with the meaning of the key word - ("must", "should", "may", etc) - used in introducing the algorithm.

    -

    Conformance requirements phrased as algorithms or specific steps - can be implemented in any manner, - so long as the end result is equivalent. - In particular, the algorithms defined in this specification - are intended to be easy to understand - and are not intended to be performant. - Implementers are encouraged to optimize.

    +

    Note, this is an informative note.

    Index

    diff --git a/0.1/schemas/plate.schema b/0.1/schemas/plate.schema new file mode 100644 index 00000000..e4f4f6f7 --- /dev/null +++ b/0.1/schemas/plate.schema @@ -0,0 +1,112 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.1/schemas/plate.schema", + "title": "OME-NGFF plate schema", + "description": "JSON from OME-NGFF Plate .zattrs", + "type": "object", + "properties": { + "plate": { + "type": "object", + "properties": { + "version": { + "type": "string", + "enum": [ + "0.1" + ] + }, + "name": { + "type": "string" + }, + "columns": { + "description": "Columns of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "rows": { + "description": "Rows of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "wells": { + "description": "Rows of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "type": "string" + } + }, + "required": [ + "path" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "field_count": { + "description": "Maximum number of fields per view across all wells." + }, + "acquisitions": { + "description": "Rows of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "maximumfieldcount": { + "type": "number" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "starttime": { + "type": "number" + } + }, + "required": [ + "id" + ] + }, + "minItems": 1, + "uniqueItems": true + } + }, + "required": [ + "version", "columns", "rows", "wells" + ] + } + }, + "required": [ + "plate" + ] +} \ No newline at end of file diff --git a/0.1/schemas/strict_image.schema b/0.1/schemas/strict_image.schema index 9c573d07..ac375073 100644 --- a/0.1/schemas/strict_image.schema +++ b/0.1/schemas/strict_image.schema @@ -1,4 +1,5 @@ { + "$id": "https://ngff.openmicroscopy.org/0.1/schemas/strict_image.schema", "allOf": [ { "$ref": "https://ngff.openmicroscopy.org/0.1/schemas/image.schema" diff --git a/0.1/schemas/well.schema b/0.1/schemas/well.schema new file mode 100644 index 00000000..02475934 --- /dev/null +++ b/0.1/schemas/well.schema @@ -0,0 +1,47 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.1/schemas/well.schema", + "title": "OME-NGFF well schema", + "description": "JSON from OME-NGFF .zattrs", + "type": "object", + "properties": { + "well": { + "type": "object", + "properties": { + "images": { + "description": "The fields of view for this well", + "type": "array", + "items": { + "type": "object", + "properties": { + "acquisition": { + "description": "A unique identifier within the context of the plate", + "type": "integer" + }, + "path": { + "description": "The path for this field of view subgroup", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "path" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "version": { + "description": "The version of the specification", + "type": "string", + "enum": [ + "0.1" + ] + } + }, + "required": [ + "images" + ] + } + } +} diff --git a/0.2/index.html b/0.2/index.html index 0857fd7d..925b44ff 100644 --- a/0.2/index.html +++ b/0.2/index.html @@ -1238,14 +1238,15 @@ grid-column: 2; width: auto; margin-right: 1rem; + border-bottom: 3px solid transparent; + margin-bottom: -3px; } #toc .content:hover, #toc .content:focus { background: rgba(75%, 75%, 75%, .25); background: var(--a-hover-bg); - border-bottom: 3px solid #054572; - border-bottom: 3px solid var(--toclink-underline); - margin-bottom: -3px; + border-bottom-color: #054572; + border-bottom-color: var(--toclink-underline); } #toc li li li .content { margin-left: 1rem; @@ -1487,11 +1488,11 @@ } } - + - - - + - + - + - - + -
    OME logo (6 circles in a hexagon)

    Next-generation file formats (NGFF)

    -

    Final Community Group Report,

    +

    Final Community Group Report,

    This version: @@ -1839,7 +2033,7 @@

    -
    @@ -1891,7 +2085,6 @@

    Table of Contents

    Conformance
    1. Document conventions -
    2. Conformant Algorithms
  • Index @@ -1939,8 +2132,8 @@

    1 parallelization.

    As a result, a number of formats have been developed more recently which provide the basic data structure of an HDF5 file, but do so in a more cloud-friendly way. -In the PyData community, the Zarr [zarr] format was developed -for easily storing collections of NumPy arrays. In the ImageJ community, N5 [n5] was developed to work around +In the PyData community, the Zarr [zarr] format was developed +for easily storing collections of NumPy arrays. In the ImageJ community, N5 [n5] was developed to work around the limitations of HDF5 ("N5" was originally short for "Not-HDF5"). Both of these formats permit storing individual chunks of data either locally in separate files or in cloud-based object stores as separate keys.

    @@ -1954,7 +2147,7 @@

    1 binary containers. Eventually, we hope, the moniker "next-generation" will no longer be applicable, and this will simply be the most efficient, common, and useful representation of bioimaging data, whether during acquisition or sharing in the cloud.

    -

    Note: The following text makes use of OME-Zarr [ome-zarr-py], the current prototype implementation, +

    Note: The following text makes use of OME-Zarr [ome-zarr-py], the current prototype implementation, for all examples.

    2. On-disk (or in-cloud) layout

    An overview of the layout of an OME-Zarr fileset should make @@ -1988,15 +2181,15 @@

    dimension_size / chunk_size</code>. + │ └─ x # will be `dimension_size / chunk_size`. │ └── labels │ ├── .zgroup # The labels group is a container which holds a list of labels to make the objects easily discoverable │ - ├── .zattrs # All labels will be listed in <code data-opaque bs-autolink-syntax='`.zattrs`'>.zattrs</code> e.g. <code data-opaque bs-autolink-syntax='`{ &quot;labels&quot;: [ &quot;original/0&quot; ] }`'>{ "labels": [ "original/0" ] }</code> - │ # Each dimension of the label <code data-opaque bs-autolink-syntax='`(t, c, z, y, x)`'>(t, c, z, y, x)</code> should be either the same as the - │ # corresponding dimension of the image, or <code data-opaque bs-autolink-syntax='`1`'>1</code> if that dimension of the label + ├── .zattrs # All labels will be listed in `.zattrs` e.g. `{ "labels": [ "original/0" ] }` + │ # Each dimension of the label `(t, c, z, y, x)` should be either the same as the + │ # corresponding dimension of the image, or `1` if that dimension of the label │ # is irrelevant. │ └── original # Intermediate folders are permitted but not necessary and currently contain no extra metadata. @@ -2077,7 +2270,7 @@

    : "gaussian", "metadata": { # the fields in metadata depend on the downscaling implementation - "method": "skimage.transform.pyramid_gaussian", # here, the paramters passed to the skimage function are given + "method": "skimage.transform.pyramid_gaussian", # here, the parameters passed to the skimage function are given "version": "0.16.1", "args": "[true]", "kwargs": {"multichannel": true} @@ -2227,7 +2420,7 @@

    3 MUST contain a path key identifying the path to the well subgroup.

    For example the following JSON object defines a plate with two acquisition and -6 wells (2 rows and 3 columns), containing up 2 fields of view per acquistion.

    +6 wells (2 rows and 3 columns), containing up 2 fields of view per acquisition.

    "plate": {
         "acquisitions": [
             {
    @@ -2349,9 +2542,9 @@ 

    OME2020 Workshop. Mouseover the blackboxes representing the implementations above to get a quick tip on how to use them.

    -

    Note: If you would like to see your project listed, please open an issue or PR on the ome/ngff repository.

    +

    Note: If you would like to see your project listed, please open an issue or PR on the ome/ngff repository.

    5. Citing

    -

    Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. J. Moore, et al. Editors. Open Microscopy Environment Consortium, 29 March, 2021. +

    Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. J. Moore, et al. Open Microscopy Environment Consortium, 29 March, 2021. This edition of the specification is https://ngff.openmicroscopy.org/0.2/. The latest edition is available at https://ngff.openmicroscopy.org/latest/. (doi:10.5281/zenodo.4282107)

    6. Version History

    @@ -2400,7 +2593,7 @@

    [RFC2119]

    + except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

    Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", @@ -2413,21 +2606,7 @@

    , like this:

    -

    Note, this is an informative note.

    -

    Conformant Algorithms

    -

    Requirements phrased in the imperative as part of algorithms - (such as "strip any leading space characters" - or "return false and abort these steps") - are to be interpreted with the meaning of the key word - ("must", "should", "may", etc) - used in introducing the algorithm.

    -

    Conformance requirements phrased as algorithms or specific steps - can be implemented in any manner, - so long as the end result is equivalent. - In particular, the algorithms defined in this specification - are intended to be easy to understand - and are not intended to be performant. - Implementers are encouraged to optimize.

    +

    Note, this is an informative note.

    Index

    diff --git a/0.2/schemas/plate.schema b/0.2/schemas/plate.schema new file mode 100644 index 00000000..e30b1662 --- /dev/null +++ b/0.2/schemas/plate.schema @@ -0,0 +1,119 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.2/schemas/plate.schema", + "title": "OME-NGFF plate schema", + "description": "JSON from OME-NGFF Plate .zattrs", + "type": "object", + "properties": { + "plate": { + "type": "object", + "properties": { + "version": { + "type": "string", + "enum": [ + "0.2" + ] + }, + "name": { + "type": "string" + }, + "columns": { + "description": "Columns of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "rows": { + "description": "Rows of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "wells": { + "description": "Rows of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "type": "string" + } + }, + "required": [ + "path" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "field_count": { + "description": "Maximum number of fields per view across all wells." + }, + "acquisitions": { + "description": "Rows of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "maximumfieldcount": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "starttime": { + "description": "The start timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch", + "type": "integer", + "minimum": 0 + }, + "endtime": { + "description": "The end timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch", + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "id" + ] + }, + "minItems": 1, + "uniqueItems": true + } + }, + "required": [ + "version", "columns", "rows", "wells" + ] + } + }, + "required": [ + "plate" + ] +} \ No newline at end of file diff --git a/0.2/schemas/well.schema b/0.2/schemas/well.schema new file mode 100644 index 00000000..8dca3290 --- /dev/null +++ b/0.2/schemas/well.schema @@ -0,0 +1,47 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.2/schemas/well.schema", + "title": "OME-NGFF well schema", + "description": "JSON from OME-NGFF .zattrs", + "type": "object", + "properties": { + "well": { + "type": "object", + "properties": { + "images": { + "description": "The fields of view for this well", + "type": "array", + "items": { + "type": "object", + "properties": { + "acquisition": { + "description": "A unique identifier within the context of the plate", + "type": "integer" + }, + "path": { + "description": "The path for this field of view subgroup", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "path" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "version": { + "description": "The version of the specification", + "type": "string", + "enum": [ + "0.2" + ] + } + }, + "required": [ + "images" + ] + } + } +} diff --git a/0.3/index.html b/0.3/index.html index c59467d1..c3ce1f17 100644 --- a/0.3/index.html +++ b/0.3/index.html @@ -5,12 +5,11 @@ Next-generation file formats (NGFF) - - + - - - + - + - + - - + -

    Next-generation file formats (NGFF)

    -

    Final Community Group Report,

    +

    Final Community Group Report,

    More details about this document
    @@ -362,7 +554,7 @@

    Next-generation file formats (NGFF)

    -
    @@ -414,7 +606,6 @@

    Table of Contents

    Conformance
    1. Document conventions -
    2. Conformant Algorithms
  • Index @@ -462,8 +653,8 @@

    1 parallelization.

    As a result, a number of formats have been developed more recently which provide the basic data structure of an HDF5 file, but do so in a more cloud-friendly way. -In the PyData community, the Zarr [zarr] format was developed -for easily storing collections of NumPy arrays. In the ImageJ community, N5 [n5] was developed to work around +In the PyData community, the Zarr [zarr] format was developed +for easily storing collections of NumPy arrays. In the ImageJ community, N5 [n5] was developed to work around the limitations of HDF5 ("N5" was originally short for "Not-HDF5"). Both of these formats permit storing individual chunks of data either locally in separate files or in cloud-based object stores as separate keys.

    @@ -477,7 +668,7 @@

    1 binary containers. Eventually, we hope, the moniker "next-generation" will no longer be applicable, and this will simply be the most efficient, common, and useful representation of bioimaging data, whether during acquisition or sharing in the cloud.

    -

    Note: The following text makes use of OME-Zarr [ome-zarr-py], the current prototype implementation, +

    Note: The following text makes use of OME-Zarr [ome-zarr-py], the current prototype implementation, for all examples.

    2. On-disk (or in-cloud) layout

    An overview of the layout of an OME-Zarr fileset should make @@ -512,15 +703,15 @@

    dimension_size / chunk_size</code>. + │ └─ x # will be `dimension_size / chunk_size`. │ └── labels │ ├── .zgroup # The labels group is a container which holds a list of labels to make the objects easily discoverable │ - ├── .zattrs # All labels will be listed in <code data-opaque bs-autolink-syntax='`.zattrs`'>.zattrs</code> e.g. <code data-opaque bs-autolink-syntax='`{ &quot;labels&quot;: [ &quot;original/0&quot; ] }`'>{ "labels": [ "original/0" ] }</code> - │ # Each dimension of the label <code data-opaque bs-autolink-syntax='`(t, c, z, y, x)`'>(t, c, z, y, x)</code> should be either the same as the - │ # corresponding dimension of the image, or <code data-opaque bs-autolink-syntax='`1`'>1</code> if that dimension of the label + ├── .zattrs # All labels will be listed in `.zattrs` e.g. `{ "labels": [ "original/0" ] }` + │ # Each dimension of the label `(t, c, z, y, x)` should be either the same as the + │ # corresponding dimension of the image, or `1` if that dimension of the label │ # is irrelevant. │ └── original # Intermediate folders are permitted but not necessary and currently contain no extra metadata. @@ -610,7 +801,7 @@

    : "gaussian", "metadata": { # the fields in metadata depend on the downscaling implementation - "method": "skimage.transform.pyramid_gaussian", # here, the paramters passed to the skimage function are given + "method": "skimage.transform.pyramid_gaussian", # here, the parameters passed to the skimage function are given "version": "0.16.1", "args": "[true]", "kwargs": {"multichannel": true} @@ -760,7 +951,7 @@

    3 MUST contain a path key identifying the path to the well subgroup.

    For example the following JSON object defines a plate with two acquisition and -6 wells (2 rows and 3 columns), containing up 2 fields of view per acquistion.

    +6 wells (2 rows and 3 columns), containing up 2 fields of view per acquisition.

    "plate": {
         "acquisitions": [
             {
    @@ -880,9 +1071,9 @@ 

    OME2020 Workshop. Mouseover the blackboxes representing the implementations above to get a quick tip on how to use them.

    -

    Note: If you would like to see your project listed, please open an issue or PR on the ome/ngff repository.

    +

    Note: If you would like to see your project listed, please open an issue or PR on the ome/ngff repository.

    5. Citing

    -

    Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. J. Moore, et al. Editors. Open Microscopy Environment Consortium, 20 November 2020. +

    Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. J. Moore, et al. Open Microscopy Environment Consortium, 20 November 2020. This edition of the specification is https://ngff.openmicroscopy.org/0.3/. The latest edition is available at https://ngff.openmicroscopy.org/latest/. (doi:10.5281/zenodo.4282107)

    6. Version History

    @@ -935,7 +1126,7 @@

    [RFC2119]

    + except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

    Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", @@ -948,21 +1139,7 @@

    , like this:

    -

    Note, this is an informative note.

    -

    Conformant Algorithms

    -

    Requirements phrased in the imperative as part of algorithms - (such as "strip any leading space characters" - or "return false and abort these steps") - are to be interpreted with the meaning of the key word - ("must", "should", "may", etc) - used in introducing the algorithm.

    -

    Conformance requirements phrased as algorithms or specific steps - can be implemented in any manner, - so long as the end result is equivalent. - In particular, the algorithms defined in this specification - are intended to be easy to understand - and are not intended to be performant. - Implementers are encouraged to optimize.

    +

    Note, this is an informative note.

    Index

    diff --git a/0.3/schemas/plate.schema b/0.3/schemas/plate.schema new file mode 100644 index 00000000..1222d895 --- /dev/null +++ b/0.3/schemas/plate.schema @@ -0,0 +1,119 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.3/schemas/plate.schema", + "title": "NGFF Plate", + "description": "JSON from OME-NGFF Plate .zattrs", + "type": "object", + "properties": { + "plate": { + "type": "object", + "properties": { + "version": { + "type": "string", + "enum": [ + "0.3" + ] + }, + "name": { + "type": "string" + }, + "columns": { + "description": "Columns of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "rows": { + "description": "Rows of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "wells": { + "description": "Rows of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "type": "string" + } + }, + "required": [ + "path" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "field_count": { + "description": "Maximum number of fields per view across all wells." + }, + "acquisitions": { + "description": "Rows of the Plate grid", + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "maximumfieldcount": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "starttime": { + "description": "The start timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch", + "type": "integer", + "minimum": 0 + }, + "endtime": { + "description": "The end timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch", + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "id" + ] + }, + "minItems": 1, + "uniqueItems": true + } + }, + "required": [ + "version", "columns", "rows", "wells" + ] + } + }, + "required": [ + "plate" + ] +} \ No newline at end of file diff --git a/0.3/schemas/strict_image.schema b/0.3/schemas/strict_image.schema index d3758444..5e16b2a4 100644 --- a/0.3/schemas/strict_image.schema +++ b/0.3/schemas/strict_image.schema @@ -1,4 +1,5 @@ { + "$id": "https://ngff.openmicroscopy.org/0.3/schemas/strict_image.schema", "allOf": [ { "$ref": "https://ngff.openmicroscopy.org/0.3/schemas/image.schema" diff --git a/0.3/schemas/well.schema b/0.3/schemas/well.schema new file mode 100644 index 00000000..b88bc745 --- /dev/null +++ b/0.3/schemas/well.schema @@ -0,0 +1,47 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.3/schemas/well.schema", + "title": "OME-NGFF well schema", + "description": "JSON from OME-NGFF .zattrs", + "type": "object", + "properties": { + "well": { + "type": "object", + "properties": { + "images": { + "description": "The fields of view for this well", + "type": "array", + "items": { + "type": "object", + "properties": { + "acquisition": { + "description": "A unique identifier within the context of the plate", + "type": "integer" + }, + "path": { + "description": "The path for this field of view subgroup", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "path" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "version": { + "description": "The version of the specification", + "type": "string", + "enum": [ + "0.3" + ] + } + }, + "required": [ + "images" + ] + } + } +} diff --git a/0.4/index.html b/0.4/index.html index eb04d38a..f34e2ac9 100644 --- a/0.4/index.html +++ b/0.4/index.html @@ -5,12 +5,11 @@ Next-generation file formats (NGFF) - - + - - - + - + - + + - - + -

    Next-generation file formats (NGFF)

    -

    Final Community Group Report,

    +

    Final Community Group Report,

    More details about this document
    @@ -362,7 +607,7 @@

    Next-generation file formats (NGFF)

    -
    @@ -402,13 +647,14 @@

    Table of Contents

    3 Metadata
    1. 3.1 "axes" metadata -
    2. 3.2 "coordinateTransformations" metadata -
    3. 3.3 "multiscales" metadata -
    4. 3.4 "omero" metadata -
    5. 3.5 "labels" metadata -
    6. 3.6 "image-label" metadata -
    7. 3.7 "plate" metadata -
    8. 3.8 "well" metadata +
    9. 3.2 "bioformats2raw.layout" (transitional) +
    10. 3.3 "coordinateTransformations" metadata +
    11. 3.4 "multiscales" metadata +
    12. 3.5 "omero" metadata (transitional) +
    13. 3.6 "labels" metadata +
    14. 3.7 "image-label" metadata +
    15. 3.8 "plate" metadata +
    16. 3.9 "well" metadata
  • 4 Specification naming style
  • 5 Implementations @@ -418,7 +664,6 @@

    Table of Contents

    Conformance
    1. Document conventions -
    2. Conformant Algorithms
  • Index @@ -466,8 +711,8 @@

    1 parallelization.

    As a result, a number of formats have been developed more recently which provide the basic data structure of an HDF5 file, but do so in a more cloud-friendly way. -In the PyData community, the Zarr [zarr] format was developed -for easily storing collections of NumPy arrays. In the ImageJ community, N5 [n5] was developed to work around +In the PyData community, the Zarr [zarr] format was developed +for easily storing collections of NumPy arrays. In the ImageJ community, N5 [n5] was developed to work around the limitations of HDF5 ("N5" was originally short for "Not-HDF5"). Both of these formats permit storing individual chunks of data either locally in separate files or in cloud-based object stores as separate keys.

    @@ -481,12 +726,17 @@

    1 binary containers. Eventually, we hope, the moniker "next-generation" will no longer be applicable, and this will simply be the most efficient, common, and useful representation of bioimaging data, whether during acquisition or sharing in the cloud.

    -

    Note: The following text makes use of OME-Zarr [ome-zarr-py], the current prototype implementation, +

    Note: The following text makes use of OME-Zarr [ome-zarr-py], the current prototype implementation, for all examples.

    1.3. Document conventions

    The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” are to be interpreted as described in RFC 2119.

    -

    Some of the JSON examples in this document include commments. However, these are only for +

    Transitional metadata is added to the specification with the +intention of removing it in the future. Implementations may be expected (MUST) or +encouraged (SHOULD) to support the reading of the data, but writing will usually +be optional (MAY). Examples of transitional metadata include custom additions by +implementations that are later submitted as a formal specification. (See § 3.2 "bioformats2raw.layout" (transitional))

    +

    Some of the JSON examples in this document include comments. However, these are only for clarity purposes and comments MUST NOT be included in JSON objects.

    2. On-disk (or in-cloud) layout

    An overview of the layout of an OME-Zarr fileset should make @@ -502,7 +752,7 @@

    2. <

    2.1. Images

    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 § 3.3 "multiscales" metadata for details. +Note that the number of dimensions is variable between 2 and 5 and that axis names are arbitrary, see § 3.4 "multiscales" metadata for details. For this example we assume an image with 5 dimensions and axes called t,c,z,y,x.

    .                             # Root folder, potentially in S3,
     │                             # with a flat list of images by image ID.
    @@ -514,7 +764,7 @@ 

    3.

    Units for "time" axes: attosecond, centisecond, day, decisecond, exasecond, femtosecond, gigasecond, hectosecond, hour, kilosecond, megasecond, microsecond, millisecond, minute, nanosecond, petasecond, picosecond, second, terasecond, yoctosecond, yottasecond, zeptosecond, zettasecond

    -

    If part of § 3.3 "multiscales" metadata, the length of "axes" MUST be equal to the number of dimensions of the arrays that contain the image data.

    -

    3.2. "coordinateTransformations" metadata

    +

    If part of § 3.4 "multiscales" metadata, the length of "axes" MUST be equal to the number of dimensions of the arrays that contain the image data.

    +

    3.2. "bioformats2raw.layout" (transitional)

    +

    Transitional "bioformats2raw.layout" metadata identifies a group which implicitly describes a series of images. +The need for the collection stems from the common "multi-image file" scenario in microscopy. Parsers like Bio-Formats +define a strict, stable ordering of the images in a single container that can be used to refer to them by other tools.

    +

    In order to capture that information within an OME-NGFF dataset, bioformats2raw internally introduced a wrapping layer. +The bioformats2raw layout has been added to v0.4 as a transitional specification to specify filesets that already exist +in the wild. An upcoming NGFF specification will replace this layout with explicit metadata.

    +

    3.2.1. Layout

    +

    Typical Zarr layout produced by running bioformats2raw on a fileset that contains more than one image (series > 1):

    +
    series.ome.zarr               # One converted fileset from bioformats2raw
    +    ├── .zgroup
    +    ├── .zattrs               # Contains "bioformats2raw.layout" metadata
    +    ├── OME                   # Special group for containing OME metadata
    +    │   ├── .zgroup
    +    │   ├── .zattrs           # Contains "series" metadata
    +    │   └── METADATA.ome.xml  # OME-XML file stored within the Zarr fileset
    +    ├── 0                     # First image in the collection
    +    ├── 1                     # Second image in the collection
    +    └── ...
    +
    +

    3.2.2. Attributes

    +

    The top-level .zattrs file must contain the bioformats2raw.layout key:

    +
    {
    +  "bioformats2raw.layout" : 3
    +}
    +

    If the top-level group represents a plate, the bioformats2raw.layout metadata will be present but +the "plate" key MUST also be present, takes precedence and parsing of such datasets should follow § 3.8 "plate" metadata. It is not +possible to mix collections of images with plates at present.

    +
    {
    +  "bioformats2raw.layout" : 3,
    +  "plate" : {
    +    "columns" : [ {
    +      "name" : "1"
    +    } ],
    +    "name" : "Plate Name 0",
    +    "wells" : [ {
    +      "path" : "A/1",
    +      "rowIndex" : 0,
    +      "columnIndex" : 0
    +    } ],
    +    "field_count" : 1,
    +    "rows" : [ {
    +      "name" : "A"
    +    } ],
    +    "acquisitions" : [ {
    +      "id" : 0
    +    } ],
    +    "version" : "0.4"
    +  }
    +}
    +
    +

    The .zattrs file within the OME group may contain the "series" key:

    +
    {
    +  "series" : [ "0", "1" ]
    +}
    +
    +

    3.2.3. Details

    +

    Conforming groups:

    +
      +
    • +

      MUST have the value "3" for the "bioformats2raw.layout" key in their .zattrs metadata at the top of the hierarchy;

      +
    • +

      SHOULD have OME metadata representing the entire collection of images in a file named "OME/METADATA.ome.xml" which:

      +
        +
      • +

        MUST adhere to the OME-XML specification but

        +
      • +

        MUST use <MetadataOnly/> elements as opposed to <BinData/>, <BinaryOnly/> or <TiffData/>;

        +
      • +

        MAY make use of the minimum specification.

        +
      +
    +

    Additionally, the logic for finding the Zarr group for each image follows the following logic:

    +
      +
    • +

      If "plate" metadata is present, images MUST be located at the defined location.

      +
        +
      • +

        Matching "series" metadata (as described next) SHOULD be provided for tools that are unaware of the "plate" specification.

        +
      +
    • +

      If the "OME" Zarr group exists, it:

      +
        +
      • +

        MAY contain a "series" attribute. If so:

        +
          +
        • +

          "series" MUST be a list of string objects, each of which is a path to an image group.

          +
        • +

          The order of the paths MUST match the order of the "Image" elements in "OME/METADATA.ome.xml" if provided.

          +
        +
      +
    • +

      If the "series" attribute does not exist and no "plate" is present:

      +
        +
      • +

        separate "multiscales" images MUST be stored in consecutively numbered groups starting from 0 (i.e. "0/", "1/", "2/", "3/", ...).

        +
      +
    • +

      Every "multiscales" group MUST represent exactly one OME-XML "Image" in the same order as either the series index or the group numbers.

      +
    +

    Conforming readers:

    +
      +
    • +

      SHOULD make users aware of the presence of more than one image (i.e. SHOULD NOT default to only opening the first image);

      +
    • +

      MAY use the "series" attribute in the "OME" group to determine a list of valid groups to display;

      +
    • +

      MAY choose to show all images within the collection or offer the user a choice of images, as with HCS plates;

      +
    • +

      MAY ignore other groups or arrays under the root of the hierarchy.

      +
    +

    3.3. "coordinateTransformations" metadata

    "coordinateTransformations" describe a series of transformations that map between two coordinate spaces (defined by "axes"). For example, to map a discrete data space of an array to the corresponding physical space. It is a list of dictionaries. Each entry describes a single transformation and MUST contain the field "type". @@ -638,7 +1000,7 @@

    3 description

    The transformations in the list are applied sequentially and in order.

    -

    3.3. "multiscales" metadata

    +

    3.4. "multiscales" metadata

    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.

    "multiscales" contains a list of dictionaries where each entry describes a multiscale image.

    Each "multiscales" dictionary MUST contain the field "axes", see § 3.1 "axes" metadata. @@ -651,7 +1013,7 @@

    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 § 3.2 "coordinateTransformations" metadata. The transformation MUST only be of type translation or scale. +The transformations are defined according to § 3.3 "coordinateTransformations" metadata. 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. It MAY contain exactly one translation that specifies the offset from the origin in physical units. If translation is given it MUST be listed after scale to ensure that it is given in physical coordinates. The length of the scale and translation array MUST be the same as the length of "axes". @@ -678,7 +1040,7 @@

    : "0", "coordinateTransformations": [{ - // the voxel size for the first scale level (0.5 micrometer) + // the voxel size for the first scale level (0.5 micrometer) "type": "scale", "scale": [1.0, 1.0, 0.5, 0.5, 0.5] }] @@ -686,7 +1048,7 @@

    : "1", "coordinateTransformations": [{ - // the voxel size for the second scale level (downscaled by a factor of 2 -> 1 micrometer) + // the voxel size for the second scale level (downscaled by a factor of 2 -> 1 micrometer) "type": "scale", "scale": [1.0, 1.0, 1.0, 1.0, 1.0] }] @@ -694,14 +1056,14 @@

    : "2", "coordinateTransformations": [{ - // the voxel size for the third scale level (downscaled by a factor of 4 -> 2 micrometer) + // the voxel size for the third scale level (downscaled by a factor of 4 -> 2 micrometer) "type": "scale", "scale": [1.0, 1.0, 2.0, 2.0, 2.0] }] } ], "coordinateTransformations": [{ - // the time unit (0.1 milliseconds), which is the same for each scale level + // 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] }], @@ -727,8 +1089,8 @@

    ] for x in multiscales[0]["datasets"]]

    -

    3.4. "omero" metadata

    -

    Information specific to the channels of an image and how to render it +

    3.5. "omero" metadata (transitional)

    +

    Transitional information specific to the channels of an image and how to render it can be found under the "omero" key in the group-level metadata:

    "id": 1,                              # ID in OMERO
     "name": "example.tif",                # Name as shown in the UI
    @@ -757,7 +1119,12 @@ 

    3

    See https://docs.openmicroscopy.org/omero/5.6.1/developers/Web/WebGateway.html#imgdata for more information.

    -

    3.5. "labels" metadata

    +

    The "omero" metadata is optional, but if present it MUST contain the field "channels", which is an array of dictionaries describing the channels of the image. +Each dictionary in "channels" MUST contain the field "color", which is a string of 6 hexadecimal digits specifying the color of the channel in RGB format. +Each dictionary in "channels" MUST contain the field "window", which is a dictionary describing the windowing of the channel. +The field "window" MUST contain the fields "min" and "max", which are the minimum and maximum values of the window, respectively. +It MUST also contain the fields "start" and "end", which are the start and end values of the window, respectively.

    +

    3.6. "labels" metadata

    The special group "labels" found under an image Zarr contains the key labels containing the paths to label objects which can be found underneath the group:

    {
    @@ -767,112 +1134,106 @@ 

    }

    Unlisted groups MAY be labels.

    -

    3.6. "image-label" metadata

    +

    3.7. "image-label" metadata

    Groups containing the image-label dictionary represent an image segmentation in which each unique pixel value represents a separate segmented object. image-label groups MUST also contain multiscales metadata and the two "datasets" series MUST have the same number of entries.

    -

    The colors key defines a list of JSON objects describing the unique label -values. Each entry in the list MUST contain the key "label-value" with the -pixel value for that label. Additionally, the "rgba" key MAY be present, the -value for which is an RGBA unsigned-int 4-tuple: [uint8, uint8, uint8, uint8] All label-values must be unique. Clients who choose to not throw an error -should ignore all except the _last_ entry.

    -

    Some implementations may represent overlapping labels by using a specially assigned +

    The image-label dictionary SHOULD contain a colors key whose value MUST be a +list of JSON objects describing the unique label values. Each color object MUST +contain the label-value key whose value MUST be an integer specifying the +pixel value for that label. It MAY contain an rgba key whose value MUST be an array +of four integers between 0 and 255 [uint8, uint8, uint8, uint8] specifying the label +color as RGBA. All the values under the label-value key MUST be unique. Clients +who choose to not throw an error SHOULD ignore all except the _last_ entry.

    +

    Some implementations MAY represent overlapping labels by using a specially assigned value, for example the highest integer available in the pixel range.

    -

    The properties key defines a list of JSON objects which also describes the unique -label values. Each entry in the list MUST contain the key "label-value" with the -pixel value for that label. Additionally, an arbitrary number of key-value pairs +

    The image-label dictionary MAY contain a properties key whose value MUST be a +list of JSON objects which also describes the unique label values. Each property object +MUST contain the label-value key whose value MUST be an integer specifying the pixel +value for that label. Additionally, an arbitrary number of key-value pairs MAY be present for each label value denoting associated metadata. Not all label values must share the same key-value pairs within the properties list.

    -

    The source key is an optional dictionary which contains information on the -image the label is associated with. If included it MAY include a key image whose value is the relative path to a Zarr image group. The default value is -"../../" since most labels are stored under a subgroup named "labels/" (see -above).

    -
    "image-label":
    -  {
    +   

    The image-label dictionary MAY contain a source key whose value MUST be a JSON +object containing information on the image the label is associated with. If included, +it MAY include a key image whose value MUST be a string specifying the relative +path to a Zarr image group. The default value is "../../" since most labels are stored +under a subgroup named "labels/" (see above).

    +

    The image-label dictionary SHOULD contain a version key whose value MUST be a string +specifying the version of the image-label specification.

    +
    {
    +  "image-label": {
         "version": "0.4",
         "colors": [
           {
             "label-value": 1,
    -        "rgba": [255, 255, 255, 0]
    +        "rgba": [255, 255, 255, 255]
           },
           {
             "label-value": 4,
             "rgba": [0, 255, 255, 128]
    -      },
    -      ...
    -      ],
    +      }
    +    ],
         "properties": [
           {
             "label-value": 1,
             "area (pixels)": 1200,
             "class": "foo"
    -
           },
           {
             "label-value": 4,
             "area (pixels)": 1650
    -      },
    -      ...
    -      ]
    -  },
    -  "source": {
    -    "image": "../../"
    +      }
    +    ],
    +    "source": {
    +      "image": "../../"
    +    }
       }
    -]
    +}
     
    -

    3.7. "plate" metadata

    +

    3.8. "plate" metadata

    For high-content screening datasets, the plate layout can be found under the -custom attributes of the plate group under the plate key.

    -
    -
    acquisitions -
    An optional list of JSON objects defining the acquisitions for a given - plate. Each acquisition object MUST contain an id key providing an - unique identifier within the context of the plate to which fields of - view can refer to. It SHOULD contain a name key identifying the name - of the acquisition. It SHOULD contain a maximumfieldcount key - indicating the maximum number of fields of view for the acquisition. It - MAY contain a description key providing a description for the - acquisition. It MAY contain a startime and/or endtime key specifying - the start and/or end timestamp of the acquisition using an epoch - string. -
    columns -
    A list of JSON objects defining the columns of the plate. Each column - object defines the properties of the column at the index of the object - in the list. Each column in the physical plate MUST be defined, even - if no wells in the column are defined. Each defined column MUST contain - a name key specifying the column name. The name MUST contain only - alphanumeric characters, MUST be case-sensitive, and MUST NOT be a - duplicate of any other name in the columns list. Care SHOULD be - taken to avoid collisions on case-insensitive filesystems - (e.g. avoid using both Aa and aA). -
    field_count -
    An integer defining the maximum number of fields per view across all - wells. -
    name -
    A string defining the name of the plate. -
    rows -
    A list of JSON objects defining the rows of the plate. Each row object - defines the properties of the row at the index of the object in the - list. Each row in the physical plate MUST be defined, even if no wells - in the row are defined. Each defined row MUST contain a name key - specifying the row name. The name MUST contain only alphanumeric - characters, MUST be case-sensitive, and MUST NOT be a duplicate - of any other name in the rows list. Care SHOULD be taken to avoid - collisions on case-insensitive filesystems (e.g. avoid using both Aa and aA). -
    version -
    A string defining the version of the specification. -
    wells -
    A list of JSON objects defining the wells of the plate. Each well object - MUST contain a path key identifying the path to the well subgroup. - The path MUST consist of a name in the rows list, a file separator (/), - and a name from the columns list, in that order. The path MUST NOT contain - additional leading or trailing directories. - Each well object MUST contain both a rowIndex key identifying the index into - the rows list and a columnIndex key indentifying the index into - the columns list. rowIndex and columnIndex MUST be 0-based. - The rowIndex, columnIndex, and path MUST all refer to the same - row/column pair. -
    +custom attributes of the plate group under the plate key in the group-level metadata.

    +

    The plate dictionary MAY contain an acquisitions key whose value MUST be a list of +JSON objects defining the acquisitions for a given plate to which wells can refer to. Each +acquisition object MUST contain an id key whose value MUST be an unique integer identifier +greater than or equal to 0 within the context of the plate to which fields of view can refer +to (see #well-md). +Each acquisition object SHOULD contain a name key whose value MUST be a string identifying +the name of the acquisition. Each acquisition object SHOULD contain a maximumfieldcount key whose value MUST be a positive integer indicating the maximum number of fields of view for the +acquisition. Each acquisition object MAY contain a description key whose value MUST be a +string specifying a description for the acquisition. Each acquisition object MAY contain +a starttime and/or endtime key whose values MUST be integer epoch timestamps specifying +the start and/or end timestamp of the acquisition.

    +

    The plate dictionary MUST contain a columns key whose value MUST be a list of JSON objects +defining the columns of the plate. Each column object defines the properties of +the column at the index of the object in the list. Each column in the physical plate +MUST be defined, even if no wells in the column are defined. Each column object MUST +contain a name key whose value is a string specifying the column name. The name MUST +contain only alphanumeric characters, MUST be case-sensitive, and MUST NOT be a duplicate of any +other name in the columns list. Care SHOULD be taken to avoid collisions on +case-insensitive filesystems (e.g. avoid using both Aa and aA).

    +

    The plate dictionary SHOULD contain a field_count key whose value MUST be a positive integer +defining the maximum number of fields per view across all wells.

    +

    The plate dictionary SHOULD contain a name key whose value MUST be a string defining the +name of the plate.

    +

    The plate dictionary MUST contain a rows key whose value MUST be a list of JSON objects +defining the rows of the plate. Each row object defines the properties of +the row at the index of the object in the list. Each row in the physical plate +MUST be defined, even if no wells in the row are defined. Each defined row MUST +contain a name key whose value MUST be a string defining the row name. The name MUST +contain only alphanumeric characters, MUST be case-sensitive, and MUST NOT be a duplicate of any +other name in the rows list. Care SHOULD be taken to avoid collisions on +case-insensitive filesystems (e.g. avoid using both Aa and aA).

    +

    The plate dictionary SHOULD contain a version key whose value MUST be a string specifying the +version of the plate specification.

    +

    The plate dictionary MUST contain a wells key whose value MUST be a list of JSON objects +defining the wells of the plate. Each well object MUST contain a path key whose value MUST +be a string specifying the path to the well subgroup. The path MUST consist of a name in +the rows list, a file separator (/), and a name from the columns list, in that order. +The path MUST NOT contain additional leading or trailing directories. +Each well object MUST contain both a rowIndex key whose value MUST be an integer identifying +the index into the rows list and a columnIndex key whose value MUST be an integer identifying +the index into the columns list. rowIndex and columnIndex MUST be 0-based. The rowIndex, columnIndex, and path MUST all refer to the same row/column pair.

    For example the following JSON object defines a plate with two acquisitions and 6 wells (2 rows and 3 columns), containing up to 2 fields of view per acquisition.

    {
    @@ -1042,21 +1403,17 @@ 

    3 } }

    -

    3.8. "well" metadata

    +

    3.9. "well" metadata

    For high-content screening datasets, the metadata about all fields of views under a given well can be found under the "well" key in the attributes of the well group.

    -
    -
    images -
    A list of JSON objects defining the fields of views for a given well. - Each object MUST contain a path key identifying the path to the - field of view. If multiple acquisitions were performed in the plate, it - MUST contain an acquisition key identifying the id of the - acquisition which must match one of acquisition JSON objects defined in - the plate metadata. -
    version -
    A string defining the version of the specification. -
    +

    The well dictionary MUST contain an images key whose value MUST be a list of JSON objects +specifying all fields of views for a given well. Each image object MUST contain a path key whose value MUST be a string specifying the path to the field of view. The path MUST contain only alphanumeric characters, MUST be case-sensitive, and MUST NOT be a duplicate +of any other path in the images list. If multiple acquisitions were performed in the plate, +it MUST contain an acquisition key whose value MUST be an integer identifying the acquisition +which MUST match one of the acquisition JSON objects defined in the plate metadata (see #plate-md).

    +

    The well dictionary SHOULD contain a version key whose value MUST be a string specifying the +version of the well specification.

    For example the following JSON object defines a well with four fields of view. The first two fields of view were part of the first acquisition while the last two fields of view were part of the second acquisition.

    @@ -1127,9 +1484,9 @@

    OME2020 Workshop. Mouseover the blackboxes representing the implementations above to get a quick tip on how to use them.

    -

    Note: If you would like to see your project listed, please open an issue or PR on the ome/ngff repository.

    +

    Note: If you would like to see your project listed, please open an issue or PR on the ome/ngff repository.

    6. Citing

    -

    Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. J. Moore, et al. Editors. Open Microscopy Environment Consortium, 8 February 2022. +

    Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. J. Moore, et al. Open Microscopy Environment Consortium, 8 February 2022. This edition of the specification is https://ngff.openmicroscopy.org/0.4/. The latest edition is available at https://ngff.openmicroscopy.org/latest/. (doi:10.5281/zenodo.4282107)

    7. Version History

    @@ -1140,6 +1497,10 @@

    7. < Date Description + + 0.4.1 + 2022-09-26 + transitional metadata for image collections ("bioformats2raw.layout") 0.4.0 2022-02-08 @@ -1190,7 +1551,7 @@

    [RFC2119]

    + except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

    Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", @@ -1203,28 +1564,16 @@

    , like this:

    -

    Note, this is an informative note.

    -

    Conformant Algorithms

    -

    Requirements phrased in the imperative as part of algorithms - (such as "strip any leading space characters" - or "return false and abort these steps") - are to be interpreted with the meaning of the key word - ("must", "should", "may", etc) - used in introducing the algorithm.

    -

    Conformance requirements phrased as algorithms or specific steps - can be implemented in any manner, - so long as the end result is equivalent. - In particular, the algorithms defined in this specification - are intended to be easy to understand - and are not intended to be performant. - Implementers are encouraged to optimize.

    +

    Note, this is an informative note.

    Index

    Terms defined by this specification

    References

    Normative References

    @@ -1240,4 +1589,357 @@

    OME; et al. ome-zarr-py: Experimental implementation of next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.. 06 October 2020. Informational. URL: https://doi.org/10.5281/zenodo.4113931
    [ZARR]
    Alistair Miles; et al. Zarr: An implementation of chunked, compressed, N-dimensional arrays for Python.. 06 October 2020. Informational. URL: https://doi.org/10.5281/zenodo.4069231 - \ No newline at end of file + + + + \ No newline at end of file diff --git a/0.4/schemas/image.schema b/0.4/schemas/image.schema index 59e8e28e..aec5db5f 100644 --- a/0.4/schemas/image.schema +++ b/0.4/schemas/image.schema @@ -124,7 +124,7 @@ "type": "string", "enum": ["space"] }, - "units": { + "unit": { "type": "string" } } diff --git a/0.4/schemas/label.schema b/0.4/schemas/label.schema new file mode 100644 index 00000000..1629d0f9 --- /dev/null +++ b/0.4/schemas/label.schema @@ -0,0 +1,77 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/label.schema", + "title": "OME-NGFF labelled image schema", + "description": "JSON from OME-NGFF .zattrs", + "type": "object", + "properties": { + "image-label": { + "type": "object", + "properties": { + "colors": { + "description": "The colors for this label image", + "type": "array", + "items": { + "type": "object", + "properties": { + "label-value": { + "description": "The value of the label", + "type": "number" + }, + "rgba": { + "description": "The RGBA color stored as an array of four integers between 0 and 255", + "type": "array", + "items": { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "minItems": 4, + "maxItems": 4 + } + }, + "required": [ + "label-value" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "properties": { + "description": "The properties for this label image", + "type": "array", + "items": { + "type": "object", + "properties": { + "label-value": { + "description": "The pixel value for this label", + "type": "integer" + } + }, + "required": [ + "label-value" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "source": { + "description": "The source of this label image", + "type": "object", + "properties": { + "image": { + "type": "string" + } + } + }, + "version": { + "description": "The version of the specification", + "type": "string", + "enum": [ + "0.4" + ] + } + } + } + } +} diff --git a/0.4/schemas/plate.schema b/0.4/schemas/plate.schema new file mode 100644 index 00000000..df7cfad0 --- /dev/null +++ b/0.4/schemas/plate.schema @@ -0,0 +1,140 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/plate.schema", + "title": "OME-NGFF plate schema", + "description": "JSON from OME-NGFF .zattrs", + "type": "object", + "properties": { + "plate": { + "type": "object", + "properties": { + "acquisitions": { + "description": "The acquisitions for this plate", + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "description": "A unique identifier within the context of the plate", + "type": "integer", + "minimum": 0 + }, + "maximumfieldcount": { + "description": "The maximum number of fields of view for the acquisition", + "type": "integer", + "exclusiveMinimum": 0 + }, + "name": { + "description": "The name of the acquisition", + "type": "string" + }, + "description": { + "description": "The description of the acquisition", + "type": "string" + }, + "starttime": { + "description": "The start timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch", + "type": "integer", + "minimum": 0 + }, + "endtime": { + "description": "The end timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch", + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "id" + ] + } + }, + "version": { + "description": "The version of the specification", + "type": "string", + "enum": [ + "0.4" + ] + }, + "field_count": { + "description": "The maximum number of fields per view across all wells", + "type": "integer", + "exclusiveMinimum": 0 + }, + "name": { + "description": "The name of the plate", + "type": "string" + }, + "columns": { + "description": "The columns of the plate", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "description": "The column name", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "rows": { + "description": "The rows of the plate", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "description": "The row name", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "wells": { + "description": "The wells of the plate", + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "description": "The path to the well subgroup", + "type": "string", + "pattern": "^[A-Za-z0-9]+/[A-Za-z0-9]+$" + }, + "rowIndex": { + "description": "The index of the well in the rows list", + "type": "integer", + "minimum": 0 + }, + "columnIndex": { + "description": "The index of the well in the columns list", + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "path", "rowIndex", "columnIndex" + ] + }, + "minItems": 1, + "uniqueItems": true + } + }, + "required": [ + "columns", "rows", "wells" + ] + } + } +} diff --git a/0.4/schemas/strict_label.schema b/0.4/schemas/strict_label.schema new file mode 100644 index 00000000..af9090da --- /dev/null +++ b/0.4/schemas/strict_label.schema @@ -0,0 +1,18 @@ +{ + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/strict_label.schema", + "allOf": [ + { + "$ref": "https://ngff.openmicroscopy.org/0.4/schemas/label.schema" + }, + { + "properties": { + "image-label": { + "required": [ + "version", + "colors" + ] + } + } + } + ] +} diff --git a/0.4/schemas/strict_plate.schema b/0.4/schemas/strict_plate.schema new file mode 100644 index 00000000..5a88ab72 --- /dev/null +++ b/0.4/schemas/strict_plate.schema @@ -0,0 +1,28 @@ +{ + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/strict_plate.schema", + "allOf": [ + { + "$ref": "https://ngff.openmicroscopy.org/0.4/schemas/plate.schema" + }, + { + "properties": { + "plate": { + "properties": { + "acquisitions": { + "items": { + "required": [ + "name", + "maximumfieldcount" + ] + } + } + }, + "required": [ + "name", + "version" + ] + } + } + } + ] +} diff --git a/0.4/schemas/strict_well.schema b/0.4/schemas/strict_well.schema new file mode 100644 index 00000000..1e200294 --- /dev/null +++ b/0.4/schemas/strict_well.schema @@ -0,0 +1,17 @@ +{ + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/strict_well.schema", + "allOf": [ + { + "$ref": "https://ngff.openmicroscopy.org/0.4/schemas/well.schema" + }, + { + "properties": { + "well": { + "required": [ + "version" + ] + } + } + } + ] +} diff --git a/0.4/schemas/well.schema b/0.4/schemas/well.schema new file mode 100644 index 00000000..971a0102 --- /dev/null +++ b/0.4/schemas/well.schema @@ -0,0 +1,47 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/well.schema", + "title": "OME-NGFF well schema", + "description": "JSON from OME-NGFF .zattrs", + "type": "object", + "properties": { + "well": { + "type": "object", + "properties": { + "images": { + "description": "The fields of view for this well", + "type": "array", + "items": { + "type": "object", + "properties": { + "acquisition": { + "description": "A unique identifier within the context of the plate", + "type": "integer" + }, + "path": { + "description": "The path for this field of view subgroup", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "path" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "version": { + "description": "The version of the specification", + "type": "string", + "enum": [ + "0.4" + ] + } + }, + "required": [ + "images" + ] + } + } +} diff --git a/latest/index.html b/latest/index.html index 2a04cc1d..66af390c 100644 --- a/latest/index.html +++ b/latest/index.html @@ -1238,14 +1238,15 @@ grid-column: 2; width: auto; margin-right: 1rem; + border-bottom: 3px solid transparent; + margin-bottom: -3px; } #toc .content:hover, #toc .content:focus { background: rgba(75%, 75%, 75%, .25); background: var(--a-hover-bg); - border-bottom: 3px solid #054572; - border-bottom: 3px solid var(--toclink-underline); - margin-bottom: -3px; + border-bottom-color: #054572; + border-bottom-color: var(--toclink-underline); } #toc li li li .content { margin-left: 1rem; @@ -1487,11 +1488,11 @@ } } - + - - - + - + - + + - - + -
    - OME logo (6 circles in a hexagon) + OME logo (6 circles in a hexagon)

    Next-generation file formats (NGFF)

    -

    Editor’s Draft,

    +

    Editor’s Draft,

    -
    @@ -1863,34 +2108,27 @@

    Table of Contents

    1. - 1 Introduction + 1 On-disk (or in-cloud) layout
        -
      1. 1.1 Why "NGFF"? -
      2. 1.2 OME-NGFF -
      3. 1.3 Document conventions +
      4. 1.1 Images +
      5. 1.2 High-content screening
    2. - 2 On-disk (or in-cloud) layout + 2 Metadata
        -
      1. 2.1 Images -
      2. 2.2 High-content screening +
      3. 2.1 "axes" metadata +
      4. 2.2 "bioformats2raw.layout" (transitional) +
      5. 2.3 "coordinateTransformations" metadata +
      6. 2.4 "multiscales" metadata +
      7. 2.5 "omero" metadata (transitional) +
      8. 2.6 "labels" metadata +
      9. 2.7 "plate" metadata +
      10. 2.8 "well" metadata
      -
    3. - 3 Metadata -
        -
      1. 3.1 "axes" metadata -
      2. 3.2 "coordinateTransformations" metadata -
      3. 3.3 "multiscales" metadata -
      4. 3.4 "omero" metadata -
      5. 3.5 "labels" metadata -
      6. 3.6 "image-label" metadata -
      7. 3.7 "plate" metadata -
      8. 3.8 "well" metadata -
      -
    4. 4 Specification naming style -
    5. 5 Implementations -
    6. 6 Citing -
    7. 7 Version History +
    8. 3 Specification naming style +
    9. 4 Implementations +
    10. 5 Citing +
    11. 6 Version History
    12. Conformance
        @@ -1911,61 +2149,26 @@

        Table of Contents

      -

      1. Introduction

      -

      Bioimaging science is at a crossroads. Currently, the drive to acquire more, -larger, preciser spatial measurements is unfortunately at odds with our ability -to structure and share those measurements with others. During a global pandemic -more than ever, we believe fervently that global, collaborative discovery as -opposed to the post-publication, "data-on-request" mode of operation is the -path forward. Bioimaging data should be shareable via open and commercial cloud -resources without the need to download entire datasets.

      -

      At the moment, that is not the norm. The plethora of data formats produced by -imaging systems are ill-suited to remote sharing. Individual scientists -typically lack the infrastructure they need to host these data themselves. When -they acquire images from elsewhere, time-consuming translations and data -cleaning are needed to interpret findings. Those same costs are multiplied when -gathering data into online repositories where curator time can be the limiting -factor before publication is possible. Without a common effort, each lab or -resource is left building the tools they need and maintaining that -infrastructure often without dedicated funding.

      -

      This document defines a specification for bioimaging data to make it possible -to enable the conversion of proprietary formats into a common, cloud-ready one. -Such next-generation file formats layout data so that individual portions, or -"chunks", of large data are reference-able eliminating the need to download -entire datasets.

      -

      1.1. Why "NGFF"?

      -

      A short description of what is needed for an imaging format is "a hierarchy -of n-dimensional (dense) arrays with metadata". This combination of features -is certainly provided by HDF5 from the HDF Group, which a number of -bioimaging formats do use. HDF5 and other larger binary structures, however, -are ill-suited for storage in the cloud where accessing individual chunks -of data by name rather than seeking through a large file is at the heart of -parallelization.

      -

      As a result, a number of formats have been developed more recently which provide -the basic data structure of an HDF5 file, but do so in a more cloud-friendly way. -In the PyData community, the Zarr [zarr] format was developed -for easily storing collections of NumPy arrays. In the ImageJ community, N5 [n5] was developed to work around -the limitations of HDF5 ("N5" was originally short for "Not-HDF5"). -Both of these formats permit storing individual chunks of data either locally in -separate files or in cloud-based object stores as separate keys.

      -

      A current effort is underway to unify the two similar specifications to provide a single binary -specification. The editor’s draft will soon be entering a request for comments (RFC) phase with the goal of having a first version early in 2021. As that -process comes to an end, this document will be updated.

      -

      1.2. OME-NGFF

      +

      OME-NGFF

      The conventions and specifications defined in this document are designed to enable next-generation file formats to represent the same bioimaging data that can be represented in OME-TIFF and beyond. However, the conventions will also be usable by HDF5 and other sufficiently advanced binary containers. Eventually, we hope, the moniker "next-generation" will no longer be applicable, and this will simply be the most efficient, common, and useful representation of bioimaging data, whether during acquisition or sharing in the cloud.

      -

      Note: The following text makes use of OME-Zarr [ome-zarr-py], the current prototype implementation, +

      Note: The following text makes use of OME-Zarr [ome-zarr-py], the current prototype implementation, for all examples.

      -

      1.3. Document conventions

      +

      Document conventions

      The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” are to be interpreted as described in RFC 2119.

      -

      Some of the JSON examples in this document include commments. However, these are only for +

      Transitional metadata is added to the specification with the +intention of removing it in the future. Implementations may be expected (MUST) or +encouraged (SHOULD) to support the reading of the data, but writing will usually +be optional (MAY). Examples of transitional metadata include custom additions by +implementations that are later submitted as a formal specification. (See § 2.2 "bioformats2raw.layout" (transitional))

      +

      Some of the JSON examples in this document include comments. However, these are only for clarity purposes and comments MUST NOT be included in JSON objects.

      -

      2. On-disk (or in-cloud) layout

      +

      1. On-disk (or in-cloud) layout

      An overview of the layout of an OME-Zarr fileset should make understanding the following metadata sections easier. The hierarchy is represented here as it would appear locally but could equally @@ -1976,10 +2179,10 @@

      2. < defined by the version 2 of the Zarr specification . OME-NGFF metadata MUST be stored as attributes in the corresponding Zarr groups.

      -

      2.1. Images

      +

      1.1. Images

      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 § 3.3 "multiscales" metadata for details. +Note that the number of dimensions is variable between 2 and 5 and that axis names are arbitrary, see § 2.4 "multiscales" metadata for details. For this example we assume an image with 5 dimensions and axes called t,c,z,y,x.

      .                             # Root folder, potentially in S3,
       │                             # with a flat list of images by image ID.
      @@ -1991,7 +2194,7 @@ 

      2.2. High-content screening

      +

      1.2. High-content screening

      The following specification defines the hierarchy for a high-content screening dataset. Three groups MUST be defined above the images:

      -

      If part of § 3.3 "multiscales" metadata, the length of "axes" MUST be equal to the number of dimensions of the arrays that contain the image data.

      -

      3.2. "coordinateTransformations" metadata

      +

      If part of § 2.4 "multiscales" metadata, the length of "axes" MUST be equal to the number of dimensions of the arrays that contain the image data.

      +

      2.2. "bioformats2raw.layout" (transitional)

      +

      Transitional "bioformats2raw.layout" metadata identifies a group which implicitly describes a series of images. +The need for the collection stems from the common "multi-image file" scenario in microscopy. Parsers like Bio-Formats +define a strict, stable ordering of the images in a single container that can be used to refer to them by other tools.

      +

      In order to capture that information within an OME-NGFF dataset, bioformats2raw internally introduced a wrapping layer. +The bioformats2raw layout has been added to v0.4 as a transitional specification to specify filesets that already exist +in the wild. An upcoming NGFF specification will replace this layout with explicit metadata.

      +

      2.2.1. Layout

      +

      Typical Zarr layout produced by running bioformats2raw on a fileset that contains more than one image (series > 1):

      +
      series.ome.zarr               # One converted fileset from bioformats2raw
      +    ├── .zgroup
      +    ├── .zattrs               # Contains "bioformats2raw.layout" metadata
      +    ├── OME                   # Special group for containing OME metadata
      +    │   ├── .zgroup
      +    │   ├── .zattrs           # Contains "series" metadata
      +    │   └── METADATA.ome.xml  # OME-XML file stored within the Zarr fileset
      +    ├── 0                     # First image in the collection
      +    ├── 1                     # Second image in the collection
      +    └── ...
      +
      +

      2.2.2. Attributes

      +

      The top-level .zattrs file must contain the bioformats2raw.layout key:

      +
      {
      +  "bioformats2raw.layout" : 3
      +}
      +

      If the top-level group represents a plate, the bioformats2raw.layout metadata will be present but +the "plate" key MUST also be present, takes precedence and parsing of such datasets should follow § 2.7 "plate" metadata. It is not +possible to mix collections of images with plates at present.

      +
      {
      +  "bioformats2raw.layout" : 3,
      +  "plate" : {
      +    "columns" : [ {
      +      "name" : "1"
      +    } ],
      +    "name" : "Plate Name 0",
      +    "wells" : [ {
      +      "path" : "A/1",
      +      "rowIndex" : 0,
      +      "columnIndex" : 0
      +    } ],
      +    "field_count" : 1,
      +    "rows" : [ {
      +      "name" : "A"
      +    } ],
      +    "acquisitions" : [ {
      +      "id" : 0
      +    } ],
      +    "version" : "0.4"
      +  }
      +}
      +
      +

      The .zattrs file within the OME group may contain the "series" key:

      +
      {
      +  "series" : [ "0", "1" ]
      +}
      +
      +

      2.2.3. Details

      +

      Conforming groups:

      +
        +
      • +

        MUST have the value "3" for the "bioformats2raw.layout" key in their .zattrs metadata at the top of the hierarchy;

        +
      • +

        SHOULD have OME metadata representing the entire collection of images in a file named "OME/METADATA.ome.xml" which:

        +
          +
        • +

          MUST adhere to the OME-XML specification but

          +
        • +

          MUST use <MetadataOnly/> elements as opposed to <BinData/>, <BinaryOnly/> or <TiffData/>;

          +
        • +

          MAY make use of the minimum specification.

          +
        +
      +

      Additionally, the logic for finding the Zarr group for each image follows the following logic:

      +
        +
      • +

        If "plate" metadata is present, images MUST be located at the defined location.

        +
          +
        • +

          Matching "series" metadata (as described next) SHOULD be provided for tools that are unaware of the "plate" specification.

          +
        +
      • +

        If the "OME" Zarr group exists, it:

        +
          +
        • +

          MAY contain a "series" attribute. If so:

          +
            +
          • +

            "series" MUST be a list of string objects, each of which is a path to an image group.

            +
          • +

            The order of the paths MUST match the order of the "Image" elements in "OME/METADATA.ome.xml" if provided.

            +
          +
        +
      • +

        If the "series" attribute does not exist and no "plate" is present:

        +
          +
        • +

          separate "multiscales" images MUST be stored in consecutively numbered groups starting from 0 (i.e. "0/", "1/", "2/", "3/", ...).

          +
        +
      • +

        Every "multiscales" group MUST represent exactly one OME-XML "Image" in the same order as either the series index or the group numbers.

        +
      +

      Conforming readers:

      +
        +
      • +

        SHOULD make users aware of the presence of more than one image (i.e. SHOULD NOT default to only opening the first image);

        +
      • +

        MAY use the "series" attribute in the "OME" group to determine a list of valid groups to display;

        +
      • +

        MAY choose to show all images within the collection or offer the user a choice of images, as with HCS plates;

        +
      • +

        MAY ignore other groups or arrays under the root of the hierarchy.

        +
      +

      2.3. "coordinateTransformations" metadata

      "coordinateTransformations" describe a series of transformations that map between two coordinate spaces (defined by "axes"). For example, to map a discrete data space of an array to the corresponding physical space. It is a list of dictionaries. Each entry describes a single transformation and MUST contain the field "type". @@ -2115,10 +2430,10 @@

      3 description

      The transformations in the list are applied sequentially and in order.

      -

      3.3. "multiscales" metadata

      +

      2.4. "multiscales" metadata

      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.

      "multiscales" contains a list of dictionaries where each entry describes a multiscale image.

      -

      Each "multiscales" dictionary MUST contain the field "axes", see § 3.1 "axes" metadata. +

      Each "multiscales" dictionary MUST contain the field "axes", see § 2.1 "axes" metadata. 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". @@ -2128,7 +2443,7 @@

      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 § 3.2 "coordinateTransformations" metadata. The transformation MUST only be of type translation or scale. +The transformations are defined according to § 2.3 "coordinateTransformations" metadata. 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. It MAY contain exactly one translation that specifies the offset from the origin in physical units. If translation is given it MUST be listed after scale to ensure that it is given in physical coordinates. The length of the scale and translation array MUST be the same as the length of "axes". @@ -2136,7 +2451,7 @@

      scale for a dimension that is the same for all resolutions.

      -

      Each "multiscales" dictionary SHOULD contain the field "name". It SHOULD contain the field "version", which indicates the version of the multiscale metadata of this image (current version is 0.5-dev).

      +

      Each "multiscales" dictionary SHOULD contain the field "name". It MUST contain the field "version", which indicates the version of the multiscale metadata of this image (current version is 0.5-dev).

      Each "multiscales" dictionary SHOULD contain the field "type", which gives the type of downscaling method used to generate the multiscale image pyramid. It SHOULD contain the field "metadata", which contains a dictionary with additional information about the downscaling method.

      {
      @@ -2155,7 +2470,7 @@ 

      : "0", "coordinateTransformations": [{ - // the voxel size for the first scale level (0.5 micrometer) + // the voxel size for the first scale level (0.5 micrometer) "type": "scale", "scale": [1.0, 1.0, 0.5, 0.5, 0.5] }] @@ -2163,7 +2478,7 @@

      : "1", "coordinateTransformations": [{ - // the voxel size for the second scale level (downscaled by a factor of 2 -> 1 micrometer) + // the voxel size for the second scale level (downscaled by a factor of 2 -> 1 micrometer) "type": "scale", "scale": [1.0, 1.0, 1.0, 1.0, 1.0] }] @@ -2171,14 +2486,14 @@

      : "2", "coordinateTransformations": [{ - // the voxel size for the third scale level (downscaled by a factor of 4 -> 2 micrometer) + // the voxel size for the third scale level (downscaled by a factor of 4 -> 2 micrometer) "type": "scale", "scale": [1.0, 1.0, 2.0, 2.0, 2.0] }] } ], "coordinateTransformations": [{ - // the time unit (0.1 milliseconds), which is the same for each scale level + // 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] }], @@ -2204,8 +2519,8 @@

      ] for x in multiscales[0]["datasets"]]

      -

      3.4. "omero" metadata

      -

      Information specific to the channels of an image and how to render it +

      2.5. "omero" metadata (transitional)

      +

      Transitional information specific to the channels of an image and how to render it can be found under the "omero" key in the group-level metadata:

      "id": 1,                              # ID in OMERO
       "name": "example.tif",                # Name as shown in the UI
      @@ -2232,351 +2547,354 @@ 

      3 "model": "color" # "color" or "greyscale" }

      -

      See https://docs.openmicroscopy.org/omero/5.6.1/developers/Web/WebGateway.html#imgdata -for more information.

      -

      3.5. "labels" metadata

      -

      The special group "labels" found under an image Zarr contains the key labels containing -the paths to label objects which can be found underneath the group:

      +

      See the OMERO WebGateway documentation for more information.

      +

      2.6. "labels" metadata

      +

      In OME-Zarr, Zarr arrays representing pixel-annotation data are stored in a group called "labels". Some applications--notably image segmentation--produce +a new image that is in the same coordinate system as a corresponding multiscale image (usually having the same dimensions and coordinate transformations). +This new image is composed of integer values corresponding to certain labels with custom meanings. For example, pixels take the value 1 or 0 +if the corresponding pixel in the original image represents cellular space or intercellular space, respectively. +Such an image is referred to in this specification as a 'label image'.

      +

      The "labels" group is nested within an image group, at the same level of the Zarr hierarchy as the resolution levels for the original image. +The "labels" group is not itself an image; it contains images. The pixels of the label images MUST be integer data types, i.e. one of +[uint8, int8, uint16, int16, uint32, int32, uint64, int64]. Intermediate groups between "labels" and the images within it are allowed, +but these MUST NOT contain metadata. Names of the images in the "labels" group are arbitrary.

      +

      The .zattrs file associated with the "labels" group MUST contain a JSON object with the key labels, whose value is a JSON array of paths to the +labeled multiscale image(s). All label images SHOULD be listed within this metadata file. For example:

      {
         "labels": [
      -    "orphaned/0"
      +    "cell_space_segmentation"
         ]
       }
       
      -

      Unlisted groups MAY be labels.

      -

      3.6. "image-label" metadata

      -

      Groups containing the image-label dictionary represent an image segmentation -in which each unique pixel value represents a separate segmented object. image-label groups MUST also contain multiscales metadata and the two -"datasets" series MUST have the same number of entries.

      -

      The colors key defines a list of JSON objects describing the unique label -values. Each entry in the list MUST contain the key "label-value" with the -pixel value for that label. Additionally, the "rgba" key MAY be present, the -value for which is an RGBA unsigned-int 4-tuple: [uint8, uint8, uint8, uint8] All label-values must be unique. Clients who choose to not throw an error -should ignore all except the _last_ entry.

      -

      Some implementations may represent overlapping labels by using a specially assigned -value, for example the highest integer available in the pixel range.

      -

      The properties key defines a list of JSON objects which also describes the unique -label values. Each entry in the list MUST contain the key "label-value" with the -pixel value for that label. Additionally, an arbitrary number of key-value pairs -MAY be present for each label value denoting associated metadata. Not all label -values must share the same key-value pairs within the properties list.

      -

      The source key is an optional dictionary which contains information on the -image the label is associated with. If included it MAY include a key image whose value is the relative path to a Zarr image group. The default value is -"../../" since most labels are stored under a subgroup named "labels/" (see -above).

      -
      "image-label":
      -  {
      +   

      The .zattrs file for the label image MUST implement the multiscales specification. Within the multiscales object, the JSON array +associated with the datasets key MUST have the same number of entries (scale levels) as the original unlabeled image.

      +

      In addition to the multiscales key, the JSON object in this image-level .zattrs file SHOULD contain another key, image-label, +whose value is also a JSON object. The image-label object stores information about the display colors, source image, and optionally, +further arbitrary properties of the label image. That image-label object SHOULD contain the following keys: first, a colors key, +whose value MUST be a JSON array describing color information for the unique label values. Second, a version key, whose value MUST be a +string specifying the version of the OME-NGFF image-label schema.

      +

      Conforming readers SHOULD display labels using the colors specified by the colors JSON array, as follows. This array contains one +JSON object for each unique custom label. Each of these objects MUST contain the label-value key, whose value MUST be the integer +corresponding to a particular label. In addition to the label-value key, the objects in this array MAY contain an rgba key whose +value MUST be an array of four integers between 0 and 255, inclusive. These integers represent the uint8 values of red, green, and +blue that comprise the final color to be displayed at the pixels with this label. The fourth integer in the rgba array represents alpha, +or the opacity of the color. Additional keys under colors are allowed.

      +

      Next, the image-label object MAY contain the following keys: a properties key, and a source key.

      +

      Like the colors key, the value of the properties key MUST be an array of JSON objects describing the set of unique possible pixel values. +Each object in the properties array MUST contain the label-value key, whose value again MUST be an integer specifying the pixel value for that label. +Additionally, an arbitrary number of key-value pairs MAY be present for each label value, denoting arbitrary metadata associated with that label. +Label-value objects within the properties array do not need to have the same keys.

      +

      The value of the source key MUST be a JSON object containing information about the original image from which the label image derives. +This object MAY include a key image, whose value MUST be a string specifying the relative path to a Zarr image group. +The default value is ../../ since most labeled images are stored in a "labels" group that is nested within the original image group.

      +

      Here is an example of a simple image-label object for a label image in which 0s and 1s represent intercellular and cellular space, respectively:

      +
      {
      +  "image-label": {
           "version": "0.5-dev",
           "colors": [
             {
      -        "label-value": 1,
      -        "rgba": [255, 255, 255, 0]
      +        "label-value": 0,
      +        "rgba": [0, 0, 128, 128]
             },
             {
      -        "label-value": 4,
      -        "rgba": [0, 255, 255, 128]
      -      },
      -      ...
      -      ],
      +        "label-value": 1,
      +        "rgba": [0, 128, 0, 128]
      +      }
      +    ],
           "properties": [
             {
      -        "label-value": 1,
      +        "label-value": 0,
               "area (pixels)": 1200,
      -        "class": "foo"
      -
      +        "class": "intercellular space"
             },
             {
      -        "label-value": 4,
      -        "area (pixels)": 1650
      -      },
      -      ...
      -      ]
      -  },
      -  "source": {
      -    "image": "../../"
      +        "label-value": 1,
      +        "area (pixels)": 1650,
      +        "class": "cell",
      +        "cell type": "neuron"
      +      }
      +    ],
      +    "source": {
      +      "image": "../../"
      +    }
         }
      -]
      +}
       
      -

      3.7. "plate" metadata

      +

      In this case, the pixels consisting of a 0 in the Zarr array will be displayed as 50% blue and 50% opacity. Pixels with a 1 in the Zarr array, +which correspond to cellular space, will be displayed as 50% green and 50% opacity.

      +

      2.7. "plate" metadata

      For high-content screening datasets, the plate layout can be found under the -custom attributes of the plate group under the plate key.

      -
      -
      acquisitions -
      An optional list of JSON objects defining the acquisitions for a given - plate. Each acquisition object MUST contain an id key providing an - unique identifier within the context of the plate to which fields of - view can refer to. It SHOULD contain a name key identifying the name - of the acquisition. It SHOULD contain a maximumfieldcount key - indicating the maximum number of fields of view for the acquisition. It - MAY contain a description key providing a description for the - acquisition. It MAY contain a startime and/or endtime key specifying - the start and/or end timestamp of the acquisition using an epoch - string. -
      columns -
      A list of JSON objects defining the columns of the plate. Each column - object defines the properties of the column at the index of the object - in the list. Each column in the physical plate MUST be defined, even - if no wells in the column are defined. Each defined column MUST contain - a name key specifying the column name. The name MUST contain only - alphanumeric characters, MUST be case-sensitive, and MUST NOT be a - duplicate of any other name in the columns list. Care SHOULD be - taken to avoid collisions on case-insensitive filesystems - (e.g. avoid using both Aa and aA). -
      field_count -
      An integer defining the maximum number of fields per view across all - wells. -
      name -
      A string defining the name of the plate. -
      rows -
      A list of JSON objects defining the rows of the plate. Each row object - defines the properties of the row at the index of the object in the - list. Each row in the physical plate MUST be defined, even if no wells - in the row are defined. Each defined row MUST contain a name key - specifying the row name. The name MUST contain only alphanumeric - characters, MUST be case-sensitive, and MUST NOT be a duplicate - of any other name in the rows list. Care SHOULD be taken to avoid - collisions on case-insensitive filesystems (e.g. avoid using both Aa and aA). -
      version -
      A string defining the version of the specification. -
      wells -
      A list of JSON objects defining the wells of the plate. Each well object - MUST contain a path key identifying the path to the well subgroup. - The path MUST consist of a name in the rows list, a file separator (/), - and a name from the columns list, in that order. The path MUST NOT contain - additional leading or trailing directories. - Each well object MUST contain both a rowIndex key identifying the index into - the rows list and a columnIndex key indentifying the index into - the columns list. rowIndex and columnIndex MUST be 0-based. - The rowIndex, columnIndex, and path MUST all refer to the same - row/column pair. -
      +custom attributes of the plate group under the plate key in the group-level metadata.

      +

      The plate dictionary MAY contain an acquisitions key whose value MUST be a list of +JSON objects defining the acquisitions for a given plate to which wells can refer to. Each +acquisition object MUST contain an id key whose value MUST be an unique integer identifier +greater than or equal to 0 within the context of the plate to which fields of view can refer +to (see #well-md). +Each acquisition object SHOULD contain a name key whose value MUST be a string identifying +the name of the acquisition. Each acquisition object SHOULD contain a maximumfieldcount key whose value MUST be a positive integer indicating the maximum number of fields of view for the +acquisition. Each acquisition object MAY contain a description key whose value MUST be a +string specifying a description for the acquisition. Each acquisition object MAY contain +a starttime and/or endtime key whose values MUST be integer epoch timestamps specifying +the start and/or end timestamp of the acquisition.

      +

      The plate dictionary MUST contain a columns key whose value MUST be a list of JSON objects +defining the columns of the plate. Each column object defines the properties of +the column at the index of the object in the list. Each column in the physical plate +MUST be defined, even if no wells in the column are defined. Each column object MUST +contain a name key whose value is a string specifying the column name. The name MUST +contain only alphanumeric characters, MUST be case-sensitive, and MUST NOT be a duplicate of any +other name in the columns list. Care SHOULD be taken to avoid collisions on +case-insensitive filesystems (e.g. avoid using both Aa and aA).

      +

      The plate dictionary SHOULD contain a field_count key whose value MUST be a positive integer +defining the maximum number of fields per view across all wells.

      +

      The plate dictionary SHOULD contain a name key whose value MUST be a string defining the +name of the plate.

      +

      The plate dictionary MUST contain a rows key whose value MUST be a list of JSON objects +defining the rows of the plate. Each row object defines the properties of +the row at the index of the object in the list. Each row in the physical plate +MUST be defined, even if no wells in the row are defined. Each defined row MUST +contain a name key whose value MUST be a string defining the row name. The name MUST +contain only alphanumeric characters, MUST be case-sensitive, and MUST NOT be a duplicate of any +other name in the rows list. Care SHOULD be taken to avoid collisions on +case-insensitive filesystems (e.g. avoid using both Aa and aA).

      +

      The plate dictionary MUST contain a version key whose value MUST be a string specifying the +version of the plate specification.

      +

      The plate dictionary MUST contain a wells key whose value MUST be a list of JSON objects +defining the wells of the plate. Each well object MUST contain a path key whose value MUST +be a string specifying the path to the well subgroup. The path MUST consist of a name in +the rows list, a file separator (/), and a name from the columns list, in that order. +The path MUST NOT contain additional leading or trailing directories. +Each well object MUST contain both a rowIndex key whose value MUST be an integer identifying +the index into the rows list and a columnIndex key whose value MUST be an integer identifying +the index into the columns list. rowIndex and columnIndex MUST be 0-based. The rowIndex, columnIndex, and path MUST all refer to the same row/column pair.

      For example the following JSON object defines a plate with two acquisitions and 6 wells (2 rows and 3 columns), containing up to 2 fields of view per acquisition.

      -
      "plate": {
      -    "acquisitions": [
      -        {
      -            "id": 1,
      -            "maximumfieldcount": 2,
      -            "name": "Meas_01(2012-07-31_10-41-12)",
      -            "starttime": 1343731272000
      -        },
      -        {
      -            "id": 2,
      -            "maximumfieldcount": 2,
      -            "name": "Meas_02(201207-31_11-56-41)",
      -            "starttime": 1343735801000
      -        }
      -    ],
      -    "columns": [
      -        {
      -            "name": "1"
      -        },
      -        {
      -            "name": "2"
      -        },
      -        {
      -            "name": "3"
      -        }
      -    ],
      -    "field_count": 4,
      -    "name": "test",
      -    "rows": [
      -        {
      -            "name": "A"
      -        },
      -        {
      -            "name": "B"
      -        }
      -    ],
      -    "version": "0.5-dev",
      -    "wells": [
      -        {
      -            "path": "A/1",
      -            "rowIndex": 0,
      -            "columnIndex": 0
      -        },
      -        {
      -            "path": "A/2"
      -            "rowIndex": 0,
      -            "columnIndex": 1
      -        },
      -        {
      -            "path": "A/3"
      -            "rowIndex": 0,
      -            "columnIndex": 2
      -        },
      -        {
      -            "path": "B/1"
      -            "rowIndex": 1,
      -            "columnIndex": 0
      -        },
      -        {
      -            "path": "B/2"
      -            "rowIndex": 1,
      -            "columnIndex": 1
      -        },
      -        {
      -            "path": "B/3"
      -            "rowIndex": 1,
      -            "columnIndex": 2
      -        }
      -    ]
      -  }
      +
      {
      +    "plate": {
      +        "acquisitions": [
      +            {
      +                "id": 1,
      +                "maximumfieldcount": 2,
      +                "name": "Meas_01(2012-07-31_10-41-12)",
      +                "starttime": 1343731272000
      +            },
      +            {
      +                "id": 2,
      +                "maximumfieldcount": 2,
      +                "name": "Meas_02(201207-31_11-56-41)",
      +                "starttime": 1343735801000
      +            }
      +        ],
      +        "columns": [
      +            {
      +                "name": "1"
      +            },
      +            {
      +                "name": "2"
      +            },
      +            {
      +                "name": "3"
      +            }
      +        ],
      +        "field_count": 4,
      +        "name": "test",
      +        "rows": [
      +            {
      +                "name": "A"
      +            },
      +            {
      +                "name": "B"
      +            }
      +        ],
      +        "version": "0.5-dev",
      +        "wells": [
      +            {
      +                "path": "A/1",
      +                "rowIndex": 0,
      +                "columnIndex": 0
      +            },
      +            {
      +                "path": "A/2",
      +                "rowIndex": 0,
      +                "columnIndex": 1
      +            },
      +            {
      +                "path": "A/3",
      +                "rowIndex": 0,
      +                "columnIndex": 2
      +            },
      +            {
      +                "path": "B/1",
      +                "rowIndex": 1,
      +                "columnIndex": 0
      +            },
      +            {
      +                "path": "B/2",
      +                "rowIndex": 1,
      +                "columnIndex": 1
      +            },
      +            {
      +                "path": "B/3",
      +                "rowIndex": 1,
      +                "columnIndex": 2
      +            }
      +        ]
      +    }
      +}
       

      The following JSON object defines a sparse plate with one acquisition and 2 wells in a 96 well plate, containing one field of view per acquisition.

      -
      "plate": {
      -    "acquisitions": [
      -        {
      -            "id": 1,
      -            "maximumfieldcount": 1,
      -            "name": "single acquisition",
      -            "starttime": 1343731272000
      -        },
      -    ],
      -    "columns": [
      -        {
      -            "name": "1"
      -        },
      -        {
      -            "name": "2"
      -        },
      -        {
      -            "name": "3"
      -        },
      -        {
      -            "name": "4"
      -        },
      -        {
      -            "name": "5"
      -        },
      -        {
      -            "name": "6"
      -        },
      -        {
      -            "name": "7"
      -        },
      -        {
      -            "name": "8"
      -        },
      -        {
      -            "name": "9"
      -        },
      -        {
      -            "name": "10"
      -        },
      -        {
      -            "name": "11"
      -        },
      -        {
      -            "name": "12"
      -        }
      -    ],
      -    "field_count": 1,
      -    "name": "sparse test",
      -    "rows": [
      -        {
      -            "name": "A"
      -        },
      -        {
      -            "name": "B"
      -        },
      -        {
      -            "name": "C"
      -        },
      -        {
      -            "name": "D"
      -        },
      -        {
      -            "name": "E"
      -        },
      -        {
      -            "name": "F"
      -        },
      -        {
      -            "name": "G"
      -        },
      -        {
      -            "name": "H"
      -        }
      -    ],
      -    "version": "0.1",
      -    "wells": [
      -        {
      -            "path": "C/5"
      -            "rowIndex": 2,
      -            "columnIndex": 4
      -        },
      -        {
      -            "path": "D/7"
      -            "rowIndex": 3,
      -            "columnIndex": 6
      -        }
      -    ]
      -  }
      +
      {
      +    "plate": {
      +        "acquisitions": [
      +            {
      +                "id": 1,
      +                "maximumfieldcount": 1,
      +                "name": "single acquisition",
      +                "starttime": 1343731272000
      +            }
      +        ],
      +        "columns": [
      +            {
      +                "name": "1"
      +            },
      +            {
      +                "name": "2"
      +            },
      +            {
      +                "name": "3"
      +            },
      +            {
      +                "name": "4"
      +            },
      +            {
      +                "name": "5"
      +            },
      +            {
      +                "name": "6"
      +            },
      +            {
      +                "name": "7"
      +            },
      +            {
      +                "name": "8"
      +            },
      +            {
      +                "name": "9"
      +            },
      +            {
      +                "name": "10"
      +            },
      +            {
      +                "name": "11"
      +            },
      +            {
      +                "name": "12"
      +            }
      +        ],
      +        "field_count": 1,
      +        "name": "sparse test",
      +        "rows": [
      +            {
      +                "name": "A"
      +            },
      +            {
      +                "name": "B"
      +            },
      +            {
      +                "name": "C"
      +            },
      +            {
      +                "name": "D"
      +            },
      +            {
      +                "name": "E"
      +            },
      +            {
      +                "name": "F"
      +            },
      +            {
      +                "name": "G"
      +            },
      +            {
      +                "name": "H"
      +            }
      +        ],
      +        "version": "0.5-dev",
      +        "wells": [
      +            {
      +                "path": "C/5",
      +                "rowIndex": 2,
      +                "columnIndex": 4
      +            },
      +            {
      +                "path": "D/7",
      +                "rowIndex": 3,
      +                "columnIndex": 6
      +            }
      +        ]
      +    }
      +}
       
      -

      3.8. "well" metadata

      +

      2.8. "well" metadata

      For high-content screening datasets, the metadata about all fields of views under a given well can be found under the "well" key in the attributes of the well group.

      -
      -
      images -
      A list of JSON objects defining the fields of views for a given well. - Each object MUST contain a path key identifying the path to the - field of view. If multiple acquisitions were performed in the plate, it - MUST contain an acquisition key identifying the id of the - acquisition which must match one of acquisition JSON objects defined in - the plate metadata. -
      version -
      A string defining the version of the specification. -
      +

      The well dictionary MUST contain an images key whose value MUST be a list of JSON objects +specifying all fields of views for a given well. Each image object MUST contain a path key whose value MUST be a string specifying the path to the field of view. The path MUST contain only alphanumeric characters, MUST be case-sensitive, and MUST NOT be a duplicate +of any other path in the images list. If multiple acquisitions were performed in the plate, +it MUST contain an acquisition key whose value MUST be an integer identifying the acquisition +which MUST match one of the acquisition JSON objects defined in the plate metadata (see #plate-md).

      +

      The well dictionary SHOULD contain a version key whose value MUST be a string specifying the +version of the well specification.

      For example the following JSON object defines a well with four fields of view. The first two fields of view were part of the first acquisition while the last two fields of view were part of the second acquisition.

      -
      "well": {
      -    "images": [
      -        {
      -            "acquisition": 1,
      -            "path": "0"
      -        },
      -        {
      -            "acquisition": 1,
      -            "path": "1"
      -        },
      -        {
      -            "acquisition": 2,
      -            "path": "2"
      -        },
      -        {
      -            "acquisition": 2,
      -            "path": "3"
      -        }
      -    ],
      -    "version": "0.5-dev"
      -  }
      -
      +
      {
      +    "well": {
      +        "images": [
      +            {
      +                "acquisition": 1,
      +                "path": "0"
      +            },
      +            {
      +                "acquisition": 1,
      +                "path": "1"
      +            },
      +            {
      +                "acquisition": 2,
      +                "path": "2"
      +            },
      +            {
      +                "acquisition": 2,
      +                "path": "3"
      +            }
      +        ],
      +        "version": "0.5-dev"
      +    }
      +}

      The following JSON object defines a well with two fields of view in a plate with four acquisitions. The first field is part of the first acquisition, and the second field is part of the last acquisition.

      -
      "well": {
      -    "images": [
      -        {
      -            "acquisition": 0,
      -            "path": "0"
      -        },
      -        {
      -            "acquisition": 3,
      -            "path": "1"
      -        }
      -    ],
      -    "version": "0.1"
      -}
      -
      -

      4. Specification naming style

      +
      {
      +    "well": {
      +        "images": [
      +            {
      +                "acquisition": 0,
      +                "path": "0"
      +            },
      +            {
      +                "acquisition": 3,
      +                "path": "1"
      +            }
      +        ],
      +        "version": "0.5-dev"
      +    }
      +}
      +

      3. Specification naming style

      Multi-word keys in this specification should use the camelCase style. NB: some parts of the specification don’t obey this convention as they were added before this was adopted, but they should be updated in due course.

      -

      5. Implementations

      +

      4. Implementations

      Projects which support reading and/or writing OME-NGFF data include:

      bigdataviewer-ome-zarr @@ -2593,17 +2911,19 @@

      vizarr
      A minimal, purely client-side program for viewing Zarr-based images with Viv & ImJoy. +
      ITKIOOMEZarrNGFF +
      ITK IO for images stored in OME-NGFF format.

      Diagram of related projects

      All implementations prevent an equivalent representation of a dataset which can be downloaded or uploaded freely. An interactive version of this diagram is available from the OME2020 Workshop. Mouseover the blackboxes representing the implementations above to get a quick tip on how to use them.

      -

      Note: If you would like to see your project listed, please open an issue or PR on the ome/ngff repository.

      -

      6. Citing

      -

      Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. J. Moore, et al. Editors. Open Microscopy Environment Consortium, 8 February 2022. +

      Note: If you would like to see your project listed, please open an issue or PR on the ome/ngff repository.

      +

      5. Citing

      +

      Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. J. Moore, et al. Open Microscopy Environment Consortium, 8 February 2022. This edition of the specification is https://ngff.openmicroscopy.org/0.4/. The latest edition is available at https://ngff.openmicroscopy.org/latest/. (doi:10.5281/zenodo.4282107)

      -

      7. Version History

      +

      6. Version History

      @@ -2611,6 +2931,14 @@

      7. <

      + + +
      Date Description
      0.4.1 + 2023-02-09 + expand on "labels" description +
      0.4.1 + 2022-09-26 + transitional metadata for image collections ("bioformats2raw.layout")
      0.4.0 2022-02-08 @@ -2661,7 +2989,7 @@

      [RFC2119]

      + except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

      Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", @@ -2674,28 +3002,30 @@

      , like this:

      -

      Note, this is an informative note.

      -

      Conformant Algorithms

      -

      Requirements phrased in the imperative as part of algorithms +

      Note, this is an informative note.

      +
      +

      Conformant Algorithms

      +

      Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

      -

      Conformance requirements phrased as algorithms or specific steps +

      Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

      +

      Index

      Terms defined by this specification

      References

      Normative References

      @@ -2705,10 +3035,359 @@

      N

      Informative References

      -
      [N5] -
      John A. Bogovic; et al. N5---a scalable Java API for hierarchies of chunked n-dimensional tensors and structured meta-data. 2020. Informational. URL: https://github.com/saalfeldlab/n5/issues/62
      [OME-ZARR-PY]
      OME; et al. ome-zarr-py: Experimental implementation of next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.. 06 October 2020. Informational. URL: https://doi.org/10.5281/zenodo.4113931 -
      [ZARR] -
      Alistair Miles; et al. Zarr: An implementation of chunked, compressed, N-dimensional arrays for Python.. 06 October 2020. Informational. URL: https://doi.org/10.5281/zenodo.4069231 -
      \ No newline at end of file + + + + \ No newline at end of file diff --git a/latest/schemas/image.schema b/latest/schemas/image.schema index 3926c4f4..cf2b477f 100644 --- a/latest/schemas/image.schema +++ b/latest/schemas/image.schema @@ -44,7 +44,7 @@ } }, "required": [ - "datasets", "axes" + "datasets", "axes", "version" ] }, "minItems": 1, @@ -93,11 +93,7 @@ "active": { "type": "boolean" } - }, - "required": [ - "window", - "color" - ] + } } } }, @@ -124,7 +120,7 @@ "type": "string", "enum": ["space"] }, - "units": { + "unit": { "type": "string" } } diff --git a/latest/schemas/label.schema b/latest/schemas/label.schema new file mode 100644 index 00000000..8b23d577 --- /dev/null +++ b/latest/schemas/label.schema @@ -0,0 +1,77 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/latest/schemas/label.schema", + "title": "OME-NGFF labelled image schema", + "description": "JSON from OME-NGFF .zattrs", + "type": "object", + "properties": { + "image-label": { + "type": "object", + "properties": { + "colors": { + "description": "The colors for this label image", + "type": "array", + "items": { + "type": "object", + "properties": { + "label-value": { + "description": "The value of the label", + "type": "number" + }, + "rgba": { + "description": "The RGBA color stored as an array of four integers between 0 and 255", + "type": "array", + "items": { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "minItems": 4, + "maxItems": 4 + } + }, + "required": [ + "label-value" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "properties": { + "description": "The properties for this label image", + "type": "array", + "items": { + "type": "object", + "properties": { + "label-value": { + "description": "The pixel value for this label", + "type": "integer" + } + }, + "required": [ + "label-value" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "source": { + "description": "The source of this label image", + "type": "object", + "properties": { + "image": { + "type": "string" + } + } + }, + "version": { + "description": "The version of the specification", + "type": "string", + "enum": [ + "0.5-dev" + ] + } + } + } + } +} diff --git a/latest/schemas/plate.schema b/latest/schemas/plate.schema new file mode 100644 index 00000000..1b7ed532 --- /dev/null +++ b/latest/schemas/plate.schema @@ -0,0 +1,140 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/plate.schema", + "title": "OME-NGFF plate schema", + "description": "JSON from OME-NGFF .zattrs", + "type": "object", + "properties": { + "plate": { + "type": "object", + "properties": { + "acquisitions": { + "description": "The acquisitions for this plate", + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "description": "A unique identifier within the context of the plate", + "type": "integer", + "minimum": 0 + }, + "maximumfieldcount": { + "description": "The maximum number of fields of view for the acquisition", + "type": "integer", + "exclusiveMinimum": 0 + }, + "name": { + "description": "The name of the acquisition", + "type": "string" + }, + "description": { + "description": "The description of the acquisition", + "type": "string" + }, + "starttime": { + "description": "The start timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch", + "type": "integer", + "minimum": 0 + }, + "endtime": { + "description": "The end timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch", + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "id" + ] + } + }, + "version": { + "description": "The version of the specification", + "type": "string", + "enum": [ + "0.5-dev" + ] + }, + "field_count": { + "description": "The maximum number of fields per view across all wells", + "type": "integer", + "exclusiveMinimum": 0 + }, + "name": { + "description": "The name of the plate", + "type": "string" + }, + "columns": { + "description": "The columns of the plate", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "description": "The column name", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "rows": { + "description": "The rows of the plate", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "description": "The row name", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "wells": { + "description": "The wells of the plate", + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "description": "The path to the well subgroup", + "type": "string", + "pattern": "^[A-Za-z0-9]+/[A-Za-z0-9]+$" + }, + "rowIndex": { + "description": "The index of the well in the rows list", + "type": "integer", + "minimum": 0 + }, + "columnIndex": { + "description": "The index of the well in the columns list", + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "path", "rowIndex", "columnIndex" + ] + }, + "minItems": 1, + "uniqueItems": true + } + }, + "required": [ + "columns", "rows", "wells", "version" + ] + } + } +} diff --git a/latest/schemas/strict_label.schema b/latest/schemas/strict_label.schema new file mode 100644 index 00000000..c52dd51b --- /dev/null +++ b/latest/schemas/strict_label.schema @@ -0,0 +1,18 @@ +{ + "$id": "https://ngff.openmicroscopy.org/latest/schemas/strict_label.schema", + "allOf": [ + { + "$ref": "https://ngff.openmicroscopy.org/latest/schemas/label.schema" + }, + { + "properties": { + "image-label": { + "required": [ + "version", + "colors" + ] + } + } + } + ] +} diff --git a/latest/schemas/strict_plate.schema b/latest/schemas/strict_plate.schema new file mode 100644 index 00000000..5a88ab72 --- /dev/null +++ b/latest/schemas/strict_plate.schema @@ -0,0 +1,28 @@ +{ + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/strict_plate.schema", + "allOf": [ + { + "$ref": "https://ngff.openmicroscopy.org/0.4/schemas/plate.schema" + }, + { + "properties": { + "plate": { + "properties": { + "acquisitions": { + "items": { + "required": [ + "name", + "maximumfieldcount" + ] + } + } + }, + "required": [ + "name", + "version" + ] + } + } + } + ] +} diff --git a/latest/schemas/strict_well.schema b/latest/schemas/strict_well.schema new file mode 100644 index 00000000..1e200294 --- /dev/null +++ b/latest/schemas/strict_well.schema @@ -0,0 +1,17 @@ +{ + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/strict_well.schema", + "allOf": [ + { + "$ref": "https://ngff.openmicroscopy.org/0.4/schemas/well.schema" + }, + { + "properties": { + "well": { + "required": [ + "version" + ] + } + } + } + ] +} diff --git a/latest/schemas/well.schema b/latest/schemas/well.schema new file mode 100644 index 00000000..891abd05 --- /dev/null +++ b/latest/schemas/well.schema @@ -0,0 +1,47 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/well.schema", + "title": "OME-NGFF well schema", + "description": "JSON from OME-NGFF .zattrs", + "type": "object", + "properties": { + "well": { + "type": "object", + "properties": { + "images": { + "description": "The fields of view for this well", + "type": "array", + "items": { + "type": "object", + "properties": { + "acquisition": { + "description": "A unique identifier within the context of the plate", + "type": "integer" + }, + "path": { + "description": "The path for this field of view subgroup", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "path" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "version": { + "description": "The version of the specification", + "type": "string", + "enum": [ + "0.5-dev" + ] + } + }, + "required": [ + "images" + ] + } + } +}