Overview
The autogalaxy_workspace and autolens_workspace lack a single guide that surveys all available
light profiles, shows how to instantiate them, how to compose them into a model, and how to make
an image from the resulting instance. Users currently have to discover profiles piecemeal from the
modeling examples and the docs API reference. This is especially relevant now that
SersicMultipole and GaussianMultipole have just landed (PyAutoGalaxy #420 and #421 for the
linear variants) and need a discoverable home outside the API reference.
This task adds scripts/guides/profiles/light.py to both workspaces — a compact survey covering
the standard, linear, operated, multipole, and Basis light-profile families with API examples,
delegating the deeper linear/operated/MGE workflows to their existing features/ subpackages.
A parallel docs audit syncs PyAutoLens/docs/api/light.rst to match
PyAutoGalaxy/docs/api/light.rst, which is needed because PyAutoLens's reference only lists
the legacy Standard subset (no Linear, Operated, Basis sections, and no Chameleon,
ElsonFreeFall, or the new multipoles).
Plan
- Add
scripts/guides/profiles/light.py to autogalaxy_workspace walking through every
standard light profile in ag.lp.*, with a detailed Sersic example showing instance →
image_2d_from and model → instance API flow.
- Give
SersicMultipole / GaussianMultipole their own dedicated subsection: explain the
m=3 / m=4 Fourier perturbation on the eccentric radius
r' = r · (1 + c_3 cos 3θ + s_3 sin 3θ + c_4 cos 4θ + s_4 sin 4θ),
show that the defaults (0.0, 0.0) recover the base profile exactly, and plot an
unperturbed vs. perturbed comparison so the reader can see what the multipole degree does.
- Add a
Basis section that introduces it as a grouping object — multiple light profiles
behaving as a single profile — with the MGE-style example of bundling several
ag.lp_linear.Gaussian profiles into one ag.lp_basis.Basis. Explain that when all
constituents are linear, every intensity is solved in one combined inversion. Point readers
to imaging/features/multi_gaussian_expansion/ for the deeper workflow.
- Add the autolens counterpart in
autolens_workspace, mirroring structure but using
al.Tracer instead of ag.Galaxies and putting model-derived instances inside the Tracer
where appropriate.
- Briefly introduce linear (
ag.lp_linear.* / al.lp_linear.*) and operated
(ag.lp_operated.* / al.lp_operated.*) light profiles with one-line API snippets, noting
that both multipoles are available as linear variants too, then point readers to the
existing imaging/features/linear_light_profiles/ and
imaging/features/operated_light_profile/ packages.
- After the detailed Sersic walkthrough, run through the remaining standard profiles compactly,
showing only their image_2d_from API and emphasising that the model/instance API is
identical to the Sersic case.
- Sync
PyAutoLens/docs/api/light.rst against PyAutoGalaxy/docs/api/light.rst: add the
missing Linear, Operated, and Basis sections, the Chameleon / ElsonFreeFall
entries, and the SersicMultipole / GaussianMultipole entries (in both Standard and
Linear). Link to the published API docs URL early in each new guide.
Detailed implementation plan
Affected Repositories
- autogalaxy_workspace (primary) — new guide
- autolens_workspace — new guide
- PyAutoLens — docs/api/light.rst sync
- PyAutoGalaxy — read-only reference; no edits expected
Work Classification
Both. Library docs PR (PyAutoLens) ships first, then workspace PRs.
Branch Survey (re-verified after multipoles merge)
| Repository |
Current Branch |
Dirty? |
Notes |
| ./autogalaxy_workspace |
main |
clean |
free |
| ./autolens_workspace |
main |
clean |
free (cluster-modeling-v2 cleared) |
| ./PyAutoLens |
main |
clean |
free |
| ./PyAutoGalaxy |
main |
clean |
free (multipole-light-profiles merged) — read-only reference |
Suggested branch: feature/light-profiles-guide (same name in PyAutoLens, autogalaxy_workspace, autolens_workspace)
Worktree root: ~/Code/PyAutoLabs-wt/light-profiles-guide/ (created later by /start_library)
Routing: library-dev → /start_library first for the PyAutoLens docs PR, then /start_workspace for the two workspace guides after that PR merges.
Implementation Steps
-
PyAutoLens: docs sync (ship first as library PR)
- Update
docs/api/light.rst to mirror PyAutoGalaxy's structure exactly:
- Standard
al.lp autosummary: add GaussianMultipole, SersicMultipole,
Chameleon, ChameleonSph, ElsonFreeFall, ElsonFreeFallSph.
- Add
Linear [\`al.lp_linear``]` section listing Gaussian/GaussianSph,
GaussianMultipole, Sersic/SersicSph, SersicMultipole, Exponential/ExponentialSph,
DevVaucouleurs/DevVaucouleursSph, SersicCore/SersicCoreSph,
ExponentialCore/ExponentialCoreSph.
- Add
Operated [\`al.lp_operated``]` section listing Gaussian, Moffat, Sersic.
- Add
Basis [\`al.lp_basis``]` section listing Basis.
- Keep all rST formatting and
:template: / :toctree: / :recursive: directives
consistent with the PyAutoGalaxy version. :currentmodule: should point at
autogalaxy.profiles.light.<subpkg> (PyAutoLens re-exports from autogalaxy).
- Run
make html in PyAutoLens/docs/ if available to catch any rST errors.
-
autogalaxy_workspace: scaffold the guide
- Create
scripts/guides/profiles/__init__.py (empty).
- Create
scripts/guides/profiles/light.py with the workspace's docstring-as-prose
style (module-level title docstring + __Contents__ block + """__Section__""" blocks
between code segments).
- Section order:
- Overview & Docs URL — short orientation; link to
https://pyautogalaxy.readthedocs.io/en/latest/api/light.html.
- All Light Profiles (Survey) — one-line construction of every profile in
ag.lp.standard.__init__, grouped by family: Sersic family (Sersic, SersicCore,
ExponentialCore, DevVaucouleurs, SersicMultipole), Gaussian-like (Gaussian,
Moffat, GaussianMultipole), specialised (Chameleon, ElsonFreeFall),
shapelets (ShapeletCartesian/Polar/Exponential families), and their *Sph variants.
Closes with a one-liner for ag.lp_basis.Basis. No image evaluation in this
section — just construction.
- Detailed Example: Sersic Image — build a
Grid2D, instantiate
ag.lp.Sersic, call image_2d_from(grid=grid), plot via aplt.LightProfilePlotter
and aplt.plot_array.
- Linear Light Profiles — one-line API
(ag.lp_linear.Sersic(centre=..., effective_radius=..., sersic_index=...)), explain
the intensity-via-inversion concept in 2-3 sentences, note that
ag.lp_linear.SersicMultipole and ag.lp_linear.GaussianMultipole exist too,
point to scripts/imaging/features/linear_light_profiles/.
- Operated Light Profiles — one-line API
(ag.lp_operated.Gaussian(...)) with same depth, point to
scripts/imaging/features/operated_light_profile/.
- Multipole Light Profiles — dedicated section.
- Explain the perturbation:
r' = r · (1 + c_3 cos 3θ + s_3 sin 3θ + c_4 cos 4θ + s_4 sin 4θ).
- Show defaults
(0.0, 0.0) recover the base profile.
- Build
ag.lp.SersicMultipole(centre=(0,0), ell_comps=(0.1, 0.05), intensity=1.0, effective_radius=1.0, sersic_index=2.5, multipole_3_comps=(0.05, 0.0), multipole_4_comps=(0.0, 0.03)) and plot side-by-side with the unperturbed Sersic.
- Repeat with
ag.lp.GaussianMultipole.
- Note no
*Sph variant (multipoles are angular perturbations on elliptical
profiles, so they require ellipticity).
- Note both are available as
ag.lp_linear.* linear variants too.
- Basis — dedicated section.
- Explain purpose: a
Basis groups multiple light profiles so they behave as a
single composite profile.
- Build an MGE-style example bundling 3-4
ag.lp_linear.Gaussian instances at
shared centre and ell_comps but increasing sigma into one
ag.lp_basis.Basis(light_profile_list=[...]), plot the combined image_2d_from.
- Explain that when all constituents are
LightProfileLinear, every intensity is
solved in a single inversion — keeping the model dimensionality low while
allowing rich morphology.
- Point to
scripts/imaging/features/multi_gaussian_expansion/ and
scripts/imaging/features/shapelets/ for the deeper workflows.
- Light Profile in a Model —
af.Model(ag.lp.Sersic) with priors set, build
an af.Collection wrapping galaxy + light profile, print model.info. Add a short
note: af.Model(ag.lp.SersicMultipole) works identically — the multipole comps
become priors automatically.
- Model Instance from Light Profile — show
model.instance_from_prior_medians() for both the bare light profile and the
galaxies-level model, then call image_2d_from on the resulting instance.
- Remaining Profiles Walkthrough — for every non-Sersic, non-multipole
standard profile, build an instance and show image_2d_from(grid=grid) (compact:
one short block per profile, re-emphasise that the model/instance API from
sections 8-9 is identical).
-
autolens_workspace: mirror with Tracer
- Create
scripts/guides/profiles/__init__.py and scripts/guides/profiles/light.py.
- Same section order, but:
- Replace
ag.Galaxies(...) flows with al.Tracer(galaxies=[...]).
- In sections 8-9, build the model so the instance is placed inside an
al.Tracer
(lens + source planes), then evaluate image_2d_from via
tracer.image_2d_from(grid=grid).
- Docs URL points to
https://pyautolens.readthedocs.io/en/latest/api/light.html.
- Use
al.lp.SersicMultipole / al.lp.GaussianMultipole for the multipole demo —
typically as a lens-galaxy light profile.
- Use
al.lp_basis.Basis with al.lp_linear.Gaussian constituents in the Basis demo.
-
Workspace housekeeping
- Refresh
.script_sizes.json snapshots in both workspaces via
bash scripts/check_sizes.sh --update.
- Confirm new scripts pass
PYAUTO_TEST_MODE=1 smoke run.
- Generate notebooks via
/generate_and_merge for both workspaces after the script PRs
merge (separate step, not part of this task).
Key Files
PyAutoLens/docs/api/light.rst — sync to match PyAutoGalaxy version (incl. multipoles)
autogalaxy_workspace/scripts/guides/profiles/__init__.py — new
autogalaxy_workspace/scripts/guides/profiles/light.py — new
autolens_workspace/scripts/guides/profiles/__init__.py — new
autolens_workspace/scripts/guides/profiles/light.py — new
*/scripts/check_sizes.sh / .script_sizes.json — refresh after additions
Reference
PyAutoGalaxy/autogalaxy/profiles/light/standard/_multipole_mixin.py — multipole math
PyAutoGalaxy/autogalaxy/profiles/light/standard/sersic_multipole.py — SersicMultipole
PyAutoGalaxy/autogalaxy/profiles/light/standard/gaussian_multipole.py — GaussianMultipole
- PyAutoGalaxy PRs #420 (standard) and #421 (linear variants), merged 2026-05-18.
Constraints / style notes
- Use docstring-as-prose with
"""__Section__""" headers (per workspace CLAUDE.md).
- Tutorial / science-teaching prose stays on Opus (workspace tutorials get Opus drafting).
- Run smoke under
PYAUTO_TEST_MODE=1 before /ship_workspace; no display required.
Original Prompt
Click to expand starting prompt
Currently, the autogalaxy_workspace and autolens_workspace do not have a guide illustrating all available light
profiles with examples of how to use them either as instances to do things like make images / convergence maps
or how to compose them as a model.
Can you make a guide for both workspaces, in scripts/guides/profiles/light.py which gfives examples for all
support light profiles, where the first bit gives exampels for all light profiles in one section but does not
use them to make images (e.g. high level run through), it then shows the API for making an image from one
light profile (e.g. Sersic).
It then explxains linear light profiles and operated light profiles, shown a one line API on how to use them
but then says they are documented in the scritps/*/features/linear light profile and operated_light_profile
packages.
it then shows the API for how to put this in a model (e.g. Sersic again),
it then shows the API for making an instance from this Sersic model, either from just the light profile or when its
in the galaxies model the modeling API shows, and then does a detailed run through of
all remainig light profiles but only showing their image_2d_from methods, emphaissing the API above is
translateable.
For the autolens_workspace this will use the Tracer object instead of Galaaxies object and put the model gernerated
instances in the Tracer where appropriate.
Do a comparison to the docs folder in PyAutoGalaxy and PyAutoLens to make sure all light profiles are in
sync and also point to the URL to the docs early on in this script.
Overview
The
autogalaxy_workspaceandautolens_workspacelack a single guide that surveys all availablelight profiles, shows how to instantiate them, how to compose them into a model, and how to make
an image from the resulting instance. Users currently have to discover profiles piecemeal from the
modeling examples and the docs API reference. This is especially relevant now that
SersicMultipoleandGaussianMultipolehave just landed (PyAutoGalaxy #420 and #421 for thelinear variants) and need a discoverable home outside the API reference.
This task adds
scripts/guides/profiles/light.pyto both workspaces — a compact survey coveringthe standard, linear, operated, multipole, and
Basislight-profile families with API examples,delegating the deeper linear/operated/MGE workflows to their existing
features/subpackages.A parallel docs audit syncs
PyAutoLens/docs/api/light.rstto matchPyAutoGalaxy/docs/api/light.rst, which is needed because PyAutoLens's reference only liststhe legacy Standard subset (no Linear, Operated, Basis sections, and no Chameleon,
ElsonFreeFall, or the new multipoles).
Plan
scripts/guides/profiles/light.pytoautogalaxy_workspacewalking through everystandard light profile in
ag.lp.*, with a detailed Sersic example showing instance →image_2d_fromand model → instance API flow.SersicMultipole/GaussianMultipoletheir own dedicated subsection: explain them=3 / m=4 Fourier perturbation on the eccentric radius
r' = r · (1 + c_3 cos 3θ + s_3 sin 3θ + c_4 cos 4θ + s_4 sin 4θ),show that the defaults
(0.0, 0.0)recover the base profile exactly, and plot anunperturbed vs. perturbed comparison so the reader can see what the multipole degree does.
Basissection that introduces it as a grouping object — multiple light profilesbehaving as a single profile — with the MGE-style example of bundling several
ag.lp_linear.Gaussianprofiles into oneag.lp_basis.Basis. Explain that when allconstituents are linear, every intensity is solved in one combined inversion. Point readers
to
imaging/features/multi_gaussian_expansion/for the deeper workflow.autolens_workspace, mirroring structure but usingal.Tracerinstead ofag.Galaxiesand putting model-derived instances inside the Tracerwhere appropriate.
ag.lp_linear.*/al.lp_linear.*) and operated(
ag.lp_operated.*/al.lp_operated.*) light profiles with one-line API snippets, notingthat both multipoles are available as linear variants too, then point readers to the
existing
imaging/features/linear_light_profiles/andimaging/features/operated_light_profile/packages.showing only their
image_2d_fromAPI and emphasising that the model/instance API isidentical to the Sersic case.
PyAutoLens/docs/api/light.rstagainstPyAutoGalaxy/docs/api/light.rst: add themissing
Linear,Operated, andBasissections, theChameleon/ElsonFreeFallentries, and the
SersicMultipole/GaussianMultipoleentries (in both Standard andLinear). Link to the published API docs URL early in each new guide.
Detailed implementation plan
Affected Repositories
Work Classification
Both. Library docs PR (PyAutoLens) ships first, then workspace PRs.
Branch Survey (re-verified after multipoles merge)
Suggested branch:
feature/light-profiles-guide(same name in PyAutoLens, autogalaxy_workspace, autolens_workspace)Worktree root:
~/Code/PyAutoLabs-wt/light-profiles-guide/(created later by/start_library)Routing:
library-dev→/start_libraryfirst for the PyAutoLens docs PR, then/start_workspacefor the two workspace guides after that PR merges.Implementation Steps
PyAutoLens: docs sync (ship first as library PR)
docs/api/light.rstto mirror PyAutoGalaxy's structure exactly:al.lpautosummary: addGaussianMultipole,SersicMultipole,Chameleon,ChameleonSph,ElsonFreeFall,ElsonFreeFallSph.Linear [\`al.lp_linear``]` section listing Gaussian/GaussianSph,GaussianMultipole, Sersic/SersicSph, SersicMultipole, Exponential/ExponentialSph,
DevVaucouleurs/DevVaucouleursSph, SersicCore/SersicCoreSph,
ExponentialCore/ExponentialCoreSph.
Operated [\`al.lp_operated``]` section listing Gaussian, Moffat, Sersic.Basis [\`al.lp_basis``]` section listing Basis.:template:/:toctree:/:recursive:directivesconsistent with the PyAutoGalaxy version.
:currentmodule:should point atautogalaxy.profiles.light.<subpkg>(PyAutoLens re-exports from autogalaxy).make htmlinPyAutoLens/docs/if available to catch any rST errors.autogalaxy_workspace: scaffold the guide
scripts/guides/profiles/__init__.py(empty).scripts/guides/profiles/light.pywith the workspace's docstring-as-prosestyle (module-level title docstring +
__Contents__block +"""__Section__"""blocksbetween code segments).
https://pyautogalaxy.readthedocs.io/en/latest/api/light.html.ag.lp.standard.__init__, grouped by family: Sersic family (Sersic, SersicCore,ExponentialCore, DevVaucouleurs, SersicMultipole), Gaussian-like (Gaussian,
Moffat, GaussianMultipole), specialised (Chameleon, ElsonFreeFall),
shapelets (ShapeletCartesian/Polar/Exponential families), and their
*Sphvariants.Closes with a one-liner for
ag.lp_basis.Basis. No image evaluation in thissection — just construction.
Grid2D, instantiateag.lp.Sersic, callimage_2d_from(grid=grid), plot viaaplt.LightProfilePlotterand
aplt.plot_array.(
ag.lp_linear.Sersic(centre=..., effective_radius=..., sersic_index=...)), explainthe intensity-via-inversion concept in 2-3 sentences, note that
ag.lp_linear.SersicMultipoleandag.lp_linear.GaussianMultipoleexist too,point to
scripts/imaging/features/linear_light_profiles/.(
ag.lp_operated.Gaussian(...)) with same depth, point toscripts/imaging/features/operated_light_profile/.r' = r · (1 + c_3 cos 3θ + s_3 sin 3θ + c_4 cos 4θ + s_4 sin 4θ).(0.0, 0.0)recover the base profile.ag.lp.SersicMultipole(centre=(0,0), ell_comps=(0.1, 0.05), intensity=1.0, effective_radius=1.0, sersic_index=2.5, multipole_3_comps=(0.05, 0.0), multipole_4_comps=(0.0, 0.03))and plot side-by-side with the unperturbed Sersic.ag.lp.GaussianMultipole.*Sphvariant (multipoles are angular perturbations on ellipticalprofiles, so they require ellipticity).
ag.lp_linear.*linear variants too.Basisgroups multiple light profiles so they behave as asingle composite profile.
ag.lp_linear.Gaussianinstances atshared
centreandell_compsbut increasingsigmainto oneag.lp_basis.Basis(light_profile_list=[...]), plot the combinedimage_2d_from.LightProfileLinear, every intensity issolved in a single inversion — keeping the model dimensionality low while
allowing rich morphology.
scripts/imaging/features/multi_gaussian_expansion/andscripts/imaging/features/shapelets/for the deeper workflows.af.Model(ag.lp.Sersic)with priors set, buildan
af.Collectionwrapping galaxy + light profile, printmodel.info. Add a shortnote:
af.Model(ag.lp.SersicMultipole)works identically — the multipole compsbecome priors automatically.
model.instance_from_prior_medians()for both the bare light profile and thegalaxies-level model, then call
image_2d_fromon the resulting instance.standard profile, build an instance and show
image_2d_from(grid=grid)(compact:one short block per profile, re-emphasise that the model/instance API from
sections 8-9 is identical).
autolens_workspace: mirror with Tracer
scripts/guides/profiles/__init__.pyandscripts/guides/profiles/light.py.ag.Galaxies(...)flows withal.Tracer(galaxies=[...]).al.Tracer(lens + source planes), then evaluate
image_2d_fromviatracer.image_2d_from(grid=grid).https://pyautolens.readthedocs.io/en/latest/api/light.html.al.lp.SersicMultipole/al.lp.GaussianMultipolefor the multipole demo —typically as a lens-galaxy light profile.
al.lp_basis.Basiswithal.lp_linear.Gaussianconstituents in the Basis demo.Workspace housekeeping
.script_sizes.jsonsnapshots in both workspaces viabash scripts/check_sizes.sh --update.PYAUTO_TEST_MODE=1smoke run./generate_and_mergefor both workspaces after the script PRsmerge (separate step, not part of this task).
Key Files
PyAutoLens/docs/api/light.rst— sync to match PyAutoGalaxy version (incl. multipoles)autogalaxy_workspace/scripts/guides/profiles/__init__.py— newautogalaxy_workspace/scripts/guides/profiles/light.py— newautolens_workspace/scripts/guides/profiles/__init__.py— newautolens_workspace/scripts/guides/profiles/light.py— new*/scripts/check_sizes.sh/.script_sizes.json— refresh after additionsReference
PyAutoGalaxy/autogalaxy/profiles/light/standard/_multipole_mixin.py— multipole mathPyAutoGalaxy/autogalaxy/profiles/light/standard/sersic_multipole.py— SersicMultipolePyAutoGalaxy/autogalaxy/profiles/light/standard/gaussian_multipole.py— GaussianMultipoleConstraints / style notes
"""__Section__"""headers (per workspace CLAUDE.md).PYAUTO_TEST_MODE=1before/ship_workspace; no display required.Original Prompt
Click to expand starting prompt
Currently, the autogalaxy_workspace and autolens_workspace do not have a guide illustrating all available light
profiles with examples of how to use them either as instances to do things like make images / convergence maps
or how to compose them as a model.
Can you make a guide for both workspaces, in scripts/guides/profiles/light.py which gfives examples for all
support light profiles, where the first bit gives exampels for all light profiles in one section but does not
use them to make images (e.g. high level run through), it then shows the API for making an image from one
light profile (e.g. Sersic).
It then explxains linear light profiles and operated light profiles, shown a one line API on how to use them
but then says they are documented in the scritps/*/features/linear light profile and operated_light_profile
packages.
it then shows the API for how to put this in a model (e.g. Sersic again),
it then shows the API for making an instance from this Sersic model, either from just the light profile or when its
in the galaxies model the modeling API shows, and then does a detailed run through of
all remainig light profiles but only showing their image_2d_from methods, emphaissing the API above is
translateable.
For the autolens_workspace this will use the Tracer object instead of Galaaxies object and put the model gernerated
instances in the Tracer where appropriate.
Do a comparison to the docs folder in PyAutoGalaxy and PyAutoLens to make sure all light profiles are in
sync and also point to the URL to the docs early on in this script.