Overview
16 mass profiles return np.zeros for convergence_2d_from or potential_2d_from — placeholders where no analytic formula was implemented. Replace these with proper implementations: direct analytic formulas for trivial cases (PointMass, MassSheet), and MGE decomposition fallback for the rest. Phase 3 of the mass profiles refactoring epic (#445), depends on Phase 2 (CSE JAX port, #446, shipped).
Plan
- Implement analytic
potential_2d_from for PointMass (ψ = R_E² ln(r)) and MassSheet (ψ = ½κ r²) — trivial closed forms
- Implement MGE-based
potential_2d_from fallback for profiles that have a convergence_func but no analytic potential: Sersic, Gaussian, Chameleon, PowerLawBroken, dPIEMass, dPIEPotential
- Implement CSE-based
convergence_2d_from for cNFW/cNFWSph (which have deflections via CSE but return zeros for convergence)
- Implement CSE or MGE-based
potential_2d_from for NFWTruncatedSph, cNFW/cNFWSph
- Leave ExternalShear and PowerLawMultipole convergence as zeros — physically correct
- Verify via Phase 1 self-consistency test suite (autolens_workspace_test scripts/mass/)
Detailed implementation plan
Affected Repositories
Work Classification
Library
Branch Survey
| Repository |
Current Branch |
Dirty? |
| PyAutoGalaxy |
main |
modified CLAUDE.md only |
Suggested branch: feature/mge-cse-fallback
Worktree root: ~/Code/PyAutoLabs-wt/mge-cse-fallback/
Implementation Steps
-
PointMass — point/point.py: replace zeros with potential = einstein_radius**2 * xp.log(r) where r = xp.sqrt(y**2 + x**2)
-
MassSheet — sheets/mass_sheet.py: replace zeros with potential = 0.5 * kappa * (y**2 + x**2)
-
cNFW/cNFWSph — dark/cnfw.py: implement convergence_2d_from via CSE decomposition (already has CSE infrastructure from MassProfileCSE mixin). Implement potential_2d_from via MGE decomposition of the convergence.
-
NFWTruncatedSph — dark/nfw_truncated.py: implement potential_2d_from via MGE fallback
-
Sersic/SersicSph — stellar/sersic.py (AbstractSersic): implement potential_2d_from via MGE decomposition of Sersic convergence
-
Gaussian — stellar/gaussian.py: implement potential_2d_from via MGE (Gaussian is itself a single MGE component — may have a direct formula)
-
Chameleon/ChameleonSph — stellar/chameleon.py: implement potential_2d_from via MGE
-
PowerLawBroken/Sph — total/power_law_broken.py: implement potential_2d_from via MGE
-
dPIEMass/Sph — total/dual_pseudo_isothermal_mass.py: implement potential_2d_from via MGE or check literature for analytic form
-
dPIEPotential/Sph — total/dual_pseudo_isothermal_potential.py: implement potential_2d_from via MGE (ironic that the "Potential" variant has no potential method)
-
Run pytest test_autogalaxy/profiles/mass/ — verify no regressions
-
Run Phase 1 self-consistency tests — verify previously-SKIP profiles now PASS
Key Files
autogalaxy/profiles/mass/abstract/abstract.py — may need base-class MGE potential helper
autogalaxy/profiles/mass/abstract/mge.py — MGEDecomposer (already mature, JAX-ready)
- Individual profile files listed above
Original Prompt
Click to expand starting prompt
Implement MGE/CSE fallback for mass profiles that currently return zeros for convergence or potential. 16 mass profiles return zeros — replace with MGE decomposition (preferred, JAX-ready) or CSE decomposition. PointMass and MassSheet get trivial analytic implementations. ExternalShear and PowerLawMultipole stay as zeros (physically correct).
Overview
16 mass profiles return
np.zerosforconvergence_2d_fromorpotential_2d_from— placeholders where no analytic formula was implemented. Replace these with proper implementations: direct analytic formulas for trivial cases (PointMass, MassSheet), and MGE decomposition fallback for the rest. Phase 3 of the mass profiles refactoring epic (#445), depends on Phase 2 (CSE JAX port, #446, shipped).Plan
potential_2d_fromfor PointMass (ψ = R_E² ln(r)) and MassSheet (ψ = ½κ r²) — trivial closed formspotential_2d_fromfallback for profiles that have aconvergence_funcbut no analytic potential: Sersic, Gaussian, Chameleon, PowerLawBroken, dPIEMass, dPIEPotentialconvergence_2d_fromfor cNFW/cNFWSph (which have deflections via CSE but return zeros for convergence)potential_2d_fromfor NFWTruncatedSph, cNFW/cNFWSphDetailed implementation plan
Affected Repositories
Work Classification
Library
Branch Survey
Suggested branch:
feature/mge-cse-fallbackWorktree root:
~/Code/PyAutoLabs-wt/mge-cse-fallback/Implementation Steps
PointMass —
point/point.py: replace zeros withpotential = einstein_radius**2 * xp.log(r)wherer = xp.sqrt(y**2 + x**2)MassSheet —
sheets/mass_sheet.py: replace zeros withpotential = 0.5 * kappa * (y**2 + x**2)cNFW/cNFWSph —
dark/cnfw.py: implementconvergence_2d_fromvia CSE decomposition (already has CSE infrastructure from MassProfileCSE mixin). Implementpotential_2d_fromvia MGE decomposition of the convergence.NFWTruncatedSph —
dark/nfw_truncated.py: implementpotential_2d_fromvia MGE fallbackSersic/SersicSph —
stellar/sersic.py(AbstractSersic): implementpotential_2d_fromvia MGE decomposition of Sersic convergenceGaussian —
stellar/gaussian.py: implementpotential_2d_fromvia MGE (Gaussian is itself a single MGE component — may have a direct formula)Chameleon/ChameleonSph —
stellar/chameleon.py: implementpotential_2d_fromvia MGEPowerLawBroken/Sph —
total/power_law_broken.py: implementpotential_2d_fromvia MGEdPIEMass/Sph —
total/dual_pseudo_isothermal_mass.py: implementpotential_2d_fromvia MGE or check literature for analytic formdPIEPotential/Sph —
total/dual_pseudo_isothermal_potential.py: implementpotential_2d_fromvia MGE (ironic that the "Potential" variant has no potential method)Run
pytest test_autogalaxy/profiles/mass/— verify no regressionsRun Phase 1 self-consistency tests — verify previously-SKIP profiles now PASS
Key Files
autogalaxy/profiles/mass/abstract/abstract.py— may need base-class MGE potential helperautogalaxy/profiles/mass/abstract/mge.py— MGEDecomposer (already mature, JAX-ready)Original Prompt
Click to expand starting prompt
Implement MGE/CSE fallback for mass profiles that currently return zeros for convergence or potential. 16 mass profiles return zeros — replace with MGE decomposition (preferred, JAX-ready) or CSE decomposition. PointMass and MassSheet get trivial analytic implementations. ExternalShear and PowerLawMultipole stay as zeros (physically correct).