From b7cd3811469c2207e7fd45c870010a2470c2c9d2 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 24 Sep 2025 23:43:41 +0200
Subject: [PATCH 01/55] Create .gitignore
---
.gitignore | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 97 insertions(+)
create mode 100644 .gitignore
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..7cbb3e98
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,97 @@
+*/.DS_Store
+**/__pycache__/*
+*/index.html
+_build
+_bikeshed
+.tox
+.vscode
+.*plist
+
+# do not sync auto-generated md files
+docs/examples/
+docs/schemas/
+
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+*_version.py
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*,cover
+.hypothesis/
+.napari_cache
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+
+# Flask instance folder
+instance/
+
+# Sphinx documentation
+docs/_build/
+
+# MkDocs documentation
+/site/
+
+# PyBuilder
+target/
+
+# IPython Notebook
+.ipynb_checkpoints
+
+# pyenv
+.python-version
+
+# OS
+.DS_Store
+
+# written by setuptools_scm
+*/_version.py
+
+# PyBuilder
+.idea
+venv/
From e20b3e9f1f49b818021211d61e48d98acaa6f1c5 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 24 Sep 2025 23:43:48 +0200
Subject: [PATCH 02/55] Create .readthedocs.yaml
---
.readthedocs.yaml | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
create mode 100644 .readthedocs.yaml
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
new file mode 100644
index 00000000..e9d6c16b
--- /dev/null
+++ b/.readthedocs.yaml
@@ -0,0 +1,30 @@
+version: 2
+
+build:
+ os: ubuntu-22.04
+ tools:
+ python: "3.11"
+ jobs:
+ pre_build:
+ # Generate the Sphinx configuration for this Jupyter Book so it builds.
+ - "jupyter-book config sphinx docs/"
+ - "python ./docs/pre_build.py"
+
+python:
+ install:
+ - method: pip
+ path: .
+ extra_requirements:
+ - sphinx
+ - sphinx-book-theme
+ - sphinx-proof
+ - sphinx-inline-tabs
+ - sphinx-examples
+ - json-schema-for-humans
+ - myst-parser
+ - json_with_comments
+
+sphinx:
+ configuration: docs/conf.py
+ builder: html
+ fail_on_warning: true
\ No newline at end of file
From 5cc0e82dc12d945d8cc967b65e3fa8fbba280043 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 24 Sep 2025 23:44:07 +0200
Subject: [PATCH 03/55] configure jupyter-book
---
_config.yml | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
_toc.yml | 15 +++++++++++++++
2 files changed, 63 insertions(+)
create mode 100644 _config.yml
create mode 100644 _toc.yml
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 00000000..84fe012f
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1,48 @@
+# Book settings
+# Learn more at https://jupyterbook.org/customize/config.html
+# Comprehensive example: https://github.com/executablebooks/jupyter-book/blob/master/docs/_config.yml
+
+title: Next-generation file format specification
+author: Josh Moore
+logo: https://www.openmicroscopy.org/img/logos/ome-logomark.svg
+
+# Force re-execution of notebooks on each build.
+# See https://jupyterbook.org/content/execute.html
+execute:
+ execute_notebooks: off
+
+# Define the name of the latex output file for PDF builds
+latex:
+ latex_documents:
+ targetname: book.tex
+
+# Add a bibtex file so that we can create citations
+bibtex_bibfiles:
+ - references.bib
+
+# Information about where the book exists on the web
+repository:
+ url: https://github.com/ome/ngff-spec # Online location of your book
+ path_to_book: docs # Optional path to your book, relative to the repository root
+ branch: main # Which branch of the repository should be used when creating links (optional)
+
+# Add GitHub buttons to your book
+# See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository
+html:
+ use_issues_button: true
+ use_repository_button: true
+
+
+sphinx:
+ extra_extensions:
+ - sphinx.ext.autosummary
+ - sphinx.ext.autodoc
+ - sphinx.ext.napoleon # Enable support for NumPy and Google style docstrings
+ - sphinx.ext.intersphinx
+ - sphinx_inline_tabs
+ - sphinx_proof
+ - sphinx_examples
+
+ config:
+ add_module_names: True
+ autosummary_generate: True
\ No newline at end of file
diff --git a/_toc.yml b/_toc.yml
new file mode 100644
index 00000000..827d9776
--- /dev/null
+++ b/_toc.yml
@@ -0,0 +1,15 @@
+# Table of contents
+# Learn more at https://jupyterbook.org/customize/toc.html
+
+format: jb-book
+root: intro
+
+chapters:
+- file: specification
+- file: docs/examples
+ sections:
+ - glob: docs/examples/*
+ exclude: docs/examples/examples.md
+- file: docs/schemas
+ sections:
+ - glob: docs/schemas/*
\ No newline at end of file
From 7a615b81dd2ed8e784a30ab5ee0edfe4cae259d2 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 24 Sep 2025 23:44:25 +0200
Subject: [PATCH 04/55] moved _includes to new directory
---
copyright.include => docs/_includes/copyright.include | 0
header.include => docs/_includes/header.include | 0
2 files changed, 0 insertions(+), 0 deletions(-)
rename copyright.include => docs/_includes/copyright.include (100%)
rename header.include => docs/_includes/header.include (100%)
diff --git a/copyright.include b/docs/_includes/copyright.include
similarity index 100%
rename from copyright.include
rename to docs/_includes/copyright.include
diff --git a/header.include b/docs/_includes/header.include
similarity index 100%
rename from header.include
rename to docs/_includes/header.include
From ef34d197025067c0c179ee9e4e817d734c24c052 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 24 Sep 2025 23:44:46 +0200
Subject: [PATCH 05/55] renamed bikeshed file to specification.md
---
index.bs => specification.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
rename index.bs => specification.md (99%)
diff --git a/index.bs b/specification.md
similarity index 99%
rename from index.bs
rename to specification.md
index 6211d398..805229f3 100644
--- a/index.bs
+++ b/specification.md
@@ -21,7 +21,7 @@ Status Text: will be provided between numbered versions. Data written with these
Status Text: (an "editor's draft") will not necessarily be supported.
-OME-Zarr specification {#ome-zarr}
+# OME-Zarr specification {#ome-zarr}
----------------------------------
The conventions and specifications defined in this document are designed to
@@ -69,7 +69,7 @@ The following layout describes the expected Zarr hierarchy for images with
multiple levels of resolutions and optionally associated labels.
Note that the number of dimensions is variable between 2 and 5 and that axis names are arbitrary, see [[#multiscale-md]] for details.
-
+```
├── 123.zarr # One OME-Zarr image (id=123).
│ ...
│
@@ -107,7 +107,7 @@ Note that the number of dimensions is variable between 2 and 5 and that axis nam
├── 0 # Each multiscale level is stored as a separate Zarr array, as above, but only integer values
└── ... # are supported.
-
+```
From 4c80c2ad68622c48445cc4514856d1ff18d39bad Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 24 Sep 2025 23:44:55 +0200
Subject: [PATCH 06/55] added ngff reference
---
references.bib | 10 ++++++++++
1 file changed, 10 insertions(+)
create mode 100644 references.bib
diff --git a/references.bib b/references.bib
new file mode 100644
index 00000000..cea36a61
--- /dev/null
+++ b/references.bib
@@ -0,0 +1,10 @@
+@article{moore2021ome,
+ title={OME-NGFF: a next-generation file format for expanding bioimaging data-access strategies},
+ author={Moore, Josh and Allan, Chris and Besson, S{\'e}bastien and Burel, Jean-Marie and Diel, Erin and Gault, David and Kozlowski, Kevin and Lindner, Dominik and Linkert, Melissa and Manz, Trevor and others},
+ journal={Nature methods},
+ volume={18},
+ number={12},
+ pages={1496--1498},
+ year={2021},
+ publisher={Nature Publishing Group US New York}
+}
\ No newline at end of file
From d47a52913752d6cf94f8ca0b92b7526c6ca2863c Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 00:09:26 +0200
Subject: [PATCH 07/55] Create intro.md
---
intro.md | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 intro.md
diff --git a/intro.md b/intro.md
new file mode 100644
index 00000000..1f8feeb5
--- /dev/null
+++ b/intro.md
@@ -0,0 +1,3 @@
+# NGFF
+
+This page contains next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. All specifications are submitted to the https://image.sc community for review. It also provides example metadata files as well as json schema files to ease practical implementation and provide validation targets for datasets in the field.
\ No newline at end of file
From 62c89fc403867c8568f8d37c1c2c7e7fbaf610e3 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 00:09:42 +0200
Subject: [PATCH 08/55] create section header files
---
docs/examples.md | 3 +++
docs/schemas.md | 3 +++
2 files changed, 6 insertions(+)
create mode 100644 docs/examples.md
create mode 100644 docs/schemas.md
diff --git a/docs/examples.md b/docs/examples.md
new file mode 100644
index 00000000..d7c1c369
--- /dev/null
+++ b/docs/examples.md
@@ -0,0 +1,3 @@
+# JSON Examples
+
+This document contains JSON examples for ngff-compliant metadata layouts.
\ No newline at end of file
diff --git a/docs/schemas.md b/docs/schemas.md
new file mode 100644
index 00000000..46bd9a73
--- /dev/null
+++ b/docs/schemas.md
@@ -0,0 +1,3 @@
+# JSON schemas
+
+Here is some information on the json schemas
\ No newline at end of file
From 6606a9c50ef91ceb125c29acb385ee42cc917436 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 00:09:53 +0200
Subject: [PATCH 09/55] Create pre_build.py
---
docs/pre_build.py | 91 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 91 insertions(+)
create mode 100644 docs/pre_build.py
diff --git a/docs/pre_build.py b/docs/pre_build.py
new file mode 100644
index 00000000..e77fa0d2
--- /dev/null
+++ b/docs/pre_build.py
@@ -0,0 +1,91 @@
+# %%
+import os
+import json
+import glob
+from pathlib import Path
+import jsonc as json
+import yaml
+
+# %%
+# change working directory to the location of this script
+os.chdir(os.path.dirname(os.path.abspath(__file__)))
+
+# %%
+# glob recursively to find all json files
+input_directory = '../examples'
+output_directory = 'examples'
+os.makedirs(output_directory, exist_ok=True)
+example_types = os.listdir(input_directory)
+
+
+md_files = []
+
+for example in example_types:
+ json_files = glob.glob(os.path.join(input_directory, example, '*.json'), recursive=True)
+
+ example_directory = os.path.join(output_directory, example)
+ markdown_file_name = os.path.join(output_directory, f'{example}.md')
+
+ # add header
+ markdown_content = f"""# {example}\n\n
+
+This document contains JSON examples for {example} metadata layouts.
+
+"""
+
+ # append each json file content
+ for json_file in json_files:
+ print(f'Processing {json_file}...')
+ with open(json_file, 'r') as file:
+ json_data = json.load(file)
+ json_str = json.dumps(json_data, indent=4)
+ json_file_name = Path(json_file).stem
+
+ # Create the Markdown content
+ markdown_content += f"""
+## {os.path.splitext(json_file_name)[0]}
+(examples:{example}:{Path(json_file).stem})=
+
+```{{code-block}} json
+:caption: {json_file_name}
+:linenos:
+
+{json_str}
+```
+"""
+
+ # create
+ with open(markdown_file_name, 'w') as md_file:
+
+ md_file.write(markdown_content)
+ md_files.append(markdown_file_name)
+
+# %% [markdown]
+# ## json schema
+
+# %%
+from json_schema_for_humans.generate import generate_from_filename
+from json_schema_for_humans.generation_configuration import GenerationConfiguration
+
+schema_source_dir = '../schemas'
+output_directory = 'schemas'
+schema_files = glob.glob(os.path.join(schema_source_dir, '*.schema'), recursive=True)
+
+for schema_file in schema_files:
+ output_md_path = os.path.join(output_directory, f"{Path(schema_file).stem}.md")
+ print(f'Processing {schema_file}...')
+
+ # Generate the documentation
+ config = GenerationConfiguration(
+ template_name='md',
+ with_footer=True,
+ show_toc=True,
+ link_to_reused_ref=False)
+ try:
+ generate_from_filename(
+ schema_file,
+ result_file_name=output_md_path,
+ config=config
+ )
+ except Exception as e:
+ print(f"Error processing {schema_file}: {e}")
From 640cdcf588327e54aa235948240523723f0d11bc Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 00:10:00 +0200
Subject: [PATCH 10/55] Update _config.yml
---
_config.yml | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/_config.yml b/_config.yml
index 84fe012f..1be635af 100644
--- a/_config.yml
+++ b/_config.yml
@@ -8,8 +8,8 @@ logo: https://www.openmicroscopy.org/img/logos/ome-logomark.svg
# Force re-execution of notebooks on each build.
# See https://jupyterbook.org/content/execute.html
-execute:
- execute_notebooks: off
+# execute:
+# execute_notebooks: off
# Define the name of the latex output file for PDF builds
latex:
@@ -32,6 +32,13 @@ html:
use_issues_button: true
use_repository_button: true
+myst:
+ enable_extensions:
+ - colon_fence
+ - deflist
+ - dollarmath
+ - linkify
+ - substitution
sphinx:
extra_extensions:
From 5ef390b7f652e954a2a83bb38202a6f189e6a4d5 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 00:10:08 +0200
Subject: [PATCH 11/55] create propper title
---
specification.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/specification.md b/specification.md
index 805229f3..4dc4e3bd 100644
--- a/specification.md
+++ b/specification.md
@@ -1,3 +1,5 @@
+# OME-Zarr specification
+
-Title: OME-Zarr specification
-Shortname: ome-zarr
-Level: 1
-Status: w3c/CG-FINAL
-TR: https://ngff.openmicroscopy.org/0.5/
-URL: https://ngff.openmicroscopy.org/0.6-dev/
-Repository: https://github.com/ome/ngff
-Issue Tracking: Forums https://forum.image.sc/tag/ome-ngff
-Logo: http://www.openmicroscopy.org/img/logos/ome-logomark.svg
-Local Boilerplate: header yes, copyright yes
-Boilerplate: style-darkmode off
-Markup Shorthands: markdown yes
-Editor: Josh Moore, German BioImaging e.V., https://gerbi-gmb.de/, https://orcid.org/0000-0003-4028-811X
-Text Macro: NGFFVERSION 0.5
-Abstract: This document contains next-generation file format (NGFF)
-Abstract: specifications for storing bioimaging data in the cloud.
-Abstract: All specifications are submitted to the https://image.sc community for review.
-Status Text: The current released version of this specification is 0.5. Migration scripts
-Status Text: will be provided between numbered versions. Data written with these latest changes
-Status Text: (an "editor's draft") will not necessarily be supported.
-
+# {{ title }}
+
+**Shortname:** {{ shortname }}
+**Level:** {{ level }}
+**Status:** {{ status }}
+
+**Feedback:** {{ issue_tracking }}
+
+**Editor:** {{ editor_name }}, ({{ editor_affiliation }}), {{ editor_orcid }}
+
+## Abstract
+
+This document contains next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. All specifications are submitted to the https://image.sc community for review.
+
+## Status of This Document
+
+The current released version of this specification is 0.5. Migration scripts will be provided between numbered versions. Data written with these latest changes (an "editor's draft") will not necessarily be supported.
# OME-Zarr specification {#ome-zarr}
----------------------------------
From d24b1fd0ecf0a3cbdcf126d55832287c2bd0bfb5 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 13:53:57 +0200
Subject: [PATCH 13/55] make code cleaner
---
docs/pre_build.py | 118 ++++++++++++++++++++++------------------------
1 file changed, 57 insertions(+), 61 deletions(-)
diff --git a/docs/pre_build.py b/docs/pre_build.py
index e77fa0d2..94c964db 100644
--- a/docs/pre_build.py
+++ b/docs/pre_build.py
@@ -6,43 +6,39 @@
import jsonc as json
import yaml
-# %%
# change working directory to the location of this script
os.chdir(os.path.dirname(os.path.abspath(__file__)))
-# %%
-# glob recursively to find all json files
-input_directory = '../examples'
-output_directory = 'examples'
-os.makedirs(output_directory, exist_ok=True)
-example_types = os.listdir(input_directory)
-
-md_files = []
+def build_json_examples():
+ """Build markdown files from json examples."""
+ # glob recursively to find all json files
+ input_directory = '../examples'
+ output_directory = 'examples'
+ os.makedirs(output_directory, exist_ok=True)
+ example_types = os.listdir(input_directory)
-for example in example_types:
- json_files = glob.glob(os.path.join(input_directory, example, '*.json'), recursive=True)
+ for example in example_types:
+ json_files = glob.glob(os.path.join(input_directory, example, '*.json'), recursive=True)
+ markdown_file_name = os.path.join(output_directory, f'{example}.md')
- example_directory = os.path.join(output_directory, example)
- markdown_file_name = os.path.join(output_directory, f'{example}.md')
-
- # add header
- markdown_content = f"""# {example}\n\n
+ # add header
+ markdown_content = f"""# {example}\n\n
This document contains JSON examples for {example} metadata layouts.
"""
- # append each json file content
- for json_file in json_files:
- print(f'Processing {json_file}...')
- with open(json_file, 'r') as file:
- json_data = json.load(file)
- json_str = json.dumps(json_data, indent=4)
- json_file_name = Path(json_file).stem
+ # append each json file content
+ for json_file in json_files:
+ print(f'Processing {json_file}...')
+ with open(json_file, 'r') as file:
+ json_data = json.load(file)
+ json_str = json.dumps(json_data, indent=4)
+ json_file_name = Path(json_file).stem
- # Create the Markdown content
- markdown_content += f"""
+ # Create the Markdown content
+ markdown_content += f"""
## {os.path.splitext(json_file_name)[0]}
(examples:{example}:{Path(json_file).stem})=
@@ -53,39 +49,39 @@
{json_str}
```
"""
-
- # create
- with open(markdown_file_name, 'w') as md_file:
-
- md_file.write(markdown_content)
- md_files.append(markdown_file_name)
-
-# %% [markdown]
-# ## json schema
-
-# %%
-from json_schema_for_humans.generate import generate_from_filename
-from json_schema_for_humans.generation_configuration import GenerationConfiguration
-
-schema_source_dir = '../schemas'
-output_directory = 'schemas'
-schema_files = glob.glob(os.path.join(schema_source_dir, '*.schema'), recursive=True)
-
-for schema_file in schema_files:
- output_md_path = os.path.join(output_directory, f"{Path(schema_file).stem}.md")
- print(f'Processing {schema_file}...')
-
- # Generate the documentation
- config = GenerationConfiguration(
- template_name='md',
- with_footer=True,
- show_toc=True,
- link_to_reused_ref=False)
- try:
- generate_from_filename(
- schema_file,
- result_file_name=output_md_path,
- config=config
- )
- except Exception as e:
- print(f"Error processing {schema_file}: {e}")
+ # create
+ with open(markdown_file_name, 'w') as md_file:
+ md_file.write(markdown_content)
+
+def build_json_schemas():
+ from json_schema_for_humans.generate import generate_from_filename
+ from json_schema_for_humans.generation_configuration import GenerationConfiguration
+
+ schema_source_dir = '../schemas'
+ output_directory = 'schemas'
+ os.makedirs(output_directory, exist_ok=True)
+ schema_files = glob.glob(os.path.join(schema_source_dir, '*.schema'), recursive=True)
+
+ for schema_file in schema_files:
+ if 'strict' in schema_file:
+ continue # skip strict schemas
+ output_md_path = os.path.join(output_directory, f"{Path(schema_file).stem}.md")
+ print(f'Processing {schema_file}...')
+
+ # Generate the documentation
+ config = GenerationConfiguration(
+ template_name='md',
+ with_footer=True,
+ show_toc=False,
+ link_to_reused_ref=False)
+ try:
+ generate_from_filename(
+ os.path.abspath(schema_file),
+ result_file_name=os.path.abspath(output_md_path),
+ config=config
+ )
+ except Exception as e:
+ print(f"Error processing {schema_file}: {e}")
+
+build_json_examples()
+build_json_schemas()
From e64e4ff8517781a5ebd937a8bc5dc1146d552b94 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 13:54:05 +0200
Subject: [PATCH 14/55] fixed myst references
---
specification.md | 59 +++++++++++++++++++++++++++---------------------
1 file changed, 33 insertions(+), 26 deletions(-)
diff --git a/specification.md b/specification.md
index b80fe125..4b91a35c 100644
--- a/specification.md
+++ b/specification.md
@@ -16,8 +16,6 @@ This document contains next-generation file format (NGFF) specifications for sto
The current released version of this specification is 0.5. Migration scripts will be provided between numbered versions. Data written with these latest changes (an "editor's draft") will not necessarily be supported.
-# OME-Zarr specification {#ome-zarr}
-----------------------------------
The conventions and specifications defined in this document are designed to
enable next-generation file formats to represent the same bioimaging data
@@ -42,8 +40,8 @@ implementations that are later submitted as a formal specification. (See [[#bf2r
Some of the JSON examples in this document include comments. However, these are only for
clarity purposes and comments MUST NOT be included in JSON objects.
-Storage format {#storage-format}
-================================
+Storage format
+==============
OME-Zarr is implemented using the Zarr format as defined by the
[version 3 of the Zarr specification](https://zarr-specs.readthedocs.io/en/latest/v3/core/v3.0.html).
@@ -57,12 +55,12 @@ is represented here as it would appear locally but could equally
be stored on a web server to be accessed via HTTP or in object storage
like S3 or GCS.
-Images {#image-layout}
-----------------------
+Images
+------
The following layout describes the expected Zarr hierarchy for images with
multiple levels of resolutions and optionally associated labels.
-Note that the number of dimensions is variable between 2 and 5 and that axis names are arbitrary, see [[#multiscale-md]] for details.
+Note that the number of dimensions is variable between 2 and 5 and that axis names are arbitrary, see [multiscales metadata](multiscale-md) for details.
```
├── 123.zarr # One OME-Zarr image (id=123).
@@ -106,19 +104,19 @@ Note that the number of dimensions is variable between 2 and 5 and that axis nam
-High-content screening {#hcs-layout}
-------------------------------------
+High-content screening
+----------------------
The following specification defines the hierarchy for a high-content screening
dataset. Three groups MUST be defined above the images:
- the group above the images defines the well and MUST implement the
- [well specification](#well-md). All images contained in a well are fields
+ [well specification](well-md). All images contained in a well are fields
of view of the same well
- the group above the well defines a row of wells
- the group above the well row defines an entire plate i.e. a two-dimensional
collection of wells organized in rows and columns. It MUST implement the
- [plate specification](#plate-md)
+ [plate specification](plate-md)
A well row group SHOULD NOT be present if there are no images in the well row.
A well group SHOULD NOT be present if there are no images in the well.
@@ -171,11 +169,13 @@ The OME-Zarr Metadata version MUST be consistent within a hierarchy.
}
```
-"axes" metadata {#axes-md}
+"axes" metadata
--------------------------
+{#axes-md}
+
"axes" describes the dimensions of a coordinate systems and adds an interpretation to the data along that dimension. A named collection
-of axes forms a coordinate system ([[#coord-sys-md]]) (see below).
+of axes forms a [coordinate system](coord-sys-md).
It is a list of dictionaries, where each dictionary describes a dimension (axis) and:
- MUST contain the field "name" that gives the name for this dimension. The values MUST be unique across all "name" fields.
- SHOULD contain the field "type". It SHOULD be one of the strings "array", "space", "time", "channel", "coordinate", or
@@ -185,7 +185,7 @@ It is a list of dictionaries, where each dictionary describes a dimension (axis)
- Units for "time" axes: 'attosecond', 'centisecond', 'day', 'decisecond', 'exasecond', 'femtosecond', 'gigasecond', 'hectosecond', 'hour', 'kilosecond', 'megasecond', 'microsecond', 'millisecond', 'minute', 'nanosecond', 'petasecond', 'picosecond', 'second', 'terasecond', 'yoctosecond', 'yottasecond', 'zeptosecond', 'zettasecond'
- MAY contain the field "longName". The value MUST be a string, and can provide a longer name or description of an axis and its properties.
-The "axes" are used as part of [[#multiscale-md]]. The length of "axes" MUST be equal to the number of dimensions of the arrays that contain the image data.
+The "axes" are used as part of [multiscales metadata](multiscales-md). The length of "axes" MUST be equal to the number of dimensions of the arrays that contain the image data.
The "dimension_names" attribute MUST be included in the `zarr.json` of the Zarr array of a multiscale level and MUST match the names in the "axes" metadata.
@@ -238,9 +238,11 @@ to the discrete axis `"c"`. Indexing an image at the point `(1, 0.2, 0.3, 0.4)`
-"coordinateSystems" metadata {#coord-sys-md}
+"coordinateSystems" metadata
--------------------------
+{#coord-sys-md}
+
A "coordinate system" is a collection of "axes" / dimensions with a name. Every coordinate system:
- MUST contain the field "name". The value MUST be a non-empty string that is unique among `coordinateSystem`s.
- MUST contain the field "axes", whose value is an array of valid "axes".
@@ -280,7 +282,7 @@ collected at different angles, a measurement by instrument 1 at the point with c
measurement at the same point in instrument 2 (i.e., it may not be the same physical location in the sample). To analyze both
images together, they must be in the same coordinate system.
-The set of coordinate transformations ([[#trafo-md]]) encodes relationships between coordinate systems, specifically, how to
+The set of [coordinate transformations](trafo-md) encodes relationships between coordinate systems, specifically, how to
convert points and images to different coordinate systems. Implementations can apply the coordinate transform to images or
points in coordinate system "sampleA_instrument2" to bring them into the "sampleA_instrument1" coordinate system. In this case,
the ROI should be transformed to the "sampleA_image1" coordinate system, then used for quantification with the instrument 1
@@ -477,9 +479,11 @@ Conforming readers:
- MAY ignore other groups or arrays under the root of the hierarchy.
-"coordinateTransformations" metadata {#trafo-md}
+"coordinateTransformations" metadata
------------------------------------------------
+{#trafo-md}
+
"coordinateTransformations" describe the mapping between two coordinate systems (defined by "axes").
For example, to map an array's discrete coordinate system to its corresponding physical coordinates.
Coordinate transforms are in the "forward" direction. They represent functions from *points* in the
@@ -547,7 +551,7 @@ Conforming readers:
- SHOULD be able to apply transformations to points;
- SHOULD be able to apply transformations to images;
-Coordinate transformations from array to physical coordinates MUST be stored in multiscales ([[#multiscale-md]]).
+Coordinate transformations from array to physical coordinates MUST be stored in [multiscales](multiscale-md).
Transformations between different images MUST be stored in the attributes of a parent zarr group. For transformations that store
data or parameters in a zarr array, those zarr arrays SHOULD be stored in a zarr group `"coordinateTransformations"`.
@@ -1335,8 +1339,9 @@ highlight: json
-"multiscales" metadata {#multiscale-md}
----------------------------------------
+"multiscales" metadata
+----------------------
+(multiscale-md)=
Metadata about an image can be found under the "multiscales" key in the group-level OME-Zarr Metadata.
Here, image refers to 2 to 5 dimensional data representing image or volumetric data with optional time or channel axes.
@@ -1344,7 +1349,7 @@ It is stored in a multiple resolution representation.
"multiscales" contains a list of dictionaries where each entry describes a multiscale image.
-Each "multiscales" dictionary MUST contain the field "coordinateSystems", see [[#coord-sys-md]], with the following constraints.
+Each "multiscales" dictionary MUST contain the field "coordinateSystems", see [coordinateSystems metadata](coord-sys-md), with the following constraints.
The length of "axes" must be between 2 and 5 and MUST be equal to the dimensionality of the zarr arrays storing the image data (see "datasets:path").
The "axes" MUST contain 2 or 3 entries of "type:space" and MAY contain one additional entry of "type:time" and MAY contain one additional entry of "type:channel" or a null / custom type.
The order of the entries MUST correspond to the order of dimensions of the zarr arrays. In addition, the entries MUST be ordered by "type" where the "time" axis must come first (if present), followed by the "channel" or custom axis (if present) and the axes of type "space".
@@ -1356,7 +1361,7 @@ to the current zarr group. The "path"s MUST be ordered from largest (i.e. highes
Each "datasets" dictionary MUST have the same number of dimensions and MUST NOT have more than 5 dimensions. The number of dimensions and order MUST correspond to number and order of "axes".
Each dictionary in "datasets" MUST contain the field "coordinateTransformations", which contains a list of transformations that map the data coordinates to the physical coordinates (as specified by "axes") for this resolution level.
-The transformations are defined according to [[#trafo-md]].
+The transformations are defined according to [coordinateTransformations metadata](trafo-md).
They MUST contain exactly one `scale` transformation that specifies the pixel size in physical units or time duration. If scaling information is not available or applicable for one of the axes, the value MUST express the scaling factor between the current resolution and the first resolution for the given axis, defaulting to 1.0 if there is no downsampling along the axis.
It MAY contain exactly one `translation` that specifies the offset from the origin in physical units. If `translation` is given it MUST be listed after `scale` to ensure that it is given in physical coordinates.
@@ -1510,7 +1515,7 @@ The `plate` dictionary MAY contain an `acquisitions` key whose value MUST be a l
JSON objects defining the acquisitions for a given plate to which wells can refer to. Each
acquisition object MUST contain an `id` key whose value MUST be an unique integer identifier
greater than or equal to 0 within the context of the plate to which fields of view can refer
-to (see #well-md).
+to (see [well metadata](well-md)).
Each acquisition object SHOULD contain a `name` key whose value MUST be a string identifying
the name of the acquisition. Each acquisition object SHOULD contain a `maximumfieldcount`
key whose value MUST be a positive integer indicating the maximum number of fields of view for the
@@ -1572,8 +1577,10 @@ path: examples/plate_strict/plate_2wells.json
highlight: json
-"well" metadata {#well-md}
---------------------------
+"well" metadata
+---------------
+
+{#well-md}
For high-content screening datasets, the metadata about all fields of views
under a given well can be found under the "well" key in the attributes of the
@@ -1585,7 +1592,7 @@ specifying all fields of views for a given well. Each image object MUST contain
MUST contain only alphanumeric characters, MUST be case-sensitive, and MUST NOT be a duplicate
of any other `path` in the `images` list. If multiple acquisitions were performed in the plate,
it MUST contain an `acquisition` key whose value MUST be an integer identifying the acquisition
-which MUST match one of the acquisition JSON objects defined in the plate metadata (see #plate-md).
+which MUST match one of the acquisition JSON objects defined in the [plate metadata](plate-md).
The `well` dictionary SHOULD contain a `version` key whose value MUST be a string specifying the
version of the well specification.
From 169fe30aec4a02ba0955cc8e61c3d137e736d08c Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 13:55:26 +0200
Subject: [PATCH 15/55] Create requirements.txt
---
requirements.txt | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 requirements.txt
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 00000000..e4cf6cc4
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,6 @@
+jupyter-book
+json-schema-for-humans
+jason-with-comments
+sphinx-inline-tabs
+sphinx-proof
+sphinx-examples
\ No newline at end of file
From b0bed90a0215a5f6aab499960dd9c5826f33c18f Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 14:01:44 +0200
Subject: [PATCH 16/55] move requirements to separate file
---
.readthedocs.yaml | 11 ++---------
docs/requirements.txt | 9 +++++++++
2 files changed, 11 insertions(+), 9 deletions(-)
create mode 100644 docs/requirements.txt
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index e9d6c16b..5291fb87 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -12,17 +12,10 @@ build:
python:
install:
+ - requirements: docs/requirements.txt
- method: pip
path: .
- extra_requirements:
- - sphinx
- - sphinx-book-theme
- - sphinx-proof
- - sphinx-inline-tabs
- - sphinx-examples
- - json-schema-for-humans
- - myst-parser
- - json_with_comments
+
sphinx:
configuration: docs/conf.py
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 00000000..4201ed42
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,9 @@
+sphinx
+sphinx-book-theme
+sphinx-proof
+sphinx-inline-tabs
+sphinx-examples
+json-schema-for-humans
+myst-parser
+json_with_comments
+jupyter-book
\ No newline at end of file
From f9273408eb4e66ea517d3833461b5b1994670846 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 14:05:38 +0200
Subject: [PATCH 17/55] remove installation attempt
---
.readthedocs.yaml | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 5291fb87..64d55372 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -3,7 +3,7 @@ version: 2
build:
os: ubuntu-22.04
tools:
- python: "3.11"
+ python: "3.13"
jobs:
pre_build:
# Generate the Sphinx configuration for this Jupyter Book so it builds.
@@ -13,11 +13,7 @@ build:
python:
install:
- requirements: docs/requirements.txt
- - method: pip
- path: .
sphinx:
- configuration: docs/conf.py
- builder: html
- fail_on_warning: true
\ No newline at end of file
+ configuration: docs/conf.py
\ No newline at end of file
From 7c37de8218697455efe5dae01ab07650a5e32955 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 14:12:11 +0200
Subject: [PATCH 18/55] change conversion target folder
---
.readthedocs.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 64d55372..360f7af7 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -7,7 +7,7 @@ build:
jobs:
pre_build:
# Generate the Sphinx configuration for this Jupyter Book so it builds.
- - "jupyter-book config sphinx docs/"
+ - "jupyter-book config sphinx ."
- "python ./docs/pre_build.py"
python:
From 780e89f27fc3d275e8f2817494f24c8bce8c30a2 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 14:16:18 +0200
Subject: [PATCH 19/55] fix conf.py location
---
.readthedocs.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 360f7af7..cc67767f 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -16,4 +16,4 @@ python:
sphinx:
- configuration: docs/conf.py
\ No newline at end of file
+ configuration: conf.py
\ No newline at end of file
From d9539b6fe4978e54698c3ab2c7846d34211d7025 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 25 Sep 2025 14:36:40 +0200
Subject: [PATCH 20/55] Use spec-text as front-page
---
_toc.yml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/_toc.yml b/_toc.yml
index 827d9776..1cdd0bf9 100644
--- a/_toc.yml
+++ b/_toc.yml
@@ -2,10 +2,9 @@
# Learn more at https://jupyterbook.org/customize/toc.html
format: jb-book
-root: intro
+root: specification
chapters:
-- file: specification
- file: docs/examples
sections:
- glob: docs/examples/*
From 2cb1c2dba672fdedb18871e12c0a1207b8d121d3 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 1 Oct 2025 13:52:15 +0200
Subject: [PATCH 21/55] convert links to myst-references
---
specification.md | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/specification.md b/specification.md
index 4b91a35c..dde0cbca 100644
--- a/specification.md
+++ b/specification.md
@@ -34,7 +34,7 @@ The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL
intention of removing it in the future. Implementations may be expected (MUST) or
encouraged (SHOULD) to support the reading of the data, but writing will usually
be optional (MAY). Examples of transitional metadata include custom additions by
-implementations that are later submitted as a formal specification. (See [[#bf2raw]])
+implementations that are later submitted as a formal specification. (See [bioformats2raw](bf2raw))
Some of the JSON examples in this document include comments. However, these are only for
@@ -400,8 +400,9 @@ half-open interval `[-0.5, 0.5) x [-0.5, 0.5)` (i.e., -0.5 is included, +0.5 is
-"bioformats2raw.layout" (transitional) {#bf2raw}
-------------------------------------------------
+"bioformats2raw.layout" (transitional)
+--------------------------------------
+(bf2raw)=
[=Transitional=] "bioformats2raw.layout" metadata identifies a group which implicitly describes a series of images.
The need for the collection stems from the common "multi-image file" scenario in microscopy. Parsers like Bio-Formats
@@ -435,7 +436,7 @@ highlight: json
If the top-level group represents a plate, the `bioformats2raw.layout` metadata will be present but
-the "plate" key MUST also be present, takes precedence and parsing of such datasets should follow [[#plate-md]]. It is not
+the "plate" key MUST also be present, takes precedence and parsing of such datasets should follow (see [plate metadata](plate-md)). It is not
possible to mix collections of images with plates at present.
@@ -1396,8 +1397,9 @@ if not datasets:
datasets = [x["path"] for x in multiscales[0]["datasets"]]
```
-"omero" metadata (transitional) {#omero-md}
--------------------------------------------
+"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:
@@ -1437,8 +1439,9 @@ Each dictionary in "channels" MUST contain the field "window", which is a dictio
The field "window" MUST contain the fields "min" and "max", which are the minimum and maximum values of the window, respectively.
It MUST also contain the fields "start" and "end", which are the start and end values of the window, respectively.
-"labels" metadata {#labels-md}
-------------------------------
+"labels" metadata
+-----------------
+(labels-md)=
In OME-Zarr, Zarr arrays representing pixel-annotation data are stored in a group called "labels". Some applications--notably image segmentation--produce
a new image that is in the same coordinate system as a corresponding multiscale image (usually having the same dimensions and coordinate transformations).
@@ -1505,8 +1508,9 @@ highlight: json
In this case, the pixels consisting of a 0 in the Zarr array will be displayed as 50% blue and 50% opacity. Pixels with a 1 in the Zarr array,
which correspond to cellular space, will be displayed as 50% green and 50% opacity.
-"plate" metadata {#plate-md}
-----------------------------
+"plate" metadata
+----------------
+(plate-md)=
For high-content screening datasets, the plate layout can be found under the
custom attributes of the plate group under the `plate` key in the group-level metadata.
From 53ab4295cf78ac82e6fec610a43e58b53fb369af Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 1 Oct 2025 14:22:23 +0200
Subject: [PATCH 22/55] add zenodo reference
---
references.bib | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/references.bib b/references.bib
index cea36a61..90d674c8 100644
--- a/references.bib
+++ b/references.bib
@@ -7,4 +7,18 @@ @article{moore2021ome
pages={1496--1498},
year={2021},
publisher={Nature Publishing Group US New York}
+}
+
+@software{ngff_spec_latest,
+ author = {Josh Moore},
+ title = {ome/ngff: Next-generation file format (NGFF)
+ specifications for storing bioimaging data in the
+ cloud.
+ },
+ month = nov,
+ year = 2020,
+ publisher = {Zenodo},
+ version = {0.0.1},
+ doi = {10.5281/zenodo.4282107},
+ url = {https://ngff.openmicroscopy.org/latest/},
}
\ No newline at end of file
From bec14e4e575a538e85f919589187acd063016fee Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 1 Oct 2025 14:22:27 +0200
Subject: [PATCH 23/55] Delete intro.md
---
intro.md | 3 ---
1 file changed, 3 deletions(-)
delete mode 100644 intro.md
diff --git a/intro.md b/intro.md
deleted file mode 100644
index 1f8feeb5..00000000
--- a/intro.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# NGFF
-
-This page contains next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. All specifications are submitted to the https://image.sc community for review. It also provides example metadata files as well as json schema files to ease practical implementation and provide validation targets for datasets in the field.
\ No newline at end of file
From ce2d7ce3e7fb6829c6734be41a1b82c368e7bff9 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 1 Oct 2025 14:22:51 +0200
Subject: [PATCH 24/55] Moved citation info to separate section
---
citing.md | 13 +++++++++++++
specification.md | 8 --------
2 files changed, 13 insertions(+), 8 deletions(-)
create mode 100644 citing.md
diff --git a/citing.md b/citing.md
new file mode 100644
index 00000000..3e4777d0
--- /dev/null
+++ b/citing.md
@@ -0,0 +1,13 @@
+Citing
+======
+(citing)=
+
+[Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.](https://ngff.openmicroscopy.org/0.4)
+J. Moore, *et al*. Open Microscopy Environment Consortium, 8 February 2022.
+
+This edition of the specification is [https://ngff.openmicroscopy.org/{{version}}](https://ngff.openmicroscopy.org/{{version}}]).
+The latest edition is publically available {cite}`ngff_spec_latest`.
+
+```{bibliography}
+:style: unsrt
+```
\ No newline at end of file
diff --git a/specification.md b/specification.md
index dde0cbca..d1c61367 100644
--- a/specification.md
+++ b/specification.md
@@ -1631,14 +1631,6 @@ Implementations {#implementations}
See [Tools](https://ngff.openmicroscopy.org/tools/index.html).
-Citing {#citing}
-================
-
-[Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.](https://ngff.openmicroscopy.org/0.4)
-J. Moore, *et al*. Open Microscopy Environment Consortium, 8 February 2022.
-This edition of the specification is [https://ngff.openmicroscopy.org/0.5/](https://ngff.openmicroscopy.org/0.5/]).
-The latest edition is available at [https://ngff.openmicroscopy.org/latest/](https://ngff.openmicroscopy.org/latest/).
-[(doi:10.5281/zenodo.4282107)](https://doi.org/10.5281/zenodo.4282107)
Version History {#history}
==========================
From b47a7053f5043cdcb383cf91184cb03f4ddbdf5a Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 1 Oct 2025 14:23:16 +0200
Subject: [PATCH 25/55] updated author and editor orchid details
---
_config.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/_config.yml b/_config.yml
index f432f91d..fffd4bd8 100644
--- a/_config.yml
+++ b/_config.yml
@@ -3,7 +3,7 @@
# Comprehensive example: https://github.com/executablebooks/jupyter-book/blob/master/docs/_config.yml
title: Next-generation file format specification
-author: Josh Moore
+author: NGFF-community
logo: https://www.openmicroscopy.org/img/logos/ome-logomark.svg
# Force re-execution of notebooks on each build.
@@ -76,4 +76,4 @@ sphinx:
logo: "http://www.openmicroscopy.org/img/logos/ome-logomark.svg"
editor_name: "[Josh Moore](https://gerbi-gmb.de/)"
editor_affiliation: "German BioImaging e.V."
- editor_orcid: "[https://orcid.org/0000-0003-4028-811X](https://orcid.org/0000-0003-4028-811X)"
\ No newline at end of file
+ editor_orcid: "[https://orcid.org/0000-0003-4028-811X](https://orcid.org/0000-0003-4028-811X)"
From 099e34bfca862728d040ca9c4012e1efccdf9ad0 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 1 Oct 2025 14:23:35 +0200
Subject: [PATCH 26/55] added version substitution
---
_config.yml | 1 +
specification.md | 1 +
2 files changed, 2 insertions(+)
diff --git a/_config.yml b/_config.yml
index fffd4bd8..74c0252e 100644
--- a/_config.yml
+++ b/_config.yml
@@ -77,3 +77,4 @@ sphinx:
editor_name: "[Josh Moore](https://gerbi-gmb.de/)"
editor_affiliation: "German BioImaging e.V."
editor_orcid: "[https://orcid.org/0000-0003-4028-811X](https://orcid.org/0000-0003-4028-811X)"
+ version: "0.6.dev1"
\ No newline at end of file
diff --git a/specification.md b/specification.md
index d1c61367..cb12d786 100644
--- a/specification.md
+++ b/specification.md
@@ -1,5 +1,6 @@
# {{ title }}
+**Version**: {{version}}
**Shortname:** {{ shortname }}
**Level:** {{ level }}
**Status:** {{ status }}
From 6ee7518bf01dab99897391046b71332d9cc4322d Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 1 Oct 2025 14:23:51 +0200
Subject: [PATCH 27/55] Use myST references throughout document
---
specification.md | 51 +++++++++++++++++++++++++-----------------------
1 file changed, 27 insertions(+), 24 deletions(-)
diff --git a/specification.md b/specification.md
index cb12d786..f42c66c3 100644
--- a/specification.md
+++ b/specification.md
@@ -61,7 +61,7 @@ Images
The following layout describes the expected Zarr hierarchy for images with
multiple levels of resolutions and optionally associated labels.
-Note that the number of dimensions is variable between 2 and 5 and that axis names are arbitrary, see [multiscales metadata](multiscale-md) for details.
+Note that the number of dimensions is variable between 2 and 5 and that axis names are arbitrary, see [multiscales metadata](multiscales-md) for details.
```
├── 123.zarr # One OME-Zarr image (id=123).
@@ -145,8 +145,9 @@ A well group SHOULD NOT be present if there are no images in the well.
└── ... # Other rows
-OME-Zarr Metadata {#metadata}
-=============================
+OME-Zarr Metadata
+=================
+(metadata)=
The "OME-Zarr Metadata" contains metadata keys as specified below
for discovering certain types of data, especially images.
@@ -172,8 +173,7 @@ The OME-Zarr Metadata version MUST be consistent within a hierarchy.
"axes" metadata
--------------------------
-
-{#axes-md}
+(axes-md)=
"axes" describes the dimensions of a coordinate systems and adds an interpretation to the data along that dimension. A named collection
of axes forms a [coordinate system](coord-sys-md).
@@ -241,8 +241,7 @@ to the discrete axis `"c"`. Indexing an image at the point `(1, 0.2, 0.3, 0.4)`
"coordinateSystems" metadata
--------------------------
-
-{#coord-sys-md}
+(coord-sys-md)=
A "coordinate system" is a collection of "axes" / dimensions with a name. Every coordinate system:
- MUST contain the field "name". The value MUST be a non-empty string that is unique among `coordinateSystem`s.
@@ -483,8 +482,7 @@ Conforming readers:
"coordinateTransformations" metadata
------------------------------------------------
-
-{#trafo-md}
+(trafo-md)=
"coordinateTransformations" describe the mapping between two coordinate systems (defined by "axes").
For example, to map an array's discrete coordinate system to its corresponding physical coordinates.
@@ -553,7 +551,7 @@ Conforming readers:
- SHOULD be able to apply transformations to points;
- SHOULD be able to apply transformations to images;
-Coordinate transformations from array to physical coordinates MUST be stored in [multiscales](multiscale-md).
+Coordinate transformations from array to physical coordinates MUST be stored in [multiscales](multiscales-md).
Transformations between different images MUST be stored in the attributes of a parent zarr group. For transformations that store
data or parameters in a zarr array, those zarr arrays SHOULD be stored in a zarr group `"coordinateTransformations"`.
@@ -675,14 +673,15 @@ transformation type, for example:
```
Implementations SHOULD be able to compute and apply the inverse of some coordinate transformations when they
-are computable in closed-form (as the [Transformation types](#transformation-types) section below indicates). If an
+are computable in closed-form (as the [Transformation types](transformation-types) section below indicates). If an
operation is requested that requires the inverse of a transformation that can not be inverted in closed-form,
implementations MAY estimate an inverse, or MAY output a warning that the requested operation is unsupported.
#### Matrix transformations
+(matrix-transformations)=
-Two transformation types ([affine](#affine) and [rotation](#rotation)) are parametrized by matrices. Matrices are applied to
+Two transformation types ([affine](affine) and [rotation](rotation)) are parametrized by matrices. Matrices are applied to
column vectors that represent points in the input coordinate system. The first (last) axis in a coordinate system is the top
(bottom) entry in the column vector. Matrices are stored as two-dimensional arrays, either as json or in a zarr array. When
stored as a 2D zarr array, the first dimension indexes rows and the second dimension indexes columns (e.g., an array of
@@ -718,6 +717,7 @@ results in the point [2,-1,3] because it is computed with the matrix-vector mult
### Transformation types
+(transformation-types)=
Input and output dimensionality may be determined by the value of the "input" and "output" fields, respectively. If the value
of "input" is an array, it's length gives the input dimension, otherwise the length of "axes" for the coordinate
@@ -864,8 +864,9 @@ y = 2 * j
#### affine
+(affine)=
-`affine`s are [matrix transformations](#matrix-transformations) from N-dimensional inputs to M-dimensional outputs are
+`affine`s are [matrix transformations](matrix-transformations) from N-dimensional inputs to M-dimensional outputs are
represented as the upper `(M)x(N+1)` sub-matrix of a `(M+1)x(N+1)` matrix in [homogeneous
coordinates](https://en.wikipedia.org/wiki/Homogeneous_coordinates) (see examples). This transformation type may be (but is not
necessarily) invertible when `N` equals `M`. The matrix MUST be stored as a 2D array either as json or as a zarr array.
@@ -939,8 +940,9 @@ necessarily) invertible when `N` equals `M`. The matrix MUST be stored as a 2D a
#### rotation
+(rotation)=
-`rotation`s are [matrix transformations](#matrix-transformations) that are special cases of affine transformations. When possible, a rotation
+`rotation`s are [matrix transformations](matrix-transformations) that are special cases of affine transformations. When possible, a rotation
transformation SHOULD be preferred to its equivalent affine. Input and output dimensionality (N) MUST be identical. Rotations
are stored as `NxN` matrices, see below, and MUST have determinant equal to one, with orthonormal rows and columns. The matrix
MUST be stored as a 2D array either as json or in a zarr array. `rotation` transformations are invertible.
@@ -1343,7 +1345,7 @@ highlight: json
"multiscales" metadata
----------------------
-(multiscale-md)=
+(multiscales-md)=
Metadata about an image can be found under the "multiscales" key in the group-level OME-Zarr Metadata.
Here, image refers to 2 to 5 dimensional data representing image or volumetric data with optional time or channel axes.
@@ -1584,8 +1586,7 @@ highlight: json
"well" metadata
---------------
-
-{#well-md}
+(well-md)=
For high-content screening datasets, the metadata about all fields of views
under a given well can be found under the "well" key in the attributes of the
@@ -1620,21 +1621,23 @@ path: examples/well_strict/well_2fields.json
highlight: json
-Specification naming style {#naming-style}
-==========================================
+Specification naming style
+==========================
+(naming-style)=
Multi-word keys in this specification should use the `camelCase` style.
NB: some parts of the specification don't obey this convention as they
were added before this was adopted, but they should be updated in due course.
-Implementations {#implementations}
-==================================
+Implementations
+===============
+(implementations)=
See [Tools](https://ngff.openmicroscopy.org/tools/index.html).
-
-Version History {#history}
-==========================
+Version History
+===============
+(history)=
From 7455e8fd85fe2d34b9fcd5b52b2b1d49adfdf053 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 1 Oct 2025 15:55:51 +0200
Subject: [PATCH 28/55] move version history in separate page
---
_toc.yml | 4 ++-
version_history.md | 83 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+), 1 deletion(-)
create mode 100644 version_history.md
diff --git a/_toc.yml b/_toc.yml
index 1cdd0bf9..5cd8b29c 100644
--- a/_toc.yml
+++ b/_toc.yml
@@ -11,4 +11,6 @@ chapters:
exclude: docs/examples/examples.md
- file: docs/schemas
sections:
- - glob: docs/schemas/*
\ No newline at end of file
+ - glob: docs/schemas/*
+- file: citing
+- file: version_history
\ No newline at end of file
diff --git a/version_history.md b/version_history.md
new file mode 100644
index 00000000..a3214f19
--- /dev/null
+++ b/version_history.md
@@ -0,0 +1,83 @@
+Version History
+===============
+(history)=
+
+
+
+
+
Revision
+
Date
+
Description
+
+
+
+
0.5.2
+
2025-01-10
+
Clarify that the dimension_names field in axes MUST be included.
transitional metadata for image collections ("bioformats2raw.layout")
+
+
+
0.4.0
+
2022-02-08
+
multiscales: add axes type, units and coordinateTransformations
+
+
+
0.4.0
+
2022-02-08
+
plate: add rowIndex/columnIndex
+
+
+
0.3.0
+
2021-08-24
+
Add axes field to multiscale metadata
+
+
+
0.2.0
+
2021-03-29
+
Change chunk dimension separator to "/"
+
+
+
0.1.4
+
2020-11-26
+
Add HCS specification
+
+
+
0.1.3
+
2020-09-14
+
Add labels specification
+
+
+
0.1.2
+
2020-05-07
+
Add description of "omero" metadata
+
+
+
0.1.1
+
2020-05-06
+
Add info on the ordering of resolutions
+
+
+
0.1.0
+
2020-04-20
+
First version for internal demo
+
+
\ No newline at end of file
From 37cb58ff8fe15e51f644fb4462364ea80b020221 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 1 Oct 2025 15:56:07 +0200
Subject: [PATCH 29/55] Update schemas.md
---
docs/schemas.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/docs/schemas.md b/docs/schemas.md
index 46bd9a73..cb4301ab 100644
--- a/docs/schemas.md
+++ b/docs/schemas.md
@@ -1,3 +1,4 @@
-# JSON schemas
-Here is some information on the json schemas
\ No newline at end of file
+# JSON Schemas
+
+Below you find schemas for the NGFF specification in both Markdown and HTML format.
\ No newline at end of file
From 4043ae23681df0ae273764718ed8d73fc78c0360 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 1 Oct 2025 15:56:22 +0200
Subject: [PATCH 30/55] removed unnecessary exclude in toc
---
_toc.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/_toc.yml b/_toc.yml
index 5cd8b29c..5eecfc0c 100644
--- a/_toc.yml
+++ b/_toc.yml
@@ -8,9 +8,9 @@ chapters:
- file: docs/examples
sections:
- glob: docs/examples/*
- exclude: docs/examples/examples.md
- file: docs/schemas
sections:
- glob: docs/schemas/*
+
- file: citing
- file: version_history
\ No newline at end of file
From 68cf5d2469d2eb07d533d4274ae77114368a51ff Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 2 Oct 2025 10:06:18 +0200
Subject: [PATCH 31/55] use consistent header formatting in document
---
specification.md | 76 ++++++++++++++++++++++--------------------------
1 file changed, 34 insertions(+), 42 deletions(-)
diff --git a/specification.md b/specification.md
index f42c66c3..7e96d971 100644
--- a/specification.md
+++ b/specification.md
@@ -23,8 +23,7 @@ enable next-generation file formats to represent the same bioimaging data
that can be represented in \[OME-TIFF](http://www.openmicroscopy.org/ome-files/)
and beyond.
-Document conventions
---------------------
+## Document conventions
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”,
“RECOMMENDED”, “MAY”, and “OPTIONAL” are to be interpreted as described in
@@ -41,8 +40,7 @@ implementations that are later submitted as a formal specification. (See [biofor
Some of the JSON examples in this document include comments. However, these are only for
clarity purposes and comments MUST NOT be included in JSON objects.
-Storage format
-==============
+# Storage format
OME-Zarr is implemented using the Zarr format as defined by the
[version 3 of the Zarr specification](https://zarr-specs.readthedocs.io/en/latest/v3/core/v3.0.html).
@@ -56,8 +54,7 @@ is represented here as it would appear locally but could equally
be stored on a web server to be accessed via HTTP or in object storage
like S3 or GCS.
-Images
-------
+## Images
The following layout describes the expected Zarr hierarchy for images with
multiple levels of resolutions and optionally associated labels.
@@ -105,8 +102,7 @@ Note that the number of dimensions is variable between 2 and 5 and that axis nam
-High-content screening
-----------------------
+## High-content screening
The following specification defines the hierarchy for a high-content screening
dataset. Three groups MUST be defined above the images:
@@ -145,8 +141,7 @@ A well group SHOULD NOT be present if there are no images in the well.
└── ... # Other rows
-OME-Zarr Metadata
-=================
+# OME-Zarr Metadata
(metadata)=
The "OME-Zarr Metadata" contains metadata keys as specified below
@@ -171,8 +166,7 @@ The OME-Zarr Metadata version MUST be consistent within a hierarchy.
}
```
-"axes" metadata
---------------------------
+## "axes" metadata
(axes-md)=
"axes" describes the dimensions of a coordinate systems and adds an interpretation to the data along that dimension. A named collection
@@ -239,8 +233,7 @@ to the discrete axis `"c"`. Indexing an image at the point `(1, 0.2, 0.3, 0.4)`
-"coordinateSystems" metadata
---------------------------
+## "coordinateSystems" metadata
(coord-sys-md)=
A "coordinate system" is a collection of "axes" / dimensions with a name. Every coordinate system:
@@ -480,8 +473,7 @@ Conforming readers:
- MAY ignore other groups or arrays under the root of the hierarchy.
-"coordinateTransformations" metadata
-------------------------------------------------
+## "coordinateTransformations" metadata
(trafo-md)=
"coordinateTransformations" describe the mapping between two coordinate systems (defined by "axes").
@@ -726,7 +718,8 @@ length gives the input dimension, otherwise it is given by the length of "axes"
the name of the "input". If the value of "output" is an array, its length gives the output dimension,
otherwise it is given by the length of "axes" for the coordinate system with the name of the "output".
-#### identity
+#### identity
+(identity)=
`identity` transformations map input coordinates to output coordinates without modification. The position of
the ith axis of the output coordinate system is set to the position of the ith axis of the input coordinate
@@ -749,7 +742,8 @@ y = j
-#### mapAxis
+#### mapAxis
+(mapAxis)=
`mapAxis` transformations describe axis permutations as a mapping of axis names. Transformations MUST include a `mapAxis` field
whose value is an object, all of whose values are strings. If the object contains `"x":"i"`, then the transform sets the value
@@ -803,7 +797,8 @@ z = b
```
-#### translation
+#### translation
+(translation)=
`translation` transformations are special cases of affine transformations. When possible, a
translation transformation should be preferred to its equivalent affine. Input and output dimensionality MUST be
@@ -834,6 +829,7 @@ y = j - 1.42
#### scale
+(scale)=
`scale` transformations are special cases of affine transformations. When possible, a scale transformation
SHOULD be preferred to its equivalent affine. Input and output dimensionality MUST be identical and MUST equal
@@ -863,7 +859,7 @@ y = 2 * j
```
-#### affine
+#### affine
(affine)=
`affine`s are [matrix transformations](matrix-transformations) from N-dimensional inputs to M-dimensional outputs are
@@ -939,7 +935,7 @@ necessarily) invertible when `N` equals `M`. The matrix MUST be stored as a 2D a
-#### rotation
+#### rotation
(rotation)=
`rotation`s are [matrix transformations](matrix-transformations) that are special cases of affine transformations. When possible, a rotation
@@ -972,7 +968,8 @@ MUST be stored as a 2D array either as json or in a zarr array. `rotation` trans
-#### inverseOf
+#### inverseOf
+(inverseOf)=
An `inverseOf` transformation contains another transformation (often non-linear), and indicates that
transforming points from output to input coordinate systems is possible using the contained transformation.
@@ -997,7 +994,8 @@ transformation (if it exists).
-#### sequence
+#### sequence
+(sequence)=
A `sequence` transformation consists of an ordered array of coordinate transformations, and is invertible if every coordinate
transform in the array is invertible (though could be invertible in other cases as well). To apply a sequence transformation
@@ -1058,7 +1056,8 @@ and is invertible.
-#### coordinates and displacements
+#### coordinates and displacements
+(coordinates-displacements)=
`coordinates` and `displacements` transformations store coordinates or displacements in an array and interpret them as a vector
field that defines a transformation. The arrays must have a dimension corresponding to every axis of the input coordinate
@@ -1247,7 +1246,8 @@ The transformation specifies linear interpolation, which in this case yields
input point, hence the output is `1.0 + (-0.5) = 0.5`.
-#### byDimension
+#### byDimension
+(byDimension)=
`byDimension` transformations build a high dimensional transformation using lower dimensional transformations
on subsets of dimensions.
@@ -1311,7 +1311,8 @@ This transformation is invalid because the output axis `x` appears in more than
-#### bijection
+#### bijection
+(bijection)=
A bijection transformation is an invertible transformation in which both the `forward` and `inverse` transformations
are explicitly defined. Each direction SHOULD be a transformation type that is not closed-form invertible.
@@ -1343,8 +1344,7 @@ highlight: json
-"multiscales" metadata
-----------------------
+## "multiscales" metadata
(multiscales-md)=
Metadata about an image can be found under the "multiscales" key in the group-level OME-Zarr Metadata.
@@ -1400,8 +1400,7 @@ if not datasets:
datasets = [x["path"] for x in multiscales[0]["datasets"]]
```
-"omero" metadata (transitional)
--------------------------------
+## "omero" metadata (transitional)
(omero-md)=
[=Transitional=] information specific to the channels of an image and how to render it
@@ -1442,8 +1441,7 @@ Each dictionary in "channels" MUST contain the field "window", which is a dictio
The field "window" MUST contain the fields "min" and "max", which are the minimum and maximum values of the window, respectively.
It MUST also contain the fields "start" and "end", which are the start and end values of the window, respectively.
-"labels" metadata
------------------
+## "labels" metadata
(labels-md)=
In OME-Zarr, Zarr arrays representing pixel-annotation data are stored in a group called "labels". Some applications--notably image segmentation--produce
@@ -1511,8 +1509,7 @@ highlight: json
In this case, the pixels consisting of a 0 in the Zarr array will be displayed as 50% blue and 50% opacity. Pixels with a 1 in the Zarr array,
which correspond to cellular space, will be displayed as 50% green and 50% opacity.
-"plate" metadata
-----------------
+## "plate" metadata
(plate-md)=
For high-content screening datasets, the plate layout can be found under the
@@ -1584,8 +1581,7 @@ path: examples/plate_strict/plate_2wells.json
highlight: json
-"well" metadata
----------------
+## "well" metadata
(well-md)=
For high-content screening datasets, the metadata about all fields of views
@@ -1621,20 +1617,16 @@ path: examples/well_strict/well_2fields.json
highlight: json
-Specification naming style
-==========================
+# Specification naming style
(naming-style)=
Multi-word keys in this specification should use the `camelCase` style.
NB: some parts of the specification don't obey this convention as they
were added before this was adopted, but they should be updated in due course.
-Implementations
-===============
+# Implementations
(implementations)=
-See [Tools](https://ngff.openmicroscopy.org/tools/index.html).
-
Version History
===============
(history)=
From 0d3a60728f884413ea660f3b40d87646372ec4d0 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 2 Oct 2025 10:06:29 +0200
Subject: [PATCH 32/55] move version history to separate page
---
specification.md | 164 +----------------------------------------------
1 file changed, 1 insertion(+), 163 deletions(-)
diff --git a/specification.md b/specification.md
index 7e96d971..d39acef6 100644
--- a/specification.md
+++ b/specification.md
@@ -1627,166 +1627,4 @@ were added before this was adopted, but they should be updated in due course.
# Implementations
(implementations)=
-Version History
-===============
-(history)=
-
-
-
-
-
Revision
-
Date
-
Description
-
-
-
-
0.5.2
-
2025-01-10
-
Clarify that the dimension_names field in axes MUST be included.
+See [Tools](https://ngff.openmicroscopy.org/tools/index.html).
\ No newline at end of file
From 6df99af0a094c3904ba141a1a7ea11933510b1a1 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 2 Oct 2025 10:06:41 +0200
Subject: [PATCH 33/55] increase header depth
---
_config.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/_config.yml b/_config.yml
index 74c0252e..8feb92b1 100644
--- a/_config.yml
+++ b/_config.yml
@@ -42,6 +42,9 @@ html:
document.getElementById('current-year').textContent = new Date().getFullYear();
+parse:
+ myst_heading_anchors: 3
+
myst:
enable_extensions:
- colon_fence
From 9526cfbe508d54df92269ac35b38077f813ec1ea Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 2 Oct 2025 14:58:06 +0200
Subject: [PATCH 34/55] Use MyST admonitions to format examples and hints
---
specification.md | 445 +++++++++++++++++++++++------------------------
1 file changed, 217 insertions(+), 228 deletions(-)
diff --git a/specification.md b/specification.md
index d39acef6..4ef71a08 100644
--- a/specification.md
+++ b/specification.md
@@ -154,7 +154,7 @@ The version of the OME-Zarr Metadata is denoted as a string in the `version` att
The OME-Zarr Metadata version MUST be consistent within a hierarchy.
-```json
+
{
...
"attributes": {
@@ -164,7 +164,7 @@ The OME-Zarr Metadata version MUST be consistent within a hierarchy.
}
}
}
-```
+
## "axes" metadata
(axes-md)=
@@ -184,7 +184,7 @@ The "axes" are used as part of [multiscales metadata](multiscales-md). The lengt
The "dimension_names" attribute MUST be included in the `zarr.json` of the Zarr array of a multiscale level and MUST match the names in the "axes" metadata.
-
+````{admonition} Example
Examples of valid axes:
@@ -199,7 +199,7 @@ Examples of valid axes:
{"name": "freq", "type": "frequency", "unit": "megahertz"}
]
```
-
+````
Arrays are inherently discrete (see Array coordinate systems, below) but are often used to store discrete samples of a
continuous variable. The continuous values "in between" discrete samples can be retrieved using an *interpolation* method. If an
@@ -212,11 +212,11 @@ Note: The most common methods for interpolation are "nearest neighbor", "linear"
to any method that obtains values at real valued coordinates using discrete samples as an "interpolator". As such, label images
may be interpolated using "nearest neighbor" to obtain labels at points along the continuum.
-
+````{admonition} Example
For the coordinate system:
-```json
+```
{
"name" : "index and interpolation",
"axes" : [
@@ -230,7 +230,8 @@ For the coordinate system:
Indexing an image at the point `(0.1, 0.2, 0.3, 0.4)` is not valid, because the value of the first coordinate (`0.1`) refers
to the discrete axis `"c"`. Indexing an image at the point `(1, 0.2, 0.3, 0.4)` is valid.
-
+
+````
## "coordinateSystems" metadata
@@ -240,7 +241,9 @@ A "coordinate system" is a collection of "axes" / dimensions with a name. Every
- MUST contain the field "name". The value MUST be a non-empty string that is unique among `coordinateSystem`s.
- MUST contain the field "axes", whose value is an array of valid "axes".
-
+````{admonition} Example
+
+Example of valid `coordinateSystems` metadata:
```json
{
@@ -252,7 +255,7 @@ A "coordinate system" is a collection of "axes" / dimensions with a name. Every
]
}
```
-
+````
The order of the `"axes"` list matters and defines the index of each array dimension and coordinates for points in that
coordinate system. For the above example, the `"x"` dimension is the last dimension. The "dimensionality" of a coordinate system
@@ -265,7 +268,7 @@ point refer to different physical entities and therefore should not be analyzed
regions of interest, etc., SHOULD ensure that they are in the same coordinate system (same name, with identical axes) or can be
transformed to the same coordinate system before doing analysis. See the example below.
-
+````{admonition} Example
Two instruments simultaneously image the same sample from two different angles, and the 3D data from both instruments are
calibrated to "micrometer" units. Two samples are collected ("sampleA" and "sampleB"). An analysis of sample A requires
@@ -310,7 +313,7 @@ image.
]
```
-
+````
### Array coordinate systems
@@ -323,7 +326,8 @@ choice explicitly will be important for interoperability. This is possible by us
Every array has a default coordinate system whose parameters need not be explicitly defined. Its name is the path to the array
in the container, its axes have `"type":"array"`, are unitless, and have default "name"s. The ith axis has `"name":"dim_i"`
(these are the same default names used by [xarray](https://docs.xarray.dev/en/stable/user-guide/terminology.html)).
-
+
+````{admonition} Example
For example, a 3D array at path `0` defines the coordinate system:
```json
@@ -338,7 +342,8 @@ For example, a 3D array at path `0` defines the coordinate system:
```
though this object should not and need not explicitly appear in metadata.
-
+
+````
The dimensionality of each array coordinate system equals the dimensionality of its corresponding zarr array. The axis with
@@ -347,11 +352,11 @@ attribute in the zarr array attributes, and whose data depends on the byte order
chunks. As described in the [zarr array metadata](https://zarr-specs.readthedocs.io/en/latest/v3/core/v3.0.html#array-metadata),
the last dimension of an array in "C" order are stored contiguously on disk or in-memory when directly loaded.
-
+````{admonition} Example
For example, if `0/zarr.json` contains:
-```json
+```
{
"zarr_format": 3,
"node_type": "array",
@@ -361,23 +366,22 @@ For example, if `0/zarr.json` contains:
```
Then `dim_0` has length 4, `dim_1` has length 3, and `dim_2` has length 5.
-
+````
The name and axes names MAY be customized by including a `arrayCoordinateSystem` field in
the user-defined attributes of the array whose value is a coordinate system object. The length of
`axes` MUST be equal to the dimensionality. The value of `"type"` for each object in the
axes array MUST equal `"array"`.
-
+
+```{literalinclude} examples/coordSystems/arrayCoordSys.json
+```
Note that dimension `i` is contiguous in memory.
-
+````
### Coordinate convention
@@ -392,9 +396,7 @@ system `(0.0, 0.0)` (when the transformation is the identity). The continuous re
half-open interval `[-0.5, 0.5) x [-0.5, 0.5)` (i.e., -0.5 is included, +0.5 is excluded). See chapter 4 and figure 4.1 of the ITK Software Guide [[itk]].
-
-"bioformats2raw.layout" (transitional)
---------------------------------------
+## bioformats2raw.layout
(bf2raw)=
[=Transitional=] "bioformats2raw.layout" metadata identifies a group which implicitly describes a series of images.
@@ -405,11 +407,12 @@ In order to capture that information within an OME-Zarr dataset, `bioformats2raw
The bioformats2raw layout has been added to v0.4 as a transitional specification to specify filesets that already exist
in the wild. An upcoming NGFF specification will replace this layout with explicit metadata.
-
Layout
+### Layout
+(bf2raw-layout)=
Typical Zarr layout produced by running `bioformats2raw` on a fileset that contains more than one image (series > 1):
-
+```
series.ome.zarr # One converted fileset from bioformats2raw
├── zarr.json # Contains "bioformats2raw.layout" metadata
├── OME # Special group for containing OME metadata
@@ -418,33 +421,32 @@ series.ome.zarr # One converted fileset from bioformats2raw
├── 0 # First image in the collection
├── 1 # Second image in the collection
└── ...
-
+```
-
Attributes
+### bf2raw-attributes
+(bf2raw-attributes)=
The OME-Zarr Metadata in the top-level `zarr.json` file must contain the `bioformats2raw.layout` key:
-
+
+```{literalinclude} examples/bf2raw/image.json
+:language: json
+```
If the top-level group represents a plate, the `bioformats2raw.layout` metadata will be present but
the "plate" key MUST also be present, takes precedence and parsing of such datasets should follow (see [plate metadata](plate-md)). It is not
possible to mix collections of images with plates at present.
-
+```{literalinclude} examples/bf2raw/plate.json
+```
The OME-Zarr Metadata in the `zarr.json` file within the OME group may contain the "series" key:
-
+### Details
+(bf2raw-details)=
Conforming groups:
@@ -547,7 +549,7 @@ Coordinate transformations from array to physical coordinates MUST be stored in
Transformations between different images MUST be stored in the attributes of a parent zarr group. For transformations that store
data or parameters in a zarr array, those zarr arrays SHOULD be stored in a zarr group `"coordinateTransformations"`.
-
+```
store.zarr # Root folder of the zarr store
│
├── zarr.json # coordinate transformations describing the relationship between two image coordinate systems
@@ -570,7 +572,7 @@ store.zarr # Root folder of the zarr store
└── image # a zarr array
└── zarr.json # physical coordinate system and transformations here
# the array attributes
-
+```
### Additional details
@@ -586,7 +588,7 @@ Transformations in the `transformations` list of a `byDimensions` transformation
of strings corresponding to axis names of the parent transformation's input and output coordinate systems (see below for
details).
-
+````{admonition} Example
The sequence transformation's input corresponds to an array coordinate system at path "my/array".
@@ -635,7 +637,7 @@ The sequence transformation's input corresponds to an array coordinate system at
]
```
-
+````
Coordinate transformations are functions of *points* in the input space to *points* in the output space. We call this the "forward" direction.
Points are ordered lists of coordinates, where a coordinate is the location/value of that point along its corresponding axis.
@@ -680,12 +682,19 @@ stored as a 2D zarr array, the first dimension indexes rows and the second dimen
`"shape":[3,4]` has 3 rows and 4 columns). When stored as a 2D json array, the inner array contains rows (e.g. `[[1,2,3],
[4,5,6]]` has 2 rows and 3 columns).
-
+````{admonition} Example
For matrix transformations, points in the coordinate system:
-```
-{ "name" : "in", "axes" : [{"name" : "z"}, {"name" : "y"}, {"name":"x"}] },
+```json
+{
+ "name" : "in",
+ "axes" : [
+ {"name" : "z"},
+ {"name" : "y"},
+ {"name":"x"}
+ ]
+},
```
are represented as column vectors:
@@ -705,8 +714,7 @@ results in the point [2,-1,3] because it is computed with the matrix-vector mult
[ 0 0 -1] [3] [-3]
```
-
-
+````
### Transformation types
(transformation-types)=
@@ -725,12 +733,11 @@ otherwise it is given by the length of "axes" for the coordinate system with the
the ith axis of the output coordinate system is set to the position of the ith axis of the input coordinate
system. `identity` transformations are invertible.
-
+```{literalinclude} examples/transformations/identity.json
+:language: json
+```
defines the function:
@@ -739,7 +746,7 @@ x = i
y = j
```
-
+````
#### mapAxis
@@ -752,12 +759,11 @@ system, the `mapAxis` MUST have a corresponding field. For every value of the ob
coordinate system with that name. Note that the order of the keys could be reversed.
-
+```{literalinclude} examples/transformations/mapAxis1.json
+:language: json
+```
The "equivalent to identity" transformation defines the function:
@@ -773,14 +779,13 @@ x = j
y = i
```
-
+```{literalinclude} examples/transformations/mapAxis2.json
+:language: json
+```
The "projection_down" transformation defines the function:
@@ -795,7 +800,7 @@ x = a
y = b
z = b
```
-
+```{literalinclude} examples/transformations/scale.json
+:language: json
+```
defines the function:
@@ -857,8 +860,7 @@ defines the function:
x = 3.12 * i
y = 2 * j
```
-
-
+````
#### affine
(affine)=
@@ -875,64 +877,62 @@ necessarily) invertible when `N` equals `M`. The matrix MUST be stored as a 2D a
The affine parameters stored in JSON. The matrix MUST be stored as 2D nested array where the outer array MUST be length
`M` and the inner arrays MUST be length `N+1`.
-
- A 2D-2D example:
+````{admonition} Example
+A 2D-2D example:
-
+```{literalinclude} examples/transformations/affine2d2d.json
+:language: json
+```
- defines the function:
+defines the function:
- ```
- x = 1*i + 2*j + 3
- y = 4*i + 5*j + 6
- ```
+```
+x = 1*i + 2*j + 3
+y = 4*i + 5*j + 6
+```
- it is equivalent to this matrix-vector multiplication in homogeneous coordinates:
+it is equivalent to this matrix-vector multiplication in homogeneous coordinates:
- ```
- [ 1 2 3 ][ i ] [ x ]
- [ 4 5 6 ][ j ] = [ y ]
- [ 0 0 1 ][ 1 ] [ 1 ]
- ```
+```
+[ 1 2 3 ][ i ] [ x ]
+[ 4 5 6 ][ j ] = [ y ]
+[ 0 0 1 ][ 1 ] [ 1 ]
+```
- where the last row `[0 0 1]` is omitted in the JSON representation.
+where the last row `[0 0 1]` is omitted in the JSON representation.
-
+````
-
- An example with two dimensional inputs and three dimensional outputs.
+````{admonition} Example
+An example with two dimensional inputs and three dimensional outputs.
- Note that the order of the axes can in general be determined by the application or user.
- These axes relate to the memory or on-disk order insofar as the last dimension is contiguous
- when the zarr array is c-order (the default for zarr version 2, and the only option for zarr version 3).
+Note that the order of the axes can in general be determined by the application or user.
+These axes relate to the memory or on-disk order insofar as the last dimension is contiguous
+when the zarr array is c-order (the default for zarr version 2, and the only option for zarr version 3).
-
+```{literalinclude} examples/transformations/affine2d3d.json
+:language: json
+```
- defines the function:
+defines the function:
- ```
- x = 1*i + 2*j + 3
- y = 4*i + 5*j + 6
- z = 7*i + 8*j + 9
- ```
+```
+x = 1*i + 2*j + 3
+y = 4*i + 5*j + 6
+z = 7*i + 8*j + 9
+```
- it is equivalent to this matrix-vector multiplication in homogeneous coordinates:
+it is equivalent to this matrix-vector multiplication in homogeneous coordinates:
- ```
- [ 1 2 3 ][ i ] [ x ]
- [ 4 5 6 ][ j ] = [ y ]
- [ 7 8 9 ][ 1 ] [ z ]
- [ 0 0 1 ] [ 1 ]
- ```
+```
+[ 1 2 3 ][ i ] [ x ]
+[ 4 5 6 ][ j ] = [ y ]
+[ 7 8 9 ][ 1 ] [ z ]
+[ 0 0 1 ] [ 1 ]
+```
- where the last row `[0 0 1]` is omitted in the JSON representation.
-
+where the last row `[0 0 1]` is omitted in the JSON representation.
+````
#### rotation
@@ -951,21 +951,20 @@ MUST be stored as a 2D array either as json or in a zarr array. `rotation` trans
The parameters stored in JSON. The matrix MUST be stored as a 2D nested array where the outer array MUST be length `N`
and the inner arrays MUST be length `N`.
-
- A 2D example
+````{admonition} Example
+A 2D example
-
+```{literalinclude} examples/transformations/rotation.json
+:language: json
+```
- defines the function:
+defines the function:
- ```
- x = 0*i - 1*j
- y = 1*i + 0*j
- ```
-
+```
+x = 0*i - 1*j
+y = 1*i + 0*j
+ ```
+````
#### inverseOf
@@ -976,23 +975,21 @@ transforming points from output to input coordinate systems is possible using th
Transforming points from the input to the output coordinate systems requires the inverse of the contained
transformation (if it exists).
-
- Software libraries that perform image registration often return the transformation from fixed image
- coordinates to moving image coordinates, because this "inverse" transformation is most often required
- when rendering the transformed moving image. Results such as this may be enclosed in an `inverseOf`
- transformation. This enables the "outer" coordinate transformation to specify the moving image coordinates
- as `input` and fixed image coordinates as `output`, a choice that many users and developers find intuitive.
-
-
+```{note}
+Software libraries that perform image registration often return the transformation from fixed image
+coordinates to moving image coordinates, because this "inverse" transformation is most often required
+when rendering the transformed moving image. Results such as this may be enclosed in an `inverseOf`
+transformation. This enables the "outer" coordinate transformation to specify the moving image coordinates
+as `input` and fixed image coordinates as `output`, a choice that many users and developers find intuitive.
+```
-
+```{literalinclude} examples/transformations/inverseOf.json
+:language: json
+```
+````
#### sequence
(sequence)=
@@ -1003,7 +1000,7 @@ to a point in the input coordinate system, apply the first transformation in the
transformation to the result. Repeat until every transformation has been applied. The output of the last transformation is the
result of the sequence.
-
+````{note}
Considering transformations as functions of points, if the list contains transformations `[f0, f1, f2]` in that order, applying
this sequence to point `x` is equivalent to:
@@ -1014,7 +1011,7 @@ f2(f1(f0(x)))
`f0` is applied first, `f1` is applied second, and `f2` is applied last.
-
+````
The transformations included in the `transformations` array may omit their `input` and `output` fields under the conditions
outlined below:
@@ -1036,14 +1033,13 @@ outlined below:
+```{literalinclude} examples/transformations/sequence.json
+:language: json
+```
describes the function
@@ -1053,7 +1049,7 @@ y = (j + 0.9) * 3
```
and is invertible.
-
+````
#### coordinates and displacements
@@ -1078,7 +1074,7 @@ metadata for the array ("field coordinate system").
The `i`th value of the array along the `coordinate` or `displacement` axis refers to the coordinate or displacement
of the `i`th output axis. See the example below.
-
+````{admonition} Example
In this example, the array located at `"displacementField"` MUST have three dimensions. One dimension MUST
correspond to an axis with `type : displacement` (in this example, the last dimension), the other two dimensions MUST be axes
@@ -1119,8 +1115,7 @@ x_displacement = displacementField[y][x][1]
I.e. the y-displacement is first, because the y-axis is the first element of the input and output coordinate systems.
-
-
+````
`coordinates` and `displacements` transformations are not invertible in general, but implementations MAY approximate their
inverses. Metadata for these coordinate transforms have the following field:
@@ -1262,53 +1257,47 @@ on subsets of dimensions.
-
+````{admonition} Example
A valid `byDimension` transformation:
-
+```{literalinclude} examples/transformations/byDimensionInvalid1.json
+:language: json
+```
It is invalid for two reasons. First because input `0` used by the scale transformation is not an axis of the `byDimension` transformation's `input`. Second, the `x` axis of the `output` does not appear in the `output` of any child transformation.
-
+````
-
+````{admonition} Example
Another **invalid** `byDimension` transform:
-
+```{literalinclude} examples/transformations/byDimensionInvalid2.json
+:language: json
+```
This transformation is invalid because the output axis `x` appears in more than one transformation in the `transformations` list.
-
+````
#### bijection
@@ -1327,21 +1316,19 @@ Practically, non-invertible transformations have finite extents, so bijection tr
to be correct / consistent for points that fall within those extents. It may not be correct for any point of
appropriate dimensionality.
-
+```{literalinclude} examples/transformations/bijection.json
+:language: json
+```
the input and output of the `forward` and `inverse` transformations are understood to be:
-
+````
## "multiscales" metadata
@@ -1380,11 +1367,11 @@ Each "multiscales" dictionary SHOULD contain the field "name".
Each "multiscales" dictionary SHOULD contain the field "type", which gives the type of downscaling method used to generate the multiscale image pyramid.
It SHOULD contain the field "metadata", which contains a dictionary with additional information about the downscaling method.
-
-
+````{admonition} Example
+```{literalinclude} examples/multiscales_strict/multiscales_example.json
+:language: json
+```
+````
If only one multiscale is provided, use it. Otherwise, the user can choose by
name, using the first multiscale as a fallback:
@@ -1456,11 +1443,12 @@ The "labels" group is not itself an image; it contains images. The pixels of the
but these MUST NOT contain metadata. Names of the images in the "labels" group are arbitrary.
The OME-Zarr Metadata in the `zarr.json` file associated with the "labels" group MUST contain a JSON object with the key `labels`, whose value is a JSON array of paths to the
-labeled multiscale image(s). All label images SHOULD be listed within this metadata file. For example:
+labeled multiscale image(s). All label images SHOULD be listed within this metadata file.
+````{admonition} Example
+For example:
```json
{
- ...
"attributes": {
"ome": {
"version": "0.5",
@@ -1471,6 +1459,7 @@ labeled multiscale image(s). All label images SHOULD be listed within this metad
}
}
```
+````
The `zarr.json` file for the label image MUST implement the multiscales specification. Within the `multiscales` object, the JSON array
associated with the `datasets` key MUST have the same number of entries (scale levels) as the original unlabeled image.
@@ -1499,15 +1488,15 @@ The value of the `source` key MUST be a JSON object containing information about
This object MAY include a key `image`, whose value MUST be a string specifying the relative path to a Zarr image group.
The default value is `../../` since most labeled images are stored in a "labels" group that is nested within the original image group.
-Here is an example of a simple `image-label` object for a label image in which 0s and 1s represent intercellular and cellular space, respectively:
-
+````{admonition} Example
+Here is an example of a simple `image-label` object for a label image in which 0s and 1s represent intercellular and cellular space, respectively:
+```{literalinclude} examples/label_strict/colors_properties.json
+:language: json
+```
+In this case, the pixels consisting of a 0 in the Zarr array will be displayed as 50% blue and 50% opacity. Pixels with a 1 in the Zarr array, which correspond to cellular space, will be displayed as 50% green and 50% opacity.
+````
-In this case, the pixels consisting of a 0 in the Zarr array will be displayed as 50% blue and 50% opacity. Pixels with a 1 in the Zarr array,
-which correspond to cellular space, will be displayed as 50% green and 50% opacity.
## "plate" metadata
(plate-md)=
@@ -1565,21 +1554,21 @@ the index into the `rows` list and a `columnIndex` key whose value MUST be an in
the index into the `columns` list. `rowIndex` and `columnIndex` MUST be 0-based. The
`rowIndex`, `columnIndex`, and `path` MUST all refer to the same row/column pair.
+````{admonition} Example
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.
-
+```{literalinclude} examples/plate_strict/plate_6wells.json
+:language: 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.
-
+```{literalinclude} examples/plate_strict/plate_2wells.json
+:language: json
+```
+````
## "well" metadata
(well-md)=
@@ -1599,23 +1588,23 @@ which MUST match one of the acquisition JSON objects defined in the [plate metad
The `well` dictionary SHOULD contain a `version` key whose value MUST be a string specifying the
version of the well specification.
+````{admonition} Example
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.
-
+```{literalinclude} examples/well_strict/well_4fields.json
+:language: 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.
-
+```{literalinclude} examples/well_strict/well_2fields.json
+:language: json
+```
+````
# Specification naming style
(naming-style)=
From 993ccc557f5f91a8f3485970a30f4d1e9b3e4b40 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 2 Oct 2025 14:58:19 +0200
Subject: [PATCH 35/55] Explain styling in contribution guide
---
contribute.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 83 insertions(+)
create mode 100644 contribute.md
diff --git a/contribute.md b/contribute.md
new file mode 100644
index 00000000..fec8c1c6
--- /dev/null
+++ b/contribute.md
@@ -0,0 +1,83 @@
+# Contribution guide
+
+Contributions to the spec text, examples and schemas are highly welcome and
+appreciated by the ngff community. If you propose an RFC (i.e., major change)
+or a aminor change (pull request), please make sure to follow [these guidelines](https://ngff.openmicroscopy.org/contributing/index.html).
+
+Major changes should follow the RFC process as it was laid out in [RFC1 ](https://ngff.openmicroscopy.org/rfc/1/index.html).
+
+## Building the documentation
+
+Build and inspect changes to the documentation before submitting a PR. To do so, you first need
+to install the necessary dependecies:
+
+```bash
+pip install -r requirements.txt
+```
+
+This document uses [jupyter-book](https://jupyterbook.org) to generate the pages and [MyST](https://mystmd.org)
+markdown for formatting. After installing these via the dependencies, navigate into the repository on your machine
+and build the book using the following command:
+
+```bash
+python docs/pre_build.py
+jupyter-book build . --path-output docs
+```
+
+You'll find the built webpages under `docs/_build/html`.
+
+### Formating hints
+
+The specification uses MyST extensively for a number of formatting options to make the text
+readible and improve structure.
+
+#### Referencing
+
+MyST allows a number of ways to reference and cross-reference inside this text and across
+several of the pages in this repo. For an overview of supported referencing syntax, see the
+[MyST doc pages](https://mystmd.org/guide/cross-references). It is recommended to use the
+following syntax in this document for consitency:
+```
+anchor: (your-reference-name)=
+reference: [This is a reference](your-reference-name)
+```
+
+#### Admonitions
+
+We suggest using [admonitions](https://mystmd.org/guide/admonitions) for example code and
+other highlighting. For examples, please use the following syntax to highlight your examples:
+
+`````markdown
+````{admonition} Example
+
+Some informative text about your example
+```json
+"key": "value"
+```
+````
+`````
+
+which results in
+
+````{admonition} Example
+
+Some informative text about your example
+```json
+"key": "value"
+```
+````
+
+If you want to link in example metadata from somewhere in this repo (i.e, a json file),
+use this syntax:
+
+`````markdown
+````{admonition} Example
+
+Some informative text about your example
+```{literalinclude} path/to/example.json
+:language: json
+```
+````
+`````
+
+Other useful admonitions (e.g., `hint`, `note`) can be found [here](https://mystmd.org/guide/directives)
From 928e411945a39e1c98342e5572ec1f8737ad698e Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 2 Oct 2025 14:58:22 +0200
Subject: [PATCH 36/55] Delete header.include
---
docs/_includes/header.include | 31 -------------------------------
1 file changed, 31 deletions(-)
delete mode 100644 docs/_includes/header.include
diff --git a/docs/_includes/header.include b/docs/_includes/header.include
deleted file mode 100644
index 7bd9e500..00000000
--- a/docs/_includes/header.include
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
- [TITLE]
-
-
-
-
-
-
-
-
[TITLE]
-
[LONGSTATUS],
-
-
-
-
-
-
-
-
-
-
Status of this document
-
-
-
-
-
From bb9e5e66611337b2a4ee09202532180da6625a86 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 2 Oct 2025 14:58:40 +0200
Subject: [PATCH 37/55] add contribution section to toc
---
_toc.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/_toc.yml b/_toc.yml
index 5eecfc0c..d4ac723f 100644
--- a/_toc.yml
+++ b/_toc.yml
@@ -12,5 +12,6 @@ chapters:
sections:
- glob: docs/schemas/*
+- file: contribute
- file: citing
- file: version_history
\ No newline at end of file
From 73c94cd3b4f7990ec29bb2ad9c25d0e8fb8f2113 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 2 Oct 2025 15:34:56 +0200
Subject: [PATCH 38/55] Add warning about WIP status
---
specification.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/specification.md b/specification.md
index 4ef71a08..f452602a 100644
--- a/specification.md
+++ b/specification.md
@@ -11,6 +11,11 @@
## Abstract
+```{warning}
+This is **not** the released version of the ngff-specficication. It is an explorative, work-in-progress document.
+
+```
+
This document contains next-generation file format (NGFF) specifications for storing bioimaging data in the cloud. All specifications are submitted to the https://image.sc community for review.
## Status of This Document
From 3b642c37cc71266ba70b3c445b71822186f2fa05 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Thu, 2 Oct 2025 23:09:56 +0200
Subject: [PATCH 39/55] fix typo
---
specification.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/specification.md b/specification.md
index f452602a..80e529e8 100644
--- a/specification.md
+++ b/specification.md
@@ -12,7 +12,7 @@
## Abstract
```{warning}
-This is **not** the released version of the ngff-specficication. It is an explorative, work-in-progress document.
+This is **not** the released version of the ngff-specification. It is an explorative, work-in-progress document.
```
From 625cc2d144d1c5be1f55272ac16731dfd128f461 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Tue, 7 Oct 2025 16:05:04 +0200
Subject: [PATCH 40/55] update `multiscales_strict` example
---
.../multiscales_example.json | 40 +++++++++++++------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/examples/multiscales_strict/multiscales_example.json b/examples/multiscales_strict/multiscales_example.json
index 4b2c718a..d8b53993 100644
--- a/examples/multiscales_strict/multiscales_example.json
+++ b/examples/multiscales_strict/multiscales_example.json
@@ -6,13 +6,18 @@
"version": "0.5",
"multiscales": [
{
- "name": "example",
- "axes": [
- { "name": "t", "type": "time", "unit": "millisecond" },
- { "name": "c", "type": "channel" },
- { "name": "z", "type": "space", "unit": "micrometer" },
- { "name": "y", "type": "space", "unit": "micrometer" },
- { "name": "x", "type": "space", "unit": "micrometer" }
+ "name": "physical",
+ "coordinateSystems": [
+ {
+ "name": "physical",
+ "axes": [
+ { "name": "t", "type": "time", "unit": "millisecond" },
+ { "name": "c", "type": "channel" },
+ { "name": "z", "type": "space", "unit": "micrometer" },
+ { "name": "y", "type": "space", "unit": "micrometer" },
+ { "name": "x", "type": "space", "unit": "micrometer" }
+ ]
+ }
],
"datasets": [
{
@@ -20,8 +25,11 @@
"coordinateTransformations": [
{
// the voxel size for the first scale level (0.5 micrometer)
+ // and the time unit (0.1 milliseconds), which is the same for each scale level
"type": "scale",
- "scale": [1.0, 1.0, 0.5, 0.5, 0.5]
+ "scale": [1.0, 1.0, 0.5, 0.5, 0.5],
+ "input": "0",
+ "output": "example"
}
]
},
@@ -29,9 +37,12 @@
"path": "1",
"coordinateTransformations": [
{
- // the voxel size for the second scale level (downscaled by a factor of 2 -> 1 micrometer)
+ // the voxel size for the first scale level (0.5 micrometer)
+ // and the time unit (0.1 milliseconds), which is the same for each scale level
"type": "scale",
- "scale": [1.0, 1.0, 1.0, 1.0, 1.0]
+ "scale": [1.0, 1.0, 1.0, 1.0, 1.0],
+ "input": "1",
+ "output": "example"
}
]
},
@@ -39,11 +50,14 @@
"path": "2",
"coordinateTransformations": [
{
- // the voxel size for the third scale level (downscaled by a factor of 4 -> 2 micrometer)
+ // the voxel size for the first scale level (0.5 micrometer)
+ // and the time unit (0.1 milliseconds), which is the same for each scale level
"type": "scale",
- "scale": [1.0, 1.0, 2.0, 2.0, 2.0]
+ "scale": [1.0, 1.0, 2.0, 2.0, 2.0],
+ "input": "2",
+ "output": "example"
}
- ]
+ ]
}
],
"coordinateTransformations": [
From bc54631c8b5a0dcc027f39186d60180ad3ff9928 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Tue, 7 Oct 2025 16:58:13 +0200
Subject: [PATCH 41/55] remove duplicate sentence
---
specification.md | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/specification.md b/specification.md
index 80e529e8..82ea06e0 100644
--- a/specification.md
+++ b/specification.md
@@ -724,12 +724,9 @@ results in the point [2,-1,3] because it is computed with the matrix-vector mult
### Transformation types
(transformation-types)=
-Input and output dimensionality may be determined by the value of the "input" and "output" fields, respectively. If the value
-of "input" is an array, it's length gives the input dimension, otherwise the length of "axes" for the coordinate
-system with the name of the "input" value gives the input dimension. If the value of "input" is an array, it's
-length gives the input dimension, otherwise it is given by the length of "axes" for the coordinate system with
-the name of the "input". If the value of "output" is an array, its length gives the output dimension,
-otherwise it is given by the length of "axes" for the coordinate system with the name of the "output".
+Input and output dimensionality may be determined by the value of the "input" and "output" fields, respectively.
+If the value of “input” is an array, it’s length gives the input dimension, otherwise it is given by the length of “axes” for the coordinate system with the name of the “input”.
+If the value of "output" is an array, its length gives the output dimension, otherwise it is given by the length of "axes" for the coordinate system with the name of the "output".
#### identity
(identity)=
From bb9f6561a325ff23813c98980ebfd426491b0e59 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Tue, 7 Oct 2025 23:43:45 +0200
Subject: [PATCH 42/55] removed missleading comments and merged time-scaling
back into multiscales
---
.../multiscales_example.json | 23 +++++++------------
1 file changed, 8 insertions(+), 15 deletions(-)
diff --git a/examples/multiscales_strict/multiscales_example.json b/examples/multiscales_strict/multiscales_example.json
index d8b53993..c8f1282e 100644
--- a/examples/multiscales_strict/multiscales_example.json
+++ b/examples/multiscales_strict/multiscales_example.json
@@ -25,9 +25,9 @@
"coordinateTransformations": [
{
// the voxel size for the first scale level (0.5 micrometer)
- // and the time unit (0.1 milliseconds), which is the same for each scale level
+ // the time unit (0.1 milliseconds), which is the same for each scale level
"type": "scale",
- "scale": [1.0, 1.0, 0.5, 0.5, 0.5],
+ "scale": [0.1, 1.0, 0.5, 0.5, 0.5],
"input": "0",
"output": "example"
}
@@ -37,10 +37,10 @@
"path": "1",
"coordinateTransformations": [
{
- // the voxel size for the first scale level (0.5 micrometer)
- // and the time unit (0.1 milliseconds), which is the same for each scale level
+ // the voxel size for the second scale level (1 micrometer)
+ // the time unit (0.1 milliseconds), which is the same for each scale level
"type": "scale",
- "scale": [1.0, 1.0, 1.0, 1.0, 1.0],
+ "scale": [0.1, 1.0, 1.0, 1.0, 1.0],
"input": "1",
"output": "example"
}
@@ -50,23 +50,16 @@
"path": "2",
"coordinateTransformations": [
{
- // the voxel size for the first scale level (0.5 micrometer)
- // and the time unit (0.1 milliseconds), which is the same for each scale level
+ // the voxel size for the third scale level (2 micrometer)
+ // the time unit (0.1 milliseconds), which is the same for each scale level
"type": "scale",
- "scale": [1.0, 1.0, 2.0, 2.0, 2.0],
+ "scale": [0.1, 1.0, 2.0, 2.0, 2.0],
"input": "2",
"output": "example"
}
]
}
],
- "coordinateTransformations": [
- {
- // the time unit (0.1 milliseconds), which is the same for each scale level
- "type": "scale",
- "scale": [0.1, 1.0, 1.0, 1.0, 1.0]
- }
- ],
"type": "gaussian",
"metadata": {
"description": "the fields in metadata depend on the downscaling implementation. Here, the parameters passed to the skimage function are given",
From 3e04ec40a360fd5411e653385c0281f135d09129 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Tue, 7 Oct 2025 23:44:03 +0200
Subject: [PATCH 43/55] updated version
---
examples/multiscales_strict/multiscales_example.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/multiscales_strict/multiscales_example.json b/examples/multiscales_strict/multiscales_example.json
index c8f1282e..ee3421ad 100644
--- a/examples/multiscales_strict/multiscales_example.json
+++ b/examples/multiscales_strict/multiscales_example.json
@@ -3,7 +3,7 @@
"node_type": "group",
"attributes": {
"ome": {
- "version": "0.5",
+ "version": "0.6dev2",
"multiscales": [
{
"name": "physical",
From c467423d71d71ad7e5189a0c4f56c562bc1beac9 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Tue, 7 Oct 2025 23:57:59 +0200
Subject: [PATCH 44/55] correct output coordinate system
---
examples/multiscales_strict/multiscales_example.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/examples/multiscales_strict/multiscales_example.json b/examples/multiscales_strict/multiscales_example.json
index ee3421ad..55799eb2 100644
--- a/examples/multiscales_strict/multiscales_example.json
+++ b/examples/multiscales_strict/multiscales_example.json
@@ -29,7 +29,7 @@
"type": "scale",
"scale": [0.1, 1.0, 0.5, 0.5, 0.5],
"input": "0",
- "output": "example"
+ "output": "physical"
}
]
},
@@ -42,7 +42,7 @@
"type": "scale",
"scale": [0.1, 1.0, 1.0, 1.0, 1.0],
"input": "1",
- "output": "example"
+ "output": "physical"
}
]
},
@@ -55,7 +55,7 @@
"type": "scale",
"scale": [0.1, 1.0, 2.0, 2.0, 2.0],
"input": "2",
- "output": "example"
+ "output": "physical"
}
]
}
From 6c259c4b52d3de45f3e3d5d819c6ad2da7655564 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 8 Oct 2025 12:20:42 +0200
Subject: [PATCH 45/55] Delete schemas.md
---
docs/schemas.md | 4 ----
1 file changed, 4 deletions(-)
delete mode 100644 docs/schemas.md
diff --git a/docs/schemas.md b/docs/schemas.md
deleted file mode 100644
index cb4301ab..00000000
--- a/docs/schemas.md
+++ /dev/null
@@ -1,4 +0,0 @@
-
-# JSON Schemas
-
-Below you find schemas for the NGFF specification in both Markdown and HTML format.
\ No newline at end of file
From 1a6d1565f3b09c9c237f877a32e1ec5c11fc04c8 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 8 Oct 2025 12:20:56 +0200
Subject: [PATCH 46/55] merge requirements files
---
docs/requirements.txt | 3 ++-
requirements.txt | 6 ------
2 files changed, 2 insertions(+), 7 deletions(-)
delete mode 100644 requirements.txt
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 4201ed42..cfc70258 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -6,4 +6,5 @@ sphinx-examples
json-schema-for-humans
myst-parser
json_with_comments
-jupyter-book
\ No newline at end of file
+jupyter-book
+jsonschema_markdown
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index e4cf6cc4..00000000
--- a/requirements.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-jupyter-book
-json-schema-for-humans
-jason-with-comments
-sphinx-inline-tabs
-sphinx-proof
-sphinx-examples
\ No newline at end of file
From afc0090fb2edadf60175db59990bb51499f49be6 Mon Sep 17 00:00:00 2001
From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com>
Date: Wed, 8 Oct 2025 12:20:59 +0200
Subject: [PATCH 47/55] Delete transform-details.bs
---
transform-details.bs | 106 -------------------------------------------
1 file changed, 106 deletions(-)
delete mode 100644 transform-details.bs
diff --git a/transform-details.bs b/transform-details.bs
deleted file mode 100644
index b2b744c8..00000000
--- a/transform-details.bs
+++ /dev/null
@@ -1,106 +0,0 @@
-
-Title: Coordinates and Transformations
-Shortname: ome-ngff-transformations
-Level: 1
-Status: LS-COMMIT
-Status: w3c/ED
-Group: ome
-URL: https://ngff.openmicroscopy.org/latest/
-Repository: https://github.com/ome/ngff
-Issue Tracking: Forums https://forum.image.sc/tag/ome-ngff
-Logo: http://www.openmicroscopy.org/img/logos/ome-logomark.svg
-Local Boilerplate: header no
-Local Boilerplate: copyright no
-Boilerplate: style-darkmode off
-Markup Shorthands: markdown yes
-Editor: Josh Moore, Open Microscopy Environment (OME) https://www.openmicroscopy.org
-Editor: Sébastien Besson, Open Microscopy Environment (OME) https://www.openmicroscopy.org
-Editor: Constantin Pape, European Molecular Biology Laboratory (EMBL) https://www.embl.org/sites/heidelberg/
-Editor: John Bogovic, Hughes Medical Institute Janelia (HHMI) https://www.janelia.org/
-Abstract: This document contains next-generation file format (NGFF)
-Abstract: specifications for storing bioimaging data in the cloud.
-Abstract: All specifications are submitted to the https://image.sc community for review.
-Status Text: The current released version of this specification is
-Status Text: will be provided between numbered versions. Data written with these latest changes
-Status Text: (an "editor's draft") will not necessarily be supported.
-
\ No newline at end of file
diff --git a/ngff_spec/autodocs/schemas/html/axes.html b/ngff_spec/autodocs/schemas/html/axes.html
new file mode 100644
index 00000000..3c4c7d8e
--- /dev/null
+++ b/ngff_spec/autodocs/schemas/html/axes.html
@@ -0,0 +1 @@
+ NGFF Axes
\ No newline at end of file
diff --git a/ngff_spec/autodocs/schemas/html/bf2raw.html b/ngff_spec/autodocs/schemas/html/bf2raw.html
new file mode 100644
index 00000000..4e20c93a
--- /dev/null
+++ b/ngff_spec/autodocs/schemas/html/bf2raw.html
@@ -0,0 +1 @@
+ OME-Zarr container produced by bioformats2raw
😅 ERROR in schema generation, a referenced schema could not be loaded, no documentation here unfortunately 🏜️
\ No newline at end of file
diff --git a/ngff_spec/autodocs/schemas/html/coordinate_systems.html b/ngff_spec/autodocs/schemas/html/coordinate_systems.html
new file mode 100644
index 00000000..ad19506a
--- /dev/null
+++ b/ngff_spec/autodocs/schemas/html/coordinate_systems.html
@@ -0,0 +1 @@
+ NGFF CoordinateSystem
\ No newline at end of file
diff --git a/ngff_spec/autodocs/schemas/html/label.html b/ngff_spec/autodocs/schemas/html/label.html
new file mode 100644
index 00000000..3b879442
--- /dev/null
+++ b/ngff_spec/autodocs/schemas/html/label.html
@@ -0,0 +1 @@
+ OME-Zarr labelled image schema
😅 ERROR in schema generation, a referenced schema could not be loaded, no documentation here unfortunately 🏜️
\ No newline at end of file
diff --git a/ngff_spec/autodocs/schemas/html/ome.html b/ngff_spec/autodocs/schemas/html/ome.html
new file mode 100644
index 00000000..e75bc793
--- /dev/null
+++ b/ngff_spec/autodocs/schemas/html/ome.html
@@ -0,0 +1 @@
+ OME-Zarr group produced by bioformats2raw to contain OME metadata
OME-Zarr group produced by bioformats2raw to contain OME metadata
😅 ERROR in schema generation, a referenced schema could not be loaded, no documentation here unfortunately 🏜️
\ No newline at end of file
diff --git a/ngff_spec/autodocs/schemas/html/ome_zarr.html b/ngff_spec/autodocs/schemas/html/ome_zarr.html
new file mode 100644
index 00000000..e3503f45
--- /dev/null
+++ b/ngff_spec/autodocs/schemas/html/ome_zarr.html
@@ -0,0 +1 @@
+ Schema Docs
😅 ERROR in schema generation, a referenced schema could not be loaded, no documentation here unfortunately 🏜️
\ No newline at end of file
diff --git a/ngff_spec/autodocs/schemas/html/plate.html b/ngff_spec/autodocs/schemas/html/plate.html
new file mode 100644
index 00000000..e342e058
--- /dev/null
+++ b/ngff_spec/autodocs/schemas/html/plate.html
@@ -0,0 +1 @@
+ OME-Zarr plate schema
\ No newline at end of file
diff --git a/ngff_spec/autodocs/schemas/html/bf2raw.html b/ngff_spec/autodocs/schemas/html/bf2raw.html
deleted file mode 100644
index 4e20c93a..00000000
--- a/ngff_spec/autodocs/schemas/html/bf2raw.html
+++ /dev/null
@@ -1 +0,0 @@
- OME-Zarr container produced by bioformats2raw
😅 ERROR in schema generation, a referenced schema could not be loaded, no documentation here unfortunately 🏜️
\ No newline at end of file
diff --git a/ngff_spec/autodocs/schemas/html/ome.html b/ngff_spec/autodocs/schemas/html/ome.html
deleted file mode 100644
index e75bc793..00000000
--- a/ngff_spec/autodocs/schemas/html/ome.html
+++ /dev/null
@@ -1 +0,0 @@
- OME-Zarr group produced by bioformats2raw to contain OME metadata
OME-Zarr group produced by bioformats2raw to contain OME metadata