LifConfig

LifConfig defines the scan parameters, runtime state, and FID storage for a Laser-Induced Fluorescence (LIF) acquisition. It inherits ExperimentObjective for the acquisition lifecycle interface and HeaderStorage for configuration persistence. The class owns a LifDigitizerConfig (accessible through digitizerConfig()) and a LifStorage instance that persists raw LIF traces and processing-gate settings alongside the experiment.

A LIF acquisition sweeps a two-dimensional grid of delay times and laser positions. The traversal order is controlled by the LifScanOrder enumerator: DelayFirst cycles through all delay points before advancing the laser, and LaserFirst cycles through all laser positions before advancing the delay. The d_delayRandom flag causes the delay axis to be randomly permuted at the start of each sweep. After the grid has been fully covered once, behavior is governed by the LifCompleteMode enumerator: StopWhenComplete ends acquisition, while ContinueAveraging allows further sweeps to accumulate.

The dialog that drives this configuration is described in LIF Configuration; the experiment-wizard page in LIF Experiment Setup; the on-disk layout in LIF Data Storage.

API Reference

class LifConfig : public ExperimentObjective, public HeaderStorage

Configuration and runtime state for a LIF (Laser-Induced Fluorescence) acquisition.

LifConfig defines a two-dimensional scan over delay time and laser position, accumulating a user-specified number of shots at each grid point. The scan can traverse points in delay-first or laser-first order, and the delay axis can optionally be randomized each sweep to reduce systematic errors.

After completion LifConfig can continue averaging (ContinueAveraging mode) or stop immediately (StopWhenComplete mode). The class owns a LifStorage instance that persists raw LIF traces and processing-gate settings to disk.

See also

LifDigitizerConfig, LifStorage, LifTrace

Public Types

enum LifScanOrder

Controls the order in which the 2-D scan grid is traversed.

Values:

enumerator DelayFirst

Scan all delay points before advancing the laser position.

enumerator LaserFirst

Scan all laser positions before advancing the delay.

enum LifCompleteMode

Controls behavior when the scan grid has been fully covered once.

Values:

enumerator StopWhenComplete

Stop acquisition after the first complete sweep.

enumerator ContinueAveraging

Continue accumulating additional sweeps indefinitely.

Public Functions

LifConfig(const QString &digitizerHwKey)

Construct with the hardware key of the LIF digitizer.

Parameters:

digitizerHwKey – Hardware key string identifying the LIF digitizer.

~LifConfig() = default
inline LifDigitizerConfig &digitizerConfig()

Return a mutable reference to the LIF digitizer configuration.

inline const LifDigitizerConfig &digitizerConfig() const

Return a const reference to the LIF digitizer configuration.

virtual bool isComplete() const override

Return true when d_complete is set and (if ContinueAveraging) once at 1000 per-mille.

double currentDelay() const

Return the current delay time in microseconds.

double currentLaserPos() const

Return the current laser position as an output-beam wavenumber (cm⁻¹), converted from the display-unit scan grid at this dispatch boundary.

QPair<double, double> delayRange() const

Return the (start, end) delay range in microseconds.

QPair<double, double> laserRange() const

Return the (start, end) laser position range, in the display LaserUnit.

int targetShots() const

Return the total number of shots across the full scan grid.

int completedShots() const

Return the number of shots accumulated so far.

QPair<int, int> lifGate() const

Return the (start, end) sample indices of the LIF signal gate.

QPair<int, int> refGate() const

Return the (start, end) sample indices of the reference gate.

inline std::shared_ptr<LifStorage> storage()

Return the shared LifStorage object managing on-disk data.

void addWaveform(const QVector<qint8> d)

Accept a raw LIF waveform and add it to storage at the current scan point.

Constructs a LifTrace and forwards it to LifStorage. If d_completeMode is StopWhenComplete and d_complete is true, the waveform is discarded.

Parameters:

d – Raw waveform bytes from the LIF digitizer.

void loadLifData()

Reconstruct LifStorage from disk for post-acquisition loading.

void setLaserUnits(BC::LifConv::LaserUnit units)

Set the display unit used for the laser position axis.

Parameters:

units – Display unit (BC::LifConv::LaserUnit).

void setLaserDecimals(int decimals)

Set the decimal precision used when serializing the laser position axis.

LaserStart/LaserStep are formatted in header.csv with this many fractional digits. Callers seed it from the LIF laser hardware’s display-decimals setting at acquisition time — the same setting that quantizes the start/step entry spin boxes the axis is built from, so a value from that path round-trips exactly at this width. On load it is inferred from the on-disk formatting of LaserStart/LaserStep.

inline BC::LifConv::LaserUnit laserUnits() const

Return the laser position display unit.

Populated from the column-6 unit cell of the LaserStart header row on load, or from the laser hardware setting at acquisition. The laser scan axis (d_laserPosStart/Step) is uniform in this unit; see currentLaserPos() for the display->output-cm⁻¹ conversion at the hardware-dispatch boundary.

inline int laserDecimals() const

Return the laser-position display precision in fractional digits.

Inferred at load time from the on-disk strings of LaserStart and LaserStep (max fractional digits across both), and seeded from the laser hardware setting at acquisition time. Used by display widgets for axis-label formatting; not persisted as its own row.

