quality_control.qc_flags
- class kpfpipe.quality_control.qc_flags.QC(kpf_obj)
Bases:
objectBase runner for per-level pass/fail QC check methods.
- Parameters:
kpf_obj (KPFDataModel) – Finished data product whose QUALITY_CONTROL header receives the 0/1 flags.
- LEVEL = None
- run()
Run all checks, write each 0/1 result, and aggregate ISGOOD.
Resets
self.resultsat the start so callingrun()repeatedly on the same instance is deterministic.- Returns:
Maps each FITS keyword to its
(passed, comment)pair (this level’s checks only).ISGOODis the cross-level aggregate (see below).- Return type:
dict
- class kpfpipe.quality_control.qc_flags.QCL0(kpf_obj)
Bases:
QCQC checks for KPF Level 0 raw data products.
- LEVEL = 'L0'
- data_l0_red_green()
Raw CCD data present: each of GREEN/RED is a supported amp readout.
KPF reads out either 2 or 4 amplifiers per chip, so the expected amp count is inferred from the data rather than fixed: a chip passes when the number of present, non-empty amplifier extensions is a supported readout mode (
_SUPPORTED_NAMP), mirroringImageAssembly.count_amplifiers. This accepts both 2-amp and 4-amp frames and rejects a chip with no data or a partial/invalid amp set (1 or 3). Absent amps are stored asarray(None, dtype=object)and skipped – the same present-amp scan QCL1 uses for read noise.
- exptime_sane()
EXPTIME present, finite, non-negative, and consistent with ELAPSED.
Bias frames legitimately have EXPTIME=0, so we don’t require strictly positive. When the raw ELAPSED readout time is present, it must not fall short of the requested EXPTIME (premature readout) or exceed it by more than
_TIME_TOL_S(the elapsed-vs-requested check formerly done in the masters frame loader); an absent ELAPSED skips only that comparison.
- header_keywords_present()
Required PRIMARY keywords exist.
- not_junk()
obs_id not on the observer junk list for this frame’s data tree.
“Junk” is a manual observer flag (e.g. the wrong telescope settings) that no automated QC can catch. The list lives at
{KPF_DATA_INPUT}/vNext/reference/junk_obs.csv; KPF_DATA_INPUT is recovered from the frame’s own source directory, which rvdata records asself.dirname({KPF_DATA_INPUT}/L0/{datecode}) when the L0 is read. An absent list or unknown source dir yields not-junk.
- radec_consistent()
Pointing agrees with the target and catalog positions.
Thresholds the DiagL0 offsets on QUALITY_CONTROL: TARGOFF < 1”, and the catalog cross-matches OBJOFF/GAIAOFF < 5” (a loose bound, since the loaded pointing coordinates are not Gaia/SIMBAD-derived). Each offset is checked only when present, so a frame with no pointing (e.g. a calibration frame) or a skipped catalog lookup passes.
- times_consistent()
DATE-BEG < DATE-MID < DATE-END and |(END-BEG) - ELAPSED| < 0.1 s.
Ports v2.12
L2_datetime. At L0 the raw instrument times live on the WMKO-native PRIMARY (the header later snapshotted verbatim into INSTRUMENT_HEADER at to_kpf1); the 0/1 flag then propagates downstream on QUALITY_CONTROL. Passes the duration check when ELAPSED is absent – only the present cards are checked.
- class kpfpipe.quality_control.qc_flags.QCL1(kpf_obj)
Bases:
QCQC checks for KPF Level 1 assembled FFI products.
- LEVEL = 'L1'
- bias_ok()
Bias subtracted (RECEIPT BIASSUB) and master bias age <= 7 days.
- dark_ok()
Dark subtracted (RECEIPT DARKSUB) and master dark age <= 14 days.
- data_present()
GREEN_CCD and RED_CCD exist and are non-empty.
- ffi_finite()
All values in GREEN_CCD and RED_CCD are finite.
- flat_ok()
Flat divided (RECEIPT FLATDIV) and master flat age <= 30 days.
- read_noise_nongauss_ok()
Every per-amp non-Gaussian read noise present is in [0.8, 1.5].
- read_noise_ok()
Every per-amp read noise present is in [2.0, 6.0] e-.
- required_keywords_present()
Every registry-required PRIMARY keyword for L1 is present (presence only).
- class kpfpipe.quality_control.qc_flags.QCL2(kpf_obj)
Bases:
QCQC checks for KPF Level 2 extracted spectra products.
- LEVEL = 'L2'
- extraction_present()
All expected {CHIP}_{FIBER}_FLUX extensions exist and are non-empty.
- flux_finite_fraction()
NaN count from headers <= 1% of total L2 flux pixels.
- nonzero_flux()
ZEROFRAC < 0.5.
- required_keywords_present()
Every registry-required PRIMARY keyword for L2 is present (presence only).
- science_snr()
Science SNR is finite and above a minimum floor.
Reads the GSNRSCI/RSNRSCI metrics written by DiagL2.snr (run DiagL2 before QCL2, mirroring the flux_finite_fraction -> nan_counts dependency). Guards against a silently failed extraction.
- variance_positive()
No strictly-negative variance where the flux is finite.
A negative extracted variance is unphysical (box/optimal variance is a sum of non-negative terms) and would corrupt downstream RV weighting. Zero variance at off-detector / fully-masked columns is tolerated.
- class kpfpipe.quality_control.qc_flags.QCL4(kpf_obj)
Bases:
QCQC checks for KPF Level 4 RV/CCF products.
- LEVEL = 'L4'
- berv_within_tolerance()
Per-order BERV deviation within +/-1% of the weighted mean.
Ports v2.12
L2_barycentric_rv_percent_change, reading BERVMAXP / BERVMINP written by DiagL4 (run DiagL4 before QCL4). Passes when the metrics are absent (e.g. a calibration frame with no science RV) – there is nothing to flag.
- ccf_rv_present()
Each science orderlet has a non-empty CCF cube and computed RVs.
Both stages of the split must have run: CrossCorrelation writes the CCF cube and seeds the RV table (with NaN RV/RV_ERR), and RadialVelocity fills the RV column. A seeded-but-unfilled table (CrossCorrelation without a following RadialVelocity) fails here, since the RVs are the L4 product.
- required_keywords_present()
Every registry-required PRIMARY keyword for L4 is present (presence only).
Submodules
QC framework base class. |
|
QC checks for KPF Level 0 (raw CCD) data products. |
|
QC checks for KPF Level 1 (assembled FFI) data products. |
|
QC checks for KPF Level 2 (extracted spectra) data products. |
|
QC checks for KPF Level 4 (RVs and CCFs) data products. |