Repository navigation
feat: source-plane fit panel paired to each Fit class #789
Description
Overview
The point-source fit.png only shows the image plane, so it cannot show how tightly the observed positions trace back together in the source plane — the quantity a source-plane chi-squared minimises and the intuitive self-consistency check for an image-plane chi-squared. This adds a "Fit Source Plane ()" panel to every positions fit, with its presentation paired to the fit class: image-plane-χ² fits get a context-only panel, source-plane-χ² fits show exactly the noise footprint and χ² their likelihood uses.
Plan
- Add a source-plane panel to
fit.png(1×2; 1×3 with fluxes): observed positions ray-traced to the point's own plane, numbered 1..N, the model source centre, the caustics of that plane, zoomed to the traced positions with a caustic inset in the emptiest corner. - Pair the panel to each positions Fit class (explicit table, tested per class):
- image-plane χ² (ImagePair / PairRepeat / PairAll and their Solved variants): context only — no noise footprints, no χ² box, subtitle "Image-plane χ² — traced positions for context";
- source-plane χ² (
FitPositionsSource,FitPositionsSourceSolved): subtitle naming the weighting; the footprint the χ² uses is primary (σ/|μ| circle for magnification, A·σ ellipse for jacobian), plus a faint dashed A·σ "propagated noise (reference)" under magnification; ★ free centre vs ◆ solved β*; χ² box.
- Move the source-χ² "Model (source plane)" crosses off the image-plane panel; number observed images 1..N on both panels, using the PointSolver figure's ordering and label-adjacency placement.
- Multi-plane / cluster: caustics of the point's own plane; the cluster inset frames only the tangential caustic.
- PyAutoArray:
apply_extenttick rounding gains adaptive significant figures so ticks never collapse to identical labels at mas zoom. - Re-render point_source_image_chi_squared, point_source_source_chi_squared and cluster in autolens_visualization.
Detailed implementation plan
Work Classification
Both (library first: PyAutoArray → PyAutoLens, then autolens_visualization)
Affected Repositories
- PyAutoLens (primary)
- PyAutoArray (tick precision fix)
- autolens_visualization (re-rendered figures)
Branch Survey
| Repository | Current Branch | Dirty? |
|---|---|---|
| ./array/PyAutoArray | main | clean |
| ./lens/PyAutoLens | main (57f1e65) | clean |
| ./lens/autolens_visualization | main | clean |
Suggested branch: feature/point-fit-source-plane-panel
Worktree root: ~/Code/PyAutoLabs-wt/point-fit-source-plane-panel/
Implementation Steps
- PyAutoArray
autoarray/plot/utils.py:_round_ticksraises its significant figures until distinct inputs stay distinct (used byapply_extentandyx); test intest_autoarray/plot/test_utils.py. - PyAutoLens new
autolens/point/plot/source_plane_panel.py: presentation table per Fit class, traced positions (same path asFitPositionsSource.model_data), σ/|μ| radii, A·σ ellipses fromprecision_tensor_components_from(fit, "jacobian")(covariance σ²AAᵀ), own-plane caustics viaLensCalc.from_tracer(tracer, use_multi_plane=True, plane_i=0, plane_j=fit.plane_index), zoom extent, corner-ranked inset/legend/χ² box. positions_panel.py: shared image-number placement (generalised frompoint_solver_plots.number_placements_from), 1..N numbering; drop the source-plane crosses from the image panel.fit_point_plots.subplot_fit: 1×2 / 1×3 layout with the new panel.- Tests: per-class presentation (all 7 classes, both weightings for source classes), panel artists, fluxes layout, multi-plane caustic plane.
- autolens_visualization: re-render the three point domains, rebuild gallery + manifest.
Key Files
autolens/point/plot/fit_point_plots.py— subplot layoutautolens/point/plot/positions_panel.py— shared panel helpersautolens/point/plot/source_plane_panel.py— newautolens/point/plot/point_solver_plots.py— numbering helper reuseautoarray/plot/utils.py— tick rounding
Original Prompt
Click to expand starting prompt
Point-source fit: source-plane panel showing how closely the positions trace
Consequence: judge
Autonomy: human-required
builds-on: complete/2026/10/point-dataset-positions-panel.md (shipped 2026-10-21; shares the fit_point_plots.py styling: markers, σ legend, titles, solver extent)
@PyAutoLens @autolens_visualization
Request (human, 2026-10-21)
A follow up issue would be to do a source plane plot of the fit showing how close things trace, which is relevent for image chi and source chi.
Intent
Add a source-plane panel to the point-source fit.png, possibly also as its own figure. It shows:
- every observed position ray-traced to the source plane through the fit's tracer
- the model source centre
- the caustics
How tightly the traced positions bunch around the source centre is the quantity FitPositionsSource (source chi-squared) minimises. For image chi-squared (FitPositionsImagePair and its variants) it is the intuitive check that the model is self-consistent.
Open design questions (settle in /start_dev)
- Scale bar for the scatter. Options are the source-plane noise from magnification-scaled σ (what source chi-squared uses, roughly σ/√μ), a circle per traced position, or a σ annotation.
- Extent. Zoom to the traced positions plus a margin, the caustic extent, or both as an inset. Too zoomed out and the scatter is invisible; too zoomed in and the caustic context is lost.
- Multiple planes. For multi-plane and cluster fits, either one panel per source plane or only the point's own plane.
- Figure placement. In
fit.pngfor both image and source chi-squared, or a separatefit_source_plane.pngtoggled by config. - Re-render set. point_source_image_chi_squared, point_source_source_chi_squared and cluster in autolens_visualization.
Prototype findings + recommended defaults (2026-10-21; NOT yet approved — confirm at /start_dev)
Prototypes. /mnt/c/Users/Jammy/Science/scratch/eyes/autolens/source_plane_prototype/ (19 PNGs; producer in producer/). The best views are S3_fit_mockup_image_chi_perturbed_RE.png and S3_fit_mockup_source_chi_truth.png.
Recommended design. fit.png gets a second panel, "Fit Source Plane (point_0)", for every positions fit (image- and source-χ²):
- Zoom: the traced observed positions plus the model source centre, with a 30% margin.
- Inset: the full caustic in the emptiest corner, with a box marking the zoom.
- Traced positions: numbered black dots.
- Model source centre: red ★.
- Noise ellipse: an orange A·σ ellipse on every traced point (the honest propagated noise).
- Noise circle: the σ/|μ| purple circle as well, but only when the fit uses
weighting="magnification". - χ² box: the fit's χ², plus the Jacobian χ².
Other recommendations:
- Move the source-χ² "Model (source plane)" ✕ off the image-plane panel into this one.
- Number images 1–N to match the PointSolver figure (the prototype used 0–N−1).
- No model-image markers for image-χ² fits (they all land on the ★).
- Absolute arcsec ticks, with an
apply_extentprecision fix: at mas zoom its 2-sig-fig rounding collapses all ticks to one value ("1.2″" ×3 on cluster point_1). - Cluster inset frames only the tangential caustic.
- With fluxes,
fit.pngbecomes 1×3. - Multi-plane: the point's own plane (
LensCalc.from_tracer(..., plane_j=fit.plane_index)works today for caustics). This pairs with the critical-curve redshift bug and the cluster pass.
Related. The default-weighting question is filed separately as draft/bug/autolens/fitpositionssource_default_magnification_weighti.md (check against Gravity.jl).
Side note (uninvestigated). At truth, the image-pair point_source model solves 5 images for 4 observed.
Human approval (2026-10-21)
Points 1–6 and all of the recommendations above are APPROVED.
Additional binding principle: pair each figure to its Fit class.
- Image-plane χ² fits (FitPositionsImagePair / PairRepeat / PairAll / …): the source-plane panel is context only (traced positions, model source ★, caustic, inset). Draw nothing that looks like a χ²: no noise circles or ellipses, no χ² box. Subtitle e.g. "Image-plane χ² — traced positions for context".
- Source-plane χ² fits: clearly indicate WHICH source-plane χ².
- The subtitle names it, e.g. "Source-plane χ² (magnification weighting)" or "(jacobian weighting)".
- The footprint the χ² actually uses is primary: the σ/|μ| circle for magnification, the A·σ ellipse for jacobian.
- Under magnification weighting, the A·σ ellipse is also shown, faint or dashed, as "propagated noise (reference)" (approved point 1).
- Free-centre and solved-β* (FitPositionsSourceSolved) fits use visibly different centre markers (★ vs ◆), with legend text naming them.
- The χ² box appears only on source-plane fits.
- Enumerate every positions Fit class in autolens/point/fit/positions/ and map each to one of these presentations, covered by tests.
Activity
Jammy2211 commentedon Oct 21, 2026
PRs open (merge in order; human /prm)
Tests: test_autoarray 2184 passed; test_autolens 902 passed. Heart YELLOW (pre-existing, acknowledged).
Per-class scratch renders: /mnt/c/Users/Jammy/Science/scratch/eyes/autolens/source_plane_fit_classes/{truth,perturbed_RE}//fit.png
🤖 Generated with Claude Code
Jammy2211 commentedon Oct 21, 2026
Shipped. Merged via /prm on 2026-10-21 in order PyAutoArray#653 → PyAutoLens#790 → autolens_visualization#13. Every CI leg was green; #13's lint was re-run against the merged library mains.
_round_ticksadds significant figures so ticks never collapse to identical labels.fit.pnggains a "Fit Source Plane" panel matched to each Fit class.fit.png.