Fid

Fid is the implicitly shared value type that carries a single co-averaged free-induction decay through Blackchirp’s acquisition and analysis pipeline.

FTMW digitizer drivers (FtmwDigitizer subclasses) parse raw waveform bytes into accumulated samples and stage them in a waveform buffer. The acquisition layer drains that buffer into a FidList (QVector<Fid>) — one entry per LO step or sideband channel — and hands it to FtWorker, which produces an Ft magnitude spectrum. FtmwViewWidget and the blackchirp-viewer’s ExperimentViewWidget share that path to drive the frequency-domain plot, peak finder, and overlay system. The accumulation and storage settings live on FtmwConfig; the RF and sideband parameters that set probeFreq and sideband come from RfConfig.

API Reference

class Fid

Implicitly shared value type that stores a single co-averaged free-induction decay (FID).

Data are stored in an implicitly shared FidData pointer, which handles reference counting and copy-on-write semantics. Please see Qt documentation on implicit sharing for details. Copying an Fid is inexpensive because only the pointer is duplicated; a deep member-by-member copy occurs only when a mutating operation is called while more than one Fid shares the same underlying data.

An Fid holds a vector of co-averaged integer samples (arbitrary digitizer units), a probe frequency (MHz), a sideband label, a per-sample time spacing (s), a voltage multiplier that converts the integer samples to volts, and a shot count. Non-const functions trigger a deep copy whenever the data is shared; const functions never do.

The convenience alias FidList is a QVector<Fid> and carries the same implicit-sharing benefits at the list level.

Public Functions

Fid()

Default constructor.

Allocates a default FidData object with zero size, unit voltage multiplier, zero shots, and the upper sideband.

Fid(const Fid &rhs)

Copy constructor (shallow; increments the shared reference count).

Parameters:

rhs – FID to copy.

Fid &operator=(const Fid &rhs)

Copy-assignment operator.

Parameters:

rhs – FID to copy.

Returns:

Reference to this FID after assignment.

~Fid()

Destructor.

Explicit declaration is required for the implicit-sharing mechanism. When the last reference to the underlying FidData is released the data is freed.

void setSpacing(const double s)

Sets the inter-sample time spacing (can trigger a deep copy).

Parameters:

s – New spacing in seconds.

void setProbeFreq(const double f)

Sets the probe (local-oscillator) frequency (can trigger a deep copy).

Parameters:

f – New probe frequency in MHz.

void setData(const QVector<qint64> d)

Replaces the raw sample vector (can trigger a deep copy).

Parameters:

d – New data vector of co-averaged integer samples.

void setSideband(const RfConfig::Sideband sb)

Sets the sideband label (can trigger a deep copy).

Parameters:

sb – Sideband; either RfConfig::UpperSideband or RfConfig::LowerSideband.

void setVMult(const double vm)

Sets the voltage multiplier used to convert integer samples to volts (can trigger a deep copy).

Parameters:

vm – Voltage multiplier in V/count.

void setShots(const quint64 s)

Sets the shot count (can trigger a deep copy).

Parameters:

s – Number of hardware shots co-averaged into the current data.

void detach()

Detaches the internal data vector from any shared storage.

Forces a deep copy of the QVector inside FidData, ensuring that subsequent raw-pointer operations do not alias another Fid's buffer.

Fid &operator+=(const Fid other)

Adds another FID’s samples in-place, accumulating shot counts.

Parameters:

other – FID whose samples are added element-wise to this one.

Returns:

Reference to this FID after addition.

Fid &operator+=(const QVector<qint64> other)

Adds a raw integer vector in-place, incrementing the shot count by one.

Parameters:

other – Vector of integer samples whose length must match size().

Returns:

Reference to this FID after addition.

Fid &operator+=(const qint64 *other)

Adds a raw C-array in-place, incrementing the shot count by one.

Parameters:

other – Pointer to an array of at least size() integer samples.

Returns:

Reference to this FID after addition.

Fid &operator-=(const Fid other)

Subtracts another FID’s samples in-place, adjusting the shot count.

If other has more shots than this FID, the subtraction is reversed so that the resulting shot count remains non-negative: the result represents other - this and carries other.shots() - this.shots() shots.

Parameters:

other – FID to subtract.

Returns:

Reference to this FID after subtraction.

void add(const Fid other, int shift)

Adds another FID’s samples with an optional time-domain shift.

When shift is zero this is equivalent to operator+=. For non-zero shift, sample i of other is added to sample i+shift of this FID, with out-of-range indices treated as zero.

Parameters:
  • other – FID whose samples are added.

  • shift – Integer sample offset applied to other before accumulation.

void copyAdd(const qint64 *other, const unsigned int offset = 0)

Copies a contiguous block from a raw C-array into the internal buffer.

Uses memcpy to overwrite this FID’s internal sample vector with size() samples read from other+offset. The shot count is incremented by one.

Parameters:
  • other – Pointer to the source sample array.

  • offset – Number of elements to skip at the start of other.

void rollingAverage(const Fid other, quint64 targetShots, int shift = 0)

Performs a rolling co-average against another FID.

Accumulates other into this FID up to targetShots shots. Once the combined shot count would exceed targetShots, the accumulator is renormalized to exactly targetShots shots using integer rounding.

Parameters:
  • other – New FID to incorporate.

  • targetShots – Maximum number of shots to retain in the rolling average.

  • shift – Integer sample offset applied to other before accumulation.

int size() const

Returns the number of samples in the data vector.

Returns:

Sample count.

bool isEmpty() const

Returns true if the data vector contains no samples.

Returns:

true when size() == 0.

double at(const int i) const

Returns the voltage at the specified index.

The returned value is the normalized (per-shot) integer sample multiplied by the voltage multiplier: atNorm(i) * vMult().

Parameters:

i – Sample index.

Returns:

Voltage in volts.

double spacing() const

Returns the inter-sample time spacing.

Returns:

Spacing in seconds.

double probeFreq() const

Returns the probe (local-oscillator) frequency.

Returns:

Probe frequency in MHz.

QVector<QPointF> toXY() const

Builds a QVector of (time, voltage) points suitable for plotting.

Each point has x = i * spacing() and y = at(i).

Returns:

XY data vector with one point per sample.

QVector<double> toVector() const

Returns the data as a vector of voltage values.

Equivalent to calling at(i) for each index; applies per-shot normalization and the voltage multiplier.

Returns:

Vector of voltage values in volts.

QVector<qint64> rawData() const

Returns the raw (un-normalized, un-scaled) co-averaged integer sample vector.

Returns:

Copy of the internal integer sample buffer.

qint64 atRaw(const int i) const

Returns the raw integer sample at index i (bounds-checked via QVector::at).

Parameters:

i – Sample index.

Returns:

Raw integer sample value.

qint64 valueRaw(const int i) const

Returns the raw integer sample at index i, or 0 if out of range.

Uses QVector::value() so out-of-range accesses return 0 instead of asserting. Useful when adding FIDs with a time-domain shift.

Parameters:

i – Sample index (may be out of range).

Returns:

Raw integer sample value, or 0.

double atNorm(const int i) const

Returns the per-shot normalized sample at index i.

When shots() > 1 the raw value is divided by the shot count; when shots() <= 1 the raw value is returned as-is (cast to double).

Parameters:

i – Sample index.

Returns:

Normalized sample value (arbitrary units, no voltage scaling applied).

quint64 shots() const

Returns the number of hardware shots co-averaged into the data.

Returns:

Shot count.

RfConfig::Sideband sideband() const

Returns the sideband label.

Returns:

RfConfig::UpperSideband or RfConfig::LowerSideband.

double maxFreq() const

Calculates the maximum spectral frequency that an FFT of this FID can represent.

For the upper sideband the maximum frequency is probeFreq() + 1 / (2 * spacing() * 1e6) MHz. For the lower sideband the probe frequency is the maximum.

Returns:

Maximum frequency in MHz, or 0 if spacing() is zero.

double minFreq() const

Calculates the minimum spectral frequency that an FFT of this FID can represent.

For the lower sideband the minimum frequency is probeFreq() - 1 / (2 * spacing() * 1e6) MHz. For the upper sideband the probe frequency is the minimum.

Returns:

Minimum frequency in MHz, or 0 if spacing() is zero.

double vMult() const

Returns the voltage multiplier.

Returns:

Voltage multiplier in V/count.

Private Members

QSharedDataPointer<FidData> data

The internal implicitly-shared data storage object.

class FidData : public QSharedData

Internal data for Fid (implicitly shared via QSharedData).

Stores the inter-sample time spacing (s), the probe frequency (MHz), the voltage multiplier (V/count), the shot count, the sideband label, and the raw co-averaged integer sample vector. This class is an implementation detail of Fid and is not part of the public API.

Public Functions

inline FidData()

Public Members

double spacing = {1.0}

Inter-sample time spacing in seconds.

double probeFreq = {0.0}

Local-oscillator probe frequency in MHz.

double vMult = {1.0}

Voltage multiplier (V/count) applied when converting to volts.

quint64 shots = {0}

Number of hardware shots accumulated in fid.

QVector<qint64> fid

Co-averaged raw integer sample buffer.

RfConfig::Sideband sideband = {RfConfig::UpperSideband}

Sideband label for frequency-axis orientation.