patchworks 0.11.1__tar.gz → 0.11.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.
Files changed (78) hide show
  1. {patchworks-0.11.1 → patchworks-0.11.3}/PKG-INFO +1 -1
  2. {patchworks-0.11.1 → patchworks-0.11.3}/docs/guide/snakemake.md +11 -0
  3. patchworks-0.11.3/workflow/.snakemake/iocache/latest.pkl +0 -0
  4. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/config/config.yaml +4 -0
  5. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/rules/common.smk +5 -0
  6. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/rules/convert.smk +2 -1
  7. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/rules/segment.smk +2 -2
  8. patchworks-0.11.3/workflow/scripts/convert.py +21 -0
  9. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/scripts/prepare_tiles.py +5 -0
  10. patchworks-0.11.1/workflow/.snakemake/metadata/L3RtcC90b3kvb3V0L2ltYWdlLnphcnI= +0 -1
  11. patchworks-0.11.1/workflow/.snakemake/metadata/L3RtcC90b3kvb3V0L2xhYmVscy5kb25l +0 -1
  12. patchworks-0.11.1/workflow/.snakemake/metadata/L3RtcC90b3kvb3V0L3N0YWdlLnphcnI= +0 -1
  13. patchworks-0.11.1/workflow/.snakemake/metadata/L3RtcC90b3kvb3V0L3NlZy80LmRvbmU= +0 -1
  14. patchworks-0.11.1/workflow/.snakemake/metadata/L3RtcC90b3kvb3V0L3NlZy8wLmRvbmU= +0 -1
  15. patchworks-0.11.1/workflow/.snakemake/metadata/L3RtcC90b3kvb3V0L3NlZy8xLmRvbmU= +0 -1
  16. patchworks-0.11.1/workflow/.snakemake/metadata/L3RtcC90b3kvb3V0L3NlZy8zLmRvbmU= +0 -1
  17. patchworks-0.11.1/workflow/.snakemake/metadata/L3RtcC90b3kvb3V0L3RpbGVzLmpzb24= +0 -1
  18. patchworks-0.11.1/workflow/scripts/convert.py +0 -15
  19. {patchworks-0.11.1 → patchworks-0.11.3}/.github/workflows/docs.yml +0 -0
  20. {patchworks-0.11.1 → patchworks-0.11.3}/.github/workflows/lint.yml +0 -0
  21. {patchworks-0.11.1 → patchworks-0.11.3}/.github/workflows/release.yml +0 -0
  22. {patchworks-0.11.1 → patchworks-0.11.3}/.gitignore +0 -0
  23. {patchworks-0.11.1 → patchworks-0.11.3}/.markdownlint-cli2.yaml +0 -0
  24. {patchworks-0.11.1 → patchworks-0.11.3}/README.md +0 -0
  25. {patchworks-0.11.1 → patchworks-0.11.3}/cliff.toml +0 -0
  26. {patchworks-0.11.1 → patchworks-0.11.3}/docs/api/chunks.md +0 -0
  27. {patchworks-0.11.1 → patchworks-0.11.3}/docs/api/cluster.md +0 -0
  28. {patchworks-0.11.1 → patchworks-0.11.3}/docs/api/io.md +0 -0
  29. {patchworks-0.11.1 → patchworks-0.11.3}/docs/api/merge_tile_labels.md +0 -0
  30. {patchworks-0.11.1 → patchworks-0.11.3}/docs/api/plugins/cellpose.md +0 -0
  31. {patchworks-0.11.1 → patchworks-0.11.3}/docs/api/plugins/napari.md +0 -0
  32. {patchworks-0.11.1 → patchworks-0.11.3}/docs/api/plugins/ome_zarr.md +0 -0
  33. {patchworks-0.11.1 → patchworks-0.11.3}/docs/api/relabel.md +0 -0
  34. {patchworks-0.11.1 → patchworks-0.11.3}/docs/api/tile_process.md +0 -0
  35. {patchworks-0.11.1 → patchworks-0.11.3}/docs/examples/cellpose_2d.md +0 -0
  36. {patchworks-0.11.1 → patchworks-0.11.3}/docs/examples/cellpose_2d.py +0 -0
  37. {patchworks-0.11.1 → patchworks-0.11.3}/docs/examples/cellpose_3d.md +0 -0
  38. {patchworks-0.11.1 → patchworks-0.11.3}/docs/examples/cellpose_3d.py +0 -0
  39. {patchworks-0.11.1 → patchworks-0.11.3}/docs/examples/custom.md +0 -0
  40. {patchworks-0.11.1 → patchworks-0.11.3}/docs/examples/custom_method.py +0 -0
  41. {patchworks-0.11.1 → patchworks-0.11.3}/docs/examples/standalone_merge.md +0 -0
  42. {patchworks-0.11.1 → patchworks-0.11.3}/docs/examples/stardist.md +0 -0
  43. {patchworks-0.11.1 → patchworks-0.11.3}/docs/examples/stardist_2d.py +0 -0
  44. {patchworks-0.11.1 → patchworks-0.11.3}/docs/getting_started.md +0 -0
  45. {patchworks-0.11.1 → patchworks-0.11.3}/docs/guide/gpu_distributed.md +0 -0
  46. {patchworks-0.11.1 → patchworks-0.11.3}/docs/guide/merging.md +0 -0
  47. {patchworks-0.11.1 → patchworks-0.11.3}/docs/guide/ome_zarr_napari.md +0 -0
  48. {patchworks-0.11.1 → patchworks-0.11.3}/docs/guide/performance.md +0 -0
  49. {patchworks-0.11.1 → patchworks-0.11.3}/docs/guide/pitfalls.md +0 -0
  50. {patchworks-0.11.1 → patchworks-0.11.3}/docs/guide/skip_empty.md +0 -0
  51. {patchworks-0.11.1 → patchworks-0.11.3}/docs/guide/tiling.md +0 -0
  52. {patchworks-0.11.1 → patchworks-0.11.3}/docs/index.md +0 -0
  53. {patchworks-0.11.1 → patchworks-0.11.3}/mkdocs.yml +0 -0
  54. {patchworks-0.11.1 → patchworks-0.11.3}/pyproject.toml +0 -0
  55. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/__init__.py +0 -0
  56. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/_chunks.py +0 -0
  57. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/_cluster.py +0 -0
  58. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/_core.py +0 -0
  59. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/_distributed.py +0 -0
  60. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/_io.py +0 -0
  61. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/_merge.py +0 -0
  62. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/_relabel.py +0 -0
  63. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/plugins/__init__.py +0 -0
  64. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/plugins/cellpose.py +0 -0
  65. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/plugins/napari.py +0 -0
  66. {patchworks-0.11.1 → patchworks-0.11.3}/src/patchworks/plugins/ome_zarr.py +0 -0
  67. {patchworks-0.11.1 → patchworks-0.11.3}/tests/test_core.py +0 -0
  68. {patchworks-0.11.1 → patchworks-0.11.3}/tests/test_distributed.py +0 -0
  69. {patchworks-0.11.1 → patchworks-0.11.3}/tests/test_napari.py +0 -0
  70. {patchworks-0.11.1 → patchworks-0.11.3}/tests/test_ome_zarr.py +0 -0
  71. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/README.md +0 -0
  72. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/Snakefile +0 -0
  73. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/pixi.toml +0 -0
  74. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/profile/slurm/config.yaml +0 -0
  75. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/rules/merge.smk +0 -0
  76. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/scripts/_pw.py +0 -0
  77. {patchworks-0.11.1 → patchworks-0.11.3}/workflow/scripts/merge.py +0 -0
  78. {patchworks-0.11.1 → patchworks-0.11.3}/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.1
3
+ Version: 0.11.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
@@ -56,6 +56,7 @@ shard: false # true → pack chunks into shards (fewer files)
56
56
  channel: 0 # channel to segment (null = keep all)
57
57
  level: 0 # pyramid level (0 = full resolution)
58
58
  tile_shape: "auto" # "auto", or e.g. [16, 1024, 1024] (zyx)
59
+ gpu_memory_gb: null # for "auto" on SLURM: your segment GPU's VRAM
59
60
  overlap: 30 # halo ≈ one object diameter
60
61
  skip_empty: true # skip background tiles
61
62
  empty_threshold: null # null → Otsu
@@ -81,6 +82,11 @@ sequential_labels: true # renumber labels to a contiguous 1..N
81
82
  more (faster) jobs; very large 3-D tiles are slow. Keep `do_3D: false` (2-D
82
83
  per slice) if your objects segment fine per slice — it is much faster.
83
84
 
85
+ Tile planning runs on a **CPU** node, which cannot see the segment GPU, so
86
+ it logs `GPU memory query failed … using 8 GiB default` and sizes tiles for
87
+ 8 GiB. Harmless, but to size for the real GPU set `gpu_memory_gb:` to its
88
+ VRAM (e.g. `24`, `40`, `80`) — or just set `tile_shape` explicitly.
89
+
84
90
  ## 4. Dry-run (always do this first)
