Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
f3d748c
Update subplot_fit_ellipse to use log_10 for data, and remove Fill op…
samlange04 Jul 30, 2025
b030cf8
Add EllipseMultipoleRelative class
samlange04 Jul 30, 2025
371d1c4
Add EllipseMultipoleRelative config
samlange04 Jul 30, 2025
50fcfef
Fix declaration of input_multipole_comps
samlange04 Jul 30, 2025
4f7f40a
fixed multipole code
Aug 7, 2025
59d9280
mix in with Sams code
Aug 7, 2025
8399338
Refactor EllipseMultipoleRelative to EllipseMultipoleScaled and add d…
samlange04 Aug 8, 2025
f9d47ab
Add option to disable the data contours in a fit ellipse subplot
samlange04 Aug 8, 2025
5f68c04
fixes
samlange04 Aug 13, 2025
9677b2e
Add fixes to align ellipse multipole angle behaviour to EPL multipole…
samlange04 Oct 13, 2025
54a170f
Add get_shape_angle function for multipole shapes
samlange04 Oct 14, 2025
79d10b5
Add get_shape_angle function for multipole shapes
samlange04 Oct 14, 2025
ea62970
Refactor config
samlange04 Oct 15, 2025
834b528
Merge branch 'main' into feature/ellipse_for_sam
samlange04 Oct 15, 2025
e01db59
Update test_multipole.py
samlange04 Oct 16, 2025
0ed099e
Update test_fit_ellipse.py
samlange04 Oct 16, 2025
fe61894
Update test_fit_ellipse.py
samlange04 Oct 16, 2025
6a15a87
Update ellipse_multipole.py
samlange04 Oct 16, 2025
ac9274c
Update shape angle to pm90deg
samlange04 Oct 16, 2025
a9de7fd
Update shape angle to pm90deg
samlange04 Oct 16, 2025
a7bba07
Merge branch 'main' into feature/ellipse_for_sam
samlange04 Oct 27, 2025
e8a982e
Fix shape angle ranges
samlange04 Nov 1, 2025
4d91bc9
Fix shape angle ranges
samlange04 Nov 1, 2025
b8f1741
first successful jit compile using .xp API
Nov 5, 2025
4977952
xp added to isothermal and shear
Nov 6, 2025
eef7e6a
more xps to get isothermal to trace
Nov 6, 2025
5ac38d0
for JAX tracing test get through all profiles
Nov 6, 2025
3d99eb3
namespace passed through to_inversion
Nov 6, 2025
8a2e530
light profiles asll pas wihtout import of jnp
Nov 8, 2025
ea11982
mass tests pass
Nov 8, 2025
54d207e
operate reverts to numpy for now
Nov 8, 2025
4a77c1c
grids added to DatasetQuantity
Nov 8, 2025
b73c557
going to take detour removing grid project
Nov 8, 2025
a9f49f6
light profiles use much simpler API
Nov 8, 2025
03c4ce7
mnass profile plotter tests pass
Nov 8, 2025
74f5f4f
removeed figue 1d stuff
Nov 8, 2025
e85bd9e
added xp to fit imaging
Nov 8, 2025
5956e3d
fix ellipse tests
Nov 8, 2025
deb8403
fixed aggregator typing isue with voer saple array
Nov 9, 2025
26013c2
black
Nov 9, 2025
71ec445
xp refactor complete
Nov 9, 2025
c20464a
all tests pass
Nov 9, 2025
d4d7f1d
RectangularSorucEPriorConfig
Nov 10, 2025
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
5 changes: 4 additions & 1 deletion autogalaxy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
mapper_from as Mapper,
) # noqa
from autoarray.inversion.pixelization.border_relocator import BorderRelocator
from autoarray.preloads import Preloads
from autoarray.preloads import mapper_indices_from
from autoarray.mask.mask_1d import Mask1D # noqa
from autoarray.mask.mask_2d import Mask2D # noqa
from autoarray.mask.derive.zoom_2d import Zoom2D
Expand All @@ -51,6 +53,7 @@
from autoarray.structures.visibilities import Visibilities # noqa
from autoarray.structures.visibilities import VisibilitiesNoiseMap # noqa

