From 06b07a48ea5e8d749f60d5c23ab2e6c84d8fe481 Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Mon, 23 May 2022 22:47:26 +0100 Subject: [PATCH 1/3] Port plate/well JSON schemas to latest specification --- latest/schemas/plate.schema | 136 +++++++++++++++++++++++++++++ latest/schemas/strict_plate.schema | 28 ++++++ latest/schemas/strict_well.schema | 17 ++++ latest/schemas/well.schema | 47 ++++++++++ 4 files changed, 228 insertions(+) create mode 100644 latest/schemas/plate.schema create mode 100644 latest/schemas/strict_plate.schema create mode 100644 latest/schemas/strict_well.schema create mode 100644 latest/schemas/well.schema diff --git a/latest/schemas/plate.schema b/latest/schemas/plate.schema new file mode 100644 index 00000000..417f156d --- /dev/null +++ b/latest/schemas/plate.schema @@ -0,0 +1,136 @@ +{ + "$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" + }, + "starttime": { + "description": "The start timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch", + "type": "integer", + "minimum": 0 + }, + "endtime": { + "description": "The end timestamp of the acquisition, expressed as epoch time i.e. the number seconds since the Epoch", + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "id" + ] + } + }, + "version": { + "description": "The version of the specification", + "type": "string", + "enum": [ + "0.5-dev" + ] + }, + "field_count": { + "description": "The maximum number of fields per view across all wells", + "type": "integer", + "exclusiveMinimum": 0 + }, + "name": { + "description": "The name of the plate", + "type": "string" + }, + "columns": { + "description": "The columns of the plate", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "description": "The column name", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "rows": { + "description": "The rows of the plate", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "description": "The row name", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "name" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "wells": { + "description": "The wells of the plate", + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "description": "The path to the well subgroup", + "type": "string", + "pattern": "^[A-Za-z0-9]+/[A-Za-z0-9]+$" + }, + "rowIndex": { + "description": "The index of the well in the rows list", + "type": "integer", + "minimum": 0 + }, + "columnIndex": { + "description": "The index of the well in the columns list", + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "path", "rowIndex", "columnIndex" + ] + }, + "minItems": 1, + "uniqueItems": true + } + }, + "required": [ + "columns", "rows", "wells" + ] + } + } +} diff --git a/latest/schemas/strict_plate.schema b/latest/schemas/strict_plate.schema new file mode 100644 index 00000000..5a88ab72 --- /dev/null +++ b/latest/schemas/strict_plate.schema @@ -0,0 +1,28 @@ +{ + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/strict_plate.schema", + "allOf": [ + { + "$ref": "https://ngff.openmicroscopy.org/0.4/schemas/plate.schema" + }, + { + "properties": { + "plate": { + "properties": { + "acquisitions": { + "items": { + "required": [ + "name", + "maximumfieldcount" + ] + } + } + }, + "required": [ + "name", + "version" + ] + } + } + } + ] +} diff --git a/latest/schemas/strict_well.schema b/latest/schemas/strict_well.schema new file mode 100644 index 00000000..1e200294 --- /dev/null +++ b/latest/schemas/strict_well.schema @@ -0,0 +1,17 @@ +{ + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/strict_well.schema", + "allOf": [ + { + "$ref": "https://ngff.openmicroscopy.org/0.4/schemas/well.schema" + }, + { + "properties": { + "well": { + "required": [ + "version" + ] + } + } + } + ] +} diff --git a/latest/schemas/well.schema b/latest/schemas/well.schema new file mode 100644 index 00000000..891abd05 --- /dev/null +++ b/latest/schemas/well.schema @@ -0,0 +1,47 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://ngff.openmicroscopy.org/0.4/schemas/well.schema", + "title": "OME-NGFF well schema", + "description": "JSON from OME-NGFF .zattrs", + "type": "object", + "properties": { + "well": { + "type": "object", + "properties": { + "images": { + "description": "The fields of view for this well", + "type": "array", + "items": { + "type": "object", + "properties": { + "acquisition": { + "description": "A unique identifier within the context of the plate", + "type": "integer" + }, + "path": { + "description": "The path for this field of view subgroup", + "type": "string", + "pattern": "^[A-Za-z0-9]+$" + } + }, + "required": [ + "path" + ] + }, + "minItems": 1, + "uniqueItems": true + }, + "version": { + "description": "The version of the specification", + "type": "string", + "enum": [ + "0.5-dev" + ] + } + }, + "required": [ + "images" + ] + } + } +} From 0f397185c923a7c6c1c4ca388fdc2b6d0a10b84c Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Mon, 23 May 2022 22:47:47 +0100 Subject: [PATCH 2/3] Add plate/well test suite and update validation tests --- latest/tests/plate_suite.json | 819 +++++++++++++++++++++++++++ latest/tests/strict_plate_suite.json | 187 ++++++ latest/tests/strict_well_suite.json | 50 ++ latest/tests/test_validation.py | 16 +- latest/tests/well_suite.json | 88 +++ 5 files changed, 1155 insertions(+), 5 deletions(-) create mode 100644 latest/tests/plate_suite.json create mode 100644 latest/tests/strict_plate_suite.json create mode 100644 latest/tests/strict_well_suite.json create mode 100644 latest/tests/well_suite.json diff --git a/latest/tests/plate_suite.json b/latest/tests/plate_suite.json new file mode 100644 index 00000000..c19ad60e --- /dev/null +++ b/latest/tests/plate_suite.json @@ -0,0 +1,819 @@ +{ + "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/latest/tests/strict_plate_suite.json b/latest/tests/strict_plate_suite.json new file mode 100644 index 00000000..931cf7e7 --- /dev/null +++ b/latest/tests/strict_plate_suite.json @@ -0,0 +1,187 @@ +{ + "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.5-dev", + "wells": [ + { + "path": "A/1", + "rowIndex": 0, + "columnIndex": 0 + } + ] + } + }, + "valid": true + }, + { + "formerly": "plate/missing_name", + "data": { + "plate": { + "columns": [ + { + "name": "A" + } + ], + "rows": [ + { + "name": "1" + } + ], + "version": "0.5-dev", + "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.5-dev", + "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.5-dev", + "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.5-dev", + "wells": [ + { + "path": "A/1", + "rowIndex": 0, + "columnIndex": 0 + } + ] + } + }, + "valid": false + } + ] +} diff --git a/latest/tests/strict_well_suite.json b/latest/tests/strict_well_suite.json new file mode 100644 index 00000000..edfb2936 --- /dev/null +++ b/latest/tests/strict_well_suite.json @@ -0,0 +1,50 @@ +{ + "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.5-dev" + } + }, + "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.5-dev" + } + }, + "valid": true + } + ] +} diff --git a/latest/tests/test_validation.py b/latest/tests/test_validation.py index 83f49911..9e441fad 100644 --- a/latest/tests/test_validation.py +++ b/latest/tests/test_validation.py @@ -1,5 +1,6 @@ import json import glob +import os from dataclasses import dataclass from typing import List @@ -9,11 +10,15 @@ 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 - schema_store: dict data: dict valid: bool = True @@ -54,7 +59,7 @@ def pytest_generate_tests(metafunc): schema = json.load(f) for test in suite["tests"]: ids.append("validate_" + str(test["formerly"]).split("/")[-1][0:-5]) - suites.append(Suite(schema, {schema["$id"]: schema}, test["data"], test["valid"])) + suites.append(Suite(schema, test["data"], test["valid"])) # Examples for config_filename in glob.glob("examples/*/.config.json"): @@ -63,13 +68,14 @@ def pytest_generate_tests(metafunc): schema = data["schema"] with open(schema) as f: schema = json.load(f) - for filename in glob.glob("examples/*/*.json"): + 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, {schema["$id"]: schema}, data, True)) # Assume true + suites.append(Suite(schema, data, True)) # Assume true metafunc.parametrize("suite", suites, ids=ids, indirect=True) @@ -80,6 +86,6 @@ def suite(request): def test_run(suite): - resolver = RefResolver.from_schema(suite.schema, store=suite.schema_store) + resolver = RefResolver.from_schema(suite.schema, store=schema_store) validator = Validator(suite.schema, resolver=resolver) suite.validate(validator) diff --git a/latest/tests/well_suite.json b/latest/tests/well_suite.json new file mode 100644 index 00000000..0f752551 --- /dev/null +++ b/latest/tests/well_suite.json @@ -0,0 +1,88 @@ +{ + "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 + } + ] +} From 8a4bd123f0a87b264171bacdadd970cd9f7baa0a Mon Sep 17 00:00:00 2001 From: Sebastien Besson Date: Mon, 23 May 2022 22:51:05 +0100 Subject: [PATCH 3/3] Extract plate/well snippets under examples --- latest/examples/plate_strict/.config.json | 3 + .../examples/plate_strict/plate_2wells.json | 91 ++++++++ .../examples/plate_strict/plate_6wells.json | 72 ++++++ latest/examples/well_strict/.config.json | 3 + latest/examples/well_strict/well_2fields.json | 15 ++ latest/examples/well_strict/well_4fields.json | 23 ++ latest/index.bs | 217 ++---------------- 7 files changed, 223 insertions(+), 201 deletions(-) create mode 100644 latest/examples/plate_strict/.config.json create mode 100644 latest/examples/plate_strict/plate_2wells.json create mode 100644 latest/examples/plate_strict/plate_6wells.json create mode 100644 latest/examples/well_strict/.config.json create mode 100644 latest/examples/well_strict/well_2fields.json create mode 100644 latest/examples/well_strict/well_4fields.json diff --git a/latest/examples/plate_strict/.config.json b/latest/examples/plate_strict/.config.json new file mode 100644 index 00000000..a49b1743 --- /dev/null +++ b/latest/examples/plate_strict/.config.json @@ -0,0 +1,3 @@ +{ + "schema": "schemas/strict_plate.schema" +} diff --git a/latest/examples/plate_strict/plate_2wells.json b/latest/examples/plate_strict/plate_2wells.json new file mode 100644 index 00000000..3578798f --- /dev/null +++ b/latest/examples/plate_strict/plate_2wells.json @@ -0,0 +1,91 @@ +{ + "plate": { + "acquisitions": [ + { + "id": 1, + "maximumfieldcount": 1, + "name": "single acquisition", + "starttime": 1343731272000 + } + ], + "columns": [ + { + "name": "1" + }, + { + "name": "2" + }, + { + "name": "3" + }, + { + "name": "4" + }, + { + "name": "5" + }, + { + "name": "6" + }, + { + "name": "7" + }, + { + "name": "8" + }, + { + "name": "9" + }, + { + "name": "10" + }, + { + "name": "11" + }, + { + "name": "12" + } + ], + "field_count": 1, + "name": "sparse test", + "rows": [ + { + "name": "A" + }, + { + "name": "B" + }, + { + "name": "C" + }, + { + "name": "D" + }, + { + "name": "E" + }, + { + "name": "F" + }, + { + "name": "G" + }, + { + "name": "H" + } + ], + "version": "0.5-dev", + "wells": [ + { + "path": "C/5", + "rowIndex": 2, + "columnIndex": 4 + }, + { + "path": "D/7", + "rowIndex": 3, + "columnIndex": 6 + } + ] + } +} diff --git a/latest/examples/plate_strict/plate_6wells.json b/latest/examples/plate_strict/plate_6wells.json new file mode 100644 index 00000000..d2f06389 --- /dev/null +++ b/latest/examples/plate_strict/plate_6wells.json @@ -0,0 +1,72 @@ +{ + "plate": { + "acquisitions": [ + { + "id": 1, + "maximumfieldcount": 2, + "name": "Meas_01(2012-07-31_10-41-12)", + "starttime": 1343731272000 + }, + { + "id": 2, + "maximumfieldcount": 2, + "name": "Meas_02(201207-31_11-56-41)", + "starttime": 1343735801000 + } + ], + "columns": [ + { + "name": "1" + }, + { + "name": "2" + }, + { + "name": "3" + } + ], + "field_count": 4, + "name": "test", + "rows": [ + { + "name": "A" + }, + { + "name": "B" + } + ], + "version": "0.5-dev", + "wells": [ + { + "path": "A/1", + "rowIndex": 0, + "columnIndex": 0 + }, + { + "path": "A/2", + "rowIndex": 0, + "columnIndex": 1 + }, + { + "path": "A/3", + "rowIndex": 0, + "columnIndex": 2 + }, + { + "path": "B/1", + "rowIndex": 1, + "columnIndex": 0 + }, + { + "path": "B/2", + "rowIndex": 1, + "columnIndex": 1 + }, + { + "path": "B/3", + "rowIndex": 1, + "columnIndex": 2 + } + ] + } +} diff --git a/latest/examples/well_strict/.config.json b/latest/examples/well_strict/.config.json new file mode 100644 index 00000000..129ac69c --- /dev/null +++ b/latest/examples/well_strict/.config.json @@ -0,0 +1,3 @@ +{ + "schema": "schemas/strict_well.schema" +} diff --git a/latest/examples/well_strict/well_2fields.json b/latest/examples/well_strict/well_2fields.json new file mode 100644 index 00000000..6f43a911 --- /dev/null +++ b/latest/examples/well_strict/well_2fields.json @@ -0,0 +1,15 @@ +{ + "well": { + "images": [ + { + "acquisition": 0, + "path": "0" + }, + { + "acquisition": 3, + "path": "1" + } + ], + "version": "0.5-dev" + } +} \ No newline at end of file diff --git a/latest/examples/well_strict/well_4fields.json b/latest/examples/well_strict/well_4fields.json new file mode 100644 index 00000000..c2285d53 --- /dev/null +++ b/latest/examples/well_strict/well_4fields.json @@ -0,0 +1,23 @@ +{ + "well": { + "images": [ + { + "acquisition": 1, + "path": "0" + }, + { + "acquisition": 1, + "path": "1" + }, + { + "acquisition": 2, + "path": "2" + }, + { + "acquisition": 2, + "path": "3" + } + ], + "version": "0.5-dev" + } +} \ No newline at end of file diff --git a/latest/index.bs b/latest/index.bs index 00b06c29..26bb77aa 100644 --- a/latest/index.bs +++ b/latest/index.bs @@ -496,173 +496,18 @@ custom attributes of the plate group under the `plate` key. 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. -```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.5-dev", - "wells": [ - { - "path": "A/1", - "rowIndex": 0, - "columnIndex": 0 - }, - { - "path": "A/2" - "rowIndex": 0, - "columnIndex": 1 - }, - { - "path": "A/3" - "rowIndex": 0, - "columnIndex": 2 - }, - { - "path": "B/1" - "rowIndex": 1, - "columnIndex": 0 - }, - { - "path": "B/2" - "rowIndex": 1, - "columnIndex": 1 - }, - { - "path": "B/3" - "rowIndex": 1, - "columnIndex": 2 - } - ] - } -``` +
+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. -```json -"plate": { - "acquisitions": [ - { - "id": 1, - "maximumfieldcount": 1, - "name": "single acquisition", - "starttime": 1343731272000 - }, - ], - "columns": [ - { - "name": "1" - }, - { - "name": "2" - }, - { - "name": "3" - }, - { - "name": "4" - }, - { - "name": "5" - }, - { - "name": "6" - }, - { - "name": "7" - }, - { - "name": "8" - }, - { - "name": "9" - }, - { - "name": "10" - }, - { - "name": "11" - }, - { - "name": "12" - } - ], - "field_count": 1, - "name": "sparse test", - "rows": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "D" - }, - { - "name": "E" - }, - { - "name": "F" - }, - { - "name": "G" - }, - { - "name": "H" - } - ], - "version": "0.1", - "wells": [ - { - "path": "C/5" - "rowIndex": 2, - "columnIndex": 4 - }, - { - "path": "D/7" - "rowIndex": 3, - "columnIndex": 6 - } - ] - } -``` +
+path: examples/plate_strict/plate_2wells.json
+highlight: json
+
"well" metadata {#well-md} -------------------------- @@ -687,49 +532,19 @@ 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. -```json -"well": { - "images": [ - { - "acquisition": 1, - "path": "0" - }, - { - "acquisition": 1, - "path": "1" - }, - { - "acquisition": 2, - "path": "2" - }, - { - "acquisition": 2, - "path": "3" - } - ], - "version": "0.5-dev" - } -``` +
+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. -```json -"well": { - "images": [ - { - "acquisition": 0, - "path": "0" - }, - { - "acquisition": 3, - "path": "1" - } - ], - "version": "0.1" -} -``` +
+path: examples/well_strict/well_2fields.json
+highlight: json
+
Specification naming style {#naming-style} ==========================================