1414Usage
1515-----
1616>>> from patchworks import tile_process
17- >>> from patchworks.plugins.ome_zarr import to_ome_zarr
1817>>> from patchworks.plugins.napari import view_in_napari
1918>>>
20- >>> tile_process(" scan.zarr", fn, write_to="labels.zarr")
21- >>> to_ome_zarr ("scan.zarr", "scan_pyramid.zarr") # optional, for speed
22- >>>
23- >>> view_in_napari("scan_pyramid.zarr", labels="labels .zarr")
19+ >>> # labels are written into scan.zarr/labels/ by default …
20+ >>> tile_process ("scan.zarr", fn)
21+ >>> # … so the viewer finds and overlays them with no labels= argument:
22+ >>> view_in_napari("scan .zarr")
2423"""
2524
2625from __future__ import annotations
@@ -86,6 +85,15 @@ def _resolve_image(
8685 return source
8786
8887
88+ def _inner_label_names (store : Union [str , Path ]) -> list [str ]:
89+ """Names registered under an OME-ZARR's NGFF ``labels/`` group, if any."""
90+ try :
91+ grp = zarr .open_group (f"{ store } /labels" , mode = "r" )
92+ except Exception :
93+ return []
94+ return list (grp .attrs .get ("labels" , []))
95+
96+
8997def _resolve_labels (
9098 source : Union [da .Array , str , Path ], component : str
9199) -> Union [da .Array , list [da .Array ]]:
@@ -123,7 +131,10 @@ def view_in_napari(
123131 labels : da.Array, str, Path or None
124132 Label array to overlay. A plain ``.zarr`` store written by
125133 ``tile_process`` is read from its ``labels_component``; an OME-ZARR
126- pyramid is shown multi-scale; ``None`` shows the image only.
134+ pyramid is shown multi-scale. ``None`` (default) **auto-loads** every
135+ label image stored inside the OME-ZARR under ``labels/<name>/`` — the
136+ place ``tile_process`` writes them by default — each as its own Labels
137+ layer. (Falls back to image-only if there are none.)
127138 channel : int or None, optional
128139 Channel to display from the image (``None`` keeps all channels).
129140 labels_component : str, optional
@@ -145,7 +156,7 @@ def view_in_napari(
145156
146157 Examples
147158 --------
148- >>> view_in_napari("scan.zarr", labels="labels .zarr") # doctest: +SKIP
159+ >>> view_in_napari("scan.zarr") # auto-loads scan .zarr/labels/* # doctest: +SKIP
149160 """
150161 napari = _require_napari ()
151162
@@ -161,6 +172,15 @@ def view_in_napari(
161172 if labels is not None :
162173 lab = _resolve_labels (labels , labels_component )
163174 viewer .add_labels (lab , name = labels_name )
175+ elif _is_zarr (image ):
176+ # No labels given → auto-overlay every label image stored inside the
177+ # OME-ZARR under labels/<name>/ (the default place tile_process writes
178+ # them), each as its own multi-scale Labels layer.
179+ for name in _inner_label_names (image ):
180+ levels = _multiscale_levels (f"{ image } /labels/{ name } " , None )
181+ lab = [lvl .astype ("int32" ) for lvl in levels ]
182+ viewer .add_labels (lab if len (lab ) > 1 else lab [0 ], name = name )
183+ logger .info ("auto-loaded labels/%s from %s" , name , image )
164184
165185 if show :
166186 napari .run ()
0 commit comments