quality_control.checkpoints.base
Checkpoint framework base class.
The third quality-control stage (after Diagnostics and QC). A Checkpoint’s
checkpoint methods READ the 0/1 QC flags written to QUALITY_CONTROL and the
product headers, then emit warnings or raise errors – they never write
keywords. A method opts in by setting _checkpoint_name on the function
object; run() walks all such methods (MRO order) and calls each.
run() also folds in the two upstream read-only stages: it first runs the
subclass’s paired Diagnostics and QC classes (DIAGNOSTICS/QC) – which
write the metrics and 0/1 flags – then the checkpoint methods. So the recipe
drives the whole pipeline order science modules -> Diagnostics -> QC ->
Checkpoints through one CheckpointL{n}(obj).run() call.
- Two responsibilities, both inherited base checkpoints:
unregistered_keywords– structural header validation: any non-structural card not registered for its extension raisesValueError(this logic used to live inQC._validate_headers).qc_flags– read each 0/1 QC flag; a failed (0) flag named in the subclass’sRAISE_FLAGSraises, every other failed flag warns.
Severity policy lives in the per-level subclasses (their RAISE_FLAGS).
- class kpfpipe.quality_control.checkpoints.base.Checkpoint(kpf_obj)
Bases:
objectBase runner for per-level checkpoint methods.
- Parameters:
kpf_obj (KPFDataModel) – Finished data product whose flags/headers are read (never written).
- DIAGNOSTICS = None
- LEVEL = None
- QC = None
- RAISE_FLAGS = ()
- qc_flags()
Read this level’s 0/1 QC flags; raise a RAISE_FLAGS failure, warn the rest.
Scoped to this level’s own checks (the registry’s
qc_flag_keywords_by_level[LEVEL]– theQCL{n}flags), NOT the flags propagated from lower levels: QUALITY_CONTROL accumulates the whole L0->L1->L2->L4 history, but a lower-level flag was already surfaced at its own level’s checkpoint, so re-warning it here would just be noise. A flag absent from the header is skipped (the check did not run); a flag equal to 0 raises if it is inRAISE_FLAGS, else warns.
- run()
Run the paired Diagnostics and QC, then every checkpoint method.
Folds in the two upstream read-only stages: Diagnostics writes its metrics, QC writes the 0/1 flags + ISGOOD (captured in
self.qc_resultsfor callers that report them), then each checkpoint method warns or raises. A level with no pairedDIAGNOSTICS/QCskips that stage. The checkpoint methods themselves never write (no return value).
- unregistered_keywords()
Raise on any non-structural card not registered for its extension.
For each registry-governed extension present on the product (PRIMARY only where it is EPRV-standard – L1 onward; the raw WMKO L0 PRIMARY is skipped), a card that is neither structural nor registered (in
keyword_registry.allowed[ext]) raisesValueErrorand names it. This subsumes the old WMKO-native leak check: a raw instrument keyword kept in INSTRUMENT_HEADER is simply unregistered for an EPRV PRIMARY.