Skip to content

Add hacks/make_superbias.py: per-chip superbias / NMAD / bad-pixel mask#1

Merged
rknop merged 1 commit into
rknop:import_ls4from
nugent68:add-make-superbias-hack
May 13, 2026
Merged

Add hacks/make_superbias.py: per-chip superbias / NMAD / bad-pixel mask#1
rknop merged 1 commit into
rknop:import_ls4from
nugent68:add-make-superbias-hack

Conversation

@nugent68
Copy link
Copy Markdown

Summary

Adds a single new script, hacks/make_superbias.py, that builds three Rice-compressed FITS products per LS4Cam chip from a stack of bias frames:

File dtype Header keyword Contents
superbias_<CCD>.fits.fz float32 MED_BIAS per-pixel median across the bias stack
superbias_nmad_<CCD>.fits.fz float32 MB_NMAD per-pixel NMAD = 1.4826 × median(|x − median(x)|)
superbias_mask_<CCD>.fits.fz int16 NMASKED, MASKTHR 1 where NMAD > 3 × 1.4826 × median(NMAD), else 0

Two input modes

  • --input-mode multi-ext (default): each input is a multi-extension raw exposure with the bias section still present; the script calls LS4Cam.overscan_and_trim per chip extension internally.
  • --input-mode per-chip: a flat directory of already-trimmed per-chip FITS files, grouped by the CCD_LOC header keyword. Different chips may have different N. Files lacking CCD_LOC are skipped with a warning.

Verified for bit-exact equivalence on a 31-frame test set: per-chip mode and multi-ext mode produce identical superbias, NMAD, and mask images for the same underlying frames.

Real-data shakedown

Run on 31 single-amp LS4Cam bias frames (992 chip-images):

  • 32 chips processed in ~16 min on Docker Desktop / Intel Mac
  • MED_BIAS clusters at 0 ± 2.5 ADU on every chip ✅
  • MB_NMAD quantizes to {3.71, 4.45, 5.19} (= 1.4826 × {2.5, 3.0, 3.5}) — expected artifact of int16 raw + N=31
  • 130,535 total bad pixels masked across the focal plane (mean 0.049%)
  • NW_B and NW_C together account for 48% of all masked pixels — visually confirmed bad columns

Test plan

  • Run with default --input-mode multi-ext against a directory of LS4Cam multi-ext bias frames; verify 3 outputs per chip and reasonable header values.
  • Run with --input-mode per-chip against an already-trimmed per-chip directory; verify same outputs.
  • --chips NE_G NW_B filter restricts processing to a subset.
  • CI lint passes (ruff check hacks/make_superbias.py is already green).

🤖 Generated with Claude Code

…mask

Builds three Rice-compressed FITS per chip from a stack of LS4Cam bias
frames:

  superbias_<CCD>.fits.fz       float32, MED_BIAS = median of image
  superbias_nmad_<CCD>.fits.fz  float32, MB_NMAD  = median of NMAD image
  superbias_mask_<CCD>.fits.fz  int16,   1 where NMAD > 3*1.4826*median(NMAD)

Two input layouts via --input-mode:

  multi-ext (default): raw multi-extension exposures; runs
                       LS4Cam.overscan_and_trim internally per chip.

  per-chip:            flat directory of already-trimmed per-chip files;
                       groups by CCD_LOC header keyword.  Different chips
                       may have different N.

Both modes have been verified to produce bit-identical superbias / NMAD /
mask outputs on the same underlying frames.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants