Skip to content

fix: consolidate guides/results fits onto _quick_fit.py (IndexError) #274

Description

@Jammy2211

Overview

The two scripts/guides/results/aggregator/*.py tutorials crash with IndexError: list index out of range under the release-validation profile (surfaced in the 2026-07-13 release tail, PyAutoHeart#72, cluster E). Reproduced on current main — it is not covered by PyAutoFit#1368 (the release profile unsets PYAUTO_TEST_MODE for guides/results/, so is_test_mode() is False and the output-routing fix does not apply).

Root cause: three results tutorials each run their own capped n_like_max=300 Nautilus fit, but only _quick_fit.py disables samples_weight_threshold. The others prune to 2 samples on disk, and the tutorials then deep-index (from_sample_index(-10), parameter_lists[9]) assuming ≥10 samples → IndexError. It is order-dependent: start_here.py runs first and plants the 2-sample fit that the aggregator readers later choke on. The scripts' docstrings already claim they "resume from the cached fit," but their model/search config diverges from _quick_fit, so they don't — they run a separate shallow fit.

Fix: consolidate onto a single fit source (_quick_fit.py). The self-fitting scripts keep their model/search/analysis written out inline (these are teaching docs — no shared "builder" imports), but the inline definition is made to match _quick_fit so search.fit() genuinely resumes its 300-sample fit. Verified: the fit identifier is [search, model, unique_tag] only (analysis-independent), so a matching inline model + plain AnalysisImaging reproduces _quick_fit's on-disk identifier 8bc8f101….

Plan

  • Keep _quick_fit.py as the single fit producer (threshold None, Isothermal + shear, MGE source, AnalysisLatent); make its primary fit unique_tag suffix-free (simple__no_lens_light) plus one more fit for the aggregator's multi-result iteration. (Bonus: fixes queries.py, which queries unique_tag == "simple__no_lens_light" — currently matches nothing.)
  • start_here.py + galaxies_fits.py: add shear=al.mp.ExternalShear to the lens (they already use the identical MGE source and unique_tag=dataset_name) and match _quick_fit's identifier-affecting search fields, so search.fit() resumes the 300-sample fit. Deep indexing becomes valid.
  • samples.py: swap the inline Sersic source for the same MGE bulge + shear so it resumes the primary fit; update prose/prints describing the source.
  • Correct the now-accurate "resumes from the cached fit" docstrings.
  • Leave the read-only aggregator scripts (samples_via_aggregator, models, queries, data_fitting, interferometer, latent_variables) unchanged — they will only ever read 300-sample fits.
  • Regenerate the affected notebooks; validate via the ordered guides/results release-profile run.
Detailed implementation plan

Affected Repositories

  • autolens_workspace (primary)

Branch Survey

Repository Current Branch Dirty?
./autolens_workspace main clean

Suggested branch: feature/aggregator-quick-fit-consolidation

Implementation Steps

  1. scripts/guides/results/_quick_fit.py — make the primary fit unique_tag=dataset_name (suffix-free) and keep a second distinct fit for aggregator iteration; keep conf.instance["output"]["samples_weight_threshold"] = None, the shear + MGE model, LatentShear/AnalysisLatent. Confirm identifier via the identifier harness.
  2. scripts/guides/results/start_here.py — add shear=al.mp.ExternalShear to the lens af.Model; align the af.Nautilus config with _quick_fit's identifier-affecting fields; fix the docstring (~line 104) that claims resumption. Keep the _quick_fit auto-trigger guard.
  3. scripts/guides/results/aggregator/galaxies_fits.py — same model/search alignment; it still needs dataset for the local al.FitImaging refit. from_sample_index(-10) (lines ~176/238) becomes valid.
  4. scripts/guides/results/aggregator/samples.py — change source al.lp.Sersic → MGE bulge (matching _quick_fit) + add shear; align search; update prose/prints referencing .source.bulge. parameter_lists[9] / log_likelihood_list[9] become valid.
  5. Regenerate notebooks: PYTHONPATH=../PyAutoBuild/autobuild python3 ../PyAutoBuild/autobuild/generate.py autolens.
  6. Validate: run_python.py autolens scripts/guides/results --env-config config/build/env_vars_release.yaml (with the PyAuto stack on PYTHONPATH) → 0 failures; assert every on-disk fit has ~300 samples and no 2-sample simple__no_lens_light fit is created; spot-run smoke (env_vars.yaml).

Key Files

  • scripts/guides/results/_quick_fit.py — the single fit producer (threshold None; canonical model).
  • scripts/guides/results/start_here.py — results-guide entry; runs its own fit.
  • scripts/guides/results/aggregator/galaxies_fits.pyfrom_sample_index(-10) crash site.
  • scripts/guides/results/aggregator/samples.py — Sersic→MGE; [9] indexing.
  • config/build/env_vars_release.yaml — release profile (guides/results/ unsets PYAUTO_TEST_MODE).

Testing approach

The ordered guides/results release-profile run is both the reproduction and the validation harness (without --report-dir it sys.exit(1)s at the first failure; with it, it records each). Identifier equality is checked with autofit.mapper.identifier.Identifier([search, model, unique_tag]).

Original Prompt

Click to expand starting prompt

Aggregator scripts crash with IndexError (empty results) on release wheels

Type: bug
Target: autolens_workspace
Difficulty: medium
Autonomy: supervised
Priority: normal

Surfaced burning down the 2026-07-13 release-validation tail (PyAutoHeart#72). On the release wheels under the release profile, both aggregator guide scripts fail fast with the same error:

scripts/guides/results/aggregator/galaxies_fits.py        ... FAIL (13.8s) IndexError: list index out of range
scripts/guides/results/aggregator/samples_via_aggregator.py ... FAIL (4.5s) IndexError: list index out of range

IndexError: list index out of range = the aggregator queried results and got an empty list, then indexed [0]. Before assuming a new bug, VERIFY it still fails on current main. Reproduce under the release profile from the autolens_workspace checkout on current main; the aggregator reads the output of a prior modeling run, so ensure that prerequisite output exists — the empty-list may be a missing/misrouted prerequisite output rather than an aggregator bug. If it reproduces: get the full traceback and fix the producer, not the [0] access. Release run: PyAutoHeart workspace-validation 29279095224, TestPyPI 2026.7.13.1.dev65601.


Investigation note (2026-07-14): reproduced on current main. Real crash site is galaxies_fits.py:176 samples.from_sample_index(sample_index=-10)parameter_lists[-10] on a 2-element list; the shallow capped fit retained only 2 samples (no samples_weight_threshold = None), while _quick_fit's fits retain 300. See PyAutoHeart#72 cluster E.

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