Skip to content

Commit 17885f3

Browse files
authored
Merge pull request #431 from PyAutoLabs/feature/small-datasets-loader-pixel-scales
fix: relabel at-or-below-cap data at the capped pixel scale
2 parents 59b0f19 + 5006f34 commit 17885f3

2 files changed

Lines changed: 57 additions & 22 deletions

File tree

autoarray/util/dataset_util.py

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,30 @@
1010
def cap_array_2d_for_small_datasets(array_2d, pixel_scales):
1111
"""
1212
Center-crop a 2D autoarray to the small-datasets cap when
13-
``PYAUTO_SMALL_DATASETS=1`` is active.
14-
15-
Returns ``(array_2d, pixel_scales)`` unchanged in any of these cases:
16-
17-
- ``PYAUTO_SMALL_DATASETS`` is not set to ``"1"``.
18-
- ``array_2d.shape_native`` is already at-or-below the cap (16, 16).
19-
20-
When the env var is set and the input shape exceeds (16, 16), returns a
21-
new ``Array2D`` center-cropped to (16, 16) with ``pixel_scales`` overridden
22-
to 0.6 — matching the convention used by ``Mask2D.circular`` and
23-
``Grid2D.uniform`` so the loaded dataset stays shape-consistent with masks
24-
and grids built under the same env var.
13+
``PYAUTO_SMALL_DATASETS=1`` is active, and relabel it at the capped
14+
pixel scale.
15+
16+
Returns ``(array_2d, pixel_scales)`` unchanged only when
17+
``PYAUTO_SMALL_DATASETS`` is not set to ``"1"``.
18+
19+
When the env var is set, ``pixel_scales`` is always overridden to 0.6 —
20+
matching the convention used by ``Mask2D.circular`` and ``Grid2D.uniform``
21+
so the loaded dataset stays shape-consistent with masks and grids built
22+
under the same env var — and the shape is handled per case:
23+
24+
- Input shape exceeds (16, 16): center-cropped to (16, 16).
25+
- Input shape is already at-or-below the cap: kept as-is, because a capped
26+
simulator wrote it at 0.6 already. Only the scale is corrected.
27+
28+
That second case must still rebuild the ``Array2D``, not just return a
29+
corrected scalar: the array is constructed by the caller before this call
30+
and carries its own geometry, so an uncorrected array would keep the
31+
caller's uncapped scale no matter what scalar is returned. Leaving it
32+
uncorrected mislabels the frame 6x (±0.8" instead of ±4.8" for a 16x16
33+
field), which pushes off-centre galaxies outside the frame; their
34+
non-negative linear intensity solve then correctly returns exactly 0.0 and
35+
the failure surfaces far downstream as a collapsed prior rather than as a
36+
geometry error (PyAutoArray #430).
2537
2638
The same env var is honoured for shape construction in
2739
``Mask2D.circular`` and ``Grid2D.uniform`` (and by ``should_simulate``
@@ -36,12 +48,18 @@ def cap_array_2d_for_small_datasets(array_2d, pixel_scales):
3648
if os.environ.get("PYAUTO_SMALL_DATASETS") != "1":
3749
return array_2d, pixel_scales
3850

51+
from autoarray.structures.arrays.uniform_2d import Array2D
52+
3953
h, w = array_2d.shape_native
4054
cap_h, cap_w = SMALL_DATASETS_SHAPE_NATIVE
4155
if h <= cap_h and w <= cap_w:
42-
return array_2d, pixel_scales
43-
44-
from autoarray.structures.arrays.uniform_2d import Array2D
56+
return (
57+
Array2D.no_mask(
58+
values=array_2d.native.array,
59+
pixel_scales=SMALL_DATASETS_PIXEL_SCALES,
60+
),
61+
SMALL_DATASETS_PIXEL_SCALES,
62+
)
4563

4664
h0, w0 = (h - cap_h) // 2, (w - cap_w) // 2
4765
cropped = array_2d.native.array[h0:h0 + cap_h, w0:w0 + cap_w]

test_autoarray/util/test_dataset_util.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,41 @@ def test__env_unset__returns_inputs_unchanged(monkeypatch):
2525
assert pixel_scales == 0.08
2626

2727

28-
def test__env_set__shape_already_at_cap__returns_inputs_unchanged(monkeypatch):
28+
def test__env_set__shape_already_at_cap__relabels_pixel_scales_without_cropping(
29+
monkeypatch,
30+
):
2931
monkeypatch.setenv("PYAUTO_SMALL_DATASETS", "1")
3032

3133
array = _array_2d(SMALL_DATASETS_SHAPE_NATIVE, pixel_scales=0.08)
3234
result, pixel_scales = cap_array_2d_for_small_datasets(array, 0.08)
3335

34-
assert result is array
35-
assert pixel_scales == 0.08
36+
assert result is not array
37+
assert result.shape_native == SMALL_DATASETS_SHAPE_NATIVE
38+
assert pixel_scales == SMALL_DATASETS_PIXEL_SCALES
39+
assert result.pixel_scales == (
40+
SMALL_DATASETS_PIXEL_SCALES,
41+
SMALL_DATASETS_PIXEL_SCALES,
42+
)
43+
assert (result.native.array == array.native.array).all()
3644

3745

38-
def test__env_set__shape_below_cap__returns_inputs_unchanged(monkeypatch):
46+
def test__env_set__shape_below_cap__relabels_pixel_scales_without_cropping(monkeypatch):
3947
monkeypatch.setenv("PYAUTO_SMALL_DATASETS", "1")
4048

41-
array = _array_2d((10, 10), pixel_scales=0.08)
49+
raw = np.arange(10 * 10, dtype=float).reshape(10, 10)
50+
array = aa.Array2D.no_mask(values=raw, pixel_scales=0.08)
51+
4252
result, pixel_scales = cap_array_2d_for_small_datasets(array, 0.08)
4353

44-
assert result is array
45-
assert pixel_scales == 0.08
54+
assert result is not array
55+
# Shape is PRESERVED — the below-cap branch relabels, it must never crop.
56+
assert result.shape_native == (10, 10)
57+
assert pixel_scales == SMALL_DATASETS_PIXEL_SCALES
58+
assert result.pixel_scales == (
59+
SMALL_DATASETS_PIXEL_SCALES,
60+
SMALL_DATASETS_PIXEL_SCALES,
61+
)
62+
assert (result.native.array == raw).all()
4663

4764

4865
def test__env_set__shape_above_cap__center_crops_and_overrides_pixel_scales(

0 commit comments

Comments
 (0)