data_models.level1

KPF Level 1 (assembled 2D frame) data model.

Represents an assembled CCD frame after combining amplifier readouts. Also used for master calibration products (bias, dark, flat) which share the same structure (mean + variance frames for GREEN and RED).

Subclasses RVDataModel (via KPFDataModel) to reuse its extension/header/data infrastructure and receipt system.

class kpfpipe.data_models.level1.KPF1

Bases: KPFDataModel

KPF Level 1 assembled 2D frame data model.

After image assembly, the L1 product contains assembled GREEN_CCD and RED_CCD frames with corresponding variance frames, plus pass-through extensions from L0 (CA_HK, exposure meter, telemetry).

Also used for master calibration products (bias, dark, flat). Construct from a FITS file with KPF1.from_fits(path), then read the assembled 4080x4080 frames from data (e.g. data[“GREEN_CCD”], data[“RED_CCD”]).

check_filename_convention(filename)

KPF L1 uses an EPRV-like name with L1 (not SL#): kpf_L1_YYYYMMDDThhmmss.fits.

The EPRV regex only accepts SL2/SL3/SL4, so L1 has its own convention.

generate_standard_filename()

KPF L1 filenames follow the kpf_L1_YYYYMMDDThhmmss.fits convention.

Delegates to kpf_filename (the single source for the KPF-native naming rule), deriving the timestamp from obs_id so the fallback name matches where the recipe writes (kpf_filepath(obs_id, “L1”)). Raises a ValueError if obs_id is unset or invalid.

info()

Print summary of L1 data model contents.

read(hdul, instrument=None, overwrite=False, **kwargs)

Route L1 FITS reads to KPF1._read.

RVDataModel.read has no lvl==1 dispatch branch, so the inherited from_fits would never call into _read without this override.

to_fits(fn=None)

Write L1 data to a FITS file.

to_kpf2()

Create a KPF2 scaffold from this L1, carrying over headers and pass-through extensions.

The L1 PRIMARY is already EPRV-standard (converted upstream in KPF0.to_kpf1), so headers are a pure pass-through: the EPRV PRIMARY and the immutable INSTRUMENT_HEADER are forwarded unchanged (value + comment). Header validation no longer runs here — it moved to the checkpoints layer (quality_control/checkpoints, Checkpoint.unregistered_keywords). Pass-through extensions (TELEMETRY, EXPMETER_SCI→EXPMETER, CA_HK→ANCILLARY_SPECTRUM) and KPF-friendly aliases (e.g., SCI2_FLUX → TRACE3_FLUX) are handled below. Trace data arrays are created but empty — the caller (spectral extraction) fills those in.