pypeit.dashboard.model module

Headless (Qt-free) data/logic layer for the PypeIt Dashboard.

This module holds the dashboard’s PypeIt-facing logic so it can be unit tested with plain pytest (no display required), keeping the Qt views thin. Stage 0 only needs the cheap reduction metadata used by the header banner; the full reduction-state layer (loading/deriving RunPypeItState) is added in Stage 1.

Generated by JXP and Claude.

class pypeit.dashboard.model.DashboardModel(pypeit_file, redux_path=None, derive=True)[source]

Bases: object

Headless (Qt-free) model for one PypeIt reduction.

It acquires a pypeit.state.RunPypeItState by source priority (load <root>_state.json if present, R4; otherwise derive it the pypeit_status way, R5), and exposes a clean, normalized API the Qt views consume — a status table, the (calib_id, det) pairs, the path-aware step order, and graceful edge states (R11). It never raises for a missing/empty/malformed state: such cases are reported via load_status.

Generated by JXP and Claude.

Parameters:
  • pypeit_file (str, pathlib.Path) – Path to the .pypeit reduction file.

  • redux_path (str, optional) – Reduction directory (where the state file lives). Defaults to the directory containing pypeit_file.

  • derive (bool, optional) – If True (default) and no state file is present, derive the state via PypeIt (requires the raw data). Set False to skip deriving (e.g. CI tests without RAW_DATA): the model then reports not_started when no state file exists.

Variables:
  • pypeit_file (pathlib.Path) – The .pypeit path.

  • redux_dir (pathlib.Path) – The reduction directory.

  • state_path (pathlib.Path) – The expected <root>_state.json path.

  • header_info (HeaderInfo) – Header metadata, or None.

  • run_state (RunPypeItState) – The state, or None when unavailable.

  • load_status (str) – One of the LOAD_* constants.

  • error (str) – An error message when relevant, else None.

_acquire_state(derive)[source]

Acquire the reduction state by source priority (R4 then R5).

Generated by JXP and Claude.

Parameters:

derive (bool) – Whether to derive the state when no state file is present.

Returns:

None. Sets run_state and load_status.

_planned_science_frames(allow_build=False)[source]

Return the cached list of planned science/standard frames for this .pypeit file (Round-4). On a cache miss, build the metadata to compute it only when allow_build is True (so live-monitoring reloads and CI loads never trigger a heavy, possibly-failing build).

Generated by JXP and Claude.

Parameters:

allow_build (bool, optional) – Permit a one-time metadata build on a cache miss (True at launch; False on refresh/CI).

Returns:

Planned-frame dicts (see planned_science_from_fitstbl()); empty when uncached and a build is not permitted/possible.

Return type:

list

_seed_planned_science(allow_build=False)[source]

