Skip to content

feat(light): add SersicMultipole and GaussianMultipole profiles#420

Merged
Jammy2211 merged 2 commits into
mainfrom
feature/multipole-light-profiles
May 18, 2026
Merged

feat(light): add SersicMultipole and GaussianMultipole profiles#420
Jammy2211 merged 2 commits into
mainfrom
feature/multipole-light-profiles

Conversation

@Jammy2211
Copy link
Copy Markdown
Collaborator

Summary

Adds two standalone elliptical multipole light profiles, SersicMultipole and GaussianMultipole, that perturb the eccentric radius by Fourier components at orders m=3 and m=4 before evaluating the underlying radial profile. With all multipole components set to zero (the default), each profile reduces exactly to its base class — confirmed by machine-precision parity tests against Sersic and Gaussian.

The parameter API uses multipole_3_comps=(c, s) and multipole_4_comps=(c, s) tuples, matching the (k_m, phi_m) convention used by EllipseMultipole and PowerLawMultipole. xp=np is threaded end-to-end for JAX support; JAX parity will be exercised in autogalaxy_workspace_test after this PR lands.

Workspace priors + a modeling example follow in a separate workspace PR. The future generalisation (multipole as a standalone wrapper around any radial profile, unified with the ellipse-fitting API) is deferred to a z_features tracker — explicitly out of scope here.

Closes #418.

API Changes

Two new public classes added to the ag.lp namespace:

  • ag.lp.SersicMultipole — Sersic with m=3 and m=4 Fourier perturbations on the eccentric radius
  • ag.lp.GaussianMultipole — Gaussian with m=3 and m=4 Fourier perturbations on the eccentric radius

Both default to no perturbation (numerical parity with ag.lp.Sersic / ag.lp.Gaussian), so this is a pure additive change — no existing scripts break.

See full details below.

Test Plan

  • python -m pytest test_autogalaxy/profiles/light/standard/test_multipole.py — 12 new tests pass (zero-perturbation parity for Sersic/Gaussian, m=3 and m=4 rotational symmetry on circular base, centre translation, nonzero-multipole diff, finiteness + non-negativity under large perturbation)
  • python -m pytest test_autogalaxy/ — 885 tests pass, no regressions
  • ag.lp.SersicMultipole() and ag.lp.GaussianMultipole() resolve via the standard ag.lp.* namespace
Full API Changes (for automation & release notes)

Added

  • ag.lp.SersicMultipole(centre, ell_comps, intensity, effective_radius, sersic_index, multipole_3_comps=(0.0, 0.0), multipole_4_comps=(0.0, 0.0)) — elliptical Sersic with m=3 and m=4 Fourier perturbations on the eccentric radius. Inherits from ag.lp.Sersic, so isinstance(profile, ag.lp.Sersic) remains true.
  • ag.lp.GaussianMultipole(centre, ell_comps, intensity, sigma, multipole_3_comps=(0.0, 0.0), multipole_4_comps=(0.0, 0.0)) — elliptical Gaussian with m=3 and m=4 Fourier perturbations on the eccentric radius. Inherits from ag.lp.Gaussian.
  • SersicMultipole.perturbed_radii_from(grid, xp=np, **kwargs) and GaussianMultipole.perturbed_radii_from(grid, xp=np, **kwargs) — returns the eccentric radii of grid perturbed by the m=3 and m=4 Fourier multipoles as a raw backend array (numpy or jax.numpy), floored at 1e-8.
  • autogalaxy.profiles.light.standard.multipole._LightProfileMultipoleMixin — internal mixin providing the shared perturbed_radii_from helper. Leading underscore signals "do not import elsewhere"; intended to be replaced by the future wrapper-style multipole abstraction.

Removed

  • None.

Renamed

  • None.

Changed Signature

  • None.

Changed Behaviour

  • None — existing ag.lp.Sersic / ag.lp.Gaussian behaviour is unchanged.

Migration

No migration required. Users wanting m=3/m=4 perturbed profiles switch their model composition from ag.lp.Sersic / ag.lp.Gaussian to the new ag.lp.SersicMultipole / ag.lp.GaussianMultipole and add the desired multipole components:

# Before — plain Sersic
galaxy = ag.Galaxy(
    redshift=0.5,
    light=ag.lp.Sersic(
        centre=(0.0, 0.0), ell_comps=(0.0, 0.1),
        intensity=1.0, effective_radius=0.6, sersic_index=4.0,
    ),
)

# After — Sersic with m=4 boxiness
galaxy = ag.Galaxy(
    redshift=0.5,
    light=ag.lp.SersicMultipole(
        centre=(0.0, 0.0), ell_comps=(0.0, 0.1),
        intensity=1.0, effective_radius=0.6, sersic_index=4.0,
        multipole_4_comps=(0.05, 0.0),
    ),
)

🤖 Generated with Claude Code

Two new standalone elliptical multipole light profiles that perturb the
eccentric radius by Fourier components at orders m=3 and m=4 before
evaluating the underlying radial profile. With all multipole components
set to zero (the default), each profile reduces exactly to its base class
(Sersic, Gaussian), verified by machine-precision parity tests.

The parameter API uses multipole_3_comps=(c, s) and multipole_4_comps=(c, s)
tuples, matching the (k_m, phi_m) convention of EllipseMultipole and
PowerLawMultipole. xp=np is threaded end-to-end through perturbed_radii_from,
image_2d_via_radii_from, and image_2d_from for JAX support; JAX parity will
be exercised in autogalaxy_workspace_test after this PR merges.

Closes #418.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e autosummary

Adds the two new classes introduced in this PR to docs/api/light.rst so they
appear in the Sphinx autosummary table under the Standard [ag.lp] section.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Jammy2211 Jammy2211 merged commit 6151902 into main May 18, 2026
6 checks passed
@Jammy2211 Jammy2211 deleted the feature/multipole-light-profiles branch May 18, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pending-release PR queued for the next release build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: standalone multipole light profiles (SersicMultipole, GaussianMultipole) with unified m=3/m=4 API

1 participant