Skip to content

Commit fe0c459

Browse files
lguerardclaude
andcommitted
fix(convert): πŸ› say which setting is missing for a glob input
A glob input without sequence_pattern fell through to bioio, which reads a single file and could only report "BioImage does not support the image: '.../*tif'" -- naming the path rather than the config key that was missing. to_ome_zarr now recognises a multi-file input and names sequence_pattern, with an example regex. run_multi checks it during its pre-flight too, so a cluster run fails before submitting anything instead of after a queue wait and a conversion attempt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 1cdf8e4 commit fe0c459

3 files changed

Lines changed: 44 additions & 0 deletions

File tree

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545

4646
from __future__ import annotations
4747

48+
import glob
4849
import logging
4950
import math
5051
from concurrent.futures import ThreadPoolExecutor
@@ -1201,6 +1202,21 @@ def _to_dask(
12011202
if sequence_pattern is not None:
12021203
arr, detected, ps = _open_tiff_sequence(path, sequence_pattern)
12031204
return arr, axes or detected, ps
1205+
if any(ch in path for ch in "*?[") or (
1206+
not Path(path).exists() and glob.glob(path)
1207+
):
1208+
# Without sequence_pattern this would be handed to bioio, which reads
1209+
# single files and reports only that it cannot handle the "format" --
1210+
# pointing at the glob rather than the missing setting.
1211+
raise ValueError(
1212+
f"{path!r} looks like a glob over several files, but "
1213+
"sequence_pattern is not set, so there is no way to tell which "
1214+
"part of each filename is Z, C or T.\n"
1215+
"Set it to a regex with named groups, e.g.\n"
1216+
" sequence_pattern: '_Z(?P<Z>\\d+)_C(?P<C>\\d+)_V\\d+'\n"
1217+
"for files like sample_Z001_C0_V0.tif. Pass a single file "
1218+
"instead if you did not mean a sequence."
1219+
)
12041220
if path.endswith(".zarr"):
12051221
arr = load_ome_zarr(source, channel=None)
12061222
ax = axes or _default_axes(arr.ndim)

β€Žtests/test_ome_zarr.pyβ€Ž

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,19 @@ def test_sharding(tmp_path):
399399
assert (
400400
getattr(_zarr.open_array(f"{out3}/0", mode="r"), "shards", None) is None
401401
)
402+
403+
404+
def test_glob_without_sequence_pattern_says_so(tmp_path):
405+
"""A glob input must name the missing setting, not blame the format.
406+
407+
Without sequence_pattern the glob fell through to bioio, which reads one
408+
file and could only report "does not support the image" -- pointing at the
409+
path instead of at the config key that was missing.
410+
"""
411+
with pytest.raises(ValueError, match="sequence_pattern is not set"):
412+
to_ome_zarr(str(tmp_path / "*.tif"), tmp_path / "out.zarr")
413+
414+
# A real single file must still reach the normal readers.
415+
with pytest.raises(Exception) as exc:
416+
to_ome_zarr(str(tmp_path / "scan.ims"), tmp_path / "o2.zarr")
417+
assert "sequence_pattern" not in str(exc.value)

β€Žworkflow/scripts/run_multi.pyβ€Ž

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,18 @@ def _spread(key):
114114
f"share a chunk layout; got {_spread(key)}"
115115
)
116116

117+
for path, cfg in zip(paths, cfgs):
118+
source = str(cfg.get("input", ""))
119+
if any(ch in source for ch in "*?[") and not cfg.get(
120+
"sequence_pattern"
121+
):
122+
problems.append(
123+
f"{path.name}: input {source!r} is a glob over several files "
124+
"but sequence_pattern is unset, so nothing says which part of "
125+
"each filename is Z/C/T. Set e.g. "
126+
r"sequence_pattern: '_Z(?P<Z>\d+)_C(?P<C>\d+)_V\d+'"
127+
)
128+
117129
names = [cfg.get("label_name") for cfg in cfgs]
118130
duplicates = {n for n in names if names.count(n) > 1}
119131
if duplicates:

0 commit comments

Comments
Β (0)