void setConversionNodes(std::vector<BC::LifConv::Node> nodes, const QString &laserKey)

Record the per-experiment conversion-topology node list and rebuild the cached assembled conversion from it.

nodes is the authoritative, already-joined node-descriptor list (op/n from each stage’s hardware, inputs/isFinal from the per-experiment wiring); empty for the identity / bare-laser case, where the output beam is the grating fundamental and no topology file is written. laserKey is the active LifLaser’s hwKey, used to serialize a tunable-source (RefType::Laser) input by its real hwKey rather than a sentinel.

Rebuilds the cached conversion() via LifConversion::assemble(); on assembly failure the cache falls back to the identity conversion (mirroring the tolerant fallback used elsewhere when a topology cannot yet be assembled, e.g. mid-edit).

inline const std::vector<BC::LifConv::Node> &conversionNodes() const

Return the current conversion-topology node list (empty = identity/no stages).

inline const LifConversion &conversion() const

Return the conversion assembled from conversionNodes() by the most recent setConversionNodes() call (identity if never set, or if assembly failed).

inline bool hasConversion() const

Return true when conversionNodes() is non-empty.

bool writeTopologyFile() const

Write liftopology.csv — one row per conversion node — into the experiment directory.

Records the raw DAG (op, harmonic order, input wiring, FINAL marker) alongside each node’s resolved output-beam affine mapping (output = A·fundamental + B, cm⁻¹). The FINAL row’s coefficients are the output-axis ↔ fundamental relation. Does nothing and returns true for the identity case (no conversion stages): header.csv already carries the full display-unit axis. Returns false only on a file-write failure.

bool readTopologyFile()

Read liftopology.csv, if present, and reconstruct the conversion-topology node list via setConversionNodes().

Mirrors RfConfig::loadClockSteps(): resolves the file from this config’s own d_number/d_path. A missing file means the identity case (writeTopologyFile() skips writing one) and is not an error. Input tokens are classified as Fixed: <cm1> -> Fixed, a token matching another row’s StageKey -> Stage, and anything else -> Laser (that token is the laser hwKey, captured as the config’s conversion laser key). OutCoeffA/B are derived data recomputed via assembly, not read. Returns false only when the file exists but cannot be opened.

virtual void prepareChildren() override

Register child HeaderStorage objects (LifDigitizerConfig).

virtual bool initialize() override

Initialize storage, build the delay index permutation, and start acquisition.

Returns:

Always returns true for LifConfig.

virtual bool advance() override

Advance the scan to the next point; return true if the point was incremented.

Checks whether the current point has reached its shot target, shuffles the delay order if randomization is enabled and a full delay sweep just completed, and calls LifStorage::advance().

virtual void hwReady() override

Clear the processing-paused flag when hardware reports readiness.

virtual int perMilComplete() const override

Return progress in per-mille (0–1000) across all scan points.

virtual bool indefinite() const override

Return true when ContinueAveraging mode is active and a full sweep is done.

virtual bool abort() override

Abort the LIF acquisition; always returns false (no-op).

virtual QString objectiveKey() const override

Return the experiment-config key used to identify the LIF type.

virtual void cleanupAndSave() override

Finalize LifStorage and flush data to disk.

Public Members

bool d_complete = {false}

Set to true once the first full sweep is complete.

LifScanOrder d_order = {DelayFirst}

Scan traversal order.

LifCompleteMode d_completeMode = {ContinueAveraging}

Behavior on completion.

bool d_disableFlashlamp = {true}

Disable the laser flashlamp between scan points when true.

double d_delayStartUs = {-1.0}

Delay scan start time in microseconds.

double d_delayStepUs = {0.0}

Delay scan step size in microseconds.

int d_delayPoints = {0}

Number of delay scan points.

bool d_delayRandom = {false}

Randomize delay point order each sweep when true.

QVector<int> d_delayIndices

Permuted index array for randomized delay scanning.

int d_delayScanIndex = {0}

Current position within d_delayIndices.

double d_laserPosStart = {-1.0}

Laser scan start position, in the display LaserUnit.

double d_laserPosStep = {0.0}

Laser scan step size, in the display LaserUnit.

int d_laserPosPoints = {0}

Number of laser scan points.

LifTrace::LifProcSettings d_procSettings

Gate positions and processing parameters for LIF traces.

int d_shotsPerPoint = {0}

Target number of shots to accumulate at each scan point.

Protected Functions

virtual void storeValues() override

Serialize LifConfig fields into HeaderStorage.

virtual void retrieveValues() override

Deserialize LifConfig fields from HeaderStorage.

Private Members

std::shared_ptr<LifStorage> ps_storage
std::shared_ptr<LifDigitizerConfig> ps_digitizerConfig
BC::LifConv::LaserUnit d_laserUnits = {BC::LifConv::LaserUnit::Nm}
int d_laserDecimals = {2}
std::vector<BC::LifConv::Node> d_conversionNodes

Conversion-topology node descriptors (empty = identity/no stages).

LifConversion d_conversion

Assembled conversion, for resolved per-node output coefficients.

QString d_conversionLaserKey

Active LifLaser hwKey, for serializing tunable-source inputs.

int d_currentDelayIndex = {0}
int d_currentLaserIndex = {0}
int d_completedSweeps = {0}