BCLifTrace

BCLifTrace is the single-point LIF container served by BCLIF.get_trace. It loads one lif/N.csv file, decodes the base-36-packed accumulated samples for the LIF and (optional) reference channels into per-shot voltages using the matching lifparams.csv row, and stores the result as 1-D numpy arrays. has_ref reports whether the trace file carried a reference column; xy() returns (x, lif, ref) when it did and (x, lif) when it did not.

The smooth and integrate methods reproduce Blackchirp’s GUI display path bit-for-bit. smooth applies an IIR low-pass filter followed by a Savitzky-Golay smoother, with both stages controlled by processing.csv (LowPassAlpha, SavGolEnabled, SavGolWindow, SavGolPoly) and overridable per call. integrate runs the same filter chain, then takes a trapezoidal sum in sample-index space: integration gates are sample indices, not times, and dx is one sample. Without a reference channel the result is in V·sample (multiply by self.spacing to get V·s); with a reference channel the result is the dimensionless ratio of LIF to reference integrals.

The integration-gate semantics, the reference-channel ratio behaviour, and the on-disk layout of the trace files are described on the LIF Data Storage user-guide page. The BCLIF aggregating helpers (delay_slice, laser_slice, image) call integrate on every present scan point with a single shared processing-override surface.

API Reference

class blackchirp.BCLifTrace(num: int, path: str, params: pandas.Series, sep: str, proc: dict)

Container for a single LIF scan-point trace.

Reads lif/N.csv for one (lIndex, dIndex) pair, decodes the base-36-encoded accumulated samples to per-shot voltages, and exposes the smoothing and integration operations that BCLIF uses to build axis slices and 2D images.

Parameters:
  • num – File number for the trace (N in lif/N.csv).

  • path – Experiment folder path.

  • params – Row from lifparams.csv corresponding to this point.

  • sep – CSV delimiter for the experiment.

  • proc – Default processing settings, parsed from lif/processing.csv.

params

The matching lifparams.csv row.

Type:

pd.Series

proc

Default processing settings.

Type:

dict

shots

Number of shots accumulated at this point.

Type:

int

lifsize

Number of LIF samples per shot.

Type:

int

refsize

Number of reference samples per shot (0 if no reference channel was recorded).

Type:

int

spacing

Sample spacing, in seconds.

Type:

float

lifymult

LIF y-multiplier (volts per integer sample).

Type:

float

refymult

Reference y-multiplier (volts per integer sample). 0 when no reference channel was recorded.

Type:

float

has_ref() bool

Indicate whether a reference channel was recorded.

integrate(lif_start=None, lif_end=None, ref_start=None, ref_end=None, **proc_overrides) float

Integrate the LIF channel and return a (possibly ratioed) float.

The trapezoidal sum is taken in sample-index space: gates are sample indices, not times, and dx is one sample. This matches Blackchirp’s GUI display number bit-for-bit.

Units. Without a reference channel, the result is in V·sample — equivalently, voltage integrated against an integer index. To convert to a time-domain integral, multiply by self.spacing (V·s) or self.spacing * 1e9 (V·ns). With a reference channel, the result is the dimensionless ratio lif_integral / ref_integral; the conversion factors cancel because both halves of the ratio are computed in the same sample-index space. If the reference integral is numerically zero the unratioed LIF integral (in V·sample) is returned instead.

Parameters:
  • lif_start – Override LIF gate start sample.

  • lif_end – Override LIF gate end sample.

  • ref_start – Override reference gate start sample.

  • ref_end – Override reference gate end sample.

  • **proc_overrides – Optional low_pass_alpha, savgol_window, savgol_poly, savgol_enabled overrides.

Returns:

Integrated value as a float.

lif() numpy.ndarray

Return the per-shot LIF waveform, in volts.

ref() numpy.ndarray | None

Return the per-shot reference waveform, or None.

None is returned for single-channel acquisitions (those whose lifparams row has refsize == 0).

smooth(low_pass=None, savgol=None, *, low_pass_alpha=None, savgol_window=None, savgol_poly=None) numpy.ndarray

Apply the IIR-then-Sav-Gol filter chain to the LIF channel.

Parameters:
  • low_pass – Override IIR-filter use. None follows processing.csv (apply if LowPassAlpha > 0); True forces the IIR on, False forces it off, and a numeric value overrides the alpha coefficient directly.

  • savgol – Override Savitzky-Golay use. None follows processing.csv (SavGolEnabled); True / False force on / off.

  • low_pass_alpha – Override the IIR alpha coefficient.

  • savgol_window – Override the Sav-Gol window length.

  • savgol_poly – Override the Sav-Gol polynomial order.

Returns:

The smoothed LIF waveform as a 1D numpy array.

x(units: str = 's') numpy.ndarray

Compute the time array for the trace.

Parameters:

units – One of "s", "ms", "us" (or "μs"), "ns". "s" is the default; the other choices rescale the array for plotting convenience and have no effect on stored sample spacing.

Returns:

1D numpy array of sample times in the requested units.

Raises:

ValueError – If units is not a recognised time-unit string.

xy(units: str = 's')

Return time and waveform arrays as a tuple.

For with-reference traces, the tuple is (x, lif, ref); for single-channel traces, (x, lif). The units argument controls the time axis only (see x()).