API Reference
OME-TIFF and OME-ZARR writer APIs designed for microscopy acquisition.
Classes:
| Name | Description |
|---|---|
AcquisitionSettings |
Top-level acquisition settings. |
Channel |
A single channel in an acquisition. |
Dimension |
A single dimension in the acquisition. |
OMEStream |
Object returned by |
OmeTiffFormat |
Settings specific to OME-TIFF format. |
OmeZarrFormat |
Settings specific to OME-Zarr format. |
Plate |
Plate structure for OME metadata. |
Position |
A single acquisition position. |
PositionDimension |
Deprecated: use Dimension(type='position', ...) instead. |
StandardAxis |
Standard axis names. |
Functions:
| Name | Description |
|---|---|
create_stream |
Create a stream for writing OME-TIFF or OME-ZARR data. |
dims_from_standard_axes |
Create dimensions from standard axis names. |
dims_from_useq |
Convert a |
useq_to_acquisition_settings |
Convert a |
AcquisitionSettings
Top-level acquisition settings.
This is the main schema object for defining an acquisition to be written using ome-writers. It includes the output path, dimensions, data type, compression, storage order, plate structure, and backend selection.
Pass this object to ome_writers.create_stream to create a data stream for writing acquisition data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root_path
|
str
|
Root output path for the acquisition data. This may be a directory (for OME-Zarr) or a file path (for OME-TIFF). It is customary to use an |
required |
dimensions
|
tuple[Dimension, ...]
|
List of dimensions in order of acquisition. Must include at least two spatial 'in-frame' dimensions (usually Y and X) at the end. May not include more than 5 non-position dimensions total. May include one position dimension (type='position') to specify multiple acquisition positions. Only the first dimension may be unbounded (count=None). |
required |
dtype
|
str
|
Data type of the pixel data to be written, e.g. 'uint8', 'uint16', 'float32', etc. Must be a valid numpy DTypeLike string. |
required |
format
|
OmeTiffFormat | OmeZarrFormat
|
Desired output format/backend. Can be a simple string: 'ome-tiff' or 'ome-zarr', in which case the first available format-appropriate backend will be used; Or it may be a full format specification dict/object ([ |
'auto'
|
compression
|
Literal['blosc-zstd', 'blosc-lz4', 'zstd', 'lzw', 'none'] | None
|
Compression algorithm for the storage backend. Zarr backends support: 'blosc-zstd', 'blosc-lz4', 'zstd', 'none'. TIFF backend supports: 'lzw', 'none'. If None, no compression is applied. |
None
|
storage_order
|
Literal['acquisition', 'ome'] | list[str]
|
Storage order for non-frame dimensions (if different from acquisition order). May be 'acquisition' (same as acquisition order), a list of dimension names to specify a custom storage order. Or 'ome' to use a format-specific OME-compliant canonical order (e.g. TCZYX for OME-Zarr v0.5), or any [TCZ]YX variation for OME-TIFF. The last two 'frame' dimensions (usually Y and X) may not be reordered. Default is 'ome'. |
'ome'
|
plate
|
Plate | None
|
Plate structure for OME metadata. If specified, requires a position dimension (type='position') in |
None
|
overwrite
|
bool
|
Whether to overwrite existing data at |
False
|
Attributes:
| Name | Type | Description |
|---|---|---|
array_dimensions |
tuple[Dimension, ...]
|
All Dimensions excluding position dimensions. |
array_storage_dimensions |
tuple[Dimension, ...]
|
All Dimensions (excluding position dimension) in storage order. |
frame_dimensions |
tuple[Dimension, ...]
|
In-frame dimensions, currently always last two dims (usually (Y,X)). |
index_dimensions |
tuple[Dimension, ...]
|
All NON-frame Dimensions, excluding position dimensions. |
is_unbounded |
bool
|
Whether the acquisition has an unbounded (None) dimension. |
num_frames |
int | None
|
Return total number of frames, or None if unlimited dimension present. |
output_path |
str
|
Output path for the acquisition data. |
position_dimension_index |
int | None
|
Index of position dimension in dimensions, or None if not present. |
positions |
tuple[Position, ...]
|
Position objects in acquisition order. |
shape |
tuple[int | None, ...]
|
Shape of the array (count for each dimension). |
storage_index_dimensions |
tuple[Dimension, ...]
|
NON-frame Dimensions in storage order. |
storage_index_permutation |
tuple[int, ...] | None
|
Permutation to convert acquisition index to storage index, if different. |
array_dimensions
property
array_dimensions: tuple[Dimension, ...]
All Dimensions excluding position dimensions.
array_storage_dimensions
property
array_storage_dimensions: tuple[Dimension, ...]
All Dimensions (excluding position dimension) in storage order.
frame_dimensions
property
frame_dimensions: tuple[Dimension, ...]
In-frame dimensions, currently always last two dims (usually (Y,X)).
index_dimensions
property
index_dimensions: tuple[Dimension, ...]
All NON-frame Dimensions, excluding position dimensions.
is_unbounded
property
is_unbounded: bool
Whether the acquisition has an unbounded (None) dimension.
num_frames
property
num_frames: int | None
Return total number of frames, or None if unlimited dimension present.
output_path
property
output_path: str
Output path for the acquisition data.
This is the root_path provided by the user, resolved by the format, possibly
with appropriate suffix/extension added.
position_dimension_index
property
position_dimension_index: int | None
Index of position dimension in dimensions, or None if not present.
positions
property
positions: tuple[Position, ...]
Position objects in acquisition order.
shape
property
shape: tuple[int | None, ...]
Shape of the array (count for each dimension).
storage_index_dimensions
property
storage_index_dimensions: tuple[Dimension, ...]
NON-frame Dimensions in storage order.
storage_index_permutation
property
storage_index_permutation: tuple[int, ...] | None
Permutation to convert acquisition index to storage index, if different.
Channel
A single channel in an acquisition.
This object may be used (instead of a plain string) in the
Dimension.coords list
for dimensions of type='channel' when you want to specify more than just channel
name.
This metadata is propagated to OME.Image.Pixels.Channel for OME-XML, and
to omero.channels for OME-Zarr.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
A name for the channel, suitable for presentation to the user. |
required |
excitation_wavelength_nm
|
int | None
|
Excitation wavelength in nanometers. |
None
|
emission_wavelength_nm
|
int | None
|
Emission wavelength in nanometers. |
None
|
fluorophore
|
str | None
|
Name of the fluorophore used in this channel. No validation done, prefer names from FPbase where possible. |
None
|
color
|
Color | None
|
A color recommended when rendering this channel. Input may be a string, or a 3-4 tuple of RGB(A) values (0-255). |
None
|
Dimension
A single dimension in the acquisition.
Dimensions define the shape and order of axis iteration during the acquisition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
User-defined name. Can be anything, but prefer using standard names like 'x', 'y', 'z', 'c', 't' where possible. Must be unique across all dimensions in an acquisition. |
required |
count
|
int | None
|
Size of this dimension (in number of elements/pixels).None indicates an unbounded (unlimited) 'append' dimension. Only the first dimension in may be unbounded. |
None
|
type
|
Literal['space', 'time', 'channel', 'position', 'other'] | None
|
Type of this dimension. Must be one of
|
None
|
coords
|
list[str | float | Channel | Position] | None
|
Explicit coordinate values for each element along this dimension. This is primarily a convenience for specifying categorical coordinates, such as channels or positions, and may also be used to explicitly list non-uniform spatial or temporal coordinates. If provided, the length of this list must match the |
None
|
chunk_size
|
int | None
|
Number of elements in a chunk for this dimension, for storage backends that support chunking (e.g. Zarr). If None, defaults to full size (i.e. |
None
|
shard_size_chunks
|
int | None
|
Number of chunks per shard (NOT number of pixels per shard), for storage backends that support sharding (e.g. Zarr v3). If not specified, no sharding is used (i.e. chunks are the unit of storage). |
None
|
unit
|
str | None
|
Physical unit for this dimension. If |
None
|
scale
|
float | None
|
Physical size of a single element along this dimension, in the specified |
None
|
translation
|
float | None
|
Physical offset of the first element along this dimension, in the specified |
None
|
OMEStream
OMEStream(
backend: ArrayBackend,
router: FrameRouter,
expected_frames: int | None,
)
Object returned by create_stream() for writing OME-TIFF or OME-ZARR data.
Important
This class should be instantiated via the
create_stream() factory
function, not directly. It is made public here only for type checking
and usage API documentation.
Outside of AcquisitionSettings, this is the main public interface.
This class manages the iteration through frames in acquisition order and delegates writing to the backend in storage order.
Usage
with create_stream(settings) as stream:
for frame in frames:
stream.append(frame)
Warning
If not used as a context manager, you must call
close() to ensure all data is flushed
and resources are released. A warning will be emitted if the object is
garbage collected without being closed.
Methods:
| Name | Description |
|---|---|
__enter__ |
Enter context manager. |
__exit__ |
Exit context manager, finalizing the backend. |
append |
Write the next frame in acquisition order. |
close |
Finalize the backend, flush any pending writes, and release resources. |
get_metadata |
Retrieve metadata from the backend. Meaning is format-dependent. |
skip |
Skip N frames in acquisition order without writing data. |
update_metadata |
Update metadata in the backend. Meaning is format-dependent. |
__enter__
__enter__() -> OMEStream
Enter context manager.
__exit__
__exit__(
exc_type: object, exc_val: object, exc_tb: object
) -> None
Exit context manager, finalizing the backend.
append
append(
frame: ndarray, *, frame_metadata: dict | None = None
) -> None
Write the next frame in acquisition order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
ndarray
|
2D array containing the frame data (Y, X). |
required |
frame_metadata
|
dict
|
Optional per-frame metadata. All data must be JSON-serializable (or will fail to be stored and a warning will be issued). The following special keys are recognized and will be mapped to format-specific locations:
All other keys will be stored as unstructured metadata. For OME-Tiff, you
can find this data in the structured annotations of the OME-XML. For
OME-Zarr, this data will be stored in the |
None
|
Raises:
| Type | Description |
|---|---|
IndexError
|
If attempting to append more frames than expected based on dimensions (for finite dimensions only). Unlimited dimensions never raise this error. |
close
close() -> None
Finalize the backend, flush any pending writes, and release resources.
get_metadata
get_metadata() -> Any
Retrieve metadata from the backend. Meaning is format-dependent.
skip
skip(*, frames: int = 1) -> None
Skip N frames in acquisition order without writing data.
This method advances the stream's position by the specified number of frames without writing any actual data. The behavior depends on the backend:
- Zarr backends: Skipped regions use the array's fill_value (default 0). For unlimited dimensions, the array is resized to accommodate the skip.
- TIFF backend: Writes zero-filled placeholder frames to maintain the sequential IFD structure required by the format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frames
|
int
|
(Keyword only). Number of frames to skip, by default 1. Must be positive. |
1
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If frames <= 0 |
IndexError
|
If skipping would exceed the total number of frames expected based on dimensions (for finite dimensions only). Unlimited dimensions never raise this error. |
Examples:
>>> with create_stream(settings) as stream:
... stream.append(frame1) # Write frame at index 0
... stream.skip(frames=1) # Skip frame at index 1
... # try something that may fail
... try:
... frame_generator = setup_next_10_frames()
... except SomeError:
... stream.skip(frames=10) # Skip next 10 frames
... else:
... for frameN in frame_generator:
... stream.append(frameN)
... stream.append(frame_last) # Continue writing at next index
update_metadata
update_metadata(metadata: Any) -> None
Update metadata in the backend. Meaning is format-dependent.
OmeTiffFormat
Settings specific to OME-TIFF format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
Literal['ome-tiff']
|
File format identifier for OME-TIFF. |
'ome-tiff'
|
backend
|
Literal['tifffile'] | Literal['auto']
|
Storage backend to use for writing data. Must be one of 'auto', or 'tifffile'. If 'auto' (the default), the backend will be chosen based on available dependencies. Currently, 'tifffile' is the only supported backend. |
'auto'
|
suffix
|
str
|
File suffix/extension to use for OME-TIFF files. Default is '.ome.tiff'. |
'.ome.tiff'
|
OmeZarrFormat
Settings specific to OME-Zarr format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
Literal['ome-zarr']
|
File format identifier for OME-Zarr. |
'ome-zarr'
|
backend
|
Literal['acquire-zarr', 'tensorstore', 'zarrs-python', 'zarr-python'] | Literal['auto']
|
Storage backend to use for writing data. Must be one of 'auto', 'tensorstore', 'acquire-zarr', 'zarrs-python', or 'zarr-python'. If 'auto' (the default), the backend will be chosen based on the available dependencies, in the order: tensorstore, acquire-zarr, zarrs-python, zarr-python. |
'auto'
|
suffix
|
str
|
Directory suffix/extension to use for OME-Zarr directories. Default is '.ome.zarr'. |
'.ome.zarr'
|
Plate
Plate structure for OME metadata.
This defines the plate geometry (rows/columns) for metadata generation.
Acquisition order is determined by position dimension in AcquisitionSettings,
not by this class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
row_names
|
list[str]
|
List of all row names in the plate, e.g. |
required |
column_names
|
list[str]
|
List of all column names in the plate, e.g. |
required |
name
|
str | None
|
Optional name for the plate. |
None
|
Methods:
| Name | Description |
|---|---|
from_standard_wells |
Convenience constructor to create a plate from standard well counts or shape. |
from_standard_wells
classmethod
from_standard_wells(
num_wells_or_shape: int | tuple[int, int],
) -> Self
Convenience constructor to create a plate from standard well counts or shape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_wells_or_shape
|
int | tuple[int, int]
|
If an integer is provided, it is interpreted as a "standard" n-well plate with common dimensions (e.g. 24 -> 4x6, 96 -> 8x12, 384 -> 16x24). If a tuple of (rows, columns) is provided, it is used directly. |
required |
Position
A single acquisition position.
This object may be used (instead of a plain string) in the
Dimension.coords list
for dimensions of type='position' when you want to specify more than just position
name.
This represents a physical position in space associated with a single camera frame
or field of view. Optional fields such as grid/plate_row/column indicate that the
position is a member of a larger coordinate system (e.g. well plate or grid). The
x_coord, y_coord, and z_coord fields represent physical coordinates. Units
should match those used in the spatial Dimensions of the acquisition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name for this position. Within a list of positions, names must be unique within each |
required |
plate_row
|
str | None
|
Row name for plate position. |
None
|
plate_column
|
str | None
|
Column name for plate position. |
None
|
grid_row
|
int | None
|
Row index for this position in a grid layout (if any). |
None
|
grid_column
|
int | None
|
Column index for this position in a grid layout (if any). |
None
|
x_coord
|
float | None
|
Physical X coordinate of this position (e.g., stage coordinate). |
None
|
y_coord
|
float | None
|
Physical Y coordinate of this position (e.g., stage coordinate). |
None
|
z_coord
|
float | None
|
Physical Z coordinate of this position (e.g., stage coordinate). |
None
|
PositionDimension
StandardAxis
Standard axis names.
Dimension names are fundamentally arbitrary strings, but these standard
names are commonly used and have well-defined meanings in terms of dimension
type and units. This is used in dims_from_standard_axes helper function.
Methods:
| Name | Description |
|---|---|
dimension_type |
Return dimension type for this standard axis. |
to_dimension |
Convert to Dimension with given count. |
unit |
Return unit for this standard axis, or None if unknown. |
dimension_type
dimension_type() -> DimensionType
Return dimension type for this standard axis.
to_dimension
to_dimension(
*,
count: int | None = None,
coords: list[str | Position] | None = None,
chunk_size: int | None = None,
shard_size_chunks: int | None = None,
scale: float | None = None,
) -> Dimension
Convert to Dimension with given count.
unit
unit() -> str | None
Return unit for this standard axis, or None if unknown.
create_stream
create_stream(settings: AcquisitionSettings) -> OMEStream
Create a stream for writing OME-TIFF or OME-ZARR data.
Warning
If not used as a context manager, you must call
stream.close() to ensure all data is flushed
and resources are released. A warning will be emitted if the object is
garbage collected without being closed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
AcquisitionSettings
|
Acquisition settings containing array configuration, path, backend, etc. |
required |
Returns:
| Type | Description |
|---|---|
OMEStream
|
A configured stream ready for writing frames via
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If settings are invalid or backend is incompatible. |
NotImplementedError
|
If requesting unsupported features (e.g., plate mode). |
Examples:
>>> settings = AcquisitionSettings(
... root_path="output.zarr",
... dimensions=dims_from_standard_axes({"t": 10, "c": 2, "y": 512, "x": 512}),
... dtype="uint16",
... overwrite=True,
... )
>>> with create_stream(settings) as stream:
... for i in range(20): # 10 timepoints x 2 channels
... stream.append(np.zeros((512, 512), dtype=np.uint16))
dims_from_standard_axes
dims_from_standard_axes(
sizes: Mapping[
str, int | Sequence[str | Position] | None
],
chunk_shapes: Mapping[str | StandardAxis, int]
| None = None,
shard_shapes: Mapping[str | StandardAxis, int]
| None = None,
) -> list[Dimension]
Create dimensions from standard axis names.
Standard axes are {'x', 'y', 'z', 'c', 't', 'p'}. Dimension types and units are inferred from these names. Chunk shapes default to 1 for non-XY dimensions.
For positions ('p'), the value can be: - int: creates a position Dimension (type='position') with names "0", "1", ... - list[str | Position]: creates a position Dimension with those names or Position objects
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sizes
|
Mapping[str, int | Sequence[str | Position] | None]
|
Mapping of axis name to size. Order determines dimension order. For 'p', value can be int or list of position names. |
required |
chunk_shapes
|
Mapping[str | StandardAxis, int] | None
|
Optional mapping of axis_name to chunk size. Defaults to full size for X/Y, 1 for others. |
None
|
shard_shapes
|
Mapping[str | StandardAxis, int] | None
|
Optional mapping of axis_name to shard size (in number of chunks). Defaults to None (no sharding). |
None
|
Returns:
| Type | Description |
|---|---|
list[Dimension]
|
Dimensions in the order specified by sizes. |
Examples:
>>> dims = dims_from_standard_axes({"t": 10, "c": 2, "y": 512, "x": 512})
>>> dims = dims_from_standard_axes({"t": 10, "p": ["A1", "B2"], "y": 512, "x": 512})
dims_from_useq
dims_from_useq(
seq: MDASequence,
image_width: int,
image_height: int,
*,
units: Mapping[str, UnitTuple | None] | None = None,
pixel_size_um: float | None = None,
chunk_shapes: Mapping[str, int] | None = None,
shard_shapes: Mapping[str, int] | None = None,
) -> list[Dimension]
Convert a useq.MDASequence to a list of Dimension.
Deprecated
This function is deprecated and will be removed in a future version.
Use useq_to_acquisition_settings
instead. Dimensions can be obtained from the returned dictionary.
useq_to_acquisition_settings
useq_to_acquisition_settings(
seq: MDASequence,
image_width: int,
image_height: int,
*,
units: Mapping[str, UnitTuple | None] | None = None,
pixel_size_um: float | None = None,
chunk_shapes: Mapping[str, int] | None = None,
shard_shapes: Mapping[str, int] | None = None,
) -> AcquisitionSettingsDict
Convert a useq.MDASequence to settings for AcquisitionSettings.
Important
useq-schema has a very expressive API that can generate complex,
irregular multi-dimensional acquisition sequences. However, not all of these
patterns can be represented in a regular N-dimensional image data structure as
used by OME-TIFF/OME-NGFF. Sequences that result in ragged dimensions will
raise NotImplementedError when passed to this function.
The following restrictions apply:
Grid and Position handling:
- Position and grid axes must be adjacent in axis_order (e.g.,
"pgcz", not"pcgz"). - When both
stage_positionsandgrid_planare specified, position must come before grid in axis_order (e.g., "pgtcz" not "gptcz"). Grid-first order is only supported when usinggrid_planalone withoutstage_positions. - Position subsequences may only contain a
grid_plan, not time/channel/z-plans. Different positions may have different grid shapes. - If
stage_positionsis aWellPlatePlan, it cannot be combined with an outergrid_plan. Usewell_points_planon theWellPlatePlaninstead.
Channel, Z, and Time handling:
- All channels must have the same
do_stackvalue when a z_plan is present. - All channels must have
acquire_every=1. Skipping timepoints on some channels creates ragged dimensions. - Unbounded time plans (duration-based plans with interval=0) are not supported.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seq
|
MDASequence
|
The |
required |
image_width
|
int
|
The expected width of the images in the stream. |
required |
image_height
|
int
|
The expected height of the images in the stream. |
required |
units
|
Mapping[str, UnitTuple | None] | None
|
An optional mapping of dimension labels to their units. |
None
|
pixel_size_um
|
float | None
|
The size of a pixel in micrometers. If provided, it will be used to set the scale for the spatial dimensions. |
None
|
chunk_shapes
|
Mapping[str, int] | None
|
An optional mapping of dimension names ("tczyx") to their chunk sizes. (In number of pixels per chunk) |
None
|
shard_shapes
|
Mapping[str, int] | None
|
An optional mapping of dimension names ("tczyx") to their shard sizes (in number of chunks per shard) |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
A dictionary suitable for passing as keyword arguments to
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If the sequence contains any of the unsupported patterns listed above. |
Examples:
import useq
from ome_writers import useq_to_acquisition_settings, AcquisitionSettings
seq = useq.MDASequence(time_plan={"interval": 10, "loops": 5})
settings = AcquisitionSettings(
root_path="/data/acquisitions/acq1.ome.zarr",
**useq_to_acquisition_settings(seq, image_width=1024, image_height=1024),
dtype="uint16",
)