85
91
 
86
92
  Check the plan without running anything:
@@ -174,6 +180,11 @@ Snakemake is resumable — if jobs fail or you cancel, just relaunch the same
174
180
  command and it picks up only the missing tiles. To force a clean rerun, delete
175
181
  `work_dir` (or the relevant outputs).
176
182
 
183
+ The OME-ZARR conversion is **not redone** once `image.zarr` exists: the
184
+ `convert` rule's output is a marker file inside the store, so Snakemake skips it
185
+ on every later run. To force a fresh conversion, delete `image.zarr` or run
186
+ `snakemake --forcerun convert`.
187
+
177
188
  ## pixi (instead of conda)
178
189
 
179
190
  Conda is **not** required — Snakemake runs in whatever environment launches it.
@@ -15,11 +15,15 @@ work_dir: "/path/to/results" # everything is written under here
15
15
  reuse_pyramid: true # for .ims: copy its own pyramid (fast); else rebuild
16
16
  convert_chunks: null # null → patchworks' bounded auto chunks; or [c,z,y,x]
17
17
  shard: false # true → pack chunks into shards (zarr v3; fewer files)
18
+ # Re-running reuses an existing image.zarr automatically (skips conversion).
19
+ # To force a rebuild: delete image.zarr, or `snakemake --forcerun convert`.
18
20
 
19
21
  # ---- tiling -----------------------------------------------------------------
20
22
  channel: 0 # channel to segment
21
23
  level: 0 # pyramid level to segment (0 = full res)
22
24
  tile_shape: "auto" # "auto", or e.g. [16, 1024, 1024] (zyx)
25
+ gpu_memory_gb: null # for "auto" on a CPU prepare node: your segment GPU's VRAM
26
+ # (e.g. 24, 40, 80). null → 8 GiB guess + a harmless warning
23
27
  overlap: 30 # halo (≈ one object diameter)
24
28
  skip_empty: true # skip background tiles
25
29
  empty_threshold: null # null → Otsu; or a number
@@ -2,6 +2,11 @@
2
2
 
3
3
  WORK = config["work_dir"]
4
4
  IMAGE = f"{WORK}/image.zarr"
5
+ # A single file inside the store, used as the convert rule's output and as the
6
+ # dependency marker for downstream rules. Tracking a leaf file (not the
7
+ # directory) lets Snakemake skip conversion when the store already exists and
8
+ # avoids wiping the whole store on a re-run (same trick as imcf/sopa).
9
+ IMAGE_OK = f"{IMAGE}/zarr.json"
5
10
  TILES = f"{WORK}/tiles.json"
6
11
  STAGE = f"{WORK}/stage.zarr"
7
12
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  rule convert:
4
4
  output:
5
- directory(IMAGE),
5
+ # marker file inside the store; existence => skip re-conversion.
6
+ IMAGE_OK,
6
7
  script:
7
8
  "../scripts/convert.py"
@@ -2,7 +2,7 @@
2
2
 
3
3
  checkpoint prepare:
4
4
  input:
5
- IMAGE,
5
+ IMAGE_OK,
6
6
  output:
7
7
  tiles=TILES,
8
8
  stage=directory(STAGE),
@@ -15,7 +15,7 @@ rule segment:
15
15
  input:
16
16
  tiles=TILES,
17
17
  stage=STAGE,
18
- image=IMAGE,
18
+ image=IMAGE_OK,
19
19
  output:
20
20
  f"{WORK}/seg/{{index}}.done",
21
21
  script:
@@ -0,0 +1,21 @@
1
+ """Snakemake script: convert the input to a pyramidal OME-ZARR.
2
+
3
+ The rule's output is a marker file inside the store (``image.zarr/zarr.json``),
4
+ so Snakemake skips this step entirely when the store already exists — the
5
+ conversion is not redone. To force a fresh conversion, delete ``image.zarr``
6
+ (or run ``snakemake --forcerun convert``).
7
+ """
8
+
9
+ from patchworks.plugins.ome_zarr import to_ome_zarr
10
+
11
+ cfg = snakemake.config # noqa: F821 (injected by Snakemake)
12
+ chunks = cfg.get("convert_chunks")
13
+ to_ome_zarr(
14
+ cfg["input"],
15
+ str(snakemake.output[0]).removesuffix("/zarr.json"), # noqa: F821
16
+ chunks=tuple(chunks) if chunks else None,
17
+ shard=bool(cfg.get("shard", False)),
18
+ reuse_pyramid=bool(cfg.get("reuse_pyramid", False)),
19
+ progress=False,
20
+ overwrite=True,
21
+ )
@@ -20,12 +20,17 @@ image = open_image(work_dir, cfg["channel"], cfg["level"])
20
20
  ts = cfg.get("tile_shape", "auto")
21
21
  if ts == "auto":
22
22
  cp = cfg["cellpose"]
23
+ # prepare runs on a CPU node, so the segment GPU's VRAM can't be queried
24
+ # here; pass gpu_memory_gb from the config to size tiles for it (avoids the
25
+ # "GPU memory query failed" fallback). None => the built-in 8 GiB default.
26
+ gpu_gb = cfg.get("gpu_memory_gb")
23
27
  tile_shape = tuple(
24
28
  partial(
25
29
  auto_tile_shape_cellpose,
26
30
  do_3D=cp.get("do_3D", False),
27
31
  use_gpu=cp.get("gpu", True),
28
32
  diameter=cp.get("diameter"),
33
+ gpu_memory=int(gpu_gb * 1024**3) if gpu_gb else None,
29
34
  )(image.shape, image.dtype)
30
35
  )
31
36
  else:
@@ -1 +0,0 @@
1
- {"rule": "convert", "input": [], "log": [], "shellcmd": null, "params": [], "code": " \"../scripts/convert.py\"\n", "record_format_version": 6, "conda_env": null, "container_img_url": null, "software_stack_hash": "d41d8cd98f00b204e9800998ecf8427e", "job_hash": 7968324357465, "starttime": 1782285191.3091571, "endtime": 1782285191.3090107, "incomplete": false, "external_jobid": null, "input_checksums": {}}
@@ -1 +0,0 @@
1
- {"rule": "merge", "input": ["/tmp/toy/out/seg/0.done", "/tmp/toy/out/seg/1.done", "/tmp/toy/out/seg/3.done", "/tmp/toy/out/seg/4.done"], "log": [], "shellcmd": null, "params": [], "code": " \"../scripts/merge.py\"\n", "record_format_version": 6, "conda_env": null, "container_img_url": null, "software_stack_hash": "d41d8cd98f00b204e9800998ecf8427e", "job_hash": 7968324177309, "starttime": 1782285198.9120235, "endtime": 1782285198.9118745, "incomplete": false, "external_jobid": null, "input_checksums": {"/tmp/toy/out/seg/0.done": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "/tmp/toy/out/seg/1.done": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "/tmp/toy/out/seg/3.done": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "/tmp/toy/out/seg/4.done": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}}
@@ -1 +0,0 @@
1
- {"rule": "prepare", "input": ["/tmp/toy/out/image.zarr"], "log": [], "shellcmd": null, "params": [], "code": " \"../scripts/prepare_tiles.py\"\n", "record_format_version": 6, "conda_env": null, "container_img_url": null, "software_stack_hash": "d41d8cd98f00b204e9800998ecf8427e", "job_hash": 7968324357329, "starttime": 1782285193.0925362, "endtime": 1782285193.0922585, "incomplete": false, "external_jobid": null, "input_checksums": {}}
@@ -1 +0,0 @@
1
- {"rule": "segment", "input": ["/tmp/toy/out/image.zarr", "/tmp/toy/out/stage.zarr", "/tmp/toy/out/tiles.json"], "log": [], "shellcmd": null, "params": [], "code": " \"../scripts/segment_tile.py\"\n", "record_format_version": 6, "conda_env": null, "container_img_url": null, "software_stack_hash": "d41d8cd98f00b204e9800998ecf8427e", "job_hash": 7968316803128, "starttime": 1782285194.9512916, "endtime": 1782285194.9498596, "incomplete": false, "external_jobid": null, "input_checksums": {"/tmp/toy/out/tiles.json": "sha256:a7ba7de7a100b9eed2f69158d779580251e48da2c4bdb722e28c4d9a79abb411"}}
@@ -1 +0,0 @@
1
- {"rule": "segment", "input": ["/tmp/toy/out/image.zarr", "/tmp/toy/out/stage.zarr", "/tmp/toy/out/tiles.json"], "log": [], "shellcmd": null, "params": [], "code": " \"../scripts/segment_tile.py\"\n", "record_format_version": 6, "conda_env": null, "container_img_url": null, "software_stack_hash": "d41d8cd98f00b204e9800998ecf8427e", "job_hash": 7968316911209, "starttime": 1782285194.9791708, "endtime": 1782285194.9778593, "incomplete": false, "external_jobid": null, "input_checksums": {"/tmp/toy/out/tiles.json": "sha256:a7ba7de7a100b9eed2f69158d779580251e48da2c4bdb722e28c4d9a79abb411"}}
@@ -1 +0,0 @@
1
- {"rule": "segment", "input": ["/tmp/toy/out/image.zarr", "/tmp/toy/out/stage.zarr", "/tmp/toy/out/tiles.json"], "log": [], "shellcmd": null, "params": [], "code": " \"../scripts/segment_tile.py\"\n", "record_format_version": 6, "conda_env": null, "container_img_url": null, "software_stack_hash": "d41d8cd98f00b204e9800998ecf8427e", "job_hash": 7968316911362, "starttime": 1782285196.8732357, "endtime": 1782285196.871846, "incomplete": false, "external_jobid": null, "input_checksums": {"/tmp/toy/out/tiles.json": "sha256:a7ba7de7a100b9eed2f69158d779580251e48da2c4bdb722e28c4d9a79abb411"}}
@@ -1 +0,0 @@
1
- {"rule": "segment", "input": ["/tmp/toy/out/image.zarr", "/tmp/toy/out/stage.zarr", "/tmp/toy/out/tiles.json"], "log": [], "shellcmd": null, "params": [], "code": " \"../scripts/segment_tile.py\"\n", "record_format_version": 6, "conda_env": null, "container_img_url": null, "software_stack_hash": "d41d8cd98f00b204e9800998ecf8427e", "job_hash": 7968316911515, "starttime": 1782285196.9122667, "endtime": 1782285196.9108458, "incomplete": false, "external_jobid": null, "input_checksums": {"/tmp/toy/out/tiles.json": "sha256:a7ba7de7a100b9eed2f69158d779580251e48da2c4bdb722e28c4d9a79abb411"}}
@@ -1 +0,0 @@
1
- {"rule": "prepare", "input": ["/tmp/toy/out/image.zarr"], "log": [], "shellcmd": null, "params": [], "code": " \"../scripts/prepare_tiles.py\"\n", "record_format_version": 6, "conda_env": null, "container_img_url": null, "software_stack_hash": "d41d8cd98f00b204e9800998ecf8427e", "job_hash": 7968324357329, "starttime": 1782285193.0925362, "endtime": 1782285193.0908728, "incomplete": false, "external_jobid": null, "input_checksums": {}}
@@ -1,15 +0,0 @@
1
- """Snakemake script: convert the input to a pyramidal OME-ZARR."""
2
-
3
- from patchworks.plugins.ome_zarr import to_ome_zarr
4
-
5
- cfg = snakemake.config # noqa: F821 (injected by Snakemake)
6
- chunks = cfg.get("convert_chunks")
7
- to_ome_zarr(
8
- cfg["input"],
9
- snakemake.output[0], # noqa: F821
10
- chunks=tuple(chunks) if chunks else None,
11
- shard=bool(cfg.get("shard", False)),
12
- reuse_pyramid=bool(cfg.get("reuse_pyramid", False)),
13
- progress=False,
14
- overwrite=True,
15
- )
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes