Skip to content

feat: add ellipse visualization integration test #39

Description

@Jammy2211

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

  1. 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.
  2. 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]).
  3. 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.
  4. 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.
  5. Use """__Section Name__""" headers between blocks per the workspace style.
  6. Smoke-test locally: python scripts/visualization.py runs to completion; PYAUTO_OUTPUT_MODE=1 python scripts/visualization.py produces PNGs under output_mode/visualization/.
  7. 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.pyPlotterEllipse 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:

  1. 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.

  2. 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.

  3. 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.

  4. Use the workspace docstring style ("""...""" blocks with __Section Name__ headers, no # comments) — see @autogalaxy_workspace/scripts/ellipse/fit.py for examples.

  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions