patchworks 0.11.16__tar.gz → 0.11.17__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. {patchworks-0.11.16 → patchworks-0.11.17}/PKG-INFO +1 -1
  2. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/plugins/napari.py +53 -4
  3. {patchworks-0.11.16 → patchworks-0.11.17}/.github/workflows/docs.yml +0 -0
  4. {patchworks-0.11.16 → patchworks-0.11.17}/.github/workflows/lint.yml +0 -0
  5. {patchworks-0.11.16 → patchworks-0.11.17}/.github/workflows/release.yml +0 -0
  6. {patchworks-0.11.16 → patchworks-0.11.17}/.gitignore +0 -0
  7. {patchworks-0.11.16 → patchworks-0.11.17}/.markdownlint-cli2.yaml +0 -0
  8. {patchworks-0.11.16 → patchworks-0.11.17}/LICENSE +0 -0
  9. {patchworks-0.11.16 → patchworks-0.11.17}/README.md +0 -0
  10. {patchworks-0.11.16 → patchworks-0.11.17}/cliff.toml +0 -0
  11. {patchworks-0.11.16 → patchworks-0.11.17}/docs/api/chunks.md +0 -0
  12. {patchworks-0.11.16 → patchworks-0.11.17}/docs/api/cluster.md +0 -0
  13. {patchworks-0.11.16 → patchworks-0.11.17}/docs/api/io.md +0 -0
  14. {patchworks-0.11.16 → patchworks-0.11.17}/docs/api/merge_tile_labels.md +0 -0
  15. {patchworks-0.11.16 → patchworks-0.11.17}/docs/api/plugins/cellpose.md +0 -0
  16. {patchworks-0.11.16 → patchworks-0.11.17}/docs/api/plugins/napari.md +0 -0
  17. {patchworks-0.11.16 → patchworks-0.11.17}/docs/api/plugins/ome_zarr.md +0 -0
  18. {patchworks-0.11.16 → patchworks-0.11.17}/docs/api/relabel.md +0 -0
  19. {patchworks-0.11.16 → patchworks-0.11.17}/docs/api/tile_process.md +0 -0
  20. {patchworks-0.11.16 → patchworks-0.11.17}/docs/assets/logo.png +0 -0
  21. {patchworks-0.11.16 → patchworks-0.11.17}/docs/examples/cellpose_2d.md +0 -0
  22. {patchworks-0.11.16 → patchworks-0.11.17}/docs/examples/cellpose_2d.py +0 -0
  23. {patchworks-0.11.16 → patchworks-0.11.17}/docs/examples/cellpose_3d.md +0 -0
  24. {patchworks-0.11.16 → patchworks-0.11.17}/docs/examples/cellpose_3d.py +0 -0
  25. {patchworks-0.11.16 → patchworks-0.11.17}/docs/examples/custom.md +0 -0
  26. {patchworks-0.11.16 → patchworks-0.11.17}/docs/examples/custom_method.py +0 -0
  27. {patchworks-0.11.16 → patchworks-0.11.17}/docs/examples/standalone_merge.md +0 -0
  28. {patchworks-0.11.16 → patchworks-0.11.17}/docs/examples/stardist.md +0 -0
  29. {patchworks-0.11.16 → patchworks-0.11.17}/docs/examples/stardist_2d.py +0 -0
  30. {patchworks-0.11.16 → patchworks-0.11.17}/docs/getting_started.md +0 -0
  31. {patchworks-0.11.16 → patchworks-0.11.17}/docs/guide/gpu_distributed.md +0 -0
  32. {patchworks-0.11.16 → patchworks-0.11.17}/docs/guide/merging.md +0 -0
  33. {patchworks-0.11.16 → patchworks-0.11.17}/docs/guide/ome_zarr_napari.md +0 -0
  34. {patchworks-0.11.16 → patchworks-0.11.17}/docs/guide/performance.md +0 -0
  35. {patchworks-0.11.16 → patchworks-0.11.17}/docs/guide/pitfalls.md +0 -0
  36. {patchworks-0.11.16 → patchworks-0.11.17}/docs/guide/skip_empty.md +0 -0
  37. {patchworks-0.11.16 → patchworks-0.11.17}/docs/guide/snakemake.md +0 -0
  38. {patchworks-0.11.16 → patchworks-0.11.17}/docs/guide/tiling.md +0 -0
  39. {patchworks-0.11.16 → patchworks-0.11.17}/docs/index.md +0 -0
  40. {patchworks-0.11.16 → patchworks-0.11.17}/mkdocs.yml +0 -0
  41. {patchworks-0.11.16 → patchworks-0.11.17}/pyproject.toml +0 -0
  42. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/__init__.py +0 -0
  43. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/_chunks.py +0 -0
  44. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/_cluster.py +0 -0
  45. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/_core.py +0 -0
  46. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/_distributed.py +0 -0
  47. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/_io.py +0 -0
  48. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/_merge.py +0 -0
  49. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/_relabel.py +0 -0
  50. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/plugins/__init__.py +0 -0
  51. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/plugins/cellpose.py +0 -0
  52. {patchworks-0.11.16 → patchworks-0.11.17}/src/patchworks/plugins/ome_zarr.py +0 -0
  53. {patchworks-0.11.16 → patchworks-0.11.17}/tests/test_core.py +0 -0
  54. {patchworks-0.11.16 → patchworks-0.11.17}/tests/test_distributed.py +0 -0
  55. {patchworks-0.11.16 → patchworks-0.11.17}/tests/test_napari.py +0 -0
  56. {patchworks-0.11.16 → patchworks-0.11.17}/tests/test_ome_zarr.py +0 -0
  57. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/README.md +0 -0
  58. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/Snakefile +0 -0
  59. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/config/config.yaml +0 -0
  60. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/pixi.toml +0 -0
  61. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/profile/slurm/config.yaml +0 -0
  62. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/rules/common.smk +0 -0
  63. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/rules/convert.smk +0 -0
  64. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/rules/merge.smk +0 -0
  65. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/rules/segment.smk +0 -0
  66. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/scripts/_pw.py +0 -0
  67. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/scripts/convert.py +0 -0
  68. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/scripts/fetch_model.py +0 -0
  69. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/scripts/merge.py +0 -0
  70. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/scripts/prepare_tiles.py +0 -0
  71. {patchworks-0.11.16 → patchworks-0.11.17}/workflow/scripts/segment_tile.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: patchworks
3
- Version: 0.11.16
3
+ Version: 0.11.17
4
4
  Summary: Tiled processing of arbitrarily large images with globally consistent labels
5
5
  Project-URL: Homepage, https://github.com/imcf/patchworks
6
6
  Project-URL: Issues, https://github.com/imcf/patchworks/issues
@@ -142,6 +142,36 @@ def _resolve_image(
142
142
  return source
143
143
 
144
144
 
145
+ def _pyramid_scale(path: Union[str, Path], ndim: int) -> list[float] | None:
146
+ """Read the level-0 physical scale (µm/px) from an OME-ZARR's own metadata.
147
+
148
+ Without this, napari shows every axis with an implicit scale of 1, so a
149
+ volume with anisotropic voxels (e.g. z coarser than x/y) renders with the
150
+ wrong aspect ratio and no real-world units.
151
+
152
+ Parameters
153
+ ----------
154
+ path : str or Path
155
+ OME-ZARR store path (image or label group) — each carries its own
156
+ ``multiscales`` metadata, so image and label stores are read
157
+ independently.
158
+ ndim : int
159
+ Number of spatial dimensions of the loaded array (2 -> "yx", 3 ->
160
+ "zyx"), used to align the calibration to the right axes.
161
+
162
+ Returns
163
+ -------
164
+ list of float or None
165
+ Physical size per axis, or ``None`` if the store carries no
166
+ calibration (napari then falls back to its uncalibrated default).
167
+ """
168
+ from .ome_zarr import _base_scale, _default_axes, _read_zarr_calibration
169
+
170
+ axes = _default_axes(ndim)
171
+ pixel_size = _read_zarr_calibration(str(path), axes)
172
+ return _base_scale(axes, pixel_size) if pixel_size else None
173
+
174
+
145
175
  def _inner_label_names(store: Union[str, Path]) -> list[str]:
146
176
  """List label images registered under an OME-ZARR's ``labels/`` group.
147
177
 
@@ -248,11 +278,14 @@ def view_in_napari(
248
278
  napari = _require_napari()
249
279
 
250
280
  img = _resolve_image(image, channel)
281
+ img_ndim = img[0].ndim if isinstance(img, list) else img.ndim
282
+ img_scale = _pyramid_scale(image, img_ndim) if _is_zarr(image) else None
251
283
  viewer = napari.Viewer()
252
284
  viewer.add_image(
253
285
  img,
254
286
  name=image_name,
255
287
  multiscale=isinstance(img, list),
288
+ scale=img_scale,
256
289
  **add_image_kwargs,
257
290
  )
258
291
 
@@ -288,16 +321,32 @@ def view_in_napari(
288
321
 
289
322
  if labels is not None:
290
323
  lab = _resolve_labels(labels, labels_component)
291
- viewer.add_labels(lab, name=labels_name, **label_kwargs)
324
+ lab_ndim = lab[0].ndim if isinstance(lab, list) else lab.ndim
325
+ lab_scale = _pyramid_scale(labels, lab_ndim) if _is_zarr(labels) else None
326
+ viewer.add_labels(
327
+ lab,
328
+ name=labels_name,
329
+ multiscale=isinstance(lab, list),
330
+ scale=lab_scale,
331
+ **label_kwargs,
332
+ )
292
333
  elif _is_zarr(image):
293
334
  # No labels given → auto-overlay every label image stored inside the
294
335
  # OME-ZARR under labels/<name>/ (the default place tile_process writes
295
- # them), each as its own multi-scale Labels layer.
336
+ # them), each as its own multi-scale Labels layer. Kept as a list (not
337
+ # unwrapped to a single array) even for one level, so napari always
338
+ # treats it as multiscale — required for 3D resolution switching, see
339
+ # https://napari.org/stable/gallery/add_multiscale_volume.html
296
340
  for name in _inner_label_names(image):
297
- levels = _multiscale_levels(f"{image}/labels/{name}", None)
341
+ store = f"{image}/labels/{name}"
342
+ levels = _multiscale_levels(store, None)
298
343
  lab = [lvl.astype("int32") for lvl in levels]
299
344
  viewer.add_labels(
300
- lab if len(lab) > 1 else lab[0], name=name, **label_kwargs
345
+ lab,
346
+ name=name,
347
+ multiscale=True,
348
+ scale=_pyramid_scale(store, lab[0].ndim),
349
+ **label_kwargs,
301
350
  )
302
351
  logger.info("auto-loaded labels/%s from %s", name, image)
303
352
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes