patchworks 1.4.0__tar.gz → 1.4.1__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.
- {patchworks-1.4.0 → patchworks-1.4.1}/PKG-INFO +3 -1
- {patchworks-1.4.0 → patchworks-1.4.1}/README.md +2 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/guide/ome_zarr_napari.md +54 -6
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/plugins/ome_zarr.py +40 -7
- {patchworks-1.4.0 → patchworks-1.4.1}/tests/test_ome_zarr.py +40 -3
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/scripts/_pw.py +3 -1
- {patchworks-1.4.0 → patchworks-1.4.1}/.github/workflows/docs.yml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/.github/workflows/lint.yml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/.github/workflows/release.yml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/.gitignore +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/.markdownlint-cli2.yaml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/LICENSE +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/cliff.toml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/api/chunks.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/api/cluster.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/api/io.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/api/merge_tile_labels.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/api/plugins/cellpose.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/api/plugins/dog.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/api/plugins/napari.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/api/plugins/ome_zarr.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/api/postprocess.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/api/relabel.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/api/tile_process.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/assets/logo.png +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/examples/cellpose_2d.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/examples/cellpose_2d.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/examples/cellpose_3d.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/examples/cellpose_3d.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/examples/custom.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/examples/custom_method.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/examples/dog.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/examples/dog.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/examples/standalone_merge.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/examples/stardist.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/examples/stardist_2d.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/getting_started.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/guide/custom_segmentation.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/guide/gpu_distributed.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/guide/label_relations.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/guide/measurements.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/guide/merging.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/guide/performance.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/guide/pitfalls.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/guide/skip_empty.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/guide/snakemake.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/guide/tiling.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/docs/index.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/mkdocs.yml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/pyproject.toml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/__init__.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/_chunks.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/_cluster.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/_core.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/_distributed.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/_io.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/_merge.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/_postprocess.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/_relabel.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/_relations.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/plugins/__init__.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/plugins/cellpose.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/plugins/dog.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/src/patchworks/plugins/napari.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/tests/test_core.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/tests/test_distributed.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/tests/test_dog.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/tests/test_napari.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/tests/test_postprocess.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/tests/test_relations.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/README.md +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/Snakefile +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/config/config.yaml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/config/config_cilia.yaml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/config/config_cyto.yaml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/config/config_nuclei.yaml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/config/multi.yaml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/pixi.toml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/profile/slurm/config.yaml +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/rules/common.smk +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/rules/convert.smk +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/rules/merge.smk +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/rules/segment.smk +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/scripts/convert.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/scripts/fetch_model.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/scripts/merge.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/scripts/prepare_tiles.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/scripts/run_multi.py +0 -0
- {patchworks-1.4.0 → patchworks-1.4.1}/workflow/scripts/segment_tile.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: patchworks
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.1
|
|
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
|
|
@@ -143,6 +143,8 @@ pip install "patchworks[all]" # Everything, incl. the napari viewer
|
|
|
143
143
|
> `[imaris]` adds native `.ims` support (HDF5, no JVM). Physical pixel
|
|
144
144
|
> calibration is read from the input and written into the OME-ZARR.
|
|
145
145
|
|
|
146
|
+
<!-- -->
|
|
147
|
+
|
|
146
148
|
> **`cupy` is never installed automatically**, unlike Cellpose's GPU support
|
|
147
149
|
> (which comes for free via PyTorch's self-contained CUDA wheels). Any
|
|
148
150
|
> `use_gpu=True`/`dilate_gpu: true` option (the `dog` plugin, `dilate_labels`)
|
|
@@ -53,6 +53,8 @@ pip install "patchworks[all]" # Everything, incl. the napari viewer
|
|
|
53
53
|
> `[imaris]` adds native `.ims` support (HDF5, no JVM). Physical pixel
|
|
54
54
|
> calibration is read from the input and written into the OME-ZARR.
|
|
55
55
|
|
|
56
|
+
<!-- -->
|
|
57
|
+
|
|
56
58
|
> **`cupy` is never installed automatically**, unlike Cellpose's GPU support
|
|
57
59
|
> (which comes for free via PyTorch's self-contained CUDA wheels). Any
|
|
58
60
|
> `use_gpu=True`/`dilate_gpu: true` option (the `dog` plugin, `dilate_labels`)
|
|
@@ -39,9 +39,10 @@ existed.
|
|
|
39
39
|
## Convert any image to OME-ZARR
|
|
40
40
|
|
|
41
41
|
`to_ome_zarr` accepts a dask/NumPy array, an existing `.zarr` store, an
|
|
42
|
-
**Imaris `.ims`** file,
|
|
43
|
-
[bioio](https://github.com/bioio-devs/bioio) (CZI, LIF, ND2, OME-TIFF, …)
|
|
44
|
-
inputs are read
|
|
42
|
+
**Imaris `.ims`** file, **any format** readable by
|
|
43
|
+
[bioio](https://github.com/bioio-devs/bioio) (CZI, LIF, ND2, OME-TIFF, …), or
|
|
44
|
+
a **folder of single-plane TIFFs** (see below). File inputs are read
|
|
45
|
+
**lazily**.
|
|
45
46
|
|
|
46
47
|
```python
|
|
47
48
|
from patchworks.plugins.ome_zarr import to_ome_zarr
|
|
@@ -50,6 +51,51 @@ to_ome_zarr("scan.czi", "scan.zarr", n_levels=5) # via bioio
|
|
|
50
51
|
to_ome_zarr("scan.ims", "scan.zarr") # Imaris, native HDF5
|
|
51
52
|
```
|
|
52
53
|
|
|
54
|
+
### A folder of single-plane TIFFs
|
|
55
|
+
|
|
56
|
+
Some acquisitions/stitching tools save **one TIFF per Z/C plane** instead of a
|
|
57
|
+
single multi-page file, e.g.:
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
sample_T0_Z000_C0_V0.tif
|
|
61
|
+
sample_T0_Z000_C1_V0.tif
|
|
62
|
+
sample_T0_Z001_C0_V0.tif
|
|
63
|
+
sample_T0_Z001_C1_V0.tif
|
|
64
|
+
...
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Pass `sequence_pattern=` and let `source` be a glob over the folder instead of
|
|
68
|
+
one file path. The pattern is a regex whose **named groups** map to axis
|
|
69
|
+
labels — one file per group of indices:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
to_ome_zarr(
|
|
73
|
+
"sample/*.tif",
|
|
74
|
+
"sample.zarr",
|
|
75
|
+
sequence_pattern=r"_T(?P<T>\d+)_Z(?P<Z>\d+)_C(?P<C>\d+)_V\d+",
|
|
76
|
+
shard=True, # recommended for large sequences, see Sharding below
|
|
77
|
+
)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
You don't need to order the named groups to match how the axes should come
|
|
81
|
+
out: the result is always reordered to patchworks' `c, z, y, x` convention —
|
|
82
|
+
required for `channel=` selection (`load_ome_zarr`/`tile_process` always read
|
|
83
|
+
the channel from axis 0) — and a constant axis like `T0` above (one value, no
|
|
84
|
+
real time series) is dropped automatically, the same way the bioio/Imaris
|
|
85
|
+
readers already drop a singleton time axis.
|
|
86
|
+
|
|
87
|
+
Each file becomes exactly **one dask chunk**, decoded lazily on access — no
|
|
88
|
+
data is duplicated or eagerly loaded, so this scales to huge (multi-TB)
|
|
89
|
+
sequences (built on `tifffile.TiffSequence`, the same mechanism Cellpose's
|
|
90
|
+
own distributed pipeline uses). Pixel calibration is read automatically from
|
|
91
|
+
the first file's own metadata — see [Pixel calibration](#pixel-calibration)
|
|
92
|
+
below.
|
|
93
|
+
|
|
94
|
+
Available on the cluster too: the Snakemake `convert` rule reads a
|
|
95
|
+
`sequence_pattern:` key from the config (`input:` then being the glob), so a
|
|
96
|
+
folder-of-TIFFs conversion runs through the same SLURM profile as any other
|
|
97
|
+
input — see [Cluster usage](snakemake.md).
|
|
98
|
+
|
|
53
99
|
!!! note "Imaris pyramids: rebuild (default) or reuse"
|
|
54
100
|
`.ims` files carry their own resolution pyramid. By default `to_ome_zarr`
|
|
55
101
|
reads only the **full-resolution** level and **builds a fresh NGFF pyramid**
|
|
@@ -64,9 +110,11 @@ to_ome_zarr("scan.ims", "scan.zarr") # Imaris, native HDF5
|
|
|
64
110
|
### Pixel calibration
|
|
65
111
|
|
|
66
112
|
The physical voxel size is read from the input — bioio's `physical_pixel_sizes`,
|
|
67
|
-
the Imaris resolution metadata,
|
|
68
|
-
|
|
69
|
-
|
|
113
|
+
the Imaris resolution metadata, an existing OME-ZARR's scale, or (for a TIFF
|
|
114
|
+
sequence) the first file's own ImageJ metadata (`spacing`/`unit`) or
|
|
115
|
+
`XResolution`/`YResolution` tags — and written into the NGFF
|
|
116
|
+
`coordinateTransformations` (in micrometers), so calibration is preserved
|
|
117
|
+
regardless of input. Override or supply it for bare arrays with
|
|
70
118
|
`pixel_size={"z": 2.0, "y": 0.32, "x": 0.32}`.
|
|
71
119
|
|
|
72
120
|
### Won't OOM
|
|
@@ -701,15 +701,19 @@ def _open_tiff_sequence(
|
|
|
701
701
|
sequence_pattern : str
|
|
702
702
|
Regular expression parsing each file name into axis labels and
|
|
703
703
|
indices, e.g. ``r"_T(?P<T>\\d+)_Z(?P<Z>\\d+)_C(?P<C>\\d+)_V\\d+"``.
|
|
704
|
-
Named groups become axis labels directly
|
|
705
|
-
|
|
704
|
+
Named groups become axis labels directly — the order they appear in
|
|
705
|
+
the *pattern* (not the filename) doesn't matter, the result is
|
|
706
|
+
always reordered to patchworks' ``tczyx`` convention and any
|
|
707
|
+
singleton non-spatial axis (e.g. a constant ``T0``) is dropped, same
|
|
708
|
+
as the bioio/Imaris readers, so a real channel axis always ends up
|
|
709
|
+
first (required by :func:`patchworks.load_ome_zarr`).
|
|
706
710
|
|
|
707
711
|
Returns
|
|
708
712
|
-------
|
|
709
713
|
tuple
|
|
710
714
|
``(array, axes, pixel_size)`` — a lazy dask array, its axes string
|
|
711
|
-
(parsed axes + trailing ``"yx"``) and a
|
|
712
|
-
calibration dict read from the first file.
|
|
715
|
+
(parsed axes, canonicalised, + trailing ``"yx"``) and a
|
|
716
|
+
``{axis: micrometers}`` calibration dict read from the first file.
|
|
713
717
|
"""
|
|
714
718
|
try:
|
|
715
719
|
import tifffile
|
|
@@ -722,7 +726,33 @@ def _open_tiff_sequence(
|
|
|
722
726
|
|
|
723
727
|
ts = tifffile.TiffSequence(pattern, pattern=sequence_pattern)
|
|
724
728
|
arr = da.from_zarr(zarr.open(store=ts.aszarr()))
|
|
725
|
-
|
|
729
|
+
full_axes = ts.axes.lower() + "yx"
|
|
730
|
+
|
|
731
|
+
# Canonicalise to patchworks' tczyx axis order regardless of the order
|
|
732
|
+
# sequence_pattern's groups happen to appear in (unrecognised axes sort
|
|
733
|
+
# last, before y/x).
|
|
734
|
+
order = sorted(
|
|
735
|
+
range(len(full_axes)),
|
|
736
|
+
key=lambda i: (
|
|
737
|
+
_DEFAULT_ORDER.index(full_axes[i])
|
|
738
|
+
if full_axes[i] in _DEFAULT_ORDER
|
|
739
|
+
else len(_DEFAULT_ORDER)
|
|
740
|
+
),
|
|
741
|
+
)
|
|
742
|
+
arr = arr.transpose(order)
|
|
743
|
+
ordered_axes = "".join(full_axes[i] for i in order)
|
|
744
|
+
|
|
745
|
+
# Drop singleton non-spatial axes (e.g. a constant T), matching
|
|
746
|
+
# _open_bioio/_open_imaris, so a real channel axis lands at position 0.
|
|
747
|
+
keep = [
|
|
748
|
+
i
|
|
749
|
+
for i, a in enumerate(ordered_axes)
|
|
750
|
+
if a in _SPATIAL_AXES or arr.shape[i] > 1
|
|
751
|
+
]
|
|
752
|
+
index = tuple(slice(None) if i in keep else 0 for i in range(arr.ndim))
|
|
753
|
+
arr = arr[index]
|
|
754
|
+
axes = "".join(ordered_axes[i] for i in keep)
|
|
755
|
+
|
|
726
756
|
pixel_size = _tiff_pixel_size(ts[0])
|
|
727
757
|
logger.info(
|
|
728
758
|
"tifffile sequence opened %s files as %s %s cal=%s",
|
|
@@ -979,8 +1009,11 @@ def to_ome_zarr(
|
|
|
979
1009
|
and indices via named groups, e.g.
|
|
980
1010
|
``r"_T(?P<T>\\d+)_Z(?P<Z>\\d+)_C(?P<C>\\d+)_V\\d+"``. Each file
|
|
981
1011
|
becomes exactly one chunk, read lazily on access (no data
|
|
982
|
-
duplicated) — see :func:`tifffile.TiffSequence`.
|
|
983
|
-
|
|
1012
|
+
duplicated) — see :func:`tifffile.TiffSequence`. The result is
|
|
1013
|
+
always reordered to patchworks' ``czyx`` convention regardless of
|
|
1014
|
+
the order named groups appear in the pattern, and any singleton
|
|
1015
|
+
non-spatial axis (e.g. a constant ``T0``) is dropped, so a real
|
|
1016
|
+
channel axis always ends up first.
|
|
984
1017
|
n_levels : int, optional
|
|
985
1018
|
Maximum number of pyramid levels including full resolution.
|
|
986
1019
|
downscale : int, optional
|
|
@@ -80,7 +80,12 @@ def test_non_spatial_axis_not_downsampled(tmp_path):
|
|
|
80
80
|
|
|
81
81
|
|
|
82
82
|
def test_tiff_sequence_conversion(tmp_path):
|
|
83
|
-
"""A folder of single-plane TIFFs is wrapped lazily and converted.
|
|
83
|
+
"""A folder of single-plane TIFFs is wrapped lazily and converted.
|
|
84
|
+
|
|
85
|
+
The filename pattern lists Z before C, but the output must still come
|
|
86
|
+
out channel-first (patchworks' tczyx convention), since load_ome_zarr /
|
|
87
|
+
tile_process hard-assume axis 0 is the channel axis.
|
|
88
|
+
"""
|
|
84
89
|
tifffile = pytest.importorskip("tifffile")
|
|
85
90
|
n_z, n_c, size = 3, 2, 8
|
|
86
91
|
for z in range(n_z):
|
|
@@ -102,11 +107,43 @@ def test_tiff_sequence_conversion(tmp_path):
|
|
|
102
107
|
)
|
|
103
108
|
|
|
104
109
|
result = np.asarray(load_ome_zarr(out, channel=None))
|
|
105
|
-
assert result.shape == (
|
|
110
|
+
assert result.shape == (n_c, n_z, size, size) # channel-first, not z-first
|
|
106
111
|
# each plane's constant value encodes its (z, c) position.
|
|
107
|
-
assert (
|
|
112
|
+
assert (
|
|
113
|
+
result[:, :, 0, 0]
|
|
114
|
+
== [[z * 10 + c for z in range(n_z)] for c in range(n_c)]
|
|
115
|
+
).all()
|
|
108
116
|
assert _level_scale(out, 0) == pytest.approx([1.0, 1.0, 0.5, 0.5])
|
|
109
117
|
|
|
118
|
+
# per-channel selection picks the right plane regardless of pattern order.
|
|
119
|
+
ch1 = np.asarray(load_ome_zarr(out, channel=1))
|
|
120
|
+
assert ch1.shape == (n_z, size, size)
|
|
121
|
+
assert (ch1[:, 0, 0] == [z * 10 + 1 for z in range(n_z)]).all()
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_tiff_sequence_drops_singleton_time_axis(tmp_path):
|
|
125
|
+
"""A constant T in the pattern is dropped, keeping channel at axis 0."""
|
|
126
|
+
tifffile = pytest.importorskip("tifffile")
|
|
127
|
+
n_z, n_c, size = 2, 3, 8
|
|
128
|
+
for z in range(n_z):
|
|
129
|
+
for c in range(n_c):
|
|
130
|
+
img = np.full((size, size), z * 10 + c, dtype="uint16")
|
|
131
|
+
tifffile.imwrite(tmp_path / f"sample_T0_Z{z:03d}_C{c}_V0.tif", img)
|
|
132
|
+
|
|
133
|
+
out = tmp_path / "out.zarr"
|
|
134
|
+
to_ome_zarr(
|
|
135
|
+
str(tmp_path / "*.tif"),
|
|
136
|
+
out,
|
|
137
|
+
sequence_pattern=r"_T(?P<T>\d+)_Z(?P<Z>\d+)_C(?P<C>\d+)_V\d+",
|
|
138
|
+
n_levels=1,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
result = np.asarray(load_ome_zarr(out, channel=None))
|
|
142
|
+
assert result.shape == (n_c, n_z, size, size) # no leftover T axis
|
|
143
|
+
ch2 = np.asarray(load_ome_zarr(out, channel=2))
|
|
144
|
+
assert ch2.shape == (n_z, size, size)
|
|
145
|
+
assert (ch2[:, 0, 0] == [z * 10 + 2 for z in range(n_z)]).all()
|
|
146
|
+
|
|
110
147
|
|
|
111
148
|
def test_axes_length_mismatch(tmp_path):
|
|
112
149
|
with pytest.raises(ValueError):
|
|
@@ -152,7 +152,9 @@ def build_fn(cfg):
|
|
|
152
152
|
if dilate:
|
|
153
153
|
from patchworks import dilate_labels
|
|
154
154
|
|
|
155
|
-
fn = dilate_labels(
|
|
155
|
+
fn = dilate_labels(
|
|
156
|
+
fn, iterations=dilate, use_gpu=cfg.get("dilate_gpu", False)
|
|
157
|
+
)
|
|
156
158
|
|
|
157
159
|
return fn
|
|
158
160
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|