from __future__ import annotations import numpy as np import pytest from image_filter import ( DimensionInferenceError, GaborFilter, SliceWise, UnsupportedDimensionError, infer_spatial_layout, ) def test_short_volume_or_rgb_without_metadata_is_ambiguous(): with pytest.raises(DimensionInferenceError, match="ambiguous"): infer_spatial_layout(np.zeros((16, 17, 3))) assert infer_spatial_layout(np.zeros((16, 17, 3)), {"spatial_dims": 3}).dimension == 3 def test_4d_requires_channel_axis(): image = np.zeros((8, 9, 10, 2)) with pytest.raises(DimensionInferenceError, match="requires"): infer_spatial_layout(image) assert infer_spatial_layout(image, {"channel_axis": 3}).dimension == 3 def test_intrinsically_2d_filter_rejects_volume_in_strict_mode(): with pytest.raises(UnsupportedDimensionError, match="SliceWise"): GaborFilter().apply(np.ones((6, 7, 8)), {"spatial_dims": 3}) def test_slice_wise_is_explicit_and_axis_sensitive(): image = np.zeros((4, 12, 13), dtype=np.float32) image[:, 5, :] = 1 adapter = SliceWise(GaborFilter(frequency=0.2), axis=0) result = adapter.apply(image) from skimage.filters import gabor expected = np.stack([np.hypot(*gabor(plane.astype(np.float64), frequency=.2, sigma_x=2, sigma_y=2)) for plane in image]) np.testing.assert_allclose(result.image, expected) assert result.image.shape == image.shape assert result.image.dtype == np.float64 assert np.isfinite(result.image).all() assert result.metadata["processing_history"][-1]["filter"] == "SliceWise" nested = result.metadata["processing_history"][-1]["parameters"]["filter"] assert nested["filter"] == "GaborFilter" assert nested["parameters"]["frequency"] == 0.2 def test_slice_wise_rejects_non_spatial_axis(): image = np.ones((5, 6, 7, 3)) with pytest.raises(UnsupportedDimensionError, match="spatial axes"): SliceWise(GaborFilter(), axis=3).apply(image, {"channel_axis": 3})