Overview
Follow-up to #612 (COOLEST interop, merged). Adds ag.mp.PowerLawIntermediate — an elliptical power-law whose einstein_radius parameter is the COOLEST intermediate-axis θ_E — making the COOLEST mapping for it an identity (no √q factors), i.e. a direct parameter-level link to herculens/lenstronomy's power-law. A herculens cross-code parity script then proves the link empirically: the same COOLEST template produces numerically matching convergence and deflections in both codes.
Plan
- PyAutoGalaxy: behavior-preserving
einstein_radius_major_from(xp) hook in the power-law implementation, then PowerLawIntermediate(PowerLaw) overriding it with the certified conversion θ_ag = θ_int/√q · ((1+q)/2)^(1/(γ−1)). Exported as ag.mp.PowerLawIntermediate with a priors-config block.
- COOLEST layer:
PowerLawIntermediate → PEMD identity mapping; intermediate=True import option (threaded through al.interop.coolest.from_coolest) to rebuild PEMDs as PowerLawIntermediate.
- Tests: PowerLawIntermediate ≡ PowerLaw equivalence under the θ rescale (parametrized over q, γ); COOLEST identity + analytic certification; round trip.
- autolens_workspace_test:
scripts/coolest_herculens_parity.py — export a PowerLawIntermediate model to a COOLEST template, load it into herculens, assert matching convergence/deflections on a shared grid (herculens installed in the env only, never a library dependency).
Detailed implementation plan
Affected Repositories
- PyAutoGalaxy (primary implementation)
- PyAutoLens (
from_coolest intermediate kwarg)
- autolens_workspace_test (parity script)
Branch
feature/coolest-powerlaw-herculens, worktree ~/Code/PyAutoLabs-wt/coolest-powerlaw-herculens/
Implementation Steps
autogalaxy/profiles/mass/total/power_law_core.py: add PowerLawCore.einstein_radius_major_from(self, xp) returning self.einstein_radius; use it in einstein_radius_rescaled and in PowerLaw.deflections_yx_2d_from's Einstein-radius line. Numerically unchanged for all existing profiles (full suite is the regression net).
power_law.py: PowerLawIntermediate(PowerLaw) — same constructor; overrides the hook with the xp-threaded conversion (JAX-safe via self.axis_ratio(xp)); docstring documents the convention and factor.
- Namespace exports (
profiles/mass/total/__init__.py, profiles/mass/__init__.py) + PowerLawIntermediate: block in config/priors/mass/total/power_law.yaml.
autogalaxy/interop/coolest/mass.py: register PowerLawIntermediate → PEMD (identity θ_E); mass_profile_from(..., intermediate=True) builds PowerLawIntermediate; thread intermediate through autolens/interop/coolest.py::from_coolest.
- Tests in
test_autogalaxy/profiles/mass/total/ + test_autogalaxy/interop/ + test_autolens/interop/ (numpy-only).
- Workspace leg: pip install herculens (dry-run first;
--no-deps fallback if it moves the pinned jax 0.10.2), scripts/coolest_herculens_parity.py comparing convergence + deflections from the same COOLEST template; settles empirically whether herculens EPL θ_E is lenstronomy-convention (identity) or carries the SPEMD √((1+q²)/(2q)) factor.
Key Files
PyAutoGalaxy/autogalaxy/profiles/mass/total/{power_law,power_law_core}.py
PyAutoGalaxy/autogalaxy/interop/coolest/mass.py, PyAutoGalaxy/autogalaxy/config/priors/mass/total/power_law.yaml
PyAutoLens/autolens/interop/coolest.py
autolens_workspace_test/scripts/coolest_herculens_parity.py (new)
Original Prompt
Click to expand starting prompt
See PyAutoMind/active/coolest_powerlaw_herculens_parity.md.
Overview
Follow-up to #612 (COOLEST interop, merged). Adds
ag.mp.PowerLawIntermediate— an elliptical power-law whoseeinstein_radiusparameter is the COOLEST intermediate-axis θ_E — making the COOLEST mapping for it an identity (no √q factors), i.e. a direct parameter-level link to herculens/lenstronomy's power-law. A herculens cross-code parity script then proves the link empirically: the same COOLEST template produces numerically matching convergence and deflections in both codes.Plan
einstein_radius_major_from(xp)hook in the power-law implementation, thenPowerLawIntermediate(PowerLaw)overriding it with the certified conversion θ_ag = θ_int/√q · ((1+q)/2)^(1/(γ−1)). Exported asag.mp.PowerLawIntermediatewith a priors-config block.PowerLawIntermediate → PEMDidentity mapping;intermediate=Trueimport option (threaded throughal.interop.coolest.from_coolest) to rebuild PEMDs asPowerLawIntermediate.scripts/coolest_herculens_parity.py— export aPowerLawIntermediatemodel to a COOLEST template, load it into herculens, assert matching convergence/deflections on a shared grid (herculens installed in the env only, never a library dependency).Detailed implementation plan
Affected Repositories
from_coolestintermediate kwarg)Branch
feature/coolest-powerlaw-herculens, worktree~/Code/PyAutoLabs-wt/coolest-powerlaw-herculens/Implementation Steps
autogalaxy/profiles/mass/total/power_law_core.py: addPowerLawCore.einstein_radius_major_from(self, xp)returningself.einstein_radius; use it ineinstein_radius_rescaledand inPowerLaw.deflections_yx_2d_from's Einstein-radius line. Numerically unchanged for all existing profiles (full suite is the regression net).power_law.py:PowerLawIntermediate(PowerLaw)— same constructor; overrides the hook with the xp-threaded conversion (JAX-safe viaself.axis_ratio(xp)); docstring documents the convention and factor.profiles/mass/total/__init__.py,profiles/mass/__init__.py) +PowerLawIntermediate:block inconfig/priors/mass/total/power_law.yaml.autogalaxy/interop/coolest/mass.py: registerPowerLawIntermediate → PEMD(identity θ_E);mass_profile_from(..., intermediate=True)buildsPowerLawIntermediate; threadintermediatethroughautolens/interop/coolest.py::from_coolest.test_autogalaxy/profiles/mass/total/+test_autogalaxy/interop/+test_autolens/interop/(numpy-only).--no-depsfallback if it moves the pinned jax 0.10.2),scripts/coolest_herculens_parity.pycomparing convergence + deflections from the same COOLEST template; settles empirically whether herculens EPL θ_E is lenstronomy-convention (identity) or carries the SPEMD √((1+q²)/(2q)) factor.Key Files
PyAutoGalaxy/autogalaxy/profiles/mass/total/{power_law,power_law_core}.pyPyAutoGalaxy/autogalaxy/interop/coolest/mass.py,PyAutoGalaxy/autogalaxy/config/priors/mass/total/power_law.yamlPyAutoLens/autolens/interop/coolest.pyautolens_workspace_test/scripts/coolest_herculens_parity.py(new)Original Prompt
Click to expand starting prompt
See
PyAutoMind/active/coolest_powerlaw_herculens_parity.md.