pub struct FeaturesConfig {Show 19 fields
pub min_charge: u8,
pub max_charge: u8,
pub min_chain_cosine: f64,
pub min_isotope_step_ratio: f64,
pub max_isotopes: usize,
pub max_isotope_log2_ratio: f64,
pub chain_predicted_intensity_gate: bool,
pub min_scan_overlap: usize,
pub exhaustive_min_isotope_score: f64,
pub isotope_evidence_ratio_sigma: f64,
pub isotope_evidence_cosine_shape: f64,
pub exhaustive_isotope_priority: bool,
pub cosine_anchor: String,
pub sulfur_offsets: Vec<i8>,
pub isotope_model: IsotopeModelSpec,
pub neutron_mass: f64,
pub min_isotope_score: f64,
pub min_cosine_score: f64,
pub min_combined_score: f64,
}Fields§
§min_charge: u8§max_charge: u8§min_chain_cosine: f64Per-extension chromatographic-cosine threshold used while building an isotope chain. The candidate hill’s cosine vs the seed hill must clear this to be added; otherwise chain extension stops in that direction.
min_isotope_step_ratio: f64Minimum intensity a candidate isotope hill must retain relative to its
chain predecessor, as a fraction: a heavier isotope must be at least
this fraction of its predecessor’s intensity or the chain stops. Chain
extension runs upward only (the seed IS the monoisotope hypothesis), so
there is no downward counterpart to this knob. Default 0.01. The
pre-0.3.0 name right_max_decrease is still accepted.
max_isotopes: usize§max_isotope_log2_ratio: f64Per-extension intensity-ratio gate. After a candidate hill clears
min_chain_cosine, also check that its apex intensity vs the
predecessor’s matches the averagine ratio within ± this many log2
units. Catches column-bleed / contaminant hills that co-elute (so
pass cosine) but have wrong intensity for an isotope. Set to a
very large value to effectively disable. Typical: 1.5 (within
~2.83× of expected).
chain_predicted_intensity_gate: boolWhen true (legacy behaviour), isotope-chain extension stops as
soon as the averagine-predicted intensity of the next isotope falls
below the per-run noise floor (5th-pct hill intensity × 0.8), computed
from the seed intensity before the hill is searched for. This cheaply
trims decayed chain tails, but it also blocks legitimate low-abundance
monoisotopic seeds from ever pairing their M+1: a seed already near the
floor has a predicted M+1 below the floor, so the chain never forms and
the feature collapses to charge 0. When false (the default), this
predicted-intensity break is skipped and chain extension is terminated
purely by evidence:
a missing hill (find_neighbors empty), min_chain_cosine, the
max_isotope_log2_ratio intensity-ratio gate, min_isotope_step_ratio
(found hill must be ≥ this fraction of the predecessor), and the
averagine-template-length / max_isotopes caps. Setting this false
recovers dim 2+/3+ features that have both isotope hills present but
were never paired — recommended when feeding an MS1 search that needs
feature depth. Re-benchmark FDR/quant when flipping.
min_scan_overlap: usizeMinimum number of mutually-overlapping scans two hills must share before a chromatographic cosine is computed between them; below it the cosine is 0 and the isotope chain will not extend across that pair. Default 3 (the long-standing hard gate — keep for PXD003881).
On fast gradients hills are only 3–5 scans wide, so a dim isotope hill
frequently overlaps its monoisotope by just 1–2 scans and is rejected
outright regardless of how well the shapes agree — the dominant cause of
koth emitting a low-abundance monoisotope as an unpaired charge-0 feature
on such data (biosaur2 requires only ≥1 shared scan). Lowering this to 2
recovers those pairs; pair it with a shorter hills.min_scans (a 2-scan
hill can never reach a 3-scan overlap) and re-benchmark quant, since
short-overlap pairs are noisier.
exhaustive_min_isotope_score: f64Minimum isotope-pattern (Bhattacharyya) score a candidate — original or truncated — must reach before it may claim its hills; below-bar candidates are dropped so their hills stay free for a better-fitting feature. Default 0.0 = no gate.
isotope_evidence_ratio_sigma: f64Signal standard deviation of seed-relative log2 isotope-ratio errors. The broad noise null has fixed sigma 2; valid range is 0 < sigma < 2.
isotope_evidence_cosine_shape: f64Shape of the Beta(shape, 1) co-elution model against a uniform null. Must be finite and > 1; larger values favor tighter co-elution.
exhaustive_isotope_priority: boolLegacy compatibility field; no longer affects claim ordering. The exhaustive resolver always ranks by additive isotope log evidence. Accepted so existing configuration files continue to deserialize.
cosine_anchor: StringChromatographic-cosine anchor for isotope-chain extension: which hill each candidate isotope’s cosine gate is measured against.
"seed" (the default): anchor every isotope’s cosine to the
monoisotope seed hill (the convention biosaur2 / AlphaPept / Dinosaur all
use). The m/z step target and the intensity-ratio predecessor still step
from the immediate predecessor — only the cosine reference changes.
Rejects a far isotope that co-elutes with its neighbour but not with the
mono. Beat "adjacent" on the 20-run PXD003881 cohort (+0.31 pp recall);
see default_cosine_anchor.
"adjacent" (legacy): anchor to the immediate predecessor in the chain —
for M+1 that is the seed, for M+k≥2 the previously-claimed isotope hill.
koth’s former default; byte-identical to the pre-2026-07 paper output.
The per-extension cosine that feeds the composite mean_cosine is
computed against whichever reference this selects (so the composite is
consistent with the gate). The reported cosine_score field and the
exhaustive-resolver rescoring remain adjacent-style regardless.
sulfur_offsets: Vec<i8>Sulfur-count offsets to score each isotope chain against, relative to the ceiling of the averagine-expected sulfur count. The chain is scored against one averagine template per offset and the best Bhattacharyya kept — this corrects the systematic penalty on Cys/Met-rich peptides whose M+2 is elevated by ³⁴S (4.25 %, +2 Da).
Default [-1, 0, 1], i.e. {0, 1, 2} sulfurs up to 2665 Da, {1, 2, 3}
to 5330 Da, {2, 3, 4} to 7995 Da. Negative results saturate at 0 and
duplicates collapse, so [-2, -1, 0, 1] on a small peptide is {0, 1, 2}.
Widen it (e.g. [-2, -1, 0, 1]) to keep the no-sulfur template on large
peptides — ~32 % of 3 kDa tryptic peptides have no sulfur at all.
An empty list disables sulfur awareness: one plain averagine template at the half-up rounded count.
Scoring takes a max over templates, so a longer list can only raise scores — including for decoys and mis-assembled chains. Judge a change on discrimination (PSM recall / target–decoy separation), never on the isotope-score distribution alone.
isotope_model: IsotopeModelSpecWhich analyte class’s average composition the theoretical isotope pattern is built from.
"peptide" (the default) is Senko’s averagine and the only model the
published benchmark exercises. "rna" and "dna" are the means of the
four ribo- / deoxyribonucleotide chain residues. An explicit table
overrides both:
isotope_model = { residue_mass = 321.2916, c = 9.5, h = 11.75, n = 3.75, o = 7.0 }s defaults to 0 and a model without sulfur ignores sulfur_offsets
entirely — varying a structurally absent atom would hand every candidate,
decoys included, a free maximum over templates. An unknown class name is
a config parse error, never a silent fallback to peptide.
neutron_mass: f64Neutron (C13) mass in Da
min_isotope_score: f64Drop features whose isotope_score (Bhattacharyya vs averagine) is below this. 0.0 = keep all. Default 0.5.
min_cosine_score: f64Drop features whose cosine_score (mean chromatographic cosine of adjacent isotope hills) is below this. 0.0 = keep all.
min_combined_score: f64Drop features whose combined_score (= isotope × cosine) is below this. 0.0 = keep all. All three filters are AND-ed.
Implementations§
Source§impl FeaturesConfig
impl FeaturesConfig
Sourcepub fn validate(&self) -> Result<(), Error>
pub fn validate(&self) -> Result<(), Error>
Validate distribution parameters and strings that serde alone cannot check. Called after TOML deserialization so invalid values fail at load time rather than silently falling back at runtime.
Sourcepub fn cosine_anchor_mode(&self) -> CosineAnchor
pub fn cosine_anchor_mode(&self) -> CosineAnchor
Resolve the chromatographic-cosine anchor. Infallible at runtime because
validate() has already rejected bad values at config load; the
defensive fallback preserves legacy behaviour if reached.
Trait Implementations§
Source§impl Clone for FeaturesConfig
impl Clone for FeaturesConfig
Source§fn clone(&self) -> FeaturesConfig
fn clone(&self) -> FeaturesConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for FeaturesConfig
impl Debug for FeaturesConfig
Source§impl Default for FeaturesConfig
impl Default for FeaturesConfig
Source§fn default() -> FeaturesConfig
fn default() -> FeaturesConfig
Source§impl<'de> Deserialize<'de> for FeaturesConfigwhere
FeaturesConfig: Default,
impl<'de> Deserialize<'de> for FeaturesConfigwhere
FeaturesConfig: Default,
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<FeaturesConfig, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<FeaturesConfig, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
Source§impl Serialize for FeaturesConfig
impl Serialize for FeaturesConfig
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
Auto Trait Implementations§
impl Freeze for FeaturesConfig
impl RefUnwindSafe for FeaturesConfig
impl Send for FeaturesConfig
impl Sync for FeaturesConfig
impl Unpin for FeaturesConfig
impl UnsafeUnpin for FeaturesConfig
impl UnwindSafe for FeaturesConfig
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.