OME_ZARR
Viewing of ome zarr file
Viewing of ome_zarr in a directory or as a zip file.
1.Open Napari with command napari
2.Open the command widget with button at the bottom left corner of the window.
3.After that, type in the command window to invoke functions that add more images as layers.
To view an ome-zarr file this way with cvpl_tools
, use the command
import cvpl_tools.ome_zarr.napari.add as napari_add_ome_zarr
napari_add_ome_zarr.subarray_from_path(viewer, "/absolute/path/to/your/ome.zarr", kwargs=dict(name="displayed_name_in_ui"))
This will create a new layer named displayed_name_in_ui which displays your ome zarr array.
subarray
uses Napari’sadd_image
function’smultiscale
argument for this, which loads different resolution based on viewer’s current zoom factorTo open a .zip file, specify ome.zarr.zip in the path (and optionally set use_zip=True to open the file as zip regardless of its suffix)
To open both the ome.zarr file and any label files located at ome.zarr/labels/label_name as specified by the ome zarr standard, use cvpl_zarr.add_ome_zarr_group_from_path instead.
To specify additional arguments passed to Napari’s add_image function, pass your arguments in the kwargs as a dictionary.
An extra argument
is_label
can be passed into the function viakwargs
dictionary. This is a boolean value that specifies whether to useviewer.add_labels
(ifTrue
) orviewer.add_image
(ifFalse
) function. This is useful for displaying instance segmentaion masks, where each segmented object has a distinct color.
The zip loading feature does not work with remote location on gcs, because of the limitations of ZipStore.
Reading and Writing ome zarr files
Before talking about the read and write, we need to first understand the directory structure of an ome zarr file. A basic ome zarr file (which is what we work with) is a directory that looks like the following:
- image.OME.ZARR/ # The ome zarr image, which is a directory in Windows/Linux
- 0/ # The original image, in ZARR format
+ 0/ # Slice of image at first axis Z=0
+ 1/
...
.zarray # .zarray is meta attribute for the ZARR image
+ 1/ # Downsampled image at downsample level 1, in ZARR format
+ 2/
+ 3/
+ 4/ # The smallest downsampled image at level 4, in ZARR format
.zattrs # .zattrs and .zgroup are meta attributes for the ome zarr image
.zgroup
Above + denotes collapsed folder and - denotes expanded folder. A few things to note here:
An image does not have to end with .OME.ZARR suffix
The image is not multiscaled if the maximum downsample level is 0 instead of 4, in which case there will only be one 0/ folder
An ome zarr image is easily confused with a ZARR image. An ome zarr image is not a standard ZARR directory and contains no .zarray meta file. Loading an ome zarr image as ZARR will crash if you forget to specify 0/ subfolder as the path to load
When saved as a zip file instead of a directory, the directory structure is the same except that the root is zipped. Loading a zipped ome zarr, cvpl_tools uses
ZipStore
’s features to directly reading individual chunks without having to unpack the entire zip file. However, writing to aZipStore
is not supported, due to lack of support by either Python’szarr
or theome-zarr
library.An HPC system like Compute Canada may work better with one large files than many small files, thus the result should be zipped. This can be done by first writing the folder to somewhere that allows creating many small files and then zip the result into a single zip in the target directory
As of the time of writing (2024.8.14), ome-zarr library’s
Writer
class has a double computation issue. To temporary patch this for our use case, I’ve added awrite_ome_zarr_image
function to write a dask array as an ome zarr file. This function also adds support for reading images stored as a .zip file.
See the API page for cvpl_tools.ome_zarr.io.py for how to read and write OME
ZARR files if you want to use cvpl_tools
for such tasks. This file provides two functions
load_zarr_group_from_path
and write_ome_zarr_image
which allows you to read and write OME
ZARR files, respectively.
Specifying slices in path
cvpl_tools
allows specifying the channel, or x/y/z slices to use in the path string when
reading or viewing an ome zarr file for convenience.
The functions cvpl_tools.ome_zarr.io.load_dask_array_from_path
, and
cvpl_tools.ome_zarr.napari.add.group_from_path/subarray_from_path
support specifying the slices in the following syntax, much similar to torch or numpy array slicing:
arr_original = load_dask_array_from_path('file.ome.zarr', level=0) # shape=(2, 200, 1000, 1000)
arr1 = load_dask_array_from_path('file.ome.zarr?slices=[0]', level=0) # shape=(200, 1000, 1000)
arr2 = load_dask_array_from_path('file.ome.zarr?slices=[:, :100]', level=0) # shape=(2, 100, 1000, 1000)
arr3 = load_dask_array_from_path('file.ome.zarr?slices=[0:1, 0, -1:, ::2]', level=0) # shape=(1, 1, 500)
The idea of this syntax attributes to Davis Bennett (see this discussion).
Why do we need to specify slices this way? Commonly, we pass in an ome
zarr path to specify the input image of a script. If we want to run the script on the first channel
of a multi-channel image, both a path
to ome zarr and an in_channel
integer specifying the channel to use are needed.
With this syntax, we only need one input variable to specify
the channel to use, as well as a sub-region of the image if we want to crop the input.