From 397cf853c6330fbf0b8655b30ad41193873893ab Mon Sep 17 00:00:00 2001 From: William Moore Date: Thu, 5 Feb 2026 10:13:56 +0000 Subject: [PATCH 01/12] omero fields optional ported from https://github.com/ome/ngff/pull/297/ --- index.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/index.md b/index.md index b7a31020..90d4f85d 100644 --- a/index.md +++ b/index.md @@ -1524,14 +1524,21 @@ for more information. The `omero` metadata is optional, but if present it MUST contain the field `channels`, which is an array of dictionaries describing the channels of the image. -Each dictionary in `channels` MUST contain the field `color`, -which is a string of 6 hexadecimal digits specifying the color of the channel in RGB format. -Each dictionary in `channels` MUST contain the field `window`, -which is a dictionary describing the windowing of the channel. -The field `window` MUST contain the fields `min` and `max`, -which are the minimum and maximum values of the window, respectively. -It MUST also contain the fields `start` and `end`, -which are the start and end values of the window, respectively. +The `channels` array length SHOULD correspond to the size of the `c` axis. +Each dictionary in `channels` MAY contain the following fields: + +- `color` (string) String of 6 hexadecimal digits specifying the color of the channel in RGB format. +- `label` (string) Channel name. +- `active` (boolean) Indicates whether the channel should be displayed. +- `window` (dictionary) Values describing the windowing of the channel. All values are optional (MAY). + The `min` and `max` values may be used by viewers as the range of channel sliders. + All values can be floating-point numbers, but will likely be integers for integer pixel types. + - `min` (float) Should correspond to the minimum pixel intensity for that channel. + - `max` (float) Should correspond to the maximum pixel intensity for that channel. + - `start` (float) Start of the rendering window. + - `end` (float) End of the rendering window. +- `inverted` (boolean) If true, the rendering of darkest to brightest pixels should be inverted. + ### "labels" metadata (labels-md)= From a5f44f9968b25141269a1e6373fcd4f51afdf8a8 Mon Sep 17 00:00:00 2001 From: Will Moore Date: Thu, 5 Feb 2026 10:33:00 +0000 Subject: [PATCH 02/12] Apply suggestion from @jo-mueller Co-authored-by: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index 90d4f85d..ffc7af39 100644 --- a/index.md +++ b/index.md @@ -1525,7 +1525,7 @@ for more information. The `omero` metadata is optional, but if present it MUST contain the field `channels`, which is an array of dictionaries describing the channels of the image. The `channels` array length SHOULD correspond to the size of the `c` axis. -Each dictionary in `channels` MAY contain the following fields: +Each object in `channels` MAY contain the following fields: - `color` (string) String of 6 hexadecimal digits specifying the color of the channel in RGB format. - `label` (string) Channel name. From 390dfb5724dcb7e48bf2f5d050d9c69e14551feb Mon Sep 17 00:00:00 2001 From: Will Moore Date: Thu, 5 Feb 2026 10:33:23 +0000 Subject: [PATCH 03/12] Apply suggestion from @jo-mueller Co-authored-by: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index ffc7af39..6d60e71f 100644 --- a/index.md +++ b/index.md @@ -1524,7 +1524,7 @@ for more information. The `omero` metadata is optional, but if present it MUST contain the field `channels`, which is an array of dictionaries describing the channels of the image. -The `channels` array length SHOULD correspond to the size of the `c` axis. +The `channels` array length SHOULD correspond to the size of the respective channels axis, if present. Each object in `channels` MAY contain the following fields: - `color` (string) String of 6 hexadecimal digits specifying the color of the channel in RGB format. From e0c81bca41b6183d34081bb15e67e29b85d99f70 Mon Sep 17 00:00:00 2001 From: William Moore Date: Thu, 5 Feb 2026 10:37:47 +0000 Subject: [PATCH 04/12] dictionaries renamed to objects --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index 6d60e71f..c50061f4 100644 --- a/index.md +++ b/index.md @@ -1523,7 +1523,7 @@ See the [OMERO WebGateway documentation](https://omero.readthedocs.io/en/stable/ for more information. The `omero` metadata is optional, but if present it MUST contain the field `channels`, -which is an array of dictionaries describing the channels of the image. +which is an array of objects describing the channels of the image. The `channels` array length SHOULD correspond to the size of the respective channels axis, if present. Each object in `channels` MAY contain the following fields: From e9141d300acaa15d2c71fce6d13f2e406d11b1e1 Mon Sep 17 00:00:00 2001 From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> Date: Thu, 12 Feb 2026 17:03:15 +0100 Subject: [PATCH 05/12] Update index.md --- index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.md b/index.md index 724c0a96..79eaa929 100644 --- a/index.md +++ b/index.md @@ -1533,8 +1533,8 @@ Each object in `channels` MAY contain the following fields: - `window` (dictionary) Values describing the windowing of the channel. All values are optional (MAY). The `min` and `max` values may be used by viewers as the range of channel sliders. All values can be floating-point numbers, but will likely be integers for integer pixel types. - - `min` (float) Should correspond to the minimum pixel intensity for that channel. - - `max` (float) Should correspond to the maximum pixel intensity for that channel. + - `min` (float) Default setting for lower bound for values of `start` field. + - `max` (float) Default setting for upper bound for values of `end` field. - `start` (float) Start of the rendering window. - `end` (float) End of the rendering window. - `inverted` (boolean) If true, the rendering of darkest to brightest pixels should be inverted. From 0886492ac442adbbdf2a9e962ab0d7c51c8f37ec Mon Sep 17 00:00:00 2001 From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> Date: Thu, 12 Feb 2026 17:16:58 +0100 Subject: [PATCH 06/12] align schema and spec text --- index.md | 6 ++++-- schemas/image.schema | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/index.md b/index.md index 79eaa929..f55b15e7 100644 --- a/index.md +++ b/index.md @@ -1530,11 +1530,13 @@ Each object in `channels` MAY contain the following fields: - `color` (string) String of 6 hexadecimal digits specifying the color of the channel in RGB format. - `label` (string) Channel name. - `active` (boolean) Indicates whether the channel should be displayed. -- `window` (dictionary) Values describing the windowing of the channel. All values are optional (MAY). - The `min` and `max` values may be used by viewers as the range of channel sliders. +- `window` (dictionary) Values describing the windowing of the channel. + If provided, `start` and `end` values MUST be specified. All values can be floating-point numbers, but will likely be integers for integer pixel types. - `min` (float) Default setting for lower bound for values of `start` field. + MAY be used by viewers as the lower range of channel sliders. - `max` (float) Default setting for upper bound for values of `end` field. + MAY be used by viewers as the upper range of channel sliders. - `start` (float) Start of the rendering window. - `end` (float) End of the rendering window. - `inverted` (boolean) If true, the rendering of darkest to brightest pixels should be inverted. diff --git a/schemas/image.schema b/schemas/image.schema index 0907d253..fcba2982 100644 --- a/schemas/image.schema +++ b/schemas/image.schema @@ -137,9 +137,7 @@ }, "required": [ "start", - "min", - "end", - "max" + "end" ] }, "label": { @@ -153,6 +151,9 @@ }, "active": { "type": "boolean" + }, + "inverted": { + "type": "boolean" } } } From 1ecf8207e060e7170f5168d71bab2e83a1aebedf Mon Sep 17 00:00:00 2001 From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:01:15 +0100 Subject: [PATCH 07/12] chore: json example code style --- index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/index.md b/index.md index f55b15e7..39b89a7e 100644 --- a/index.md +++ b/index.md @@ -1494,9 +1494,9 @@ if not datasets: [=Transitional=] information specific to the channels of an image and how to render it can be found under the `omero` key in the group-level metadata: ```json -"id": 1, # ID in OMERO -"name": "example.tif", # Name as shown in the UI -"channels": [ # Array matching the c dimension size +"id": 1, // ID in OMERO +"name": "example.tif", // Name as shown in the UI +"channels": [ // Array matching the c dimension size { "active": true, "coefficient": 1, @@ -1513,9 +1513,9 @@ if not datasets: } ], "rdefs": { - "defaultT": 0, # First timepoint to show the user - "defaultZ": 118, # First Z section to show the user - "model": "color" # "color" or "greyscale" + "defaultT": 0, // First timepoint to show the user + "defaultZ": 118, // First Z section to show the user + "model": "color" // "color" or "greyscale" } ``` From 16eda0692bf5c40d52f35ce967e05977aefb6ed4 Mon Sep 17 00:00:00 2001 From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:01:35 +0100 Subject: [PATCH 08/12] fix: added missing fields to spec text --- index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.md b/index.md index 39b89a7e..db9ec9fe 100644 --- a/index.md +++ b/index.md @@ -1530,6 +1530,8 @@ Each object in `channels` MAY contain the following fields: - `color` (string) String of 6 hexadecimal digits specifying the color of the channel in RGB format. - `label` (string) Channel name. - `active` (boolean) Indicates whether the channel should be displayed. +- `coefficient`: (float) Value to multiply the pixel values of the channel by when rendering. +- `family`: (string) Used transfer function family for rendering the channel, e.g. "linear", "log", "gamma". - `window` (dictionary) Values describing the windowing of the channel. If provided, `start` and `end` values MUST be specified. All values can be floating-point numbers, but will likely be integers for integer pixel types. From b6d5807734b690b8a6f5a88164b761069f45ad3b Mon Sep 17 00:00:00 2001 From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:01:55 +0100 Subject: [PATCH 09/12] chore: semantic line break and text style --- index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/index.md b/index.md index db9ec9fe..5553570e 100644 --- a/index.md +++ b/index.md @@ -1491,7 +1491,8 @@ if not datasets: ### "omero" metadata (transitional) (omero-md)= -[=Transitional=] information specific to the channels of an image and how to render it can be found under the `omero` key in the group-level metadata: +Information specific to the channels of an image and how to render it +can be found under the `omero` key in the group-level metadata (i.e., under `"ome" > "omero"`): ```json "id": 1, // ID in OMERO @@ -1525,7 +1526,7 @@ for more information. The `omero` metadata is optional, but if present it MUST contain the field `channels`, which is an array of objects describing the channels of the image. The `channels` array length SHOULD correspond to the size of the respective channels axis, if present. -Each object in `channels` MAY contain the following fields: +Each object in `channels` is optional and MAY contain the following fields: - `color` (string) String of 6 hexadecimal digits specifying the color of the channel in RGB format. - `label` (string) Channel name. From cd4509b812606f60253f8a11697770914bbc048f Mon Sep 17 00:00:00 2001 From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:02:20 +0100 Subject: [PATCH 10/12] fix: adding missing `coefficient` to schema --- schemas/image.schema | 3 +++ 1 file changed, 3 insertions(+) diff --git a/schemas/image.schema b/schemas/image.schema index fcba2982..bc181458 100644 --- a/schemas/image.schema +++ b/schemas/image.schema @@ -143,6 +143,9 @@ "label": { "type": "string" }, + "coefficient": { + "type": "number" + }, "family": { "type": "string" }, From 362a98873f5b9df416cfb3b22286e7e232c8fa0f Mon Sep 17 00:00:00 2001 From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:02:28 +0100 Subject: [PATCH 11/12] test: added test cases --- .../spec/invalid/omero/missing_channels.json | 56 +++++++++++ .../spec/invalid/omero/missing_start_end.json | 94 ++++++++++++++++++ .../spec/valid/omero/full_omero_metadata.json | 99 +++++++++++++++++++ 3 files changed, 249 insertions(+) create mode 100644 tests/attributes/spec/invalid/omero/missing_channels.json create mode 100644 tests/attributes/spec/invalid/omero/missing_start_end.json create mode 100644 tests/attributes/spec/valid/omero/full_omero_metadata.json diff --git a/tests/attributes/spec/invalid/omero/missing_channels.json b/tests/attributes/spec/invalid/omero/missing_channels.json new file mode 100644 index 00000000..7c5b7b58 --- /dev/null +++ b/tests/attributes/spec/invalid/omero/missing_channels.json @@ -0,0 +1,56 @@ +{ + "ome": { + "version": "0.6.dev3", + "multiscales": [ + { + "coordinateSystems": [ + { + "name": "physical", + "axes": [ + { + "name": "z", + "type": "space", + "unit": "micrometer" + }, + { + "name": "y", + "type": "space", + "unit": "micrometer" + }, + { + "name": "x", + "type": "space", + "unit": "micrometer" + } + ] + } + ], + "datasets": [ + { + "path": "s0", + "coordinateTransformations": [ + { + "scale": [ + 1, + 1, + 1 + ], + "input": "s0", + "output": "physical", + "type": "scale" + } + ] + } + ] + } + ], + "omero": { + } + }, + "_conformance": { + "schema": { + "id": "schemas/image.schema" + }, + "valid": false + } +} \ No newline at end of file diff --git a/tests/attributes/spec/invalid/omero/missing_start_end.json b/tests/attributes/spec/invalid/omero/missing_start_end.json new file mode 100644 index 00000000..c188b5f9 --- /dev/null +++ b/tests/attributes/spec/invalid/omero/missing_start_end.json @@ -0,0 +1,94 @@ +{ + "ome": { + "version": "0.6.dev3", + "multiscales": [ + { + "coordinateSystems": [ + { + "name": "physical", + "axes": [ + { + "name": "z", + "type": "space", + "unit": "micrometer" + }, + { + "name": "y", + "type": "space", + "unit": "micrometer" + }, + { + "name": "x", + "type": "space", + "unit": "micrometer" + } + ] + } + ], + "datasets": [ + { + "path": "s0", + "coordinateTransformations": [ + { + "scale": [ + 1, + 1, + 1 + ], + "input": "s0", + "output": "physical", + "type": "scale" + } + ] + } + ] + } + ], + "omero": { + "channels": [ + { + "label": "Channel:0", + "color": "#ff0000", + "active": true, + "family": "linear", + "coefficient": 1.0, + "inverted": false, + "window": { + "min": 0, + "max": 255 + } + }, + { + "label": "Channel:1", + "color": "#00ff00", + "active": true, + "family": "log", + "coefficient": 0.5, + "inverted": true, + "window": { + "min": 0, + "max": 255 + } + }, + { + "label": "Channel:2", + "color": "#0000ff", + "active": true, + "family": "gamma", + "coefficient": 2.0, + "inverted": false, + "window": { + "min": 0, + "max": 255 + } + } + ] + } + }, + "_conformance": { + "schema": { + "id": "schemas/image.schema" + }, + "valid": false + } +} \ No newline at end of file diff --git a/tests/attributes/spec/valid/omero/full_omero_metadata.json b/tests/attributes/spec/valid/omero/full_omero_metadata.json new file mode 100644 index 00000000..367d255f --- /dev/null +++ b/tests/attributes/spec/valid/omero/full_omero_metadata.json @@ -0,0 +1,99 @@ +{ + "ome": { + "version": "0.6.dev3", + "multiscales": [ + { + "coordinateSystems": [ + { + "name": "physical", + "axes": [ + { + "name": "z", + "type": "space", + "unit": "micrometer" + }, + { + "name": "y", + "type": "space", + "unit": "micrometer" + }, + { + "name": "x", + "type": "space", + "unit": "micrometer" + } + ] + } + ], + "datasets": [ + { + "path": "s0", + "coordinateTransformations": [ + { + "scale": [ + 1, + 1, + 1 + ], + "input": "s0", + "output": "physical", + "type": "scale" + } + ] + } + ] + } + ], + "omero": { + "channels": [ + { + "label": "Channel:0", + "color": "#ff0000", + "active": true, + "family": "linear", + "coefficient": 1.0, + "inverted": false, + "window": { + "min": 0, + "start": 100, + "end": 200, + "max": 255 + } + }, + { + "label": "Channel:1", + "color": "#00ff00", + "active": true, + "family": "log", + "coefficient": 0.5, + "inverted": true, + "window": { + "min": 0, + "start": 50, + "end": 150, + "max": 255 + } + }, + { + "label": "Channel:2", + "color": "#0000ff", + "active": true, + "family": "gamma", + "coefficient": 2.0, + "inverted": false, + "window": { + "min": 0, + "start": 25, + "end": 125, + "max": 255 + } + } + ] + } + }, + "_conformance": { + "schema": { + "id": "schemas/image.schema" + } + } +} \ No newline at end of file From facbf73cbba62f3c3f859632aea3fe50351dd8e2 Mon Sep 17 00:00:00 2001 From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:26:43 +0100 Subject: [PATCH 12/12] Added note to changelog --- version_history.md | 1 + 1 file changed, 1 insertion(+) diff --git a/version_history.md b/version_history.md index f08db909..041af156 100644 --- a/version_history.md +++ b/version_history.md @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Updated version keys from `0.6.dev2` to `0.6.dev3` everywhere - style: Homogeneous use of backticks in spec document +- spec: Released requirements for `omero` metadata in the spec document and in schemas. ### Removed