Skip to content

feat: stamp the small-datasets regime into FITS headers at the writer funnel #153

Description

@Jammy2211

Overview

PYAUTO_SMALL_DATASETS=1 caps simulated datasets to a reduced resolution, but nothing on disk records which regime a dataset was written under. That gap let a capped dataset survive into a later full-resolution run and be loaded silently, producing deterministic assertion failures that pass in CI on the same commit — diagnosed in autolens_workspace_test#260.

The imaging manifestation is fixed on PyAutoArray branch claude/jax-grad-assertions-ci-hontn3 (commit 5ef6eea), which infers the regime from data.fits's shape. That inference is deliberately narrow and, by construction, cannot cover two dataset families:

  • Point-source and weak-lensing datasets are JSON with no FITS at all, so there is nothing to infer from.
  • Interferometer datasets keep their shape under the cap. The visibility count is fixed by the committed uv file while the real-space grid behind it is capped 256x256 -> 16x16, so a capped run writes a data.fits with identical NAXIS and different values. This one fails silently — there is no shape mismatch and no assertion to trip — which is strictly worse than the loud imaging failure that started this.

Proposal

Record the regime at write time instead of inferring it at read time.

Every FITS write in the entire stack funnels through a single function — autonerves/fitsable.py:89 output_to_fits (verified: it is the only output_to_fits definition across PyAutoNerves, PyAutoArray, PyAutoGalaxy and PyAutoLens, and is re-exported as aa.output_to_fits). Adding a header card there when PYAUTO_SMALL_DATASETS=1 is active would be:

  • truthful by construction — the stamp is written by the same call that writes the data, so it cannot disagree with it, and there is no stamped-but-empty-directory failure mode;
  • zero-call-site — no changes across the ~420 should_simulate sites in the workspaces;
  • the only discriminant that can catch the interferometer case, since it does not depend on shape.

PyAutoArray.should_simulate would then prefer the stamp and keep the shape heuristic as the legacy fallback for datasets already on disk that carry no stamp.

Scope and risks worth weighing

  • This changes a header card on every FITS the stack writes. Round-trip tests, file-hash regression pins, and any golden-file comparison could be disturbed. That is the main reason this was deliberately kept out of the PyAutoArray fix rather than riding along with it.
  • JSON datasets (autonerves/dictable.py:370 is the equivalent funnel) would need their own treatment, and stamping there risks round-trip pollution of the dictable schema. Point-source and weak lensing stay exposed until that is settled — worth deciding explicitly rather than by omission.
  • The stamp only helps datasets written after it lands, so the shape fallback is not throwaway work.

Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions