Skip to content

Commit 54c360b

Browse files
committed
feat: add direct signal-to-noise over-sampling helper
1 parent ffd13ba commit 54c360b

2 files changed

Lines changed: 89 additions & 0 deletions

File tree

‎autoarray/operators/over_sampling/over_sample_util.py‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,42 @@ def over_sample_size_via_radial_bins_from(
528528
return Array2D(values=sub_size, mask=grid.mask)
529529

530530

531+
def over_sample_size_via_snr_from(
532+
signal_to_noise_map: Array2D,
533+
signal_to_noise_cut: float = 3.0,
534+
sub_size_lower: int = 2,
535+
sub_size_upper: int = 4,
536+
) -> Array2D:
537+
"""
538+
Return integer sub-grid sizes by thresholding an existing signal-to-noise map.
539+
540+
Pixels strictly above the cut receive the upper size; all other pixels receive
541+
the lower size. The input is already signal-to-noise, so no noise division is
542+
performed and the cut is never lowered for low signal-to-noise data.
543+
544+
Parameters
545+
----------
546+
signal_to_noise_map
547+
The signal-to-noise of each unmasked pixel.
548+
signal_to_noise_cut
549+
The fixed threshold separating the lower and upper sub-grid sizes.
550+
sub_size_lower
551+
The sub-grid size for pixels at or below the cut.
552+
sub_size_upper
553+
The sub-grid size for pixels strictly above the cut.
554+
555+
Returns
556+
-------
557+
Array2D
558+
The sub-grid sizes, preserving the input mask and its pixel metadata.
559+
"""
560+
sub_size = np.where(
561+
signal_to_noise_map.array > signal_to_noise_cut, sub_size_upper, sub_size_lower
562+
)
563+
564+
return Array2D(values=sub_size, mask=signal_to_noise_map.mask)
565+
566+
531567
def over_sample_size_via_adapt_from(
532568
data: Array2D,
533569
noise_map: Array2D,

‎test_autoarray/operators/over_sample/test_over_sample_util.py‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,59 @@ def test__from_manual_adapt_radial_bin__centre_list_input():
238238
)
239239

240240

241+
@pytest.mark.parametrize(
242+
"values, cut, lower, upper",
243+
[
244+
([-2.0, 0.0, 2.999, 3.0, 3.001, 20.0], 3.0, 2, 4),
245+
([0.0, 0.5, 1.0, 2.0, 2.5, 2.9], 3.0, 2, 4),
246+
([-2.0, 0.0, 1.0, 1.5, 2.0, 3.0], 1.5, 1, 8),
247+
],
248+
)
249+
def test__from_snr(values, cut, lower, upper):
250+
mask = aa.Mask2D(
251+
mask=[[True, False, False], [False, False, True], [False, True, False]],
252+
pixel_scales=(0.2, 0.3),
253+
origin=(1.0, -2.0),
254+
)
255+
signal_to_noise_map = aa.Array2D(values=values, mask=mask)
256+
257+
sub_size = aa.util.over_sample.over_sample_size_via_snr_from(
258+
signal_to_noise_map=signal_to_noise_map,
259+
signal_to_noise_cut=cut,
260+
sub_size_lower=lower,
261+
sub_size_upper=upper,
262+
)
263+
264+
np.testing.assert_array_equal(
265+
sub_size.array, np.where(np.array(values) > cut, upper, lower)
266+
)
267+
assert np.issubdtype(sub_size.array.dtype, np.integer)
268+
assert sub_size.mask is mask
269+
assert sub_size.pixel_scales == (0.2, 0.3)
270+
assert sub_size.origin == (1.0, -2.0)
271+
assert sub_size.shape_native == (3, 3)
272+
np.testing.assert_array_equal(signal_to_noise_map.array, values)
273+
274+
275+
def test__from_snr_defaults():
276+
signal_to_noise_map = aa.Array2D.no_mask(
277+
values=[[0.0, 3.0, 4.0]], pixel_scales=1.0
278+
)
279+
280+
sub_size = aa.util.over_sample.over_sample_size_via_snr_from(signal_to_noise_map)
281+
282+
np.testing.assert_array_equal(sub_size.array, [2, 2, 4])
283+
284+
285+
def test__from_adapt_lowers_cut_and_divides_by_noise():
286+
data = aa.Array2D.no_mask(values=[[2.0, 4.0, 6.0]], pixel_scales=1.0)
287+
noise_map = aa.Array2D.no_mask(values=[[2.0, 2.0, 2.0]], pixel_scales=1.0)
288+
289+
sub_size = aa.util.over_sample.over_sample_size_via_adapt_from(data, noise_map)
290+
291+
np.testing.assert_array_equal(sub_size.array, [2, 4, 4])
292+
293+
241294
def test__from_adapt():
242295
mask = aa.Mask2D(
243296
mask=[[True, True, True], [True, False, False], [True, True, False]],

0 commit comments

Comments
 (0)