patchworks 2.6.2__tar.gz → 2.6.3__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-2.6.2 → patchworks-2.6.3}/PKG-INFO +2 -2
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_notify.py +9 -4
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_notify.py +24 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/profile/slurm/config.yaml +24 -4
- {patchworks-2.6.2 → patchworks-2.6.3}/.github/workflows/docs.yml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/.github/workflows/lint.yml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/.github/workflows/release.yml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/.gitignore +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/.markdownlint-cli2.yaml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/LICENSE +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/README.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/cliff.toml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/api/chunks.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/api/cluster.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/api/io.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/api/merge_tile_labels.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/api/plugins/cellpose.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/api/plugins/dog.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/api/plugins/napari.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/api/plugins/ome_zarr.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/api/postprocess.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/api/relabel.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/api/tile_process.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/assets/logo.png +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/examples/cellpose_2d.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/examples/cellpose_2d.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/examples/cellpose_3d.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/examples/cellpose_3d.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/examples/custom.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/examples/custom_method.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/examples/dog.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/examples/dog.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/examples/standalone_merge.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/examples/stardist.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/examples/stardist_2d.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/getting_started.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/guide/custom_segmentation.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/guide/gpu_distributed.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/guide/label_relations.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/guide/measurements.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/guide/merging.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/guide/ome_zarr_napari.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/guide/performance.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/guide/pitfalls.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/guide/skip_empty.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/guide/snakemake.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/guide/tiling.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/docs/index.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/mkdocs.yml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/pyproject.toml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/__init__.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_chunks.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_cluster.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_core.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_distributed.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_gpu.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_io.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_merge.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_occupancy.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_postprocess.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_progress.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_relabel.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/_relations.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/plugins/__init__.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/plugins/cellpose.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/plugins/dog.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/plugins/napari.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/src/patchworks/plugins/ome_zarr.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_allocation.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_core.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_distributed.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_dog.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_gpu.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_napari.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_occupancy.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_ome_zarr.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_postprocess.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_progress.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_relations.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/tests/test_run_multi.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/README.md +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/Snakefile +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/config/common.yaml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/config/config.yaml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/config/config_cilia.yaml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/config/config_cyto.yaml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/config/config_nuclei.yaml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/config/multi.yaml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/pixi.toml +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/rules/common.smk +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/rules/convert.smk +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/rules/merge.smk +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/rules/segment.smk +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/scripts/_pw.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/scripts/build_occupancy.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/scripts/convert.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/scripts/fetch_model.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/scripts/merge.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/scripts/prepare_tiles.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/scripts/run_multi.py +0 -0
- {patchworks-2.6.2 → patchworks-2.6.3}/workflow/scripts/segment_tile.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: patchworks
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.3
|
|
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
|
|
@@ -159,7 +159,7 @@ def slurm_mail_extra(
|
|
|
159
159
|
|
|
160
160
|
|
|
161
161
|
def failing_step(
|
|
162
|
-
snakemake_log: Union[str, Path, None],
|
|
162
|
+
snakemake_log: "Union[str, Path, list, tuple, None]",
|
|
163
163
|
) -> "tuple[Union[str, None], Union[str, None]]":
|
|
164
164
|
"""Find which rule failed, and its log, from Snakemake's own log file.
|
|
165
165
|
|
|
@@ -171,9 +171,12 @@ def failing_step(
|
|
|
171
171
|
|
|
172
172
|
Parameters
|
|
173
173
|
----------
|
|
174
|
-
snakemake_log : str
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
snakemake_log : str, Path, list, tuple, or None
|
|
175
|
+
Snakemake's own log (the ``log`` variable inside an ``onerror``
|
|
176
|
+
handler). Snakemake 8+ passes this as a list of paths (its
|
|
177
|
+
``LoggerManager.get_logfile()`` returns ``List[str]``, even though
|
|
178
|
+
there is normally just one) rather than a single string -- take the
|
|
179
|
+
first entry.
|
|
177
180
|
|
|
178
181
|
Returns
|
|
179
182
|
-------
|
|
@@ -181,6 +184,8 @@ def failing_step(
|
|
|
181
184
|
``(rule_name, log_path)``, either of which may be None when the log
|
|
182
185
|
is unreadable or records no rule error.
|
|
183
186
|
"""
|
|
187
|
+
if isinstance(snakemake_log, (list, tuple)):
|
|
188
|
+
snakemake_log = snakemake_log[0] if snakemake_log else None
|
|
184
189
|
try:
|
|
185
190
|
text = Path(snakemake_log).read_text(errors="replace")
|
|
186
191
|
except (OSError, TypeError, ValueError):
|
|
@@ -99,6 +99,30 @@ def test_failing_step_reads_the_rule_from_snakemakes_log(tmp_path):
|
|
|
99
99
|
)
|
|
100
100
|
|
|
101
101
|
|
|
102
|
+
def test_failing_step_accepts_snakemakes_list_log(tmp_path):
|
|
103
|
+
"""Snakemake 8+ passes `log` as a list, not a bare path.
|
|
104
|
+
|
|
105
|
+
``LoggerManager.get_logfile()`` returns ``List[str]``, and that's what
|
|
106
|
+
the `log` variable inside `onerror:` actually is. `Path(a_list)` raises
|
|
107
|
+
`TypeError`, which the old code caught and turned into `(None, None)` --
|
|
108
|
+
so this path was *always* silently falling back to the mtime guess it
|
|
109
|
+
was written to replace, on every real failure.
|
|
110
|
+
"""
|
|
111
|
+
from patchworks._notify import failing_step
|
|
112
|
+
|
|
113
|
+
log = tmp_path / "sm.log"
|
|
114
|
+
log.write_text(
|
|
115
|
+
"Error in rule segment:\n"
|
|
116
|
+
" jobid: 69\n"
|
|
117
|
+
" output: seg/61.done\n"
|
|
118
|
+
" log: /w/nuclei_labels/logs/segment/61.log (check log file(s))\n"
|
|
119
|
+
)
|
|
120
|
+
expected = ("segment", "/w/nuclei_labels/logs/segment/61.log")
|
|
121
|
+
assert failing_step([str(log)]) == expected
|
|
122
|
+
assert failing_step((str(log),)) == expected
|
|
123
|
+
assert failing_step([]) == (None, None)
|
|
124
|
+
|
|
125
|
+
|
|
102
126
|
def test_failing_step_degrades_quietly(tmp_path):
|
|
103
127
|
"""It runs inside an error handler, so it must never raise itself."""
|
|
104
128
|
from patchworks._notify import failing_step
|
|
@@ -74,7 +74,7 @@ set-resources:
|
|
|
74
74
|
# equal to segment's mem_mb below: lower and tiles come out needlessly
|
|
75
75
|
# small; higher and the sizer budgets against more host RAM than segment
|
|
76
76
|
# will actually get, undoing the point of the host-RAM check.
|
|
77
|
-
mem_mb: "attempt *
|
|
77
|
+
mem_mb: "attempt * 128000"
|
|
78
78
|
runtime: 120
|
|
79
79
|
segment:
|
|
80
80
|
# one GPU per job — this is what spreads Cellpose across GPUs.
|
|
@@ -83,15 +83,35 @@ set-resources:
|
|
|
83
83
|
# leaves the job without a device.)
|
|
84
84
|
slurm_partition: "rtx4090"
|
|
85
85
|
gres: "gpu:1"
|
|
86
|
-
|
|
86
|
+
# rtx4090-6hours wasn't enough: a do_3D whole-z tile (126 planes, full
|
|
87
|
+
# footprint) can run past 6h even though most same-sized tiles finish in
|
|
88
|
+
# 2.5-3.5h -- retrying it bought nothing since `runtime` didn't scale with
|
|
89
|
+
# `attempt` the way `mem_mb` does below, so it hit the identical wall on
|
|
90
|
+
# every attempt and burned all `retries` for a job that was never going to
|
|
91
|
+
# finish in the window. rtx4090-1day is scicore's next tier up (see
|
|
92
|
+
# `sacctmgr show qos format=name,maxwall | grep rtx4090`); 24h is wide
|
|
93
|
+
# margin over anything observed so far. If a tile still times out at 24h,
|
|
94
|
+
# that's not a slow tile anymore -- it's stuck, and worth profiling on its
|
|
95
|
+
# own rather than reaching for rtx4090-1week.
|
|
96
|
+
qos: "rtx4090-1day" # scicore: <partition>-<duration> QOS
|
|
87
97
|
# A job now processes `tiles_per_job` tiles sequentially, so both memory
|
|
88
98
|
# and runtime scale with that setting — raise it there and re-check here.
|
|
89
99
|
# The old "a tile used ~1G" note predates tile_shape: "auto", which sizes
|
|
90
100
|
# tiles against the real GPU and makes them far bigger. If you raise
|
|
91
101
|
# this, raise prepare's mem_mb above to match (see its comment).
|
|
92
|
-
|
|
102
|
+
#
|
|
103
|
+
# 128 GB base (256/384 GB on retry) is a wide safety margin, not a tight
|
|
104
|
+
# estimate: a do_3D tile that `auto_tile_shape_cellpose`'s 20x
|
|
105
|
+
# cellpose_memory_factor judged safe within a 24 GiB GPU budget still hit
|
|
106
|
+
# a real 32 GB host OOM, so that heuristic underestimates do_3D's actual
|
|
107
|
+
# host-RAM use by more than expected. rtx4090 nodes have ~1 TB RAM
|
|
108
|
+
# (~800 GB usable) and the QOS caps at 4 TB account-wide, so this has
|
|
109
|
+
# plenty of room -- it buys time until do_3D gets a properly measured
|
|
110
|
+
# memory factor (e.g. from `seff` on a job that completes) instead of a
|
|
111
|
+
# guess. ``ponytail:`` tighten this once real peak-RSS numbers exist.
|
|
112
|
+
mem_mb: "attempt * 128000"
|
|
93
113
|
cpus_per_task: 4
|
|
94
|
-
runtime:
|
|
114
|
+
runtime: 1400 # ~23.3h — must stay under the rtx4090-1day QOS cap (24h)
|
|
95
115
|
merge:
|
|
96
116
|
# merge.py sizes its worker pool from the cgroup/SLURM budget rather than
|
|
97
117
|
# the node's core count, and the pyramid is written zarr-natively (one
|
|
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
|
|
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
|