Create Scenes

This tutorial demonstrates basic usage around writing and reading Ngff Scenes using the ome_zarr.classes.scene.OMEZarrScene class.

from ome_zarr_models.v06.coordinate_transforms import CoordinateSystem, Translation
from skimage import data

from ome_zarr import OMEZarrImage, OMEZarrMultiscale, OMEZarrScene

We create some sample data, which we will store as a tiled layout in a scene zarr group:

example_image = data.human_mitosis()
example_image.shape
/home/docs/checkouts/readthedocs.org/user_builds/ome-zarr/envs/stable/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm
Downloading file 'data/mitosis.tif' from 'https://gitlab.com/scikit-image/data/-/raw/2cdc5ce89b334d28f06a58c9f0ca21aa6992a5ba/AS_09125_050116030001_D03f00d0.tif' to '/home/docs/.cache/scikit-image/0.26.0'.
(512, 512)

First, we cut the image into four tiles and convert them into instances of ome_zarr.classes.image.OMEZarrMultiscale:

img1 = OMEZarrImage(data=example_image[:256, :256], axes=["y", "x"], name="img1")
img2 = OMEZarrImage(data=example_image[256:, :256], axes=["y", "x"], name="img2")
img3 = OMEZarrImage(data=example_image[:256, 256:], axes=["y", "x"], name="img3")
img4 = OMEZarrImage(data=example_image[256:, 256:], axes=["y", "x"], name="img4")

img1_ms = OMEZarrMultiscale(img1)
img2_ms = OMEZarrMultiscale(img2)
img3_ms = OMEZarrMultiscale(img3)
img4_ms = OMEZarrMultiscale(img4)

Next, we need to define a coordinate system into which all images are projected. This is defined in accordance with the NGFF coordinate systems specification. The coordinate systems can be defined using the ome_zarr_models.v06.coordinate_transforms.CoordinateSystem class:

coordinate_system = CoordinateSystem.model_validate({
    "name": "world",
    "axes": [
        {"name": "y", "type": "space"},
        {"name": "x", "type": "space"},
    ],
})

Hint

ome_zarr_models.v06.coordinate_transforms.CoordinateSystem is a pydantic class. This means that it can be instantiated either from a to-be validated dictionary or from keyword arguments and subfields:

coordinate_system = CoordinateSystem.model_validate({...})
coordinate_system = CoordinateSystem(name="world", axes=[...])

In the second case, the axes argument would need to be populated with the respective ome_zarr_models.v06.coordinate_transforms.Axis instances.

We then define translations that move each tile into the appropriate position in the world coordinate system. In this example, these are simple translations in the y and x dimensions:

coordinate_transformations = [
    Translation.model_validate({
        "type": "translation",
        "translation": [0, 0],
        "input": {"path": "img1", "name": "physical"},
        "output": {"name": "world"},
    }),
    Translation.model_validate({
        "type": "translation",
        "translation": [256, 0],
        "input": {"path": "img2", "name": "physical"},
        "output": {"name": "world"},
    }),
    Translation.model_validate({
        "type": "translation",
        "translation": [0, 256],
        "input": {"path": "img3", "name": "physical"},
        "output": {"name": "world"},
    }),
    Translation.model_validate({
        "type": "translation",
        "translation": [256, 256],
        "input": {"path": "img4", "name": "physical"},
        "output": {"name": "world"},
    }),
]

We can then create and write a scene like this:

scene = OMEZarrScene(
    images=[img1_ms, img2_ms, img3_ms, img4_ms],
    coordinate_systems=[coordinate_system],
    coordinate_transformations=coordinate_transformations
)

scene.to_ome_zarr("test_example_scene.zarr", overwrite=True)
[]

….and load it back like this:

loaded_scene = OMEZarrScene.from_ome_zarr("test_example_scene.zarr")
loaded_scene.coordinate_transformations
(Translation(type='translation', input=CoordinateSystemIdentifier(name='physical', path='img1'), output=CoordinateSystemIdentifier(name='world', path=None), name=None, translation=(0.0, 0.0)),
 Translation(type='translation', input=CoordinateSystemIdentifier(name='physical', path='img2'), output=CoordinateSystemIdentifier(name='world', path=None), name=None, translation=(256.0, 0.0)),
 Translation(type='translation', input=CoordinateSystemIdentifier(name='physical', path='img3'), output=CoordinateSystemIdentifier(name='world', path=None), name=None, translation=(0.0, 256.0)),
 Translation(type='translation', input=CoordinateSystemIdentifier(name='physical', path='img4'), output=CoordinateSystemIdentifier(name='world', path=None), name=None, translation=(256.0, 256.0)))