Overview
Add an integration test that exercises every public path through the ellipse visualization plotters (PlotterEllipse.imaging, PlotterEllipse.fit_ellipse, multipole and masked-data variants) end-to-end. This is step 1 of a 7-prompt feature decomposing JAX support for AnalysisEllipse.log_likelihood_function (see PyAutoPrompt/z_features/ellipse_fitting_jax.md). The visualization test locks down current behaviour so later prompts that rewrite the masked-points loop and add JAX paths can be diff-checked against a stable reference.
Plan
- Add a single
scripts/visualization.py script that loads (or auto-simulates) a small ellipse-fitting dataset.
- Exercise the three visualization scenarios that today touch different code paths: plain ellipse, ellipse + multipole (m=4), and ellipse over a masked dataset that forces the 300-iteration mask-rejection loop in
FitEllipse.
- Run every public plotter method on each scenario so the script breaks loudly if any plotter regresses.
- Use the workspace docstring style (
"""...""" blocks with __Section Name__ headers) so the script reads as a tutorial in addition to a smoke test.
- The script must run end-to-end under
bash run_all_scripts.sh and produce numbered PNGs under output_mode/visualization/ when PYAUTO_OUTPUT_MODE=1 is set. Numpy-only — no JAX imports.
Detailed implementation plan
Affected Repositories
- autogalaxy_workspace_test (primary)
- PyAutoGalaxy (read-only, for understanding plotter API)
Work Classification
Workspace
Branch Survey
| Repository |
Current Branch |
Dirty? |
| ./autogalaxy_workspace_test |
main |
clean |
Suggested branch: feature/ellipse-visualization-test
Worktree root: ~/Code/PyAutoLabs-wt/ellipse-visualization-test/ (created later by /start_workspace)
Implementation Steps
- Create
autogalaxy_workspace_test/scripts/visualization.py. Pattern on autogalaxy_workspace/scripts/ellipse/fit.py for dataset-loading and model construction; trim the modeling block down to a single fixed Ellipse instance.
- Section A — plain ellipse: build
ag.Ellipse(centre=(0.0, 0.0), ell_comps=(0.1, 0.05), major_axis=1.0), build FitEllipse, run PlotterEllipse.imaging(dataset) and PlotterEllipse.fit_ellipse(fit_list=[fit]).
- Section B — multipole: same ellipse plus
multipole_list=[ag.EllipseMultipole(m=4, multipole_comps=(0.05, 0.0))], run all plotters again. Repeat once with EllipseMultipoleScaled from autogalaxy/ellipse/ellipse/ellipse_multipole.py:118.
- Section C — masked: apply a
Mask2D whose circle partially overlaps the ellipse so FitEllipse.points_from_major_axis_from's 300-iteration mask-rejection loop fires. Run all plotters.
- Use
"""__Section Name__""" headers between blocks per the workspace style.
- Smoke-test locally:
python scripts/visualization.py runs to completion; PYAUTO_OUTPUT_MODE=1 python scripts/visualization.py produces PNGs under output_mode/visualization/.
- Add the new script to
smoke_tests.txt only if the existing curated set already includes equivalent ellipse coverage. Otherwise leave it out — per MEMORY.md's "smoke tests are a small curated subset" rule.
Key Files
scripts/visualization.py — new file, the integration test itself.
scripts/ellipse/ — reference for existing ellipse workspace patterns (read-only).
PyAutoGalaxy/autogalaxy/ellipse/model/plotter.py — PlotterEllipse API the script exercises (read-only).
PyAutoGalaxy/autogalaxy/ellipse/fit_ellipse.py:81-134 — the masked-points loop the masked scenario must trigger (read-only).
Testing Approach
- Local:
bash run_all_scripts.sh from the repo root, confirm green.
- Local with output capture:
PYAUTO_OUTPUT_MODE=1 python scripts/visualization.py, visually inspect the PNGs.
- CI:
/ship_workspace will re-run the smoke suite.
Original Prompt
Click to expand starting prompt
Step 1 of the ellipse-JAX series. The end goal is to make @PyAutoGalaxy/autogalaxy/ellipse/model/analysis.py, AnalysisEllipse.log_likelihood_function JAX-compatible (analogous to AnalysisImaging in @PyAutoGalaxy/autogalaxy/imaging/model/analysis.py). Before any of that, we need to lock down the existing numpy behaviour with integration tests in @autogalaxy_workspace_test/scripts, so when later prompts rewrite the gnarly bits we can spot regressions immediately.
This prompt covers the ellipse visualization integration test. The follow-up 2_workspace_jax_likelihood.md covers the likelihood-function script.
Please:
-
Add @autogalaxy_workspace_test/scripts/visualization.py. Pattern it on the existing @autogalaxy_workspace/scripts/ellipse/fit.py walkthrough but trimmed to the visualization side: load (or auto-simulate) a small dataset, fit a single Ellipse (and an Ellipse + EllipseMultipole), then exercise every public plotter path through @PyAutoGalaxy/autogalaxy/ellipse/model/plotter.py (PlotterEllipse.imaging, PlotterEllipse.fit_ellipse) and aplt.FitEllipsePlotter if one exists. Use PYAUTO_OUTPUT_MODE=1 semantics — the script just has to run end-to-end without raising.
-
Cover the multipole code path too: a fit with multipole_list=[ag.EllipseMultipole(m=4, multipole_comps=(0.05, 0.0))] and a fit with EllipseMultipoleScaled from @PyAutoGalaxy/autogalaxy/ellipse/ellipse/ellipse_multipole.py.
-
Cover the masked-data code path: apply a Mask2D that the ellipse partially overlaps, so FitEllipse.points_from_major_axis_from's 300-iteration mask-rejection loop in @PyAutoGalaxy/autogalaxy/ellipse/fit_ellipse.py:81-134 actually fires. Without this, prompt 6 has nothing to compare against.
-
Use the workspace docstring style ("""...""" blocks with __Section Name__ headers, no # comments) — see @autogalaxy_workspace/scripts/ellipse/fit.py for examples.
-
Test bar: the script runs cleanly under bash run_all_scripts.sh from @autogalaxy_workspace_test/, and produces output PNGs under output_mode/visualization/ when PYAUTO_OUTPUT_MODE=1 is set.
This is numpy-only — no JAX yet. The point is to have a regression target before we touch anything underneath.
Overview
Add an integration test that exercises every public path through the ellipse visualization plotters (
PlotterEllipse.imaging,PlotterEllipse.fit_ellipse, multipole and masked-data variants) end-to-end. This is step 1 of a 7-prompt feature decomposing JAX support forAnalysisEllipse.log_likelihood_function(seePyAutoPrompt/z_features/ellipse_fitting_jax.md). The visualization test locks down current behaviour so later prompts that rewrite the masked-points loop and add JAX paths can be diff-checked against a stable reference.Plan
scripts/visualization.pyscript that loads (or auto-simulates) a small ellipse-fitting dataset.FitEllipse."""..."""blocks with__Section Name__headers) so the script reads as a tutorial in addition to a smoke test.bash run_all_scripts.shand produce numbered PNGs underoutput_mode/visualization/whenPYAUTO_OUTPUT_MODE=1is set. Numpy-only — no JAX imports.Detailed implementation plan
Affected Repositories
Work Classification
Workspace
Branch Survey
Suggested branch:
feature/ellipse-visualization-testWorktree root:
~/Code/PyAutoLabs-wt/ellipse-visualization-test/(created later by/start_workspace)Implementation Steps
autogalaxy_workspace_test/scripts/visualization.py. Pattern onautogalaxy_workspace/scripts/ellipse/fit.pyfor dataset-loading and model construction; trim the modeling block down to a single fixedEllipseinstance.ag.Ellipse(centre=(0.0, 0.0), ell_comps=(0.1, 0.05), major_axis=1.0), buildFitEllipse, runPlotterEllipse.imaging(dataset)andPlotterEllipse.fit_ellipse(fit_list=[fit]).multipole_list=[ag.EllipseMultipole(m=4, multipole_comps=(0.05, 0.0))], run all plotters again. Repeat once withEllipseMultipoleScaledfromautogalaxy/ellipse/ellipse/ellipse_multipole.py:118.Mask2Dwhose circle partially overlaps the ellipse soFitEllipse.points_from_major_axis_from's 300-iteration mask-rejection loop fires. Run all plotters."""__Section Name__"""headers between blocks per the workspace style.python scripts/visualization.pyruns to completion;PYAUTO_OUTPUT_MODE=1 python scripts/visualization.pyproduces PNGs underoutput_mode/visualization/.smoke_tests.txtonly if the existing curated set already includes equivalent ellipse coverage. Otherwise leave it out — perMEMORY.md's "smoke tests are a small curated subset" rule.Key Files
scripts/visualization.py— new file, the integration test itself.scripts/ellipse/— reference for existing ellipse workspace patterns (read-only).PyAutoGalaxy/autogalaxy/ellipse/model/plotter.py—PlotterEllipseAPI the script exercises (read-only).PyAutoGalaxy/autogalaxy/ellipse/fit_ellipse.py:81-134— the masked-points loop the masked scenario must trigger (read-only).Testing Approach
bash run_all_scripts.shfrom the repo root, confirm green.PYAUTO_OUTPUT_MODE=1 python scripts/visualization.py, visually inspect the PNGs./ship_workspacewill re-run the smoke suite.Original Prompt
Click to expand starting prompt
Step 1 of the ellipse-JAX series. The end goal is to make
@PyAutoGalaxy/autogalaxy/ellipse/model/analysis.py,AnalysisEllipse.log_likelihood_functionJAX-compatible (analogous toAnalysisImagingin@PyAutoGalaxy/autogalaxy/imaging/model/analysis.py). Before any of that, we need to lock down the existing numpy behaviour with integration tests in@autogalaxy_workspace_test/scripts, so when later prompts rewrite the gnarly bits we can spot regressions immediately.This prompt covers the ellipse visualization integration test. The follow-up
2_workspace_jax_likelihood.mdcovers the likelihood-function script.Please:
Add
@autogalaxy_workspace_test/scripts/visualization.py. Pattern it on the existing@autogalaxy_workspace/scripts/ellipse/fit.pywalkthrough but trimmed to the visualization side: load (or auto-simulate) a small dataset, fit a singleEllipse(and anEllipse + EllipseMultipole), then exercise every public plotter path through@PyAutoGalaxy/autogalaxy/ellipse/model/plotter.py(PlotterEllipse.imaging,PlotterEllipse.fit_ellipse) andaplt.FitEllipsePlotterif one exists. UsePYAUTO_OUTPUT_MODE=1semantics — the script just has to run end-to-end without raising.Cover the multipole code path too: a fit with
multipole_list=[ag.EllipseMultipole(m=4, multipole_comps=(0.05, 0.0))]and a fit withEllipseMultipoleScaledfrom@PyAutoGalaxy/autogalaxy/ellipse/ellipse/ellipse_multipole.py.Cover the masked-data code path: apply a
Mask2Dthat the ellipse partially overlaps, soFitEllipse.points_from_major_axis_from's 300-iteration mask-rejection loop in@PyAutoGalaxy/autogalaxy/ellipse/fit_ellipse.py:81-134actually fires. Without this, prompt 6 has nothing to compare against.Use the workspace docstring style (
"""..."""blocks with__Section Name__headers, no#comments) — see@autogalaxy_workspace/scripts/ellipse/fit.pyfor examples.Test bar: the script runs cleanly under
bash run_all_scripts.shfrom@autogalaxy_workspace_test/, and produces output PNGs underoutput_mode/visualization/whenPYAUTO_OUTPUT_MODE=1is set.This is numpy-only — no JAX yet. The point is to have a regression target before we touch anything underneath.