From 6bcde902b89246e1ee02e23e01552e81355523e7 Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Tue, 3 Dec 2024 20:32:43 +0100 Subject: [PATCH 01/13] implement doc-building from branches --- .../image/invalid/invalid_channels_color.json | 31 - .../invalid/invalid_channels_window.json | 31 - 0.1/examples/image/invalid/invalid_path.json | 17 - .../image/invalid/missing_datasets.json | 9 - 0.1/examples/image/invalid/missing_path.json | 17 - 0.1/examples/image/invalid/no_datasets.json | 15 - .../image/invalid/no_multiscales.json | 4 - 0.1/examples/image/valid/image.json | 12 - 0.1/examples/image/valid/image_complete.json | 58 - .../image/valid/image_complete_no_omero.json | 28 - 0.1/examples/image/valid/missing_name.json | 18 - 0.1/examples/image/valid/missing_type.json | 20 - 0.1/examples/image/valid/missing_version.json | 39 - 0.1/examples/plate/invalid/empty_wells.json | 16 - .../plate/invalid/invalid_fieldcount.json | 31 - .../plate/invalid/missing_acquisition_id.json | 35 - .../plate/invalid/missing_column_name.json | 18 - .../plate/invalid/missing_columns.json | 15 - 0.1/examples/plate/invalid/missing_rows.json | 15 - .../plate/invalid/missing_version.json | 19 - .../plate/invalid/missing_well_path.json | 18 - 0.1/examples/plate/invalid/missing_wells.json | 15 - .../plate/valid/minimal_acquisition.json | 31 - 0.1/examples/plate/valid/plate.json | 40 - .../plate/valid/plate_acquisition.json | 55 - 0.1/examples/well/valid/well.json | 15 - 0.1/header.include | 34 - 0.1/index.bs | 622 --------- 0.1/schemas/image.schema | 112 -- 0.1/schemas/plate.schema | 112 -- 0.1/schemas/strict_image.schema | 19 - 0.1/schemas/well.schema | 47 - 0.1/tests/test_validation.py | 97 -- 0.1/tox.ini | 10 - 0.2/copyright.include | 4 - .../image/invalid/invalid_channels_color.json | 31 - .../invalid/invalid_channels_window.json | 31 - 0.2/examples/image/invalid/invalid_path.json | 17 - .../image/invalid/missing_datasets.json | 9 - 0.2/examples/image/invalid/missing_path.json | 17 - 0.2/examples/image/invalid/no_datasets.json | 15 - .../image/invalid/no_multiscales.json | 4 - 0.2/examples/image/valid/image.json | 14 - 0.2/examples/image/valid/image_metadata.json | 28 - 0.2/examples/image/valid/image_omero.json | 58 - 0.2/examples/image/valid/missing_name.json | 13 - 0.2/examples/image/valid/missing_version.json | 13 - 0.2/examples/plate/valid/plate.json | 40 - 0.2/examples/well/valid/well.json | 15 - 0.2/header.include | 34 - 0.2/index.bs | 685 ---------- 0.2/schemas/image.schema | 101 -- 0.2/schemas/plate.schema | 119 -- 0.2/schemas/well.schema | 47 - 0.2/tests/test_validation.py | 44 - 0.2/tox.ini | 10 - 0.3/copyright.include | 4 - 0.3/examples/image/invalid/invalid_axes.json | 22 - .../image/invalid/invalid_axes_count.json | 20 - .../image/invalid/invalid_axes_order.json | 22 - .../image/invalid/invalid_channels_color.json | 36 - .../invalid/invalid_channels_window.json | 36 - 0.3/examples/image/invalid/invalid_path.json | 22 - .../image/invalid/invalid_version.json | 25 - 0.3/examples/image/invalid/missing_axes.json | 14 - .../image/invalid/missing_datasets.json | 14 - 0.3/examples/image/invalid/missing_path.json | 22 - 0.3/examples/image/invalid/no_axes.json | 15 - 0.3/examples/image/invalid/no_datasets.json | 15 - .../image/invalid/no_multiscales.json | 4 - 0.3/examples/image/valid/image.json | 15 - 0.3/examples/image/valid/image_metadata.json | 33 - 0.3/examples/image/valid/image_omero.json | 63 - 0.3/examples/image/valid/missing_name.json | 30 - 0.3/examples/image/valid/missing_version.json | 18 - 0.3/examples/plate/valid/plate.json | 40 - 0.3/examples/well/valid/well.json | 15 - 0.3/index.bs | 700 ---------- 0.3/schemas/image.schema | 109 -- 0.3/schemas/jsonld/context.json | 6 - 0.3/schemas/jsonld/frame.json | 42 - 0.3/schemas/jsonld/shacl.ttl | 210 --- 0.3/schemas/plate.schema | 119 -- 0.3/schemas/salad_schema/image.yml | 213 --- 0.3/schemas/strict_image.schema | 19 - 0.3/schemas/well.schema | 47 - 0.3/tests/test_frame.py | 39 - 0.3/tests/test_validation.py | 173 --- 0.3/tox.ini | 15 - 0.4/copyright.include | 4 - 0.4/examples/bf2raw/image.json | 3 - 0.4/examples/bf2raw/plate.json | 22 - .../label_strict/colors_properties.json | 29 - .../multiscales_example.json | 54 - .../multiscales_transformations.json | 47 - 0.4/examples/ome/series-2.json | 3 - 0.4/examples/plate_strict/plate_2wells.json | 91 -- 0.4/examples/plate_strict/plate_6wells.json | 72 -- 0.4/examples/well_strict/well_2fields.json | 15 - 0.4/examples/well_strict/well_4fields.json | 23 - 0.4/header.include | 34 - 0.4/index.bs | 790 ------------ 0.4/schemas/bf2raw.schema | 14 - 0.4/schemas/image.schema | 233 ---- 0.4/schemas/label.schema | 77 -- 0.4/schemas/ome.schema | 17 - 0.4/schemas/plate.schema | 140 -- 0.4/schemas/strict_image.schema | 19 - 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 - 0.4/tests/image_suite.json | 1148 ----------------- 0.4/tests/label_suite.json | 131 -- 0.4/tests/plate_suite.json | 819 ------------ 0.4/tests/strict_image_suite.json | 388 ------ 0.4/tests/strict_label_suite.json | 31 - 0.4/tests/strict_plate_suite.json | 187 --- 0.4/tests/strict_well_suite.json | 50 - 0.4/tests/test_validation.py | 91 -- 0.4/tests/well_suite.json | 88 -- 0.5/copyright.include | 4 - 0.5/examples/bf2raw/.config.json | 3 - 0.5/examples/label_strict/.config.json | 3 - 0.5/examples/multiscales_strict/.config.json | 3 - 0.5/examples/ome/.config.json | 3 - 0.5/examples/plate_strict/.config.json | 3 - 0.5/examples/well_strict/.config.json | 3 - 0.5/header.include | 34 - 0.5/tox.ini | 10 - conf.py | 8 + latest | 1 - {0.1 => spec}/copyright.include | 0 {0.4 => spec}/examples/bf2raw/.config.json | 0 {0.5 => spec}/examples/bf2raw/image.json | 0 {0.5 => spec}/examples/bf2raw/plate.json | 0 .../examples/label_strict/.config.json | 0 .../label_strict/colors_properties.json | 0 .../examples/multiscales_strict/.config.json | 0 .../multiscales_example.json | 0 .../multiscales_transformations.json | 0 {0.4 => spec}/examples/ome/.config.json | 0 {0.5 => spec}/examples/ome/series-2.json | 0 .../examples/plate_strict/.config.json | 0 .../examples/plate_strict/plate_2wells.json | 0 .../examples/plate_strict/plate_6wells.json | 0 .../examples/well_strict/.config.json | 0 .../examples/well_strict/well_2fields.json | 0 .../examples/well_strict/well_4fields.json | 0 {0.3 => spec}/header.include | 0 {0.5 => spec}/index.bs | 0 {0.5 => spec}/schemas/_version.schema | 0 {0.5 => spec}/schemas/bf2raw.schema | 0 {0.5 => spec}/schemas/image.schema | 0 {0.5 => spec}/schemas/label.schema | 0 {0.5 => spec}/schemas/ome.schema | 0 {0.5 => spec}/schemas/ome_zarr.schema | 0 {0.5 => spec}/schemas/plate.schema | 0 {0.5 => spec}/schemas/strict_image.schema | 0 {0.5 => spec}/schemas/strict_label.schema | 0 {0.5 => spec}/schemas/strict_plate.schema | 0 {0.5 => spec}/schemas/strict_well.schema | 0 {0.5 => spec}/schemas/well.schema | 0 {0.5 => spec}/tests/image_suite.json | 0 {0.5 => spec}/tests/label_suite.json | 0 {0.5 => spec}/tests/plate_suite.json | 0 {0.5 => spec}/tests/strict_image_suite.json | 0 {0.5 => spec}/tests/strict_label_suite.json | 0 {0.5 => spec}/tests/strict_plate_suite.json | 0 {0.5 => spec}/tests/strict_well_suite.json | 0 {0.5 => spec}/tests/test_validation.py | 0 {0.5 => spec}/tests/well_suite.json | 0 {0.4 => spec}/tox.ini | 0 173 files changed, 8 insertions(+), 9998 deletions(-) delete mode 100644 0.1/examples/image/invalid/invalid_channels_color.json delete mode 100644 0.1/examples/image/invalid/invalid_channels_window.json delete mode 100644 0.1/examples/image/invalid/invalid_path.json delete mode 100644 0.1/examples/image/invalid/missing_datasets.json delete mode 100644 0.1/examples/image/invalid/missing_path.json delete mode 100644 0.1/examples/image/invalid/no_datasets.json delete mode 100644 0.1/examples/image/invalid/no_multiscales.json delete mode 100644 0.1/examples/image/valid/image.json delete mode 100644 0.1/examples/image/valid/image_complete.json delete mode 100644 0.1/examples/image/valid/image_complete_no_omero.json delete mode 100644 0.1/examples/image/valid/missing_name.json delete mode 100644 0.1/examples/image/valid/missing_type.json delete mode 100644 0.1/examples/image/valid/missing_version.json delete mode 100644 0.1/examples/plate/invalid/empty_wells.json delete mode 100644 0.1/examples/plate/invalid/invalid_fieldcount.json delete mode 100644 0.1/examples/plate/invalid/missing_acquisition_id.json delete mode 100644 0.1/examples/plate/invalid/missing_column_name.json delete mode 100644 0.1/examples/plate/invalid/missing_columns.json delete mode 100644 0.1/examples/plate/invalid/missing_rows.json delete mode 100644 0.1/examples/plate/invalid/missing_version.json delete mode 100644 0.1/examples/plate/invalid/missing_well_path.json delete mode 100644 0.1/examples/plate/invalid/missing_wells.json delete mode 100644 0.1/examples/plate/valid/minimal_acquisition.json delete mode 100644 0.1/examples/plate/valid/plate.json delete mode 100644 0.1/examples/plate/valid/plate_acquisition.json delete mode 100644 0.1/examples/well/valid/well.json delete mode 100644 0.1/header.include delete mode 100644 0.1/index.bs delete mode 100644 0.1/schemas/image.schema delete mode 100644 0.1/schemas/plate.schema delete mode 100644 0.1/schemas/strict_image.schema delete mode 100644 0.1/schemas/well.schema delete mode 100644 0.1/tests/test_validation.py delete mode 100644 0.1/tox.ini delete mode 100644 0.2/copyright.include delete mode 100644 0.2/examples/image/invalid/invalid_channels_color.json delete mode 100644 0.2/examples/image/invalid/invalid_channels_window.json delete mode 100644 0.2/examples/image/invalid/invalid_path.json delete mode 100644 0.2/examples/image/invalid/missing_datasets.json delete mode 100644 0.2/examples/image/invalid/missing_path.json delete mode 100644 0.2/examples/image/invalid/no_datasets.json delete mode 100644 0.2/examples/image/invalid/no_multiscales.json delete mode 100644 0.2/examples/image/valid/image.json delete mode 100644 0.2/examples/image/valid/image_metadata.json delete mode 100644 0.2/examples/image/valid/image_omero.json delete mode 100644 0.2/examples/image/valid/missing_name.json delete mode 100644 0.2/examples/image/valid/missing_version.json delete mode 100644 0.2/examples/plate/valid/plate.json delete mode 100644 0.2/examples/well/valid/well.json delete mode 100644 0.2/header.include delete mode 100644 0.2/index.bs delete mode 100644 0.2/schemas/image.schema delete mode 100644 0.2/schemas/plate.schema delete mode 100644 0.2/schemas/well.schema delete mode 100644 0.2/tests/test_validation.py delete mode 100644 0.2/tox.ini delete mode 100644 0.3/copyright.include delete mode 100644 0.3/examples/image/invalid/invalid_axes.json delete mode 100644 0.3/examples/image/invalid/invalid_axes_count.json delete mode 100644 0.3/examples/image/invalid/invalid_axes_order.json delete mode 100644 0.3/examples/image/invalid/invalid_channels_color.json delete mode 100644 0.3/examples/image/invalid/invalid_channels_window.json delete mode 100644 0.3/examples/image/invalid/invalid_path.json delete mode 100644 0.3/examples/image/invalid/invalid_version.json delete mode 100644 0.3/examples/image/invalid/missing_axes.json delete mode 100644 0.3/examples/image/invalid/missing_datasets.json delete mode 100644 0.3/examples/image/invalid/missing_path.json delete mode 100644 0.3/examples/image/invalid/no_axes.json delete mode 100644 0.3/examples/image/invalid/no_datasets.json delete mode 100644 0.3/examples/image/invalid/no_multiscales.json delete mode 100644 0.3/examples/image/valid/image.json delete mode 100644 0.3/examples/image/valid/image_metadata.json delete mode 100644 0.3/examples/image/valid/image_omero.json delete mode 100644 0.3/examples/image/valid/missing_name.json delete mode 100644 0.3/examples/image/valid/missing_version.json delete mode 100644 0.3/examples/plate/valid/plate.json delete mode 100644 0.3/examples/well/valid/well.json delete mode 100644 0.3/index.bs delete mode 100644 0.3/schemas/image.schema delete mode 100644 0.3/schemas/jsonld/context.json delete mode 100644 0.3/schemas/jsonld/frame.json delete mode 100644 0.3/schemas/jsonld/shacl.ttl delete mode 100644 0.3/schemas/plate.schema delete mode 100644 0.3/schemas/salad_schema/image.yml delete mode 100644 0.3/schemas/strict_image.schema delete mode 100644 0.3/schemas/well.schema delete mode 100644 0.3/tests/test_frame.py delete mode 100644 0.3/tests/test_validation.py delete mode 100644 0.3/tox.ini delete mode 100644 0.4/copyright.include delete mode 100644 0.4/examples/bf2raw/image.json delete mode 100644 0.4/examples/bf2raw/plate.json delete mode 100644 0.4/examples/label_strict/colors_properties.json delete mode 100644 0.4/examples/multiscales_strict/multiscales_example.json delete mode 100644 0.4/examples/multiscales_strict/multiscales_transformations.json delete mode 100644 0.4/examples/ome/series-2.json delete mode 100644 0.4/examples/plate_strict/plate_2wells.json delete mode 100644 0.4/examples/plate_strict/plate_6wells.json delete mode 100644 0.4/examples/well_strict/well_2fields.json delete mode 100644 0.4/examples/well_strict/well_4fields.json delete mode 100644 0.4/header.include delete mode 100644 0.4/index.bs delete mode 100644 0.4/schemas/bf2raw.schema delete mode 100644 0.4/schemas/image.schema delete mode 100644 0.4/schemas/label.schema delete mode 100644 0.4/schemas/ome.schema delete mode 100644 0.4/schemas/plate.schema delete mode 100644 0.4/schemas/strict_image.schema delete mode 100644 0.4/schemas/strict_label.schema delete mode 100644 0.4/schemas/strict_plate.schema delete mode 100644 0.4/schemas/strict_well.schema delete mode 100644 0.4/schemas/well.schema delete mode 100644 0.4/tests/image_suite.json delete mode 100644 0.4/tests/label_suite.json delete mode 100644 0.4/tests/plate_suite.json delete mode 100644 0.4/tests/strict_image_suite.json delete mode 100644 0.4/tests/strict_label_suite.json delete mode 100644 0.4/tests/strict_plate_suite.json delete mode 100644 0.4/tests/strict_well_suite.json delete mode 100644 0.4/tests/test_validation.py delete mode 100644 0.4/tests/well_suite.json delete mode 100644 0.5/copyright.include delete mode 100644 0.5/examples/bf2raw/.config.json delete mode 100644 0.5/examples/label_strict/.config.json delete mode 100644 0.5/examples/multiscales_strict/.config.json delete mode 100644 0.5/examples/ome/.config.json delete mode 100644 0.5/examples/plate_strict/.config.json delete mode 100644 0.5/examples/well_strict/.config.json delete mode 100644 0.5/header.include delete mode 100644 0.5/tox.ini delete mode 120000 latest rename {0.1 => spec}/copyright.include (100%) rename {0.4 => spec}/examples/bf2raw/.config.json (100%) rename {0.5 => spec}/examples/bf2raw/image.json (100%) rename {0.5 => spec}/examples/bf2raw/plate.json (100%) rename {0.4 => spec}/examples/label_strict/.config.json (100%) rename {0.5 => spec}/examples/label_strict/colors_properties.json (100%) rename {0.4 => spec}/examples/multiscales_strict/.config.json (100%) rename {0.5 => spec}/examples/multiscales_strict/multiscales_example.json (100%) rename {0.5 => spec}/examples/multiscales_strict/multiscales_transformations.json (100%) rename {0.4 => spec}/examples/ome/.config.json (100%) rename {0.5 => spec}/examples/ome/series-2.json (100%) rename {0.4 => spec}/examples/plate_strict/.config.json (100%) rename {0.5 => spec}/examples/plate_strict/plate_2wells.json (100%) rename {0.5 => spec}/examples/plate_strict/plate_6wells.json (100%) rename {0.4 => spec}/examples/well_strict/.config.json (100%) rename {0.5 => spec}/examples/well_strict/well_2fields.json (100%) rename {0.5 => spec}/examples/well_strict/well_4fields.json (100%) rename {0.3 => spec}/header.include (100%) rename {0.5 => spec}/index.bs (100%) rename {0.5 => spec}/schemas/_version.schema (100%) rename {0.5 => spec}/schemas/bf2raw.schema (100%) rename {0.5 => spec}/schemas/image.schema (100%) rename {0.5 => spec}/schemas/label.schema (100%) rename {0.5 => spec}/schemas/ome.schema (100%) rename {0.5 => spec}/schemas/ome_zarr.schema (100%) rename {0.5 => spec}/schemas/plate.schema (100%) rename {0.5 => spec}/schemas/strict_image.schema (100%) rename {0.5 => spec}/schemas/strict_label.schema (100%) rename {0.5 => spec}/schemas/strict_plate.schema (100%) rename {0.5 => spec}/schemas/strict_well.schema (100%) rename {0.5 => spec}/schemas/well.schema (100%) rename {0.5 => spec}/tests/image_suite.json (100%) rename {0.5 => spec}/tests/label_suite.json (100%) rename {0.5 => spec}/tests/plate_suite.json (100%) rename {0.5 => spec}/tests/strict_image_suite.json (100%) rename {0.5 => spec}/tests/strict_label_suite.json (100%) rename {0.5 => spec}/tests/strict_plate_suite.json (100%) rename {0.5 => spec}/tests/strict_well_suite.json (100%) rename {0.5 => spec}/tests/test_validation.py (100%) rename {0.5 => spec}/tests/well_suite.json (100%) rename {0.4 => spec}/tox.ini (100%) diff --git a/0.1/examples/image/invalid/invalid_channels_color.json b/0.1/examples/image/invalid/invalid_channels_color.json deleted file mode 100644 index da301713..00000000 --- a/0.1/examples/image/invalid/invalid_channels_color.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.1", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ] - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": 255, - "family": "linear", - "label": "1234", - "window": { - "end": 1765.0, - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ] - } -} diff --git a/0.1/examples/image/invalid/invalid_channels_window.json b/0.1/examples/image/invalid/invalid_channels_window.json deleted file mode 100644 index 534b6eb6..00000000 --- a/0.1/examples/image/invalid/invalid_channels_window.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.2", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ] - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": "ff0000", - "family": "linear", - "label": "1234", - "window": { - "end": "100", - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ] - } -} diff --git a/0.1/examples/image/invalid/invalid_path.json b/0.1/examples/image/invalid/invalid_path.json deleted file mode 100644 index 33d8b9ac..00000000 --- a/0.1/examples/image/invalid/invalid_path.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.1", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - }, - { - "path": 0 - } - ] - } - ] -} diff --git a/0.1/examples/image/invalid/missing_datasets.json b/0.1/examples/image/invalid/missing_datasets.json deleted file mode 100644 index ea5eee52..00000000 --- a/0.1/examples/image/invalid/missing_datasets.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.1", - "name": "example" - } - ] -} diff --git a/0.1/examples/image/invalid/missing_path.json b/0.1/examples/image/invalid/missing_path.json deleted file mode 100644 index df9c74cc..00000000 --- a/0.1/examples/image/invalid/missing_path.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.1", - "name": "example", - "datasets": [ - { - "foo": "path/to/0" - }, - { - "path": "1" - } - ] - } - ] -} diff --git a/0.1/examples/image/invalid/no_datasets.json b/0.1/examples/image/invalid/no_datasets.json deleted file mode 100644 index e519c9c7..00000000 --- a/0.1/examples/image/invalid/no_datasets.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.1", - "name": "example", - "datasets": [], - "axes": [ - "z", - "y", - "x" - ] - } - ] -} diff --git a/0.1/examples/image/invalid/no_multiscales.json b/0.1/examples/image/invalid/no_multiscales.json deleted file mode 100644 index d6dbfb33..00000000 --- a/0.1/examples/image/invalid/no_multiscales.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [] -} diff --git a/0.1/examples/image/valid/image.json b/0.1/examples/image/valid/image.json deleted file mode 100644 index 5c749323..00000000 --- a/0.1/examples/image/valid/image.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "datasets": [ - {"path": "path/to/0"}, - {"path": "1"}, - {"path": "2"} - ] - } - ] -} diff --git a/0.1/examples/image/valid/image_complete.json b/0.1/examples/image/valid/image_complete.json deleted file mode 100644 index 080448a2..00000000 --- a/0.1/examples/image/valid/image_complete.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "@id": "#my-image", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "#my-pyramid", - "version": "0.1", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - }, - { - "path": "1" - }, - { - "path": "2" - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": [ - "true", - "false" - ], - "kwargs": { - "multichannel": true - } - } - } - ], - "omero": { - "id": 1, - "version": "0.1", - "channels": [ - { - "active": true, - "color": "0000FF", - "family": "linear", - "inverted": false, - "label": "1234", - "window": { - "end": 1765.0, - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ], - "rdefs": { - "defaultZ": 0, - "defaultT": 0, - "model": "color" - } - } -} diff --git a/0.1/examples/image/valid/image_complete_no_omero.json b/0.1/examples/image/valid/image_complete_no_omero.json deleted file mode 100644 index a2669b48..00000000 --- a/0.1/examples/image/valid/image_complete_no_omero.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "@id": "top", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "inner", - "version": "0.1", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": [ - "true", - "false" - ], - "kwargs": { - "multichannel": true - } - } - } - ] -} diff --git a/0.1/examples/image/valid/missing_name.json b/0.1/examples/image/valid/missing_name.json deleted file mode 100644 index fe3de034..00000000 --- a/0.1/examples/image/valid/missing_name.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.1", - "datasets": [ - { - "path": "path/to/0" - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1" - } - } - ] -} diff --git a/0.1/examples/image/valid/missing_type.json b/0.1/examples/image/valid/missing_type.json deleted file mode 100644 index b9ece803..00000000 --- a/0.1/examples/image/valid/missing_type.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "@id": "#my-image", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "#my-pyramid", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ], - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1" - }, - "version": "0.1" - } - ] -} \ No newline at end of file diff --git a/0.1/examples/image/valid/missing_version.json b/0.1/examples/image/valid/missing_version.json deleted file mode 100644 index 51086c4b..00000000 --- a/0.1/examples/image/valid/missing_version.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "@id": "#my-image", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "#my-pyramid", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1" - } - } - ], - "omero": { - "id": 1, - "version": "0.1", - "channels": [ - { - "active": true, - "color": "0000FF", - "family": "linear", - "inverted": false, - "label": "1234", - "window": { - "end": 1765.0, - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ] - } -} \ No newline at end of file diff --git a/0.1/examples/plate/invalid/empty_wells.json b/0.1/examples/plate/invalid/empty_wells.json deleted file mode 100644 index 1c8861da..00000000 --- a/0.1/examples/plate/invalid/empty_wells.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - } - ], - "rows": [ - { - "name": "A" - } - ], - "version": "0.1", - "wells": [] - } -} \ No newline at end of file diff --git a/0.1/examples/plate/invalid/invalid_fieldcount.json b/0.1/examples/plate/invalid/invalid_fieldcount.json deleted file mode 100644 index 89540652..00000000 --- a/0.1/examples/plate/invalid/invalid_fieldcount.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - } - ], - "field_count": 1, - "name": "plate name", - "rows": [ - { - "name": "A" - } - ], - "version": "0.1", - "wells": [ - { - "path": "A/3" - } - ], - "acquisitions": [ - { - "id": 1, - "maximumfieldcount": "2" - }, - { - "id": 2 - } - ] - } -} \ No newline at end of file diff --git a/0.1/examples/plate/invalid/missing_acquisition_id.json b/0.1/examples/plate/invalid/missing_acquisition_id.json deleted file mode 100644 index 46fe420a..00000000 --- a/0.1/examples/plate/invalid/missing_acquisition_id.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - } - ], - "field_count": 1, - "name": "plate name", - "rows": [ - { - "name": "A" - } - ], - "version": "0.1", - "wells": [ - { - "path": "A/3" - } - ], - "acquisitions": [ - { - "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 - } - ] - } -} \ No newline at end of file diff --git a/0.1/examples/plate/invalid/missing_column_name.json b/0.1/examples/plate/invalid/missing_column_name.json deleted file mode 100644 index dbf4e2d6..00000000 --- a/0.1/examples/plate/invalid/missing_column_name.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "plate": { - "columns": [ - {} - ], - "rows": [ - { - "name": "A" - } - ], - "version": "0.1", - "wells": [ - { - "path": "A/3" - } - ] - } -} \ No newline at end of file diff --git a/0.1/examples/plate/invalid/missing_columns.json b/0.1/examples/plate/invalid/missing_columns.json deleted file mode 100644 index 997e2927..00000000 --- a/0.1/examples/plate/invalid/missing_columns.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "plate": { - "rows": [ - { - "name": "A" - } - ], - "version": "0.1", - "wells": [ - { - "path": "A/3" - } - ] - } -} \ No newline at end of file diff --git a/0.1/examples/plate/invalid/missing_rows.json b/0.1/examples/plate/invalid/missing_rows.json deleted file mode 100644 index 74f6ba6a..00000000 --- a/0.1/examples/plate/invalid/missing_rows.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - } - ], - "version": "0.1", - "wells": [ - { - "path": "A/3" - } - ] - } -} \ No newline at end of file diff --git a/0.1/examples/plate/invalid/missing_version.json b/0.1/examples/plate/invalid/missing_version.json deleted file mode 100644 index 36b0afde..00000000 --- a/0.1/examples/plate/invalid/missing_version.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - } - ], - "rows": [ - { - "name": "A" - } - ], - "wells": [ - { - "path": "A/1" - } - ] - } -} \ No newline at end of file diff --git a/0.1/examples/plate/invalid/missing_well_path.json b/0.1/examples/plate/invalid/missing_well_path.json deleted file mode 100644 index ded5f769..00000000 --- a/0.1/examples/plate/invalid/missing_well_path.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - } - ], - "rows": [ - { - "name": "A" - } - ], - "version": "0.1", - "wells": [ - {} - ] - } -} \ No newline at end of file diff --git a/0.1/examples/plate/invalid/missing_wells.json b/0.1/examples/plate/invalid/missing_wells.json deleted file mode 100644 index fd00f136..00000000 --- a/0.1/examples/plate/invalid/missing_wells.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - } - ], - "rows": [ - { - "name": "A" - } - ], - "version": "0.1" - } -} \ No newline at end of file diff --git a/0.1/examples/plate/valid/minimal_acquisition.json b/0.1/examples/plate/valid/minimal_acquisition.json deleted file mode 100644 index 43037600..00000000 --- a/0.1/examples/plate/valid/minimal_acquisition.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - } - ], - "field_count": 1, - "name": "plate name", - "rows": [ - { - "name": "A" - } - ], - "version": "0.1", - "wells": [ - { - "path": "A/3" - } - ], - "acquisitions": [ - { - "id": 1, - "name": "SHOULD have a name" - }, - { - "id": 2 - } - ] - } -} \ No newline at end of file diff --git a/0.1/examples/plate/valid/plate.json b/0.1/examples/plate/valid/plate.json deleted file mode 100644 index eb2bd031..00000000 --- a/0.1/examples/plate/valid/plate.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - }, - { - "name": "2" - }, - { - "name": "3" - } - ], - "field_count": 1, - "name": "plate name", - "rows": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "version": "0.1", - "wells": [ - { - "path": "A/3" - }, - { - "path": "B/2" - }, - { - "path": "A/1" - }, - { - "path": "B/3" - } - ] - } -} \ No newline at end of file diff --git a/0.1/examples/plate/valid/plate_acquisition.json b/0.1/examples/plate/valid/plate_acquisition.json deleted file mode 100644 index 0559909b..00000000 --- a/0.1/examples/plate/valid/plate_acquisition.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - }, - { - "name": "2" - }, - { - "name": "3" - } - ], - "field_count": 1, - "name": "plate name", - "rows": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "version": "0.1", - "wells": [ - { - "path": "A/3" - }, - { - "path": "B/2" - }, - { - "path": "A/1" - }, - { - "path": "B/3" - } - ], - "acquisitions": [ - { - "id": 1, - "description": "First Acquisition", - "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 - } - ] - } -} \ No newline at end of file diff --git a/0.1/examples/well/valid/well.json b/0.1/examples/well/valid/well.json deleted file mode 100644 index 47f91479..00000000 --- a/0.1/examples/well/valid/well.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "well": { - "images": [ - { - "acquisition": 0, - "path": "0" - }, - { - "acquisition": 3, - "path": "1" - } - ], - "version": "0.1" - } -} \ No newline at end of file diff --git a/0.1/header.include b/0.1/header.include deleted file mode 100644 index 28305fe4..00000000 --- a/0.1/header.include +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - [TITLE] - - - -
- - - OME logo (6 circles in a hexagon) - -

