use crate::{
annotation::model::MatchingParameters, chemistry::MassMode, fragment::Fragment,
sequence::CompoundPeptidoformIon, system::MassOverCharge,
};
use super::AnnotatedSpectrum;
pub trait AnnotatableSpectrum {
type Tolerance: From<crate::quantities::Tolerance<MassOverCharge>> + Copy;
fn empty_annotated(&self, peptide: CompoundPeptidoformIon) -> AnnotatedSpectrum;
fn search(&self, query: MassOverCharge, tolerance: Self::Tolerance) -> Option<usize>;
fn annotate(
&self,
peptide: CompoundPeptidoformIon,
theoretical_fragments: &[Fragment],
parameters: &MatchingParameters,
mode: MassMode,
) -> AnnotatedSpectrum {
let tolerance = parameters.tolerance.into();
let mut annotated = Self::empty_annotated(self, peptide);
for fragment in theoretical_fragments {
if let Some(mz) = fragment.mz(mode) {
if !parameters.mz_range.contains(&mz) {
continue;
}
if let Some(index) = Self::search(self, mz, tolerance) {
match annotated.spectrum[index].annotation.binary_search(fragment) {
Ok(ai) | Err(ai) => annotated.spectrum[index]
.annotation
.insert(ai, fragment.clone()),
}
}
}
}
annotated
}
}