Writing an image¶
import numpy as np
from ome_zarr_io import Writer
# Create sample multichannel 3D confocal image data
image = np.random.randint(0, 255, size=(2, 32, 512, 512), dtype=np.uint8)
dims = ["c", "z", "y", "x"]
# Define axis units for each dimension explicitly
axis_units = {
"z": "micrometer",
"y": "micrometer",
"x": "micrometer"
}
# Units should be one of the OME-Zarr 0.5 recommended names (e.g. "micrometer").
# "pixel" is also accepted for uncalibrated images, but is not in the spec's list
# and emits a UserWarning.
# Define scale transformations (pixel/voxel sizes)
# Units are determined by axis_units above
scale_transformations = {
"z": 0.325, # 0.325 μm z-step size
"y": 0.15, # 0.15 μm pixel size in Y
"x": 0.15 # 0.15 μm pixel size in X
}
writer = Writer(
path='example.ome.zarr',
image=image,
dims=dims,
axis_units=axis_units,
scale_transformations=scale_transformations,
downscale_method='mean', # Block average; use 'nearest' for label images
downscale_levels=3, # Create 3 additional downscale levels
downscale_factor=2, # Integer >= 2; each level is 2x smaller in Y/X
overwrite=True
)
writer.write()
The downscale_levels, downscale_factor and downscale_method options are explained under
Resolution level in the terminology section.
Chunks, shards and compression¶
write() takes three optional arguments that control how the image data is stored. They apply to every
resolution level. Without them, zarr chooses the chunk shape and compresses with Zstd.
writer = Writer(
path="chunked.ome.zarr",
image=image,
dims=dims,
axis_units=axis_units,
scale_transformations=scale_transformations,
overwrite=True,
)
writer.write(
chunks=(1, 8, 256, 256), # the unit that is read and decompressed on its own
shards=(2, 32, 512, 512), # groups chunks into fewer, larger files
compressors={"name": "zstd", "configuration": {"level": 5}},
)
Each shard shape has to be a whole multiple of the chunk shape. Sharding keeps the number of files manageable for large images.
Choosing a compressor¶
compressors takes a codec as a plain dictionary or as an object from zarr. You do not need to import
anything from zarr to use the dictionary form. It follows the
Zarr v3 codec names, a name and an optional configuration:
You want |
Pass |
|---|---|
zarr’s default (Zstd, level 0) |
nothing, or |
Zstd, stronger |
|
Blosc with Zstd and bit shuffling |
|
Gzip |
|
Several codecs in a row |
a list of such dictionaries |
No compression |
|
The same options as objects, if you already work with zarr:
import zarr
writer = Writer(
path="blosc.ome.zarr",
image=image,
dims=dims,
axis_units=axis_units,
scale_transformations=scale_transformations,
overwrite=True,
)
writer.write(
compressors=zarr.codecs.BloscCodec(cname="zstd", clevel=5, shuffle="bitshuffle"),
)
add_labels accepts the same chunks, shards and compressors arguments for label images.