Load planes in Python
Use this when you want pixels, table rows or trace samples as NumPy arrays in your own script or notebook. The openreadout package reads files with the same Rust code as the command line, so it gives the same numbers, and it needs no vendor software and no Java.
Run it
pip install openreadoutThe package does not install the openreadout command; for that, see Install.
import openreadout
with openreadout.File("mini.nd2") as f: f.format # 'nd2' len(f.images) # how many images (CZI scenes, ND2 positions, LIF series) f.images[0]["channels"][0]["name"] # 'DAPI' f.dims(0), f.shape(0), f.dtype(0) # ('TCZYX', (2, 1, 1, 8, 8), dtype('uint16')) plane = f.read_plane(image=0, c=0, z=0, t=1) # NumPy array, shape (8, 8)mini.nd2 is a small Nikon file in the repository at crates/openreadout-cli/tests/fixtures/mini.nd2. The values in the comments are the ones the Python guide shows for it.
What it tells you
openreadout.Filedetects the format from the file’s signature, not its extension. Use it as a context manager so the file handle is closed promptly.f.imagesis a list of dicts with the same keys asopenreadout info --json:size_x,size_c,physical_size,channels,objectiveand the rest. See Reading the JSON output.- Every image array has the axes
T, C, Z, Y, X, the same order bioio uses. Interleaved RGB images have a sixth axis,S. read_planedecodes one plane and returns an array shaped(Y, X), or(Y, X, S)for RGB, in the file’s data type.read_image(i)reads the whole image into one(T, C, Z, Y, X)array, so keep it for small images.- Errors are exceptions derived from
openreadout.OpenReadoutError, with the samecode,exit_codeandhintas the command line. A damaged plane raisesCorruptFileError.
Variations
Tables and traces
FCS events, plate-reader values and spike tables are tables. Electrophysiology sweeps, chromatograms and spectra are traces. Both come back as float64 arrays:
with openreadout.File("tube1.fcs") as f: [c["name"] for c in f.tables[0]["columns"]] # the $PnN parameter names events = f.read_table(0) # (events, parameters)
with openreadout.File("synthetic-timeseries.nwb") as f: y = f.read_trace(2) # (channels, samples): (2, 1000)Table values are raw: not compensated and not scaled. Trace values are in each channel’s unit, f.traces[i]["channels"][c]["unit"]. read_trace also takes sweep=, first_sample=, max_samples= and channel=.
Large images
For anything that does not fit in memory, use a lazy array, which decodes planes only when they are needed. This needs pip install 'openreadout[xarray]':
with openreadout.File("run.czi") as f: lazy = f.to_dask(0) # one chunk per plane stack = f.get_image_data("ZYX", image=0, T=0, C=1) # decodes only those planes window = f.read_plane(0, region=(0, 0, 512, 512)) # x, y, width, heightregion= works on whole-slide images and other pyramids too; tiled formats decode only the tiles it touches. f.levels(0) lists the pyramid levels, and level= picks one.
bioio
If your code already uses BioImage, install the plugin instead:
pip install bioio bioio-openreadoutfrom bioio import BioImageimport bioio_openreadout
img = BioImage("run42.nd2", reader=bioio_openreadout.Reader)img.scenes, img.dims, img.channel_names, img.physical_pixel_sizesstack = img.get_image_dask_data("ZYX", T=0, C=1).compute()For .czi, .nd2, .lif, .vsi, .svs, .ndpi, .qptiff, .ims, .oir, .oib, .oif and .zvi, BioImage(path) finds the plugin without reader=. The plugin reads local files only.
napari
pip install napari napari-openreadoutnapari run.cziEach image opens as its own layers, one per channel, scaled in micrometres and read lazily. Whole-slide images open as multiscale layers.
More
- Python: the whole package, including Arrow and pandas, analyses, export and reading from bytes.
- napari: the plugin, and building layers yourself.
- Reading the JSON output: the metadata keys
f.imagesandf.tablesuse.