From 402ffba7d862988d276fd35a691c80b46eb525b1 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Wed, 22 Jul 2026 10:23:39 +0100 Subject: [PATCH] fix(convolver): build from_gaussian kernel at full size under PYAUTO_SMALL_DATASETS `Convolver.from_gaussian` evaluates its Gaussian on a `Grid2D.uniform`, which the `PYAUTO_SMALL_DATASETS` fast-mode cap silently shrinks to 16x16, and then wraps those values in an `Array2D` at the caller's uncapped `shape_native`. For any kernel above 16x16 the two disagree and construction raises: ArrayException: array_2d_slim.shape = 256 mask_2d.pixels_in_mask = 961, shape_native (31, 31) A kernel's shape is intrinsic to the convolution operator rather than a dataset size, so the dataset cap must not reach it. Pass the existing `Grid2D.uniform(respect_small_datasets=False)` opt-out. Unblocks `imaging/data_preparation/manual/mask_irregular.py` in both the autolens and autogalaxy workspaces, which failed in fast-mode runs. No workspace changes needed. Closes #397 Co-Authored-By: Claude Opus 4.8 --- autoarray/operators/convolver.py | 13 ++++++++++-- test_autoarray/operators/test_convolver.py | 24 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/autoarray/operators/convolver.py b/autoarray/operators/convolver.py index ef793f54..702d1f16 100644 --- a/autoarray/operators/convolver.py +++ b/autoarray/operators/convolver.py @@ -699,7 +699,10 @@ def from_gaussian( Parameters ---------- shape_native - The 2D shape of the mask the array is paired with. + The 2D shape of the mask the array is paired with. The kernel is always built at this + size, including when ``PYAUTO_SMALL_DATASETS=1`` is set — a kernel's shape is intrinsic + to the convolution operator, not a dataset size, so the fast-mode dataset cap does not + apply to it. pixel_scales The (y,x) arcsecond-to-pixel units conversion factor of every pixel. If this is input as a `float`, it is converted to a (float, float). @@ -718,7 +721,13 @@ def from_gaussian( ``pixel_scales`` input should be the fine resolution (image pixel scale divided by this size). """ - grid = Grid2D.uniform(shape_native=shape_native, pixel_scales=pixel_scales) + grid = Grid2D.uniform( + shape_native=shape_native, + pixel_scales=pixel_scales, + # The kernel is wrapped in an `Array2D` at `shape_native` below, so letting the + # `PYAUTO_SMALL_DATASETS` cap shrink this grid would leave the two inconsistent. + respect_small_datasets=False, + ) grid_shifted = np.subtract(grid.array, centre) grid_radius = np.sqrt(np.sum(grid_shifted**2.0, 1)) theta_coordinate_to_profile = np.arctan2( diff --git a/test_autoarray/operators/test_convolver.py b/test_autoarray/operators/test_convolver.py index 70f26466..43adfab6 100644 --- a/test_autoarray/operators/test_convolver.py +++ b/test_autoarray/operators/test_convolver.py @@ -53,6 +53,30 @@ def test__from_gaussian__normalized__kernel_values_match_expected(): ) +def test__from_gaussian__small_datasets__kernel_keeps_full_requested_shape(monkeypatch): + """ + The `PYAUTO_SMALL_DATASETS` fast-mode cap shrinks datasets (and the grids paired with + them) to 16x16, but a convolution kernel's shape is intrinsic to the operator. If the + cap reached the grid the Gaussian is evaluated on, its 256 values would be wrapped in an + `Array2D` at the uncapped `shape_native` of 961, raising an `ArrayException`. + """ + monkeypatch.setenv("PYAUTO_SMALL_DATASETS", "1") + + convolver = aa.Convolver.from_gaussian( + shape_native=(31, 31), + pixel_scales=0.1, + sigma=0.1, + ) + + assert convolver.kernel.shape_native == (31, 31) + + image = aa.Array2D.ones(shape_native=(16, 16), pixel_scales=0.1) + + blurred_image = convolver.convolved_image_from(image=image, blurring_image=None) + + assert blurred_image.shape_native == (16, 16) + + def test__normalize__ones_kernel__each_element_equals_one_ninth(): kernel_data = aa.Array2D.ones(shape_native=(3, 3), pixel_scales=1.0)