Czitools
This repository provides a collection of tools to simplify reading CZI (Carl Zeiss Image) pixel and metadata in Python. In addition it also contains other useful utilities to visualize CZI images inside Napari.
Install / Use
/learn @sebi06/CzitoolsREADME
czitools
This repository provides a collection of tools to simplify reading CZI (Carl Zeiss Image) pixel and metadata in Python. It is available as a Python Package on PyPi
Installation
To install czitools (core functionality) use:
pip install czitools
To install the package with all optional dependencies use::
pip install czitools[all]
Local Installation
Local installation for developing etc.:
pip install -e .
Local installation (full functionality):
pip install -e ".[all]"
Supported Operating Systems
Currently this only works on:
- Linux
- Windows
MacOS is not supported yet out of the box, but if one installs pylibCZIrw wheels for MacOS manually the package should work (not tested).
Thanks to the community for providing MacOS wheels for pylibCZIrw, which makes it possible to read and write CZI files on MacOS.
Reading the metadata
Please check use_metadata_tools.py for some examples.
from czitools.metadata_tools.czi_metadata import CziMetadata, writexml
from czitools.metadata_tools.dimension import CziDimensions
from czitools.metadata_tools.boundingbox import CziBoundingBox
from czitools.metadata_tools.channel import CziChannelInfo
from czitools.metadata_tools.scaling import CziScaling
from czitools.metadata_tools.sample import CziSampleInfo
from czitools.metadata_tools.objective import CziObjectives
from czitools.metadata_tools.microscope import CziMicroscope
from czitools.metadata_tools.add_metadata import CziAddMetaData
from czitools.metadata_tools.detector import CziDetector
from czitools.read_tools import read_tools
try:
import napari
from napari.utils.colormaps import Colormap
show_napari = True
except ImportError:
print("Napari not installed, skipping napari import")
show_napari = False
# get the metadata_tools at once as one big class
mdata = CziMetadata(filepath)
# get only specific metadata_tools
czi_dimensions = CziDimensions(filepath)
print("SizeS: ", czi_dimensions.SizeS)
print("SizeT: ", czi_dimensions.SizeT)
print("SizeZ: ", czi_dimensions.SizeZ)
print("SizeC: ", czi_dimensions.SizeC)
print("SizeY: ", czi_dimensions.SizeY)
print("SizeX: ", czi_dimensions.SizeX)
# try to write XML to file
xmlfile = writexml(filepath)
# get info about the channels
czi_channels = CziChannelInfo(filepath)
# get the complete metadata_tools from the CZI as one big object
czimd_complete = get_metadata_as_object(filepath)
# get an object containing only the dimension information
czi_scale = CziScaling(filepath)
# get an object containing information about the sample
czi_sample = CziSampleInfo(filepath)
# get info about the objective, the microscope and the detectors
czi_objectives = CziObjectives(filepath)
czi_detectors = CziDetector(filepath)
czi_microscope = CziMicroscope(filepath)
# get info about the sample carrier
czi_sample = CziSampleInfo(filepath)
# get additional metainformation
czi_addmd = CziAddMetaData(filepath)
# get the complete data about the bounding boxes
czi_bbox = CziBoundingBox(filepath)
Reading CZI pixel data
While the pylibCZIrw is focussing on reading individual planes it is also helpful to read CZI pixel data as a STCZYX(A) stack. Please check use_read_tools.py for some examples.
# return a dask or numpy array with dimension order STCZYX(A)
array6d, mdata = read_tools.read_6darray(filepath, use_xarray=True)
if show_napari:
# show in napari (requires napari to be installed!)
viewer = napari.Viewer()
# loop over all channels
for ch in range(0, array6d.sizes["C"]):
# extract channel subarray
sub_array = array6d.sel(C=ch)
# get the scaling factors for that channel and adapt Z-axis scaling
scalefactors = [1.0] * len(sub_array.shape)
scalefactors[sub_array.get_axis_num("Z")] = mdata.scale.ratio["zx_sf"]
# remove the last scaling factor in case of an RGB image
if "A" in sub_array.dims:
# remove the A axis from the scaling factors
scalefactors.pop(sub_array.get_axis_num("A"))
# get colors and channel name
chname = mdata.channelinfo.names[ch]
# inside the CZI metadata_tools colors are defined as ARGB hexstring
rgb = "#" + mdata.channelinfo.colors[ch][3:]
ncmap = Colormap(["#000000", rgb], name="cm_" + chname)
# add the channel to the viewer
viewer.add_image(
sub_array,
name=chname,
colormap=ncmap,
blending="additive",
scale=scalefactors,
gamma=0.85,
)
# set the axis labels based on the dimensions
viewer.dims.axis_labels = sub_array.dims
napari.run()
Reading Scene Stacks (read_stacks)
read_stacks supports scene-wise reading with optional stacking:
from czitools.read_tools import read_tools
result, dims, num_stacks, mdata = read_tools.read_stacks(
filepath,
use_dask=True,
use_xarray=True,
stack_scenes=True,
)
Important return behavior:
-
function return signature is
(result, dims, num_stacks, mdata) -
stack_scenes=False: always returns a list (one array per scene) -
stack_scenes=Trueand shapes match: returns one stacked array (withSdim) -
stack_scenes=Trueand shapes differ: returns a list (with warning)
If you prefer strict return contracts for typed code:
read_tools.read_stacks_list(...)always returns a listread_tools.read_stacks_stacked(...)requires stacked output and raisesValueErrorwhen scenes cannot be stacked
Napari Display Helpers
For robust display in Napari (including string channel labels and list-of-stacks results), use the helpers from czitools.utils.napari_tools.
Single array:
from czitools.utils.napari_tools import display_xarray_in_napari
subset_planes = array6d.attrs.get("subset_planes", {})
display_xarray_in_napari(array6d, mdata, subset_planes)
List of stacks (works even if scenes have different shapes):
from czitools.utils.napari_tools import display_xarray_list_in_napari
display_xarray_list_in_napari(result_list, mdata)
Tip: if you only want one stack from a list, select it first:
idx = 0
subset_planes = result_list[idx].attrs.get("subset_planes", {})
display_xarray_in_napari(result_list[idx], mdata, subset_planes)
NDV Viewer Helpers
For NDV visualization workflows, czitools provides small helpers to generate channel LUTs and axis scales directly from CZI metadata:
from czitools.metadata_tools.czi_metadata import CziMetadata
from czitools.utils.ndv_tools import create_luts_ndv, create_scales_ndv
mdata = CziMetadata(filepath)
luts = create_luts_ndv(mdata)
scales = create_scales_ndv(mdata)
These helpers are used by demo/scripts/use_ndv.py and keep color/scale conversion logic in one place.

Colab Notebooks
Read CZI metadata
The basic usage can be inferred from this sample notebook:
Read CZI pixeldata
The basic usage can be inferred from this sample notebook:
Write OME-ZARR from 5D CZI image data
The basic usage can be inferred from this sample notebook:
Write CZI using ZSTD compression
The basic usage can be inferred from this sample notebook:
Show planetable of a CZI image as surface
The basic usage can be inferred from this sample notebook:
Read a CZI and segment using Voronoi-Otsu provided by PyClesperanto GPU processing
The basic usage can be inferred from this sample notebook:
[](https://colab.research.google.com/github/sebi06/cz
