Skip to content

Commit dec498c

Browse files
author
Niek Wielders
committed
Merge branch 'feature/cored_NFW' of https://github.com/Jammy2211/PyAutoGalaxy into feature/cored_NFW
2 parents d867d6a + ed50465 commit dec498c

File tree

26 files changed

+497
-813
lines changed

26 files changed

+497
-813
lines changed

CONTRIBUTING.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
# Community Guidelines
2+
3+
We strive to maintain a welcoming, respectful, and inclusive community. All contributors—whether opening issues, submitting pull requests, reviewing code, or participating in discussions—are expected to follow these guidelines.
4+
5+
- Be respectful and considerate of others.
6+
- Assume good intent and be patient, especially with newcomers.
7+
- Keep feedback constructive and focused on the work, not the person.
8+
- Communicate clearly and professionally.
9+
- Respect maintainers’ time and decisions.
10+
11+
Harassment, discrimination, or abusive behavior of any kind will not be tolerated.
12+
13+
This project follows our [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you agree to uphold it.
14+
15+
### Reporting concerns
16+
If you experience or witness behavior that violates these guidelines or the Code of Conduct, please contact the project maintainers privately.
17+
18+
119
# Contributing
220

321
Contributions are welcome and greatly appreciated!
@@ -74,3 +92,4 @@ Before you submit a pull request, check that it meets these guidelines:
7492
7593
1. The pull request should include new tests for all the core routines that have been developed.
7694
2. If the pull request adds functionality, the docs should be updated accordingly.
95+

README.rst

Lines changed: 35 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ PyAutoGalaxy: Open-Source Multi Wavelength Galaxy Structure & Morphology
3434

3535
`Installation Guide <https://pyautogalaxy.readthedocs.io/en/latest/installation/overview.html>`_ |
3636
`readthedocs <https://pyautogalaxy.readthedocs.io/en/latest/index.html>`_ |
37-
`Introduction on Binder <https://mybinder.org/v2/gh/Jammy2211/autogalaxy_workspace/release?filepath=start_here.ipynb>`_ |
37+
`Introduction on Colab <https://colab.research.google.com/github/Jammy2211/autogalaxy_workspace/blob/release/start_here.ipynb>`_
3838
`HowToGalaxy <https://pyautogalaxy.readthedocs.io/en/latest/howtogalaxy/howtogalaxy.html>`_
3939

4040
**PyAutoGalaxy** is software for analysing the morphologies and structures of galaxies:
@@ -54,7 +54,7 @@ The following links are useful for new starters:
5454

5555
- `The PyAutoGalaxy readthedocs <https://pyautogalaxy.readthedocs.io/en/latest>`_, which includes `an overview of PyAutoGalaxy's core features <https://pyautogalaxy.readthedocs.io/en/latest/overview/overview_1_start_here.html>`_, `a new user starting guide <https://pyautogalaxy.readthedocs.io/en/latest/overview/overview_2_new_user_guide.html>`_ and `an installation guide <https://pyautogalaxy.readthedocs.io/en/latest/installation/overview.html>`_.
5656

57-
- `The introduction Jupyter Notebook on Binder <https://mybinder.org/v2/gh/Jammy2211/autogalaxy_workspace/release?filepath=start_here.ipynb>`_, where you can try **PyAutoGalaxy** in a web browser (without installation).
57+
- `The introduction Jupyter Notebook on Google Colab <https://colab.research.google.com/github/Jammy2211/autogalaxy_workspace/blob/release/start_here.ipynb>`_, where you can try **PyAutoGalaxy** in a web browser (without installation).
5858

5959
- `The autogalaxy_workspace GitHub repository <https://github.com/Jammy2211/autogalaxy_workspace>`_, which includes example scripts and the `HowToGalaxy Jupyter notebook lectures <https://github.com/Jammy2211/autogalaxy_workspace/tree/main/notebooks/howtogalaxy>`_ which give new users a step-by-step introduction to **PyAutoGalaxy**.
6060

@@ -63,149 +63,43 @@ Core Aims
6363

6464
**PyAutoGalaxy** has three core aims:
6565

66-
- **Model Complexity**: Fitting complex galaxy morphology models (e.g. Multi Gaussian Expansion, Shapelets, Ellipse Fitting, Irregular Meshes) that go beyond just simple Sersic fitting (which is supported too!).
66+
- **Big Data**: Scaling automated Sérsic fitting to extremely large datasets, *accelerated with JAX on GPUs and using tools like an SQL database to **build a scalable scientific workflow***.
6767

68-
- **Data Variety**: Support for many data types (e.g. CCD imaging, interferometry, multi-band imaging) which can be fitted independently or simultaneously.
68+
- **Model Complexity**: Fitting complex galaxy morphology models (e.g. Multi Gaussian Expansion, Shapelets, Ellipse Fitting, Irregular Meshes) that go beyond just simple Sérsic fitting.
6969

70-
- **Big Data**: Scaling automated analysis to extremely large datasets, using tools like an SQL database to build a scalable scientific workflow.
70+
- **Data Variety**: Support for many data types (e.g. CCD imaging, interferometry, multi-band imaging) which can be fitted independently or simultaneously.
7171

7272
A complete overview of the software's aims is provided in our `Journal of Open Source Software paper <https://joss.theoj.org/papers/10.21105/joss.04475>`_.
7373

74-
API Overview
74+
Community & Support
75+
-------------------
76+
77+
Support for **PyAutoGalaxy** is available via our Slack workspace, where the community shares updates, discusses
78+
galaxy modeling and analysis, and helps troubleshoot problems.
79+
80+
Slack is invitation-only. If you’d like to join, please send an email requesting an invite.
81+
82+
For installation issues, bug reports, or feature requests, please raise an issue on the [GitHub issues page](https://github.com/Jammy2211/PyAutoGalaxy/issues).
83+
84+
Here’s a clean, **AutoGalaxy**-appropriate rewrite, keeping the same structure and tone but removing lensing-specific language:
85+
86+
HowToGalaxy
87+
-----------
88+
89+
For users less familiar with galaxy analysis, Bayesian inference, and scientific analysis, you may wish to read through
90+
the **HowToGalaxy** lectures. These introduce the basic principles of galaxy modeling and Bayesian inference, with
91+
the material pitched at undergraduate level and above.
92+
93+
A complete overview of the lectures is provided on the `HowToGalaxy readthedocs page <https://pyautogalaxy.readthedocs.io/en/latest/howtogalaxy/howtogalaxy.html`_
94+
95+
Citations
96+
---------
97+
98+
Information on how to cite **PyAutoGalaxy** in publications can be found `on the citations page <https://github.com/Jammy2211/PyAutoGalaxy/blob/main/CITATIONS.rst>`_.
99+
100+
Contributing
75101
------------
76102

77-
Galaxy morphology calculations are performed in **PyAutoGalaaxy** by building a ``Plane`` object from ``LightProfile``
78-
and ``Galaxy`` objects. We create a simple galaxy system where a redshift 0.5
79-
``Galaxy`` with an ``Sersic`` ``LightProfile`` representing a bulge and an ``Exponential`` ``LightProfile``
80-
representing a disk.
81-
82-
.. code-block:: python
83-
84-
import autogalaxy as ag
85-
import autogalaxy.plot as aplt
86-
87-
"""
88-
To describe the galaxy emission two-dimensional grids of (y,x) Cartesian
89-
coordinates are used.
90-
"""
91-
grid = ag.Grid2D.uniform(
92-
shape_native=(50, 50),
93-
pixel_scales=0.05, # <- Conversion from pixel units to arc-seconds.
94-
)
95-
96-
"""
97-
The galaxy has an elliptical sersic light profile representing its bulge.
98-
"""
99-
bulge=ag.lp.Sersic(
100-
centre=(0.0, 0.0),
101-
ell_comps=ag.convert.ell_comps_from(axis_ratio=0.9, angle=45.0),
102-
intensity=1.0,
103-
effective_radius=0.6,
104-
sersic_index=3.0,
105-
)
106-
107-
"""
108-
The galaxy also has an elliptical exponential disk
109-
"""
110-
disk = ag.lp.Exponential(
111-
centre=(0.0, 0.0),
112-
ell_comps=ag.convert.ell_comps_from(axis_ratio=0.7, angle=30.0),
113-
intensity=0.5,
114-
effective_radius=1.6,
115-
)
116-
117-
"""
118-
We combine the above light profiles to compose a galaxy at redshift 1.0.
119-
"""
120-
galaxy = ag.Galaxy(redshift=1.0, bulge=bulge, disk=disk)
121-
122-
"""
123-
We create a Plane, which in this example has just one galaxy but can
124-
be extended for datasets with many galaxies.
125-
"""
126-
plane = ag.Plane(
127-
galaxies=[galaxy],
128-
)
129-
130-
"""
131-
We can use the Grid2D and Plane to perform many calculations, for example
132-
plotting the image of the galaxyed source.
133-
"""
134-
plane_plotter = aplt.GalaxiesPlotter(plane=plane, grid=grid)
135-
plane_plotter.figures_2d(image=True)
136-
137-
138-
With **PyAutoGalaxy**, you can begin modeling a galaxy in just a couple of minutes. The example below demonstrates a
139-
simple analysis which fits a galaxy's light.
140-
141-
.. code-block:: python
142-
143-
import autofit as af
144-
import autogalaxy as ag
145-
146-
import os
147-
148-
"""
149-
Load Imaging data of the strong galaxy from the dataset folder of the workspace.
150-
"""
151-
dataset = ag.Imaging.from_fits(
152-
data_path="/path/to/dataset/image.fits",
153-
noise_map_path="/path/to/dataset/noise_map.fits",
154-
psf_path="/path/to/dataset/psf.fits",
155-
pixel_scales=0.1,
156-
)
157-
158-
"""
159-
Create a mask for the data, which we setup as a 3.0" circle.
160-
"""
161-
mask = ag.Mask2D.circular(
162-
shape_native=dataset.shape_native,
163-
pixel_scales=dataset.pixel_scales,
164-
radius=3.0
165-
)
166-
167-
"""
168-
We model the galaxy using an Sersic LightProfile.
169-
"""
170-
light_profile = ag.lp.Sersic
171-
172-
"""
173-
We next setup this profile as model components whose parameters are free & fitted for
174-
by setting up a Galaxy as a Model.
175-
"""
176-
galaxy_model = af.Model(ag.Galaxy, redshift=1.0, light=light_profile)
177-
model = af.Collection(galaxy=galaxy_model)
178-
179-
"""
180-
We define the non-linear search used to fit the model to the data (in this case, Dynesty).
181-
"""
182-
search = af.Nautilus(name="search[example]", n_live=50)
183-
184-
"""
185-
We next set up the `Analysis`, which contains the `log likelihood function` that the
186-
non-linear search calls to fit the galaxy model to the data.
187-
"""
188-
analysis = ag.AnalysisImaging(dataset=masked_dataset)
189-
190-
"""
191-
To perform the model-fit we pass the model and analysis to the search's fit method. This will
192-
output results (e.g., dynesty samples, model parameters, visualization) to hard-disk.
193-
"""
194-
result = search.fit(model=model, analysis=analysis)
195-
196-
"""
197-
The results contain information on the fit, for example the maximum likelihood
198-
model from the Dynesty parameter space search.
199-
"""
200-
print(result.samples.max_log_likelihood())
201-
202-
203-
Support
204-
-------
205-
206-
Support for installation issues, help with galaxy modeling and using **PyAutoGalaxy** is available by
207-
`raising an issue on the GitHub issues page <https://github.com/Jammy2211/PyAutoGalaxy/issues>`_.
208-
209-
We also offer support on the **PyAutoGalaxy** `Slack channel <https://pyautogalaxy.slack.com/>`_, where we also provide the
210-
latest updates on **PyAutoGalaxy**. Slack is invitation-only, so if you'd like to join send
211-
an `email <https://github.com/Jammy2211>`_ requesting an invite.
103+
Information on how to contribute to **PyAutoGalaxy** can be found `on the contributing page <https://github.com/Jammy2211/PyAutoGalaxy/blob/main/CONTRIBUTING.md>`_.
104+
105+
Hands on support for contributions is available via our Slack workspace, again please email to request an invite.

autogalaxy/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
from autoconf.dictable import from_dict, from_json, output_to_json, to_dict
88
from autoarray.dataset import preprocess # noqa
9+
from autoarray.dataset.interferometer.w_tilde import (
10+
load_curvature_preload_if_compatible,
11+
)
912
from autoarray.dataset.imaging.dataset import Imaging # noqa
1013
from autoarray.dataset.interferometer.dataset import Interferometer # noqa
1114
from autoarray.dataset.dataset_model import DatasetModel
@@ -44,6 +47,9 @@
4447
from autoarray.structures.grids.irregular_2d import Grid2DIrregular # noqa
4548
from autoarray.operators.over_sampling.over_sampler import OverSampler # noqa
4649
from autoarray.structures.mesh.rectangular_2d import Mesh2DRectangular # noqa
50+
from autoarray.structures.mesh.rectangular_2d_uniform import (
51+
Mesh2DRectangularUniform,
52+
) # noqa
4753
from autoarray.structures.mesh.delaunay_2d import Mesh2DDelaunay # noqa
4854
from autoarray.structures.vectors.uniform import VectorYX2D # noqa
4955
from autoarray.structures.vectors.irregular import VectorYX2DIrregular # noqa
@@ -119,4 +125,4 @@
119125
from autoconf.fitsable import output_to_fits
120126
from autoconf.fitsable import hdu_list_for_output_from
121127

122-
__version__ = "2025.12.21.1"
128+
__version__ = "2026.1.21.3"

autogalaxy/aggregator/interferometer/interferometer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def _interferometer_from(
5353
)
5454
uv_wavelengths = fit.value(name="dataset")[3].data
5555

56-
transformer_class = fit.value(name="dataset.transformer_class")
56+
transformer_class = fit.value(name="transformer_class")
5757

5858
dataset = aa.Interferometer(
5959
data=data,

autogalaxy/analysis/model_util.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,28 @@ def mge_model_from(
127127
Basis,
128128
profile_list=bulge_gaussian_list,
129129
)
130+
131+
132+
def simulator_start_here_model_from():
133+
134+
from autogalaxy.profiles.light.snr import Sersic
135+
from autogalaxy.galaxy.galaxy import Galaxy
136+
137+
bulge = af.Model(Sersic)
138+
139+
bulge.centre = (0.0, 0.0)
140+
bulge.ell_comps.ell_comps_0 = af.TruncatedGaussianPrior(
141+
mean=0.0, sigma=0.2, lower_limit=-1.0, upper_limit=1.0
142+
)
143+
bulge.ell_comps.ell_comps_1 = af.TruncatedGaussianPrior(
144+
mean=0.0, sigma=0.2, lower_limit=-1.0, upper_limit=1.0
145+
)
146+
bulge.signal_to_noise_ratio = af.UniformPrior(lower_limit=20.0, upper_limit=60.0)
147+
bulge.effective_radius = af.UniformPrior(lower_limit=1.0, upper_limit=5.0)
148+
bulge.sersic_index = af.TruncatedGaussianPrior(
149+
mean=4.0, sigma=0.5, lower_limit=0.8, upper_limit=5.0
150+
)
151+
152+
galaxy = af.Model(Galaxy, redshift=0.5, bulge=bulge)
153+
154+
return galaxy

autogalaxy/config/priors/mesh/rectangular.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
RectangularMagnification:
1+
RectangularAdaptDensity:
22
shape_0:
33
type: Uniform
44
lower_limit: 20.0
@@ -19,7 +19,7 @@ RectangularMagnification:
1919
limits:
2020
lower: 3.0
2121
upper: inf
22-
RectangularSource:
22+
RectangularAdaptImage:
2323
shape_0:
2424
type: Uniform
2525
lower_limit: 20.0

autogalaxy/exc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class PixelizationException(af.exc.FitException):
3939
"""
4040
Raises exceptions associated with the `inversion/pixelization` modules and `Pixelization` classes.
4141
42-
For example if a `RectangularMagnification` mesh has dimensions below 3x3.
42+
For example if a `RectangularAdaptDensity` mesh has dimensions below 3x3.
4343
4444
This exception overwrites `autoarray.exc.PixelizationException` in order to add a `FitException`. This means that
4545
if this exception is raised during a model-fit in the analysis class's `log_likelihood_function` that model

autogalaxy/galaxy/to_inversion.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,15 @@ def __init__(
8080

8181
self.preloads = preloads
8282

83-
self._xp = xp
83+
self.use_jax = xp is not np
84+
85+
@property
86+
def _xp(self):
87+
if self.use_jax:
88+
import jax.numpy as jnp
89+
90+
return jnp
91+
return np
8492

8593
@property
8694
def psf(self) -> Optional[aa.Kernel2D]:

autogalaxy/interferometer/model/analysis.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,5 +185,6 @@ def save_attributes(self, paths: af.DirectoryPaths):
185185
super().save_attributes(paths=paths)
186186

187187
paths.save_json(
188-
"transformer_class", to_dict(self.dataset.transformer.__class__), "dataset"
188+
"transformer_class",
189+
to_dict(self.dataset.transformer.__class__),
189190
)

autogalaxy/plot/visuals/two_d.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,15 @@ def plot_via_plotter(self, plotter, grid_indexes=None):
9393
plotter.tangential_critical_curves_plot.plot_grid(
9494
grid=self.tangential_critical_curves
9595
)
96-
except TypeError:
96+
except (AttributeError, TypeError):
9797
pass
9898

9999
if self.radial_critical_curves is not None:
100100
try:
101101
plotter.radial_critical_curves_plot.plot_grid(
102102
grid=self.radial_critical_curves
103103
)
104-
except TypeError:
104+
except (AttributeError, TypeError):
105105
pass
106106

107107
if self.tangential_caustics is not None:
@@ -111,16 +111,19 @@ def plot_via_plotter(self, plotter, grid_indexes=None):
111111
grid=self.tangential_caustics
112112
)
113113
except (AttributeError, ValueError):
114-
plotter.tangential_caustics_plot.plot_grid(
115-
grid=self.tangential_caustics.array
116-
)
117-
except TypeError:
114+
try:
115+
plotter.tangential_caustics_plot.plot_grid(
116+
grid=self.tangential_caustics.array
117+
)
118+
except (AttributeError, TypeError):
119+
pass
120+
except (AttributeError, TypeError):
118121
pass
119122

120123
if self.radial_caustics is not None:
121124
try:
122125
plotter.radial_caustics_plot.plot_grid(grid=self.radial_caustics)
123-
except TypeError:
126+
except (AttributeError, TypeError):
124127
pass
125128

126129
def add_critical_curves_or_caustics(

0 commit comments

Comments
 (0)