Skip to content

Commit cc1fe45

Browse files
committed
docs: πŸ“ link napari-chunked-regionprops for whole-store measurement
Points users at https://github.com/imcf/napari-chunked-regionprops as the recommended way to measure every object in a large label store β€” both interactively (napari guide) and in the headless/scripted Measurements section β€” instead of skimage.measure.regionprops (in-memory) or napari-skimage-regionprops (cropped-region only).
1 parent eb22f28 commit cc1fe45

5 files changed

Lines changed: 40 additions & 14 deletions

File tree

β€Ždocs/guide/ome_zarr_napari.mdβ€Ž

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,16 @@ just one channel instead: `view_in_napari("scan.zarr", channel=0)`.
152152
napari ships in `patchworks[all]`, or install just it with
153153
`pip install "patchworks[napari]"`.
154154

155+
!!! tip "Measuring all the objects"
156+
Once labels are loaded, use
157+
[napari-chunked-regionprops](https://github.com/imcf/napari-chunked-regionprops)'s
158+
"Measure" dock widget for area/centroid/intensity stats β€” it works
159+
out-of-core straight off the Labels layer's backing dask/zarr array, so
160+
it scales to the same huge label images `tile_process` writes, unlike
161+
plain `skimage.measure.regionprops`. Bundled in `patchworks[napari]`. See
162+
[Measurements](snakemake.md#measurements-fast-whole-volume-regionprops)
163+
for the non-interactive/headless equivalent.
164+
155165
## End-to-end
156166

157167
```python

β€Ždocs/guide/snakemake.mdβ€Ž

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,20 @@ needs `pip install "patchworks[dog]"` in the segment jobs' environment.
361361
## Measurements (fast, whole-volume regionprops)
362362

363363
`skimage.measure.regionprops` needs the full labelled + intensity array in
364-
RAM β€” fine for one tile, not for a hundred-thousand-object OME-ZARR. Use
365-
[`dask-image`](https://image.dask.org)'s `ndmeasure`, which computes directly
366-
on the dask/zarr-backed arrays, chunk-parallel, without materializing the
367-
volume:
364+
RAM β€” fine for one tile, not for a hundred-thousand-object OME-ZARR.
365+
366+
**Interactively, in napari**, this is what
367+
[napari-chunked-regionprops](https://github.com/imcf/napari-chunked-regionprops)
368+
is for β€” its "Measure" dock widget computes area/centroid/intensity stats
369+
directly off a Labels layer's dask/zarr-backed array, out-of-core, and scales
370+
with chunk count rather than object count. It's the best fit for measuring
371+
*every* object in a store this size, not just a cropped region β€” see
372+
[View image + labels in napari](ome_zarr_napari.md#view-image--labels-in-napari).
373+
Bundled in `patchworks[napari]`.
374+
375+
**Headless/scripted**, use [`dask-image`](https://image.dask.org)'s
376+
`ndmeasure`, which computes directly on the dask/zarr-backed arrays,
377+
chunk-parallel, without materializing the volume:
368378

369379
```bash
370380
pip install dask-image
@@ -392,7 +402,10 @@ For interactively inspecting individual cells by clicking in the viewer
392402
(not all objects at once), the
393403
[napari-skimage-regionprops](https://github.com/haesleinhuepf/napari-skimage-regionprops)
394404
plugin's table widget works well β€” point it at a cropped region rather than
395-
the full volume, since it loads its input fully into memory.
405+
the full volume, since it loads its input fully into memory. For measuring
406+
*all* objects at once, use
407+
[napari-chunked-regionprops](https://github.com/imcf/napari-chunked-regionprops)
408+
instead (see above) β€” it doesn't have this in-memory limitation.
396409

397410
## Custom segmentation function
398411

β€Žpyproject.tomlβ€Ž

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,12 @@ imaris = ["imaris-ims-file-reader"]
7272
# - lxml-html-clean: napari's notebook_display imports lxml.html.clean, split
7373
# into a separate package in lxml >= 5.2 (else ImportError on Viewer()).
7474
# - glasbey: distinct high-contrast label LUTs for view_in_napari.
75-
# - napari-chunked-regionprops: out-of-core regionprops-style measurements
76-
# (area/centroid/intensity stats) for huge Labels layers, straight off
77-
# their backing dask/zarr arrays β€” the "Measure" dock widget. Formerly
78-
# napari-dask-ndmeasure; renamed when its engine dropped dask_image.ndmeasure
79-
# for a chunk-local map/merge that scales with chunk count, not object count.
75+
# - napari-chunked-regionprops (https://github.com/imcf/napari-chunked-regionprops):
76+
# out-of-core regionprops-style measurements (area/centroid/intensity
77+
# stats) for huge Labels layers, straight off their backing dask/zarr
78+
# arrays β€” the "Measure" dock widget. Formerly napari-dask-ndmeasure;
79+
# renamed when its engine dropped dask_image.ndmeasure for a chunk-local
80+
# map/merge that scales with chunk count, not object count.
8081
# - pyqt6 < 6.10: PyQt6-Qt6 6.10.2's Windows wheel fails to import (`DLL load
8182
# failed while importing QtWidgets: The specified procedure could not be
8283
# found`) β€” confirmed unrelated to napari/qtpy, reproduces on a bare

β€Žsrc/patchworks/plugins/napari.pyβ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ def _label_hint(path: Union[str, Path]) -> dict[str, Any]:
187187
during the merge) β€” the exact id set is then ``range(1, n_objects +
188188
1)`` by construction, with no scan needed. Passed through as a Labels
189189
layer's ``metadata`` so a downstream consumer (e.g.
190-
napari-chunked-regionprops) can use it instead of re-deriving the id
191-
set from the array itself.
190+
napari-chunked-regionprops, https://github.com/imcf/napari-chunked-regionprops)
191+
can use it instead of re-deriving the id set from the array itself.
192192
193193
Parameters
194194
----------

β€Žsrc/patchworks/plugins/ome_zarr.pyβ€Ž

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,8 +1083,10 @@ def register_labels(
10831083
``sequential_labels=True``, which means ``ids == range(1, n_objects
10841084
+ 1)`` by construction). When given, written into the label group's
10851085
attrs as ``n_objects``/``sequential_labels`` so a downstream reader
1086-
(e.g. napari-chunked-regionprops) can use the known id set instead
1087-
of re-deriving it with a full-volume scan of its own.
1086+
(e.g. napari-chunked-regionprops,
1087+
https://github.com/imcf/napari-chunked-regionprops) can use the
1088+
known id set instead of re-deriving it with a full-volume scan of
1089+
its own.
10881090
10891091
Returns
10901092
-------

0 commit comments

Comments
Β (0)