Repository navigation
Description
Overview
Phase 0c of the JAX visualization roadmap. PyAutoGalaxy's FitImaging and FitInterferometer are JAX pytree-registered (PRs #364 and #376 respectively). The remaining gap is FitEllipse and FitQuantity — neither has pytree registration today, so use_jax_for_visualization=True on ag.AnalysisEllipse or ag.AnalysisQuantity would crash when fit_for_visualization tries to lift the fit across the JIT boundary.
This task ports the imaging / interferometer pytree pattern to those two remaining dataset types and adds round-trip JIT tests.
Plan
- Add
_register_fit_ellipse_pytreestoag.AnalysisEllipsemirroring_register_fit_interferometer_pytreesfrom PR feat: register pytrees for AnalysisInterferometer #376 (autogalaxy/interferometer/model/analysis.py:165-184). - Add
_register_fit_quantity_pytreestoag.AnalysisQuantitymirroring the same pattern. - Reuse the shared
autogalaxy/analysis/jax_pytrees.py::register_galaxies_pytree()helper. - For each fit class, identify dynamic (JAX-traced arrays / sub-pytrees) vs static (
no_flattenaux: masks, pixel scales, redshifts, settings) attributes by reading the populatedFit*instance. - Wire
self._register_fit_*_pytrees()into eachAnalysis.__init__underif use_jax:. - If
ag.AnalysisEllipseorag.AnalysisQuantitylacks**kwargspassthrough on__init__, fix it inline (2-line addition, same pattern as fix: ag.AnalysisInterferometer.__init__ kwargs passthrough #399). - Add round-trip JIT tests under
test_autogalaxy/ellipse/jax/andtest_autogalaxy/quantity/jax/following the three-step pattern fromautolens_workspace_test/scripts/hessian_jax.py(build → tree_flatten/unflatten round-trip → jax.jit returning the fit).
Detailed implementation plan
Affected Repositories
- PyAutoGalaxy (primary, only)
Work Classification
Library
Branch Survey
| Repository | Current Branch | Dirty? |
|---|---|---|
| ./PyAutoGalaxy | main | clean (recent merge from jax-interp-2d #398) |
Suggested branch: feature/ag-ellipse-quantity-pytree
Worktree root: ~/Code/PyAutoLabs-wt/ag-ellipse-quantity-pytree/ (parallel-safe with in-flight nfw-jax-port mass-profile worktree — file-disjoint)
Implementation Steps
-
autogalaxy/ellipse/model/analysis.py: add_register_fit_ellipse_pytreesstatic method + invoke underif use_jax:in__init__. RegisterFitEllipsewithno_flatten=("dataset", "settings", ...), plusDatasetModelif applicable, plusregister_galaxies_pytree(). -
autogalaxy/quantity/model/analysis.py: same pattern for_register_fit_quantity_pytrees. RegisterFitQuantitywith appropriateno_flattenaux, plusDatasetQuantity(its dataset analogue), plusregister_galaxies_pytree(). -
If either analysis
__init__lacks**kwargspassthrough (parallel pattern to PR fix: ag.AnalysisInterferometer.__init__ kwargs passthrough #399), add 2-line fix. -
test_autogalaxy/ellipse/jax/test_fit_ellipse_pytree.py(NEW) — three-step JIT round-trip test. -
test_autogalaxy/quantity/jax/test_fit_quantity_pytree.py(NEW) — same. -
pytest test_autogalaxy/ellipse/ test_autogalaxy/quantity/— all existing tests must still pass.
Key Files
autogalaxy/ellipse/model/analysis.py— add registration method + invoke underif use_jaxautogalaxy/quantity/model/analysis.py— add registration method + invoke underif use_jaxtest_autogalaxy/ellipse/jax/test_fit_ellipse_pytree.py(NEW)test_autogalaxy/quantity/jax/test_fit_quantity_pytree.py(NEW)
Reference patterns
autogalaxy/interferometer/model/analysis.py:165-184—_register_fit_interferometer_pytrees(closest sibling)autogalaxy/imaging/model/analysis.py:169-187—_register_fit_imaging_pytreesautogalaxy/analysis/jax_pytrees.py— sharedregister_galaxies_pytree()helper
Parallel worktree safety
Coexisting with nfw-jax-port (PyAutoGalaxy mass profiles) and interferometer-nufftax-updates (workspaces). This task touches autogalaxy/ellipse/ + autogalaxy/quantity/ only — file-disjoint from all in-flight work. User confirmed file-level safety.
Original Prompt
Click to expand starting prompt
(elided — full text in PyAutoPrompt/issued/fit_pytree_registration_other_datasets.md)
Activity
Jammy2211 commentedon May 14, 2026
Shipped — 2026-05-14
PR
Summary
Phase 0c shipped.
ag.AnalysisEllipseandag.AnalysisQuantitynow registerFitEllipse+FitQuantity(plusEllipse,EllipseMultipole, and reusedGalaxiesregistration) as JAX pytrees when constructed withuse_jax=True. Plus the**kwargspassthrough fix on both__init__methods (parity with #399). 154/154 unit tests acrosstest_autogalaxy/{ellipse,quantity,imaging,interferometer}/pass; pytree round-trip verified interactively (FitEllipse: 8 dynamic leaves; FitQuantity: 3 dynamic leaves withGalaxiescorrectly reconstructed).With this PR, all four PyAutoGalaxy Fit* types now have JAX pytree registration.
Session Notes
Scope narrowed mid-task after audit. The original prompt assumed registering pytrees would unblock
use_jax_for_visualization=Truefor these analyses. Reading the code revealed both visualizers bypassanalysis.fit_for_visualizationentirely:VisualizerEllipse.visualizecallsanalysis.fit_list_from(instance)(returns a list);VisualizerQuantity.visualizecallsanalysis.fit_quantity_for_instance(instance)(singular). Souse_jax_for_visualization=Trueremains a no-op for these two analyses despite the pytree work — separate dispatch follow-ups needed.Two deferred follow-ups:
fit_from = fit_quantity_for_instance(or wrapper) onAnalysisQuantity, switchVisualizerQuantity.visualizeto useanalysis.fit_for_visualization(instance). Mirrors the autolens / autogalaxy imaging + interferometer pattern. Unlocksuse_jax_for_visualization=Trueend-to-end on quantity.AnalysisEllipse.fit_list_fromreturnsList[FitEllipse], not a single fit. Either generalize the autofitfit_for_visualizationcontract to accept list returns, or have ellipse-side compose its list into a wrapper. Likely a separate small design pass.Pytree no_flatten decisions:
Ellipse: nono_flatten(centre, ell_comps, major_axis are all fittable params).EllipseMultipole:no_flatten=("m",)—mis the multipole order (integer discriminator, not fittable).FitEllipse:no_flatten=("dataset",)— dataset is per-analysis-constant.FitQuantity:no_flatten=("dataset", "func_str", "use_mask_in_fit")— all three are per-analysis-constant or static config.Parallel-worktree safety confirmed. Coexisted with in-flight
nfw-jax-port(PyAutoGalaxy mass profiles) — file-disjoint fromautogalaxy/ellipse/andautogalaxy/quantity/. Worktree-conflict guard bypassed per user-confirmed file-level safety, same pattern as PR fix: ag.AnalysisInterferometer.__init__ kwargs passthrough #399.Library kwargs-gap series — COMPLETE
al.AnalysisImaging— always had**kwargs✓al.AnalysisInterferometer— fixed in fix: JAX-trace Sérsic stellar-mass CSE deflection path (#499) #500 ✓al.AnalysisPoint— fixed in dPIE: make Lenstool-native parameterization the default profile #506 ✓ag.AnalysisImaging— always had**kwargs✓ag.AnalysisInterferometer— fixed in fix: ag.AnalysisInterferometer.__init__ kwargs passthrough #399 ✓ag.AnalysisEllipse+ag.AnalysisQuantity— fixed in this PR (feat: pytree registration for FitEllipse + FitQuantity (Phase 0c) #401) ✓PyAutoGalaxy pytree series — COMPLETE
ag.FitImaging— PR feat: register FitImaging, DatasetModel, Galaxies as pytrees in AnalysisImaging #364 ✓ag.FitInterferometer— PR feat: register pytrees for AnalysisInterferometer #376 ✓ag.FitEllipse+ag.FitQuantity— this PR (feat: pytree registration for FitEllipse + FitQuantity (Phase 0c) #401) ✓