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
19 changes: 19 additions & 0 deletions autogalaxy/galaxy/galaxies.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
"""
The `Galaxies` class groups a list of `Galaxy` objects and exposes aggregate methods that operate across all
galaxies simultaneously.

Common operations — summing images, deflection angles, convergence, and potential — are trivial (simply sum
each galaxy's contribution). More complex operations, such as computing a PSF-blurred image that correctly
handles a mix of standard and operated (PSF-already-applied) light profiles, require careful bookkeeping that
`Galaxies` handles automatically.

In a typical modeling workflow, a list of fitted galaxies is always wrapped in a `Galaxies` object, which is
then passed to a `Fit*` class (e.g. `FitImaging`) for comparison against the observed data.
"""
import numpy as np
from typing import Dict, List, Optional, Tuple, Type, Union

Expand Down Expand Up @@ -46,6 +58,13 @@ def __init__(

@property
def redshift(self):
"""
The redshift of the first galaxy in the collection.

This is used when all galaxies in the collection are at the same redshift (e.g. a group of galaxies
at the lens plane). For multi-plane lensing with galaxies at different redshifts, individual galaxy
redshifts should be accessed directly via `galaxies[i].redshift`.
"""
return self[0].redshift

def image_2d_list_from(
Expand Down
47 changes: 42 additions & 5 deletions autogalaxy/galaxy/galaxy.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
"""
The `Galaxy` class is the central object in **PyAutoGalaxy** that groups light profiles, mass profiles, and
other components (e.g. pixelizations) at a given redshift.

A `Galaxy` holds its components as named keyword-argument attributes, so the user can access them by name
(e.g. `galaxy.bulge`, `galaxy.disk`). It then provides aggregate methods — `image_2d_from`,
`deflections_yx_2d_from`, `convergence_2d_from`, `potential_2d_from` — that sum the contributions of all
matching component types.

The `Galaxies` class (in `galaxies.py`) wraps a list of `Galaxy` objects and provides the same aggregate
interface over the whole ensemble.
"""
from typing import Dict, List, Optional, Type, Union

import numpy as np
Expand Down Expand Up @@ -295,12 +307,41 @@ def convergence_2d_from(

return xp.zeros((grid.shape[0],))

@property
def half_light_radius(self):
"""
The half-light radius of the galaxy.

Returns `None` because a `Galaxy` may contain multiple light profiles with different effective radii;
there is no single half-light radius that characterises the whole galaxy. Individual light profile
components expose their own `half_light_radius` / `effective_radius` attributes.
"""
return None

@aa.grid_dec.to_grid
def traced_grid_2d_from(
self, grid: aa.type.Grid2DLike, xp=np
) -> aa.type.Grid2DLike:
"""
Trace an input grid using the galaxy's its deflection angles.
Trace an input grid of (y,x) coordinates through the galaxy's deflection angles.

The traced grid is computed as:

β = θ − α(θ)

where θ is the image-plane grid and α(θ) are the deflection angles from the galaxy's mass profiles.

This is the lensing ray-tracing step that maps image-plane positions to source-plane positions.

Parameters
----------
grid
The 2D (y, x) image-plane coordinates to be traced to the source plane.

Returns
-------
aa.type.Grid2DLike
The source-plane (y, x) coordinates after deflection.
"""
if isinstance(grid, aa.Grid2D):
return aa.Grid2D(
Expand Down Expand Up @@ -343,10 +384,6 @@ def potential_2d_from(
)
return xp.zeros((grid.shape[0],))

@property
def half_light_radius(self):
return None

def extract_attribute(self, cls, attr_name):
"""
Returns an attribute of a class and its children profiles in the galaxy as a `ValueIrregular`
Expand Down
11 changes: 11 additions & 0 deletions autogalaxy/galaxy/redshift.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
"""
Provides the `Redshift` class, a thin float subclass used when the redshift of a `Galaxy` is treated as a
free parameter in a model fit.

In standard use, galaxy redshifts are fixed scalars passed directly to `Galaxy(redshift=0.5, ...)`.
When the redshift itself needs to be inferred by the non-linear search, **PyAutoFit** requires every model
parameter to be wrapped in a Python class. The `Redshift` class satisfies this requirement while behaving
identically to a plain Python `float` in all arithmetic and comparison contexts.
"""


class Redshift(float):
"""
Class used when assigning a redshift to a `Galaxy` object.
Expand Down
13 changes: 13 additions & 0 deletions autogalaxy/galaxy/to_inversion.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
"""
Classes that convert a list of galaxies (some of which may contain linear light profiles or pixelizations) into
the inversion objects required by **PyAutoArray** to perform the linear algebra solve.

The key class is `GalaxiesToInversion`, which:

1. Extracts all linear light profiles across all galaxies and computes their mapping matrices.
2. Extracts all pixelization objects and constructs the `Mapper` objects they require.
3. Passes these to `autoarray.inversion_from` to perform the linear algebra inversion.

Standard (non-linear) light profiles are handled separately by the `Fit*` classes, which subtract them from
the data before passing the residuals to this inversion pipeline.
"""
from __future__ import annotations
import numpy as np
from typing import Dict, List, Optional, Type, Union
Expand Down
Loading