Seed the planned science/standard frames into run_state (from the cache, or a one-time build when allow_build), keyed to the calibration (group, det) pairs in the current state (Round-3 #2 / Round-4). Best-effort: never raises into the load/derive path.

Generated by JXP and Claude.

Parameters:

allow_build (bool, optional) – Permit a one-time metadata build on a cache miss.

Returns:

None.

calib_det_pairs()[source]

Enumerate the (calibration_group, detector) pairs present in the state, in sorted order, for the scope drop-downs/selectors (R16 / C2).

Generated by JXP and Claude.

Returns:

(calib_id, det) tuples; det is left in its raw form (an int or a mosaic tuple) for the view to format.

Return type:

list

property calib_dir

The reduction’s Calibrations/ directory (where output files live).

Generated by JXP and Claude.

Returns:

<redux_dir>/Calibrations.

Return type:

pathlib.Path

calib_file_path(prefix, group, det, ext='fits')[source]

Construct the path to a calibration file by naming convention (<prefix>_<setup>_<group>_<detname>.<ext>) — used when the viewer needs a different file than a step’s output_file (e.g. the Edges_* file for the slits step, or the Slits_* file required by pypeit_chk_scattlight).

Generated by JXP and Claude.

Parameters:
  • prefix (str) – File-type prefix (e.g. Edges, Slits).

  • group (int) – Calibration group ID.

  • det – Detector (int) or mosaic (tuple/list).

  • ext (str, optional) – Extension (fits or fits.gz).

Returns:

The constructed path (None if the setup is unknown).

Return type:

pathlib.Path or None

calibrations_ready(group, det)[source]

Whether the required calibrations for one (group, det) are all built successfully — the precondition for a science (Re)Build (Round-3 #2): until the calibrations a science frame depends on exist, its (Re)Build is disabled.

Generated by JXP and Claude.

Parameters:
  • group – The calibration group ID of the science frame.

  • det – The detector (int) or mosaic the science frame is on.

Returns:

True only if at least one required, in-pipeline calibration step exists for (group, det) and all such steps have a success/complete status; False otherwise (including when no matching calibration entries are known).

Return type:

bool

default_steps()[source]

Return the active spectrograph’s calibration steps, in pipeline order (path-aware: MultiSlit/Echelle vs IFU), including bpm.

Generated by JXP and Claude.

Returns:

The ordered step names, or [] if the pipeline is unknown (e.g. the .pypeit file was not found).

Return type:

list

det_name(det)[source]

Return a human-readable name for a detector or mosaic, for display in the views (drop-downs, navigator).

Generated by JXP and Claude.

Parameters:

det (int, tuple, list) – The detector (int) or mosaic (tuple/list of ints), as stored in the state.

Returns:

The PypeIt detector name (e.g. DET01, MSC01) when it can be resolved, else a plain readable fallback (Det 1 / Mosaic (1, 5)).

Return type:

str

has_science()[source]

Whether any science-frame state is available.

Generated by JXP and Claude.

Returns:

True if the state has at least one science entry.

Return type:

bool

is_stale()[source]

Whether the loaded *_state.json looks out of date relative to the .pypeit file or the calibration outputs (R13).

Generated by JXP and Claude.

Returns:

True if the state file’s mtime is older than the .pypeit file or the newest file in Calibrations/; False if there is no state file or nothing newer.

Return type:

bool

is_started()[source]

Whether the reduction has any calibration-state entries.

Generated by JXP and Claude.

Returns:

True if a state with at least one entry is available.

Return type:

bool

property log_path

The reduction .log file that run_pypeit / pypeit_run_to_calibstep write to (used by the single-run lock to detect an active run via the log’s modification time, design X1).

Generated by JXP and Claude.

Returns:

<pypeit_root>.log (next to the .pypeit file, matching pypeit_run_to_calibstep’s default log path).

Return type:

pathlib.Path

output_path(step, group, det)[source]

Full path to a step’s processed output file, or None.

Generated by JXP and Claude.

Parameters:
  • step (str) – Calibration step name.

  • group (int) – Calibration group ID.

  • det – Detector (int) or mosaic (tuple/list).

Returns:

Calibrations/<output_file>.

Return type:

pathlib.Path or None

science_frame_entry(frame, det)[source]

Return the raw ScienceFrameState for one (frame, det), or None.

Generated by JXP and Claude.

Parameters:
  • frame (str) – Exposure basename.

  • det – Detector (int) or mosaic (tuple/list).

Returns:

The matching pydantic science entry, or None.

science_object_qa_files(frame, det, slitid)[source]

Return the per-object QA PNGs (obj_prof / obj_trace) for one object’s slit, so the per-object table can open them (Stage 6 Round-1 #3, S6-Q15(c)). The science QA PNGs encode the slit as S{spat_id:04d}, matching ScienceObj.slitid.

Generated by JXP and Claude.

Parameters:
  • frame (str) – Exposure basename.

  • det – Detector (int) or mosaic (tuple/list).

  • slitid (int) – The object’s slit (SPAT_ID).

Returns:

{'obj_prof': Path|None, 'obj_trace': Path|None}.

Return type:

dict

science_object_table(frame, det)[source]

Return the per-object science rows for one frame (ScienceObj).

Generated by JXP and Claude.

Parameters:
  • frame (str) – Exposure basename.

  • det – Detector (int) or mosaic (tuple/list).

Returns:

One dict per detected object, keys objid, slitid, spat_pixpos, fwhm, snr_find, s2n, sign, extracted. Empty if none.

Return type:

list

science_qa_files(frame, det)[source]

Return all on-disk QA PNGs for one science (frame, det) (Stage 6 Round-1 #3, S6-Q15(a)): the per-object obj_prof/obj_trace figures and the frame-level spec_flex_* flexure figures.

Derived at view time by globbing <redux>/QA/PNGs/ for files whose name starts with the frame basename and contains the detector name — so no science-state change is needed (mirrors the S6-Q10(a) reconstruct- from-disk approach) and it works for both live and derived state.

Generated by JXP and Claude.

Parameters:
  • frame (str) – Exposure basename (the science-table key).

  • det – Detector (int) or mosaic (tuple/list).

Returns:

Sorted pathlib.Path of the matching QA PNGs (empty if the QA/PNGs directory or matches are absent).

Return type:

list

science_slit_table(frame, det)[source]

Return the per-slit science rows for one frame (ScienceSlit).

Generated by JXP and Claude.

Parameters:
  • frame (str) – Exposure basename.

  • det – Detector (int) or mosaic (tuple/list).

Returns:

One dict per slit (sorted), keys slit, status, nobj. Empty if none.

Return type:

list

science_table()[source]

Return the normalized per-frame science-status table the Science view renders (one row per (frame, detector)).

Generated by JXP and Claude.

Returns:

Columns SCIENCE_COLUMNS; empty when there are no science entries.

Return type:

pandas.DataFrame

slit_table(step, group, det)[source]

Return the per-slit/order rows for a step that tracks them (slits / wv_calib / tilts / flats).

Generated by JXP and Claude.

Parameters:
  • step (str) – Calibration step name.

  • group (int) – Calibration group ID.

  • det – Detector (int) or mosaic (tuple/list).

Returns:

One dict per slit (sorted by slit id), with keys slit, status, and step-specific metrics: center/slitord_id (slits), rms (wv_calib/tilts), or corrections (flats — a dict name {'mean':…, 'rms':…}). Empty if the step has no per-slit data.

Return type:

list

status_table()[source]

Return the normalized calibration-status table the views consume.

Built on pypeit.state.RunPypeItState.get_status() but normalized: required becomes a real bool (or None), the "--" sentinels become None/"absent", an in_pipeline column is added (membership in default_steps()), and an empty/unavailable state yields an empty table.

Generated by JXP and Claude.

Returns:

Columns STATUS_COLUMNS; empty when the reduction has not started or the state is unavailable.

Return type:

pandas.DataFrame

step_entry(step, group, det)[source]

Return the raw RunPypeItState entry for one (step, group, det), or None if absent.

Generated by JXP and Claude.

Parameters:
  • step (str) – Calibration step name (e.g. wv_calib).

  • group (int) – Calibration group ID.

  • det – Detector (int) or mosaic (tuple/list).

Returns:

The matching pydantic step entry, or None.

step_metrics(step, group, det)[source]

Return the entry-level metrics for a step, as a plain dict for the detail panel (per-slit metrics come from slit_table()).

Generated by JXP and Claude.

Parameters:
  • step (str) – Calibration step name.

  • group (int) – Calibration group ID.

  • det – Detector (int) or mosaic (tuple/list).

Returns:

Metric name → value (empty if the entry is absent or has no entry-level metrics). bias → mean/std; slits → nslits; flats → corrections/pixelflat_source.

Return type:

dict

step_order(include_bpm=False)[source]

Return the path-aware step order for the calibration button row.

Generated by JXP and Claude.

Parameters:

include_bpm (bool, optional) – Include the bpm step. Default False — bpm runs internally but has no standalone output/QA, so it is omitted from the button row (design C13).

Returns:

The ordered step names.

Return type:

list

step_output_files(step, group, det)[source]

The existing Calibrations/ file(s) a (re)build of this step would overwrite — named explicitly in the clobber confirmation (X2/X3, S4-Q4).

Most steps write a single output_file; slits writes both Slits_* (its output_file) and the companion Edges_*. Only files that currently exist on disk are returned (a step with no output yet is a fresh build, nothing to overwrite).

Generated by JXP and Claude.

Parameters:
  • step (str) – Calibration step name.

  • group (int) – Calibration group ID.

  • det – Detector (int) or mosaic (tuple/list).

Returns:

Existing pathlib.Path outputs (possibly empty).

Return type:

list

class pypeit.dashboard.model.HeaderInfo(pypeit_file, spectrograph, setup, path, redux_dir)[source]

Bases: object

Cheap, no-reduction metadata describing a reduction, used to populate the dashboard’s shared header banner (design requirement R6).

Generated by JXP and Claude.

Variables:
  • pypeit_file (str) – Name of the .pypeit file (basename, for display).

  • spectrograph (str) – The spectrograph name (PYP_SPEC), e.g. shane_kast_blue.

  • setup (str) – The setup/configuration identifier, e.g. A. May be None if the .pypeit file does not define one.

  • path (str) – The reduction path label: MultiSlit, Echelle, or IFU.

  • redux_dir (str) – The reduction directory (absolute path).

path: str = <dataclasses._MISSING_TYPE object>
pypeit_file: str = <dataclasses._MISSING_TYPE object>
redux_dir: str = <dataclasses._MISSING_TYPE object>
setup: str = <dataclasses._MISSING_TYPE object>
spectrograph: str = <dataclasses._MISSING_TYPE object>
pypeit.dashboard.model._parse_pypeit(pypeit_file, redux_path=None)[source]

Parse a .pypeit file once, returning both the header metadata and the instantiated spectrograph (the latter is reused for, e.g., detector-name formatting).

Generated by JXP and Claude.

Parameters:
  • pypeit_file (str, pathlib.Path) – Path to the .pypeit reduction file.

  • redux_path (str, optional) – Reduction directory. If None, the directory containing pypeit_file is used.

Returns:

(HeaderInfo, Spectrograph).

Return type:

tuple

Raises:

FileNotFoundError – If pypeit_file does not exist (R11 edge case).

pypeit.dashboard.model.read_header_info(pypeit_file, redux_path=None)[source]

Parse a .pypeit file and return the cheap metadata needed by the header banner, performing no reduction.

Generated by JXP and Claude.

Parameters:
  • pypeit_file (str, pathlib.Path) – Path to the .pypeit reduction file.

  • redux_path (str, optional) – Reduction directory. If None, the directory containing pypeit_file is used.

Returns:

The parsed header metadata.

Return type:

HeaderInfo

Raises:

FileNotFoundError – If pypeit_file does not exist (R11 edge case: the named .pypeit file is absent).