Skip to content

feat: COOLEST standard interop — profile converters + template import/export #612

Description

@Jammy2211

Overview

Preparation for modeling ~18,000 Euclid DR1 lenses: PyAutoLens results must be exchangeable with lenstronomy/herculens/Glee via the COOLEST standard (https://github.com/aymgal/COOLEST). This task adds a conversion layer at the model I/O boundary covering all profiles COOLEST defines — internals unchanged (sampling stays on (e1,e2); no internal convention flip), per the Slack consensus (Sonnenfeld, Galan). The intermediate-axis question is handled by a follow-up PowerLawIntermediate + herculens-parity task (PyAutoMind/draft/feature/autolens/coolest_powerlaw_herculens_parity.md).

Plan

  • PyAutoGalaxy: new autogalaxy/interop/coolest/ package — pure, dependency-free bidirectional parameter converters for every COOLEST-defined light/mass profile (ellipticity, angle, intermediate-axis radius conventions), reusing autogalaxy/convert.py.
  • PyAutoLens: new autolens/interop/coolest.py — COOLEST JSON template import/export of full lens models (analytic profile parameters only) via the coolest pip package as an optional dependency.
  • Explicit, documented Einstein-radius definition on export (COOLEST intermediate-axis profile parameter; distinguished from the DR1 tangential-critical-curve definition).
  • Round-trip + numerical-certification tests for every √q / angle factor in both repos.
  • Workspace guide + workspace_test script as a follow-up PR behind the library-first merge gate.
Detailed implementation plan

Affected Repositories

  • PyAutoLens (primary)
  • PyAutoGalaxy

Branch Survey

Repository Current Branch Dirty?
./PyAutoGalaxy main clean
./PyAutoLens main paper_jax/paper.md modified (pre-existing, unrelated)

Suggested branch: feature/coolest-standard-support
Work classification: Library (workspace follow-up)
Worktree root: ~/Code/PyAutoLabs-wt/coolest-standard-support/

Convention facts (verified against coolest.readthedocs.io)

Quantity COOLEST PyAutoGalaxy/PyAutoLens
Coordinates cartesian (x right, y up), arcsec (y, x) grids, arcsec
Position angle CCW from +y (East-of-North), (-90°, +90°] CCW from +x, (-45°, 135°] (autogalaxy/convert.py) → φ_coolest = angle_ag − 90° renormalized
Ellipticity q = b/a + PA (e1, e2) ell_comps — ell_comps_from / axis_ratio_and_angle_from
Radii (r_eff, θ_E) intermediate axis r = √(a·b) = √q·a profile-specific; PowerLaw uses the 2/(q^-½+q^½) rescale (profiles/mass/total/power_law.py) — per-profile factors derived and numerically certified
Shear γ_ext, φ_ext (gamma_1, gamma_2) — shear_magnitude_and_angle_from
Template I/O coolest pip package (coolest.template) new optional dependency in PyAutoLens

Implementation Steps

Phase A — PyAutoGalaxy autogalaxy/interop/coolest/

  1. conventions.py — angle (+x ↔ East-of-North), (e1,e2) ↔ (q, PA), (y,x) ↔ (x,y) centre swap, per-profile radius-factor helpers. Reuse autogalaxy/convert.py; do not duplicate its math.
  2. light.py — ag.lp.Sersic ↔ COOLEST Sersic (effective-radius factor audited against ag's elliptical-radius definition); shapelets if supported by the installed coolest version.
  3. mass.py — ag.mp.Isothermal ↔ SIE, ag.mp.PowerLaw ↔ PEMD/EPL (θ_E intermediate-axis conversion), ag.mp.NFW ↔ NFW, ag.mp.ExternalShear ↔ ExternalShear, ag.mp.MassSheet ↔ convergence sheet if defined.
  4. Converters are dict-in/dict-out on plain floats (no coolest import in autogalaxy — zero new dependencies). Unsupported profiles raise a clear, named error (no silent skips).
  5. Tests test_autogalaxy/interop/ (numpy-only): per-profile round-trip identity + numerical certification — evaluate the ag profile and the profile reconstructed from its COOLEST parameters, assert equal convergence/deflections; for PowerLaw assert the analytic √q relation between θ_E definitions.

Phase B — PyAutoLens autolens/interop/coolest.py
6. to_coolest(galaxies_or_tracer, file_path) — export analytic profile parameters into a COOLEST JSON template (lensing entities from lens/source galaxies, redshifts from Galaxy.redshift), via the Phase A registry. Lazy coolest import with informative error; pip install autolens[coolest] extra; added to test/dev extras so CI exercises it.
7. from_coolest(file_path) -> Tracer — read a template, build ag/al profiles via the inverse mappings (built to consume Sonnenfeld's golden-lens JSONs).
8. Einstein-radius definition documented in module docstring + template metadata.
9. Tests test_autolens/interop/: full-model round-trip (PowerLaw + Shear lens, Sersic light + Sersic source), template written and re-read with coolest.template, parameters equal to input; end-to-end convergence/deflection equality on a grid.

Phase C — workspace follow-up PR (after library merge)
10. Minimal autolens_workspace/scripts/guides/ COOLEST example + autolens_workspace_test round-trip script.

Key Files

  • PyAutoGalaxy/autogalaxy/convert.py — existing (e1,e2)/(q,PA)/shear converters to reuse
  • PyAutoGalaxy/autogalaxy/profiles/mass/total/power_law.py — the 2/(q^-½+q^½) Einstein-radius rescale to map
  • PyAutoGalaxy/autogalaxy/interop/coolest/{conventions,light,mass}.py — new
  • PyAutoLens/autolens/interop/coolest.py — new
  • test_autogalaxy/interop/, test_autolens/interop/ — new tests

Original Prompt

Click to expand starting prompt

See PyAutoMind/active/coolest_standard_support.md (filed from the COOLEST Slack thread with Alessandro Sonnenfeld and Aymeric Galan; original request verbatim inside).

Activity

  1. Jammy2211 commented on Jul 16, 2026

    @Jammy2211
    CollaboratorAuthor

    Library PRs Created

    Heart was RED on 6 pre-existing, unrelated reasons at ship time; shipped through on explicit user acknowledgement (commit/push/PR-open only).

    API changes: Added only (new ag.interop / al.interop namespaces + coolest extra) — no workspace script is affected (grep confirms no interop usage).

    Next:

    1. Merge both PRs (library-first), then a minimal autolens_workspace COOLEST guide + autolens_workspace_test round-trip script as a follow-up PR (Phase C).
    2. Follow-up task (filed, starts after this merges): PowerLawIntermediate profile + herculens EPL cross-code parity via a shared COOLEST file — PyAutoMind/draft/feature/autolens/coolest_powerlaw_herculens_parity.md.
  2. Jammy2211 commented on Jul 17, 2026

    @Jammy2211
    CollaboratorAuthor

    Phase C Shipped — workspace PRs open

    Also merged this session: the library PRs PyAutoGalaxy#501 + PyAutoLens#613, and the corrective PyAutoLens#615 (the coolest JSONSerializer rejects relative paths; to_coolest/from_coolest now absolutize — found by running the guide, regression-tested).

    Note: the guide is named coolest_interop.py because a guides/coolest.py shadows the coolest package (script dir is on sys.path).

    Remaining: merge the two workspace PRs (library-first gate satisfied — upstream MERGED), then issue the follow-up task draft/feature/autolens/coolest_powerlaw_herculens_parity.md (PowerLawIntermediate + herculens parity).

  3. Jammy2211 commented on Jul 17, 2026

    @Jammy2211
    CollaboratorAuthor

    Shipped — 2026-07-17

    PRs (all MERGED)

    Summary

    COOLEST interop is live on all mains: ag.interop.coolest parameter converters (derived + numerically certified √q/angle factors) and al.interop.coolest.to_coolest/from_coolest JSON template I/O, with a workspace guide and a workspace_test validation script (round trip to 8.9e-16). Conversion sits at the model I/O boundary; internal conventions unchanged.

    Session Notes

    • A workspace script named coolest.py shadows the coolest package — guide is coolest_interop.py.
    • notebooks/weak/*.ipynb are stale on autolens_workspace main (regeneration diffs them) — worth a separate sweep.
    • Validation against Sonnenfeld's golden-lens templates (euclid-sgs GitLab, auth) remains a human step via from_coolest.
    • Next: follow-up task draft/feature/autolens/coolest_powerlaw_herculens_parity.md — PowerLawIntermediate profile + herculens EPL parity via a shared COOLEST file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions