Observation Modes#
Different observing strategies require different reference selection and data preparation. This page describes the supported modes and how to add new ones.
Mode Detection#
The engine auto-detects the observation mode from the data via
prepare() in cal-core/src/modes/prepare.rs:
Check the
instmodeattribute andsobsmodestringsDetect OTF-chopped (dual beam switch) from SWA/SWB patterns
Detect OTF from OTF-ON/OTF-OFF patterns
Fall back to
TotalPowerif ambiguous
This can be overridden with --mode otf, --mode tp, or
--mode otf-chopped on the command line.
Implementation: cal-core/src/config.rs – ObsMode enum,
cal-core/src/modes/prepare.rs – prepare() dispatcher
Implemented Modes#
TotalPower (TP)#
Single-point position-switched observations with discrete ON/OFF pairs.
graph LR
OFF1[OFF] --> ON1[ON]
ON1 --> OFF2[OFF]
OFF2 --> ON2[ON]
ON2 --> OFF3[OFF]
style OFF1 fill:#bbdefb
style OFF2 fill:#bbdefb
style OFF3 fill:#bbdefb
style ON1 fill:#c8e6c9
style ON2 fill:#c8e6c9
ON subscans: single dump per pointing
Reference: linear interpolation between bracketing OFFs (by MJD)
Matching: each ON is paired with its temporally bracketing OFFs
OTF TotalPower#
On-the-fly scanning where multiple dumps trace a path across the source.
graph LR
OFF1[OFF] --> OTF1[OTF-ON<br/>D dumps]
OTF1 --> OFF2[OFF]
OFF2 --> OTF2[OTF-ON<br/>D dumps]
OTF2 --> OFF3[OFF]
style OFF1 fill:#bbdefb
style OFF2 fill:#bbdefb
style OFF3 fill:#bbdefb
style OTF1 fill:#c8e6c9
style OTF2 fill:#c8e6c9
ON subscans: multiple dumps along scan direction (D > 1)
Reference: linear interpolation between bracketing OFFs, averaged over all dumps (NaN-aware)
OTF coordinates:
otf_lonandotf_latare propagated to the output as[D, S]arrays
OTF Chopped (Dual Beam Switch)#
On-the-fly scanning with beam switching (OTFSWA/OTFSWB patterns). Each ON subscan is paired with its same-beam OFF. Beams A and B are calibrated independently.
ON subscans: SWA-ON and SWB-ON dumps
Reference: per-dump OFF subtraction (matching kalibrate’s per-dump subtraction for chopped data)
DBS coupling: optional adhesive coupling (
--dbs-coupling) enables cross-beam OFF averaging and post-calibration A+B merge
Implementation: cal-core/src/modes/prepare.rs –
prepare_otf_chopped(), cal-io/src/pipeline/dbs.rs –
merge_dbs_pairs()
Data Preparation#
File: cal-core/src/modes/prepare.rs
A single prepare() function dispatches to mode-specific preparation
based on auto-detected ObsMode:
pub fn prepare(scan: &ScanData) -> Result<(PreparedData, ObsMode), CalibrationError> {
let mode = scan.detect_obs_mode();
let prepared = match mode {
ObsMode::OtfTotalPower => prepare_otf(scan)?,
ObsMode::OtfChopped => prepare_otf_chopped(scan)?,
ObsMode::TotalPower => prepare_tp(scan)?,
// ...
};
Ok((prepared, mode))
}
The preparation phase decouples reference selection from calibration math, enabling vectorized processing:
Identify ON subscan indices from
sobsmodeFor each ON, find bracketing OFFs and interpolate linearly by MJD
Deduplicate OFF references (compute average once, reuse for all ONs sharing the same reference)
Build
ref_data[C, R, A, S_on]from interpolated OFF averagesCompute integration time
t_int[S_on]
The ON data is not copied – PreparedData stores indices into
ScanData.data, and the calibration loop reads from there directly.
This avoids a ~1 GB allocation for large OTF datasets.
The calibration math (calibrate_full) is mode-agnostic – it
operates on the PreparedData output uniformly.
Stubbed / Future Modes#
The ObsMode enum includes placeholders for:
BeamSwitch – standalone (non-OTF) beam-switched reference
FrequencySwitch – reference from frequency-shifted spectra
These will be implemented when test data becomes available. See /source/developer/adding-observation-mode for the extension guide.