Skip to content

refactor: consolidation sweep — adapter-owned exposure-time knowledge + shared FWHM helper #48

Description

@Jammy2211

Overview

Behaviour-preserving consolidation sweep from the mined candidates in PyAutoMind/draft/refactor/pyautoreduce/consolidation_sweep.md (Refactor Agent: invariant witnessed by test_autoreduce; API guard none-expected). Public behaviour observable through the test suite is unchanged; no dial or output changes.

Plan

  • Move the per-observatory single-exposure-time header knowledge (HST EXPTIME vs Keck ITIME×COADDS) out of pipeline._psf onto InstrumentAdapter, where the adapter-boundary contract says it belongs — shrinking the if/elif chains the planned ground-based instruments would otherwise extend.
  • Merge the two mathematically identical second-moment FWHM helpers (psf/frame_combine._moment_fwhm, psf/starred_epsf._size_fwhm) into one shared psf/moments.py helper; leave the two genuinely different estimators (epsf._fwhm_of radial half-max diagnostic, nirc2_star._fwhm_arcsec equivalent-area) in place.
  • Fold single-function noise/jwst_rms.py into noise/rms.py (callers/tests updated).
  • Rider: gitignore prototypes/cache_inject/ (the inject-recovery prototype's fresh cache; FITS are never committed).
Detailed implementation plan

Affected Repositories

  • PyAutoReduce (primary, only)

Branch Survey

Repository Current Branch Dirty?
./PyAutoReduce main @ 59beb04 clean (background prototype writing to untracked cache dir)

Suggested branch: refactor/consolidation-sweep

Implementation Steps

  1. autoreduce/instruments/adapter.pymax_single_exposure_seconds(headers) -> Optional[float]: HST max EXPTIME; Keck max ITIME×COADDS; JWST None (surface-brightness mosaics take no full-well cut). Loud on non-positive results for observatories that require it. The per-observatory explanatory comments move with the knowledge.
  2. autoreduce/pipeline.py _psf — replace the hst/keck/else peak_max branches with one call: t = adapter.max_single_exposure_seconds(headers); peak_max = selection.saturation_fraction * adapter.saturation_dn / t if t else None.
  3. New autoreduce/psf/moments.pymoment_fwhm(kernel) (second-moment 2.3548σ, non-negative clip); frame_combine and starred_epsf import it; private duplicates deleted.
  4. noise/rms.py absorbs noise_map_from_error from noise/jwst_rms.py; pipeline._noise import updated; noise/jwst_rms.py deleted; tests touching it updated.
  5. .gitignore — add prototypes/cache_inject/.
  6. Full suite must stay green unchanged (229 passed / 3 skipped baseline).

Key Files

  • autoreduce/instruments/adapter.py, autoreduce/pipeline.py
  • autoreduce/psf/moments.py (new), autoreduce/psf/frame_combine.py, autoreduce/psf/starred_epsf.py
  • autoreduce/noise/rms.py, autoreduce/noise/jwst_rms.py (removed)

Original Prompt

Click to expand starting prompt

See PyAutoMind/draft/refactor/pyautoreduce/consolidation_sweep.md (moves to active/ with this issue) — user request 2026-07-16 + mined candidates (including the checked-and-rejected list: mad_sigma already shared, combine dispatch already centralised, frames.py vs keck_frames.py divergence deliberate).


Autonomy: --auto, effective level safe (refactor cap): plan recorded here in lieu of the Plan-Mode hold per PyAutoBrain/AUTONOMY.md. Behaviour-preservation witness: test_autoreduce. Merge stays human.

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