From 2018d3af0ce2915901ac131012c74ff280abd559 Mon Sep 17 00:00:00 2001 From: William Moore Date: Wed, 1 Dec 2021 10:20:28 +0000 Subject: [PATCH 01/18] Remove v0.2 support from 0.3/schemas/json_schema/image.schema --- 0.3/examples/valid/image_v0.2.json | 14 --------- 0.3/schemas/json_schema/image.schema | 47 ++++++++-------------------- 2 files changed, 13 insertions(+), 48 deletions(-) delete mode 100644 0.3/examples/valid/image_v0.2.json diff --git a/0.3/examples/valid/image_v0.2.json b/0.3/examples/valid/image_v0.2.json deleted file mode 100644 index ab73ed40..00000000 --- a/0.3/examples/valid/image_v0.2.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.2", - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ] - } - ] -} \ No newline at end of file diff --git a/0.3/schemas/json_schema/image.schema b/0.3/schemas/json_schema/image.schema index 6b2562ce..286d40df 100644 --- a/0.3/schemas/json_schema/image.schema +++ b/0.3/schemas/json_schema/image.schema @@ -26,45 +26,24 @@ }, "required": ["path"] } - } - }, - "oneOf": [ - { - "type": "object", - "properties": { - "version": { - "type": "string", - "enum": [ - "0.3" - ] - }, - "axes": { - "type": "array", - "minItems": 2, - "items": { - "type": "string", - "pattern": "^[xyzct]$" - } - } - }, - "required": [ - "axes" + }, + "version": { + "type": "string", + "enum": [ + "0.3" ] }, - { - "type": "object", - "properties": { - "version": { - "type": "string", - "enum": [ - "0.2" - ] - } + "axes": { + "type": "array", + "minItems": 2, + "items": { + "type": "string", + "pattern": "^[xyzct]$" } } - ], + }, "required": [ - "name", "datasets" + "version", "name", "datasets", "axes" ] }, "minItems": 1, From 2eaf0c8450617257d168d04df863ccbd2bf59efe Mon Sep 17 00:00:00 2001 From: William Moore Date: Wed, 1 Dec 2021 12:54:35 +0000 Subject: [PATCH 02/18] Add validation tests and schemas for 0.1 and 0.2 --- .github/workflows/validation.yml | 2 + .gitignore | 2 + .../invalid/invalid_channels_color.json | 31 ++++++ .../invalid/invalid_channels_window.json | 31 ++++++ 0.1/examples/invalid/invalid_path.json | 17 +++ 0.1/examples/invalid/missing_datasets.json | 9 ++ 0.1/examples/invalid/missing_name.json | 28 +++++ 0.1/examples/invalid/missing_path.json | 17 +++ 0.1/examples/invalid/missing_version.json | 13 +++ 0.1/examples/invalid/no_datasets.json | 15 +++ 0.1/examples/invalid/no_multiscales.json | 4 + 0.1/examples/valid/image.json | 14 +++ 0.1/examples/valid/image_metadata.json | 28 +++++ 0.1/examples/valid/image_omero.json | 58 ++++++++++ 0.1/schemas/.DS_Store | Bin 0 -> 6148 bytes 0.1/schemas/json_schema/.DS_Store | Bin 0 -> 6148 bytes 0.1/schemas/json_schema/image.schema | 101 ++++++++++++++++++ 0.1/tests/test_validation.py | 40 +++++++ 0.1/tox.ini | 10 ++ .../invalid/invalid_channels_color.json | 31 ++++++ .../invalid/invalid_channels_window.json | 31 ++++++ 0.2/examples/invalid/invalid_path.json | 17 +++ 0.2/examples/invalid/missing_datasets.json | 9 ++ 0.2/examples/invalid/missing_name.json | 28 +++++ 0.2/examples/invalid/missing_path.json | 17 +++ 0.2/examples/invalid/missing_version.json | 13 +++ 0.2/examples/invalid/no_datasets.json | 15 +++ 0.2/examples/invalid/no_multiscales.json | 4 + 0.2/examples/valid/image.json | 14 +++ 0.2/examples/valid/image_metadata.json | 28 +++++ 0.2/examples/valid/image_omero.json | 58 ++++++++++ 0.2/schemas/.DS_Store | Bin 0 -> 6148 bytes 0.2/schemas/json_schema/.DS_Store | Bin 0 -> 6148 bytes 0.2/schemas/json_schema/image.schema | 101 ++++++++++++++++++ 0.2/tests/test_validation.py | 40 +++++++ 0.2/tox.ini | 10 ++ 36 files changed, 836 insertions(+) create mode 100644 .gitignore create mode 100644 0.1/examples/invalid/invalid_channels_color.json create mode 100644 0.1/examples/invalid/invalid_channels_window.json create mode 100644 0.1/examples/invalid/invalid_path.json create mode 100644 0.1/examples/invalid/missing_datasets.json create mode 100644 0.1/examples/invalid/missing_name.json create mode 100644 0.1/examples/invalid/missing_path.json create mode 100644 0.1/examples/invalid/missing_version.json create mode 100644 0.1/examples/invalid/no_datasets.json create mode 100644 0.1/examples/invalid/no_multiscales.json create mode 100644 0.1/examples/valid/image.json create mode 100644 0.1/examples/valid/image_metadata.json create mode 100644 0.1/examples/valid/image_omero.json create mode 100644 0.1/schemas/.DS_Store create mode 100644 0.1/schemas/json_schema/.DS_Store create mode 100644 0.1/schemas/json_schema/image.schema create mode 100644 0.1/tests/test_validation.py create mode 100644 0.1/tox.ini create mode 100644 0.2/examples/invalid/invalid_channels_color.json create mode 100644 0.2/examples/invalid/invalid_channels_window.json create mode 100644 0.2/examples/invalid/invalid_path.json create mode 100644 0.2/examples/invalid/missing_datasets.json create mode 100644 0.2/examples/invalid/missing_name.json create mode 100644 0.2/examples/invalid/missing_path.json create mode 100644 0.2/examples/invalid/missing_version.json create mode 100644 0.2/examples/invalid/no_datasets.json create mode 100644 0.2/examples/invalid/no_multiscales.json create mode 100644 0.2/examples/valid/image.json create mode 100644 0.2/examples/valid/image_metadata.json create mode 100644 0.2/examples/valid/image_omero.json create mode 100644 0.2/schemas/.DS_Store create mode 100644 0.2/schemas/json_schema/.DS_Store create mode 100644 0.2/schemas/json_schema/image.schema create mode 100644 0.2/tests/test_validation.py create mode 100644 0.2/tox.ini diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index ab2226ce..a23bb72f 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -10,6 +10,8 @@ jobs: strategy: matrix: ngff: + - '0.1' + - '0.2' - '0.3' runs-on: ubuntu-20.04 steps: diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..53de2396 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*/.DS_Store +**/__pycache__/* \ No newline at end of file diff --git a/0.1/examples/invalid/invalid_channels_color.json b/0.1/examples/invalid/invalid_channels_color.json new file mode 100644 index 00000000..da301713 --- /dev/null +++ b/0.1/examples/invalid/invalid_channels_color.json @@ -0,0 +1,31 @@ +{ + "@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/invalid/invalid_channels_window.json b/0.1/examples/invalid/invalid_channels_window.json new file mode 100644 index 00000000..534b6eb6 --- /dev/null +++ b/0.1/examples/invalid/invalid_channels_window.json @@ -0,0 +1,31 @@ +{ + "@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/invalid/invalid_path.json b/0.1/examples/invalid/invalid_path.json new file mode 100644 index 00000000..33d8b9ac --- /dev/null +++ b/0.1/examples/invalid/invalid_path.json @@ -0,0 +1,17 @@ +{ + "@type": "ngff:Image", + "multiscales": [ + { + "version": "0.1", + "name": "example", + "datasets": [ + { + "path": "path/to/0" + }, + { + "path": 0 + } + ] + } + ] +} diff --git a/0.1/examples/invalid/missing_datasets.json b/0.1/examples/invalid/missing_datasets.json new file mode 100644 index 00000000..ea5eee52 --- /dev/null +++ b/0.1/examples/invalid/missing_datasets.json @@ -0,0 +1,9 @@ +{ + "@type": "ngff:Image", + "multiscales": [ + { + "version": "0.1", + "name": "example" + } + ] +} diff --git a/0.1/examples/invalid/missing_name.json b/0.1/examples/invalid/missing_name.json new file mode 100644 index 00000000..f2395d84 --- /dev/null +++ b/0.1/examples/invalid/missing_name.json @@ -0,0 +1,28 @@ +{ + "@type": "ngff:Image", + "multiscales": [ + { + "version": "0.1", + "datasets": [ + { + "path": "path/to/0" + }, + { + "path": 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/invalid/missing_path.json b/0.1/examples/invalid/missing_path.json new file mode 100644 index 00000000..df9c74cc --- /dev/null +++ b/0.1/examples/invalid/missing_path.json @@ -0,0 +1,17 @@ +{ + "@type": "ngff:Image", + "multiscales": [ + { + "version": "0.1", + "name": "example", + "datasets": [ + { + "foo": "path/to/0" + }, + { + "path": "1" + } + ] + } + ] +} diff --git a/0.1/examples/invalid/missing_version.json b/0.1/examples/invalid/missing_version.json new file mode 100644 index 00000000..c278ddef --- /dev/null +++ b/0.1/examples/invalid/missing_version.json @@ -0,0 +1,13 @@ +{ + "@type": "ngff:Image", + "multiscales": [ + { + "name": "example", + "datasets": [ + { + "path": "path/to/0" + } + ] + } + ] +} diff --git a/0.1/examples/invalid/no_datasets.json b/0.1/examples/invalid/no_datasets.json new file mode 100644 index 00000000..e519c9c7 --- /dev/null +++ b/0.1/examples/invalid/no_datasets.json @@ -0,0 +1,15 @@ +{ + "@type": "ngff:Image", + "multiscales": [ + { + "version": "0.1", + "name": "example", + "datasets": [], + "axes": [ + "z", + "y", + "x" + ] + } + ] +} diff --git a/0.1/examples/invalid/no_multiscales.json b/0.1/examples/invalid/no_multiscales.json new file mode 100644 index 00000000..d6dbfb33 --- /dev/null +++ b/0.1/examples/invalid/no_multiscales.json @@ -0,0 +1,4 @@ +{ + "@type": "ngff:Image", + "multiscales": [] +} diff --git a/0.1/examples/valid/image.json b/0.1/examples/valid/image.json new file mode 100644 index 00000000..069a35c8 --- /dev/null +++ b/0.1/examples/valid/image.json @@ -0,0 +1,14 @@ +{ + "@type": "ngff:Image", + "multiscales": [ + { + "version": "0.1", + "name": "example", + "datasets": [ + {"path": "path/to/0"}, + {"path": "1"}, + {"path": "2"} + ] + } + ] +} diff --git a/0.1/examples/valid/image_metadata.json b/0.1/examples/valid/image_metadata.json new file mode 100644 index 00000000..a2669b48 --- /dev/null +++ b/0.1/examples/valid/image_metadata.json @@ -0,0 +1,28 @@ +{ + "@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/valid/image_omero.json b/0.1/examples/valid/image_omero.json new file mode 100644 index 00000000..c568a08e --- /dev/null +++ b/0.1/examples/valid/image_omero.json @@ -0,0 +1,58 @@ +{ + "@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.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.1/schemas/.DS_Store b/0.1/schemas/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d053bb1cc0388fa27ebfb1f84760ec85f17d67bc GIT binary patch literal 6148 zcmeHKJx{|h5PgOYmAZ6f^o~S;Ul3IR7SshXLxBPUL8~McYkoTKKKQ5zjHsYH%lGW_ z-PwLp>=;0rtZoi~F@PbfV3J0Uh`D!Y%bf+2=D0wEYusawr=CQcXp*&$@W6F1@Qlyv zpDo*~(^b>f^w`BYJ?5yX3%qc53znLe0u^=D zrkQ@4d+Kw4v${DU?S(Ltq8 z0OEjV6}IIqAu-vpbnFZ{LP-`%w9w>FjAY@oXZI@|J3|Xc(wUjZXMTIUB%Pi1tnNsq zVd!8W7+7au+qz@9|Bv{|^gi;}L!uW91Oxw!fi$SjstGscck7q!$z7XSFIh#zuagFa m?X{l(cH|t{(Lo!}(xzYO*cnO|v1>Rnegu?|P{F`2Fz^Z@H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0=;0rtZoi~F@PbfV3J0Uh`D!Y%bf+2=D0wEYusawr=CQcXp*&$@W6F1@Qlyv zpDo*~(^b>f^w`BYJ?5yX3%qc53znLe0u^=D zrkQ@4d+Kw4v${DU?S(Ltq8 z0OEjV6}IIqAu-vpbnFZ{LP-`%w9w>FjAY@oXZI@|J3|Xc(wUjZXMTIUB%Pi1tnNsq zVd!8W7+7au+qz@9|Bv{|^gi;}L!uW91Oxw!fi$SjstGscck7q!$z7XSFIh#zuagFa m?X{l(cH|t{(Lo!}(xzYO*cnO|v1>Rnegu?|P{F`2Fz^Z@H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Wed, 1 Dec 2021 13:44:29 +0000 Subject: [PATCH 03/18] Add plate schema and examples for v0.1 --- .../invalid/invalid_channels_color.json | 0 .../invalid/invalid_channels_window.json | 0 .../{ => image}/invalid/invalid_path.json | 0 .../{ => image}/invalid/missing_datasets.json | 0 .../{ => image}/invalid/missing_name.json | 0 .../{ => image}/invalid/missing_path.json | 0 .../{ => image}/invalid/missing_version.json | 0 .../{ => image}/invalid/no_datasets.json | 0 .../{ => image}/invalid/no_multiscales.json | 0 0.1/examples/{ => image}/valid/image.json | 0 .../{ => image}/valid/image_metadata.json | 0 .../{ => image}/valid/image_omero.json | 0 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/schemas/json_schema/plate.schema | 112 ++++++++++++++++++ 0.1/tests/test_validation.py | 6 +- 26 files changed, 424 insertions(+), 2 deletions(-) rename 0.1/examples/{ => image}/invalid/invalid_channels_color.json (100%) rename 0.1/examples/{ => image}/invalid/invalid_channels_window.json (100%) rename 0.1/examples/{ => image}/invalid/invalid_path.json (100%) rename 0.1/examples/{ => image}/invalid/missing_datasets.json (100%) rename 0.1/examples/{ => image}/invalid/missing_name.json (100%) rename 0.1/examples/{ => image}/invalid/missing_path.json (100%) rename 0.1/examples/{ => image}/invalid/missing_version.json (100%) rename 0.1/examples/{ => image}/invalid/no_datasets.json (100%) rename 0.1/examples/{ => image}/invalid/no_multiscales.json (100%) rename 0.1/examples/{ => image}/valid/image.json (100%) rename 0.1/examples/{ => image}/valid/image_metadata.json (100%) rename 0.1/examples/{ => image}/valid/image_omero.json (100%) create mode 100644 0.1/examples/plate/invalid/empty_wells.json create mode 100644 0.1/examples/plate/invalid/invalid_fieldcount.json create mode 100644 0.1/examples/plate/invalid/missing_acquisition_id.json create mode 100644 0.1/examples/plate/invalid/missing_column_name.json create mode 100644 0.1/examples/plate/invalid/missing_columns.json create mode 100644 0.1/examples/plate/invalid/missing_rows.json create mode 100644 0.1/examples/plate/invalid/missing_version.json create mode 100644 0.1/examples/plate/invalid/missing_well_path.json create mode 100644 0.1/examples/plate/invalid/missing_wells.json create mode 100644 0.1/examples/plate/valid/minimal_acquisition.json create mode 100644 0.1/examples/plate/valid/plate.json create mode 100644 0.1/examples/plate/valid/plate_acquisition.json create mode 100644 0.1/schemas/json_schema/plate.schema diff --git a/0.1/examples/invalid/invalid_channels_color.json b/0.1/examples/image/invalid/invalid_channels_color.json similarity index 100% rename from 0.1/examples/invalid/invalid_channels_color.json rename to 0.1/examples/image/invalid/invalid_channels_color.json diff --git a/0.1/examples/invalid/invalid_channels_window.json b/0.1/examples/image/invalid/invalid_channels_window.json similarity index 100% rename from 0.1/examples/invalid/invalid_channels_window.json rename to 0.1/examples/image/invalid/invalid_channels_window.json diff --git a/0.1/examples/invalid/invalid_path.json b/0.1/examples/image/invalid/invalid_path.json similarity index 100% rename from 0.1/examples/invalid/invalid_path.json rename to 0.1/examples/image/invalid/invalid_path.json diff --git a/0.1/examples/invalid/missing_datasets.json b/0.1/examples/image/invalid/missing_datasets.json similarity index 100% rename from 0.1/examples/invalid/missing_datasets.json rename to 0.1/examples/image/invalid/missing_datasets.json diff --git a/0.1/examples/invalid/missing_name.json b/0.1/examples/image/invalid/missing_name.json similarity index 100% rename from 0.1/examples/invalid/missing_name.json rename to 0.1/examples/image/invalid/missing_name.json diff --git a/0.1/examples/invalid/missing_path.json b/0.1/examples/image/invalid/missing_path.json similarity index 100% rename from 0.1/examples/invalid/missing_path.json rename to 0.1/examples/image/invalid/missing_path.json diff --git a/0.1/examples/invalid/missing_version.json b/0.1/examples/image/invalid/missing_version.json similarity index 100% rename from 0.1/examples/invalid/missing_version.json rename to 0.1/examples/image/invalid/missing_version.json diff --git a/0.1/examples/invalid/no_datasets.json b/0.1/examples/image/invalid/no_datasets.json similarity index 100% rename from 0.1/examples/invalid/no_datasets.json rename to 0.1/examples/image/invalid/no_datasets.json diff --git a/0.1/examples/invalid/no_multiscales.json b/0.1/examples/image/invalid/no_multiscales.json similarity index 100% rename from 0.1/examples/invalid/no_multiscales.json rename to 0.1/examples/image/invalid/no_multiscales.json diff --git a/0.1/examples/valid/image.json b/0.1/examples/image/valid/image.json similarity index 100% rename from 0.1/examples/valid/image.json rename to 0.1/examples/image/valid/image.json diff --git a/0.1/examples/valid/image_metadata.json b/0.1/examples/image/valid/image_metadata.json similarity index 100% rename from 0.1/examples/valid/image_metadata.json rename to 0.1/examples/image/valid/image_metadata.json diff --git a/0.1/examples/valid/image_omero.json b/0.1/examples/image/valid/image_omero.json similarity index 100% rename from 0.1/examples/valid/image_omero.json rename to 0.1/examples/image/valid/image_omero.json diff --git a/0.1/examples/plate/invalid/empty_wells.json b/0.1/examples/plate/invalid/empty_wells.json new file mode 100644 index 00000000..1c8861da --- /dev/null +++ b/0.1/examples/plate/invalid/empty_wells.json @@ -0,0 +1,16 @@ +{ + "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 new file mode 100644 index 00000000..89540652 --- /dev/null +++ b/0.1/examples/plate/invalid/invalid_fieldcount.json @@ -0,0 +1,31 @@ +{ + "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 new file mode 100644 index 00000000..46fe420a --- /dev/null +++ b/0.1/examples/plate/invalid/missing_acquisition_id.json @@ -0,0 +1,35 @@ +{ + "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 new file mode 100644 index 00000000..dbf4e2d6 --- /dev/null +++ b/0.1/examples/plate/invalid/missing_column_name.json @@ -0,0 +1,18 @@ +{ + "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 new file mode 100644 index 00000000..997e2927 --- /dev/null +++ b/0.1/examples/plate/invalid/missing_columns.json @@ -0,0 +1,15 @@ +{ + "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 new file mode 100644 index 00000000..74f6ba6a --- /dev/null +++ b/0.1/examples/plate/invalid/missing_rows.json @@ -0,0 +1,15 @@ +{ + "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 new file mode 100644 index 00000000..36b0afde --- /dev/null +++ b/0.1/examples/plate/invalid/missing_version.json @@ -0,0 +1,19 @@ +{ + "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 new file mode 100644 index 00000000..ded5f769 --- /dev/null +++ b/0.1/examples/plate/invalid/missing_well_path.json @@ -0,0 +1,18 @@ +{ + "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 new file mode 100644 index 00000000..fd00f136 --- /dev/null +++ b/0.1/examples/plate/invalid/missing_wells.json @@ -0,0 +1,15 @@ +{ + "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 new file mode 100644 index 00000000..43037600 --- /dev/null +++ b/0.1/examples/plate/valid/minimal_acquisition.json @@ -0,0 +1,31 @@ +{ + "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 new file mode 100644 index 00000000..eb2bd031 --- /dev/null +++ b/0.1/examples/plate/valid/plate.json @@ -0,0 +1,40 @@ +{ + "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 new file mode 100644 index 00000000..0559909b --- /dev/null +++ b/0.1/examples/plate/valid/plate_acquisition.json @@ -0,0 +1,55 @@ +{ + "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/schemas/json_schema/plate.schema b/0.1/schemas/json_schema/plate.schema new file mode 100644 index 00000000..09110cfc --- /dev/null +++ b/0.1/schemas/json_schema/plate.schema @@ -0,0 +1,112 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "http://localhost:8000/plate.schema", + "title": "NGFF Plate", + "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/tests/test_validation.py b/0.1/tests/test_validation.py index 7bdbaf56..e3cbe671 100644 --- a/0.1/tests/test_validation.py +++ b/0.1/tests/test_validation.py @@ -8,8 +8,8 @@ def files(): - return list(glob.glob(f"examples/valid/*.json")) + \ - list(glob.glob(f"examples/invalid/*.json")) + 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()] @@ -32,6 +32,8 @@ def json_schema(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" else: raise Exception("No schema found") From e9b55600d6a2f9ec13234d7da66454a797f34a1b Mon Sep 17 00:00:00 2001 From: William Moore Date: Wed, 1 Dec 2021 15:46:17 +0000 Subject: [PATCH 04/18] Test for SHOULD rules --- 0.1/examples/image/invalid/missing_name.json | 28 ------- 0.1/examples/image/valid/image_complete.json | 58 ++++++++++++++ 0.1/examples/image/valid/image_omero.json | 15 +--- 0.1/examples/image/valid/missing_name.json | 14 ++++ 0.1/schemas/json_schema/image.schema | 13 ++- 0.1/schemas/json_schema/strict_image.schema | 18 +++++ 0.1/tests/test_validation.py | 83 ++++++++++++++++---- 0.3/tests/test_validation.py | 2 - 8 files changed, 171 insertions(+), 60 deletions(-) delete mode 100644 0.1/examples/image/invalid/missing_name.json create mode 100644 0.1/examples/image/valid/image_complete.json create mode 100644 0.1/examples/image/valid/missing_name.json create mode 100644 0.1/schemas/json_schema/strict_image.schema diff --git a/0.1/examples/image/invalid/missing_name.json b/0.1/examples/image/invalid/missing_name.json deleted file mode 100644 index f2395d84..00000000 --- a/0.1/examples/image/invalid/missing_name.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.1", - "datasets": [ - { - "path": "path/to/0" - }, - { - "path": 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/image_complete.json b/0.1/examples/image/valid/image_complete.json new file mode 100644 index 00000000..c568a08e --- /dev/null +++ b/0.1/examples/image/valid/image_complete.json @@ -0,0 +1,58 @@ +{ + "@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.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.1/examples/image/valid/image_omero.json b/0.1/examples/image/valid/image_omero.json index c568a08e..02b0178c 100644 --- a/0.1/examples/image/valid/image_omero.json +++ b/0.1/examples/image/valid/image_omero.json @@ -17,18 +17,7 @@ "path": "2" } ], - "type": "gaussian", - "metadata": { - "method": "skimage.transform.pyramid_gaussian", - "version": "0.16.1", - "args": [ - "true", - "false" - ], - "kwargs": { - "multichannel": true - } - } + "type": "gaussian" } ], "omero": { @@ -55,4 +44,4 @@ "model": "color" } } -} +} \ No newline at end of file diff --git a/0.1/examples/image/valid/missing_name.json b/0.1/examples/image/valid/missing_name.json new file mode 100644 index 00000000..5c267fa2 --- /dev/null +++ b/0.1/examples/image/valid/missing_name.json @@ -0,0 +1,14 @@ +{ + "@type": "ngff:Image", + "multiscales": [ + { + "version": "0.1", + "datasets": [ + { + "path": "path/to/0" + } + ], + "type": "gaussian" + } + ] +} diff --git a/0.1/schemas/json_schema/image.schema b/0.1/schemas/json_schema/image.schema index 1bb9c055..5fe99cbe 100644 --- a/0.1/schemas/json_schema/image.schema +++ b/0.1/schemas/json_schema/image.schema @@ -32,10 +32,21 @@ "enum": [ "0.1" ] + }, + "metadata": { + "type": "object", + "properties": { + "method": { + "type": "string" + }, + "version": { + "type": "string" + } + } } }, "required": [ - "version", "name", "datasets" + "version", "datasets" ] }, "minItems": 1, diff --git a/0.1/schemas/json_schema/strict_image.schema b/0.1/schemas/json_schema/strict_image.schema new file mode 100644 index 00000000..d9cdda8d --- /dev/null +++ b/0.1/schemas/json_schema/strict_image.schema @@ -0,0 +1,18 @@ +{ + "properties": { + "multiscales": { + "items": { + "required": [ + "version", + "name", + "metadata", + "datasets" + ] + } + } + }, + "required": [ + "multiscales", + "omero" + ] +} \ No newline at end of file diff --git a/0.1/tests/test_validation.py b/0.1/tests/test_validation.py index e3cbe671..143d60d8 100644 --- a/0.1/tests/test_validation.py +++ b/0.1/tests/test_validation.py @@ -1,9 +1,11 @@ import json +import os import glob import pytest from jsonschema import validate +from jsonschema.validators import validator_for from jsonschema.exceptions import ValidationError @@ -11,32 +13,81 @@ 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()] +def strict(): + return list(glob.glob(f"examples/image/valid/*.json")) -@pytest.mark.parametrize("testfile", files(), ids=ids()) + +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): - json_schema(testfile) + validate(instance=test_json, schema=schema) else: - json_schema(testfile) + validate(instance=test_json, schema=schema) + + +@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) + validator = cls(schema) + 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 json_schema(path): +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" + else: + raise Exception("No schema found") + + schema = load_json('schemas/json_schema/' + schema_name) + + strict_path = 'schemas/json_schema/strict_' + schema_name + if strict and os.path.exists(strict_path): + strict_rules = load_json(strict_path) + schema = merge(schema, strict_rules) + + return (test_json, schema) + + +def load_json(path): 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" + json_data = json.loads(f.read()) + return json_data + + +def merge(destination, source): + """ + deep merge of source into destination dict + https://stackoverflow.com/questions/20656135/python-deep-merge-dictionary-data + """ + for key, value in source.items(): + if isinstance(value, dict): + node = destination.setdefault(key, {}) + merge(node, value) else: - raise Exception("No schema found") + destination[key] = value - with open('schemas/json_schema/' + schema_name) as f: - schema = json.loads(f.read()) - validate(instance=test_json, schema=schema) + return destination \ No newline at end of file diff --git a/0.3/tests/test_validation.py b/0.3/tests/test_validation.py index 30c0af97..8655b9cd 100644 --- a/0.3/tests/test_validation.py +++ b/0.3/tests/test_validation.py @@ -46,8 +46,6 @@ def test_json(method, testfile, httpserver): pytest.skip("not supported") else: - if "jsonld" in method.__name__ and "v0.2" in testfile: - pytest.skip("not supported") method(testfile) From df8962ecea5859d6fcfd0479bb1fca01449051f7 Mon Sep 17 00:00:00 2001 From: William Moore Date: Wed, 1 Dec 2021 16:26:51 +0000 Subject: [PATCH 05/18] multiscales 'name' is not required --- 0.2/examples/invalid/missing_name.json | 28 ------------------- 0.2/examples/valid/missing_name.json | 13 +++++++++ 0.2/schemas/json_schema/image.schema | 2 +- .../{invalid => valid}/missing_name.json | 3 -- 0.3/schemas/json_schema/image.schema | 2 +- 0.3/schemas/jsonld/shacl.ttl | 1 - 6 files changed, 15 insertions(+), 34 deletions(-) delete mode 100644 0.2/examples/invalid/missing_name.json create mode 100644 0.2/examples/valid/missing_name.json rename 0.3/examples/{invalid => valid}/missing_name.json (91%) diff --git a/0.2/examples/invalid/missing_name.json b/0.2/examples/invalid/missing_name.json deleted file mode 100644 index a0c3f650..00000000 --- a/0.2/examples/invalid/missing_name.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "version": "0.2", - "datasets": [ - { - "path": "path/to/0" - }, - { - "path": 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/valid/missing_name.json b/0.2/examples/valid/missing_name.json new file mode 100644 index 00000000..3942a543 --- /dev/null +++ b/0.2/examples/valid/missing_name.json @@ -0,0 +1,13 @@ +{ + "@type": "ngff:Image", + "multiscales": [ + { + "version": "0.2", + "datasets": [ + { + "path": "path/to/0" + } + ] + } + ] +} diff --git a/0.2/schemas/json_schema/image.schema b/0.2/schemas/json_schema/image.schema index 38da767c..41c0dfbc 100644 --- a/0.2/schemas/json_schema/image.schema +++ b/0.2/schemas/json_schema/image.schema @@ -35,7 +35,7 @@ } }, "required": [ - "version", "name", "datasets" + "version", "datasets" ] }, "minItems": 1, diff --git a/0.3/examples/invalid/missing_name.json b/0.3/examples/valid/missing_name.json similarity index 91% rename from 0.3/examples/invalid/missing_name.json rename to 0.3/examples/valid/missing_name.json index a0b0963f..22697e44 100644 --- a/0.3/examples/invalid/missing_name.json +++ b/0.3/examples/valid/missing_name.json @@ -6,9 +6,6 @@ "datasets": [ { "path": "path/to/0" - }, - { - "path": 0 } ], "type": "gaussian", diff --git a/0.3/schemas/json_schema/image.schema b/0.3/schemas/json_schema/image.schema index 286d40df..30181385 100644 --- a/0.3/schemas/json_schema/image.schema +++ b/0.3/schemas/json_schema/image.schema @@ -43,7 +43,7 @@ } }, "required": [ - "version", "name", "datasets", "axes" + "version", "datasets", "axes" ] }, "minItems": 1, diff --git a/0.3/schemas/jsonld/shacl.ttl b/0.3/schemas/jsonld/shacl.ttl index 7bc00fd9..a66b2a4f 100644 --- a/0.3/schemas/jsonld/shacl.ttl +++ b/0.3/schemas/jsonld/shacl.ttl @@ -56,7 +56,6 @@ schema:Multiscale_Shape a sh:NodeShape; sh:property [ sh:path ngff:name; sh:datatype xsd:string; - sh:minCount 1; ]; sh:property [ From 20481ca3a13fd7e5a86acc21585711d34c954c0f Mon Sep 17 00:00:00 2001 From: William Moore Date: Wed, 1 Dec 2021 16:47:10 +0000 Subject: [PATCH 06/18] version is not required property 0.1, 0.2, 0.3 --- 0.1/examples/image/valid/missing_version.json | 39 +++++++++++++++++++ 0.1/schemas/json_schema/image.schema | 2 +- 0.2/examples/invalid/missing_version.json | 13 ------- .../examples/valid}/missing_version.json | 0 0.2/schemas/json_schema/image.schema | 2 +- 0.3/examples/invalid/invalid_version.json | 25 ++++++++++++ .../{invalid => valid}/missing_version.json | 0 0.3/schemas/json_schema/image.schema | 2 +- 0.3/schemas/jsonld/shacl.ttl | 3 +- 9 files changed, 68 insertions(+), 18 deletions(-) create mode 100644 0.1/examples/image/valid/missing_version.json delete mode 100644 0.2/examples/invalid/missing_version.json rename {0.1/examples/image/invalid => 0.2/examples/valid}/missing_version.json (100%) create mode 100644 0.3/examples/invalid/invalid_version.json rename 0.3/examples/{invalid => valid}/missing_version.json (100%) diff --git a/0.1/examples/image/valid/missing_version.json b/0.1/examples/image/valid/missing_version.json new file mode 100644 index 00000000..0dccf564 --- /dev/null +++ b/0.1/examples/image/valid/missing_version.json @@ -0,0 +1,39 @@ +{ + "@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.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 + } + } + ] + } +} \ No newline at end of file diff --git a/0.1/schemas/json_schema/image.schema b/0.1/schemas/json_schema/image.schema index 5fe99cbe..220ff4ae 100644 --- a/0.1/schemas/json_schema/image.schema +++ b/0.1/schemas/json_schema/image.schema @@ -46,7 +46,7 @@ } }, "required": [ - "version", "datasets" + "datasets" ] }, "minItems": 1, diff --git a/0.2/examples/invalid/missing_version.json b/0.2/examples/invalid/missing_version.json deleted file mode 100644 index c278ddef..00000000 --- a/0.2/examples/invalid/missing_version.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "@type": "ngff:Image", - "multiscales": [ - { - "name": "example", - "datasets": [ - { - "path": "path/to/0" - } - ] - } - ] -} diff --git a/0.1/examples/image/invalid/missing_version.json b/0.2/examples/valid/missing_version.json similarity index 100% rename from 0.1/examples/image/invalid/missing_version.json rename to 0.2/examples/valid/missing_version.json diff --git a/0.2/schemas/json_schema/image.schema b/0.2/schemas/json_schema/image.schema index 41c0dfbc..6eb26274 100644 --- a/0.2/schemas/json_schema/image.schema +++ b/0.2/schemas/json_schema/image.schema @@ -35,7 +35,7 @@ } }, "required": [ - "version", "datasets" + "datasets" ] }, "minItems": 1, diff --git a/0.3/examples/invalid/invalid_version.json b/0.3/examples/invalid/invalid_version.json new file mode 100644 index 00000000..ba995783 --- /dev/null +++ b/0.3/examples/invalid/invalid_version.json @@ -0,0 +1,25 @@ +{ + "@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/invalid/missing_version.json b/0.3/examples/valid/missing_version.json similarity index 100% rename from 0.3/examples/invalid/missing_version.json rename to 0.3/examples/valid/missing_version.json diff --git a/0.3/schemas/json_schema/image.schema b/0.3/schemas/json_schema/image.schema index 30181385..899f4876 100644 --- a/0.3/schemas/json_schema/image.schema +++ b/0.3/schemas/json_schema/image.schema @@ -43,7 +43,7 @@ } }, "required": [ - "version", "datasets", "axes" + "datasets", "axes" ] }, "minItems": 1, diff --git a/0.3/schemas/jsonld/shacl.ttl b/0.3/schemas/jsonld/shacl.ttl index a66b2a4f..02cb213b 100644 --- a/0.3/schemas/jsonld/shacl.ttl +++ b/0.3/schemas/jsonld/shacl.ttl @@ -61,8 +61,7 @@ schema:Multiscale_Shape a sh:NodeShape; sh:property [ sh:path ngff:version; sh:datatype xsd:string; - sh:minCount 1; - sh:hasValue "0.3"; + sh:pattern "0.3"; ]; sh:property [ From 145b0ad50b6282a1df73e4482b163f994f25237a Mon Sep 17 00:00:00 2001 From: William Moore Date: Wed, 1 Dec 2021 17:15:31 +0000 Subject: [PATCH 07/18] v0.1. images SHOULD contain 'type' but not 'omero' --- 0.1/examples/image/valid/image.json | 2 - ...data.json => image_complete_no_omero.json} | 0 0.1/examples/image/valid/image_omero.json | 47 ------------------- 0.1/examples/image/valid/missing_type.json | 20 ++++++++ 0.1/schemas/json_schema/strict_image.schema | 4 +- 5 files changed, 22 insertions(+), 51 deletions(-) rename 0.1/examples/image/valid/{image_metadata.json => image_complete_no_omero.json} (100%) delete mode 100644 0.1/examples/image/valid/image_omero.json create mode 100644 0.1/examples/image/valid/missing_type.json diff --git a/0.1/examples/image/valid/image.json b/0.1/examples/image/valid/image.json index 069a35c8..5c749323 100644 --- a/0.1/examples/image/valid/image.json +++ b/0.1/examples/image/valid/image.json @@ -2,8 +2,6 @@ "@type": "ngff:Image", "multiscales": [ { - "version": "0.1", - "name": "example", "datasets": [ {"path": "path/to/0"}, {"path": "1"}, diff --git a/0.1/examples/image/valid/image_metadata.json b/0.1/examples/image/valid/image_complete_no_omero.json similarity index 100% rename from 0.1/examples/image/valid/image_metadata.json rename to 0.1/examples/image/valid/image_complete_no_omero.json diff --git a/0.1/examples/image/valid/image_omero.json b/0.1/examples/image/valid/image_omero.json deleted file mode 100644 index 02b0178c..00000000 --- a/0.1/examples/image/valid/image_omero.json +++ /dev/null @@ -1,47 +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" - } - ], - "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" - } - } -} \ No newline at end of file diff --git a/0.1/examples/image/valid/missing_type.json b/0.1/examples/image/valid/missing_type.json new file mode 100644 index 00000000..b9ece803 --- /dev/null +++ b/0.1/examples/image/valid/missing_type.json @@ -0,0 +1,20 @@ +{ + "@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/schemas/json_schema/strict_image.schema b/0.1/schemas/json_schema/strict_image.schema index d9cdda8d..7dad8969 100644 --- a/0.1/schemas/json_schema/strict_image.schema +++ b/0.1/schemas/json_schema/strict_image.schema @@ -5,6 +5,7 @@ "required": [ "version", "name", + "type", "metadata", "datasets" ] @@ -12,7 +13,6 @@ } }, "required": [ - "multiscales", - "omero" + "multiscales" ] } \ No newline at end of file From f39250068751ba097472d99c76d67a12f9389cef Mon Sep 17 00:00:00 2001 From: William Moore Date: Wed, 1 Dec 2021 17:20:46 +0000 Subject: [PATCH 08/18] Remove unused 'multiscales' from strict_image.schema --- 0.1/schemas/json_schema/strict_image.schema | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/0.1/schemas/json_schema/strict_image.schema b/0.1/schemas/json_schema/strict_image.schema index 7dad8969..ac374e23 100644 --- a/0.1/schemas/json_schema/strict_image.schema +++ b/0.1/schemas/json_schema/strict_image.schema @@ -11,8 +11,5 @@ ] } } - }, - "required": [ - "multiscales" - ] + } } \ No newline at end of file From 84498216938a3a7b31b4e083511681b04518f2e7 Mon Sep 17 00:00:00 2001 From: William Moore Date: Wed, 1 Dec 2021 17:22:32 +0000 Subject: [PATCH 09/18] Remove non-essential 'version' and 'name' from v0.3 image.json --- 0.3/examples/valid/image.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/0.3/examples/valid/image.json b/0.3/examples/valid/image.json index 98f32e79..ebcb882d 100644 --- a/0.3/examples/valid/image.json +++ b/0.3/examples/valid/image.json @@ -2,8 +2,6 @@ "@type": "ngff:Image", "multiscales": [ { - "version": "0.3", - "name": "example", "datasets": [ {"path": "path/to/0"}, {"path": "1"}, From 4f2bf33de736330aa26e86aea6064d65ec92bb32 Mon Sep 17 00:00:00 2001 From: William Moore Date: Thu, 2 Dec 2021 16:40:08 +0000 Subject: [PATCH 10/18] Use allOf in strict_image.schema to add SHOULD rules to image.schema --- 0.1/schemas/json_schema/strict_image.schema | 23 ++++++++++++--------- 0.1/tests/test_validation.py | 20 ++++++++++++++---- 0.1/tox.ini | 1 + 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/0.1/schemas/json_schema/strict_image.schema b/0.1/schemas/json_schema/strict_image.schema index ac374e23..2b127207 100644 --- a/0.1/schemas/json_schema/strict_image.schema +++ b/0.1/schemas/json_schema/strict_image.schema @@ -1,15 +1,18 @@ { - "properties": { + "allOf": [ + { + "$ref": "http://localhost:8000/image.schema" + }, + { + "properties": { "multiscales": { - "items": { - "required": [ - "version", - "name", - "type", - "metadata", - "datasets" - ] - } + "items": { + "required": [ + "version", "metadata", "type" + ] + } } + } } + ] } \ No newline at end of file diff --git a/0.1/tests/test_validation.py b/0.1/tests/test_validation.py index 143d60d8..ffb59953 100644 --- a/0.1/tests/test_validation.py +++ b/0.1/tests/test_validation.py @@ -9,6 +9,11 @@ from jsonschema.exceptions import ValidationError +@pytest.fixture(scope="session") +def httpserver_listen_address(): + return ("127.0.0.1", 8000) + + def files(): return list(glob.glob(f"examples/*/valid/*.json")) + \ list(glob.glob(f"examples/*/invalid/*.json")) @@ -35,7 +40,13 @@ def test_json(testfile): @pytest.mark.parametrize("testfile", strict(), ids=ids(strict())) -def test_strict_rules(testfile): +def test_strict_rules(testfile, httpserver): + + for uri, filename in ( + ("/image.schema", "schemas/json_schema/image.schema"), + ): + with open(filename) as o: + httpserver.expect_request(uri).respond_with_data(o.read()) test_json, schema = load_instance_and_schema(testfile, strict=True) @@ -65,9 +76,10 @@ def load_instance_and_schema(path, strict=False): schema = load_json('schemas/json_schema/' + schema_name) strict_path = 'schemas/json_schema/strict_' + schema_name - if strict and os.path.exists(strict_path): - strict_rules = load_json(strict_path) - schema = merge(schema, strict_rules) + if strict and schema_name == "image.schema": + schema = load_json(strict_path) + # If the schema were using an external URL, could point at local image.schema + # schema['allOf'][0]['$ref'] = "http://localhost:8000/image.schema" return (test_json, schema) diff --git a/0.1/tox.ini b/0.1/tox.ini index 2de32a96..bf07dea4 100644 --- a/0.1/tox.ini +++ b/0.1/tox.ini @@ -5,6 +5,7 @@ skipsdist = True [testenv] deps = pytest + pytest-httpserver jsonschema commands = pytest tests --color=yes --basetemp={envtmpdir} {posargs:-v} From c3283d101331c0bb6f6690ceabb39fcc673ade55 Mon Sep 17 00:00:00 2001 From: William Moore Date: Thu, 2 Dec 2021 16:42:31 +0000 Subject: [PATCH 11/18] Remove unused merge() --- 0.1/tests/test_validation.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/0.1/tests/test_validation.py b/0.1/tests/test_validation.py index ffb59953..32f23f38 100644 --- a/0.1/tests/test_validation.py +++ b/0.1/tests/test_validation.py @@ -88,18 +88,3 @@ def load_json(path): with open(path) as f: json_data = json.loads(f.read()) return json_data - - -def merge(destination, source): - """ - deep merge of source into destination dict - https://stackoverflow.com/questions/20656135/python-deep-merge-dictionary-data - """ - for key, value in source.items(): - if isinstance(value, dict): - node = destination.setdefault(key, {}) - merge(node, value) - else: - destination[key] = value - - return destination \ No newline at end of file From c2c13945ff5992c3f09e18a6532f1068f1813880 Mon Sep 17 00:00:00 2001 From: William Moore Date: Fri, 3 Dec 2021 10:13:32 +0000 Subject: [PATCH 12/18] Manually cache image.schema instead of load via URL resolver --- 0.1/schemas/json_schema/strict_image.schema | 2 +- 0.1/tests/test_validation.py | 21 ++++++++------------- 0.1/tox.ini | 1 - 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/0.1/schemas/json_schema/strict_image.schema b/0.1/schemas/json_schema/strict_image.schema index 2b127207..1756f329 100644 --- a/0.1/schemas/json_schema/strict_image.schema +++ b/0.1/schemas/json_schema/strict_image.schema @@ -1,7 +1,7 @@ { "allOf": [ { - "$ref": "http://localhost:8000/image.schema" + "$ref": "FIXME! https://ngff.openmicroscopy.org/0.1/schemas/image.schema" }, { "properties": { diff --git a/0.1/tests/test_validation.py b/0.1/tests/test_validation.py index 32f23f38..29893f38 100644 --- a/0.1/tests/test_validation.py +++ b/0.1/tests/test_validation.py @@ -9,9 +9,7 @@ from jsonschema.exceptions import ValidationError -@pytest.fixture(scope="session") -def httpserver_listen_address(): - return ("127.0.0.1", 8000) +IMAGE_SCHEMA_KEY = "/image.schema" def files(): @@ -40,13 +38,7 @@ def test_json(testfile): @pytest.mark.parametrize("testfile", strict(), ids=ids(strict())) -def test_strict_rules(testfile, httpserver): - - for uri, filename in ( - ("/image.schema", "schemas/json_schema/image.schema"), - ): - with open(filename) as o: - httpserver.expect_request(uri).respond_with_data(o.read()) +def test_strict_rules(testfile): test_json, schema = load_instance_and_schema(testfile, strict=True) @@ -54,6 +46,9 @@ def test_strict_rules(testfile, httpserver): cls = validator_for(schema) cls.check_schema(schema) validator = cls(schema) + # Manually populate the URL resolver, so it doesn't try to load invalid URL + image_schema = load_json('schemas/json_schema/image.schema') + validator.resolver.store.update({IMAGE_SCHEMA_KEY: image_schema}) warnings = list(validator.iter_errors(test_json)) for warning in warnings: print("WARNING", warning.message) @@ -75,11 +70,11 @@ def load_instance_and_schema(path, strict=False): schema = load_json('schemas/json_schema/' + schema_name) - strict_path = 'schemas/json_schema/strict_' + schema_name if strict and schema_name == "image.schema": + strict_path = 'schemas/json_schema/strict_' + schema_name schema = load_json(strict_path) - # If the schema were using an external URL, could point at local image.schema - # schema['allOf'][0]['$ref'] = "http://localhost:8000/image.schema" + # Replace external URL, with ref to schema we cached above + schema['allOf'][0]['$ref'] = IMAGE_SCHEMA_KEY return (test_json, schema) diff --git a/0.1/tox.ini b/0.1/tox.ini index bf07dea4..2de32a96 100644 --- a/0.1/tox.ini +++ b/0.1/tox.ini @@ -5,7 +5,6 @@ skipsdist = True [testenv] deps = pytest - pytest-httpserver jsonschema commands = pytest tests --color=yes --basetemp={envtmpdir} {posargs:-v} From 7513ddc337e8d944816b4a610cdb37f59f61e556 Mon Sep 17 00:00:00 2001 From: William Moore Date: Fri, 3 Dec 2021 11:15:05 +0000 Subject: [PATCH 13/18] Subclass RefResolver to load local files --- 0.1/schemas/json_schema/strict_image.schema | 2 +- 0.1/tests/test_validation.py | 27 +++++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/0.1/schemas/json_schema/strict_image.schema b/0.1/schemas/json_schema/strict_image.schema index 1756f329..4762ff6d 100644 --- a/0.1/schemas/json_schema/strict_image.schema +++ b/0.1/schemas/json_schema/strict_image.schema @@ -1,7 +1,7 @@ { "allOf": [ { - "$ref": "FIXME! https://ngff.openmicroscopy.org/0.1/schemas/image.schema" + "$ref": "https://ngff.openmicroscopy.org/0.1/schemas/image.schema" }, { "properties": { diff --git a/0.1/tests/test_validation.py b/0.1/tests/test_validation.py index 29893f38..b6dd4e68 100644 --- a/0.1/tests/test_validation.py +++ b/0.1/tests/test_validation.py @@ -4,12 +4,12 @@ import pytest -from jsonschema import validate +from jsonschema import validate, RefResolver from jsonschema.validators import validator_for from jsonschema.exceptions import ValidationError -IMAGE_SCHEMA_KEY = "/image.schema" +IMAGE_SCHEMA_KEY = "https://ngff.openmicroscopy.org/0.1/schemas/image.schema" def files(): @@ -37,6 +37,18 @@ def test_json(testfile): validate(instance=test_json, schema=schema) +class LocalRefResolver(RefResolver): + + def resolve_from_url(self, url): + # Use remote URL to generate local path + url = url.replace("https://ngff.openmicroscopy.org/0.1/schemas", "schemas/json_schema") + # Load local document and cache it + document = load_json(url) + self.store[url] = document + # This will use the cached document, resolve fragment etc. + return super(LocalRefResolver, self).resolve_from_url(url) + + @pytest.mark.parametrize("testfile", strict(), ids=ids(strict())) def test_strict_rules(testfile): @@ -45,10 +57,11 @@ def test_strict_rules(testfile): # Check for all validation errors without throwing exception cls = validator_for(schema) cls.check_schema(schema) - validator = cls(schema) - # Manually populate the URL resolver, so it doesn't try to load invalid URL - image_schema = load_json('schemas/json_schema/image.schema') - validator.resolver.store.update({IMAGE_SCHEMA_KEY: image_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) @@ -73,8 +86,6 @@ def load_instance_and_schema(path, strict=False): if strict and schema_name == "image.schema": strict_path = 'schemas/json_schema/strict_' + schema_name schema = load_json(strict_path) - # Replace external URL, with ref to schema we cached above - schema['allOf'][0]['$ref'] = IMAGE_SCHEMA_KEY return (test_json, schema) From 37c56dd182a42f75357557a6b98f74f1ceb45afd Mon Sep 17 00:00:00 2001 From: William Moore Date: Fri, 3 Dec 2021 16:30:19 +0000 Subject: [PATCH 14/18] Add 'name' to strict_image.schema. multiscales SHOULD have name --- 0.1/examples/image/valid/missing_name.json | 6 +++++- 0.1/schemas/json_schema/strict_image.schema | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/0.1/examples/image/valid/missing_name.json b/0.1/examples/image/valid/missing_name.json index 5c267fa2..fe3de034 100644 --- a/0.1/examples/image/valid/missing_name.json +++ b/0.1/examples/image/valid/missing_name.json @@ -8,7 +8,11 @@ "path": "path/to/0" } ], - "type": "gaussian" + "type": "gaussian", + "metadata": { + "method": "skimage.transform.pyramid_gaussian", + "version": "0.16.1" + } } ] } diff --git a/0.1/schemas/json_schema/strict_image.schema b/0.1/schemas/json_schema/strict_image.schema index 4762ff6d..9c573d07 100644 --- a/0.1/schemas/json_schema/strict_image.schema +++ b/0.1/schemas/json_schema/strict_image.schema @@ -8,7 +8,7 @@ "multiscales": { "items": { "required": [ - "version", "metadata", "type" + "version", "metadata", "type", "name" ] } } From e4865a6e945c64f379c75dc3c6454f3285e6f14e Mon Sep 17 00:00:00 2001 From: William Moore Date: Fri, 3 Dec 2021 17:16:18 +0000 Subject: [PATCH 15/18] Improve LocalRefResolver - overwrite resolve_remove() --- 0.1/schemas/json_schema/image.schema | 2 +- 0.1/schemas/json_schema/strict_image.schema | 2 +- 0.1/tests/test_validation.py | 7 +++---- 0.3/schemas/json_schema/image.schema | 2 +- 0.3/schemas/json_schema/strict_image.schema | 18 ++++++++++++++++++ 5 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 0.3/schemas/json_schema/strict_image.schema diff --git a/0.1/schemas/json_schema/image.schema b/0.1/schemas/json_schema/image.schema index 220ff4ae..23e24eab 100644 --- a/0.1/schemas/json_schema/image.schema +++ b/0.1/schemas/json_schema/image.schema @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "http://localhost:8000/image.schema", + "$id": "https://ngff.openmicroscopy.org/0.1/schemas/json_schema/image.schema", "title": "NGFF Image", "description": "JSON from OME-NGFF .zattrs", "type": "object", diff --git a/0.1/schemas/json_schema/strict_image.schema b/0.1/schemas/json_schema/strict_image.schema index 9c573d07..e240e1be 100644 --- a/0.1/schemas/json_schema/strict_image.schema +++ b/0.1/schemas/json_schema/strict_image.schema @@ -1,7 +1,7 @@ { "allOf": [ { - "$ref": "https://ngff.openmicroscopy.org/0.1/schemas/image.schema" + "$ref": "https://ngff.openmicroscopy.org/0.1/schemas/json_schema/image.schema" }, { "properties": { diff --git a/0.1/tests/test_validation.py b/0.1/tests/test_validation.py index b6dd4e68..0ed5e94e 100644 --- a/0.1/tests/test_validation.py +++ b/0.1/tests/test_validation.py @@ -39,14 +39,13 @@ def test_json(testfile): class LocalRefResolver(RefResolver): - def resolve_from_url(self, url): + def resolve_remote(self, url): # Use remote URL to generate local path - url = url.replace("https://ngff.openmicroscopy.org/0.1/schemas", "schemas/json_schema") + url = url.replace("https://ngff.openmicroscopy.org/0.1/", "") # Load local document and cache it document = load_json(url) self.store[url] = document - # This will use the cached document, resolve fragment etc. - return super(LocalRefResolver, self).resolve_from_url(url) + return document @pytest.mark.parametrize("testfile", strict(), ids=ids(strict())) diff --git a/0.3/schemas/json_schema/image.schema b/0.3/schemas/json_schema/image.schema index 899f4876..1802487b 100644 --- a/0.3/schemas/json_schema/image.schema +++ b/0.3/schemas/json_schema/image.schema @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "http://localhost:8000/image.schema", + "$id": "https://ngff.openmicroscopy.org/0.3/schemas/json_schema/image.schema", "title": "NGFF Image", "description": "JSON from OME-NGFF .zattrs", "type": "object", diff --git a/0.3/schemas/json_schema/strict_image.schema b/0.3/schemas/json_schema/strict_image.schema new file mode 100644 index 00000000..b349a653 --- /dev/null +++ b/0.3/schemas/json_schema/strict_image.schema @@ -0,0 +1,18 @@ +{ + "allOf": [ + { + "$ref": "https://ngff.openmicroscopy.org/0.3/schemas/json_schema/image.schema" + }, + { + "properties": { + "multiscales": { + "items": { + "required": [ + "version", "metadata", "type", "name" + ] + } + } + } + } + ] +} \ No newline at end of file From 78c658f5d375451ed80d7ae903d306529a04627a Mon Sep 17 00:00:00 2001 From: William Moore Date: Thu, 9 Dec 2021 12:18:44 +0000 Subject: [PATCH 16/18] Fix omero.version numbers in 0.1 samples --- 0.1/examples/image/valid/image_complete.json | 2 +- 0.1/examples/image/valid/missing_version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/0.1/examples/image/valid/image_complete.json b/0.1/examples/image/valid/image_complete.json index c568a08e..080448a2 100644 --- a/0.1/examples/image/valid/image_complete.json +++ b/0.1/examples/image/valid/image_complete.json @@ -33,7 +33,7 @@ ], "omero": { "id": 1, - "version": "0.2", + "version": "0.1", "channels": [ { "active": true, diff --git a/0.1/examples/image/valid/missing_version.json b/0.1/examples/image/valid/missing_version.json index 0dccf564..51086c4b 100644 --- a/0.1/examples/image/valid/missing_version.json +++ b/0.1/examples/image/valid/missing_version.json @@ -19,7 +19,7 @@ ], "omero": { "id": 1, - "version": "0.2", + "version": "0.1", "channels": [ { "active": true, From 7ec782c6aa33ae3a64f836aad73c3c27faa9beaa Mon Sep 17 00:00:00 2001 From: William Moore Date: Fri, 10 Dec 2021 14:14:45 +0000 Subject: [PATCH 17/18] remove json_schema/ directory from each version --- 0.1/schemas/{json_schema => }/image.schema | 2 +- 0.1/schemas/json_schema/.DS_Store | Bin 6148 -> 0 bytes 0.1/schemas/{json_schema => }/plate.schema | 0 .../schemas}/strict_image.schema | 2 +- 0.1/tests/test_validation.py | 4 ++-- 0.2/schemas/{json_schema => }/image.schema | 0 0.2/schemas/json_schema/.DS_Store | Bin 6148 -> 0 bytes 0.2/tests/test_validation.py | 2 +- 0.3/schemas/{json_schema => }/image.schema | 2 +- .../schemas}/strict_image.schema | 2 +- 0.3/tests/test_validation.py | 10 ++-------- 11 files changed, 9 insertions(+), 15 deletions(-) rename 0.1/schemas/{json_schema => }/image.schema (96%) delete mode 100644 0.1/schemas/json_schema/.DS_Store rename 0.1/schemas/{json_schema => }/plate.schema (100%) rename {0.3/schemas/json_schema => 0.1/schemas}/strict_image.schema (73%) rename 0.2/schemas/{json_schema => }/image.schema (100%) delete mode 100644 0.2/schemas/json_schema/.DS_Store rename 0.3/schemas/{json_schema => }/image.schema (96%) rename {0.1/schemas/json_schema => 0.3/schemas}/strict_image.schema (73%) diff --git a/0.1/schemas/json_schema/image.schema b/0.1/schemas/image.schema similarity index 96% rename from 0.1/schemas/json_schema/image.schema rename to 0.1/schemas/image.schema index 23e24eab..5a97f3f2 100644 --- a/0.1/schemas/json_schema/image.schema +++ b/0.1/schemas/image.schema @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://ngff.openmicroscopy.org/0.1/schemas/json_schema/image.schema", + "$id": "https://ngff.openmicroscopy.org/0.1/schemas/image.schema", "title": "NGFF Image", "description": "JSON from OME-NGFF .zattrs", "type": "object", diff --git a/0.1/schemas/json_schema/.DS_Store b/0.1/schemas/json_schema/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Fri, 10 Dec 2021 16:49:22 +0000 Subject: [PATCH 18/18] Remove .DS_Store --- 0.1/schemas/.DS_Store | Bin 6148 -> 0 bytes 0.2/schemas/.DS_Store | Bin 6148 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 0.1/schemas/.DS_Store delete mode 100644 0.2/schemas/.DS_Store diff --git a/0.1/schemas/.DS_Store b/0.1/schemas/.DS_Store deleted file mode 100644 index d053bb1cc0388fa27ebfb1f84760ec85f17d67bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKJx{|h5PgOYmAZ6f^o~S;Ul3IR7SshXLxBPUL8~McYkoTKKKQ5zjHsYH%lGW_ z-PwLp>=;0rtZoi~F@PbfV3J0Uh`D!Y%bf+2=D0wEYusawr=CQcXp*&$@W6F1@Qlyv zpDo*~(^b>f^w`BYJ?5yX3%qc53znLe0u^=D zrkQ@4d+Kw4v${DU?S(Ltq8 z0OEjV6}IIqAu-vpbnFZ{LP-`%w9w>FjAY@oXZI@|J3|Xc(wUjZXMTIUB%Pi1tnNsq zVd!8W7+7au+qz@9|Bv{|^gi;}L!uW91Oxw!fi$SjstGscck7q!$z7XSFIh#zuagFa m?X{l(cH|t{(Lo!}(xzYO*cnO|v1>Rnegu?|P{F`2Fz^Z@=;0rtZoi~F@PbfV3J0Uh`D!Y%bf+2=D0wEYusawr=CQcXp*&$@W6F1@Qlyv zpDo*~(^b>f^w`BYJ?5yX3%qc53znLe0u^=D zrkQ@4d+Kw4v${DU?S(Ltq8 z0OEjV6}IIqAu-vpbnFZ{LP-`%w9w>FjAY@oXZI@|J3|Xc(wUjZXMTIUB%Pi1tnNsq zVd!8W7+7au+qz@9|Bv{|^gi;}L!uW91Oxw!fi$SjstGscck7q!$z7XSFIh#zuagFa m?X{l(cH|t{(Lo!}(xzYO*cnO|v1>Rnegu?|P{F`2Fz^Z@