pub struct LfqConfig {Show 26 fields
pub mz_ppm: f64,
pub rt_window_pct: f64,
pub im_tolerance: f64,
pub n_isotopes: usize,
pub grid_cols: usize,
pub grid_scans_per_column: f64,
pub peak_max_halfwidth_frac: f64,
pub min_spectral_bhattacharyya: f64,
pub score_mode: ScoreMode,
pub run_tdc: bool,
pub decoy_mz_shift_da: f64,
pub decoy_rt_shift_pct: f64,
pub consensus: ConsensusConfig,
pub normalize: String,
pub quant_estimator: String,
pub detected_use_grid: bool,
pub rt_spread_scoring: bool,
pub search_scoring: SearchScoring,
pub search_rt_rescue: bool,
pub search_rt_rescue_per_run_transfers: bool,
pub search_expand_charges: bool,
pub search_gate_transfers_only: bool,
pub averagine_projection: bool,
pub decoy_own_template: bool,
pub lone_coelution: f64,
pub isotope_model: IsotopeModelSpec,
}Expand description
Configuration for LFQ grid extraction and peak integration.
Fields§
§mz_ppm: f64m/z tolerance for hill lookup (ppm)
rt_window_pct: f64Half-window size as a fraction of the run’s total RT span. 0.005 = ±0.5% of the observed RT span → 1% total window, centred on the alignment-predicted native RT. Default 0.005.
im_tolerance: f64Ion mobility half-window for hill lookup (absolute 1/K0 units). Default 0.015; inert when the input has no ion mobility.
n_isotopes: usizeNumber of isotopologue rows: 1 = M only, 2 = M+M1, 3 = M+M1+M2
grid_cols: usizeRetention-time bins across the extraction window. This should track the run’s MS1 scan density: on a two-hour Orbitrap gradient the default window holds roughly fifteen real scans, so a finer grid spreads them over mostly empty bins and the per-column statistics that drive scoring and peak bounds become noise. Measured on IonStar, dropping from 100 to 25 cuts the paired CV difference against FlashLFQ from 2.98 to 0.76 points and improves identification-free median CV from 16.58% to 14.00%. A faster-scanning instrument supports more bins; deriving this from the observed scan rate instead of a fixed count is the proper fix.
grid_scans_per_column: f64Target MS1 scans averaged into each retention-time column. When above
zero the column count is derived per run from the measured scan spacing
as window / (target * spacing), so the amount of smoothing per column
is the same on a fast instrument as on a slow one, and grid_cols
becomes an upper bound. A column fed by a single scan carries that
scan’s noise straight into the isotope and hybrid statistics that choose
the peak bounds, which is what a fixed column count produced here: on
these gradients 100 columns worked out to 1.01 scans each.
peak_max_halfwidth_frac: f64Furthest a peak may expand from its apex, as a fraction of the grid’s half-width. This used to be a fixed twenty bins, which silently coupled the integration width to the grid resolution: the same setting meant 0.28 minutes at 100 columns and 0.07 at 400, so raising the resolution truncated peaks. Expressed against the window it means the same span whatever the column count. One allows expansion across the half-window, leaving the isotope and hybrid gates as the operative control.
min_spectral_bhattacharyya: f64Minimum spectral Bhattacharyya score for a grid column to keep
extending the integration peak (peak-expansion gate). Named for the
metric it actually uses — it is NOT a cosine threshold. Optional
(defaults to 0.1 when omitted); the config was previously named
spectral_cosine_min, which now errors (see deny_unknown_fields).
score_mode: ScoreModeScoring mode used to find the best integration window
run_tdc: boolWhether to run target-decoy competition and compute q-values
decoy_mz_shift_da: f64Decoy m/z shift in Da, added to the target m/z and divided by charge (so the decoy m/z = target_mz + decoy_mz_shift_da / charge). Must be large enough to fall outside any plausible isotopologue or adduct envelope of the target.
decoy_rt_shift_pct: f64Decoy RT shift as a fraction of the run’s RT span, subtracted from the
target RT. The default 0.01 is twice the default extraction half-window,
so the target and decoy RT windows meet at one boundary. A shift larger
than twice rt_window_pct fully separates their RT intervals.
consensus: ConsensusConfigTolerances for building the multi-run consensus feature list.
normalize: StringCross-run intensity normalization applied to the assembled matrix. “none” = raw intensities (original; downstream must normalize). “median_ratios” = DESeq/edgeR-style size factors: each run is scaled by the median, over features detected in ALL runs, of its log2 deviation from the per-feature mean. Robust to a fraction of genuinely-changing features, unlike a plain column-median (which is biased when a sizeable subset of peptides changes systematically). Default “none”.
quant_estimator: StringPer-cell intensity estimator for the consensus matrix.
“apex” = apex intensity (detected: feature intensityApex; MBR: total
isotopologue intensity at the apex grid column). Default since
0.10.0: lower fold-change error than “sum” on IonStar and on a
held-out cohort (see docs/CONFIGURATION.md §4.2).
“sum” = integrated peak area (detected: feature intensitySum; MBR:
summed XIC grid over start..=end). The default before 0.10.0.
detected_use_grid: boolQuantify EVERY consensus cell (detected and MBR) by the same grid re-integration, instead of using the per-run feature’s own intensity for detected cells. Keeps detected and MBR cells on one commensurate scale — essential on timsTOF, where the feature integrates the ion-mobility dimension but the 2-D XIC grid does not, so mixing the two inflates CV, and validated as a win on Orbitrap too (PXD003881: gated matrix CV 14.27 → 12.31 %, ECOLI bias −0.067 → −0.020, HUMAN IQR 0.219 → 0.194). Default TRUE since 2026-08-27: one estimator, one scale, everywhere. Legacy false values now warn and use grid intensities: exclusive native signal ownership cannot validate a feature-intensity override.
rt_spread_scoring: boolReplace the raw RT closeness term in the hybrid score with a
σ-normalised Gaussian RT likelihood exp(−½ z²), where
z = (column RT − predicted RT) / σ_local(RT) and σ_local is the
post-warp RT-residual spread estimated per run from the RANSAC inlier
anchors (see alignment::RtSigmaModel). Makes the RT term of the
target-decoy discriminant region-aware: strict where alignment is
confident, tolerant where it is not. Applied identically to target and
decoy cells so the TDC null stays calibrated. Non-reference runs only;
falls back to the raw term when no σ model is available. Default false.
search_scoring: SearchScoringExperimental search-guided scorer; legacy preserves the release path.
search_rt_rescue: boolRescue unambiguous same-run IDs when global RT observations conflict. Ambiguous targets remain ineligible for cross-run transfer.
search_rt_rescue_per_run_transfers: boolDecide transfer eligibility per recipient run rather than per target.
Without this, pruning one run’s ambiguous IDs withdraws the peptide from
transfer in every run, including runs whose chromatography was clean.
Requires search_rt_rescue; runs whose own IDs were withheld as
unsupported stay ineligible, and a target whose retained IDs still
disagree across runs remains globally ineligible because its consensus
coordinate is what a transfer would be centred on.
search_expand_charges: boolExperimental inferred 2+/3+/4+ targets, with explicit charge provenance.
search_gate_transfers_only: boolApply the extraction q-value gate only to transferred cells. A cell with an accepted same-run MS2 identification has already passed peptide-level FDR; gating it again on an exploratory extraction score re-litigates an identification that was accepted, and discards a quantity for a peptide known to be present in that run. Transfers, which have no such evidence, stay gated. FlashLFQ applies FDR to its match-between-runs peaks only. Identification-free mode is unaffected: every cell there is inferred, so every cell stays gated.
averagine_projection: boolReport the averagine-projected intensity per cell instead of the raw
box-sum. For each grid column the observed isotopologue vector is passed
through a matched filter for the theoretical averagine pattern (the same
mass-derived fingerprint the Bhattacharyya score already uses):
proj = <observed, pattern_hat>, where pattern_hat is the L2-normalised
pattern. As a matched filter this maximises SNR for on-pattern signal
(recovering faint peptides the raw sum buries in noise) and rejects the
component of each column orthogonal to the fingerprint (intensity
distributed unlike averagine — interference, chemical noise). It is NOT a
pattern-match gate: gross mismatches (lone monoisotopes, wrong charge)
are still rejected by the Bhattacharyya window gate and the TDC q-value,
unchanged. The per-peptide constant ‖pattern‖ factor cancels in
cross-run ratios and CV, so LFQ ratios/CV are unaffected in scale. Apex
selection and window expansion stay on the raw signal / hybrid score;
only the reported value changes. Default false (byte-identical raw
box-sum). Mass-based, ID-free. Effect on the benchmark is unmeasured —
this is an opt-in knob to be validated, not a new default.
decoy_own_template: bool(Experiment B / audit A2) Score each decoy cell against an averagine
isotope template and theoretical pattern computed from the DECOY’s own
shifted mass (neutral_mass + decoy_mz_shift_da) rather than the target’s
mass. When false the decoy reuses the target’s template. When true
(the default) the +11 Da decoy is judged against the isotope envelope it
actually sits on, removing the target-template freebie a mis-massed
decoy otherwise inherits on the Bhattacharyya (QDA feature 2) and the
co-elution theory weighting (feature 3). Applies only to the TDC decoy
grid; target scoring and all reported intensities are unchanged.
lone_coelution: f64(Experiment B / audit A4) Co-elution value assigned to a grid cell with fewer than two isotope rows carrying signal (a lone monoisotope — nothing to co-elute). Applied identically to target and decoy cells. Default 0.5 (neutral). 1.0 gives an un-judgeable cell the maximal, target-like score, which hands noise-grabbing lone-hill decoys a free target-like coordinate on QDA feature index 3.
isotope_model: IsotopeModelSpecWhich analyte class’s average composition the LFQ isotope templates are
built from. Mirrors [features] isotope_model and must match the model
the per-run features were detected with, or the consensus cells are
scored against a pattern the detector never used. Default "peptide".
Trait Implementations§
Source§impl<'de> Deserialize<'de> for LfqConfig
impl<'de> Deserialize<'de> for LfqConfig
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for LfqConfig
impl RefUnwindSafe for LfqConfig
impl Send for LfqConfig
impl Sync for LfqConfig
impl Unpin for LfqConfig
impl UnsafeUnpin for LfqConfig
impl UnwindSafe for LfqConfig
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.