Skip to content

Commit ea209d3

Browse files
committed
fix(ome_zarr): πŸ› strip leading singleton dims in TIFF-sequence chunks
_open_tiff_sequence assumed each file was a flat 2D (y, x) array, but tifffile.imread reports leading singleton dims (e.g. (1, 1, y, x)) even for a plain single-page TIFF in practice, so full_axes (seq axes + "yx") didn't match arr.ndim and to_ome_zarr("*.tif", sequence_pattern=...) raised "axes don't match array" on real acquisitions. Read the first file's own shape up front and drop any leading singleton dims before building the sequence axes string.
1 parent 83f7739 commit ea209d3

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,21 @@ def _open_tiff_sequence(
725725
) from exc
726726

727727
ts = tifffile.TiffSequence(pattern, pattern=sequence_pattern)
728+
729+
# Each file should be a single 2D (y, x) plane, but tifffile.imread can
730+
# report extra leading singleton dims (e.g. a page/sample axis) even for
731+
# a plain single-page TIFF β€” drop those so one file maps to exactly (y, x).
732+
chunkshape = tifffile.imread(ts[0]).shape
733+
lead = len(chunkshape) - 2
734+
if lead < 0 or any(s != 1 for s in chunkshape[:lead]):
735+
raise ValueError(
736+
f"expected single 2D (y, x) planes per file, got shape "
737+
f"{chunkshape} for {ts[0]!r}"
738+
)
739+
728740
arr = da.from_zarr(zarr.open(store=ts.aszarr()))
741+
if lead:
742+
arr = arr[(slice(None),) * len(ts.axes) + (0,) * lead]
729743
full_axes = ts.axes.lower() + "yx"
730744

731745
# Canonicalise to patchworks' tczyx axis order regardless of the order

β€Žtests/test_ome_zarr.pyβ€Ž

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,18 @@ def test_tiff_sequence_conversion(tmp_path):
122122

123123

124124
def test_tiff_sequence_drops_singleton_time_axis(tmp_path):
125-
"""A constant T in the pattern is dropped, keeping channel at axis 0."""
125+
"""A constant T in the pattern is dropped, keeping channel at axis 0.
126+
127+
Each file's own array has leading singleton dims (1, 1, y, x) β€” what
128+
tifffile.imread reports even for a plain single-page TIFF in practice β€”
129+
to make sure those get stripped instead of being mistaken for real
130+
sequence axes.
131+
"""
126132
tifffile = pytest.importorskip("tifffile")
127133
n_z, n_c, size = 2, 3, 8
128134
for z in range(n_z):
129135
for c in range(n_c):
130-
img = np.full((size, size), z * 10 + c, dtype="uint16")
136+
img = np.full((1, 1, size, size), z * 10 + c, dtype="uint16")
131137
tifffile.imwrite(tmp_path / f"sample_T0_Z{z:03d}_C{c}_V0.tif", img)
132138

133139
out = tmp_path / "out.zarr"

0 commit comments

Comments
Β (0)