from .analysis import model_util
from .analysis.adapt_images.adapt_images import AdaptImages
from .analysis.adapt_images.adapt_image_maker import AdaptImageMaker
from . import aggregator as agg
Expand All @@ -60,6 +63,7 @@
from .ellipse.dataset_interp import DatasetInterp
from .ellipse.ellipse.ellipse import Ellipse
from .ellipse.ellipse.ellipse_multipole import EllipseMultipole
from .ellipse.ellipse.ellipse_multipole import EllipseMultipoleScaled
from .ellipse.fit_ellipse import FitEllipse
from .ellipse.model.analysis import AnalysisEllipse
from .operate.image import OperateImage
Expand All @@ -80,7 +84,6 @@
from .galaxy.galaxy import Galaxy
from .galaxy.galaxies import Galaxies
from .galaxy.redshift import Redshift
from .galaxy.stellar_dark_decomp import StellarDarkDecomp
from .galaxy.to_inversion import AbstractToInversion
from .galaxy.to_inversion import GalaxiesToInversion
from .profiles.geometry_profiles import EllProfile
Expand Down
3 changes: 1 addition & 2 deletions autogalaxy/analysis/adapt_images/adapt_images.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from __future__ import annotations
import jax.numpy as jnp
import numpy as np
from typing import TYPE_CHECKING, Dict, Optional, Tuple

Expand Down Expand Up @@ -132,7 +131,7 @@ def from_result(cls, result, use_model_images: bool = False) -> "AdaptImages":
else:
galaxy_image = result.subtracted_signal_to_noise_map_galaxy_dict[path]

minimum_galaxy_value = adapt_minimum_percent * jnp.max(galaxy_image.array)
minimum_galaxy_value = adapt_minimum_percent * np.max(galaxy_image.array)
galaxy_image[galaxy_image < minimum_galaxy_value] = minimum_galaxy_value

galaxy_name_image_dict[path] = galaxy_image
Expand Down
129 changes: 129 additions & 0 deletions autogalaxy/analysis/model_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import numpy as np
from typing import Optional, Tuple

import autofit as af


def mge_model_from(
mask_radius: float,
total_gaussians: int = 30,
gaussian_per_basis: int = 1,
centre_prior_is_uniform: bool = True,
centre: Tuple[float, float] = (0.0, 0.0),
centre_fixed: Optional[Tuple[float, float]] = None,
use_spherical: bool = False,
) -> af.Collection:
"""
Construct a Multi-Gaussian Expansion (MGE) for the lens or source galaxy light

This model is designed as a "start here" configuration for lens modeling:

- The lens and source light are represented by a Basis object composed of many
Gaussian light profiles with fixed logarithmically spaced widths (`sigma`).
- All Gaussians within each basis share common centres and ellipticity
components, reducing degeneracy while retaining flexibility.

- Users can combine with a lens mass model of their choiuce.

The resulting model provides a good balance of speed, flexibility, and accuracy
for fitting most galaxy-scale strong lenses.

This code is mostly to make the API simple for new users, hiding the technical
details of setting up an MGE. More advanced users may wish to customize the
model further.

Parameters
----------
mask_radius
The outer radius (in arcseconds) of the circular mask applied to the data.
This determines the maximum Gaussian width (`sigma`) used in the lens MGE.
lens_total_gaussians
Total number of Gaussian light profiles used in the lens MGE basis.
source_total_gaussians
Total number of Gaussian light profiles used in the source MGE basis.
lens_gaussian_per_basis
Number of separate Gaussian bases to include for the lens light profile.
Each basis has `lens_total_gaussians` components.
source_gaussian_per_basis
Number of separate Gaussian bases to include for the source light profile.
Each basis has `source_total_gaussians` components.

Returns
-------
model : af.Collection
An `autofit.Collection` containing:
- A lens galaxy at redshift 0.5, with:
* bulge light profile: MGE basis of Gaussians
* mass profile: Isothermal ellipsoid
* external shear
- A source galaxy at redshift 1.0, with:
* bulge light profile: MGE basis of Gaussians

Notes
-----
- Lens light Gaussians have widths (sigma) logarithmically spaced between 0.01"
and the mask radius.
- Source light Gaussians have widths logarithmically spaced between 0.01" and 1.0".
- Gaussian centres are free parameters but tied across all components in each
basis to reduce dimensionality.
- This function is a convenience utility: it hides the technical setup of MGE
composition and provides a ready-to-use lens model for quick experimentation.
"""

from autogalaxy.profiles.light.linear import Gaussian, GaussianSph
from autogalaxy.profiles.basis import Basis

# The sigma values of the Gaussians will be fixed to values spanning 0.01 to the mask radius, 3.0".
log10_sigma_list = np.linspace(-4, np.log10(mask_radius), total_gaussians)

# By defining the centre here, it creates two free parameters that are assigned below to all Gaussians.

if centre_fixed is not None:
centre_0 = centre[0]
centre_1 = centre[1]
elif centre_prior_is_uniform:
centre_0 = af.UniformPrior(
lower_limit=centre[0] - 0.1, upper_limit=centre[0] + 0.1
)
centre_1 = af.UniformPrior(
lower_limit=centre[1] - 0.1, upper_limit=centre[1] + 0.1
)
else:
centre_0 = af.GaussianPrior(mean=centre[0], sigma=0.3)
centre_1 = af.GaussianPrior(mean=centre[1], sigma=0.3)

