1+ """
2+ Abstract base class for all mass profiles in **PyAutoGalaxy** and **PyAutoLens**.
3+
4+ A mass profile describes the projected mass distribution of a galaxy and exposes three fundamental lensing
5+ quantities:
6+
7+ - `deflections_yx_2d_from` — the deflection angles α(θ) that describe how light rays are bent.
8+ - `convergence_2d_from` — the dimensionless surface mass density κ(θ) = Σ(θ) / Σ_cr.
9+ - `potential_2d_from` — the lensing (Shapiro) potential ψ(θ).
10+
11+ Every other lensing observable (shear, magnification, critical curves, Einstein radius, Fermat potential) can
12+ be derived from these three quantities. See the `autogalaxy.operate.lens_calc` module for the `LensCalc` class
13+ that derives these secondary quantities.
14+ """
115import numpy as np
216from typing import Tuple
317
@@ -25,9 +39,53 @@ def __init__(
2539 super ().__init__ (centre = centre , ell_comps = ell_comps )
2640
2741 def deflections_yx_2d_from (self , grid ):
42+ """
43+ Returns the 2D deflection angles of the mass profile from a 2D grid of Cartesian (y,x) coordinates.
44+
45+ The deflection angle α(θ) at image-plane position θ describes how a light ray is bent by the
46+ gravitational field of the lens. The source-plane position β is then:
47+
48+ β = θ − α(θ)
49+
50+ Deflection angles are the single most important output of a mass profile — every other lensing quantity
51+ (convergence, shear, magnification, critical curves, caustics) can be derived from them.
52+
53+ Parameters
54+ ----------
55+ grid
56+ The 2D (y, x) coordinates where the deflection angles are evaluated.
57+
58+ Returns
59+ -------
60+ aa.VectorYX2D
61+ The (y, x) deflection angles at every coordinate on the input grid.
62+ """
2863 raise NotImplementedError
2964
3065 def deflections_2d_via_potential_2d_from (self , grid ):
66+ """
67+ Returns the 2D deflection angles of the mass profile by numerically differentiating the lensing
68+ potential on the input grid.
69+
70+ This is a fallback implementation that computes deflection angles as the gradient of the potential via
71+ finite differences:
72+
73+ α_y = ∂ψ/∂y, α_x = ∂ψ/∂x
74+
75+ Most concrete mass profiles override `deflections_yx_2d_from` with an analytic expression. This
76+ method is provided for cross-checking and for profiles where only the potential is known analytically.
77+
78+ Parameters
79+ ----------
80+ grid
81+ The 2D (y, x) coordinates where the deflection angles are evaluated.
82+
83+ Returns
84+ -------
85+ aa.Grid2D
86+ The (y, x) deflection angles at every coordinate on the input grid, computed via finite differences
87+ of the lensing potential.
88+ """
3189 potential = self .potential_2d_from (grid = grid )
3290
3391 deflections_y_2d = np .gradient (
@@ -43,22 +101,110 @@ def deflections_2d_via_potential_2d_from(self, grid):
43101 )
44102
45103 def convergence_2d_from (self , grid , xp = np ):
104+ """
105+ Returns the 2D convergence of the mass profile from a 2D grid of Cartesian (y,x) coordinates.
106+
107+ The convergence κ(θ) is the dimensionless surface mass density of the lens, defined as the projected
108+ surface mass density Σ(θ) divided by the critical surface mass density Σ_cr:
109+
110+ κ(θ) = Σ(θ) / Σ_cr
111+
112+ Physically, κ = 1 on the Einstein ring. Regions with κ > 1 produce multiple images.
113+
114+ Parameters
115+ ----------
116+ grid
117+ The 2D (y, x) coordinates where the convergence is evaluated.
118+
119+ Returns
120+ -------
121+ aa.Array2D
122+ The convergence κ(θ) at every coordinate on the input grid.
123+ """
46124 raise NotImplementedError
47125
48126 def convergence_func (self , grid_radius : float ) -> float :
127+ """
128+ Returns the convergence of the mass profile as a function of the radial coordinate.
129+
130+ This is used to integrate the convergence profile to compute enclosed masses and the Einstein radius.
131+
132+ Parameters
133+ ----------
134+ grid_radius
135+ The radial distance from the profile centre at which the convergence is evaluated.
136+
137+ Returns
138+ -------
139+ float
140+ The convergence at the input radial distance.
141+ """
49142 raise NotImplementedError
50143
51144 def potential_2d_from (self , grid ):
145+ """
146+ Returns the 2D lensing potential of the mass profile from a 2D grid of Cartesian (y,x) coordinates.
147+
148+ The lensing potential ψ(θ) is the gravitational (Shapiro) time-delay term. It quantifies how much the
149+ passage of light through the gravitational field delays its arrival relative to a straight-line path in
150+ empty space.
151+
152+ The potential enters directly into the Fermat potential:
153+
154+ φ(θ) = ½ |θ − β|² − ψ(θ)
155+
156+ which governs time delays between multiple lensed images of the same source.
157+
158+ Parameters
159+ ----------
160+ grid
161+ The 2D (y, x) coordinates where the lensing potential is evaluated.
162+
163+ Returns
164+ -------
165+ aa.Array2D
166+ The lensing potential ψ(θ) at every coordinate on the input grid.
167+ """
52168 raise NotImplementedError
53169
54170 def potential_func (self , u , y , x ):
171+ """
172+ Returns the integrand of the lensing potential at a single point, used in numerical integration schemes
173+ for computing the potential from the mass profile's convergence.
174+
175+ Parameters
176+ ----------
177+ u
178+ The integration variable.
179+ y
180+ The y-coordinate of the point at which the potential is evaluated.
181+ x
182+ The x-coordinate of the point at which the potential is evaluated.
183+ """
55184 raise NotImplementedError
56185
57186 def mass_integral (self , x , xp = np ):
187+ """
188+ Integrand used by `mass_angular_within_circle_from` to compute the total projected mass within a circle.
189+
190+ This integrates 2π r κ(r) to give the enclosed convergence (dimensionless mass) at radius `x`.
191+
192+ Parameters
193+ ----------
194+ x
195+ The radial coordinate at which the integrand is evaluated.
196+ """
58197 return 2 * xp .pi * x * self .convergence_func (grid_radius = aa .ArrayIrregular (x ))
59198
60199 @property
61200 def ellipticity_rescale (self ):
201+ """
202+ A rescaling factor applied to account for the ellipticity of the mass profile when computing the
203+ Einstein radius from the average convergence equals unity criterion.
204+
205+ For a spherical profile this is 1.0. Elliptical profiles return a factor that maps the elliptical
206+ enclosed mass to an equivalent circular Einstein radius.
207+ """
62208 return NotImplementedError ()
63209
64210 def mass_angular_within_circle_from (self , radius : float ):
0 commit comments