diff --git a/autoarray/mask/mask_2d.py b/autoarray/mask/mask_2d.py index e83fbea53..0ad474d5b 100644 --- a/autoarray/mask/mask_2d.py +++ b/autoarray/mask/mask_2d.py @@ -361,8 +361,8 @@ def circular( """ if os.environ.get("PYAUTO_SMALL_DATASETS") == "1": - if shape_native[0] > 15 or shape_native[1] > 15: - shape_native = (15, 15) + if shape_native[0] > 16 or shape_native[1] > 16: + shape_native = (16, 16) pixel_scales = 0.6 scale_scalar = ( pixel_scales diff --git a/autoarray/structures/grids/uniform_2d.py b/autoarray/structures/grids/uniform_2d.py index 68638790a..b29d3ce7d 100644 --- a/autoarray/structures/grids/uniform_2d.py +++ b/autoarray/structures/grids/uniform_2d.py @@ -491,14 +491,14 @@ def uniform( origin The origin of the grid's mask. respect_small_datasets - When ``PYAUTO_SMALL_DATASETS=1`` is set, grids larger than 15x15 are silently shrunk to - ``(15, 15)`` at ``pixel_scales=0.6`` to keep smoke runs fast. Pass ``False`` to opt out + When ``PYAUTO_SMALL_DATASETS=1`` is set, grids larger than 16x16 are silently shrunk to + ``(16, 16)`` at ``pixel_scales=0.6`` to keep smoke runs fast. Pass ``False`` to opt out of that shrink for grids whose spatial extent is load-bearing for the script (e.g. a visualization asserting cluster-scale critical curves at ~30-50"). """ if respect_small_datasets and os.environ.get("PYAUTO_SMALL_DATASETS") == "1": - if shape_native[0] > 15 or shape_native[1] > 15: - shape_native = (15, 15) + if shape_native[0] > 16 or shape_native[1] > 16: + shape_native = (16, 16) pixel_scales = 0.6 pixel_scales = geometry_util.convert_pixel_scales_2d(pixel_scales=pixel_scales) diff --git a/autoarray/util/dataset_util.py b/autoarray/util/dataset_util.py index 71672cf20..4871eb4f5 100644 --- a/autoarray/util/dataset_util.py +++ b/autoarray/util/dataset_util.py @@ -3,7 +3,7 @@ from pathlib import Path -SMALL_DATASETS_SHAPE_NATIVE = (15, 15) +SMALL_DATASETS_SHAPE_NATIVE = (16, 16) SMALL_DATASETS_PIXEL_SCALES = 0.6 @@ -15,10 +15,10 @@ def cap_array_2d_for_small_datasets(array_2d, pixel_scales): Returns ``(array_2d, pixel_scales)`` unchanged in any of these cases: - ``PYAUTO_SMALL_DATASETS`` is not set to ``"1"``. - - ``array_2d.shape_native`` is already at-or-below the cap (15, 15). + - ``array_2d.shape_native`` is already at-or-below the cap (16, 16). - When the env var is set and the input shape exceeds (15, 15), returns a - new ``Array2D`` center-cropped to (15, 15) with ``pixel_scales`` overridden + When the env var is set and the input shape exceeds (16, 16), returns a + new ``Array2D`` center-cropped to (16, 16) with ``pixel_scales`` overridden to 0.6 — matching the convention used by ``Mask2D.circular`` and ``Grid2D.uniform`` so the loaded dataset stays shape-consistent with masks and grids built under the same env var. diff --git a/test_autoarray/dataset/imaging/test_dataset.py b/test_autoarray/dataset/imaging/test_dataset.py index d880ab275..43952880d 100644 --- a/test_autoarray/dataset/imaging/test_dataset.py +++ b/test_autoarray/dataset/imaging/test_dataset.py @@ -196,8 +196,8 @@ def test__from_fits__small_datasets_env_caps_data_and_noise_map( noise_map_path=Path(test_data_path) / "noise_map_30x30.fits", ) - assert dataset.data.shape_native == (15, 15) - assert dataset.noise_map.shape_native == (15, 15) + assert dataset.data.shape_native == (16, 16) + assert dataset.noise_map.shape_native == (16, 16) assert dataset.pixel_scales == (0.6, 0.6) assert dataset.psf.kernel.shape_native == (5, 5) @@ -410,117 +410,117 @@ def test__psf_not_odd_x_odd_kernel__raises_error(): noise_map=noise_map, psf=psf, ) - - -def test__convolve_over_sample_size__validation_and_plumbing(): - data = aa.Array2D.no_mask(values=np.ones((11, 11)), pixel_scales=1.0) - noise_map = aa.Array2D.no_mask(values=np.ones((11, 11)), pixel_scales=1.0) - kernel_fine = aa.Array2D.no_mask(values=np.ones((9, 9)), pixel_scales=0.5) - psf = aa.Convolver(kernel=kernel_fine) - - # convolve size must be a plain int. - with pytest.raises(TypeError): - aa.Imaging( - data=data, - noise_map=noise_map, - psf=psf, - over_sample_size_lp=2, - convolve_over_sample_size_lp=2.0, - ) - - # k x s coupling: every over_sample_size entry must be divisible by the - # convolve size — a non-divisible int raises, divisible ints and adaptive - # arrays are legal. - with pytest.raises(aa.exc.DatasetException): - aa.Imaging( - data=data, - noise_map=noise_map, - psf=psf, - over_sample_size_lp=3, - convolve_over_sample_size_lp=2, - ) - - sub_size_adaptive = np.full(fill_value=2, shape=data.shape_slim) - sub_size_adaptive[0] = 4 - - dataset_adaptive = aa.Imaging( - data=data, - noise_map=noise_map, - psf=psf, - over_sample_size_lp=aa.Array2D(values=sub_size_adaptive, mask=data.mask), - convolve_over_sample_size_lp=2, - ) - assert dataset_adaptive.convolve_over_sample_size_lp == 2 - - sub_size_bad = np.full(fill_value=2, shape=data.shape_slim) - sub_size_bad[0] = 3 - - with pytest.raises(aa.exc.DatasetException): - aa.Imaging( - data=data, - noise_map=noise_map, - psf=psf, - over_sample_size_lp=aa.Array2D(values=sub_size_bad, mask=data.mask), - convolve_over_sample_size_lp=2, - ) - - # Differing lp / pixelization convolve sizes are not supported (single PSF kernel). - with pytest.raises(aa.exc.DatasetException): - aa.Imaging( - data=data, - noise_map=noise_map, - psf=psf, - over_sample_size_lp=2, - over_sample_size_pixelization=4, - convolve_over_sample_size_lp=2, - convolve_over_sample_size_pixelization=4, - ) - - # Valid dataset: the psf carries the convolve size and apply_mask preserves it, - # precomputing the fine state and building the blurring grid at the fine resolution. - dataset = aa.Imaging( - data=data, - noise_map=noise_map, - psf=psf, - over_sample_size_lp=2, - convolve_over_sample_size_lp=2, - ) - - assert dataset.convolve_over_sample_size_lp == 2 - assert dataset.psf.convolve_over_sample_size == 2 - - mask = aa.Mask2D.circular(shape_native=(11, 11), pixel_scales=1.0, radius=3.5) - masked = dataset.apply_mask(mask=mask) - - assert masked.convolve_over_sample_size_lp == 2 - assert masked.psf.convolve_over_sample_size == 2 - assert masked.psf._state is not None - assert masked.psf._state.sub_slim_to_fine_slim is not None - - # The blurring grid footprint uses the kernel's image-resolution shape (5x5 for a - # 9x9 fine kernel at s=2) and is evaluated at the fine resolution. - blurring_mask = mask.derive_mask.blurring_from( - kernel_shape_native=(5, 5), allow_padding=True - ) - assert np.array(masked.grids.blurring.over_sampled).shape == ( - blurring_mask.pixels_in_mask * 4, - 2, - ) - - -def test__convolve_over_sample_size__sparse_operator_guard(): - data = aa.Array2D.no_mask(values=np.ones((11, 11)), pixel_scales=1.0) - noise_map = aa.Array2D.no_mask(values=np.ones((11, 11)), pixel_scales=1.0) - kernel_fine = aa.Array2D.no_mask(values=np.ones((9, 9)), pixel_scales=0.5) - psf = aa.Convolver(kernel=kernel_fine) - - dataset = aa.Imaging( - data=data, - noise_map=noise_map, - psf=psf, - over_sample_size_pixelization=2, - convolve_over_sample_size_pixelization=2, - ) - - with pytest.raises(aa.exc.DatasetException): - dataset.apply_sparse_operator() + + +def test__convolve_over_sample_size__validation_and_plumbing(): + data = aa.Array2D.no_mask(values=np.ones((11, 11)), pixel_scales=1.0) + noise_map = aa.Array2D.no_mask(values=np.ones((11, 11)), pixel_scales=1.0) + kernel_fine = aa.Array2D.no_mask(values=np.ones((9, 9)), pixel_scales=0.5) + psf = aa.Convolver(kernel=kernel_fine) + + # convolve size must be a plain int. + with pytest.raises(TypeError): + aa.Imaging( + data=data, + noise_map=noise_map, + psf=psf, + over_sample_size_lp=2, + convolve_over_sample_size_lp=2.0, + ) + + # k x s coupling: every over_sample_size entry must be divisible by the + # convolve size — a non-divisible int raises, divisible ints and adaptive + # arrays are legal. + with pytest.raises(aa.exc.DatasetException): + aa.Imaging( + data=data, + noise_map=noise_map, + psf=psf, + over_sample_size_lp=3, + convolve_over_sample_size_lp=2, + ) + + sub_size_adaptive = np.full(fill_value=2, shape=data.shape_slim) + sub_size_adaptive[0] = 4 + + dataset_adaptive = aa.Imaging( + data=data, + noise_map=noise_map, + psf=psf, + over_sample_size_lp=aa.Array2D(values=sub_size_adaptive, mask=data.mask), + convolve_over_sample_size_lp=2, + ) + assert dataset_adaptive.convolve_over_sample_size_lp == 2 + + sub_size_bad = np.full(fill_value=2, shape=data.shape_slim) + sub_size_bad[0] = 3 + + with pytest.raises(aa.exc.DatasetException): + aa.Imaging( + data=data, + noise_map=noise_map, + psf=psf, + over_sample_size_lp=aa.Array2D(values=sub_size_bad, mask=data.mask), + convolve_over_sample_size_lp=2, + ) + + # Differing lp / pixelization convolve sizes are not supported (single PSF kernel). + with pytest.raises(aa.exc.DatasetException): + aa.Imaging( + data=data, + noise_map=noise_map, + psf=psf, + over_sample_size_lp=2, + over_sample_size_pixelization=4, + convolve_over_sample_size_lp=2, + convolve_over_sample_size_pixelization=4, + ) + + # Valid dataset: the psf carries the convolve size and apply_mask preserves it, + # precomputing the fine state and building the blurring grid at the fine resolution. + dataset = aa.Imaging( + data=data, + noise_map=noise_map, + psf=psf, + over_sample_size_lp=2, + convolve_over_sample_size_lp=2, + ) + + assert dataset.convolve_over_sample_size_lp == 2 + assert dataset.psf.convolve_over_sample_size == 2 + + mask = aa.Mask2D.circular(shape_native=(11, 11), pixel_scales=1.0, radius=3.5) + masked = dataset.apply_mask(mask=mask) + + assert masked.convolve_over_sample_size_lp == 2 + assert masked.psf.convolve_over_sample_size == 2 + assert masked.psf._state is not None + assert masked.psf._state.sub_slim_to_fine_slim is not None + + # The blurring grid footprint uses the kernel's image-resolution shape (5x5 for a + # 9x9 fine kernel at s=2) and is evaluated at the fine resolution. + blurring_mask = mask.derive_mask.blurring_from( + kernel_shape_native=(5, 5), allow_padding=True + ) + assert np.array(masked.grids.blurring.over_sampled).shape == ( + blurring_mask.pixels_in_mask * 4, + 2, + ) + + +def test__convolve_over_sample_size__sparse_operator_guard(): + data = aa.Array2D.no_mask(values=np.ones((11, 11)), pixel_scales=1.0) + noise_map = aa.Array2D.no_mask(values=np.ones((11, 11)), pixel_scales=1.0) + kernel_fine = aa.Array2D.no_mask(values=np.ones((9, 9)), pixel_scales=0.5) + psf = aa.Convolver(kernel=kernel_fine) + + dataset = aa.Imaging( + data=data, + noise_map=noise_map, + psf=psf, + over_sample_size_pixelization=2, + convolve_over_sample_size_pixelization=2, + ) + + with pytest.raises(aa.exc.DatasetException): + dataset.apply_sparse_operator() diff --git a/test_autoarray/mask/test_mask_2d.py b/test_autoarray/mask/test_mask_2d.py index ef35ad6ac..063c0fbd8 100644 --- a/test_autoarray/mask/test_mask_2d.py +++ b/test_autoarray/mask/test_mask_2d.py @@ -134,11 +134,11 @@ def test__circular__small_datasets_env__oversized_radius_clamped_to_disc(monkeyp mask = aa.Mask2D.circular(shape_native=(100, 100), pixel_scales=0.1, radius=6.0) - assert mask.shape_native == (15, 15) + assert mask.shape_native == (16, 16) assert mask.pixel_scales == (0.6, 0.6) assert mask.is_circular n_unmasked = int((~mask.array).sum()) - assert 100 < n_unmasked < 225 + assert 100 < n_unmasked < 256 def test__circular__small_datasets_env__in_bounds_radius_unchanged(monkeypatch): @@ -161,7 +161,7 @@ def test__circular__small_datasets_env__tuple_pixel_scales_oversized_radius_clam shape_native=(200, 200), pixel_scales=(0.1, 0.1), radius=7.5 ) - assert mask.shape_native == (15, 15) + assert mask.shape_native == (16, 16) assert mask.is_circular diff --git a/test_autoarray/util/test_dataset_util.py b/test_autoarray/util/test_dataset_util.py index d59585677..308ac05c6 100644 --- a/test_autoarray/util/test_dataset_util.py +++ b/test_autoarray/util/test_dataset_util.py @@ -59,12 +59,13 @@ def test__env_set__shape_above_cap__center_crops_and_overrides_pixel_scales( assert result.shape_native == SMALL_DATASETS_SHAPE_NATIVE assert pixel_scales == SMALL_DATASETS_PIXEL_SCALES - h0 = (150 - 15) // 2 - expected = raw[h0:h0 + 15, h0:h0 + 15] + cap_h, cap_w = SMALL_DATASETS_SHAPE_NATIVE + h0, w0 = (150 - cap_h) // 2, (150 - cap_w) // 2 + expected = raw[h0:h0 + cap_h, w0:w0 + cap_w] assert (result.native.array == expected).all() -def test__env_set__non_square_above_cap__center_crops_to_15x15(monkeypatch): +def test__env_set__non_square_above_cap__center_crops_to_16x16(monkeypatch): monkeypatch.setenv("PYAUTO_SMALL_DATASETS", "1") array = _array_2d((100, 50))