if use_spherical:
model_cls = GaussianSph
else:
model_cls = Gaussian

bulge_gaussian_list = []

for j in range(gaussian_per_basis):
# A list of Gaussian model components whose parameters are customized belows.

gaussian_list = af.Collection(
af.Model(model_cls) for _ in range(total_gaussians)
)

# Iterate over every Gaussian and customize its parameters.

for i, gaussian in enumerate(gaussian_list):
gaussian.centre.centre_0 = centre_0 # All Gaussians have same y centre.
gaussian.centre.centre_1 = centre_1 # All Gaussians have same x centre.
if not use_spherical:
gaussian.ell_comps = gaussian_list[
0
].ell_comps # All Gaussians have same elliptical components.
gaussian.sigma = (
10 ** log10_sigma_list[i]
) # All Gaussian sigmas are fixed to values above.

bulge_gaussian_list += gaussian_list

# The Basis object groups many light profiles together into a single model component.

return af.Model(
Basis,
profile_list=bulge_gaussian_list,
)
12 changes: 0 additions & 12 deletions autogalaxy/analysis/plotter_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,6 @@ def should_plot(name):
mat_plot_1d=mat_plot_1d,
)

try:
if should_plot("subplot_galaxies_1d"):
galaxies_plotter.subplot_galaxies_1d()
except OverflowError:
pass

try:
if should_plot("subplot_galaxies_1d_decomposed"):
galaxies_plotter.subplot_galaxies_1d_decomposed()
except OverflowError:
pass

if should_plot("fits_galaxy_images"):

image_list = [
Expand Down
4 changes: 4 additions & 0 deletions autogalaxy/config/notation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ label:
ell_comps_1: \epsilon_{\rm 2}
multipole_comps_0: M_{\rm 1}
multipole_comps_1: M_{\rm 2}
scaled_multipole_comps_0: M_{\rm 1}
scaled_multipole_comps_1: M_{\rm 2}
flux: F
gamma: \gamma
gamma_1: \gamma
Expand Down Expand Up @@ -94,6 +96,8 @@ label_format:
ell_comps_1: '{:.4f}'
multipole_comps_0: '{:.4f}'
multipole_comps_1: '{:.4f}'
input_multipole_comps_0: '{:.4f}'
input_multipole_comps_1: '{:.4f}'
flux: '{:.4e}'
gamma: '{:.4f}'
inner_coefficient: '{:.4f}'
Expand Down
22 changes: 22 additions & 0 deletions autogalaxy/config/priors/ellipse/ellipse_multipole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,25 @@ EllipseMultipole:
limits:
lower: -inf
upper: inf

EllipseMultipoleRelative:
scaled_multipole_comps_0:
type: Uniform
lower_limit: -0.1
upper_limit: 0.1
width_modifier:
type: Absolute
value: 0.05
gaussian_limits:
lower: -inf
upper: inf
scaled_multipole_comps_1:
type: Uniform
lower_limit: -0.1
upper_limit: 0.1
width_modifier:
type: Absolute
value: 0.05
gaussian_limits:
lower: -inf
upper: inf
33 changes: 32 additions & 1 deletion autogalaxy/config/priors/mesh/rectangular.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Rectangular:
RectangularMagnification:
shape_0:
type: Uniform
lower_limit: 20.0
Expand All @@ -19,3 +19,34 @@ Rectangular:
limits:
lower: 3.0
upper: inf
RectangularSource:
shape_0:
type: Uniform
lower_limit: 20.0
upper_limit: 45.0
width_modifier:
type: Absolute
value: 8.0
limits:
lower: 3.0
upper: inf
shape_1:
type: Uniform
lower_limit: 20.0
upper_limit: 45.0
width_modifier:
type: Absolute
value: 8.0
limits:
lower: 3.0
upper: inf
weight_power:
type : Uniform
lower_limit: -5.0
upper_limit: 5.0
width_modifier:
type: Absolute
value: 2.0
limits:
lower: -100.0
upper: 100.0
2 changes: 0 additions & 2 deletions autogalaxy/config/visualize/plots.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ fit_imaging: {} # Settings for plots of fits to imagi
galaxies: # Settings for plots of galaxies (e.g. GalaxiesPlotter).
subplot_galaxies: true # Plot subplot of all quantities in each galaxies group (e.g. images, convergence)?
subplot_galaxy_images: false # Plot subplot of the image of each galaxy in the model?
subplot_galaxies_1d: false # Plot subplot of all quantities in 1D of each galaxies group (e.g. images, convergence)?
subplot_galaxies_1d_decomposed: false # Plot subplot of all quantities in 1D decomposed of each galaxies group (e.g. images, convergence)?
fits_galaxy_images: false # Output a .fits file containing images of every galaxy?

inversion: # Settings for plots of inversions (e.g. InversionPlotter).
Expand Down
Loading
Loading