Skip to content

Commit 6bb4460

Browse files
committed
Reject ambiguous TIFF axes in inference and postprocessing
1 parent af30d23 commit 6bb4460

4 files changed

Lines changed: 17 additions & 3 deletions

File tree

‎Postprocess/FRMC_post.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,10 @@ def _load_volume(path):
9393
return np.load(path, allow_pickle=False)
9494
if path.suffix.lower() in (".tif", ".tiff"):
9595
import tifffile
96-
return tifffile.imread(path)
96+
with tifffile.TiffFile(path) as image:
97+
if len(image.series) != 1 or image.series[0].axes not in {"ZYX", "QYX", "IYX"}:
98+
raise ValueError("TIFF must contain one grayscale ZYX stack")
99+
return image.series[0].asarray()
97100
raise ValueError(f"Expected .npy, .tif or .tiff: {path}")
98101

99102

‎Train_and_Inference/inference.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def load_volume(path):
2424
import tifffile
2525

2626
with tifffile.TiffFile(path) as image:
27-
if len(image.series) != 1 or any(axis in image.series[0].axes for axis in "CST"):
27+
if len(image.series) != 1 or image.series[0].axes not in {"ZYX", "QYX", "IYX"}:
2828
raise ValueError("TIFF must contain one grayscale ZYX stack, without color, channel or time axes")
2929
volume = image.series[0].asarray()
3030
else:
@@ -152,7 +152,7 @@ def sha256(path):
152152
def main(argv=None):
153153
parser = argparse.ArgumentParser(description=__doc__)
154154
parser.add_argument("--input", required=True, type=Path, help="uint8 3D ZYX TIFF or NPY raw volume")
155-
parser.add_argument("--checkpoint", required=True, type=Path, help="MNet checkpoint (.pth or .pt)")
155+
parser.add_argument("--checkpoint", required=True, type=Path, help="MNet checkpoint (.ckpt, .pth or .pt)")
156156
parser.add_argument("--output-dir", required=True, type=Path, help="New directory; existing paths are refused")
157157
parser.add_argument("--device", default="cpu", help="cpu (default) or cuda:N, e.g. cuda:0")
158158
args = parser.parse_args(argv)

‎tests/test_inference.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ def test_rejects_rgb_and_time_series_tiff(self):
8585
tifffile.imwrite(path, np.zeros((4, 8, 9), np.uint8), photometric="minisblack", metadata={"axes": "TYX"})
8686
with self.assertRaisesRegex(ValueError, "grayscale"):
8787
inference.load_volume(path)
88+
tifffile.imwrite(path, np.zeros((4, 8, 9), np.uint8), photometric="minisblack", metadata={"axes": "YZX"})
89+
with self.assertRaisesRegex(ValueError, "grayscale"):
90+
inference.load_volume(path)
8891

8992
def test_checkpoint_formats_and_dataparallel_prefix(self):
9093
source = torch.nn.Conv3d(1, 1, 1)

‎tests/test_postprocess.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@
2121

2222

2323
class PostprocessTests(unittest.TestCase):
24+
def test_tiff_axes_are_not_silently_reinterpreted(self):
25+
with tempfile.TemporaryDirectory() as temporary:
26+
path = Path(temporary) / "head.tif"
27+
tifffile.imwrite(path, np.zeros((4, 8, 9), dtype=np.float32),
28+
photometric="minisblack", metadata={"axes": "YZX"})
29+
with self.assertRaisesRegex(ValueError, "ZYX"):
30+
post._load_volume(path)
31+
2432
def test_help_does_not_import_elf(self):
2533
code = (
2634
"import sys; sys.modules['elf'] = None; "

0 commit comments

Comments
 (0)