[TITLE]

-

[LONGSTATUS], -

-
-
- -
-
- -
- -

Status of this document

-
-
- - -
diff --git a/0.1/index.bs b/0.1/index.bs deleted file mode 100644 index 1e7fe1e2..00000000 --- a/0.1/index.bs +++ /dev/null @@ -1,622 +0,0 @@ - - -Introduction {#intro} -===================== - -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. - - -Why "NGFF"? {#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](https://pydata.org/) community, the Zarr [[zarr]] format was developed -for easily storing collections of [NumPy](https://numpy.org/) arrays. In the -[ImageJ](https://imagej.net/) 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](https://zarr-specs.readthedocs.io/en/core-protocol-v3.0-dev/protocol/core/v3.0.html) -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)](https://github.com/zarr-developers/zarr-specs/issues/101) phase with the goal of having a first version early in 2021. As that -process comes to an end, this document will be updated. - -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](http://www.openmicroscopy.org/ome-files/) -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, -for all examples. - -On-disk (or in-cloud) layout {#on-disk} -======================================= - -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 -be stored on a web server to be accessed via HTTP or in object storage -like S3 or GCS. - -Images {#image-layout} ----------------------- - -The following layout describes the expected Zarr hierarchy for images with -multiple levels of resolutions and optionally associated labels. - -``` -. # Root folder, potentially in S3, -│ # with a flat list of images by image ID. -│ -├── 123.zarr # One image (id=123) converted to Zarr. -│ -└── 456.zarr # Another image (id=456) converted to Zarr. - │ - ├── .zgroup # Each image is a Zarr group, or a folder, of other groups and arrays. - ├── .zattrs # Group level attributes are stored in the .zattrs file and include - │ # "multiscales" and "omero" below) - │ - ├── 0 # Each multiscale level is stored as a separate Zarr array, - │ ... # which is a folder containing chunk files which compose the array. - ├── n # The name of the array is arbitrary with the ordering defined by - │ │ # by the "multiscales" metadata, but is often a sequence starting at 0. - │ │ - │ ├── .zarray # All image arrays are 5-dimensional - │ │ # with dimension order (t, c, z, y, x). - │ │ - │ ├── 0.0.0.0.0 # Chunks are stored with the flat directory layout. - │ │ ... # Each dotted component of the chunk file represents - │ └── t.c.z.y.x # a "chunk coordinate", where the maximum coordinate - │ # 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 `.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. - │ - └── 0 # Multiscale, labeled image. The name is unimportant but is registered in the "labels" group above. - ├── .zgroup # Zarr Group which is both a multiscaled image as well as a labeled image. - ├── .zattrs # Metadata of the related image and as well as display information under the "image-label" key. - │ - ├── 0 # Each multiscale level is stored as a separate Zarr array, as above, but only integer values - │ ... # are supported. - └── n -``` - -High-content screening {#hcs-layout} ------------------------------------- - -The following specification defines the hierarchy for a high-content screening -dataset. Three groups must be defined above the images: - -- the group above the images defines the well and MUST implement the - [well specification](#well-md). All images contained in a well are fields - of view of the same well -- the group above the well defines a row of wells -- the group above the well row defines an entire plate i.e. a two-dimensional - collection of wells organized in rows and columns. It MUST implement the - [plate specification](#plate-md) - - -``` -. # Root folder, potentially in S3, -│ -└── 5966.zarr # One plate (id=5966) converted to Zarr - ├── .zgroup - ├── .zattrs # Implements "plate" specification - ├── A # First row of the plate - │ ├── .zgroup - │ │ - │ ├── 1 # First column of row A - │ │ ├── .zgroup - │ │ ├── .zattrs # Implements "well" specification - │ │ │ - │ │ ├── 0 # First field of view of well A1 - │ │ │ │ - │ │ │ ├── .zgroup - │ │ │ ├── .zattrs # Implements "multiscales", "omero" - │ │ │ ├── 0 - │ │ │ │ ... # Resolution levels - │ │ │ ├── n - │ │ │ └── labels # Labels (optional) - │ │ ├── ... # Fields of view - │ │ └── m - │ ├── ... # Columns - │ └── 12 - ├── ... # Rows - └── H -``` - -Metadata {#metadata} -==================== - -The various `.zattrs` files throughout the above array hierarchy may contain metadata -keys as specified below for discovering certain types of data, especially images. - -"multiscales" metadata {#multiscale-md} ---------------------------------------- - -Metadata about the multiple resolution representations of the image can be -found under the "multiscales" key in the group-level metadata. -The specification for the multiscale (i.e. "resolution") metadata is provided -in [zarr-specs#50](https://github.com/zarr-developers/zarr-specs/issues/50). -If only one multiscale is provided, use it. Otherwise, the user can choose by -name, using the first multiscale as a fallback: - -```python -datasets = [] -for named in multiscales: - if named["name"] == "3D": - datasets = [x["path"] for x in named["datasets"]] - break -if not datasets: - # Use the first by default. Or perhaps choose based on chunk size. - datasets = [x["path"] for x in multiscales[0]["datasets"]] -``` - -The subresolutions in each multiscale are ordered from highest-resolution -to lowest. - -"omero" metadata {#omero-md} ----------------------------- - -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: - -```json -"id": 1, # ID in OMERO -"name": "example.tif", # Name as shown in the UI -"version": "0.1", # Current version -"channels": [ # Array matching the c dimension size - { - "active": true, - "coefficient": 1, - "color": "0000FF", - "family": "linear", - "inverted": false, - "label": "LaminB1", - "window": { - "end": 1500, - "max": 65535, - "min": 0, - "start": 0 - } - } -], -"rdefs": { - "defaultT": 0, # First timepoint to show the user - "defaultZ": 118, # First Z section to show the user - "model": "color" # "color" or "greyscale" -} -``` - -See https://docs.openmicroscopy.org/omero/5.6.1/developers/Web/WebGateway.html#imgdata -for more information. - -"labels" metadata {#labels-md} ------------------------------- - -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: - -```json -{ - "labels": [ - "orphaned/0" - ] -} -``` - -Unlisted groups MAY be labels. - -"image-label" metadata {#label-md} ----------------------------------- - -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-value`s 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 `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). - - -```json -"image-label": - { - "version": "0.1", - "colors": [ - { - "label-value": 1, - "rgba": [255, 255, 255, 0] - }, - { - "label-value": 4, - "rgba": [0, 255, 255, 128] - }, - ... - ] - }, - "source": { - "image": "../../" - } -] -``` - -"plate" metadata {#plate-md} ----------------------------- - -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. If not empty, it MUST contain a `name` key specifying the - column name.
-
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. If not empty, it MUST contain a `name` key specifying the row - name.
-
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.
-
- -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 acquisition. - -```json -"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.1", - "wells": [ - { - "path": "2020-10-10/A/1" - }, - { - "path": "2020-10-10/A/2" - }, - { - "path": "2020-10-10/A/3" - }, - { - "path": "2020-10-10/B/1" - }, - { - "path": "2020-10-10/B/2" - }, - { - "path": "2020-10-10/B/3" - } - ] - } -``` - -"well" metadata {#well-md} --------------------------- - -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 - SHOULD 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.
-
- -For example the following JSON object defines a well with four fields of -views. 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. - -```json -"well": { - "images": [ - { - "acquisition": 1, - "path": "0" - }, - { - "acquisition": 1, - "path": "1" - }, - { - "acquisition": 2, - "path": "2" - }, - { - "acquisition": 2, - "path": "3" - } - ], - "version": "0.1" - } -``` - -Implementations {#implementations} -================================== - -Projects which support reading and/or writing OME-NGFF data include: - -
- -
[omero-ms-zarr](https://github.com/ome/omero-ms-zarr)
-
A microservice for OMERO.server that converts images stored in OMERO to OME Zarr files on the fly, served via a web API.
- -
[idr-zarr-tools](https://github.com/IDR/idr-zarr-tools)
-
A full workflow demonstrating the conversion of IDR images to OME Zarr images on S3.
- -
[OMERO CLI Zarr plugin](https://github.com/ome/omero-cli-zarr)
-
An OMERO CLI plugin that converts images stored in OMERO.server into a local Zarr file.
- -
[ome-zarr-py](https://github.com/ome/ome-zarr-py)
-
A napari plugin for reading ome-zarr files.
- -
[bioformats2raw](https://github.com/glencoesoftware/bioformats2raw)
-
A performant, Bio-Formats image file format converter.
- -
[vizarr](https://github.com/hms-dbmi/vizarr/)
-
A minimal, purely client-side program for viewing Zarr-based images with Viv & ImJoy.
- -
- -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](https://downloads.openmicroscopy.org/presentations/2020/Dundee/Workshops/NGFF/zarr_diagram/). -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](https://github.com/ome/ngff) repository. - -Citing {#citing} -================ - -[Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.](https://ngff.openmicroscopy.org/0.1) -J. Moore, *et al*. Open Microscopy Environment Consortium, 20 November 2020. -This edition of the specification is [https://ngff.openmicroscopy.org/0.1/](https://ngff.openmicroscopy.org/0.1/]). -The latest edition is available at [https://ngff.openmicroscopy.org/latest/](https://ngff.openmicroscopy.org/latest/). -[(doi:10.5281/zenodo.4282107)](https://doi.org/10.5281/zenodo.4282107) - -Version History {#history} -========================== - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RevisionDateDescription
0.1.42020-11-26Add HCS specification
0.1.32020-09-14Add labels specification
0.1.2 2020-05-07Add description of "omero" metadata
0.1.1 2020-05-06Add info on the ordering of resolutions
0.1.0 2020-04-20First version for internal demo
- - -
-{
-  "blogNov2020": {
-    "href": "https://blog.openmicroscopy.org/file-formats/community/2020/11/04/zarr-data/",
-    "title": "Public OME-Zarr data (Nov. 2020)",
-    "authors": [
-      "OME Team"
-    ],
-    "status": "Informational",
-    "publisher": "OME",
-    "id": "blogNov2020",
-    "date": "04 November 2020"
-  },
-  "imagesc26952": {
-    "href": "https://forum.image.sc/t/ome-s-position-regarding-file-formats/26952",
-    "title": "OME’s position regarding file formats",
-    "authors": [
-      "OME Team"
-    ],
-    "status": "Informational",
-    "publisher": "OME",
-    "id": "imagesc26952",
-    "date": "19 June 2020"
-  },
-  "n5": {
-    "id": "n5",
-    "href": "https://github.com/saalfeldlab/n5/issues/62",
-    "title": "N5---a scalable Java API for hierarchies of chunked n-dimensional tensors and structured meta-data",
-    "status": "Informational",
-    "authors": [
-      "John A. Bogovic",
-      "Igor Pisarev",
-      "Philipp Hanslovsky",
-      "Neil Thistlethwaite",
-      "Stephan Saalfeld"
-    ],
-    "date": "2020"
-  },
-  "ome-zarr-py": {
-    "id": "ome-zarr-py",
-    "href": "https://doi.org/10.5281/zenodo.4113931",
-    "title": "ome-zarr-py: Experimental implementation of next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.",
-    "status": "Informational",
-    "publisher": "Zenodo",
-    "authors": [
-      "OME",
-      "et al"
-    ],
-    "date": "06 October 2020"
-  },
-  "zarr": {
-    "id": "zarr",
-    "href": "https://doi.org/10.5281/zenodo.4069231",
-    "title": "Zarr: An implementation of chunked, compressed, N-dimensional arrays for Python.",
-    "status": "Informational",
-    "publisher": "Zenodo",
-    "authors": [
-      "Alistair Miles",
-      "et al"
-    ],
-    "date": "06 October 2020"
-  }
-}
-
diff --git a/0.1/schemas/image.schema b/0.1/schemas/image.schema deleted file mode 100644 index 5a97f3f2..00000000 --- a/0.1/schemas/image.schema +++ /dev/null @@ -1,112 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.1/schemas/image.schema", - "title": "NGFF Image", - "description": "JSON from OME-NGFF .zattrs", - "type": "object", - "properties": { - "multiscales": { - "description": "The multiscale datasets for this image", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "datasets": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - }, - "required": ["path"] - } - }, - "version": { - "type": "string", - "enum": [ - "0.1" - ] - }, - "metadata": { - "type": "object", - "properties": { - "method": { - "type": "string" - }, - "version": { - "type": "string" - } - } - } - }, - "required": [ - "datasets" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "omero": { - "type": "object", - "properties": { - "channels": { - "type": "array", - "items": { - "type": "object", - "properties": { - "window": { - "type": "object", - "properties": { - "end": { - "type": "number" - }, - "max": { - "type": "number" - }, - "min": { - "type": "number" - }, - "start": { - "type": "number" - } - }, - "required": [ - "start", - "min", - "end", - "max" - ] - }, - "label": { - "type": "string" - }, - "family": { - "type": "string" - }, - "color": { - "type": "string" - }, - "active": { - "type": "boolean" - } - }, - "required": [ - "window", - "color" - ] - } - } - }, - "required": [ - "channels" - ] - } - }, - "required": [ "multiscales" ] -} diff --git a/0.1/schemas/plate.schema b/0.1/schemas/plate.schema deleted file mode 100644 index e4f4f6f7..00000000 --- a/0.1/schemas/plate.schema +++ /dev/null @@ -1,112 +0,0 @@ -{ - "$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 deleted file mode 100644 index ac375073..00000000 --- a/0.1/schemas/strict_image.schema +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$id": "https://ngff.openmicroscopy.org/0.1/schemas/strict_image.schema", - "allOf": [ - { - "$ref": "https://ngff.openmicroscopy.org/0.1/schemas/image.schema" - }, - { - "properties": { - "multiscales": { - "items": { - "required": [ - "version", "metadata", "type", "name" - ] - } - } - } - } - ] -} \ No newline at end of file diff --git a/0.1/schemas/well.schema b/0.1/schemas/well.schema deleted file mode 100644 index 02475934..00000000 --- a/0.1/schemas/well.schema +++ /dev/null @@ -1,47 +0,0 @@ -{ - "$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.1/tests/test_validation.py b/0.1/tests/test_validation.py deleted file mode 100644 index 21d0e826..00000000 --- a/0.1/tests/test_validation.py +++ /dev/null @@ -1,97 +0,0 @@ -import json -import os -import glob - -import pytest - -from jsonschema import validate, RefResolver -from jsonschema.validators import validator_for -from jsonschema.exceptions import ValidationError - - -IMAGE_SCHEMA_KEY = "https://ngff.openmicroscopy.org/0.1/schemas/image.schema" - - -def files(): - return list(glob.glob(f"examples/*/valid/*.json")) + \ - list(glob.glob(f"examples/*/invalid/*.json")) - - -def strict(): - return list(glob.glob(f"examples/image/valid/*.json")) - - -def ids(paths): - return [str(x).split("/")[-1][0:-5] for x in paths] - - -@pytest.mark.parametrize("testfile", files(), ids=ids(files())) -def test_json(testfile): - - test_json, schema = load_instance_and_schema(testfile) - - if "invalid" in testfile: - with pytest.raises(ValidationError): - validate(instance=test_json, schema=schema) - else: - validate(instance=test_json, schema=schema) - - -class LocalRefResolver(RefResolver): - - def resolve_remote(self, url): - # Use remote URL to generate local path - url = url.replace("https://ngff.openmicroscopy.org/0.1/", "") - # Load local document and cache it - document = load_json(url) - self.store[url] = document - return document - - -@pytest.mark.parametrize("testfile", strict(), ids=ids(strict())) -def test_strict_rules(testfile): - - test_json, schema = load_instance_and_schema(testfile, strict=True) - - # Check for all validation errors without throwing exception - cls = validator_for(schema) - cls.check_schema(schema) - - # Use our local resolver subclass to resolve local documents - localResolver = LocalRefResolver.from_schema(schema) - validator = cls(schema, localResolver) - - warnings = list(validator.iter_errors(test_json)) - for warning in warnings: - print("WARNING", warning.message) - # ONLY the complete example has no warnings in strict mode - if "complete" not in testfile: - assert len(warnings) > 0 - - -def load_instance_and_schema(path, strict=False): - # Load the correct schema - test_json = load_json(path) - # we don't have @type in this version - if "multiscales" in test_json: - schema_name = "image.schema" - elif "plate" in test_json: - schema_name = "plate.schema" - elif "well" in test_json: - schema_name = "well.schema" - else: - raise Exception("No schema found") - - schema = load_json('schemas/' + schema_name) - - if strict and schema_name == "image.schema": - strict_path = 'schemas/strict_' + schema_name - schema = load_json(strict_path) - - return (test_json, schema) - - -def load_json(path): - with open(path) as f: - json_data = json.loads(f.read()) - return json_data diff --git a/0.1/tox.ini b/0.1/tox.ini deleted file mode 100644 index 2de32a96..00000000 --- a/0.1/tox.ini +++ /dev/null @@ -1,10 +0,0 @@ -[tox] -envlist = v01 -skipsdist = True - -[testenv] -deps = - pytest - jsonschema -commands = - pytest tests --color=yes --basetemp={envtmpdir} {posargs:-v} diff --git a/0.2/copyright.include b/0.2/copyright.include deleted file mode 100644 index f0def708..00000000 --- a/0.2/copyright.include +++ /dev/null @@ -1,4 +0,0 @@ -Copyright © 2020-[YEAR] -OME® -(U. Dundee). -OME trademark rules apply. diff --git a/0.2/examples/image/invalid/invalid_channels_color.json b/0.2/examples/image/invalid/invalid_channels_color.json deleted file mode 100644 index 56f9f7f2..00000000 --- a/0.2/examples/image/invalid/invalid_channels_color.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.2", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ] - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": 255, - "family": "linear", - "label": "1234", - "window": { - "end": 1765.0, - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ] - } -} diff --git a/0.2/examples/image/invalid/invalid_channels_window.json b/0.2/examples/image/invalid/invalid_channels_window.json deleted file mode 100644 index 534b6eb6..00000000 --- a/0.2/examples/image/invalid/invalid_channels_window.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.2", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ] - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": "ff0000", - "family": "linear", - "label": "1234", - "window": { - "end": "100", - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ] - } -} diff --git a/0.2/examples/image/invalid/invalid_path.json b/0.2/examples/image/invalid/invalid_path.json deleted file mode 100644 index 0ea1f2d9..00000000 --- a/0.2/examples/image/invalid/invalid_path.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.2", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - }, - { - "path": 0 - } - ] - } - ] -} diff --git a/0.2/examples/image/invalid/missing_datasets.json b/0.2/examples/image/invalid/missing_datasets.json deleted file mode 100644 index 6604968d..00000000 --- a/0.2/examples/image/invalid/missing_datasets.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.2", - "name": "example" - } - ] -} diff --git a/0.2/examples/image/invalid/missing_path.json b/0.2/examples/image/invalid/missing_path.json deleted file mode 100644 index 487a4266..00000000 --- a/0.2/examples/image/invalid/missing_path.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.2", - "name": "example", - "datasets": [ - { - "foo": "path/to/0" - }, - { - "path": "1" - } - ] - } - ] -} diff --git a/0.2/examples/image/invalid/no_datasets.json b/0.2/examples/image/invalid/no_datasets.json deleted file mode 100644 index 839a60aa..00000000 --- a/0.2/examples/image/invalid/no_datasets.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.2", - "name": "example", - "datasets": [], - "axes": [ - "z", - "y", - "x" - ] - } - ] -} diff --git a/0.2/examples/image/invalid/no_multiscales.json b/0.2/examples/image/invalid/no_multiscales.json deleted file mode 100644 index d6dbfb33..00000000 --- a/0.2/examples/image/invalid/no_multiscales.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [] -} diff --git a/0.2/examples/image/valid/image.json b/0.2/examples/image/valid/image.json deleted file mode 100644 index 2c1e7d27..00000000 --- a/0.2/examples/image/valid/image.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.2", - "name": "example", - "datasets": [ - {"path": "path/to/0"}, - {"path": "1"}, - {"path": "2"} - ] - } - ] -} diff --git a/0.2/examples/image/valid/image_metadata.json b/0.2/examples/image/valid/image_metadata.json deleted file mode 100644 index 3ca5cd47..00000000 --- a/0.2/examples/image/valid/image_metadata.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "@id": "top", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "inner", - "version": "0.2", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": [ - "true", - "false" - ], - "kwargs": { - "multichannel": true - } - } - } - ] -} diff --git a/0.2/examples/image/valid/image_omero.json b/0.2/examples/image/valid/image_omero.json deleted file mode 100644 index 20b3b892..00000000 --- a/0.2/examples/image/valid/image_omero.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "@id": "#my-image", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "#my-pyramid", - "version": "0.2", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - }, - { - "path": "1" - }, - { - "path": "2" - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": [ - "true", - "false" - ], - "kwargs": { - "multichannel": true - } - } - } - ], - "omero": { - "id": 1, - "version": "0.2", - "channels": [ - { - "active": true, - "color": "0000FF", - "family": "linear", - "inverted": false, - "label": "1234", - "window": { - "end": 1765.0, - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ], - "rdefs": { - "defaultZ": 0, - "defaultT": 0, - "model": "color" - } - } -} diff --git a/0.2/examples/image/valid/missing_name.json b/0.2/examples/image/valid/missing_name.json deleted file mode 100644 index 3942a543..00000000 --- a/0.2/examples/image/valid/missing_name.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.2", - "datasets": [ - { - "path": "path/to/0" - } - ] - } - ] -} diff --git a/0.2/examples/image/valid/missing_version.json b/0.2/examples/image/valid/missing_version.json deleted file mode 100644 index c278ddef..00000000 --- a/0.2/examples/image/valid/missing_version.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ] - } - ] -} diff --git a/0.2/examples/plate/valid/plate.json b/0.2/examples/plate/valid/plate.json deleted file mode 100644 index 0712bad8..00000000 --- a/0.2/examples/plate/valid/plate.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - }, - { - "name": "2" - }, - { - "name": "3" - } - ], - "field_count": 1, - "name": "plate name", - "rows": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "version": "0.2", - "wells": [ - { - "path": "A/3" - }, - { - "path": "B/2" - }, - { - "path": "A/1" - }, - { - "path": "B/3" - } - ] - } -} \ No newline at end of file diff --git a/0.2/examples/well/valid/well.json b/0.2/examples/well/valid/well.json deleted file mode 100644 index fe6edd09..00000000 --- a/0.2/examples/well/valid/well.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "well": { - "images": [ - { - "acquisition": 0, - "path": "0" - }, - { - "acquisition": 3, - "path": "1" - } - ], - "version": "0.2" - } -} \ No newline at end of file diff --git a/0.2/header.include b/0.2/header.include deleted file mode 100644 index 28305fe4..00000000 --- a/0.2/header.include +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - [TITLE] - - - -
- - - OME logo (6 circles in a hexagon) - -

[TITLE]

-

[LONGSTATUS], -

-
-
- -
-
- -
- -

Status of this document

-
-
- - -
diff --git a/0.2/index.bs b/0.2/index.bs deleted file mode 100644 index 960f38ee..00000000 --- a/0.2/index.bs +++ /dev/null @@ -1,685 +0,0 @@ - - -Introduction {#intro} -===================== - -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. - - -Why "NGFF"? {#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](https://pydata.org/) community, the Zarr [[zarr]] format was developed -for easily storing collections of [NumPy](https://numpy.org/) arrays. In the -[ImageJ](https://imagej.net/) 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](https://zarr-specs.readthedocs.io/en/core-protocol-v3.0-dev/protocol/core/v3.0.html) -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)](https://github.com/zarr-developers/zarr-specs/issues/101) phase with the goal of having a first version early in 2021. As that -process comes to an end, this document will be updated. - -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](http://www.openmicroscopy.org/ome-files/) -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, -for all examples. - -On-disk (or in-cloud) layout {#on-disk} -======================================= - -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 -be stored on a web server to be accessed via HTTP or in object storage -like S3 or GCS. - -Images {#image-layout} ----------------------- - -The following layout describes the expected Zarr hierarchy for images with -multiple levels of resolutions and optionally associated labels. - -``` -. # Root folder, potentially in S3, -│ # with a flat list of images by image ID. -│ -├── 123.zarr # One image (id=123) converted to Zarr. -│ -└── 456.zarr # Another image (id=456) converted to Zarr. - │ - ├── .zgroup # Each image is a Zarr group, or a folder, of other groups and arrays. - ├── .zattrs # Group level attributes are stored in the .zattrs file and include - │ # "multiscales" and "omero" below) - │ - ├── 0 # Each multiscale level is stored as a separate Zarr array, - │ ... # which is a folder containing chunk files which compose the array. - ├── n # The name of the array is arbitrary with the ordering defined by - │ │ # by the "multiscales" metadata, but is often a sequence starting at 0. - │ │ - │ ├── .zarray # All image arrays are 5-dimensional - │ │ # with dimension order (t, c, z, y, x). - │ │ - │ └─ t # Chunks are stored with the nested directory layout. - │ └─ c # All but the last chunk element are stored as directories. - │ └─ z # The terminal chunk is a file. Together the directory and file names - │ └─ y # provide the "chunk coordinate" (t, c, z, y, x), where the maximum coordinate - │ └─ 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 `.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. - │ - └── 0 # Multiscale, labeled image. The name is unimportant but is registered in the "labels" group above. - ├── .zgroup # Zarr Group which is both a multiscaled image as well as a labeled image. - ├── .zattrs # Metadata of the related image and as well as display information under the "image-label" key. - │ - ├── 0 # Each multiscale level is stored as a separate Zarr array, as above, but only integer values - │ ... # are supported. - └── n -``` - -High-content screening {#hcs-layout} ------------------------------------- - -The following specification defines the hierarchy for a high-content screening -dataset. Three groups must be defined above the images: - -- the group above the images defines the well and MUST implement the - [well specification](#well-md). All images contained in a well are fields - of view of the same well -- the group above the well defines a row of wells -- the group above the well row defines an entire plate i.e. a two-dimensional - collection of wells organized in rows and columns. It MUST implement the - [plate specification](#plate-md) - - -``` -. # Root folder, potentially in S3, -│ -└── 5966.zarr # One plate (id=5966) converted to Zarr - ├── .zgroup - ├── .zattrs # Implements "plate" specification - ├── A # First row of the plate - │ ├── .zgroup - │ │ - │ ├── 1 # First column of row A - │ │ ├── .zgroup - │ │ ├── .zattrs # Implements "well" specification - │ │ │ - │ │ ├── 0 # First field of view of well A1 - │ │ │ │ - │ │ │ ├── .zgroup - │ │ │ ├── .zattrs # Implements "multiscales", "omero" - │ │ │ ├── 0 - │ │ │ │ ... # Resolution levels - │ │ │ ├── n - │ │ │ └── labels # Labels (optional) - │ │ ├── ... # Fields of view - │ │ └── m - │ ├── ... # Columns - │ └── 12 - ├── ... # Rows - └── H -``` - -Metadata {#metadata} -==================== - -The various `.zattrs` files throughout the above array hierarchy may contain metadata -keys as specified below for discovering certain types of data, especially images. - -"multiscales" metadata {#multiscale-md} ---------------------------------------- - -Metadata about the multiple resolution representations of the image can be -found under the "multiscales" key in the group-level metadata. - -"multiscales" contains a list of dictionaries where each entry describes a multiscale image. - -Each dictionary contained in the list MUST contain the field "datasets", which is a list of dictionaries describing -the arrays storing the individual resolution levels. -Each dictionary in "datasets" MUST contain the field "path", whose value contains the path to the array for this resolution relative -to the current zarr group. The "path"s MUST be ordered from largest (i.e. highest resolution) to smallest. - -It 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.2). - -It 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. - -```json -{ - "multiscales": [ - { - "version": "0.2", - "name": "example", - "datasets": [ - {"path": "0"}, - {"path": "1"}, - {"path": "2"} - ], - "type": "gaussian", - "metadata": { # the fields in metadata depend on the downscaling implementation - "method": "skimage.transform.pyramid_gaussian", # here, the parameters passed to the skimage function are given - "version": "0.16.1", - "args": "[true]", - "kwargs": {"multichannel": true} - } - } - ] -} -``` - -If only one multiscale is provided, use it. Otherwise, the user can choose by -name, using the first multiscale as a fallback: - -```python -datasets = [] -for named in multiscales: - if named["name"] == "3D": - datasets = [x["path"] for x in named["datasets"]] - break -if not datasets: - # Use the first by default. Or perhaps choose based on chunk size. - datasets = [x["path"] for x in multiscales[0]["datasets"]] -``` - -"omero" metadata {#omero-md} ----------------------------- - -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: - -```json -"id": 1, # ID in OMERO -"name": "example.tif", # Name as shown in the UI -"version": "0.2", # Current version -"channels": [ # Array matching the c dimension size - { - "active": true, - "coefficient": 1, - "color": "0000FF", - "family": "linear", - "inverted": false, - "label": "LaminB1", - "window": { - "end": 1500, - "max": 65535, - "min": 0, - "start": 0 - } - } -], -"rdefs": { - "defaultT": 0, # First timepoint to show the user - "defaultZ": 118, # First Z section to show the user - "model": "color" # "color" or "greyscale" -} -``` - -See https://docs.openmicroscopy.org/omero/5.6.1/developers/Web/WebGateway.html#imgdata -for more information. - -"labels" metadata {#labels-md} ------------------------------- - -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: - -```json -{ - "labels": [ - "orphaned/0" - ] -} -``` - -Unlisted groups MAY be labels. - -"image-label" metadata {#label-md} ----------------------------------- - -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-value`s 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). - - -```json -"image-label": - { - "version": "0.2", - "colors": [ - { - "label-value": 1, - "rgba": [255, 255, 255, 0] - }, - { - "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": "../../" - } -] -``` - -"plate" metadata {#plate-md} ----------------------------- - -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. If not empty, it MUST contain a `name` key specifying the - column name.
-
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. If not empty, it MUST contain a `name` key specifying the row - name.
-
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.
-
- -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 acquisition. - -```json -"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.2", - "wells": [ - { - "path": "2020-10-10/A/1" - }, - { - "path": "2020-10-10/A/2" - }, - { - "path": "2020-10-10/A/3" - }, - { - "path": "2020-10-10/B/1" - }, - { - "path": "2020-10-10/B/2" - }, - { - "path": "2020-10-10/B/3" - } - ] - } -``` - -"well" metadata {#well-md} --------------------------- - -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 - SHOULD 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.
-
- -For example the following JSON object defines a well with four fields of -views. 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. - -```json -"well": { - "images": [ - { - "acquisition": 1, - "path": "0" - }, - { - "acquisition": 1, - "path": "1" - }, - { - "acquisition": 2, - "path": "2" - }, - { - "acquisition": 2, - "path": "3" - } - ], - "version": "0.2" - } -``` - -Implementations {#implementations} -================================== - -Projects which support reading and/or writing OME-NGFF data include: - -
- -
[bigdataviewer-ome-zarr](https://github.com/mobie/bigdataviewer-ome-zarr)
-
Fiji-plugin for reading OME-Zarr.
- -
[bioformats2raw](https://github.com/glencoesoftware/bioformats2raw)
-
A performant, Bio-Formats image file format converter.
- -
[omero-ms-zarr](https://github.com/ome/omero-ms-zarr)
-
A microservice for OMERO.server that converts images stored in OMERO to OME-Zarr files on the fly, served via a web API.
- -
[idr-zarr-tools](https://github.com/IDR/idr-zarr-tools)
-
A full workflow demonstrating the conversion of IDR images to OME-Zarr images on S3.
- -
[OMERO CLI Zarr plugin](https://github.com/ome/omero-cli-zarr)
-
An OMERO CLI plugin that converts images stored in OMERO.server into a local Zarr file.
- -
[ome-zarr-py](https://github.com/ome/ome-zarr-py)
-
A napari plugin for reading ome-zarr files.
- -
[vizarr](https://github.com/hms-dbmi/vizarr/)
-
A minimal, purely client-side program for viewing Zarr-based images with Viv & ImJoy.
- -
- -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](https://downloads.openmicroscopy.org/presentations/2020/Dundee/Workshops/NGFF/zarr_diagram/). -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](https://github.com/ome/ngff) repository. - -Citing {#citing} -================ - -[Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.](https://ngff.openmicroscopy.org/0.2) -J. Moore, *et al*. Open Microscopy Environment Consortium, 29 March, 2021. -This edition of the specification is [https://ngff.openmicroscopy.org/0.2/](https://ngff.openmicroscopy.org/0.2/]). -The latest edition is available at [https://ngff.openmicroscopy.org/latest/](https://ngff.openmicroscopy.org/latest/). -[(doi:10.5281/zenodo.4282107)](https://doi.org/10.5281/zenodo.4282107) - -Version History {#history} -========================== - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RevisionDateDescription
0.2.02021-03-29Change chunk dimension separator to "/"
0.1.42020-11-26Add HCS specification
0.1.32020-09-14Add labels specification
0.1.2 2020-05-07Add description of "omero" metadata
0.1.1 2020-05-06Add info on the ordering of resolutions
0.1.0 2020-04-20First version for internal demo
- - -
-{
-  "blogNov2020": {
-    "href": "https://blog.openmicroscopy.org/file-formats/community/2020/11/04/zarr-data/",
-    "title": "Public OME-Zarr data (Nov. 2020)",
-    "authors": [
-      "OME Team"
-    ],
-    "status": "Informational",
-    "publisher": "OME",
-    "id": "blogNov2020",
-    "date": "04 November 2020"
-  },
-  "imagesc26952": {
-    "href": "https://forum.image.sc/t/ome-s-position-regarding-file-formats/26952",
-    "title": "OME’s position regarding file formats",
-    "authors": [
-      "OME Team"
-    ],
-    "status": "Informational",
-    "publisher": "OME",
-    "id": "imagesc26952",
-    "date": "19 June 2020"
-  },
-  "n5": {
-    "id": "n5",
-    "href": "https://github.com/saalfeldlab/n5/issues/62",
-    "title": "N5---a scalable Java API for hierarchies of chunked n-dimensional tensors and structured meta-data",
-    "status": "Informational",
-    "authors": [
-      "John A. Bogovic",
-      "Igor Pisarev",
-      "Philipp Hanslovsky",
-      "Neil Thistlethwaite",
-      "Stephan Saalfeld"
-    ],
-    "date": "2020"
-  },
-  "ome-zarr-py": {
-    "id": "ome-zarr-py",
-    "href": "https://doi.org/10.5281/zenodo.4113931",
-    "title": "ome-zarr-py: Experimental implementation of next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.",
-    "status": "Informational",
-    "publisher": "Zenodo",
-    "authors": [
-      "OME",
-      "et al"
-    ],
-    "date": "06 October 2020"
-  },
-  "zarr": {
-    "id": "zarr",
-    "href": "https://doi.org/10.5281/zenodo.4069231",
-    "title": "Zarr: An implementation of chunked, compressed, N-dimensional arrays for Python.",
-    "status": "Informational",
-    "publisher": "Zenodo",
-    "authors": [
-      "Alistair Miles",
-      "et al"
-    ],
-    "date": "06 October 2020"
-  }
-}
-
diff --git a/0.2/schemas/image.schema b/0.2/schemas/image.schema deleted file mode 100644 index 6eb26274..00000000 --- a/0.2/schemas/image.schema +++ /dev/null @@ -1,101 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "http://localhost:8000/image.schema", - "title": "NGFF Image", - "description": "JSON from OME-NGFF .zattrs", - "type": "object", - "properties": { - "multiscales": { - "description": "The multiscale datasets for this image", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "datasets": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - }, - "required": ["path"] - } - }, - "version": { - "type": "string", - "enum": [ - "0.2" - ] - } - }, - "required": [ - "datasets" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "omero": { - "type": "object", - "properties": { - "channels": { - "type": "array", - "items": { - "type": "object", - "properties": { - "window": { - "type": "object", - "properties": { - "end": { - "type": "number" - }, - "max": { - "type": "number" - }, - "min": { - "type": "number" - }, - "start": { - "type": "number" - } - }, - "required": [ - "start", - "min", - "end", - "max" - ] - }, - "label": { - "type": "string" - }, - "family": { - "type": "string" - }, - "color": { - "type": "string" - }, - "active": { - "type": "boolean" - } - }, - "required": [ - "window", - "color" - ] - } - } - }, - "required": [ - "channels" - ] - } - }, - "required": [ "multiscales" ] -} diff --git a/0.2/schemas/plate.schema b/0.2/schemas/plate.schema deleted file mode 100644 index e30b1662..00000000 --- a/0.2/schemas/plate.schema +++ /dev/null @@ -1,119 +0,0 @@ -{ - "$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 deleted file mode 100644 index 8dca3290..00000000 --- a/0.2/schemas/well.schema +++ /dev/null @@ -1,47 +0,0 @@ -{ - "$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.2/tests/test_validation.py b/0.2/tests/test_validation.py deleted file mode 100644 index 80decdf4..00000000 --- a/0.2/tests/test_validation.py +++ /dev/null @@ -1,44 +0,0 @@ -import json -import glob - -import pytest - -from jsonschema import validate -from jsonschema.exceptions import ValidationError - - -def files(): - return list(glob.glob(f"examples/*/valid/*.json")) + \ - list(glob.glob(f"examples/*/invalid/*.json")) - -def ids(): - return [str(x).split("/")[-1][0:-5] for x in files()] - - -@pytest.mark.parametrize("testfile", files(), ids=ids()) -def test_json(testfile): - - if "invalid" in testfile: - with pytest.raises(ValidationError): - json_schema(testfile) - else: - json_schema(testfile) - - -def json_schema(path): - # Load the correct schema - with open(path) as f: - test_json = json.loads(f.read()) - # we don't have @type in this version - if "multiscales" in test_json: - schema_name = "image.schema" - elif "plate" in test_json: - schema_name = "plate.schema" - elif "well" in test_json: - schema_name = "well.schema" - else: - raise Exception("No schema found") - - with open('schemas/' + schema_name) as f: - schema = json.loads(f.read()) - validate(instance=test_json, schema=schema) diff --git a/0.2/tox.ini b/0.2/tox.ini deleted file mode 100644 index 5f9175d3..00000000 --- a/0.2/tox.ini +++ /dev/null @@ -1,10 +0,0 @@ -[tox] -envlist = v02 -skipsdist = True - -[testenv] -deps = - pytest - jsonschema -commands = - pytest tests --color=yes --basetemp={envtmpdir} {posargs:-v} diff --git a/0.3/copyright.include b/0.3/copyright.include deleted file mode 100644 index f0def708..00000000 --- a/0.3/copyright.include +++ /dev/null @@ -1,4 +0,0 @@ -Copyright © 2020-[YEAR] -OME® -(U. Dundee). -OME trademark rules apply. diff --git a/0.3/examples/image/invalid/invalid_axes.json b/0.3/examples/image/invalid/invalid_axes.json deleted file mode 100644 index 74fb909d..00000000 --- a/0.3/examples/image/invalid/invalid_axes.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "@id": "#my-image", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "#my-pyramid", - "version": "0.3", - "name": "example", - "datasets": [ - { - "@id": "#my-full-resolution", - "path": "path/to/0" - } - ], - "axes": [ - "z", - "y", - "ct" - ] - } - ] -} diff --git a/0.3/examples/image/invalid/invalid_axes_count.json b/0.3/examples/image/invalid/invalid_axes_count.json deleted file mode 100644 index b79d5ee2..00000000 --- a/0.3/examples/image/invalid/invalid_axes_count.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "@id": "#my-image", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "#my-pyramid", - "version": "0.3", - "name": "example", - "datasets": [ - { - "@id": "#my-full-resolution", - "path": "path/to/0" - } - ], - "axes": [ - "y" - ] - } - ] -} \ No newline at end of file diff --git a/0.3/examples/image/invalid/invalid_axes_order.json b/0.3/examples/image/invalid/invalid_axes_order.json deleted file mode 100644 index d27e3e8a..00000000 --- a/0.3/examples/image/invalid/invalid_axes_order.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "@id": "#my-image", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "#my-pyramid", - "version": "0.3", - "name": "example", - "datasets": [ - { - "@id": "#my-full-resolution", - "path": "path/to/0" - } - ], - "axes": [ - "y", - "t", - "c" - ] - } - ] -} \ No newline at end of file diff --git a/0.3/examples/image/invalid/invalid_channels_color.json b/0.3/examples/image/invalid/invalid_channels_color.json deleted file mode 100644 index 6c6990c0..00000000 --- a/0.3/examples/image/invalid/invalid_channels_color.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.3", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ], - "axes": [ - "z", - "y", - "x" - ] - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": 255, - "family": "linear", - "label": "1234", - "window": { - "end": 1765.0, - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ] - } -} diff --git a/0.3/examples/image/invalid/invalid_channels_window.json b/0.3/examples/image/invalid/invalid_channels_window.json deleted file mode 100644 index 9c198f02..00000000 --- a/0.3/examples/image/invalid/invalid_channels_window.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.3", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ], - "axes": [ - "z", - "y", - "x" - ] - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": "ff0000", - "family": "linear", - "label": "1234", - "window": { - "end": "100", - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ] - } -} diff --git a/0.3/examples/image/invalid/invalid_path.json b/0.3/examples/image/invalid/invalid_path.json deleted file mode 100644 index 1c517fb8..00000000 --- a/0.3/examples/image/invalid/invalid_path.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.3", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - }, - { - "path": 0 - } - ], - "axes": [ - "z", - "y", - "x" - ] - } - ] -} diff --git a/0.3/examples/image/invalid/invalid_version.json b/0.3/examples/image/invalid/invalid_version.json deleted file mode 100644 index ba995783..00000000 --- a/0.3/examples/image/invalid/invalid_version.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "invalid", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - }, - { - "path": "1" - }, - { - "path": "2" - } - ], - "axes": [ - "z", - "y", - "x" - ] - } - ] -} \ No newline at end of file diff --git a/0.3/examples/image/invalid/missing_axes.json b/0.3/examples/image/invalid/missing_axes.json deleted file mode 100644 index 5c1ebc4b..00000000 --- a/0.3/examples/image/invalid/missing_axes.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.3", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ] - } - ] -} \ No newline at end of file diff --git a/0.3/examples/image/invalid/missing_datasets.json b/0.3/examples/image/invalid/missing_datasets.json deleted file mode 100644 index bcf96e46..00000000 --- a/0.3/examples/image/invalid/missing_datasets.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.3", - "name": "example", - "axes": [ - "z", - "y", - "x" - ] - } - ] -} diff --git a/0.3/examples/image/invalid/missing_path.json b/0.3/examples/image/invalid/missing_path.json deleted file mode 100644 index 36439fa2..00000000 --- a/0.3/examples/image/invalid/missing_path.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.3", - "name": "example", - "datasets": [ - { - "foo": "path/to/0" - }, - { - "path": "1" - } - ], - "axes": [ - "z", - "y", - "x" - ] - } - ] -} diff --git a/0.3/examples/image/invalid/no_axes.json b/0.3/examples/image/invalid/no_axes.json deleted file mode 100644 index 7bc397bb..00000000 --- a/0.3/examples/image/invalid/no_axes.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.3", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ], - "axes": [] - } - ] -} diff --git a/0.3/examples/image/invalid/no_datasets.json b/0.3/examples/image/invalid/no_datasets.json deleted file mode 100644 index 31537f03..00000000 --- a/0.3/examples/image/invalid/no_datasets.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.3", - "name": "example", - "datasets": [], - "axes": [ - "z", - "y", - "x" - ] - } - ] -} diff --git a/0.3/examples/image/invalid/no_multiscales.json b/0.3/examples/image/invalid/no_multiscales.json deleted file mode 100644 index d6dbfb33..00000000 --- a/0.3/examples/image/invalid/no_multiscales.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [] -} diff --git a/0.3/examples/image/valid/image.json b/0.3/examples/image/valid/image.json deleted file mode 100644 index ebcb882d..00000000 --- a/0.3/examples/image/valid/image.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "datasets": [ - {"path": "path/to/0"}, - {"path": "1"}, - {"path": "2"} - ], - "axes": [ - "z", "y", "x" - ] - } - ] -} diff --git a/0.3/examples/image/valid/image_metadata.json b/0.3/examples/image/valid/image_metadata.json deleted file mode 100644 index 7f1e2ffd..00000000 --- a/0.3/examples/image/valid/image_metadata.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "@id": "top", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "inner", - "version": "0.3", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": [ - "true", - "false" - ], - "kwargs": { - "multichannel": true - } - }, - "axes": [ - "z", - "y", - "x" - ] - } - ] -} diff --git a/0.3/examples/image/valid/image_omero.json b/0.3/examples/image/valid/image_omero.json deleted file mode 100644 index 775dc2dc..00000000 --- a/0.3/examples/image/valid/image_omero.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "@id": "#my-image", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "#my-pyramid", - "version": "0.3", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - }, - { - "path": "1" - }, - { - "path": "2" - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": [ - "true", - "false" - ], - "kwargs": { - "multichannel": true - } - }, - "axes": [ - "z", - "y", - "x" - ] - } - ], - "omero": { - "id": 1, - "version": "0.3", - "channels": [ - { - "active": true, - "color": "0000FF", - "family": "linear", - "inverted": false, - "label": "1234", - "window": { - "end": 1765.0, - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ], - "rdefs": { - "defaultZ": 0, - "defaultT": 0, - "model": "color" - } - } -} diff --git a/0.3/examples/image/valid/missing_name.json b/0.3/examples/image/valid/missing_name.json deleted file mode 100644 index 22697e44..00000000 --- a/0.3/examples/image/valid/missing_name.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.3", - "datasets": [ - { - "path": "path/to/0" - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": [ - "true", - "false" - ], - "kwargs": { - "multichannel": true - } - }, - "axes": [ - "z", - "y", - "x" - ] - } - ] -} diff --git a/0.3/examples/image/valid/missing_version.json b/0.3/examples/image/valid/missing_version.json deleted file mode 100644 index df165311..00000000 --- a/0.3/examples/image/valid/missing_version.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ], - "axes": [ - "z", - "y", - "x" - ] - } - ] -} diff --git a/0.3/examples/plate/valid/plate.json b/0.3/examples/plate/valid/plate.json deleted file mode 100644 index d06552f3..00000000 --- a/0.3/examples/plate/valid/plate.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "plate": { - "columns": [ - { - "name": "1" - }, - { - "name": "2" - }, - { - "name": "3" - } - ], - "field_count": 1, - "name": "plate name", - "rows": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "version": "0.3", - "wells": [ - { - "path": "A/3" - }, - { - "path": "B/2" - }, - { - "path": "A/1" - }, - { - "path": "B/3" - } - ] - } -} \ No newline at end of file diff --git a/0.3/examples/well/valid/well.json b/0.3/examples/well/valid/well.json deleted file mode 100644 index e4efac11..00000000 --- a/0.3/examples/well/valid/well.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "well": { - "images": [ - { - "acquisition": 0, - "path": "0" - }, - { - "acquisition": 3, - "path": "1" - } - ], - "version": "0.3" - } -} \ No newline at end of file diff --git a/0.3/index.bs b/0.3/index.bs deleted file mode 100644 index f8b3550e..00000000 --- a/0.3/index.bs +++ /dev/null @@ -1,700 +0,0 @@ - - - -Introduction {#intro} -===================== - -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. - - -Why "NGFF"? {#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](https://pydata.org/) community, the Zarr [[zarr]] format was developed -for easily storing collections of [NumPy](https://numpy.org/) arrays. In the -[ImageJ](https://imagej.net/) 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](https://zarr-specs.readthedocs.io/en/core-protocol-v3.0-dev/protocol/core/v3.0.html) -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)](https://github.com/zarr-developers/zarr-specs/issues/101) phase with the goal of having a first version early in 2021. As that -process comes to an end, this document will be updated. - -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](http://www.openmicroscopy.org/ome-files/) -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, -for all examples. - -On-disk (or in-cloud) layout {#on-disk} -======================================= - -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 -be stored on a web server to be accessed via HTTP or in object storage -like S3 or GCS. - -Images {#image-layout} ----------------------- - -The following layout describes the expected Zarr hierarchy for images with -multiple levels of resolutions and optionally associated labels. - -``` -. # Root folder, potentially in S3, -│ # with a flat list of images by image ID. -│ -├── 123.zarr # One image (id=123) converted to Zarr. -│ -└── 456.zarr # Another image (id=456) converted to Zarr. - │ - ├── .zgroup # Each image is a Zarr group, or a folder, of other groups and arrays. - ├── .zattrs # Group level attributes are stored in the .zattrs file and include - │ # "multiscales" and "omero" (see below). In addition, the group level attributes - │ # must also contain "_ARRAY_DIMENSIONS" if this group directly contains multi-scale arrays. - │ - ├── 0 # Each multiscale level is stored as a separate Zarr array, - │ ... # which is a folder containing chunk files which compose the array. - ├── n # The name of the array is arbitrary with the ordering defined by - │ │ # by the "multiscales" metadata, but is often a sequence starting at 0. - │ │ - │ ├── .zarray # All image arrays must be up to 5-dimensional - │ │ # with dimension order (t, c, z, y, x). - │ │ - │ └─ t # Chunks are stored with the nested directory layout. - │ └─ c # All but the last chunk element are stored as directories. - │ └─ z # The terminal chunk is a file. Together the directory and file names - │ └─ y # provide the "chunk coordinate" (t, c, z, y, x), where the maximum coordinate - │ └─ 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 `.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. - │ - └── 0 # Multiscale, labeled image. The name is unimportant but is registered in the "labels" group above. - ├── .zgroup # Zarr Group which is both a multiscaled image as well as a labeled image. - ├── .zattrs # Metadata of the related image and as well as display information under the "image-label" key. - │ - ├── 0 # Each multiscale level is stored as a separate Zarr array, as above, but only integer values - │ ... # are supported. - └── n -``` - -High-content screening {#hcs-layout} ------------------------------------- - -The following specification defines the hierarchy for a high-content screening -dataset. Three groups must be defined above the images: - -- the group above the images defines the well and MUST implement the - [well specification](#well-md). All images contained in a well are fields - of view of the same well -- the group above the well defines a row of wells -- the group above the well row defines an entire plate i.e. a two-dimensional - collection of wells organized in rows and columns. It MUST implement the - [plate specification](#plate-md) - - -``` -. # Root folder, potentially in S3, -│ -└── 5966.zarr # One plate (id=5966) converted to Zarr - ├── .zgroup - ├── .zattrs # Implements "plate" specification - ├── A # First row of the plate - │ ├── .zgroup - │ │ - │ ├── 1 # First column of row A - │ │ ├── .zgroup - │ │ ├── .zattrs # Implements "well" specification - │ │ │ - │ │ ├── 0 # First field of view of well A1 - │ │ │ │ - │ │ │ ├── .zgroup - │ │ │ ├── .zattrs # Implements "multiscales", "omero" - │ │ │ ├── 0 - │ │ │ │ ... # Resolution levels - │ │ │ ├── n - │ │ │ └── labels # Labels (optional) - │ │ ├── ... # Fields of view - │ │ └── m - │ ├── ... # Columns - │ └── 12 - ├── ... # Rows - └── H -``` - -Metadata {#metadata} -==================== - -The various `.zattrs` files throughout the above array hierarchy may contain metadata -keys as specified below for discovering certain types of data, especially images. - -"multiscales" metadata {#multiscale-md} ---------------------------------------- - -Metadata about the multiple resolution representations of the image can be -found under the "multiscales" key in the group-level metadata. - -"multiscales" contains a list of dictionaries where each entry describes a multiscale image. - -Each dictionary contained in the list MUST contain the field "datasets", which is a list of dictionaries describing -the arrays storing the individual resolution levels. -Each dictionary in "datasets" MUST contain the field "path", whose value contains the path to the array for this resolution relative -to the current zarr group. The "path"s MUST be ordered from largest (i.e. highest resolution) to smallest. - -It MUST contain the field "axes", which is a list of dimension names of the axes. -The values MUST be unique and one of `{"t", "c", "z", "y", "x"}`. -The number of values MUST be the same as the number of dimensions of the arrays corresponding to this image. -In addition, the "axes" values MUST be repeated in the field "_ARRAY_DIMENSIONS" of all scale groups -(i.e. groups containing arrays with the multiscale data). -This ensures compatibility with the [xarray zarr encoding](http://xarray.pydata.org/en/stable/internals/zarr-encoding-spec.html#zarr-encoding). - -It 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.3). - -It 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. - -```json -{ - "multiscales": [ - { - "version": "0.3", - "name": "example", - "datasets": [ - {"path": "0"}, - {"path": "1"}, - {"path": "2"} - ], - "axes": [ - "t", "c", "z", "y", "x" - ], - "type": "gaussian", - "metadata": { # the fields in metadata depend on the downscaling implementation - "method": "skimage.transform.pyramid_gaussian", # here, the parameters passed to the skimage function are given - "version": "0.16.1", - "args": "[true]", - "kwargs": {"multichannel": true} - } - } - ] -} -``` - -If only one multiscale is provided, use it. Otherwise, the user can choose by -name, using the first multiscale as a fallback: - -```python -datasets = [] -for named in multiscales: - if named["name"] == "3D": - datasets = [x["path"] for x in named["datasets"]] - break -if not datasets: - # Use the first by default. Or perhaps choose based on chunk size. - datasets = [x["path"] for x in multiscales[0]["datasets"]] -``` - -"omero" metadata {#omero-md} ----------------------------- - -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: - -```json -"id": 1, # ID in OMERO -"name": "example.tif", # Name as shown in the UI -"version": "0.3", # Current version -"channels": [ # Array matching the c dimension size - { - "active": true, - "coefficient": 1, - "color": "0000FF", - "family": "linear", - "inverted": false, - "label": "LaminB1", - "window": { - "end": 1500, - "max": 65535, - "min": 0, - "start": 0 - } - } -], -"rdefs": { - "defaultT": 0, # First timepoint to show the user - "defaultZ": 118, # First Z section to show the user - "model": "color" # "color" or "greyscale" -} -``` - -See https://docs.openmicroscopy.org/omero/5.6.1/developers/Web/WebGateway.html#imgdata -for more information. - -"labels" metadata {#labels-md} ------------------------------- - -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: - -```json -{ - "labels": [ - "orphaned/0" - ] -} -``` - -Unlisted groups MAY be labels. - -"image-label" metadata {#label-md} ----------------------------------- - -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-value`s 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). - - -```json -"image-label": - { - "version": "0.3", - "colors": [ - { - "label-value": 1, - "rgba": [255, 255, 255, 0] - }, - { - "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": "../../" - } -] -``` - -"plate" metadata {#plate-md} ----------------------------- - -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. If not empty, it MUST contain a `name` key specifying the - column name.
-
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. If not empty, it MUST contain a `name` key specifying the row - name.
-
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.
-
- -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 acquisition. - -```json -"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.3", - "wells": [ - { - "path": "2020-10-10/A/1" - }, - { - "path": "2020-10-10/A/2" - }, - { - "path": "2020-10-10/A/3" - }, - { - "path": "2020-10-10/B/1" - }, - { - "path": "2020-10-10/B/2" - }, - { - "path": "2020-10-10/B/3" - } - ] - } -``` - -"well" metadata {#well-md} --------------------------- - -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 - SHOULD 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.
-
- -For example the following JSON object defines a well with four fields of -views. 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. - -```json -"well": { - "images": [ - { - "acquisition": 1, - "path": "0" - }, - { - "acquisition": 1, - "path": "1" - }, - { - "acquisition": 2, - "path": "2" - }, - { - "acquisition": 2, - "path": "3" - } - ], - "version": "0.3" - } -``` - -Implementations {#implementations} -================================== - -Projects which support reading and/or writing OME-NGFF data include: - -
- -
[omero-ms-zarr](https://github.com/ome/omero-ms-zarr)
-
A microservice for OMERO.server that converts images stored in OMERO to OME Zarr files on the fly, served via a web API.
- -
[idr-zarr-tools](https://github.com/IDR/idr-zarr-tools)
-
A full workflow demonstrating the conversion of IDR images to OME Zarr images on S3.
- -
[OMERO CLI Zarr plugin](https://github.com/ome/omero-cli-zarr)
-
An OMERO CLI plugin that converts images stored in OMERO.server into a local Zarr file.
- -
[ome-zarr-py](https://github.com/ome/ome-zarr-py)
-
A napari plugin for reading ome-zarr files.
- -
[bioformats2raw](https://github.com/glencoesoftware/bioformats2raw)
-
A performant, Bio-Formats image file format converter.
- -
[vizarr](https://github.com/hms-dbmi/vizarr/)
-
A minimal, purely client-side program for viewing Zarr-based images with Viv & ImJoy.
- -
- -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](https://downloads.openmicroscopy.org/presentations/2020/Dundee/Workshops/NGFF/zarr_diagram/). -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](https://github.com/ome/ngff) repository. - -Citing {#citing} -================ - -[Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.](https://ngff.openmicroscopy.org/0.3) -J. Moore, *et al*. Open Microscopy Environment Consortium, 20 November 2020. -This edition of the specification is [https://ngff.openmicroscopy.org/0.3/](https://ngff.openmicroscopy.org/0.3/]). -The latest edition is available at [https://ngff.openmicroscopy.org/latest/](https://ngff.openmicroscopy.org/latest/). -[(doi:10.5281/zenodo.4282107)](https://doi.org/10.5281/zenodo.4282107) - -Version History {#history} -========================== - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RevisionDateDescription
0.3.02021-08-24Add axes field to multiscale metadata
0.2.02021-03-29Change chunk dimension separator to "/"
0.1.42020-11-26Add HCS specification
0.1.32020-09-14Add labels specification
0.1.2 2020-05-07Add description of "omero" metadata
0.1.1 2020-05-06Add info on the ordering of resolutions
0.1.0 2020-04-20First version for internal demo
- - -
-{
-  "blogNov2020": {
-    "href": "https://blog.openmicroscopy.org/file-formats/community/2020/11/04/zarr-data/",
-    "title": "Public OME-Zarr data (Nov. 2020)",
-    "authors": [
-      "OME Team"
-    ],
-    "status": "Informational",
-    "publisher": "OME",
-    "id": "blogNov2020",
-    "date": "04 November 2020"
-  },
-  "imagesc26952": {
-    "href": "https://forum.image.sc/t/ome-s-position-regarding-file-formats/26952",
-    "title": "OME’s position regarding file formats",
-    "authors": [
-      "OME Team"
-    ],
-    "status": "Informational",
-    "publisher": "OME",
-    "id": "imagesc26952",
-    "date": "19 June 2020"
-  },
-  "n5": {
-    "id": "n5",
-    "href": "https://github.com/saalfeldlab/n5/issues/62",
-    "title": "N5---a scalable Java API for hierarchies of chunked n-dimensional tensors and structured meta-data",
-    "status": "Informational",
-    "authors": [
-      "John A. Bogovic",
-      "Igor Pisarev",
-      "Philipp Hanslovsky",
-      "Neil Thistlethwaite",
-      "Stephan Saalfeld"
-    ],
-    "date": "2020"
-  },
-  "ome-zarr-py": {
-    "id": "ome-zarr-py",
-    "href": "https://doi.org/10.5281/zenodo.4113931",
-    "title": "ome-zarr-py: Experimental implementation of next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.",
-    "status": "Informational",
-    "publisher": "Zenodo",
-    "authors": [
-      "OME",
-      "et al"
-    ],
-    "date": "06 October 2020"
-  },
-  "zarr": {
-    "id": "zarr",
-    "href": "https://doi.org/10.5281/zenodo.4069231",
-    "title": "Zarr: An implementation of chunked, compressed, N-dimensional arrays for Python.",
-    "status": "Informational",
-    "publisher": "Zenodo",
-    "authors": [
-      "Alistair Miles",
-      "et al"
-    ],
-    "date": "06 October 2020"
-  }
-}
-
diff --git a/0.3/schemas/image.schema b/0.3/schemas/image.schema deleted file mode 100644 index afc2bd16..00000000 --- a/0.3/schemas/image.schema +++ /dev/null @@ -1,109 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.3/schemas/image.schema", - "title": "NGFF Image", - "description": "JSON from OME-NGFF .zattrs", - "type": "object", - "properties": { - "multiscales": { - "description": "The multiscale datasets for this image", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "datasets": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - } - }, - "required": ["path"] - } - }, - "version": { - "type": "string", - "enum": [ - "0.3" - ] - }, - "axes": { - "type": "array", - "minItems": 2, - "items": { - "type": "string", - "pattern": "^[xyzct]$" - } - } - }, - "required": [ - "datasets", "axes" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "omero": { - "type": "object", - "properties": { - "channels": { - "type": "array", - "items": { - "type": "object", - "properties": { - "window": { - "type": "object", - "properties": { - "end": { - "type": "number" - }, - "max": { - "type": "number" - }, - "min": { - "type": "number" - }, - "start": { - "type": "number" - } - }, - "required": [ - "start", - "min", - "end", - "max" - ] - }, - "label": { - "type": "string" - }, - "family": { - "type": "string" - }, - "color": { - "type": "string" - }, - "active": { - "type": "boolean" - } - }, - "required": [ - "window", - "color" - ] - } - } - }, - "required": [ - "channels" - ] - } - }, - "required": [ "multiscales" ] -} diff --git a/0.3/schemas/jsonld/context.json b/0.3/schemas/jsonld/context.json deleted file mode 100644 index 0341b30f..00000000 --- a/0.3/schemas/jsonld/context.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "@context": { - "@vocab" : "http://localhost:8000/context.json#", - "ngff" : "http://localhost:8000/context.json#" - } -} diff --git a/0.3/schemas/jsonld/frame.json b/0.3/schemas/jsonld/frame.json deleted file mode 100644 index 092ff3f6..00000000 --- a/0.3/schemas/jsonld/frame.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "@context": { - "@vocab" : "http://localhost:8000/context.json#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "ngff" : "http://localhost:8000/context.json#", - "ngff:multiscales": { - "@container": "@set" - }, - "ngff:datasets": { - "@container": "@set" - }, - "ngff:end": { - "@type": "xsd:decimal" - } - }, - "@type": "Image", - "multiscales": { - "@type": { - "@default": "Multiscale" - }, - "datasets" : { - "@type": { - "@default": "Dataset" - } - } - }, - "omero": { - "@type": { - "@default": "omero" - }, - "channels": { - "@type": { - "@default": "Channel" - }, - "window": { - "@type": { - "@default": "Window" - } - } - } - } -} diff --git a/0.3/schemas/jsonld/shacl.ttl b/0.3/schemas/jsonld/shacl.ttl deleted file mode 100644 index 02cb213b..00000000 --- a/0.3/schemas/jsonld/shacl.ttl +++ /dev/null @@ -1,210 +0,0 @@ -@prefix xsd: . -@prefix rdf: . -@prefix dash: . -@prefix sh: . -@prefix schema: . -@prefix ngff: . - -# Collection of wrapped Multiscale objects -schema:TopLevelImageShape a sh:NodeShape; - - sh:targetClass ngff:Image; - sh:closed true ; - sh:ignoredProperties ( rdf:type ) ; - - sh:property [ - sh:path ngff:multiscales; - sh:node dash:ListShape; - sh:property [ - sh:path ([sh:zeroOrMorePath rdf:rest] rdf:first); - sh:datatype schema:Multiscale_Shape; - ]; - sh:minCount 1; - ]; - - sh:property [ - sh:path ngff:omero; - sh:node schema:omero_Shape; - ]. - - -# -# Contents of the "multiscales" array (NOT YET USED) -# -schema:Multiscale_Wrapper a sh:NodeShape; - - sh:targetClass ngff:ListItem; - sh:closed true ; - sh:ignoredProperties ( rdf:type ) ; - - sh:property [ - sh:path ngff:item ; - ] ; - sh:property [ - sh:path ngff:position; - sh:datatype xsd:integer ; - ] . - - -# -# Contents of the "multiscales" array -# -schema:Multiscale_Shape a sh:NodeShape; - - sh:targetClass ngff:Multiscale; - - sh:property [ - sh:path ngff:name; - sh:datatype xsd:string; - ]; - - sh:property [ - sh:path ngff:version; - sh:datatype xsd:string; - sh:pattern "0.3"; - ]; - - sh:property [ - sh:path ngff:datasets; - sh:node dash:ListShape; - sh:property [ - sh:path ([sh:zeroOrMorePath rdf:rest] rdf:first); - sh:datatype schema:Dataset_Shape; - ]; - sh:minCount 1; - ]; - - sh:property [ - sh:path ngff:axes; - sh:node dash:ListShape; - sh:property [ - sh:path ([sh:zeroOrMorePath rdf:rest] rdf:first); - ]; - sh:minCount 2; - sh:pattern "^[xyzct]$"; - sh:datatype xsd:string; - ] ; - - sh:property [ - sh:path ngff:type; - sh:datatype xsd:string; - ] ; - - sh:property [ - sh:path ngff:metadata; - ] . - -schema:omero_Shape a sh:NodeShape; - - sh:targetClass ngff:omero; - sh:closed true ; - sh:ignoredProperties ( rdf:type ) ; - - sh:property [ - sh:path ngff:id; - sh:datatype xsd:integer; - ] ; - - sh:property [ - sh:path ngff:version; - sh:datatype xsd:string; - ] ; - - sh:property [ - sh:path ngff:channels; - sh:node dash:ListShape; - sh:property [ - sh:path ([sh:zeroOrMorePath rdf:rest] rdf:first); - sh:datatype schema:Channel_Shape; - ]; - sh:minCount 1; - ] ; - - sh:property [ - sh:path ngff:rdefs; - sh:node schema:RDef_Shape; - ]. - -schema:RDef_Shape a sh:NodeShape; - - sh:property [ - sh:path ngff:model; - sh:datatype xsd:string; - ] ; - - sh:property [ - sh:path ngff:defaultZ; - sh:datatype xsd:integer; - ] ; - - sh:property [ - sh:path ngff:defaultT; - sh:datatype xsd:integer; - ] . - -# -# Contents of the "datasets" array -# -schema:Dataset_Shape a sh:NodeShape; - - sh:targetClass ngff:Dataset; - sh:closed true ; - sh:ignoredProperties ( rdf:type ) ; - - sh:property [ - sh:path ngff:path; - sh:datatype xsd:string; - sh:minCount 1; - ]. - -schema:Channel_Shape a sh:NodeShape; - sh:targetClass ngff:Channel; - sh:property [ - sh:path ngff:window; - sh:node schema:window_Shape; - sh:minCount 1; - ]; - sh:property [ - sh:path ngff:label; - sh:datatype xsd:string; - ]; - sh:property [ - sh:path ngff:family; - sh:datatype xsd:string; - ]; - sh:property [ - sh:path ngff:color; - sh:datatype xsd:string; - sh:minCount 1; - ]; - sh:property [ - sh:path ngff:active; - sh:datatype xsd:boolean; - ]; - sh:property [ - sh:path ngff:inverted; - sh:datatype xsd:boolean; - ]. - -schema:window_Shape a sh:NodeShape; - sh:targetClass ngff:Window; - sh:property [ - sh:path ngff:end; - sh:datatype xsd:double; - sh:minCount 1; - ]; - sh:property [ - sh:path ngff:max; - sh:datatype xsd:double; - sh:minCount 1; - ]; - sh:property [ - sh:path ngff:min; - sh:datatype xsd:double; - sh:minCount 1; - ]; - sh:property [ - sh:path ngff:start; - sh:datatype xsd:double; - sh:minCount 1; - ]. diff --git a/0.3/schemas/plate.schema b/0.3/schemas/plate.schema deleted file mode 100644 index 1222d895..00000000 --- a/0.3/schemas/plate.schema +++ /dev/null @@ -1,119 +0,0 @@ -{ - "$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/salad_schema/image.yml b/0.3/schemas/salad_schema/image.yml deleted file mode 100644 index b22e4dee..00000000 --- a/0.3/schemas/salad_schema/image.yml +++ /dev/null @@ -1,213 +0,0 @@ -$base: "https://ngff.openmicroscopy.org/latest/" - -$namespaces: - ngff: "https://ngff.openmicroscopy.org/latest/" - -$graph: - -- name: DatasetMetadata - doc: | - Optional information about a Dataset. - type: record - fields: - version: - type: string - jsonldPredicate: '#version' - args: - type: - type: array - items: string - kwargs: - type: Any - method: - type: string - -- name: OmeroMetadata - doc: | - Optional rendering info for an Image. - type: record - fields: - version: - type: string - jsonldPredicate: '#version' - channels: - type: - type: array - items: ChannelMetadata - id: int - rdefs: - type: RdefMetadata - -- name: ChannelMetadata - doc: | - Rendering info for a Channel. - type: record - fields: - active: boolean? - coefficient: float? - color: string? - family: string? - inverted: boolean? - label: string? - window: WindowMetadata - -- name: WindowMetadata - doc: | - Rendering Window for a Channel. - type: record - fields: - start: float - end: float - min: float? - max: float? - -- name: RdefMetadata - doc: | - Rendering Rdef for an Image. - type: record - fields: - defaultT: int - defaultZ: int - model: string - -# This causes "SchemaException: Predicate collision on name" with Multiscale/name -# - name: CreatorMetadata -# doc: | -# Creator info for an Image. -# type: record -# fields: -# name: string - -- name: Dataset - doc: | - One array series in descending order of size. - type: record - fields: - path: - type: string - -- name: Multiscale - doc: | - Identifies pyramid-like collections of arrays. - type: record - abstract: true - fields: - - name: name - type: [string, "null"] - - name: datasets - type: - type: array - items: Dataset - - name: metadata - type: [DatasetMetadata, "null"] - - name: type - type: [string, "null"] - - -- name: MultiscaleV2 - type: record - extends: [Multiscale] - fields: - - name: version - jsonldPredicate: '#version' - type: - type: enum - symbols: - - "0.2" - - -- name: MultiscaleV3 - type: record - extends: [Multiscale] - fields: - - name: version - jsonldPredicate: '#version' - type: - type: enum - symbols: - - "0.3" - - name: axes - type: - type: array - items: - type: enum - symbols: - - x - - y - - z - - c - - t - -- name: Image - doc: | - OME:Image - type: record - documentRoot: true - fields: - multiscales: - type: - type: array - items: Multiscale - omero: - type: [OmeroMetadata, "null"] - # _creator: [CreatorMetadata, "null"] - -- name: Label - doc: | - OME:Label - type: record - extends: [Image] - documentRoot: true - fields: - image-label: LabelMetadata - -- name: LabelMetadata - doc: | - Metadata for a Label - type: record - fields: - version: - type: string - jsonldPredicate: '#version' - source: SourceMetadata - colors: - type: - type: array - items: LabelColor - properties: - type: - type: array - items: LabelValueMetadata - -- name: SourceMetadata - doc: | - Source Image for a Label - type: record - fields: - image: string - -- name: LabelValueMetadata - doc: | - Specifies metadata for a specified label-value - type: record - abstract: true - fields: - label-value: int - -- name: LabelColor - doc: | - Specifies a color for a specified label-value - type: record - extends: [LabelValueMetadata] - fields: - rgba: - type: - type: array - items: int - -- name: LabelProperties - doc: | - Somewhere to store custom key-value pairs - type: record - extends: [LabelValueMetadata] - # How to do custom fields? - (anything goes) diff --git a/0.3/schemas/strict_image.schema b/0.3/schemas/strict_image.schema deleted file mode 100644 index 5e16b2a4..00000000 --- a/0.3/schemas/strict_image.schema +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$id": "https://ngff.openmicroscopy.org/0.3/schemas/strict_image.schema", - "allOf": [ - { - "$ref": "https://ngff.openmicroscopy.org/0.3/schemas/image.schema" - }, - { - "properties": { - "multiscales": { - "items": { - "required": [ - "version", "metadata", "type", "name" - ] - } - } - } - } - ] -} \ No newline at end of file diff --git a/0.3/schemas/well.schema b/0.3/schemas/well.schema deleted file mode 100644 index b88bc745..00000000 --- a/0.3/schemas/well.schema +++ /dev/null @@ -1,47 +0,0 @@ -{ - "$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.3/tests/test_frame.py b/0.3/tests/test_frame.py deleted file mode 100644 index 8aa406a0..00000000 --- a/0.3/tests/test_frame.py +++ /dev/null @@ -1,39 +0,0 @@ -import json -from pprint import pprint -from pyld import jsonld - - -with open("schemas/jsonld/frame.json") as o: - frame = json.load(o) - - -with open("examples/image/valid/image_metadata.json") as o: - data = json.load(o) - - -def frame_with_options(data, frame, options=None): - if options is None: - options = dict() - return jsonld.frame( - data, - frame, - options) - -def test_insertion(): - pprint(data) - data["@context"] = frame["@context"] - r = frame_with_options(data, frame) - pprint(r) - assert "@type" in r["ngff:multiscales"][0], r - assert "@type" in r["ngff:multiscales"][0]["ngff:datasets"][0], r - -def test_pass_context(): - pprint(data) - with open("schemas/jsonld/context.json") as o: - context = json.load(o) - r = frame_with_options(data, frame, options={ - "context": context, - }) - pprint(r) - assert "@type" in r["ngff:multiscales"][0], r - assert "@type" in r["ngff:multiscales"][0]["ngff:datasets"][0], r diff --git a/0.3/tests/test_validation.py b/0.3/tests/test_validation.py deleted file mode 100644 index 0d1ceff8..00000000 --- a/0.3/tests/test_validation.py +++ /dev/null @@ -1,173 +0,0 @@ -import os -import json -import glob - -import pytest - -from jsonschema import validate as js_valid -from jsonschema.exceptions import ValidationError as JSErr - -from pyld import jsonld -from pyshacl import validate as ld_valid -from rdflib import Graph - -from schema_salad.schema import load_schema, load_and_validate -from schema_salad.exceptions import ValidationException as SaladErr - - -class LDErr(Exception): - pass - - -@pytest.fixture(scope="session") -def httpserver_listen_address(): - return ("127.0.0.1", 8000) - - -def test_json(method, testfile, httpserver): - - for uri, filename in ( - ("/context.json", "schemas/jsonld/context.json"), - ("/image.schema", "schemas/image.schema"), - ): - with open(filename) as o: - httpserver.expect_request(uri).respond_with_data(o.read()) - - if "invalid" in testfile: - with pytest.raises((JSErr, LDErr, SaladErr)): - method(testfile) - if "invalid_axes_order" in testfile: - pytest.skip("not supported") - - else: - method(testfile) - - -def files(): - return list(glob.glob(f"examples/*/valid/*.json")) + \ - list(glob.glob(f"examples/*/invalid/*.json")) - -def ids(): - return [str(x).split("/")[-1][0:-5] for x in files()] - - -@pytest.fixture(params=files(), ids=ids()) -def testfile(request): - return request.param - - -@pytest.fixture(params=("jsonschema", "jsonld")) -def method(request): - - if request.param == "jsonschema": - - def json_schema(path): - print("json_schema", path) - schemaName = None - for name in ['image', 'plate', 'well']: - if name in path: - schemaName = name - if schemaName is None: - raise Exception("No schema found") - with open(f'schemas/{schemaName}.schema') as f: - schema = json.loads(f.read()) - - with open(path) as f: - test_json = json.loads(f.read()) - return js_valid(instance=test_json, schema=schema) - - return json_schema - - elif request.param == "salad": - document_loader, avsc_names, schema_metadata, metaschema_loader = \ - load_schema('salad_schema/image.yml') - - def salad(path): - load_and_validate(document_loader, avsc_names, path, strict=True) - - return salad - - else: - with open('schemas/jsonld/shacl.ttl') as f: - shacl = f.read() - - def jsonld(path): - - with open(path) as f: - graph = f.read() - - graph = modify(graph) - s = Graph().parse(data=shacl, format="turtle") - d = Graph().parse(data=graph, format="json-ld") - - if False: - print("=" * 100) - for stmt in s: - import pprint - pprint.pprint(stmt) - print("=" * 100) - for stmt in d: - import pprint - pprint.pprint(stmt) - print("=" * 100) - - conforms, report, message = ld_valid( - data_graph=d, - shacl_graph=s, - advanced=True, - debug=False, - allow_warnings=True, - ) - - if not conforms: - raise LDErr(message) - - return jsonld - - -def modify(data): - print("BEFORE", data) - data = json.loads(data) - - # Can be used to wrap collections - # DISABLED: data = walk(data) - - # Framing can be used to inject @type attributes - with open("schemas/jsonld/frame.json") as o: - frame = json.load(o) - options = dict() - data["@context"] = frame["@context"] - data = jsonld.frame( - data, - frame, - options) - data= {"@context": "http://localhost:8000/context.json#", "@graph": data} - data = json.dumps(data, indent=4) ## TODO: Seems wasteful - print("AFTER", data) - return data - - -def walk(data, path=None): - - if path is None: - path = [] - - if isinstance(data, dict): - for k, v in data.items(): - data[k] = walk(v, path + [k]) - - elif isinstance(data, list): - replacement = list() - for idx, item in enumerate(data): - if path[-1] == "@graph": - replacement.append(walk(item, path)) - else: - wrapper = { - "@type": "ngff:ListItem", - "ngff:position": idx - } - wrapper["ngff:item"] = walk(item, path + [idx]) - replacement.append(wrapper) - data = replacement - - return data diff --git a/0.3/tox.ini b/0.3/tox.ini deleted file mode 100644 index efd934c2..00000000 --- a/0.3/tox.ini +++ /dev/null @@ -1,15 +0,0 @@ -[tox] -envlist = v03 -skipsdist = True - -[testenv] -deps = - pytest - pytest-httpserver - jsonschema - rdflib - pyld - pyshacl - schema-salad -commands = - pytest tests --color=yes --basetemp={envtmpdir} {posargs:-v} diff --git a/0.4/copyright.include b/0.4/copyright.include deleted file mode 100644 index f0def708..00000000 --- a/0.4/copyright.include +++ /dev/null @@ -1,4 +0,0 @@ -Copyright © 2020-[YEAR] -OME® -(U. Dundee). -OME trademark rules apply. diff --git a/0.4/examples/bf2raw/image.json b/0.4/examples/bf2raw/image.json deleted file mode 100644 index c5eadb8a..00000000 --- a/0.4/examples/bf2raw/image.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "bioformats2raw.layout" : 3 -} \ No newline at end of file diff --git a/0.4/examples/bf2raw/plate.json b/0.4/examples/bf2raw/plate.json deleted file mode 100644 index bd98a16e..00000000 --- a/0.4/examples/bf2raw/plate.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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" - } -} diff --git a/0.4/examples/label_strict/colors_properties.json b/0.4/examples/label_strict/colors_properties.json deleted file mode 100644 index 2a14cbe4..00000000 --- a/0.4/examples/label_strict/colors_properties.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "image-label": { - "version": "0.4", - "colors": [ - { - "label-value": 1, - "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": "../../" - } - } -} diff --git a/0.4/examples/multiscales_strict/multiscales_example.json b/0.4/examples/multiscales_strict/multiscales_example.json deleted file mode 100644 index c03044d1..00000000 --- a/0.4/examples/multiscales_strict/multiscales_example.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "multiscales": [ - { - "version": "0.4", - "name": "example", - "axes": [ - {"name": "t", "type": "time", "unit": "millisecond"}, - {"name": "c", "type": "channel"}, - {"name": "z", "type": "space", "unit": "micrometer"}, - {"name": "y", "type": "space", "unit": "micrometer"}, - {"name": "x", "type": "space", "unit": "micrometer"} - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [{ - // the voxel size for the first scale level (0.5 micrometer) - "type": "scale", - "scale": [1.0, 1.0, 0.5, 0.5, 0.5] - }] - }, - { - "path": "1", - "coordinateTransformations": [{ - // 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] - }] - }, - { - "path": "2", - "coordinateTransformations": [{ - // 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 - "type": "scale", - "scale": [0.1, 1.0, 1.0, 1.0, 1.0] - }], - "type": "gaussian", - "metadata": { - "description": "the fields in metadata depend on the downscaling implementation. Here, the parameters passed to the skimage function are given", - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": "[true]", - "kwargs": {"multichannel": true} - } - } - ] -} \ No newline at end of file diff --git a/0.4/examples/multiscales_strict/multiscales_transformations.json b/0.4/examples/multiscales_strict/multiscales_transformations.json deleted file mode 100644 index 0097c47c..00000000 --- a/0.4/examples/multiscales_strict/multiscales_transformations.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "coordinateTransformations": [ - { - "scale": [ - 10, - 10 - ], - "type": "scale" - } - ], - "version": "0.4", - "name": "image_with_coordinateTransformations", - "type": "foo", - "metadata": { - "key": "value" - } - } - ] -} \ No newline at end of file diff --git a/0.4/examples/ome/series-2.json b/0.4/examples/ome/series-2.json deleted file mode 100644 index be7e9ed6..00000000 --- a/0.4/examples/ome/series-2.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "series" : [ "0", "1" ] -} diff --git a/0.4/examples/plate_strict/plate_2wells.json b/0.4/examples/plate_strict/plate_2wells.json deleted file mode 100644 index 2f963bd3..00000000 --- a/0.4/examples/plate_strict/plate_2wells.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "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.4", - "wells": [ - { - "path": "C/5", - "rowIndex": 2, - "columnIndex": 4 - }, - { - "path": "D/7", - "rowIndex": 3, - "columnIndex": 6 - } - ] - } -} diff --git a/0.4/examples/plate_strict/plate_6wells.json b/0.4/examples/plate_strict/plate_6wells.json deleted file mode 100644 index 6bc262c6..00000000 --- a/0.4/examples/plate_strict/plate_6wells.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "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.4", - "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 - } - ] - } -} diff --git a/0.4/examples/well_strict/well_2fields.json b/0.4/examples/well_strict/well_2fields.json deleted file mode 100644 index 5dca0af6..00000000 --- a/0.4/examples/well_strict/well_2fields.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "well": { - "images": [ - { - "acquisition": 0, - "path": "0" - }, - { - "acquisition": 3, - "path": "1" - } - ], - "version": "0.4" - } -} \ No newline at end of file diff --git a/0.4/examples/well_strict/well_4fields.json b/0.4/examples/well_strict/well_4fields.json deleted file mode 100644 index e2f0890a..00000000 --- a/0.4/examples/well_strict/well_4fields.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "well": { - "images": [ - { - "acquisition": 1, - "path": "0" - }, - { - "acquisition": 1, - "path": "1" - }, - { - "acquisition": 2, - "path": "2" - }, - { - "acquisition": 2, - "path": "3" - } - ], - "version": "0.4" - } -} \ No newline at end of file diff --git a/0.4/header.include b/0.4/header.include deleted file mode 100644 index e98bf6fe..00000000 --- a/0.4/header.include +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - [TITLE] - - - -
- - - OME logo (6 circles in a hexagon) - -

[TITLE]

-

[LONGSTATUS], -

-
-
- -
-
- -
- -

Status of this document

-
-
- - -
diff --git a/0.4/index.bs b/0.4/index.bs deleted file mode 100644 index 98db1b16..00000000 --- a/0.4/index.bs +++ /dev/null @@ -1,790 +0,0 @@ - - -Introduction {#intro} -===================== - -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. - - -Why "NGFF"? {#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](https://pydata.org/) community, the Zarr [[zarr]] format was developed -for easily storing collections of [NumPy](https://numpy.org/) arrays. In the -[ImageJ](https://imagej.net/) 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](https://zarr-specs.readthedocs.io/en/core-protocol-v3.0-dev/protocol/core/v3.0.html) -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)](https://github.com/zarr-developers/zarr-specs/issues/101) phase with the goal of having a first version early in 2021. As that -process comes to an end, this document will be updated. - -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](http://www.openmicroscopy.org/ome-files/) -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, -for all examples. - -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](https://tools.ietf.org/html/rfc2119). - -

-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 [[#bf2raw]]) -

- -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. - -On-disk (or in-cloud) layout {#on-disk} -======================================= - -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 -be stored on a web server to be accessed via HTTP or in object storage -like S3 or GCS. - -OME-Zarr is an implementation of the OME-NGFF specification using the Zarr -format. Arrays MUST be defined and stored in a hierarchical organization as -defined by the -[version 2 of the Zarr specification ](https://zarr.readthedocs.io/en/stable/spec/v2.html). -OME-NGFF metadata MUST be stored as attributes in the corresponding Zarr -groups. - -Images {#image-layout} ----------------------- - -The following layout describes the expected Zarr hierarchy for images with -multiple levels of resolutions and optionally associated labels. -Note that the number of dimensions is variable between 2 and 5 and that axis names are arbitrary, see [[#multiscale-md]] for details. -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.
-│
-├── 123.zarr                  # One image (id=123) converted to Zarr.
-│
-└── 456.zarr                  # Another image (id=456) converted to Zarr.
-    │
-    ├── .zgroup               # Each image is a Zarr group, or a folder, of other groups and arrays.
-    ├── .zattrs               # Group level attributes are stored in the .zattrs file and include
-    │                         # "multiscales" and "omero" (see below). In addition, the group level attributes
-    │                         # may also contain "_ARRAY_DIMENSIONS" for compatibility with xarray if this group directly contains multi-scale arrays.
-    │
-    ├── 0                     # Each multiscale level is stored as a separate Zarr array,
-    │   ...                   # which is a folder containing chunk files which compose the array.
-    ├── n                     # The name of the array is arbitrary with the ordering defined by
-    │   │                     # by the "multiscales" metadata, but is often a sequence starting at 0.
-    │   │
-    │   ├── .zarray           # All image arrays must be up to 5-dimensional
-    │   │                     # with the axis of type time before type channel, before spatial axes.
-    │   │
-    │   └─ t                  # Chunks are stored with the nested directory layout.
-    │      └─ c               # All but the last chunk element are stored as directories.
-    │         └─ z            # The terminal chunk is a file. Together the directory and file names
-    │            └─ y         # provide the "chunk coordinate" (t, c, z, y, x), where the maximum coordinate
-    │               └─ 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 `.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.
-            │
-            └── 0             # Multiscale, labeled image. The name is unimportant but is registered in the "labels" group above.
-                ├── .zgroup   # Zarr Group which is both a multiscaled image as well as a labeled image.
-                ├── .zattrs   # Metadata of the related image and as well as display information under the "image-label" key.
-                │
-                ├── 0         # Each multiscale level is stored as a separate Zarr array, as above, but only integer values
-                │   ...       # are supported.
-                └── n
-
- - - -High-content screening {#hcs-layout} ------------------------------------- - -The following specification defines the hierarchy for a high-content screening -dataset. Three groups MUST be defined above the images: - -- the group above the images defines the well and MUST implement the - [well specification](#well-md). All images contained in a well are fields - of view of the same well -- the group above the well defines a row of wells -- the group above the well row defines an entire plate i.e. a two-dimensional - collection of wells organized in rows and columns. It MUST implement the - [plate specification](#plate-md) - -A well row group SHOULD NOT be present if there are no images in the well row. -A well group SHOULD NOT be present if there are no images in the well. - - -
-.                             # Root folder, potentially in S3,
-│
-└── 5966.zarr                 # One plate (id=5966) converted to Zarr
-    ├── .zgroup
-    ├── .zattrs               # Implements "plate" specification
-    ├── A                     # First row of the plate
-    │   ├── .zgroup
-    │   │
-    │   ├── 1                 # First column of row A
-    │   │   ├── .zgroup
-    │   │   ├── .zattrs       # Implements "well" specification
-    │   │   │
-    │   │   ├── 0             # First field of view of well A1
-    │   │   │   │
-    │   │   │   ├── .zgroup
-    │   │   │   ├── .zattrs   # Implements "multiscales", "omero"
-    │   │   │   ├── 0
-    │   │   │   │   ...       # Resolution levels
-    │   │   │   ├── n
-    │   │   │   └── labels    # Labels (optional)
-    │   │   ├── ...           # Fields of view
-    │   │   └── m
-    │   ├── ...               # Columns
-    │   └── 12
-    ├── ...                   # Rows
-    └── H
-
- -Metadata {#metadata} -==================== - -The various `.zattrs` files throughout the above array hierarchy may contain metadata -keys as specified below for discovering certain types of data, especially images. - -"axes" metadata {#axes-md} --------------------------- - -"axes" describes the dimensions of a physical coordinate space. It is a list of dictionaries, where each dictionary describes a dimension (axis) and: -- MUST contain the field "name" that gives the name for this dimension. The values MUST be unique across all "name" fields. -- SHOULD contain the field "type". It SHOULD be one of "space", "time" or "channel", but MAY take other string values for custom axis types that are not part of this specification yet. -- SHOULD contain the field "unit" to specify the physical unit of this dimension. The value SHOULD be one of the following strings, which are valid units according to UDUNITS-2. - - Units for "space" axes: 'angstrom', 'attometer', 'centimeter', 'decimeter', 'exameter', 'femtometer', 'foot', 'gigameter', 'hectometer', 'inch', 'kilometer', 'megameter', 'meter', 'micrometer', 'mile', 'millimeter', 'nanometer', 'parsec', 'petameter', 'picometer', 'terameter', 'yard', 'yoctometer', 'yottameter', 'zeptometer', 'zettameter' - - 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 [[#multiscale-md]], the length of "axes" MUST be equal to the number of dimensions of the arrays that contain the image data. - -"bioformats2raw.layout" (transitional) {#bf2raw} ------------------------------------------------- - -[=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. - -

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
-    └── ...
-
- -

Attributes

- -The top-level `.zattrs` file must contain the `bioformats2raw.layout` key: -
-path: examples/bf2raw/image.json
-highlight: json
-
- -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 [[#plate-md]]. It is not -possible to mix collections of images with plates at present. - -
-path: examples/bf2raw/plate.json
-highlight: json
-
- -The `.zattrs` file within the OME group may contain the "series" key: - -
-path: examples/ome/series-2.json
-highlight: json
-
- -

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 `` elements as opposed to ``, `` or ``; - - MAY make use of the [minimum specification](https://docs.openmicroscopy.org/ome-model/6.2.2/specifications/minimum.html). - -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. - -"coordinateTransformations" metadata {#trafo-md} -------------------------------------- - -"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". -The value of "type" MUST be one of the elements of the `type` column in the table below. -Additional fields for the entry depend on "type" and are defined by the column `fields`. - - - -
`identity` identity transformation, is the default transformation and is typically not explicitly defined -
`translation` one of: `"translation":List[float]`, `"path":str` translation vector, stored either as a list of floats (`"translation"`) or as binary data at a location in this container (`path`). The length of vector defines number of dimensions. | -
`scale` one of: `"scale":List[float]`, `"path":str` scale vector, stored either as a list of floats (`scale`) or as binary data at a location in this container (`path`). The length of vector defines number of dimensions. | -
typefieldsdescription -
- -The transformations in the list are applied sequentially and in order. - - -"multiscales" metadata {#multiscale-md} ---------------------------------------- - -Metadata about an image can be found under the "multiscales" key in the group-level metadata. Here, image refers to 2 to 5 dimensional data representing image or volumetric data with optional time or channel axes. It is stored in a multiple resolution representation. - -"multiscales" contains a list of dictionaries where each entry describes a multiscale image. - -Each "multiscales" dictionary MUST contain the field "axes", see [[#axes-md]]. -The length of "axes" must be between 2 and 5 and MUST be equal to the dimensionality of the zarr arrays storing the image data (see "datasets:path"). -The "axes" MUST contain 2 or 3 entries of "type:space" and MAY contain one additional entry of "type:time" and MAY contain one additional entry of "type:channel" or a null / custom type. -The order of the entries MUST correspond to the order of dimensions of the zarr arrays. In addition, the entries MUST be ordered by "type" where the "time" axis must come first (if present), followed by the "channel" or custom axis (if present) and the axes of type "space". -If there are three spatial axes where two correspond to the image plane ("yx") and images are stacked along the other (anisotropic) axis ("z"), the spatial axes SHOULD be ordered as "zyx". - -Each "multiscales" dictionary MUST contain the field "datasets", which is a list of dictionaries describing the arrays storing the individual resolution levels. -Each dictionary in "datasets" MUST contain the field "path", whose value contains the path to the array for this resolution relative -to the current zarr group. The "path"s MUST be ordered from largest (i.e. highest resolution) to smallest. - -Each "datasets" dictionary MUST have the same number of dimensions and MUST NOT have more than 5 dimensions. The number of dimensions and order MUST correspond to number and order of "axes". -Each dictionary in "datasets" MUST contain the field "coordinateTransformations", which contains a list of transformations that map the data coordinates to the physical coordinates (as specified by "axes") for this resolution level. -The transformations are defined according to [[#trafo-md]]. The transformation MUST only be of type `translation` or `scale`. -They MUST contain exactly one `scale` transformation that specifies the pixel size in physical units or time duration. If scaling information is not available or applicable for one of the axes, the value MUST express the scaling factor between the current resolution and the first resolution for the given axis, defaulting to 1.0 if there is no downsampling along the axis. -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". -The requirements (only `scale` and `translation`, restrictions on order) are in place to provide a simple mapping from data coordinates to physical coordinates while being compatible with the general transformation spec. - -Each "multiscales" dictionary MAY contain the field "coordinateTransformations", describing transformations that are applied to all resolution levels in the same manner. -The transformations MUST follow the same rules about allowed types, order, etc. as in "datasets:coordinateTransformations" and are applied after them. -They can for example be used to specify the `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.4). - -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. - -
-path: examples/multiscales_strict/multiscales_example.json
-highlight: json
-
- - -If only one multiscale is provided, use it. Otherwise, the user can choose by -name, using the first multiscale as a fallback: - -```python -datasets = [] -for named in multiscales: - if named["name"] == "3D": - datasets = [x["path"] for x in named["datasets"]] - break -if not datasets: - # Use the first by default. Or perhaps choose based on chunk size. - datasets = [x["path"] for x in multiscales[0]["datasets"]] -``` - -"omero" metadata (transitional) {#omero-md} -------------------------------------------- - -[=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: - -```json -"id": 1, # ID in OMERO -"name": "example.tif", # Name as shown in the UI -"version": "0.4", # Current version -"channels": [ # Array matching the c dimension size - { - "active": true, - "coefficient": 1, - "color": "0000FF", - "family": "linear", - "inverted": false, - "label": "LaminB1", - "window": { - "end": 1500, - "max": 65535, - "min": 0, - "start": 0 - } - } -], -"rdefs": { - "defaultT": 0, # First timepoint to show the user - "defaultZ": 118, # First Z section to show the user - "model": "color" # "color" or "greyscale" -} -``` - -See https://docs.openmicroscopy.org/omero/5.6.1/developers/Web/WebGateway.html#imgdata -for more information. - -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. - -"labels" metadata {#labels-md} ------------------------------- - -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: - -```json -{ - "labels": [ - "orphaned/0" - ] -} -``` - -Unlisted groups MAY be labels. - -"image-label" metadata {#label-md} ----------------------------------- - -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 `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 `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 `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. - -
-path: examples/label_strict/colors_properties.json
-highlight: json
-
- -"plate" metadata {#plate-md} ----------------------------- - -For high-content screening datasets, the plate layout can be found under the -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. - -
-path: examples/plate_strict/plate_6wells.json
-highlight: json
-
- -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. - -
-path: examples/plate_strict/plate_2wells.json
-highlight: json
-
- -"well" metadata {#well-md} --------------------------- - -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. - -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. - -
-path: examples/well_strict/well_4fields.json
-highlight: json
-
- -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. - -
-path: examples/well_strict/well_2fields.json
-highlight: json
-
- -Specification naming style {#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. - -Implementations {#implementations} -================================== - -Projects which support reading and/or writing OME-NGFF data include: - -
- -
[bigdataviewer-ome-zarr](https://github.com/mobie/bigdataviewer-ome-zarr)
-
Fiji-plugin for reading OME-Zarr.
- -
[bioformats2raw](https://github.com/glencoesoftware/bioformats2raw)
-
A performant, Bio-Formats image file format converter.
- -
[omero-ms-zarr](https://github.com/ome/omero-ms-zarr)
-
A microservice for OMERO.server that converts images stored in OMERO to OME-Zarr files on the fly, served via a web API.
- -
[idr-zarr-tools](https://github.com/IDR/idr-zarr-tools)
-
A full workflow demonstrating the conversion of IDR images to OME-Zarr images on S3.
- -
[OMERO CLI Zarr plugin](https://github.com/ome/omero-cli-zarr)
-
An OMERO CLI plugin that converts images stored in OMERO.server into a local Zarr file.
- -
[ome-zarr-py](https://github.com/ome/ome-zarr-py)
-
A napari plugin for reading ome-zarr files.
- -
[vizarr](https://github.com/hms-dbmi/vizarr/)
-
A minimal, purely client-side program for viewing Zarr-based images with Viv & ImJoy.
- -
- -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](https://downloads.openmicroscopy.org/presentations/2020/Dundee/Workshops/NGFF/zarr_diagram/). -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](https://github.com/ome/ngff) repository. - -Citing {#citing} -================ - -[Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.](https://ngff.openmicroscopy.org/0.4) -J. Moore, *et al*. Open Microscopy Environment Consortium, 8 February 2022. -This edition of the specification is [https://ngff.openmicroscopy.org/0.4/](https://ngff.openmicroscopy.org/0.4/]). -The latest edition is available at [https://ngff.openmicroscopy.org/latest/](https://ngff.openmicroscopy.org/latest/). -[(doi:10.5281/zenodo.4282107)](https://doi.org/10.5281/zenodo.4282107) - -Version History {#history} -========================== - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RevisionDateDescription
0.4.12022-09-26transitional metadata for image collections ("bioformats2raw.layout")
0.4.02022-02-08multiscales: add axes type, units and coordinateTransformations
0.4.02022-02-08plate: add rowIndex/columnIndex
0.3.02021-08-24Add axes field to multiscale metadata
0.2.02021-03-29Change chunk dimension separator to "/"
0.1.42020-11-26Add HCS specification
0.1.32020-09-14Add labels specification
0.1.2 2020-05-07Add description of "omero" metadata
0.1.1 2020-05-06Add info on the ordering of resolutions
0.1.0 2020-04-20First version for internal demo
- - -
-{
-  "blogNov2020": {
-    "href": "https://blog.openmicroscopy.org/file-formats/community/2020/11/04/zarr-data/",
-    "title": "Public OME-Zarr data (Nov. 2020)",
-    "authors": [
-      "OME Team"
-    ],
-    "status": "Informational",
-    "publisher": "OME",
-    "id": "blogNov2020",
-    "date": "04 November 2020"
-  },
-  "imagesc26952": {
-    "href": "https://forum.image.sc/t/ome-s-position-regarding-file-formats/26952",
-    "title": "OME’s position regarding file formats",
-    "authors": [
-      "OME Team"
-    ],
-    "status": "Informational",
-    "publisher": "OME",
-    "id": "imagesc26952",
-    "date": "19 June 2020"
-  },
-  "n5": {
-    "id": "n5",
-    "href": "https://github.com/saalfeldlab/n5/issues/62",
-    "title": "N5---a scalable Java API for hierarchies of chunked n-dimensional tensors and structured meta-data",
-    "status": "Informational",
-    "authors": [
-      "John A. Bogovic",
-      "Igor Pisarev",
-      "Philipp Hanslovsky",
-      "Neil Thistlethwaite",
-      "Stephan Saalfeld"
-    ],
-    "date": "2020"
-  },
-  "ome-zarr-py": {
-    "id": "ome-zarr-py",
-    "href": "https://doi.org/10.5281/zenodo.4113931",
-    "title": "ome-zarr-py: Experimental implementation of next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.",
-    "status": "Informational",
-    "publisher": "Zenodo",
-    "authors": [
-      "OME",
-      "et al"
-    ],
-    "date": "06 October 2020"
-  },
-  "zarr": {
-    "id": "zarr",
-    "href": "https://doi.org/10.5281/zenodo.4069231",
-    "title": "Zarr: An implementation of chunked, compressed, N-dimensional arrays for Python.",
-    "status": "Informational",
-    "publisher": "Zenodo",
-    "authors": [
-      "Alistair Miles",
-      "et al"
-    ],
-    "date": "06 October 2020"
-  }
-}
-
diff --git a/0.4/schemas/bf2raw.schema b/0.4/schemas/bf2raw.schema deleted file mode 100644 index 834aee24..00000000 --- a/0.4/schemas/bf2raw.schema +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/latest/schemas/bf2raw.schema", - "title": "NGFF container produced by bioformats2raw", - "description": "JSON from OME-NGFF .zattrs", - "type": "object", - "properties": { - "bioformats2raw.layout": { - "description": "The top-level identifier metadata added by bioformats2raw", - "type": "number", - "enum": [3] - } - } -} diff --git a/0.4/schemas/image.schema b/0.4/schemas/image.schema deleted file mode 100644 index aec5db5f..00000000 --- a/0.4/schemas/image.schema +++ /dev/null @@ -1,233 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.4/schemas/image.schema", - "title": "NGFF Image", - "description": "JSON from OME-NGFF .zattrs", - "type": "object", - "properties": { - "multiscales": { - "description": "The multiscale datasets for this image", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "datasets": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "coordinateTransformations": { - "$ref": "#/$defs/coordinateTransformations" - } - }, - "required": ["path", "coordinateTransformations"] - } - }, - "version": { - "type": "string", - "enum": [ - "0.4" - ] - }, - "axes": { - "$ref": "#/$defs/axes" - }, - "coordinateTransformations": { - "$ref": "#/$defs/coordinateTransformations" - } - }, - "required": [ - "datasets", "axes" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "omero": { - "type": "object", - "properties": { - "channels": { - "type": "array", - "items": { - "type": "object", - "properties": { - "window": { - "type": "object", - "properties": { - "end": { - "type": "number" - }, - "max": { - "type": "number" - }, - "min": { - "type": "number" - }, - "start": { - "type": "number" - } - }, - "required": [ - "start", - "min", - "end", - "max" - ] - }, - "label": { - "type": "string" - }, - "family": { - "type": "string" - }, - "color": { - "type": "string" - }, - "active": { - "type": "boolean" - } - }, - "required": [ - "window", - "color" - ] - } - } - }, - "required": [ - "channels" - ] - } - }, - "required": [ "multiscales" ], - - "$defs": { - "axes": { - "type": "array", - "uniqueItems": true, - "minItems": 2, - "maxItems": 5, - "contains": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["space"] - }, - "unit": { - "type": "string" - } - } - }, - "minContains": 2, - "maxContains": 3, - "items": { - "oneOf": [ - { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["channel", "time", "space"] - } - }, - "required": ["name", "type"] - }, - { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "not": { - "enum": ["space", "time", "channel"] - } - } - }, - "required": ["name"] - } - ] - } - }, - "coordinateTransformations": { - "type": "array", - "minItems": 1, - "contains": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "scale" - ] - }, - "scale": { - "type": "array", - "minItems": 2, - "items": { - "type": "number" - } - } - } - }, - "maxContains": 1, - "items": { - "oneOf": [ - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "scale" - ] - }, - "scale": { - "type": "array", - "minItems": 2, - "items": { - "type": "number" - } - } - }, - "required": ["type", "scale"] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "translation" - ] - }, - "translation": { - "type": "array", - "minItems": 2, - "items": { - "type": "number" - } - } - }, - "required": ["type", "translation"] - } - ] - } - } - } -} diff --git a/0.4/schemas/label.schema b/0.4/schemas/label.schema deleted file mode 100644 index 1629d0f9..00000000 --- a/0.4/schemas/label.schema +++ /dev/null @@ -1,77 +0,0 @@ -{ - "$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/ome.schema b/0.4/schemas/ome.schema deleted file mode 100644 index bd600a2a..00000000 --- a/0.4/schemas/ome.schema +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/latest/schemas/ome.schema", - "title": "NGFF group produced by bioformats2raw to contain OME metadata", - "description": "JSON from OME-NGFF OME/.zattrs linked to an OME-XML file", - "type": "object", - "properties": { - "series": { - "description": "An array of the same length and the same order as the images defined in the OME-XML", - "type": "array", - "items": { - "type": "string" - }, - "minContains": 1 - } - } -} diff --git a/0.4/schemas/plate.schema b/0.4/schemas/plate.schema deleted file mode 100644 index df7cfad0..00000000 --- a/0.4/schemas/plate.schema +++ /dev/null @@ -1,140 +0,0 @@ -{ - "$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_image.schema b/0.4/schemas/strict_image.schema deleted file mode 100644 index 87d0d6b5..00000000 --- a/0.4/schemas/strict_image.schema +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$id": "https://ngff.openmicroscopy.org/0.4/schemas/strict_image.schema", - "allOf": [ - { - "$ref": "https://ngff.openmicroscopy.org/0.4/schemas/image.schema" - }, - { - "properties": { - "multiscales": { - "items": { - "required": [ - "version", "metadata", "type", "name" - ] - } - } - } - } - ] -} \ No newline at end of file diff --git a/0.4/schemas/strict_label.schema b/0.4/schemas/strict_label.schema deleted file mode 100644 index af9090da..00000000 --- a/0.4/schemas/strict_label.schema +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$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 deleted file mode 100644 index 5a88ab72..00000000 --- a/0.4/schemas/strict_plate.schema +++ /dev/null @@ -1,28 +0,0 @@ -{ - "$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 deleted file mode 100644 index 1e200294..00000000 --- a/0.4/schemas/strict_well.schema +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$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 deleted file mode 100644 index 971a0102..00000000 --- a/0.4/schemas/well.schema +++ /dev/null @@ -1,47 +0,0 @@ -{ - "$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/0.4/tests/image_suite.json b/0.4/tests/image_suite.json deleted file mode 100644 index 42906985..00000000 --- a/0.4/tests/image_suite.json +++ /dev/null @@ -1,1148 +0,0 @@ -{ - "description": "TBD", - "schema": { - "id": "schemas/image.schema" - }, - "tests": [ - { - "formerly": "valid/mismatch_axes_units.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "t", - "type": "time", - "unit": "micrometer" - }, - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 0.13, - 0.13 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": true - }, - { - "formerly": "valid/untyped_axes.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "angle" - }, - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": true - }, - { - "formerly": "valid/missing_version.json", - "description": "TBD", - "data": { - "@type": "ngff:Image", - "multiscales": [ - { - "name": "example", - "datasets": [ - { - "path": "path/to/0", - "coordinateTransformations": [ - { - "type": "scale", - "scale": [ - 1, - 1 - ] - } - ] - } - ], - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ] - } - ] - }, - "valid": true - }, - { - "formerly": "valid/invalid_axis_units.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micron" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 0.13, - 0.13 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": true - }, - { - "formerly": "valid/missing_name.json", - "description": "TBD", - "data": { - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.4", - "datasets": [ - { - "path": "path/to/0", - "coordinateTransformations": [ - { - "type": "scale", - "scale": [ - 1, - 1 - ] - } - ] - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": [ - "true", - "false" - ], - "kwargs": { - "multichannel": true - } - }, - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ] - } - ] - }, - "valid": true - }, - { - "formerly": "valid/custom_type_axes.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "angle", - "type": "custom" - }, - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": true - }, - { - "formerly": "invalid/duplicate_axes.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "x", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/missing_space_axes.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "t", - "type": "time" - }, - { - "name": "c", - "type": "channel" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/invalid_transformation_type.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "translation" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/missing_scale.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "translation": [ - 1, - 1 - ], - "type": "translation" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/too_many_axes.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "angle", - "type": "custom" - }, - { - "name": "t", - "type": "time" - }, - { - "name": "c", - "type": "channel" - }, - { - "name": "z", - "type": "space" - }, - { - "name": "y", - "type": "space" - }, - { - "name": "x", - "type": "space" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1, - 1, - 1, - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/invalid_channels_color.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": 255, - "family": "linear", - "label": "1234", - "window": { - "end": 1765.0, - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/missing_axes_name.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "type": "space", - "unit": "micron" - }, - { - "type": "space", - "unit": "micron" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 0.13, - 0.13 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/invalid_axes_count.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/one_space_axes.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "t", - "type": "time" - }, - { - "name": "c", - "type": "channel" - }, - { - "name": "x", - "type": "space" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/invalid_path.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": 0, - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/invalid_multiscales_transformations.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "coordinateTransformations": [ - { - "scale": [ - "invalid" - ], - "type": "scale" - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/missing_transformations.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0" - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/no_datasets.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/missing_datasets.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/missing_axes.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/invalid_version.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.3" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/invalid_axis_type.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "invalid", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/duplicate_scale.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - }, - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/no_axes.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/too_many_space_axes.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "X", - "type": "space" - }, - { - "name": "z", - "type": "space" - }, - { - "name": "y", - "type": "space" - }, - { - "name": "x", - "type": "space" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1, - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/no_multiscales.json", - "description": "TBD", - "data": { - "@type": "ngff:Image", - "multiscales": [] - }, - "valid": false - }, - { - "formerly": "invalid/invalid_channels_window.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": "ff0000", - "family": "linear", - "label": "1234", - "window": { - "end": "100", - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/empty_transformations.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - }, - { - "formerly": "invalid/missing_path.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4" - } - ] - }, - "valid": false - } - ] -} diff --git a/0.4/tests/label_suite.json b/0.4/tests/label_suite.json deleted file mode 100644 index 634225c8..00000000 --- a/0.4/tests/label_suite.json +++ /dev/null @@ -1,131 +0,0 @@ -{ - "description": "Tests for the image-label JSON schema", - "schema": { - "id": "schemas/label.schema" - }, - "tests": [ - { - "formerly": "image-label/minimal", - "data": { - "image-label": { - "colors": [ - { - "label-value": 1, - "rgba": [0, 0, 0, 0] - } - ] - } - }, - "valid": true - }, - { - "formerly": "image-label/minimal_properties", - "data": { - "image-label": { - "colors": [ - { - "label-value": 1, - "rgba": [0, 0, 0, 0] - } - ], - "properties": [ - { - "label-value": 1 - } - ] - } - }, - "valid": true - }, - { - "formerly": "image-label/empty_colors", - "data": { - "image-label": { - "colors": [] - } - }, - "valid": false - }, - { - "formerly": "image-label/empty_properties", - "data": { - "image-label": { - "properties": [] - } - }, - "valid": false - }, - { - "formerly": "image-label/colors_no_label_value", - "data": { - "image-label": { - "colors": [ - { - "rgba": [0, 0, 0, 0] - } - ] - } - }, - "valid": false - }, - { - "formerly": "image-label/properties_no_label_value", - "data": { - "image-label": { - "properties": [ - { - "value": "foo" - } - ] - } - }, - "valid": false - }, - { - "formerly": "image-label/colors_rgba_length", - "data": { - "image-label": { - "colors": [ - { - "label-value": 1, - "rgba": [0, 0, 0] - } - ] - } - }, - "valid": false - }, - { - "formerly": "image-label/colors_rgba_type", - "data": { - "image-label": { - "colors": [ - { - "label-value": 1, - "rgba": [0, 0, 0, 500] - } - ] - } - }, - "valid": false - }, - { - "formerly": "image-label/colors_duplicate", - "data": { - "image-label": { - "colors": [ - { - "label-value": 1, - "rgba": [0, 0, 0, 0] - }, - { - "label-value": 1, - "rgba": [0, 0, 0, 0] - } - ] - } - }, - "valid": false - } - ] -} diff --git a/0.4/tests/plate_suite.json b/0.4/tests/plate_suite.json deleted file mode 100644 index c19ad60e..00000000 --- a/0.4/tests/plate_suite.json +++ /dev/null @@ -1,819 +0,0 @@ -{ - "description": "Tests for the plate JSON schema", - "schema": { - "id": "schemas/plate.schema" - }, - "tests": [ - { - "formerly": "plate/minimal_no_acquisitions", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": true - }, - { - "formerly": "plate/minimal_acquisitions", - "data": { - "plate": { - "acquisitions": [ - { - "id": 0 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": true - }, - { - "formerly": "plate/missing_rows", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/empty_rows", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/duplicate_rows", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - }, - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/missing_columns", - "data": { - "plate": { - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/empty_columns", - "data": { - "plate": { - "columns": [], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/duplicate_columns", - "data": { - "plate": { - "columns": [ - { - "name": "A" - }, - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/missing_wells", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/empty_wells", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": {} - } - }, - "valid": false - }, - { - "formerly": "plate/duplicate_rows", - "data": { - "plate": { - "columns": [ - { - "name": "A" - }, - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - }, - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/missing_column_name", - "data": { - "plate": { - "columns": [ - { - "concentration": 10 - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/missing_row_name", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "concentration": 10 - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/missing_well_path", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/missing_well_rowIndex", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/missing_well_columnIndex", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/well_1group", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A1", - "rowIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/well_3groups", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "plate/A/1", - "rowIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/invalid_version", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ], - "version": "foo" - } - }, - "valid": false - }, - { - "formerly": "plate/non_alphanumeric_column", - "data": { - "plate": { - "columns": [ - { - "name": "A-1" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A-1/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/non_alphanumeric_row", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "A1" - } - ], - "wells": [ - { - "path": "A/A1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": true - }, - { - "formerly": "plate/missing_acquisition_id", - "data": { - "plate": { - "acquisitions": [ - { - "maximumfieldcount": 1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/non_integer_acquisition_id", - "data": { - "plate": { - "acquisitions": [ - { - "id": "0" - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/negative_acquisition_id", - "data": { - "plate": { - "acquisitions": [ - { - "id": -1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/non_integer_acquisition_maximumfieldcount", - "data": { - "plate": { - "acquisitions": [ - { - "id": 0, - "maximumfieldcount": "0" - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/acquisition_zero_maximumfieldcount", - "data": { - "plate": { - "acquisitions": [ - { - "id": 0, - "maximumfieldcount": 0 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/acquisition_noninteger_starttime", - "data": { - "plate": { - "acquisitions": [ - { - "id": 0, - "starttime": "2022-05-13T13:48:06+00:00" - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/acquisition_negative_starttime", - "data": { - "plate": { - "acquisitions": [ - { - "id": 0, - "starttime": -1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/acquisition_noninteger_endtime", - "data": { - "plate": { - "acquisitions": [ - { - "id": 0, - "endtime": "2022-05-13T13:48:06+00:00" - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/negative_endtime", - "data": { - "plate": { - "acquisitions": [ - { - "id": 0, - "endtime": -1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/zero_field_count", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "field_count": 0, - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - } - ] -} diff --git a/0.4/tests/strict_image_suite.json b/0.4/tests/strict_image_suite.json deleted file mode 100644 index ec6295d3..00000000 --- a/0.4/tests/strict_image_suite.json +++ /dev/null @@ -1,388 +0,0 @@ -{ - "description": "TBD", - "schema": { - "id": "schemas/strict_image.schema" - }, - "tests": [ - { - "formerly": "valid_strict/multiscales_example.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "version": "0.4", - "name": "example", - "axes": [ - { - "name": "t", - "type": "time", - "unit": "millisecond" - }, - { - "name": "c", - "type": "channel" - }, - { - "name": "z", - "type": "space", - "unit": "micrometer" - }, - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "type": "scale", - "scale": [ - 1.0, - 1.0, - 0.5, - 0.5, - 0.5 - ] - } - ] - }, - { - "path": "1", - "coordinateTransformations": [ - { - "type": "scale", - "scale": [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - } - ] - }, - { - "path": "2", - "coordinateTransformations": [ - { - "type": "scale", - "scale": [ - 1.0, - 1.0, - 2.0, - 2.0, - 2.0 - ] - } - ] - } - ], - "coordinateTransformations": [ - { - "type": "scale", - "scale": [ - 0.1, - 1.0, - 1.0, - 1.0, - 1.0 - ] - } - ], - "type": "gaussian", - "metadata": { - "description": "the fields in metadata depend on the downscaling implementation. Here, the parameters passed to the skimage function are given", - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": "[true]", - "kwargs": { - "multichannel": true - } - } - } - ] - }, - "valid": true - }, - { - "formerly": "valid_strict/multiscales_transformations.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "coordinateTransformations": [ - { - "scale": [ - 10, - 10 - ], - "type": "scale" - } - ], - "version": "0.4", - "name": "image_with_coordinateTransformations", - "type": "foo", - "metadata": { - "key": "value" - } - } - ] - }, - "valid": true - }, - { - "formerly": "valid_strict/image_metadata.json", - "description": "TBD", - "data": { - "@id": "top", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "inner", - "version": "0.4", - "name": "example", - "datasets": [ - { - "path": "path/to/0", - "coordinateTransformations": [ - { - "type": "scale", - "scale": [ - 1, - 1 - ] - } - ] - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": [ - "true", - "false" - ], - "kwargs": { - "multichannel": true - } - }, - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ] - } - ] - }, - "valid": true - }, - { - "formerly": "valid_strict/image.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4", - "name": "simple_image", - "type": "foo", - "metadata": { - "key": "value" - } - } - ] - }, - "valid": true - }, - { - "formerly": "valid_strict/image_omero.json", - "description": "TBD", - "data": { - "multiscales": [ - { - "axes": [ - { - "name": "t", - "type": "time" - }, - { - "name": "c", - "type": "channel" - }, - { - "name": "z", - "type": "space", - "unit": "micrometer" - }, - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1, - 0.5, - 0.13, - 0.13 - ], - "type": "scale" - }, - { - "translation": [ - 0, - 9, - 0.5, - 25.74, - 21.58 - ], - "type": "translation" - } - ] - }, - { - "path": "1", - "coordinateTransformations": [ - { - "scale": [ - 1, - 1, - 1, - 0.26, - 0.26 - ], - "type": "scale" - } - ] - } - ], - "version": "0.4", - "name": "image_with_omero_metadata", - "type": "foo", - "metadata": { - "key": "value" - } - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": "00FF00", - "family": "linear", - "inverted": false, - "label": "FITC", - "window": { - "end": 813.0, - "max": 870.0, - "min": 102.0, - "start": 82.0 - } - }, - { - "active": true, - "coefficient": 1.0, - "color": "FF0000", - "family": "linear", - "inverted": false, - "label": "RD-TR-PE", - "window": { - "end": 815.0, - "max": 441.0, - "min": 129.0, - "start": 78.0 - } - } - ], - "id": 1, - "rdefs": { - "defaultT": 0, - "defaultZ": 2, - "model": "color" - }, - "version": "0.4" - } - }, - "valid": true - } - ] -} diff --git a/0.4/tests/strict_label_suite.json b/0.4/tests/strict_label_suite.json deleted file mode 100644 index a4ccf01d..00000000 --- a/0.4/tests/strict_label_suite.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "description": "Tests for the strict image-label JSON schema", - "schema": { - "id": "schemas/strict_label.schema" - }, - "tests": [ - { - "formerly": "image-label/no_version", - "data": { - "image-label": { - "colors": [ - { - "label-value": 1, - "rgba": [0, 0, 0, 0] - } - ] - } - }, - "valid": false - }, - { - "formerly": "image-label/no_colors", - "data": { - "image-label": { - "version": "0.4" - } - }, - "valid": false - } - ] -} diff --git a/0.4/tests/strict_plate_suite.json b/0.4/tests/strict_plate_suite.json deleted file mode 100644 index 49eeb3fc..00000000 --- a/0.4/tests/strict_plate_suite.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "description": "Tests for the strict plate JSON schema", - "schema": { - "id": "schemas/strict_plate.schema" - }, - "tests": [ - { - "formerly": "plate/strict_no_acquisitions", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "name": "test plate", - "rows": [ - { - "name": "1" - } - ], - "version": "0.4", - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": true - }, - { - "formerly": "plate/missing_name", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "version": "0.4", - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/missing_version", - "data": { - "plate": { - "columns": [ - { - "name": "A" - } - ], - "name": "test plate", - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/strict_acquisitions", - "data": { - "plate": { - "acquisitions": [ - { - "id": 0, - "name": "0", - "maximumfieldcount": 1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "name": "test plate", - "rows": [ - { - "name": "1" - } - ], - "version": "0.4", - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": true - }, - { - "formerly": "plate/missing_acquisition_name", - "data": { - "plate": { - "acquisitions": [ - { - "id": 0, - "maximumfieldcount": 1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "name": "test plate", - "rows": [ - { - "name": "1" - } - ], - "version": "0.4", - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/missing_acquisition_maximumfieldcount", - "data": { - "plate": { - "acquisitions": [ - { - "id": 0, - "name": "0" - } - ], - "columns": [ - { - "name": "A" - } - ], - "name": "test plate", - "rows": [ - { - "name": "1" - } - ], - "version": "0.4", - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - }, - "valid": false - } - ] -} diff --git a/0.4/tests/strict_well_suite.json b/0.4/tests/strict_well_suite.json deleted file mode 100644 index b4f8fe71..00000000 --- a/0.4/tests/strict_well_suite.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "description": "Tests for the strict well JSON schema", - "schema": { - "id": "schemas/strict_well.schema" - }, - "tests": [ - { - "formerly": "well/strict_no_acquisitions", - "data": { - "well": { - "images": [ - { - "path": "0" - } - ], - "version": "0.4" - } - }, - "valid": true - }, - { - "formerly": "plate/missing_version", - "data": { - "well": { - "images": [ - { - "path": "0" - } - ] - } - }, - "valid": false - }, - { - "formerly": "plate/strict_acquisitions", - "data": { - "well": { - "images": [ - { - "acquisition": 0, - "path": "0" - } - ], - "version": "0.4" - } - }, - "valid": true - } - ] -} diff --git a/0.4/tests/test_validation.py b/0.4/tests/test_validation.py deleted file mode 100644 index 82efd90d..00000000 --- a/0.4/tests/test_validation.py +++ /dev/null @@ -1,91 +0,0 @@ -import json -import glob -import os - -from dataclasses import dataclass -from typing import List - -import pytest - -from jsonschema import RefResolver, Draft202012Validator as Validator -from jsonschema.exceptions import ValidationError - -schema_store = {} -for schema_filename in glob.glob("schemas/*"): - with open(schema_filename) as f: - schema = json.load(f) - schema_store[schema["$id"]] = schema - -@dataclass -class Suite: - schema: dict - data: dict - valid: bool = True - - def validate(self, validator) -> None: - if not self.valid: - with pytest.raises(ValidationError): - validator.validate(self.data) - else: - validator.validate(self.data) - - -def pytest_generate_tests(metafunc): - """ - Generates tests for the examples/ as well as tests/ subdirectories. - - Examples: - These tests evaluate all of the files under the examples/ directory - using the configuration in the provided config file in order detect - what should be run. It is assumed that all files are valid and complete - so that they can be wholly included into the specification. The - .config.json file in each directory defines which schema will be used. - - Validation: - These test consumes https://github.com/json-schema-org/JSON-Schema-Test-Suite#structure-of-a-test - styled JSON tests. Metadata in each test defines which schema is used - and whether or not the block is considered valid. - """ - if "suite" in metafunc.fixturenames: - suites: List[Schema] = [] - ids: List[str] = [] - - # Validation - for filename in glob.glob("tests/*.json"): - with open(filename) as o: - suite = json.load(o) - schema = suite["schema"] - with open(schema["id"]) as f: - schema = json.load(f) - for test in suite["tests"]: - ids.append("validate_" + str(test["formerly"]).split("/")[-1][0:-5]) - suites.append(Suite(schema, test["data"], test["valid"])) - - # Examples - for config_filename in glob.glob("examples/*/.config.json"): - with open(config_filename) as o: - data = json.load(o) - schema = data["schema"] - with open(schema) as f: - schema = json.load(f) - example_folder = os.path.dirname(config_filename) - for filename in glob.glob(f"{example_folder}/*.json"): - with open(filename) as f: - # Strip comments - data = ''.join(line for line in f if not line.lstrip().startswith('//')) - data = json.loads(data) - ids.append("example_" + str(filename).split("/")[-1][0:-5]) - suites.append(Suite(schema, data, True)) # Assume true - - metafunc.parametrize("suite", suites, ids=ids, indirect=True) - - -@pytest.fixture -def suite(request): - return request.param - - -def test_run(suite): - resolver = RefResolver.from_schema(suite.schema, store=schema_store) - validator = Validator(suite.schema, resolver=resolver) - suite.validate(validator) diff --git a/0.4/tests/well_suite.json b/0.4/tests/well_suite.json deleted file mode 100644 index 0f752551..00000000 --- a/0.4/tests/well_suite.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "description": "Tests for the well JSON schema", - "schema": { - "id": "schemas/well.schema" - }, - "tests": [ - { - "formerly": "well/minimal_no_acquisition", - "data": { - "well": { - "images": [ - { - "path": "0" - } - ] - } - }, - "valid": true - }, - { - "formerly": "well/minimal_acquisitions", - "data": { - "well": { - "images": [ - { - "acquisition": 1, - "path": "0" - } - ] - } - }, - "valid": true - }, - { - "formerly": "well/empty_images", - "data": { - "well": { - "images": [] - } - }, - "valid": false - }, - { - "formerly": "well/duplicate_images", - "data": { - "well": { - "images": [ - { - "path": "0" - }, - { - "path": "0" - } - ] - } - }, - "valid": false - }, - { - "formerly": "well/invalid_version", - "data": { - "well": { - "images": [ - { - "path": "0" - } - ], - "version": "foo" - } - }, - "valid": false - }, - { - "formerly": "well/non_integer_acquisition_id", - "data": { - "well": { - "images": [ - { - "acquisition": "0", - "path": "0" - } - ] - } - }, - "valid": false - } - ] -} diff --git a/0.5/copyright.include b/0.5/copyright.include deleted file mode 100644 index f0def708..00000000 --- a/0.5/copyright.include +++ /dev/null @@ -1,4 +0,0 @@ -Copyright © 2020-[YEAR] -OME® -(U. Dundee). -OME trademark rules apply. diff --git a/0.5/examples/bf2raw/.config.json b/0.5/examples/bf2raw/.config.json deleted file mode 100644 index 2525328c..00000000 --- a/0.5/examples/bf2raw/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/bf2raw.schema" -} diff --git a/0.5/examples/label_strict/.config.json b/0.5/examples/label_strict/.config.json deleted file mode 100644 index e7329dc9..00000000 --- a/0.5/examples/label_strict/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/strict_label.schema" -} diff --git a/0.5/examples/multiscales_strict/.config.json b/0.5/examples/multiscales_strict/.config.json deleted file mode 100644 index b0469538..00000000 --- a/0.5/examples/multiscales_strict/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/strict_image.schema" -} diff --git a/0.5/examples/ome/.config.json b/0.5/examples/ome/.config.json deleted file mode 100644 index 8a611ccf..00000000 --- a/0.5/examples/ome/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/ome.schema" -} diff --git a/0.5/examples/plate_strict/.config.json b/0.5/examples/plate_strict/.config.json deleted file mode 100644 index a49b1743..00000000 --- a/0.5/examples/plate_strict/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/strict_plate.schema" -} diff --git a/0.5/examples/well_strict/.config.json b/0.5/examples/well_strict/.config.json deleted file mode 100644 index 129ac69c..00000000 --- a/0.5/examples/well_strict/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/strict_well.schema" -} diff --git a/0.5/header.include b/0.5/header.include deleted file mode 100644 index e98bf6fe..00000000 --- a/0.5/header.include +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - [TITLE] - - - -
- - - OME logo (6 circles in a hexagon) - -

[TITLE]

-

[LONGSTATUS], -

-
-
- -
-
- -
- -

Status of this document

-
-
- - -
diff --git a/0.5/tox.ini b/0.5/tox.ini deleted file mode 100644 index 632ca64e..00000000 --- a/0.5/tox.ini +++ /dev/null @@ -1,10 +0,0 @@ -[tox] -envlist = v04 -skipsdist = True - -[testenv] -deps = - pytest - jsonschema -commands = - pytest tests --color=yes --basetemp={envtmpdir} {posargs:-v} \ No newline at end of file diff --git a/conf.py b/conf.py index 5f64deaa..c8019656 100644 --- a/conf.py +++ b/conf.py @@ -71,6 +71,14 @@ def bikeshed(): run_bikeshed = True + for version in ["0.1", "0.2", "0.3", "0.4", "0.5"]: + os.makedirs(".cache", exist_ok=True) + subprocess.check_call( + f"git clone --depth=1 --branch {version}.0 https://github.com/ome/ngff.git .cache/{version}", + shell=True, + ) + os.symlink(f".cache/{version}/{version}", f"{version}") + # Give the loop a chance to skip files if no build is needed/requested if "BIKESHED" not in os.environ and os.path.exists(output_file): src_time = os.path.getmtime(index_file) diff --git a/latest b/latest deleted file mode 120000 index ea2303bc..00000000 --- a/latest +++ /dev/null @@ -1 +0,0 @@ -0.5 \ No newline at end of file diff --git a/0.1/copyright.include b/spec/copyright.include similarity index 100% rename from 0.1/copyright.include rename to spec/copyright.include diff --git a/0.4/examples/bf2raw/.config.json b/spec/examples/bf2raw/.config.json similarity index 100% rename from 0.4/examples/bf2raw/.config.json rename to spec/examples/bf2raw/.config.json diff --git a/0.5/examples/bf2raw/image.json b/spec/examples/bf2raw/image.json similarity index 100% rename from 0.5/examples/bf2raw/image.json rename to spec/examples/bf2raw/image.json diff --git a/0.5/examples/bf2raw/plate.json b/spec/examples/bf2raw/plate.json similarity index 100% rename from 0.5/examples/bf2raw/plate.json rename to spec/examples/bf2raw/plate.json diff --git a/0.4/examples/label_strict/.config.json b/spec/examples/label_strict/.config.json similarity index 100% rename from 0.4/examples/label_strict/.config.json rename to spec/examples/label_strict/.config.json diff --git a/0.5/examples/label_strict/colors_properties.json b/spec/examples/label_strict/colors_properties.json similarity index 100% rename from 0.5/examples/label_strict/colors_properties.json rename to spec/examples/label_strict/colors_properties.json diff --git a/0.4/examples/multiscales_strict/.config.json b/spec/examples/multiscales_strict/.config.json similarity index 100% rename from 0.4/examples/multiscales_strict/.config.json rename to spec/examples/multiscales_strict/.config.json diff --git a/0.5/examples/multiscales_strict/multiscales_example.json b/spec/examples/multiscales_strict/multiscales_example.json similarity index 100% rename from 0.5/examples/multiscales_strict/multiscales_example.json rename to spec/examples/multiscales_strict/multiscales_example.json diff --git a/0.5/examples/multiscales_strict/multiscales_transformations.json b/spec/examples/multiscales_strict/multiscales_transformations.json similarity index 100% rename from 0.5/examples/multiscales_strict/multiscales_transformations.json rename to spec/examples/multiscales_strict/multiscales_transformations.json diff --git a/0.4/examples/ome/.config.json b/spec/examples/ome/.config.json similarity index 100% rename from 0.4/examples/ome/.config.json rename to spec/examples/ome/.config.json diff --git a/0.5/examples/ome/series-2.json b/spec/examples/ome/series-2.json similarity index 100% rename from 0.5/examples/ome/series-2.json rename to spec/examples/ome/series-2.json diff --git a/0.4/examples/plate_strict/.config.json b/spec/examples/plate_strict/.config.json similarity index 100% rename from 0.4/examples/plate_strict/.config.json rename to spec/examples/plate_strict/.config.json diff --git a/0.5/examples/plate_strict/plate_2wells.json b/spec/examples/plate_strict/plate_2wells.json similarity index 100% rename from 0.5/examples/plate_strict/plate_2wells.json rename to spec/examples/plate_strict/plate_2wells.json diff --git a/0.5/examples/plate_strict/plate_6wells.json b/spec/examples/plate_strict/plate_6wells.json similarity index 100% rename from 0.5/examples/plate_strict/plate_6wells.json rename to spec/examples/plate_strict/plate_6wells.json diff --git a/0.4/examples/well_strict/.config.json b/spec/examples/well_strict/.config.json similarity index 100% rename from 0.4/examples/well_strict/.config.json rename to spec/examples/well_strict/.config.json diff --git a/0.5/examples/well_strict/well_2fields.json b/spec/examples/well_strict/well_2fields.json similarity index 100% rename from 0.5/examples/well_strict/well_2fields.json rename to spec/examples/well_strict/well_2fields.json diff --git a/0.5/examples/well_strict/well_4fields.json b/spec/examples/well_strict/well_4fields.json similarity index 100% rename from 0.5/examples/well_strict/well_4fields.json rename to spec/examples/well_strict/well_4fields.json diff --git a/0.3/header.include b/spec/header.include similarity index 100% rename from 0.3/header.include rename to spec/header.include diff --git a/0.5/index.bs b/spec/index.bs similarity index 100% rename from 0.5/index.bs rename to spec/index.bs diff --git a/0.5/schemas/_version.schema b/spec/schemas/_version.schema similarity index 100% rename from 0.5/schemas/_version.schema rename to spec/schemas/_version.schema diff --git a/0.5/schemas/bf2raw.schema b/spec/schemas/bf2raw.schema similarity index 100% rename from 0.5/schemas/bf2raw.schema rename to spec/schemas/bf2raw.schema diff --git a/0.5/schemas/image.schema b/spec/schemas/image.schema similarity index 100% rename from 0.5/schemas/image.schema rename to spec/schemas/image.schema diff --git a/0.5/schemas/label.schema b/spec/schemas/label.schema similarity index 100% rename from 0.5/schemas/label.schema rename to spec/schemas/label.schema diff --git a/0.5/schemas/ome.schema b/spec/schemas/ome.schema similarity index 100% rename from 0.5/schemas/ome.schema rename to spec/schemas/ome.schema diff --git a/0.5/schemas/ome_zarr.schema b/spec/schemas/ome_zarr.schema similarity index 100% rename from 0.5/schemas/ome_zarr.schema rename to spec/schemas/ome_zarr.schema diff --git a/0.5/schemas/plate.schema b/spec/schemas/plate.schema similarity index 100% rename from 0.5/schemas/plate.schema rename to spec/schemas/plate.schema diff --git a/0.5/schemas/strict_image.schema b/spec/schemas/strict_image.schema similarity index 100% rename from 0.5/schemas/strict_image.schema rename to spec/schemas/strict_image.schema diff --git a/0.5/schemas/strict_label.schema b/spec/schemas/strict_label.schema similarity index 100% rename from 0.5/schemas/strict_label.schema rename to spec/schemas/strict_label.schema diff --git a/0.5/schemas/strict_plate.schema b/spec/schemas/strict_plate.schema similarity index 100% rename from 0.5/schemas/strict_plate.schema rename to spec/schemas/strict_plate.schema diff --git a/0.5/schemas/strict_well.schema b/spec/schemas/strict_well.schema similarity index 100% rename from 0.5/schemas/strict_well.schema rename to spec/schemas/strict_well.schema diff --git a/0.5/schemas/well.schema b/spec/schemas/well.schema similarity index 100% rename from 0.5/schemas/well.schema rename to spec/schemas/well.schema diff --git a/0.5/tests/image_suite.json b/spec/tests/image_suite.json similarity index 100% rename from 0.5/tests/image_suite.json rename to spec/tests/image_suite.json diff --git a/0.5/tests/label_suite.json b/spec/tests/label_suite.json similarity index 100% rename from 0.5/tests/label_suite.json rename to spec/tests/label_suite.json diff --git a/0.5/tests/plate_suite.json b/spec/tests/plate_suite.json similarity index 100% rename from 0.5/tests/plate_suite.json rename to spec/tests/plate_suite.json diff --git a/0.5/tests/strict_image_suite.json b/spec/tests/strict_image_suite.json similarity index 100% rename from 0.5/tests/strict_image_suite.json rename to spec/tests/strict_image_suite.json diff --git a/0.5/tests/strict_label_suite.json b/spec/tests/strict_label_suite.json similarity index 100% rename from 0.5/tests/strict_label_suite.json rename to spec/tests/strict_label_suite.json diff --git a/0.5/tests/strict_plate_suite.json b/spec/tests/strict_plate_suite.json similarity index 100% rename from 0.5/tests/strict_plate_suite.json rename to spec/tests/strict_plate_suite.json diff --git a/0.5/tests/strict_well_suite.json b/spec/tests/strict_well_suite.json similarity index 100% rename from 0.5/tests/strict_well_suite.json rename to spec/tests/strict_well_suite.json diff --git a/0.5/tests/test_validation.py b/spec/tests/test_validation.py similarity index 100% rename from 0.5/tests/test_validation.py rename to spec/tests/test_validation.py diff --git a/0.5/tests/well_suite.json b/spec/tests/well_suite.json similarity index 100% rename from 0.5/tests/well_suite.json rename to spec/tests/well_suite.json diff --git a/0.4/tox.ini b/spec/tox.ini similarity index 100% rename from 0.4/tox.ini rename to spec/tox.ini From d7bd5b33e74c4f547e111b3abb50b5e6807ccb65 Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Tue, 3 Dec 2024 20:35:27 +0100 Subject: [PATCH 02/13] no 0.5 tag yet --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index c8019656..e44ee1b5 100644 --- a/conf.py +++ b/conf.py @@ -71,7 +71,7 @@ def bikeshed(): run_bikeshed = True - for version in ["0.1", "0.2", "0.3", "0.4", "0.5"]: + for version in ["0.1", "0.2", "0.3", "0.4"]: os.makedirs(".cache", exist_ok=True) subprocess.check_call( f"git clone --depth=1 --branch {version}.0 https://github.com/ome/ngff.git .cache/{version}", From ca9fbaf5623d40e7e96b832126b7b5a240f83317 Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Tue, 3 Dec 2024 20:38:59 +0100 Subject: [PATCH 03/13] latest --- conf.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/conf.py b/conf.py index e44ee1b5..24f77fab 100644 --- a/conf.py +++ b/conf.py @@ -64,6 +64,15 @@ def bikeshed(): import shutil import subprocess + for version in ["0.1", "0.2", "0.3", "0.4"]: + os.makedirs(".cache", exist_ok=True) + subprocess.check_call( + f"git clone --depth=1 --branch {version}.0 https://github.com/ome/ngff.git .cache/{version}", + shell=True, + ) + os.symlink(f".cache/{version}/{version}", f"{version}") + os.symlink("spec", "latest") + for index_file in ["latest/index.bs"] + glob.glob("[0-9]*/index.bs"): output_file = index_file.replace("bs", "html") output_dir = os.path.dirname(output_file) @@ -71,14 +80,6 @@ def bikeshed(): run_bikeshed = True - for version in ["0.1", "0.2", "0.3", "0.4"]: - os.makedirs(".cache", exist_ok=True) - subprocess.check_call( - f"git clone --depth=1 --branch {version}.0 https://github.com/ome/ngff.git .cache/{version}", - shell=True, - ) - os.symlink(f".cache/{version}/{version}", f"{version}") - # Give the loop a chance to skip files if no build is needed/requested if "BIKESHED" not in os.environ and os.path.exists(output_file): src_time = os.path.getmtime(index_file) From e2c116fd9b8c7d5e65bace64fe227200f2da3254 Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Tue, 3 Dec 2024 20:44:14 +0100 Subject: [PATCH 04/13] use main for now --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 24f77fab..1adf8a55 100644 --- a/conf.py +++ b/conf.py @@ -67,7 +67,7 @@ def bikeshed(): for version in ["0.1", "0.2", "0.3", "0.4"]: os.makedirs(".cache", exist_ok=True) subprocess.check_call( - f"git clone --depth=1 --branch {version}.0 https://github.com/ome/ngff.git .cache/{version}", + f"git clone --depth=1 --branch main https://github.com/ome/ngff.git .cache/{version}", shell=True, ) os.symlink(f".cache/{version}/{version}", f"{version}") From 7d644ada0f0ec988c3e269271f351a1404dd9b63 Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Tue, 3 Dec 2024 21:09:18 +0100 Subject: [PATCH 05/13] 0.5 again --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 1adf8a55..fb361976 100644 --- a/conf.py +++ b/conf.py @@ -64,7 +64,7 @@ def bikeshed(): import shutil import subprocess - for version in ["0.1", "0.2", "0.3", "0.4"]: + for version in ["0.1", "0.2", "0.3", "0.4", "0.5"]: os.makedirs(".cache", exist_ok=True) subprocess.check_call( f"git clone --depth=1 --branch main https://github.com/ome/ngff.git .cache/{version}", From e661b533c52235ea1f338b3fae9d3869ad4a876c Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 4 Dec 2024 21:06:42 +0100 Subject: [PATCH 06/13] WIP: pre-submodules --- Makefile | 7 ++++++- conf.py | 18 ++++++++++++++---- specifications/index.md | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index d4bb2cbb..13d18b31 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,12 @@ BUILDDIR = _build help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -.PHONY: help Makefile +.PHONY: help Makefile clean + + +clean: Makefile + rm -rf .cache 0.1 0.2 0.3 0.4 0.5 draft + @$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). diff --git a/conf.py b/conf.py index fb361976..f0b80eb2 100644 --- a/conf.py +++ b/conf.py @@ -64,16 +64,26 @@ def bikeshed(): import shutil import subprocess - for version in ["0.1", "0.2", "0.3", "0.4", "0.5"]: + branches = subprocess.check_output( + f"git branch -l v/*", + shell=True, + ).split() + branches = [x.decode("utf-8").strip() for x in branches] + # TODO: generate specifications/index.md + for branch in branches: + version = branch[2:] os.makedirs(".cache", exist_ok=True) subprocess.check_call( - f"git clone --depth=1 --branch main https://github.com/ome/ngff.git .cache/{version}", + #f"git clone --depth=1 --branch v/{version} https://github.com/ome/ngff.git .cache/{version}", + f"git clone --depth=1 --branch {branch} . .cache/{version}", shell=True, ) os.symlink(f".cache/{version}/{version}", f"{version}") - os.symlink("spec", "latest") - for index_file in ["latest/index.bs"] + glob.glob("[0-9]*/index.bs"): + # TODO: skip this step on a tag + os.symlink("spec", "draft") + + for index_file in ["draft/index.bs"] + glob.glob("[0-9]*/index.bs"): output_file = index_file.replace("bs", "html") output_dir = os.path.dirname(output_file) target_dir = os.path.join("_bikeshed", output_dir) diff --git a/specifications/index.md b/specifications/index.md index b33772b6..677e86c8 100644 --- a/specifications/index.md +++ b/specifications/index.md @@ -11,5 +11,5 @@ Version history:
  • 0.3 August 2021
  • 0.4 February 2022
  • 0.5 November 2024
  • -
  • latest
  • +
  • draft
  • From c4765ca1fd47d36ffe0e7b0b966e798ecaae58d7 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 4 Dec 2024 21:55:56 +0100 Subject: [PATCH 07/13] Drop spec directory in favor of submodules --- spec/copyright.include | 4 - spec/examples/bf2raw/.config.json | 3 - spec/examples/bf2raw/image.json | 10 - spec/examples/bf2raw/plate.json | 36 - spec/examples/label_strict/.config.json | 3 - .../label_strict/colors_properties.json | 37 - spec/examples/multiscales_strict/.config.json | 3 - .../multiscales_example.json | 68 -- .../multiscales_transformations.json | 47 - spec/examples/ome/.config.json | 3 - spec/examples/ome/series-2.json | 10 - spec/examples/plate_strict/.config.json | 3 - spec/examples/plate_strict/plate_2wells.json | 97 -- spec/examples/plate_strict/plate_6wells.json | 78 -- spec/examples/well_strict/.config.json | 3 - spec/examples/well_strict/well_2fields.json | 21 - spec/examples/well_strict/well_4fields.json | 29 - spec/header.include | 34 - spec/index.bs | 718 ------------ spec/schemas/_version.schema | 10 - spec/schemas/bf2raw.schema | 32 - spec/schemas/image.schema | 268 ----- spec/schemas/label.schema | 91 -- spec/schemas/ome.schema | 33 - spec/schemas/ome_zarr.schema | 24 - spec/schemas/plate.schema | 153 --- spec/schemas/strict_image.schema | 25 - spec/schemas/strict_label.schema | 21 - spec/schemas/strict_plate.schema | 31 - spec/schemas/strict_well.schema | 8 - spec/schemas/well.schema | 56 - spec/tests/image_suite.json | 1040 ----------------- spec/tests/label_suite.json | 158 --- spec/tests/plate_suite.json | 883 -------------- spec/tests/strict_image_suite.json | 341 ------ spec/tests/strict_label_suite.json | 18 - spec/tests/strict_plate_suite.json | 171 --- spec/tests/strict_well_suite.json | 41 - spec/tests/test_validation.py | 125 -- spec/tests/well_suite.json | 80 -- spec/tox.ini | 10 - 41 files changed, 4826 deletions(-) delete mode 100644 spec/copyright.include delete mode 100644 spec/examples/bf2raw/.config.json delete mode 100644 spec/examples/bf2raw/image.json delete mode 100644 spec/examples/bf2raw/plate.json delete mode 100644 spec/examples/label_strict/.config.json delete mode 100644 spec/examples/label_strict/colors_properties.json delete mode 100644 spec/examples/multiscales_strict/.config.json delete mode 100644 spec/examples/multiscales_strict/multiscales_example.json delete mode 100644 spec/examples/multiscales_strict/multiscales_transformations.json delete mode 100644 spec/examples/ome/.config.json delete mode 100644 spec/examples/ome/series-2.json delete mode 100644 spec/examples/plate_strict/.config.json delete mode 100644 spec/examples/plate_strict/plate_2wells.json delete mode 100644 spec/examples/plate_strict/plate_6wells.json delete mode 100644 spec/examples/well_strict/.config.json delete mode 100644 spec/examples/well_strict/well_2fields.json delete mode 100644 spec/examples/well_strict/well_4fields.json delete mode 100644 spec/header.include delete mode 100644 spec/index.bs delete mode 100644 spec/schemas/_version.schema delete mode 100644 spec/schemas/bf2raw.schema delete mode 100644 spec/schemas/image.schema delete mode 100644 spec/schemas/label.schema delete mode 100644 spec/schemas/ome.schema delete mode 100644 spec/schemas/ome_zarr.schema delete mode 100644 spec/schemas/plate.schema delete mode 100644 spec/schemas/strict_image.schema delete mode 100644 spec/schemas/strict_label.schema delete mode 100644 spec/schemas/strict_plate.schema delete mode 100644 spec/schemas/strict_well.schema delete mode 100644 spec/schemas/well.schema delete mode 100644 spec/tests/image_suite.json delete mode 100644 spec/tests/label_suite.json delete mode 100644 spec/tests/plate_suite.json delete mode 100644 spec/tests/strict_image_suite.json delete mode 100644 spec/tests/strict_label_suite.json delete mode 100644 spec/tests/strict_plate_suite.json delete mode 100644 spec/tests/strict_well_suite.json delete mode 100644 spec/tests/test_validation.py delete mode 100644 spec/tests/well_suite.json delete mode 100644 spec/tox.ini diff --git a/spec/copyright.include b/spec/copyright.include deleted file mode 100644 index f0def708..00000000 --- a/spec/copyright.include +++ /dev/null @@ -1,4 +0,0 @@ -Copyright © 2020-[YEAR] -OME® -(U. Dundee). -OME trademark rules apply. diff --git a/spec/examples/bf2raw/.config.json b/spec/examples/bf2raw/.config.json deleted file mode 100644 index 2525328c..00000000 --- a/spec/examples/bf2raw/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/bf2raw.schema" -} diff --git a/spec/examples/bf2raw/image.json b/spec/examples/bf2raw/image.json deleted file mode 100644 index 8fda1fd2..00000000 --- a/spec/examples/bf2raw/image.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "zarr_format": 3, - "node_type": "group", - "attributes": { - "ome": { - "version": "0.5", - "bioformats2raw.layout": 3 - } - } -} diff --git a/spec/examples/bf2raw/plate.json b/spec/examples/bf2raw/plate.json deleted file mode 100644 index ef1ac0a7..00000000 --- a/spec/examples/bf2raw/plate.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "zarr_format": 3, - "node_type": "group", - "attributes": { - "ome": { - "version": "0.5", - "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 - } - ] - } - } - } -} diff --git a/spec/examples/label_strict/.config.json b/spec/examples/label_strict/.config.json deleted file mode 100644 index e7329dc9..00000000 --- a/spec/examples/label_strict/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/strict_label.schema" -} diff --git a/spec/examples/label_strict/colors_properties.json b/spec/examples/label_strict/colors_properties.json deleted file mode 100644 index fa1f4cd6..00000000 --- a/spec/examples/label_strict/colors_properties.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "zarr_format": 3, - "node_type": "group", - "attributes": { - "ome": { - "version": "0.5", - "image-label": { - "colors": [ - { - "label-value": 0, - "rgba": [0, 0, 128, 128] - }, - { - "label-value": 1, - "rgba": [0, 128, 0, 128] - } - ], - "properties": [ - { - "label-value": 0, - "area (pixels)": 1200, - "class": "intercellular space" - }, - { - "label-value": 1, - "area (pixels)": 1650, - "class": "cell", - "cell type": "neuron" - } - ], - "source": { - "image": "../../" - } - } - } - } -} diff --git a/spec/examples/multiscales_strict/.config.json b/spec/examples/multiscales_strict/.config.json deleted file mode 100644 index b0469538..00000000 --- a/spec/examples/multiscales_strict/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/strict_image.schema" -} diff --git a/spec/examples/multiscales_strict/multiscales_example.json b/spec/examples/multiscales_strict/multiscales_example.json deleted file mode 100644 index 4b2c718a..00000000 --- a/spec/examples/multiscales_strict/multiscales_example.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "zarr_format": 3, - "node_type": "group", - "attributes": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "name": "example", - "axes": [ - { "name": "t", "type": "time", "unit": "millisecond" }, - { "name": "c", "type": "channel" }, - { "name": "z", "type": "space", "unit": "micrometer" }, - { "name": "y", "type": "space", "unit": "micrometer" }, - { "name": "x", "type": "space", "unit": "micrometer" } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - // the voxel size for the first scale level (0.5 micrometer) - "type": "scale", - "scale": [1.0, 1.0, 0.5, 0.5, 0.5] - } - ] - }, - { - "path": "1", - "coordinateTransformations": [ - { - // 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] - } - ] - }, - { - "path": "2", - "coordinateTransformations": [ - { - // 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 - "type": "scale", - "scale": [0.1, 1.0, 1.0, 1.0, 1.0] - } - ], - "type": "gaussian", - "metadata": { - "description": "the fields in metadata depend on the downscaling implementation. Here, the parameters passed to the skimage function are given", - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": "[true]", - "kwargs": { "multichannel": true } - } - } - ] - } - } -} diff --git a/spec/examples/multiscales_strict/multiscales_transformations.json b/spec/examples/multiscales_strict/multiscales_transformations.json deleted file mode 100644 index e4eb742a..00000000 --- a/spec/examples/multiscales_strict/multiscales_transformations.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "zarr_format": 3, - "node_type": "group", - "attributes": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ], - "coordinateTransformations": [ - { - "scale": [10, 10], - "type": "scale" - } - ], - "name": "image_with_coordinateTransformations", - "type": "foo", - "metadata": { - "key": "value" - } - } - ] - } - } -} diff --git a/spec/examples/ome/.config.json b/spec/examples/ome/.config.json deleted file mode 100644 index 8a611ccf..00000000 --- a/spec/examples/ome/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/ome.schema" -} diff --git a/spec/examples/ome/series-2.json b/spec/examples/ome/series-2.json deleted file mode 100644 index ad4c25e8..00000000 --- a/spec/examples/ome/series-2.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "zarr_format": 3, - "node_type": "group", - "attributes": { - "ome": { - "version": "0.5", - "series": ["0", "1"] - } - } -} diff --git a/spec/examples/plate_strict/.config.json b/spec/examples/plate_strict/.config.json deleted file mode 100644 index a49b1743..00000000 --- a/spec/examples/plate_strict/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/strict_plate.schema" -} diff --git a/spec/examples/plate_strict/plate_2wells.json b/spec/examples/plate_strict/plate_2wells.json deleted file mode 100644 index e8961001..00000000 --- a/spec/examples/plate_strict/plate_2wells.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "zarr_format": 3, - "node_type": "group", - "attributes": { - "ome": { - "version": "0.5", - "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" - } - ], - "wells": [ - { - "path": "C/5", - "rowIndex": 2, - "columnIndex": 4 - }, - { - "path": "D/7", - "rowIndex": 3, - "columnIndex": 6 - } - ] - } - } - } -} diff --git a/spec/examples/plate_strict/plate_6wells.json b/spec/examples/plate_strict/plate_6wells.json deleted file mode 100644 index bf1b8afe..00000000 --- a/spec/examples/plate_strict/plate_6wells.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "zarr_format": 3, - "node_type": "group", - "attributes": { - "ome": { - "version": "0.5", - "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" - } - ], - "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 - } - ] - } - } - } -} diff --git a/spec/examples/well_strict/.config.json b/spec/examples/well_strict/.config.json deleted file mode 100644 index 129ac69c..00000000 --- a/spec/examples/well_strict/.config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "schema": "schemas/strict_well.schema" -} diff --git a/spec/examples/well_strict/well_2fields.json b/spec/examples/well_strict/well_2fields.json deleted file mode 100644 index 987fe5e4..00000000 --- a/spec/examples/well_strict/well_2fields.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "zarr_format": 3, - "node_type": "group", - "attributes": { - "ome": { - "version": "0.5", - "well": { - "images": [ - { - "acquisition": 0, - "path": "0" - }, - { - "acquisition": 3, - "path": "1" - } - ] - } - } - } -} diff --git a/spec/examples/well_strict/well_4fields.json b/spec/examples/well_strict/well_4fields.json deleted file mode 100644 index 581ec66b..00000000 --- a/spec/examples/well_strict/well_4fields.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "zarr_format": 3, - "node_type": "group", - "attributes": { - "ome": { - "version": "0.5", - "well": { - "images": [ - { - "acquisition": 1, - "path": "0" - }, - { - "acquisition": 1, - "path": "1" - }, - { - "acquisition": 2, - "path": "2" - }, - { - "acquisition": 2, - "path": "3" - } - ] - } - } - } -} diff --git a/spec/header.include b/spec/header.include deleted file mode 100644 index e98bf6fe..00000000 --- a/spec/header.include +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - [TITLE] - - - -
    - - - OME logo (6 circles in a hexagon) - -

    [TITLE]

    -

    [LONGSTATUS], -

    -
    -
    - -
    -
    - -
    - -

    Status of this document

    -
    -
    - - -
    diff --git a/spec/index.bs b/spec/index.bs deleted file mode 100644 index 474119e3..00000000 --- a/spec/index.bs +++ /dev/null @@ -1,718 +0,0 @@ - - -OME-Zarr specification {#ome-zarr} ----------------------------------- - -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](http://www.openmicroscopy.org/ome-files/) -and beyond. - -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](https://tools.ietf.org/html/rfc2119). - -

    -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 [[#bf2raw]]) -

    - -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. - -Storage format {#storage-format} -================================ - -OME-Zarr is implemented using the Zarr format as defined by the -[version 3 of the Zarr specification](https://zarr-specs.readthedocs.io/en/latest/v3/core/v3.0.html). -All features of the Zarr format including codecs, chunk grids, chunk -key encodings, data types and storage transformers may be used with -OME-Zarr unless explicitly disallowed in this specification. - -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 -be stored on a web server to be accessed via HTTP or in object storage -like S3 or GCS. - -Images {#image-layout} ----------------------- - -The following layout describes the expected Zarr hierarchy for images with -multiple levels of resolutions and optionally associated labels. -Note that the number of dimensions is variable between 2 and 5 and that axis names are arbitrary, see [[#multiscale-md]] for details. - -
    -├── 123.zarr                  # One OME-Zarr image (id=123).
    -│   ...
    -│
    -└── 456.zarr                  # Another OME-Zarr image (id=456).
    -    │
    -    ├── zarr.json             # Each image is a Zarr group of other groups and arrays.
    -    │                         # Group level attributes are stored in the `zarr.json` file and include
    -    │                         # "multiscales" and "omero" (see below).
    -    │
    -    ├── 0                     # Each multiscale level is stored as a separate Zarr array,
    -    │   ...                   # which is a folder containing chunk files which compose the array.
    -    ├── n                     # The name of the array is arbitrary with the ordering defined by
    -    │   │                     # by the "multiscales" metadata, but is often a sequence starting at 0.
    -    │   │
    -    │   ├── zarr.json         # All image arrays must be up to 5-dimensional
    -    │   │                     # with the axis of type time before type channel, before spatial axes.
    -    │   │
    -    │   └─ ...                # Chunks are stored conforming to the Zarr array specification and 
    -    │                         # metadata as specified in the array's `zarr.json`.
    -    │
    -    └── labels
    -        │
    -        ├── zarr.json         # The labels group is a container which holds a list of labels to make the objects easily discoverable
    -        │                     # All labels will be listed in `zarr.json` e.g. `{ "labels": [ "original/0" ] }`
    -        │                     # Each dimension of the label 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.
    -            │
    -            └── 0             # Multiscale, labeled image. The name is unimportant but is registered in the "labels" group above.
    -                ├── zarr.json # Zarr Group which is both a multiscaled image as well as a labeled image.
    -                │             # Metadata of the related image and as well as display information under the "image-label" key.
    -                │
    -                ├── 0         # Each multiscale level is stored as a separate Zarr array, as above, but only integer values
    -                └── ...       # are supported.
    -                
    -
    - - - -High-content screening {#hcs-layout} ------------------------------------- - -The following specification defines the hierarchy for a high-content screening -dataset. Three groups MUST be defined above the images: - -- the group above the images defines the well and MUST implement the - [well specification](#well-md). All images contained in a well are fields - of view of the same well -- the group above the well defines a row of wells -- the group above the well row defines an entire plate i.e. a two-dimensional - collection of wells organized in rows and columns. It MUST implement the - [plate specification](#plate-md) - -A well row group SHOULD NOT be present if there are no images in the well row. -A well group SHOULD NOT be present if there are no images in the well. - - -
    -.
    -│
    -└── 5966.zarr                 # One OME-Zarr plate (id=5966)
    -    ├── zarr.json             # Implements "plate" specification
    -    ├── A                     # First row of the plate
    -    │   ├── zarr.json
    -    │   │
    -    │   ├── 1                 # First column of row A
    -    │   │   ├── zarr.json     # Implements "well" specification
    -    │   │   │
    -    │   │   ├── 0             # First field of view of well A1
    -    │   │   │   │
    -    │   │   │   ├── zarr.json # Implements "multiscales", "omero"
    -    │   │   │   ├── 0         # Resolution levels          
    -    │   │   │   ├── ...
    -    │   │   │   └── labels    # Labels (optional)
    -    │   │   └── ...           # Other fields of view
    -    │   └── ...               # Other columns
    -    └── ...                   # Other rows
    -
    - -OME-Zarr Metadata {#metadata} -============================= - -The "OME-Zarr Metadata" contains metadata keys as specified below -for discovering certain types of data, especially images. - -The OME-Zarr Metadata is stored in the various `zarr.json` files throughout the above array -hierarchy. In this file, the metadata is stored under the namespaced key -`ome` in `attributes`. -The version of the OME-Zarr Metadata is denoted as a string in the `version` attribute within the `ome` namespace. - -The OME-Zarr Metadata version MUST be consistent within a hierarchy. - -```json -{ - ... - "attributes": { - "ome": { - "version": "0.5", - ... - } - } -} -``` - -"axes" metadata {#axes-md} --------------------------- - -"axes" describes the dimensions of a physical coordinate space. It is a list of dictionaries, where each dictionary describes a dimension (axis) and: -- MUST contain the field "name" that gives the name for this dimension. The values MUST be unique across all "name" fields. -- SHOULD contain the field "type". It SHOULD be one of "space", "time" or "channel", but MAY take other string values for custom axis types that are not part of this specification yet. -- SHOULD contain the field "unit" to specify the physical unit of this dimension. The value SHOULD be one of the following strings, which are valid units according to UDUNITS-2. - - Units for "space" axes: 'angstrom', 'attometer', 'centimeter', 'decimeter', 'exameter', 'femtometer', 'foot', 'gigameter', 'hectometer', 'inch', 'kilometer', 'megameter', 'meter', 'micrometer', 'mile', 'millimeter', 'nanometer', 'parsec', 'petameter', 'picometer', 'terameter', 'yard', 'yoctometer', 'yottameter', 'zeptometer', 'zettameter' - - 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' - -The "axes" are used as part of [[#multiscale-md]]. The length of "axes" MUST be equal to the number of dimensions of the arrays that contain the image data. - -The "dimension_names" attribute in the `zarr.json` of the Zarr array of a multiscale level MUST match the names in the "axes" metadata. - - -"bioformats2raw.layout" (transitional) {#bf2raw} ------------------------------------------------- - -[=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-Zarr 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. - -

    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
    -    ├── zarr.json             # Contains "bioformats2raw.layout" metadata
    -    ├── OME                   # Special group for containing OME metadata
    -    │   ├── zarr.json         # 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
    -    └── ...
    -
    - -

    Attributes

    - -The OME-Zarr Metadata in the top-level `zarr.json` file must contain the `bioformats2raw.layout` key: -
    -path: examples/bf2raw/image.json
    -highlight: json
    -
    - -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 [[#plate-md]]. It is not -possible to mix collections of images with plates at present. - -
    -path: examples/bf2raw/plate.json
    -highlight: json
    -
    - -The OME-Zarr Metadata in the `zarr.json` file within the OME group may contain the "series" key: - -
    -path: examples/ome/series-2.json
    -highlight: json
    -
    - -

    Details

    - -Conforming groups: - -- MUST have the value "3" for the "bioformats2raw.layout" key in their OME-Zarr Metadata in the `zarr.json` 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 `` elements as opposed to ``, `` or ``; - - MAY make use of the [minimum specification](https://docs.openmicroscopy.org/ome-model/6.2.2/specifications/minimum.html). - -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. - - -"coordinateTransformations" metadata {#trafo-md} ------------------------------------------------- - -"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". -The value of "type" MUST be one of the elements of the `type` column in the table below. -Additional fields for the entry depend on "type" and are defined by the column `fields`. - - - -
    `identity` identity transformation, is the default transformation and is typically not explicitly defined -
    `translation` one of: `"translation":List[float]`, `"path":str` translation vector, stored either as a list of floats (`"translation"`) or as binary data at a location in this container (`path`). The length of vector defines number of dimensions. | -
    `scale` one of: `"scale":List[float]`, `"path":str` scale vector, stored either as a list of floats (`scale`) or as binary data at a location in this container (`path`). The length of vector defines number of dimensions. | -
    typefieldsdescription -
    - -The transformations in the list are applied sequentially and in order. - - -"multiscales" metadata {#multiscale-md} ---------------------------------------- - -Metadata about an image can be found under the "multiscales" key in the group-level OME-Zarr 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 [[#axes-md]]. -The length of "axes" must be between 2 and 5 and MUST be equal to the dimensionality of the zarr arrays storing the image data (see "datasets:path"). -The "axes" MUST contain 2 or 3 entries of "type:space" and MAY contain one additional entry of "type:time" and MAY contain one additional entry of "type:channel" or a null / custom type. -The order of the entries MUST correspond to the order of dimensions of the zarr arrays. In addition, the entries MUST be ordered by "type" where the "time" axis must come first (if present), followed by the "channel" or custom axis (if present) and the axes of type "space". -If there are three spatial axes where two correspond to the image plane ("yx") and images are stacked along the other (anisotropic) axis ("z"), the spatial axes SHOULD be ordered as "zyx". - -Each "multiscales" dictionary MUST contain the field "datasets", which is a list of dictionaries describing the arrays storing the individual resolution levels. -Each dictionary in "datasets" MUST contain the field "path", whose value contains the path to the array for this resolution relative -to the current zarr group. The "path"s MUST be ordered from largest (i.e. highest resolution) to smallest. - -Each "datasets" dictionary MUST have the same number of dimensions and MUST NOT have more than 5 dimensions. The number of dimensions and order MUST correspond to number and order of "axes". -Each dictionary in "datasets" MUST contain the field "coordinateTransformations", which contains a list of transformations that map the data coordinates to the physical coordinates (as specified by "axes") for this resolution level. -The transformations are defined according to [[#trafo-md]]. The transformation MUST only be of type `translation` or `scale`. -They MUST contain exactly one `scale` transformation that specifies the pixel size in physical units or time duration. If scaling information is not available or applicable for one of the axes, the value MUST express the scaling factor between the current resolution and the first resolution for the given axis, defaulting to 1.0 if there is no downsampling along the axis. -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". -The requirements (only `scale` and `translation`, restrictions on order) are in place to provide a simple mapping from data coordinates to physical coordinates while being compatible with the general transformation spec. - -Each "multiscales" dictionary MAY contain the field "coordinateTransformations", describing transformations that are applied to all resolution levels in the same manner. -The transformations MUST follow the same rules about allowed types, order, etc. as in "datasets:coordinateTransformations" and are applied after them. -They can for example be used to specify the `scale` for a dimension that is the same for all resolutions. - -Each "multiscales" dictionary SHOULD contain the field "name". - -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. - -
    -path: examples/multiscales_strict/multiscales_example.json
    -highlight: json
    -
    - - -If only one multiscale is provided, use it. Otherwise, the user can choose by -name, using the first multiscale as a fallback: - -```python -datasets = [] -for named in multiscales: - if named["name"] == "3D": - datasets = [x["path"] for x in named["datasets"]] - break -if not datasets: - # Use the first by default. Or perhaps choose based on chunk size. - datasets = [x["path"] for x in multiscales[0]["datasets"]] -``` - -"omero" metadata (transitional) {#omero-md} -------------------------------------------- - -[=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: - -```json -"id": 1, # ID in OMERO -"name": "example.tif", # Name as shown in the UI -"channels": [ # Array matching the c dimension size - { - "active": true, - "coefficient": 1, - "color": "0000FF", - "family": "linear", - "inverted": false, - "label": "LaminB1", - "window": { - "end": 1500, - "max": 65535, - "min": 0, - "start": 0 - } - } -], -"rdefs": { - "defaultT": 0, # First timepoint to show the user - "defaultZ": 118, # First Z section to show the user - "model": "color" # "color" or "greyscale" -} -``` - -See the [OMERO WebGateway documentation](https://omero.readthedocs.io/en/stable/developers/Web/WebGateway.html#imgdata) -for more information. - -"labels" metadata {#labels-md} ------------------------------- - -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 OME-Zarr Metadata in the `zarr.json` 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: - -```json -{ - ... - "attributes": { - "ome": { - "version": "0.5", - "labels": [ - "cell_space_segmentation" - ] - } - } -} -``` - -The `zarr.json` 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 OME-Zarr Metadata in this image-level `zarr.json` 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-Zarr `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: - -
    -path: examples/label_strict/colors_properties.json
    -highlight: json
    -
    - -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. - -"plate" metadata {#plate-md} ----------------------------- - -For high-content screening datasets, the plate layout can be found under the -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. - -
    -path: examples/plate_strict/plate_6wells.json
    -highlight: json
    -
    - -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. - -
    -path: examples/plate_strict/plate_2wells.json
    -highlight: json
    -
    - -"well" metadata {#well-md} --------------------------- - -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. - -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. - -
    -path: examples/well_strict/well_4fields.json
    -highlight: json
    -
    - -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. - -
    -path: examples/well_strict/well_2fields.json
    -highlight: json
    -
    - -Specification naming style {#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. - -Implementations {#implementations} -================================== - -See [Tools](https://ngff.openmicroscopy.org/tools/index.html). - -Citing {#citing} -================ - -[Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.](https://ngff.openmicroscopy.org/0.4) -J. Moore, *et al*. Open Microscopy Environment Consortium, 8 February 2022. -This edition of the specification is [https://ngff.openmicroscopy.org/0.5/](https://ngff.openmicroscopy.org/0.5/]). -The latest edition is available at [https://ngff.openmicroscopy.org/latest/](https://ngff.openmicroscopy.org/latest/). -[(doi:10.5281/zenodo.4282107)](https://doi.org/10.5281/zenodo.4282107) - -Version History {#history} -========================== - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    RevisionDateDescription
    0.52024-11-21use Zarr v3 in OME-Zarr, see RFC-2.
    0.4.12023-02-09expand on "labels" description
    0.4.12022-09-26transitional metadata for image collections ("bioformats2raw.layout")
    0.4.02022-02-08multiscales: add axes type, units and coordinateTransformations
    0.4.02022-02-08plate: add rowIndex/columnIndex
    0.3.02021-08-24Add axes field to multiscale metadata
    0.2.02021-03-29Change chunk dimension separator to "/"
    0.1.42020-11-26Add HCS specification
    0.1.32020-09-14Add labels specification
    0.1.2 2020-05-07Add description of "omero" metadata
    0.1.1 2020-05-06Add info on the ordering of resolutions
    0.1.0 2020-04-20First version for internal demo
    - - -
    -{
    -  "blogNov2020": {
    -    "href": "https://blog.openmicroscopy.org/file-formats/community/2020/11/04/zarr-data/",
    -    "title": "Public OME-Zarr data (Nov. 2020)",
    -    "authors": [
    -      "OME Team"
    -    ],
    -    "status": "Informational",
    -    "publisher": "OME",
    -    "id": "blogNov2020",
    -    "date": "04 November 2020"
    -  },
    -  "imagesc26952": {
    -    "href": "https://forum.image.sc/t/ome-s-position-regarding-file-formats/26952",
    -    "title": "OME’s position regarding file formats",
    -    "authors": [
    -      "OME Team"
    -    ],
    -    "status": "Informational",
    -    "publisher": "OME",
    -    "id": "imagesc26952",
    -    "date": "19 June 2020"
    -  },
    -  "n5": {
    -    "id": "n5",
    -    "href": "https://github.com/saalfeldlab/n5/issues/62",
    -    "title": "N5---a scalable Java API for hierarchies of chunked n-dimensional tensors and structured meta-data",
    -    "status": "Informational",
    -    "authors": [
    -      "John A. Bogovic",
    -      "Igor Pisarev",
    -      "Philipp Hanslovsky",
    -      "Neil Thistlethwaite",
    -      "Stephan Saalfeld"
    -    ],
    -    "date": "2020"
    -  },
    -  "ome-zarr-py": {
    -    "id": "ome-zarr-py",
    -    "href": "https://doi.org/10.5281/zenodo.4113931",
    -    "title": "ome-zarr-py: Experimental implementation of next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.",
    -    "status": "Informational",
    -    "publisher": "Zenodo",
    -    "authors": [
    -      "OME",
    -      "et al"
    -    ],
    -    "date": "06 October 2020"
    -  },
    -  "zarr": {
    -    "id": "zarr",
    -    "href": "https://doi.org/10.5281/zenodo.4069231",
    -    "title": "Zarr: An implementation of chunked, compressed, N-dimensional arrays for Python.",
    -    "status": "Informational",
    -    "publisher": "Zenodo",
    -    "authors": [
    -      "Alistair Miles",
    -      "et al"
    -    ],
    -    "date": "06 October 2020"
    -  }
    -}
    -
    diff --git a/spec/schemas/_version.schema b/spec/schemas/_version.schema deleted file mode 100644 index 1da06a6d..00000000 --- a/spec/schemas/_version.schema +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/_version.schema", - "title": "OME-Zarr Metadata version", - "description": "The version of the OME-Zarr Metadata", - "type": "string", - "enum": [ - "0.5" - ] -} diff --git a/spec/schemas/bf2raw.schema b/spec/schemas/bf2raw.schema deleted file mode 100644 index d3c87253..00000000 --- a/spec/schemas/bf2raw.schema +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/bf2raw.schema", - "title": "OME-Zarr container produced by bioformats2raw", - "description": "The zarr.json attributes key", - "type": "object", - "properties": { - "ome": { - "description": "The versioned OME-Zarr Metadata namespace", - "type": "object", - "properties": { - "bioformats2raw.layout": { - "description": "The top-level identifier metadata added by bioformats2raw", - "type": "number", - "enum": [ - 3 - ] - }, - "version": { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/_version.schema" - } - }, - "required": [ - "bioformats2raw.layout", - "version" - ] - } - }, - "required": [ - "ome" - ] -} diff --git a/spec/schemas/image.schema b/spec/schemas/image.schema deleted file mode 100644 index f94fd942..00000000 --- a/spec/schemas/image.schema +++ /dev/null @@ -1,268 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/image.schema", - "title": "OME-Zarr Image", - "description": "The zarr.json attributes key", - "type": "object", - "properties": { - "ome": { - "description": "The versioned OME-Zarr Metadata namespace", - "type": "object", - "properties": { - "multiscales": { - "$ref": "#/$defs/multiscales" - }, - "omero": { - "$ref": "#/$defs/omero" - }, - "version": { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/_version.schema" - } - }, - "required": [ - "multiscales", - "version" - ] - } - }, - "required": [ - "ome" - ], - "$defs": { - "multiscales": { - "description": "The multiscale datasets for this image", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "datasets": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "coordinateTransformations": { - "$ref": "#/$defs/coordinateTransformations" - } - }, - "required": [ - "path", - "coordinateTransformations" - ] - } - }, - "axes": { - "$ref": "#/$defs/axes" - }, - "coordinateTransformations": { - "$ref": "#/$defs/coordinateTransformations" - } - }, - "required": [ - "datasets", - "axes" - ] - }, - "minItems": 1, - "uniqueItems": true - }, - "omero": { - "type": "object", - "properties": { - "channels": { - "type": "array", - "items": { - "type": "object", - "properties": { - "window": { - "type": "object", - "properties": { - "end": { - "type": "number" - }, - "max": { - "type": "number" - }, - "min": { - "type": "number" - }, - "start": { - "type": "number" - } - }, - "required": [ - "start", - "min", - "end", - "max" - ] - }, - "label": { - "type": "string" - }, - "family": { - "type": "string" - }, - "color": { - "type": "string" - }, - "active": { - "type": "boolean" - } - } - } - } - }, - "required": [ - "channels" - ] - }, - "axes": { - "type": "array", - "uniqueItems": true, - "minItems": 2, - "maxItems": 5, - "contains": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "space" - ] - }, - "unit": { - "type": "string" - } - } - }, - "minContains": 2, - "maxContains": 3, - "items": { - "oneOf": [ - { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "channel", - "time", - "space" - ] - } - }, - "required": [ - "name", - "type" - ] - }, - { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "not": { - "enum": [ - "space", - "time", - "channel" - ] - } - } - }, - "required": [ - "name" - ] - } - ] - } - }, - "coordinateTransformations": { - "type": "array", - "minItems": 1, - "contains": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "scale" - ] - }, - "scale": { - "type": "array", - "minItems": 2, - "items": { - "type": "number" - } - } - } - }, - "maxContains": 1, - "items": { - "oneOf": [ - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "scale" - ] - }, - "scale": { - "type": "array", - "minItems": 2, - "items": { - "type": "number" - } - } - }, - "required": [ - "type", - "scale" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "translation" - ] - }, - "translation": { - "type": "array", - "minItems": 2, - "items": { - "type": "number" - } - } - }, - "required": [ - "type", - "translation" - ] - } - ] - } - } - } -} diff --git a/spec/schemas/label.schema b/spec/schemas/label.schema deleted file mode 100644 index dd5cb6d6..00000000 --- a/spec/schemas/label.schema +++ /dev/null @@ -1,91 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/label.schema", - "title": "OME-Zarr labelled image schema", - "description": "The zarr.json attributes key", - "type": "object", - "properties": { - "ome": { - "description": "The versioned OME-Zarr Metadata namespace", - "type": "object", - "properties": { - "image-label": { - "$ref": "#/$defs/image-label" - }, - "version": { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/_version.schema" - } - }, - "required": [ - "image-label", - "version" - ] - } - }, - "required": [ - "ome" - ], - "$defs": { - "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" - } - } - } - } - } - } -} diff --git a/spec/schemas/ome.schema b/spec/schemas/ome.schema deleted file mode 100644 index 36569280..00000000 --- a/spec/schemas/ome.schema +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/ome.schema", - "title": "OME-Zarr group produced by bioformats2raw to contain OME metadata", - "description": "The zarr.json attributes key", - "type": "object", - "properties": { - "ome": { - "description": "The versioned OME-Zarr Metadata namespace", - "type": "object", - "properties": { - "series": { - "description": "An array of the same length and the same order as the images defined in the OME-XML", - "type": "array", - "items": { - "type": "string" - }, - "minContains": 1 - }, - "version": { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/_version.schema" - } - }, - "required": [ - "series", - "version" - ] - } - }, - "required": [ - "ome" - ] -} diff --git a/spec/schemas/ome_zarr.schema b/spec/schemas/ome_zarr.schema deleted file mode 100644 index 9b22bba6..00000000 --- a/spec/schemas/ome_zarr.schema +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/ome_zarr.schema", - "anyOf": [ - { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/bf2raw.schema" - }, - { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/image.schema" - }, - { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/label.schema" - }, - { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/ome.schema" - }, - { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/plate.schema" - }, - { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/well.schema" - } - ] -} diff --git a/spec/schemas/plate.schema b/spec/schemas/plate.schema deleted file mode 100644 index 3c8a1b97..00000000 --- a/spec/schemas/plate.schema +++ /dev/null @@ -1,153 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/plate.schema", - "title": "OME-Zarr plate schema", - "description": "The zarr.json attributes key", - "type": "object", - "properties": { - "ome": { - "description": "The versioned OME-Zarr Metadata namespace", - "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" - ] - } - }, - "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": { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/_version.schema" - } - }, - "required": [ - "plate", - "version" - ] - } - }, - "required": [ - "ome" - ] -} diff --git a/spec/schemas/strict_image.schema b/spec/schemas/strict_image.schema deleted file mode 100644 index 042790e7..00000000 --- a/spec/schemas/strict_image.schema +++ /dev/null @@ -1,25 +0,0 @@ -{ - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/strict_image.schema", - "allOf": [ - { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/image.schema" - }, - { - "properties": { - "ome": { - "properties": { - "multiscales": { - "items": { - "required": [ - "metadata", - "type", - "name" - ] - } - } - } - } - } - } - ] -} diff --git a/spec/schemas/strict_label.schema b/spec/schemas/strict_label.schema deleted file mode 100644 index f1ec4db5..00000000 --- a/spec/schemas/strict_label.schema +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/strict_label.schema", - "allOf": [ - { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/label.schema" - }, - { - "properties": { - "ome": { - "properties": { - "image-label": { - "required": [ - "colors" - ] - } - } - } - } - } - ] -} diff --git a/spec/schemas/strict_plate.schema b/spec/schemas/strict_plate.schema deleted file mode 100644 index ce678ce8..00000000 --- a/spec/schemas/strict_plate.schema +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/strict_plate.schema", - "allOf": [ - { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/plate.schema" - }, - { - "properties": { - "ome": { - "properties": { - "plate": { - "properties": { - "acquisitions": { - "items": { - "required": [ - "name", - "maximumfieldcount" - ] - } - } - }, - "required": [ - "name" - ] - } - } - } - } - } - ] -} diff --git a/spec/schemas/strict_well.schema b/spec/schemas/strict_well.schema deleted file mode 100644 index 43cb58cb..00000000 --- a/spec/schemas/strict_well.schema +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/strict_well.schema", - "allOf": [ - { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/well.schema" - } - ] -} diff --git a/spec/schemas/well.schema b/spec/schemas/well.schema deleted file mode 100644 index 447f51df..00000000 --- a/spec/schemas/well.schema +++ /dev/null @@ -1,56 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.5/schemas/well.schema", - "title": "OME-Zarr well schema", - "description": "JSON from OME-Zarr zarr.json", - "type": "object", - "properties": { - "ome": { - "description": "The versioned OME-Zarr Metadata namespace", - "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 - } - }, - "required": [ - "images" - ] - }, - "version": { - "$ref": "https://ngff.openmicroscopy.org/0.5/schemas/_version.schema" - } - }, - "required": [ - "well", - "version" - ] - } - }, - "required": [ - "ome" - ] -} diff --git a/spec/tests/image_suite.json b/spec/tests/image_suite.json deleted file mode 100644 index df359ce4..00000000 --- a/spec/tests/image_suite.json +++ /dev/null @@ -1,1040 +0,0 @@ -{ - "description": "TBD", - "schema": { - "id": "schemas/image.schema" - }, - "tests": [ - { - "formerly": "valid/mismatch_axes_units.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "t", - "type": "time", - "unit": "micrometer" - }, - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [0.13, 0.13], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": true - }, - { - "formerly": "valid/untyped_axes.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "angle" - }, - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": true - }, - { - "formerly": "valid/invalid_axis_units.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micron" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [0.13, 0.13], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": true - }, - { - "formerly": "valid/missing_name.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "datasets": [ - { - "path": "path/to/0", - "coordinateTransformations": [ - { - "type": "scale", - "scale": [1, 1] - } - ] - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": ["true", "false"], - "kwargs": { - "multichannel": true - } - }, - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ] - } - ] - } - }, - "valid": true - }, - { - "formerly": "valid/custom_type_axes.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "angle", - "type": "custom" - }, - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": true - }, - { - "formerly": "invalid/duplicate_axes.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "x", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/missing_space_axes.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "t", - "type": "time" - }, - { - "name": "c", - "type": "channel" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/invalid_transformation_type.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "translation" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/missing_scale.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "translation": [1, 1], - "type": "translation" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/too_many_axes.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "angle", - "type": "custom" - }, - { - "name": "t", - "type": "time" - }, - { - "name": "c", - "type": "channel" - }, - { - "name": "z", - "type": "space" - }, - { - "name": "y", - "type": "space" - }, - { - "name": "x", - "type": "space" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1, 1, 1, 1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/invalid_channels_color.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ] - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": 255, - "family": "linear", - "label": "1234", - "window": { - "end": 1765.0, - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "invalid/missing_axes_name.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "type": "space", - "unit": "micron" - }, - { - "type": "space", - "unit": "micron" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [0.13, 0.13], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/invalid_axes_count.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/one_space_axes.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "t", - "type": "time" - }, - { - "name": "c", - "type": "channel" - }, - { - "name": "x", - "type": "space" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/invalid_path.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": 0, - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/invalid_multiscales_transformations.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ], - "coordinateTransformations": [ - { - "scale": ["invalid"], - "type": "scale" - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/missing_transformations.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0" - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/no_datasets.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/missing_datasets.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/missing_axes.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/invalid_axis_type.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "invalid", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/duplicate_scale.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - }, - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/no_axes.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/too_many_space_axes.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "X", - "type": "space" - }, - { - "name": "z", - "type": "space" - }, - { - "name": "y", - "type": "space" - }, - { - "name": "x", - "type": "space" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1, 1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/no_multiscales.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [] - } - }, - "valid": false - }, - { - "formerly": "invalid/invalid_channels_window.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ] - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": "ff0000", - "family": "linear", - "label": "1234", - "window": { - "end": "100", - "max": 2555.0, - "min": 5.0, - "start": 0.0 - } - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "invalid/empty_transformations.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [] - } - ] - } - ] - } - }, - "valid": false - }, - { - "formerly": "invalid/missing_path.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ] - } - ] - } - }, - "valid": false - } - ] -} diff --git a/spec/tests/label_suite.json b/spec/tests/label_suite.json deleted file mode 100644 index 66a2d35d..00000000 --- a/spec/tests/label_suite.json +++ /dev/null @@ -1,158 +0,0 @@ -{ - "description": "Tests for the image-label JSON schema", - "schema": { - "id": "schemas/label.schema" - }, - "tests": [ - { - "formerly": "image-label/minimal", - "data": { - "ome": { - "version": "0.5", - "image-label": { - "colors": [ - { - "label-value": 1, - "rgba": [0, 0, 0, 0] - } - ] - } - } - }, - "valid": true - }, - { - "formerly": "image-label/minimal_properties", - "data": { - "ome": { - "version": "0.5", - "image-label": { - "colors": [ - { - "label-value": 1, - "rgba": [0, 0, 0, 0] - } - ], - "properties": [ - { - "label-value": 1 - } - ] - } - } - }, - "valid": true - }, - { - "formerly": "image-label/empty_colors", - "data": { - "ome": { - "version": "0.5", - "image-label": { - "colors": [] - } - } - }, - "valid": false - }, - { - "formerly": "image-label/empty_properties", - "data": { - "ome": { - "version": "0.5", - "image-label": { - "properties": [] - } - } - }, - "valid": false - }, - { - "formerly": "image-label/colors_no_label_value", - "data": { - "ome": { - "version": "0.5", - "image-label": { - "colors": [ - { - "rgba": [0, 0, 0, 0] - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "image-label/properties_no_label_value", - "data": { - "ome": { - "version": "0.5", - "image-label": { - "properties": [ - { - "value": "foo" - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "image-label/colors_rgba_length", - "data": { - "ome": { - "version": "0.5", - "image-label": { - "colors": [ - { - "label-value": 1, - "rgba": [0, 0, 0] - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "image-label/colors_rgba_type", - "data": { - "ome": { - "version": "0.5", - "image-label": { - "colors": [ - { - "label-value": 1, - "rgba": [0, 0, 0, 500] - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "image-label/colors_duplicate", - "data": { - "ome": { - "version": "0.5", - "image-label": { - "colors": [ - { - "label-value": 1, - "rgba": [0, 0, 0, 0] - }, - { - "label-value": 1, - "rgba": [0, 0, 0, 0] - } - ] - } - } - }, - "valid": false - } - ] -} diff --git a/spec/tests/plate_suite.json b/spec/tests/plate_suite.json deleted file mode 100644 index 3db70de7..00000000 --- a/spec/tests/plate_suite.json +++ /dev/null @@ -1,883 +0,0 @@ -{ - "description": "Tests for the plate JSON schema", - "schema": { - "id": "schemas/plate.schema" - }, - "tests": [ - { - "formerly": "plate/minimal_no_acquisitions", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": true - }, - { - "formerly": "plate/minimal_acquisitions", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": 0 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": true - }, - { - "formerly": "plate/missing_rows", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/empty_rows", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/duplicate_rows", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - }, - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/missing_columns", - "data": { - "ome": { - "version": "0.5", - "plate": { - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/empty_columns", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/duplicate_columns", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - }, - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/missing_wells", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/empty_wells", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": {} - } - } - }, - "valid": false - }, - { - "formerly": "plate/duplicate_rows", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - }, - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - }, - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/missing_column_name", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "concentration": 10 - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/missing_row_name", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "concentration": 10 - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/missing_well_path", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/missing_well_rowIndex", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/missing_well_columnIndex", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/well_1group", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A1", - "rowIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/well_3groups", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "plate/A/1", - "rowIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/non_alphanumeric_column", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A-1" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A-1/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/non_alphanumeric_row", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "A1" - } - ], - "wells": [ - { - "path": "A/A1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": true - }, - { - "formerly": "plate/missing_acquisition_id", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "maximumfieldcount": 1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/non_integer_acquisition_id", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": "0" - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/negative_acquisition_id", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": -1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/non_integer_acquisition_maximumfieldcount", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": 0, - "maximumfieldcount": "0" - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/acquisition_zero_maximumfieldcount", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": 0, - "maximumfieldcount": 0 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/acquisition_noninteger_starttime", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": 0, - "starttime": "2022-05-13T13:48:06+00:00" - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/acquisition_negative_starttime", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": 0, - "starttime": -1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/acquisition_noninteger_endtime", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": 0, - "endtime": "2022-05-13T13:48:06+00:00" - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/negative_endtime", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": 0, - "endtime": -1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/zero_field_count", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "field_count": 0, - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - } - ] -} diff --git a/spec/tests/strict_image_suite.json b/spec/tests/strict_image_suite.json deleted file mode 100644 index b52fd2d3..00000000 --- a/spec/tests/strict_image_suite.json +++ /dev/null @@ -1,341 +0,0 @@ -{ - "description": "TBD", - "schema": { - "id": "schemas/strict_image.schema" - }, - "tests": [ - { - "formerly": "valid_strict/multiscales_example.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "name": "example", - "axes": [ - { - "name": "t", - "type": "time", - "unit": "millisecond" - }, - { - "name": "c", - "type": "channel" - }, - { - "name": "z", - "type": "space", - "unit": "micrometer" - }, - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "type": "scale", - "scale": [1.0, 1.0, 0.5, 0.5, 0.5] - } - ] - }, - { - "path": "1", - "coordinateTransformations": [ - { - "type": "scale", - "scale": [1.0, 1.0, 1.0, 1.0, 1.0] - } - ] - }, - { - "path": "2", - "coordinateTransformations": [ - { - "type": "scale", - "scale": [1.0, 1.0, 2.0, 2.0, 2.0] - } - ] - } - ], - "coordinateTransformations": [ - { - "type": "scale", - "scale": [0.1, 1.0, 1.0, 1.0, 1.0] - } - ], - "type": "gaussian", - "metadata": { - "description": "the fields in metadata depend on the downscaling implementation. Here, the parameters passed to the skimage function are given", - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": "[true]", - "kwargs": { - "multichannel": true - } - } - } - ] - } - }, - "valid": true - }, - { - "formerly": "valid_strict/multiscales_transformations.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ], - "coordinateTransformations": [ - { - "scale": [10, 10], - "type": "scale" - } - ], - "name": "image_with_coordinateTransformations", - "type": "foo", - "metadata": { - "key": "value" - } - } - ] - } - }, - "valid": true - }, - { - "formerly": "valid_strict/image_metadata.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "@id": "top", - "@type": "ngff:Image", - "multiscales": [ - { - "@id": "inner", - "name": "example", - "datasets": [ - { - "path": "path/to/0", - "coordinateTransformations": [ - { - "type": "scale", - "scale": [1, 1] - } - ] - } - ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": ["true", "false"], - "kwargs": { - "multichannel": true - } - }, - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ] - } - ] - } - }, - "valid": true - }, - { - "formerly": "valid_strict/image.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1], - "type": "scale" - } - ] - } - ], - "name": "simple_image", - "type": "foo", - "metadata": { - "key": "value" - } - } - ] - } - }, - "valid": true - }, - { - "formerly": "valid_strict/image_omero.json", - "description": "TBD", - "data": { - "ome": { - "version": "0.5", - "multiscales": [ - { - "axes": [ - { - "name": "t", - "type": "time" - }, - { - "name": "c", - "type": "channel" - }, - { - "name": "z", - "type": "space", - "unit": "micrometer" - }, - { - "name": "y", - "type": "space", - "unit": "micrometer" - }, - { - "name": "x", - "type": "space", - "unit": "micrometer" - } - ], - "datasets": [ - { - "path": "0", - "coordinateTransformations": [ - { - "scale": [1, 1, 0.5, 0.13, 0.13], - "type": "scale" - }, - { - "translation": [0, 9, 0.5, 25.74, 21.58], - "type": "translation" - } - ] - }, - { - "path": "1", - "coordinateTransformations": [ - { - "scale": [1, 1, 1, 0.26, 0.26], - "type": "scale" - } - ] - } - ], - "name": "image_with_omero_metadata", - "type": "foo", - "metadata": { - "key": "value" - } - } - ], - "omero": { - "channels": [ - { - "active": true, - "coefficient": 1.0, - "color": "00FF00", - "family": "linear", - "inverted": false, - "label": "FITC", - "window": { - "end": 813.0, - "max": 870.0, - "min": 102.0, - "start": 82.0 - } - }, - { - "active": true, - "coefficient": 1.0, - "color": "FF0000", - "family": "linear", - "inverted": false, - "label": "RD-TR-PE", - "window": { - "end": 815.0, - "max": 441.0, - "min": 129.0, - "start": 78.0 - } - } - ], - "id": 1, - "rdefs": { - "defaultT": 0, - "defaultZ": 2, - "model": "color" - }, - "version": "0.5-dev" - } - } - }, - "valid": true - } - ] -} diff --git a/spec/tests/strict_label_suite.json b/spec/tests/strict_label_suite.json deleted file mode 100644 index 1b3535c2..00000000 --- a/spec/tests/strict_label_suite.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "description": "Tests for the strict image-label JSON schema", - "schema": { - "id": "schemas/strict_label.schema" - }, - "tests": [ - { - "formerly": "image-label/no_colors", - "data": { - "ome": { - "version": "0.5", - "image-label": {} - } - }, - "valid": false - } - ] -} diff --git a/spec/tests/strict_plate_suite.json b/spec/tests/strict_plate_suite.json deleted file mode 100644 index 7cea0747..00000000 --- a/spec/tests/strict_plate_suite.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "description": "Tests for the strict plate JSON schema", - "schema": { - "id": "schemas/strict_plate.schema" - }, - "tests": [ - { - "formerly": "plate/strict_no_acquisitions", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "name": "test plate", - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": true - }, - { - "formerly": "plate/missing_name", - "data": { - "ome": { - "version": "0.5", - "plate": { - "columns": [ - { - "name": "A" - } - ], - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/strict_acquisitions", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": 0, - "name": "0", - "maximumfieldcount": 1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "name": "test plate", - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": true - }, - { - "formerly": "plate/missing_acquisition_name", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": 0, - "maximumfieldcount": 1 - } - ], - "columns": [ - { - "name": "A" - } - ], - "name": "test plate", - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - }, - { - "formerly": "plate/missing_acquisition_maximumfieldcount", - "data": { - "ome": { - "version": "0.5", - "plate": { - "acquisitions": [ - { - "id": 0, - "name": "0" - } - ], - "columns": [ - { - "name": "A" - } - ], - "name": "test plate", - "rows": [ - { - "name": "1" - } - ], - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - } - ] - } - } - }, - "valid": false - } - ] -} diff --git a/spec/tests/strict_well_suite.json b/spec/tests/strict_well_suite.json deleted file mode 100644 index f56b6c24..00000000 --- a/spec/tests/strict_well_suite.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "description": "Tests for the strict well JSON schema", - "schema": { - "id": "schemas/strict_well.schema" - }, - "tests": [ - { - "formerly": "well/strict_no_acquisitions", - "data": { - "ome": { - "version": "0.5", - "well": { - "images": [ - { - "path": "0" - } - ] - } - } - }, - "valid": true - }, - { - "formerly": "plate/strict_acquisitions", - "data": { - "ome": { - "version": "0.5", - "well": { - "images": [ - { - "acquisition": 0, - "path": "0" - } - ] - } - } - }, - "valid": true - } - ] -} diff --git a/spec/tests/test_validation.py b/spec/tests/test_validation.py deleted file mode 100644 index b9c7c929..00000000 --- a/spec/tests/test_validation.py +++ /dev/null @@ -1,125 +0,0 @@ -import json -import glob -import os - -from dataclasses import dataclass -from typing import List - -import pytest - -from jsonschema import RefResolver, Draft202012Validator as Validator -from jsonschema.exceptions import ValidationError - -schema_store = {} -for schema_filename in glob.glob("schemas/*"): - with open(schema_filename) as f: - schema = json.load(f) - schema_store[schema["$id"]] = schema - -GENERIC_SCHEMA = schema_store[ - "https://ngff.openmicroscopy.org/0.5/schemas/ome_zarr.schema" -] - -print(schema_store) - - -@dataclass -class Suite: - schema: dict - data: dict - valid: bool = True - - def validate(self, validator) -> None: - if not self.valid: - with pytest.raises(ValidationError): - validator.validate(self.data) - else: - validator.validate(self.data) - - def maybe_validate(self, validator) -> None: - if self.valid: - validator.validate(self.data) - - -def pytest_generate_tests(metafunc): - """ - Generates tests for the examples/ as well as tests/ subdirectories. - - Examples: - These tests evaluate all of the files under the examples/ directory - using the configuration in the provided config file in order detect - what should be run. It is assumed that all files are valid and complete - so that they can be wholly included into the specification. The - .config.json file in each directory defines which schema will be used. - - Validation: - These test consumes https://github.com/json-schema-org/JSON-Schema-Test-Suite#structure-of-a-test - styled JSON tests. Metadata in each test defines which schema is used - and whether or not the block is considered valid. - """ - if "suite" in metafunc.fixturenames: - suites: List[Schema] = [] - ids: List[str] = [] - - # Validation - for filename in glob.glob("tests/*.json"): - with open(filename) as o: - suite = json.load(o) - schema = suite["schema"] - with open(schema["id"]) as f: - schema = json.load(f) - for test in suite["tests"]: - ids.append("validate_" + str(test["formerly"]).split("/")[-1][0:-5]) - suites.append(Suite(schema, test["data"], test["valid"])) - - # Examples - for config_filename in glob.glob("examples/*/.config.json"): - with open(config_filename) as o: - data = json.load(o) - schema = data["schema"] - with open(schema) as f: - schema = json.load(f) - example_folder = os.path.dirname(config_filename) - for filename in glob.glob(f"{example_folder}/*.json"): - with open(filename) as f: - # Strip comments - data = "".join( - line for line in f if not line.lstrip().startswith("//") - ) - data = json.loads(data) - data = data["attributes"] # Only validate the attributes object - ids.append("example_" + str(filename).split("/")[-1][0:-5]) - suites.append(Suite(schema, data, True)) # Assume true - - metafunc.parametrize("suite", suites, ids=ids, indirect=True) - - -@pytest.fixture -def suite(request): - return request.param - - -def test_run(suite): - resolver = RefResolver.from_schema(suite.schema, store=schema_store) - validator = Validator(suite.schema, resolver=resolver) - suite.validate(validator) - - -def test_generic_run(suite): - resolver = RefResolver.from_schema(GENERIC_SCHEMA, store=schema_store) - validator = Validator(GENERIC_SCHEMA, resolver=resolver) - suite.maybe_validate(validator) - - -def test_example_configs(): - """ - Test that all example folders have a config file - """ - missing = [] - for subdir in os.walk("examples"): - has_examples = glob.glob(f"{subdir[0]}/*.json") - has_config = glob.glob(f"{subdir[0]}/.config.json") - if has_examples and not has_config: - missing.append(subdir[0]) - if missing: - raise Exception(f"Directories missing configs: {missing}") diff --git a/spec/tests/well_suite.json b/spec/tests/well_suite.json deleted file mode 100644 index 7fbf8ca2..00000000 --- a/spec/tests/well_suite.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "description": "Tests for the well JSON schema", - "schema": { - "id": "schemas/well.schema" - }, - "tests": [ - { - "formerly": "well/minimal_no_acquisition", - "data": { - "ome": { - "version": "0.5", - "well": { - "images": [ - { - "path": "0" - } - ] - } - } - }, - "valid": true - }, - { - "formerly": "well/minimal_acquisitions", - "data": { - "ome": { - "version": "0.5", - "well": { - "images": [ - { - "acquisition": 1, - "path": "0" - } - ] - } - } - }, - "valid": true - }, - { - "formerly": "well/empty_images", - "data": { - "well": { - "images": [] - } - }, - "valid": false - }, - { - "formerly": "well/duplicate_images", - "data": { - "well": { - "images": [ - { - "path": "0" - }, - { - "path": "0" - } - ] - } - }, - "valid": false - }, - { - "formerly": "well/non_integer_acquisition_id", - "data": { - "well": { - "images": [ - { - "acquisition": "0", - "path": "0" - } - ] - } - }, - "valid": false - } - ] -} diff --git a/spec/tox.ini b/spec/tox.ini deleted file mode 100644 index 632ca64e..00000000 --- a/spec/tox.ini +++ /dev/null @@ -1,10 +0,0 @@ -[tox] -envlist = v04 -skipsdist = True - -[testenv] -deps = - pytest - jsonschema -commands = - pytest tests --color=yes --basetemp={envtmpdir} {posargs:-v} \ No newline at end of file From 1eea7170f3262e0132e784dd30f9621602d6c3d3 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 4 Dec 2024 22:01:41 +0100 Subject: [PATCH 08/13] Convert to use of submodules --- .gitmodules | 20 ++++++++++++++++++++ 0.1 | 1 + 0.2 | 1 + 0.3 | 1 + 0.4 | 1 + 0.5 | 1 + Makefile | 5 ----- conf.py | 21 +-------------------- specifications/index.md | 1 - 9 files changed, 26 insertions(+), 26 deletions(-) create mode 100644 .gitmodules create mode 160000 0.1 create mode 160000 0.2 create mode 160000 0.3 create mode 160000 0.4 create mode 160000 0.5 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..8f11e937 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,20 @@ +[submodule "0.1"] + path = 0.1 + url = https://github.com/joshmoore/ngff-specifications + branch = 0.1 +[submodule "0.2"] + path = 0.2 + url = https://github.com/joshmoore/ngff-specifications + branch = 0.2 +[submodule "0.3"] + path = 0.3 + url = https://github.com/joshmoore/ngff-specifications + branch = 0.3 +[submodule "0.4"] + path = 0.4 + url = https://github.com/joshmoore/ngff-specifications + branch = 0.4 +[submodule "0.5"] + path = 0.5 + url = https://github.com/joshmoore/ngff-specifications + branch = 0.5 diff --git a/0.1 b/0.1 new file mode 160000 index 00000000..a896990f --- /dev/null +++ b/0.1 @@ -0,0 +1 @@ +Subproject commit a896990fffcdffa844a8113d8cc6f34e354fbe61 diff --git a/0.2 b/0.2 new file mode 160000 index 00000000..52ef8521 --- /dev/null +++ b/0.2 @@ -0,0 +1 @@ +Subproject commit 52ef852122bba505ed6ef130815faea3d766c208 diff --git a/0.3 b/0.3 new file mode 160000 index 00000000..1107cca8 --- /dev/null +++ b/0.3 @@ -0,0 +1 @@ +Subproject commit 1107cca8d9d5dca783786229ff771032de1680f9 diff --git a/0.4 b/0.4 new file mode 160000 index 00000000..3643ec93 --- /dev/null +++ b/0.4 @@ -0,0 +1 @@ +Subproject commit 3643ec93afef70191184a2f0a5465cf85ae41dbf diff --git a/0.5 b/0.5 new file mode 160000 index 00000000..3a49789e --- /dev/null +++ b/0.5 @@ -0,0 +1 @@ +Subproject commit 3a49789eb0f3e8ffe842e1e257af0b80b2a1da8b diff --git a/Makefile b/Makefile index 13d18b31..72426cbc 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,6 @@ help: .PHONY: help Makefile clean - -clean: Makefile - rm -rf .cache 0.1 0.2 0.3 0.4 0.5 draft - @$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile diff --git a/conf.py b/conf.py index f0b80eb2..df98f441 100644 --- a/conf.py +++ b/conf.py @@ -64,26 +64,7 @@ def bikeshed(): import shutil import subprocess - branches = subprocess.check_output( - f"git branch -l v/*", - shell=True, - ).split() - branches = [x.decode("utf-8").strip() for x in branches] - # TODO: generate specifications/index.md - for branch in branches: - version = branch[2:] - os.makedirs(".cache", exist_ok=True) - subprocess.check_call( - #f"git clone --depth=1 --branch v/{version} https://github.com/ome/ngff.git .cache/{version}", - f"git clone --depth=1 --branch {branch} . .cache/{version}", - shell=True, - ) - os.symlink(f".cache/{version}/{version}", f"{version}") - - # TODO: skip this step on a tag - os.symlink("spec", "draft") - - for index_file in ["draft/index.bs"] + glob.glob("[0-9]*/index.bs"): + for index_file in glob.glob("[0-9]*/index.bs"): output_file = index_file.replace("bs", "html") output_dir = os.path.dirname(output_file) target_dir = os.path.join("_bikeshed", output_dir) diff --git a/specifications/index.md b/specifications/index.md index 677e86c8..ee31360f 100644 --- a/specifications/index.md +++ b/specifications/index.md @@ -11,5 +11,4 @@ Version history:
  • 0.3 August 2021
  • 0.4 February 2022
  • 0.5 November 2024
  • -
  • draft
  • From bf13de9ac176f955bd15178493e8740a9f727b6d Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 4 Dec 2024 22:11:03 +0100 Subject: [PATCH 09/13] Re-add 'latest' as a submodule copy of 0.5 --- .gitmodules | 4 ++++ conf.py | 2 +- latest | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) create mode 160000 latest diff --git a/.gitmodules b/.gitmodules index 8f11e937..2223342f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -18,3 +18,7 @@ path = 0.5 url = https://github.com/joshmoore/ngff-specifications branch = 0.5 +[submodule "latest"] + path = latest + url = https://github.com/joshmoore/ngff-specifications + branch = 0.5 diff --git a/conf.py b/conf.py index df98f441..5f64deaa 100644 --- a/conf.py +++ b/conf.py @@ -64,7 +64,7 @@ def bikeshed(): import shutil import subprocess - for index_file in glob.glob("[0-9]*/index.bs"): + for index_file in ["latest/index.bs"] + glob.glob("[0-9]*/index.bs"): output_file = index_file.replace("bs", "html") output_dir = os.path.dirname(output_file) target_dir = os.path.join("_bikeshed", output_dir) diff --git a/latest b/latest new file mode 160000 index 00000000..3a49789e --- /dev/null +++ b/latest @@ -0,0 +1 @@ +Subproject commit 3a49789eb0f3e8ffe842e1e257af0b80b2a1da8b From 755a50470feb1e884ae8fa9981a748b88a7fa92e Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 4 Dec 2024 22:14:07 +0100 Subject: [PATCH 10/13] Add a line to the index about the alias --- specifications/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/specifications/index.md b/specifications/index.md index ee31360f..b59f0531 100644 --- a/specifications/index.md +++ b/specifications/index.md @@ -11,4 +11,5 @@ Version history:
  • 0.3 August 2021
  • 0.4 February 2022
  • 0.5 November 2024
  • +
  • latest Alias for 0.5
  • From 913a2fd9a966653ac8435788e1e0e81485d6ed6f Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 4 Dec 2024 22:17:46 +0100 Subject: [PATCH 11/13] Checkout submodules in actions --- .github/workflows/publish.yml | 2 ++ .github/workflows/validation.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b6301fd3..df9f27e4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,6 +15,8 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - uses: ome/spec-prod@main with: GH_PAGES_BRANCH: gh-pages diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index 32a2d601..81e6b7a5 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -19,6 +19,8 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - uses: actions/setup-python@v2 with: python-version: '3.9' From 2f6a3bff39bbadf9f68f2048ace4692da6433192 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 4 Dec 2024 22:20:09 +0100 Subject: [PATCH 12/13] Checkout submodules in RTD --- .readthedocs.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 52ecf6d1..f0db1348 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -5,6 +5,9 @@ build: tools: python: "3.10" +submodules: + include: all + sphinx: configuration: conf.py From 376c0b0b09b380ca3a4ed2f70f300fa6e6a2a528 Mon Sep 17 00:00:00 2001 From: Josh Moore Date: Wed, 4 Dec 2024 22:30:57 +0100 Subject: [PATCH 13/13] Try adding recursive for RTD --- .readthedocs.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index f0db1348..b23558fa 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -7,6 +7,7 @@ build: submodules: include: all + recursive: true sphinx: configuration: conf.py