Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions autogalaxy/analysis/model_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,39 @@ def mge_point_model_from(
return af.Model(Basis, profile_list=gaussian_list)


def hilbert_pixels_from_pixel_scale(pixel_scale: float) -> int:
"""
Return the number of Hilbert-curve pixels appropriate for a given image pixel scale.

The Hilbert pixel count controls the resolution of the Hilbert-curve ordering used
in adaptive source-plane pixelizations. Finer pixel scales resolve smaller angular
features and therefore benefit from a higher Hilbert resolution.

Parameters
----------
pixel_scale
The pixel scale of the image in arcseconds per pixel.

Returns
-------
int
The recommended number of Hilbert pixels.
"""
if not np.isfinite(pixel_scale) or pixel_scale <= 0:
raise ValueError(
f"hilbert_pixels_from_pixel_scale requires pixel_scale to be finite and > 0, got {pixel_scale}."
)

if pixel_scale > 0.06:
return 1000
elif pixel_scale > 0.04:
return 1250
elif pixel_scale >= 0.03:
return 1500
else:
return 1750
Comment on lines +230 to +237
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hilbert_pixels_from_pixel_scale silently returns a value for non-physical inputs (e.g. pixel_scale <= 0 or NaN), which can mask upstream bugs and produce misleading pixel counts. Consider validating that pixel_scale is finite and > 0 and raising a ValueError (similar to the validation in mge_point_model_from).

Copilot uses AI. Check for mistakes.


def simulator_start_here_model_from():

from autogalaxy.profiles.light.snr import Sersic
Expand Down
42 changes: 42 additions & 0 deletions test_autogalaxy/analysis/test_model_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,48 @@ def test__mge_point_model_from__shared_centre_and_ell_comps():
assert model.prior_count == 4


def test__hilbert_pixels_from_pixel_scale__above_006():
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.07) == 1000
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.1) == 1000


def test__hilbert_pixels_from_pixel_scale__between_004_and_006():
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.05) == 1250
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.061) == 1000
Comment on lines +64 to +68
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test name says it covers pixel scales between 0.04 and 0.06, but it also asserts a value for 0.061 (which is > 0.06 and therefore belongs to the "above 0.06" branch). Renaming the test or moving the 0.061 assertion to the appropriate test would make the test intent match the behavior being exercised.

Suggested change
def test__hilbert_pixels_from_pixel_scale__between_004_and_006():
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.05) == 1250
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.061) == 1000
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.061) == 1000
def test__hilbert_pixels_from_pixel_scale__between_004_and_006():
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.05) == 1250

Copilot uses AI. Check for mistakes.
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.041) == 1250


def test__hilbert_pixels_from_pixel_scale__between_003_and_004():
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.03) == 1500
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.035) == 1500


def test__hilbert_pixels_from_pixel_scale__below_003():
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.02) == 1750
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.01) == 1750


def test__hilbert_pixels_from_pixel_scale__raises_for_non_positive():
with pytest.raises(ValueError):
ag.model_util.hilbert_pixels_from_pixel_scale(0.0)
with pytest.raises(ValueError):
ag.model_util.hilbert_pixels_from_pixel_scale(-0.05)


def test__hilbert_pixels_from_pixel_scale__raises_for_non_finite():
with pytest.raises(ValueError):
ag.model_util.hilbert_pixels_from_pixel_scale(float("nan"))
with pytest.raises(ValueError):
ag.model_util.hilbert_pixels_from_pixel_scale(float("inf"))


def test__hilbert_pixels_from_pixel_scale__boundary_values():
# Exactly 0.06 is NOT > 0.06, so falls to next branch (> 0.04 → 1250)
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.06) == 1250
# Exactly 0.04 is NOT > 0.04, but IS >= 0.03 → 1500
assert ag.model_util.hilbert_pixels_from_pixel_scale(0.04) == 1500


def test__mge_point_model_from__centre_prior_bounds():
"""
When a custom centre is supplied the UniformPrior limits shift by ±0.1
Expand Down
Loading