API Reference
OMIO’s public API functions
High level I/O
OMIO’s main high-level API functions for reading, writing, and converting microscopy image data:
- omio.omio.imread(fname, zarr_store=None, return_list=False, recursive=False, folder_stacks=False, merge_folder_stacks=False, merge_multiple_files_in_folder=False, merge_along_axis='T', zeropadding=True, physicalsize_xyz=None, pixelunit='micron', collapse_ome_multifile_series=True, verbose=True)[source]
Read microscopy images and folders into OMIO’s canonical representation, with optional folder stack handling and concatenation based merges.
This is OMIO’s high level entry point. It accepts a single file, a list of files, or a folder path. Supported input formats are TIFF family files (including OME TIFF and LSM), Zeiss CZI, and Thorlabs RAW. For each file, the corresponding format specific reader is selected automatically, metadata are standardized, and the returned image is normalized to OME axis order TZCYX.
If zarr_store is set to “memory” or “disk”, readers return a Zarr array instead of a NumPy array. For “disk”, Zarr outputs are created in a hidden cache folder .omio_cache next to the source data. This is intended for large files where memory mapping and chunked access are required downstream.
Folder input behavior
If fname resolves to a folder, OMIO lists all supported image files inside the folder (optionally recursive) and reads them in sorted order.
If folder_stacks=True or merge_folder_stacks=True, the folder is interpreted as one member of a tagged folder stack family with names like <TAG>_000, <TAG>_001, etc. OMIO derives <TAG>_ from the provided folder name, finds all co folders with the same tag in the parent directory, reads the first image file in each of these folders, and returns either the list of stacks or a merged stack.
Merge behavior
Two merge modes are supported.
merge_multiple_files_in_folder=True merges all images found in a folder by concatenating along merge_along_axis. This is applied after reading all files from that folder.
merge_folder_stacks=True merges the tagged co folder stacks by concatenating along merge_along_axis.
merge_along_axis must be one of {“T”, “Z”, “C”}. In merge modes, OMIO expects that all inputs are already in OME order and have 5 dimensions (TZCYX). If zeropadding=False, non merge axes must match exactly, otherwise the merge is aborted with a warning and a None result. If zeropadding=True, non merge axes are padded with zeros up to the maximum size across inputs before concatenation. The merge axis may have length greater than one in each input; OMIO concatenates the full segments in the discovered order.
For merge outputs, metadata are merged with a provenance policy that records the inputs under the Annotations namespace and uses stack 0 as the reference for physical size and time increment fields.
- param fname:
File path, folder path, or list of file paths to read.
- type fname:
Union[str,PathLike,List[Union[str,PathLike]]]- param zarr_store:
Controls whether images are returned as NumPy arrays (None) or as materialized Zarr arrays (“memory” or “disk”). Default is None.
- type zarr_store:
Optional[str]- param return_list:
If True, always return lists of images and metadata. If False, return a single image and metadata for single input cases, otherwise lists. Default is False.
- type return_list:
bool- param recursive:
If True and fname is a folder, search recursively for supported image files. Default is False.
- type recursive:
bool- param folder_stacks:
If True and fname is a folder, interpret it as a tagged folder stack member and read the first image file from each tagged co folder. Default is False.
- type folder_stacks:
bool- param merge_folder_stacks:
If True, interpret tagged folder stacks and merge them along merge_along_axis. Default is False.
- type merge_folder_stacks:
bool- param merge_multiple_files_in_folder:
If True and fname is a folder, merge all files found in that folder along merge_along_axis. Default is False.
- type merge_multiple_files_in_folder:
bool- param merge_along_axis:
Axis along which concatenation is performed in merge modes. Default is “T”.
- type merge_along_axis:
str- param zeropadding:
If True, allow merges with mismatched non merge axes by zero padding to maxima. If False, require exact match on non merge axes. Default is True.
- type zeropadding:
bool- param physicalsize_xyz:
Optional voxel size override forwarded to the underlying readers. Default is None.
- type physicalsize_xyz:
Optional[Any]- param pixelunit:
Unit string forwarded to readers for unit normalization and defaults. Default is “micron”.
- type pixelunit:
str- param collapse_ome_multifile_series:
If True, detect OME multifile series and keep only one representative file per series to avoid duplicate loading. Default is True.
- type collapse_ome_multifile_series:
bool- param verbose:
If True, print diagnostic progress messages. Default is True.
- type verbose:
bool- returns:
image, metadata – For single non folder inputs and return_list=False, returns one image and one metadata dict. For multi file inputs, folder reads, or return_list=True, returns lists. Merge modes return a single merged image and merged metadata (or lists if return_list=True). If a requested merge fails validation, returns None results according to the calling branch.
- rtype:
Union[Tuple[Any,Dict[str,Any]],Tuple[List[Any],List[Dict[str,Any]]]]- raises ValueError:
If merge_along_axis is not one of {“T”, “Z”, “C”}.
- raises FileNotFoundError:
If a requested file path does not exist or is not a file.
- omio.omio.imwrite(fname, images, metadatas, compression_level=3, relative_path=None, overwrite=False, return_fnames=False, indicate_merged_files=False, verbose=True)[source]
Write image stacks as OME-TIFF with OMIO-normalized metadata.
This function is OMIO’s main OME-TIFF writer. It accepts either a single image and metadata dictionary or lists of images and metadatas. For each stack, it constructs an OME-XML metadata payload compatible with tifffile.imwrite, normalizes axes for OME-TIFF writing, decides whether BigTIFF is required, and writes a compressed OME-TIFF using zlib.
Output naming follows a provenance-first policy:
If the metadata contain an original filename inside
Annotations, that basename is used as the output basename.Otherwise, the basename is derived from fname (file stem) or from the directory name if fname is a directory.
Filename collisions are resolved by _check_fname_out unless overwrite is True.
If multiple stacks are written and no per-stack provenance name is available, a numeric suffix
_NNNis appended to keep outputs distinct.
If relative_path is provided, outputs are written into a subfolder relative to the chosen output parent directory.
- Parameters:
fname (
str) – Output anchor path. If fname is a directory, outputs are written into that directory (or into relative_path below it). If fname is a file path, outputs are written next to that file (or into relative_path below that parent directory).images (
Union[ndarray,Array,list[Union[ndarray,Array]]]) – Image data to write. A single image is accepted and treated as a one-element list. Arrays are expected to represent OME-like dimensions; the function normalizes axes and permutes to the writer’s target order internally.metadatas (
Union[dict,list[dict]]) – Metadata dictionary or list of dictionaries aligned with images. Each metadata dictionary should include at leastaxesand physical pixel sizes (PhysicalSizeX,PhysicalSizeY) for correct resolution tagging.compression_level (
int) – zlib compression level passed to tifffile.imwrite viacompressionargs={"level": ...}. Typical values are 0 to 9. Default is 3.relative_path (
Optional[str]) – If not None, outputs are written into<out_parent>/<relative_path>and the directory is created if needed. Default is None.overwrite (
bool) – If True, allow overwriting existing output files. If False, resolve name collisions by appending a numeric suffix. Default is False.return_fnames (
bool) – If True, return a list of written filenames. If False, return None. Default is False.indicate_merged_files (
bool) – If True, append"_merged"to the output basename for each written stack. This is intended to mark stacks that originate from prior merging steps. Default is False.verbose (
bool) – If True, print diagnostic messages about output naming and BigTIFF decisions. Default is True.
- Returns:
If return_fnames is True, returns a list of full paths to the written OME-TIFF files in the order processed. Otherwise returns None.
- Return type:
Optional[list[str]]- Raises:
ValueError – If images and metadatas have different lengths.
Notes
BigTIFF selection is determined by _check_bigtiff, using the uncompressed array size and, if needed, an estimated compressed size.
Axes are normalized by _normalize_axes_for_ometiff (currently removing a singleton
"S"axis) and then permuted into the writer’s target axis order before writing.Physical pixel sizes are written both as OME physical size fields and as TIFF resolution tags using
resolution=(1/PhysicalSizeY, 1/PhysicalSizeX).Map annotations are written from
metadata["Annotations"]. If annotations are a dictionary, a single MapAnnotation is written. If annotations are a list of dictionaries, multiple MapAnnotations are written. A namespace entry is ensured if missing.The function writes with
photometric="minisblack"and disables ImageJ metadata blocks (imagej=False), relying on OME metadata for interoperability.
- omio.omio.imconvert(fname, zarr_store=None, recursive=False, folder_stacks=False, merge_folder_stacks=False, merge_multiple_files_in_folder=False, merge_along_axis='T', collapse_ome_multifile_series=True, zeropadding=True, physicalsize_xyz=None, pixelunit='micron', compression_level=3, relative_path='omio_converted', overwrite=False, return_fnames=False, cleanup_cache=True, verbose=True)[source]
Convert microscopy image inputs to OME TIFF using OMIO’s reader plus OME TIFF writer.
This function is a convenience wrapper around imread(…) followed by imwrite(…). It accepts a single file path, a list of file paths, or a folder path, reads the input data into OMIO’s canonical representation (OME ordered axes TZCYX plus standardized metadata), and writes one OME TIFF per resulting image stack.
Input path semantics (inherited from imread(…))
Input handling and optional merges follow the same semantics as imread(…): folder reading can be recursive, tagged folder stacks can be interpreted as a sequence of co folders, and merge operations can concatenate multiple stacks along a chosen OME axis (“T”, “Z”, or “C”), optionally with zero padding on non merge axes.
The behavior depends on the type and structure of fname:
- Single file path
The file is read according to its extension (TIFF, OME TIFF, LSM, CZI, or RAW), converted to OMIO’s internal representation, and written as a single OME TIFF.
- List of file paths
Each file is read independently. By default, one OME TIFF per input file is written. If merge options are enabled (for example
merge_multiple_files_in_folder), files may be concatenated before writing.- Folder path
By default, all supported image files in the folder are read, optionally recursively if
recursive=True, and written as individual OME TIFF files.Additional folder specific modes are available:
folder_stacks=True: The folder is interpreted as one element of a tagged folder stack (for exampleTAG_000,TAG_001). The first valid image file from each tagged folder is read and written as a separate OME TIFF.merge_folder_stacks=True: Tagged folder stacks are read as above, but the resulting stacks are concatenated alongmerge_along_axisand written as a single merged OME TIFF.merge_multiple_files_in_folder=True: All image files found in the folder are concatenated alongmerge_along_axisand written as a single merged OME TIFF.
Merge behavior
Merge operations follow the same validation and padding rules as in imread(…):
Allowed merge axes are “T”, “Z”, and “C”.
If zeropadding=False, all non merge axes must match exactly.
If zeropadding=True, non merge axes are padded with zeros to the maximum size across inputs before concatenation.
Output behavior
The output location and naming follow imwrite(…):
OME TIFFs are written next to the input file or inside the input folder.
If relative_path is provided, a subfolder is created under the chosen output parent directory.
When merge modes are used, output filenames may include an indicator suffix to reflect merged content.
If overwrite=False, existing files are not replaced and collision safe names are generated.
Zarr handling and cache cleanup
If zarr_store is “memory” or “disk”, imread(…) may create Zarr arrays or materialize intermediate Zarr stores under a hidden .omio_cache directory. If cleanup_cache=True, this function removes the corresponding cache entries after writing. Cache cleanup is skipped when zarr_store=None.
- param fname:
File path, folder path, or list of file paths to convert.
- type fname:
Union[str,PathLike,List[Union[str,PathLike]]]- param zarr_store:
Controls whether imread(…) returns NumPy arrays (None) or Zarr arrays (“memory” or “disk”). Default is None.
- type zarr_store:
Optional[str]- param recursive:
If True and fname is a folder, search recursively for supported image files. Default is False.
- type recursive:
bool- param folder_stacks:
Interpret a tagged folder as part of a folder stack and read one image per tagged subfolder. Default is False.
- type folder_stacks:
bool- param merge_folder_stacks:
Merge tagged folder stacks along merge_along_axis and write a single OME TIFF. Default is False.
- type merge_folder_stacks:
bool- param merge_multiple_files_in_folder:
Merge all image files found in a folder along merge_along_axis and write a single OME TIFF. Default is False.
- type merge_multiple_files_in_folder:
bool- param merge_along_axis:
Axis along which concatenation is performed in merge modes. Default is “T”.
- type merge_along_axis:
str- param collapse_ome_multifile_series:
If True, detect OME multifile series and keep only one representative file per series to avoid duplicate loading. Default is True.
- type collapse_ome_multifile_series:
bool- param zeropadding:
Allow padding of non merge axes during merges. Default is True.
- type zeropadding:
bool- param physicalsize_xyz:
Optional voxel size override forwarded to the underlying readers. Default is None.
- type physicalsize_xyz:
Optional[Any]- param pixelunit:
Unit string forwarded to readers for unit normalization. Default is “micron”.
- type pixelunit:
str- param compression_level:
Zlib compression level passed to imwrite(…). Default is 3.
- type compression_level:
int- param relative_path:
Optional relative subfolder under the output parent directory where OME TIFFs are written. Default is “omio_converted”.
- type relative_path:
Optional[str]- param overwrite:
Control overwriting behavior for existing outputs. Default is False.
- type overwrite:
bool- param return_fnames:
If True, return the list of written OME TIFF filenames. Default is False.
- type return_fnames:
bool- param cleanup_cache:
Remove .omio_cache entries after writing when Zarr output was used. Default is True.
- type cleanup_cache:
bool- param verbose:
Print diagnostic progress messages. Default is True.
- type verbose:
bool- returns:
If return_fnames=True, returns a list of output OME TIFF paths. Otherwise returns None.
- rtype:
Optional[List[str]]- raises ValueError:
If invalid merge options are provided.
- raises FileNotFoundError:
If an input file does not exist.
- raises Other exceptions:
Reader and writer errors may propagate during I O or metadata handling.
- omio.omio.bids_batch_convert(fname, sub, exp, exp_match_mode='startswith', tagfolder=None, merge_multiple_files_in_folder=False, merge_tagfolders=False, merge_along_axis='T', collapse_ome_multifile_series=True, zeropadding=True, zarr_store=None, recursive=False, physicalsize_xyz=None, pixelunit='micron', compression_level=3, relative_path='omio_converted', overwrite=False, cleanup_cache=True, return_fnames=False, verbose=True)[source]
Batch converter for a BIDS-like directory tree.
This function traverses a project root folder and converts image files found in a subject and experiment hierarchy into OME-TIFF using OMIO’s reader and writer. It supports two main discovery modes: direct conversion of image files located inside experiment folders, or conversion and optional merging of tagged subfolders (folder-stacks) inside experiment folders.
Abstract expected folder scheme
The converter expects a project root that contains subject folders, which in turn contain experiment folders. Depending on whether tagfolder is provided, an experiment folder either contains image files directly, or contains multiple tagfolders which contain the image files.
The schematic below uses
<...>as placeholders for your chosen naming policy:project_root (= fname) ├─ <sub*> │ ├─ <exp*> │ │ ├─ image_01.tif / image_01.ome.tif / image_01.lsm / image_01.czi / image_01.raw │ ├─ <exp*> │ │ ├─ image_01.tif / image_01.ome.tif / image_01.lsm / image_01.czi / image_01.raw │ │ ├─ image_02.tif / image_02.ome.tif / image_02.lsm / image_02.czi / image_02.raw │ │ └─ ... │ ├─ <exp*> │ │ ├─ <tagfolder*>01 │ │ │ ├─ image_01.tif / image_01.czi / image_01.raw / ... │ │ │ └─ ... │ │ ├─ <tagfolder*>02 │ │ │ ├─ image_02.tif / image_02.czi / image_02.raw / ... │ │ │ └─ ... │ │ └─ ... │ └─ ... └─ <sub*> └─ ...
Where:
<sub*>are subject folders detected by prefix matching withsub. For example, ifsub="sub", then"sub-01","sub01","sub_01", and"sub-A"all match, because this function usesstartswith(sub)only.<exp*>are experiment folders detected within each subject folder viaexpandexp_match_mode("startswith","exact", or"regex").<tagfolder*>are optional tagfolders detected within an experiment folder via prefix matching withtagfolder(for example"TAG_"). Iftagfolderis set, direct image files in<exp*>are ignored and only tagfolders are processed.
Folder discovery and selection
The input
fnamemust be a directory and is treated as the project root.Subject detection:
Every immediate subdirectory of
fnamewhose name starts withsubis treated as a subject folder. No additional validation is performed.
Experiment detection:
Within each subject folder, every immediate subdirectory whose name matches
expunderexp_match_modeis treated as an experiment folder. Matching modes are:"startswith": folder name starts withexp"exact": folder name equalsexp"regex":re.match(exp, foldername)succeeds
Conversion behavior inside each experiment folder
Two mutually exclusive modes exist depending on tagfolder.
Mode A: tagfolder is None (direct file conversion):
The converter processes image files located directly in the experiment folder.
If
merge_multiple_files_in_folder=False, every supported image file is converted to its own OME-TIFF output.If
merge_multiple_files_in_folder=True, all supported image files in the experiment folder are read and concatenated alongmerge_along_axis(with optionalzeropaddingon non-merge axes) into one merged output.
Mode B: tagfolder is not None (tagged folder stacks):
Direct image files in the experiment folder are ignored.
The converter searches for tagfolders inside the experiment folder whose name starts with
tagfolder(for example"TAG_").If
merge_tagfolders=False(default), each tagfolder is converted separately and produces its own OME-TIFF output.If
merge_tagfolders=True, all tagfolders are read and merged into a single output by reusing OMIO’s folder-stack logic. To keep output naming stable and collision-free when provenance-driven naming is used, a synthetic provenance name is injected intometadata["Annotations"]["original_filename"].
Input path semantics
Only directory input is accepted:
fnamemust be an existing directory and is treated as the project root.All outputs are written within the experiment scope determined by traversal.
Output placement and naming
Output placement follows OMIO’s writer conventions via
imconvert()andimwrite():If
relative_pathis not None, outputs are written into a subfolder namedrelative_pathunder the relevant experiment folder (or under the experiment folder when writing a merged tagfolder product).If
relative_pathis None, outputs are written directly into the experiment folder.Per-stack output basenames are preferably derived from metadata provenance via
Annotations["original_filename"]when present. Otherwise, a fallback basename is derived from the corresponding folder name.If
overwrite=False, name collisions are resolved by appending an incrementing suffix to the output filename.
Merging semantics
merge_along_axismust be one of {“T”,”Z”,”C”}.In merge operations, the merge axis segments are concatenated in discovery order.
If
zeropadding=True, non-merge axes may differ between inputs and will be padded with zeros to the maximum size across inputs before concatenation.If
zeropadding=False, non-merge axes must match exactly or the merge is aborted.
Zarr and cache handling
zarr_storecontrols whether intermediate data are represented as NumPy in RAM or as Zarr arrays (“memory” or “disk”) during reading and merging.If
cleanup_cache=Trueandzarr_storeis not None, the function removes the per-input .omio_cache artifacts created during conversion once outputs are written.
- param fname:
Project root directory (must exist).
- type fname:
str- param sub:
Prefix used to detect subject folders at the project root level.
- type sub:
str- param exp:
Pattern used to detect experiment folders within each subject.
- type exp:
str- param exp_match_mode:
Matching strategy for experiment folder selection.
- type exp_match_mode:
str- param tagfolder:
If None, convert direct files in experiment folders. If set, only process tagged subfolders inside experiment folders whose names start with tagfolder.
- type tagfolder:
str|None- param merge_multiple_files_in_folder:
If tagfolder is None, optionally merge all image files in an experiment folder into a single output.
- type merge_multiple_files_in_folder:
bool- param merge_tagfolders:
If tagfolder is set, optionally merge all detected tagfolders into a single output.
- type merge_tagfolders:
bool- param merge_along_axis:
Axis along which merges are performed.
- type merge_along_axis:
str- param collapse_ome_multifile_series:
If True, detect and collapse OME multifile series during reading to avoid duplicate loading.
- type collapse_ome_multifile_series:
bool- param zeropadding:
If True, allow mismatched non-merge axes by padding with zeros before merging.
- type zeropadding:
bool- param zarr_store:
Intermediate representation for reading and merging.
- type zarr_store:
str|None- param recursive:
Passed through to the underlying folder readers for file discovery.
- type recursive:
bool- type physicalsize_xyz:
tuple or None
- param physicalsize_xyz:
Optional override for physical voxel sizes.
- type physicalsize_xyz:
tuple or None
- param pixelunit:
Unit string for pixel size fields (default “micron”).
- type pixelunit:
str- param compression_level:
zlib compression level for OME-TIFF writing.
- type compression_level:
int- param relative_path:
Subfolder name for outputs under experiment folders. Default “omio_converted”.
- type relative_path:
str|None- param overwrite:
If True, existing output files may be overwritten. Otherwise, collision-safe suffixing is used.
- type overwrite:
bool- param cleanup_cache:
If True, remove .omio_cache artifacts created during conversion.
- type cleanup_cache:
bool- param return_fnames:
If True, return a list of all written output filenames.
- type return_fnames:
bool- param verbose:
If True, print progress and diagnostic messages.
- type verbose:
bool- returns:
If return_fnames=True, returns a list of written OME-TIFF file paths. Otherwise returns None. The list may be empty if nothing matched or all conversions failed.
- rtype:
list[str] or None
Checks and utilities
API functions for miscellaneous checks and utilities, including the napari viewer opener:
- omio.omio.hello_world()[source]
Print a simple sanity-check message including the current OMIO version.
This function is intended as a minimal diagnostic utility to verify that the OMIO package can be imported correctly, that external dependencies are resolved, and that the module-level version variable is accessible at runtime. It has no return value and produces output only via standard output.
Side effects
- Prints a message of the form:
“Hello from omio.py! OMIO version: <version>”
- omio.omio.OME_metadata_checkup(metadata, namespace='omio:metadata', verbose=True)[source]
Normalize metadata by collecting non-core entries into an OME Annotations block.
This function performs a post-hoc cleanup of a metadata dictionary by separating core OME-compatible fields from auxiliary or tool-specific metadata. All non-core keys that are not explicitly retained at the top level are moved into a single
"Annotations"dictionary, which is suitable for serialization as an OMEMapAnnotationblock.The input metadata dictionary is not modified in place; all operations are performed on a shallow copy.
- Parameters:
metadata (
dict) – Input metadata dictionary.namespace (
str) – Namespace identifier to be stored underAnnotations["Namespace"]. Default is"omio:metadata".
- Returns:
md – Normalized metadata dictionary in which auxiliary fields have been moved into an
"Annotations"entry.- Return type:
dict
Notes
Core OME-like keys (for example physical sizes, time increment, and axis declarations) remain at the top level.
Selected non-OME but operationally useful keys (such as
Size*entries,shape, andChannel_Count) are explicitly retained at the top level.All remaining keys are transferred into
Annotations.Existing annotations are preserved and extended. The namespace is always set or overwritten with the provided value.
Keys starting with
"original_"in an existingAnnotationsblock are protected from being overwritten.
- omio.omio.cleanup_omio_cache(fname, full_cleanup=False, verbose=True)[source]
Remove OMIO-generated on-disk cache data under the .omio_cache folder.
This utility deletes Zarr stores created by OMIO when reading files with
zarr_store="disk". The cache is expected to live in a hidden subfolder.omio_cachewithin a dataset’s parent directory.Two modes are supported:
Targeted cleanup: If
fnameis a file path andfull_cleanupis False, only the corresponding cache store.omio_cache/<basename>.zarris removed.Full cleanup: If
full_cleanupis True, or iffnamepoints to a directory, the entire.omio_cachefolder under that directory is removed.
- Parameters:
fname (str) – Path to a file whose cache should be removed, or a directory containing an
.omio_cachefolder to be cleaned.full_cleanup (bool, optional) – If True, delete the entire
.omio_cachefolder. If False andfnameis a file, delete only the cache store corresponding to that file’s basename. Default is False.verbose (bool, optional) – If True, print diagnostic messages. Default is True.
- Return type:
None
- Raises:
ValueError – If fname is neither an existing file nor an existing directory.
Notes
Cache deletion is performed via recursive directory removal and is not reversible.
If no
.omio_cachefolder exists at the expected location, the function returns without error.
- omio.omio.open_in_napari(images, metadatas, fname, zarr_mode='numpy', cache_folder_name='.omio_cache', axes_full='TZCYX', viewer=None, returns=False, verbose=True)[source]
Open or extend a Napari viewer with one or multiple OMIO images.
This is the main Napari convenience wrapper exposed to users. It accepts a single image or a sequence of images together with matching metadata objects, and adds each dataset as a Napari image layer by delegating per-image handling to
_single_image_open_in_napari.Input images may be NumPy arrays or Zarr arrays. For Zarr inputs, the behavior is controlled by zarr_mode and follows the same strategies implemented in
_single_image_open_in_napari(full materialization to NumPy, creation of a squeezed cache Zarr without Dask, or creation of a squeezed cache Zarr with Dask). A single viewer instance is reused across all layers.- Parameters:
images (
Union[ndarray,Array,list[Union[ndarray,Array]]]) – Image data to visualize. If a single array is provided, it is treated as a one-element list. Each image is expected to be consistent with axes_full before squeezing (for example already normalized by_correct_for_OME_axes_order).metadatas (
Union[dict,list[dict]]) – Metadata dictionaries corresponding to images. If a single dict is provided, it is treated as a one-element list. Each metadata dict should provide the physical voxel sizes used for Napari scaling (typicallyPhysicalSizeX,PhysicalSizeY,PhysicalSizeZ) and optionally a unit string underunit.fname (
str) – Base name used for Napari layer naming and cache path construction. If multiple images are provided, an_idx{n}suffix is appended.zarr_mode (
str) – Strategy for handling Zarr inputs, forwarded to_single_image_open_in_napari. Default is"numpy".cache_folder_name (
str) – Name of the cache folder used for derived Zarr stores. Default is".omio_cache".axes_full (
str) – Full axis string describing the expected axis order of the input images before squeezing. Default is"TZCYX".viewer (
Viewer) – Existing Napari viewer to reuse. If None, a current viewer is reused if available, otherwise a new viewer is created (via the single-image helper).returns (
bool) – If True, return detailed objects (viewer, layers, napari_datas, napari_axess). If False, the function returns None. Default is False.verbose (
bool) – If True, print diagnostic progress messages. Default is True.
- Returns:
viewer (napari.Viewer) – The Napari viewer that was used or created. Only returned if returns=True.
layers (list of napari.layers.Image) – The image layers added to the viewer, one per input image. Only returned if returns=True.
napari_datas (list of (np.ndarray or dask.array.Array)) – The data objects passed to Napari for each layer (Zarr inputs are typically converted to Dask arrays in the single-image helper). Only returned if returns=True.
napari_axess (list of str) – Axis strings corresponding to each entry in napari_datas after squeezing. Only returned if returns=True.
- Raises:
ValueError – If the number of images does not match the number of metadata dictionaries.
Notes
This function does not perform axis normalization itself. It assumes that inputs already follow OMIO’s canonical axis convention as declared by
axes_full, and delegates squeezing, channel-axis inference, and scaling to_single_image_open_in_napari.When multiple images are opened, the layer name is derived from
fnamewith a simple index suffix; if more informative naming is desired, pass a distinctfnameper call or use theviewer_namemechanism in the single-image helper.
Readers
API functions to currently implemented image files readers:
- omio.omio.read_tif(fname, physicalsize_xyz=None, pixelunit='micron', zarr_store=None, return_list=False, verbose=True)[source]
Read TIFF family files into OMIO’s canonical representation.
This function reads TIFF, OME-TIFF, multi file OME-TIFF series, and Zeiss LSM files using tifffile, extracts available metadata (OME-XML, ImageJ metadata, and LSM metadata), standardizes metadata keys, and normalizes axis handling to canonical OME order TZCYX. Depending on configuration, the returned image is either a NumPy array in RAM or a Zarr array backed by an in-memory or on-disk store.
If the input is a paginated TIFF or LSM (axis “P”), OMIO splits the dataset into individual pages and returns a list of images together with a list of matching metadata dictionaries. In that case, lists are returned regardless of return_list, because a single object return would be semantically ambiguous.
- Parameters:
fname (str) – Path to the input file. Note: read_tif is the core function for TIF and LSM file reading; omio.read() dispatches to this function when encountering a .tif or .lsm file. read_tif can only handle TIF and LSM files but no folder paths (for this, please use read_thorlabs_raw_folder).
physicalsize_xyz (tuple of float or None, optional) – Manual override for voxel sizes in the order
(PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ). If provided, these values override metadata-derived sizes. If None, missing sizes fall back to 1.0. Default is None.pixelunit (str, optional) – Unit string used for pixel size fields and unit normalization. Default is
"micron".zarr_store ({None, "memory", "disk"}, optional) –
Controls the representation of the returned image data.
None: load fully into RAM and return a NumPy array
”memory”: return a Zarr array backed by an in-memory store
”disk”: return a Zarr array stored in the cache folder
{parent}/.omio_cache/<basename>.zarr
Default is None.
return_list (bool, optional) – If True, force backward-compatible list return for non-paginated inputs by returning
[image]and[metadata]. Default is False.verbose (bool, optional) – If True, print diagnostic progress messages. Default is True.
- Returns:
image (np.ndarray or zarr.core.array.Array or list) – Image data in canonical OME axis order TZCYX. For paginated inputs, a list of per-page arrays is returned.
metadata (dict or list) – Metadata dictionary aligned with the returned image. For paginated inputs, a list of per-page metadata dictionaries is returned.
- Raises:
ValueError – If zarr_store is not one of {None, “memory”, “disk”}.
Notes
Metadata sources are merged in the order they are read. Missing essentials are filled from the image shape and default values.
Unit normalization updates unit fields only. Numerical unit conversion is not performed except for specific paginated LSM cases where Zeiss voxel sizes are converted from meters to micrometers.
If zarr_store is not None, tifffile’s
aszarr=Truepath is used and then materialized into a concrete Zarr store to ensure predictable downstream behavior. Data transfer uses slice-wise copying over the last two spatial dimensions to limit peak memory use.Axis normalization to TZCYX may insert singleton dimensions for missing OME axes and may reorder existing axes. The updated axis string is stored in the returned metadata.
When zarr_store=”disk”, the function may create and overwrite paths under
.omio_cache.Multi-file OME-TIFF series are supported. In this layout, individual OME-TIFF files each store subsets of the full dataset (e.g. single time points, channels, or z-slices). OMIO/tifffile reconstructs the complete logical image by following the OME-XML metadata references across files. It is therefore sufficient to pass the path of a single file belonging to the series; all referenced files are discovered and read implicitly. The resulting image is returned as a contiguous and complete stack in canonical OME axis order.
General note on series and pages
TIFF family containers can store data in two different structural layers that are easy to confuse:
Series are top level image datasets within a container. Each series can have its own dimensionality, axis semantics, pixel type, and metadata context. In tifffile, these are exposed via tif.series.
Pages are the lower level IFD entries that physically store image planes or tiles. Depending on the file layout, pages can represent planes along Z, C, or T, pyramid levels, tiles, or other internal subdivisions. In tifffile, these are exposed via tif.pages.
In many microscopy TIFF variants, tifffile reconstructs a logical N dimensional array for a series by reading and stacking its pages. The exact mapping depends on the file and on tifffile’s internal interpretation of the container structure. OMIO therefore treats tif.series as the authoritative high level grouping and applies explicit, deterministic policies where the container structure could otherwise lead to ambiguous outcomes.
OMIO behavior for paginated files
Some TIFF and LSM files are stored as paginated stacks and expose an explicit pagination axis P in the inferred axis string. OMIO treats pagination as a semantic split into independent image stacks:
If the input is detected as paginated (axis P present), OMIO splits the dataset into per page images and returns images and metadatas as lists with matching length.
Lists are returned regardless of return_list, because a single object return would be semantically ambiguous once pagination is present.
Each returned metadata dictionary corresponds to exactly one page and reflects the page specific axis string with the pagination axis removed.
If zarr_store is set, each page is materialized into its own Zarr array according to the selected backend (memory or disk).
After splitting, OMIO applies axis normalization to each page so that each page is returned in canonical OME axis order.
OMIO restrictions for multi-series TIFF/LSM files
TIFF and LSM containers may store multiple datasets (“series”) in a single file. While tifffile exposes these as tif.series, OMIO enforces a strict and predictable policy to avoid ambiguous interpretations:
If a file contains exactly one series (len(tif.series) == 1), OMIO guarantees correct reading and normalization to canonical OME axis order (TZCYX).
If a file contains multiple series (len(tif.series) > 1), OMIO will process only the first series (series 0) and ignore all others.
A warning is emitted in this case, and the policy decision is recorded in the returned metadata.
OMIO does not attempt to infer relationships between multiple series, does not concatenate them, and does not inspect their shapes, axes, or photometric interpretation beyond series 0.
This policy is intentional and favors reproducibility and explicit behavior over heuristic reconstruction of complex TIFF layouts.
- omio.omio.read_czi(fname, physicalsize_xyz=None, pixelunit='micron', zarr_store=None, return_list=False, verbose=True)[source]
Read Zeiss CZI files into OMIO’s canonical representation.
This function reads a Zeiss CZI file using czifile, extracts basic acquisition metadata, filters and normalizes axes to the canonical OME axis convention TZCYX, and optionally materializes the result as a Zarr array backed by an in-memory store or an on-disk cache.
CZI pixel data are always read fully into RAM first, because lazy, memory-mapped reading is not supported in this code path. Optional Zarr export therefore represents an explicit post-read materialization step for downstream workflows that benefit from chunked access or reduced peak RAM usage in later stages.
- Parameters:
fname (str) – Path to the CZI file. Note: read_czi is the core function for Zeiss CZI file reading; omio.read() dispatches to this function when encountering a .czi file. read_czi can only handle RAW files but no folder paths (for this, please use read_thorlabs_raw_folder).
physicalsize_xyz (tuple of float or None, optional) – Manual override for voxel sizes in the order
(PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ). If provided, these values override metadata-derived sizes. If None, missing or invalid sizes fall back to 1.0. Default is None.pixelunit (str, optional) – Unit string used for pixel size fields and unit normalization. Default is
"micron".zarr_store ({None, "memory", "disk"}, optional) –
Controls the representation of the returned image data.
None: return a NumPy array in RAM
”memory”: return a Zarr array backed by an in-memory store
”disk”: return a Zarr array stored in the cache folder
{parent}/.omio_cache/<basename>.zarr
Existing on-disk stores at that location are replaced. Default is None.
return_list (bool, optional) – If True, return
[image]and[metadata]for backward compatibility. Default is False.verbose (bool, optional) – If True, print diagnostic progress messages. Default is True.
- Returns:
image (np.ndarray or zarr.core.array.Array) – Image data in canonical OME axis order TZCYX. If zarr_store is not None, the returned object is a Zarr array.
metadata (dict) – Metadata dictionary aligned with the returned image, including axis and size information and an
Annotationsblock for non-core fields.
- Raises:
ValueError – If zarr_store is not one of {None, “memory”, “disk”}.
Notes
Non-OME axes present in CZI files (for example B, V, or trailing singleton axes) are collapsed by indexing at 0 so that only OME-relevant axes remain. The resulting axis string is updated accordingly.
Physical voxel sizes are extracted from the CZI scaling metadata and converted to micrometer units using a fixed conversion factor. If values are missing or non-positive, they fall back to 1.0.
Axis reordering to TZCYX may insert singleton dimensions for missing OME axes and may permute existing axes. The updated axis declaration is stored in the returned metadata.
When zarr_store=”disk”, the function may create and overwrite paths under
.omio_cache.
- omio.omio.read_thorlabs_raw(fname, physicalsize_xyz=None, pixelunit='micron', zarr_store=None, return_list=False, verbose=True)[source]
Read Thorlabs RAW files into OMIO’s canonical representation.
This function reads a Thorlabs RAW file and constructs an image array together with an OMIO metadata dictionary that follows the canonical OME axis convention TZCYX. Dimensions and acquisition metadata are obtained from an accompanying XML file in the same folder. If no XML is present, the function falls back to a single YAML metadata file located in the same folder.
The RAW payload is interpreted as a contiguous raster of pixel values that must be reshaped into a 5D stack
(T, Z, C, Y, X). If requested, the data are materialized into a Zarr array either in memory or on disk. For Zarr output, copying is performed slice-wise over the last two spatial dimensions to limit peak RAM usage.YAML fallback in case of missing XML
In case no XML metadata file is found, the function looks for a YAML file in the same folder. If found, it extracts the necessary dimensions and pixel size information from the YAML keys
T,Z,C,Y,X,bits,PhysicalSizeX,PhysicalSizeY,PhysicalSizeZ, andpixelunit.The YAML file is not generated automatically by OMIO; it must be created manually if no XML is available.
An example YAML file might look like this: .. code-block:: yaml
T: 1 Z: 10 C: 3 Y: 512 X: 512 bits: 16 PhysicalSizeX: 0.65 PhysicalSizeY: 0.65 PhysicalSizeZ: 2.0 pixelunit: micron
Saved as e.g.
image_metadata.yamlin the same folder as the RAW file, this file allows read_thorlabs_raw to successfully interpret the RAW pixel.OMIO offers a utility function to help create such YAML files:
omio.utilities.create_thorlabs_raw_yaml(), which prompts the user for the necessary parameters and writes the YAML file (or takes defaults).Note: The values entered in the YAML file must match the actual RAW data size. I.e., the user must know the correct dimensions and bit depth in advance.
If neither XML nor YAML metadata is available, the function does not raise an exception. Instead, it emits a warning and returns
(None, None)or([None], [None])depending on return_list.- type fname:
str
- param fname:
Path to the RAW file. Note: the function expects an XML or YAML metadata file to be present in the same folder. Also: read_thorlabs_raw is the core function for Thorlabs RAW reading; omio.read() dispatches to this function when encountering a .raw file. read_thorlabs_raw can only handle RAW files but no folder paths (for this, please use read_thorlabs_raw_folder).
- type fname:
str
- type physicalsize_xyz:
tuple of float or None, optional
- param physicalsize_xyz:
Manual override for voxel sizes in the order
(PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ). If provided, these values override XML or YAML values. Default is None.- type physicalsize_xyz:
tuple of float or None, optional
- type pixelunit:
str, optional
- param pixelunit:
Default unit string used when neither XML nor YAML provides a unit. Default is
"micron".- type pixelunit:
str, optional
- type zarr_store:
{None, “memory”, “disk”}, optional
- param zarr_store:
Controls the representation of the returned image data.
None: read and return a NumPy array in RAM
“memory”: return a Zarr array backed by an in-memory store
“disk”: return a Zarr array stored in the cache folder
{parent}/.omio_cache/<basename>.zarr
Existing on-disk stores at that location are replaced. Default is None.
- type zarr_store:
{None, “memory”, “disk”}, optional
- type return_list:
bool, optional
- param return_list:
If True, return
[image]and[metadata]for backward compatibility. Default is False.- type return_list:
bool, optional
- type verbose:
bool, optional
- param verbose:
If True, print diagnostic progress messages. Default is True.
- type verbose:
bool, optional
- returns:
image (np.ndarray or zarr.core.array.Array or None) – Image data in canonical OME axis order TZCYX, or None if dimensions cannot be inferred from XML or YAML.
metadata (dict or None) – Metadata dictionary aligned with the returned image, or None if metadata is unavailable. The dictionary includes an
Annotationsblock for auxiliary fields when reading succeeds.
- raises ValueError:
If zarr_store is not one of {None, “memory”, “disk”}, or if an XML file is present but incomplete or inconsistent.
- raises FileNotFoundError:
If fname does not exist.
- raises ImportError:
If zarr_store is “memory” or “disk” but Zarr support is unavailable.
Notes
RAW reading requires the dimensions T, Z, C, Y, X and a bit depth to infer the dtype and reshape the pixel stream. XML metadata is preferred. YAML is used only if XML is absent.
YAML fallback expects at minimum the keys
T,Z,C,Y,X, andbits. Additional keys such aspixelunit,PhysicalSizeX/Y/Z, andTimeIncrementare optional.For zarr_store not None, the function uses
numpy.memmapand slice-wise copying to avoid loading the full RAW into RAM before writing.Axis normalization to TZCYX is applied at the end and may insert singleton dimensions or reorder axes. The updated axis string and shape are stored in the returned metadata.
When zarr_store=”disk”, the function may create and overwrite paths under
.omio_cache.
Metadata and image helpers
API functions to create empty metadata/image structures and to update metadata from image data:
- omio.omio.create_empty_metadata(physicalsize_xyz=None, pixelunit='micron', time_increment=None, time_increment_unit=None, shape=None, annotations=None, input_metadata=None, verbose=True)[source]
Create a new OMIO metadata dictionary populated with canonical default keys.
This factory returns a metadata dictionary that follows OMIO’s OME-oriented key conventions and provides a complete set of standard fields with safe default values. It is intended as a starting point for downstream routines that progressively refine metadata, for example by filling sizes from image data or merging acquisition metadata from files.
The returned dictionary always includes:
canonical axis declaration under
"axes"(typically TZCYX),shape and per-axis size fields (
shape,SizeT,SizeZ,SizeC,SizeY,SizeX),physical voxel sizes and time sampling (
PhysicalSize*,TimeIncrement,TimeIncrementUnit),a unit field (
unit),an
Annotationsmapping for auxiliary fields,the current OMIO version identifier under
_OMIO_VERSION.
User-provided values can be injected via input_metadata, overridden via dedicated arguments, and merged into the
Annotationsblock. Finally, the metadata are normalized via OME_metadata_checkup to ensure that non-core entries are moved intoAnnotationsand a namespace entry is present.- Parameters:
physicalsize_xyz (
Optional[tuple[float,float,float]]) – Optional voxel size override in the order(PhysicalSizeX, PhysicalSizeY, PhysicalSizeZ). If provided, these values overwrite the defaults and any corresponding entries from input_metadata.pixelunit (
str) – Unit string for pixel sizes. Common micrometer spellings are normalized to the symbol"µm"in the returned dictionary. Default is"micron".time_increment (
Optional[float]) – Optional override forTimeIncrement. If None, the default value is used.time_increment_unit (
str) – Optional override forTimeIncrementUnit. If None, the default value is used.shape (
Optional[tuple[int,int,int,int,int]]) – Optional 5D shape tuple in canonical order(T, Z, C, Y, X). If provided,shapeand the correspondingSize*fields are set consistently. If the tuple does not have length 5, a warning is issued and the shape is not set.annotations (
dict|None) – Additional key value pairs to merge into theAnnotationsblock.input_metadata (
dict|None) – Existing metadata dictionary whose entries are merged into the returned dictionary prior to applying explicit overrides.verbose (
bool) – If True, enable diagnostic messages from downstream normalization steps. Default is True.
- Returns:
md – A normalized OMIO metadata dictionary containing canonical keys and user overrides, with auxiliary fields stored under
Annotations.- Return type:
dict
Notes
The function constructs a new dictionary and does not modify input_metadata in place, but if input_metadata[“Annotations”] is a dictionary it may be reused and updated during merging.
The default axis string is taken from the module-level constant
_OME_AXES, and size indices are derived from_AXIS_TO_INDEX.Final normalization is performed by OME_metadata_checkup, which may move non-core fields into
Annotationsand enforce an annotations namespace.
- omio.omio.create_empty_image(shape=(1, 1, 1, 1, 1), dtype=<class 'numpy.uint16'>, fill_value=0, zarr_store=None, zarr_store_path=None, zarr_store_name=None, return_metadata=False, input_metadata=None, verbose=True)[source]
Create an empty 5D image in canonical OME axis order TZCYX.
This factory creates a new image container with shape
(T, Z, C, Y, X)and a specified dtype, either as a NumPy array in RAM or as a Zarr array backed by an in-memory store or an on-disk cache. Optionally, it also returns a matching OMIO metadata dictionary consistent with the created image.For Zarr output, chunking is determined via compute_default_chunks using the canonical OME axes. When writing to disk, the array is created under a hidden cache folder
.omio_cachelocated in the specified parent directory. Any existing store at the target path is replaced.- Parameters:
shape (
tuple[int,int,int,int,int]) – Desired image shape as a 5-tuple(T, Z, C, Y, X). Default is(1, 1, 1, 1, 1). If shape is None or does not have length 5, a warning is issued and the function returns None (or(None, None)if return_metadata is True).dtype (numpy dtype, optional) – Data type of the created array. Default is
np.uint16.fill_value (scalar or None, optional) – Value used to initialize the array. If 0 and zarr_store is None, a zero-initialized NumPy array is created via np.zeros. If fill_value is None for Zarr output, the array is left uninitialized. Default is 0.
zarr_store (
Optional[str]) –Storage backend for the created image.
None: return a NumPy array in RAM
”memory”: return a Zarr array backed by a zarr.storage.MemoryStore
”disk”: return a Zarr array stored under
.omio_cacheon disk
Default is None.
zarr_store_path (
Optional[str]) – Path used to determine the parent directory for on-disk storage when zarr_store=”disk”. If this is a directory, it is used directly. If it is a file path, its parent directory is used. Required for zarr_store=”disk”.zarr_store_name (
Optional[str]) – Basename used for the on-disk Zarr store when zarr_store=”disk”. The final store path is<parent>/.omio_cache/<zarr_store_name>.zarr. Required for zarr_store=”disk”.return_metadata (
bool) – If True, return a tuple(image, metadata)where metadata is created by create_empty_metadata and is consistent with shape. Default is False.input_metadata (
Optional[dict]) – Optional metadata dictionary merged into the generated metadata when return_metadata is True. Default is None.verbose (
bool) – If True, print diagnostic messages for some path handling cases. Default is True.
- Return type:
Union[None,ndarray,Array,tuple[ndarray,dict],tuple[Array,dict]]- Returns:
image (np.ndarray or zarr.core.array.Array or None) – The created image container. Returns None if validation fails.
metadata (dict, optional) – Only returned when return_metadata is True. The metadata dictionary is consistent with the created image shape and canonical axes TZCYX.
Notes
The function assumes canonical OME axes TZCYX as defined by the module-level constant
_OME_AXES.For zarr_store=”disk”, any existing store at the target location is removed before creating a new one.
Chunking is delegated to compute_default_chunks. For very small arrays, chunk sizes may match the full dimensions.
- omio.omio.update_metadata_from_image(metadata, image, run_checkup=True, verbose=True)[source]
Update size-related metadata fields from a 5D image in canonical OME order.
This helper synchronizes a metadata dictionary with the shape of a provided image array. It enforces OMIO’s canonical axis convention TZCYX, reads the image shape, stores it under
"shape", and updates the correspondingSize*fields (SizeT,SizeZ,SizeC,SizeY,SizeX).Optionally, the result is normalized via OME_metadata_checkup, which collects non-core fields into
Annotationsand enforces the annotations namespace.- Parameters:
metadata (
dict) – Input metadata dictionary to update. If None, an empty dictionary is used.image (
Union[ndarray,Array]) – Image array whose shape defines the updated metadata. The image must be 5D and already in canonical axis order TZCYX.run_checkup (
bool) – If True, run OME_metadata_checkup on the updated metadata. Default is True.verbose (
bool) – If True, enable diagnostic messages from the normalization step. Default is True.
- Returns:
md – Updated metadata dictionary with consistent
axes,shape, andSize*fields.- Return type:
dict- Raises:
ValueError – If the provided image is not 5D, since OMIO expects canonical order TZCYX.
Notes
The function enforces
md["axes"] = _OME_AXESunconditionally. It does not attempt to infer axes from the input metadata.The input dictionary is copied; updates are applied to a new dictionary and the original metadata is not modified in place.