Skip to main content

timsrust_core/
quadrupole.rs

1use std::hash::{Hash, Hasher};
2
3use crate::Mz;
4
5/// The quadrupole settings used for fragmentation.
6#[derive(Clone, Debug, Default, PartialEq)]
7pub struct QuadrupoleSettings {
8    pub index: usize,
9    pub scan_starts: Vec<usize>,
10    pub scan_ends: Vec<usize>,
11    pub isolation_windows: Vec<IsolationWindow>,
12}
13
14impl Hash for QuadrupoleSettings {
15    fn hash<H: Hasher>(&self, state: &mut H) {
16        self.index.hash(state);
17        self.scan_starts.hash(state);
18        self.scan_ends.hash(state);
19        for window in &self.isolation_windows {
20            window.hash(state);
21        }
22    }
23}
24
25impl QuadrupoleSettings {
26    pub fn len(&self) -> usize {
27        self.isolation_windows.len()
28    }
29
30    pub fn is_empty(&self) -> bool {
31        self.len() == 0
32    }
33
34    pub fn get_isolation_window(
35        &self,
36        scan_index: usize,
37    ) -> Option<IsolationWindow> {
38        let index = self
39            .scan_starts
40            .iter()
41            .zip(self.scan_ends.iter())
42            .position(|(&start, &end)| scan_index >= start && scan_index < end)
43            // todo, should this be inclusive?
44            .unwrap_or(self.len());
45        if index >= self.len() {
46            return None;
47        }
48        let isolation_window = &self.isolation_windows[index];
49        Some(isolation_window.clone())
50    }
51}
52
53#[derive(Clone, Debug, PartialEq)]
54pub struct IsolationWindow {
55    lower: Mz,
56    upper: Mz,
57    ce: f64,
58}
59
60impl IsolationWindow {
61    pub fn new_from_bounds(lower: Mz, upper: Mz, ce: f64) -> Self {
62        Self { lower, upper, ce }
63    }
64
65    pub fn new_from_center(center: Mz, width: Mz, ce: f64) -> Self {
66        let half_width = Mz::from(f64::from(width) / 2.0);
67        Self {
68            lower: Mz::from(f64::from(center) - f64::from(half_width)),
69            upper: Mz::from(f64::from(center) + f64::from(half_width)),
70            ce,
71        }
72    }
73
74    pub fn lower(&self) -> Mz {
75        self.lower
76    }
77
78    pub fn upper(&self) -> Mz {
79        self.upper
80    }
81
82    pub fn center(&self) -> Mz {
83        Mz::from((f64::from(self.lower) + f64::from(self.upper)) / 2.0)
84    }
85
86    pub fn width(&self) -> Mz {
87        Mz::from(f64::from(self.upper) - f64::from(self.lower))
88    }
89
90    pub fn collision_energy(&self) -> f64 {
91        self.ce
92    }
93}
94
95impl Hash for IsolationWindow {
96    fn hash<H: Hasher>(&self, state: &mut H) {
97        f64::from(self.lower).to_bits().hash(state);
98        f64::from(self.upper).to_bits().hash(state);
99        self.ce.to_bits().hash(state);
100    }
101}
102
103impl Default for IsolationWindow {
104    fn default() -> Self {
105        Self {
106            lower: Mz::from(0.0),
107            upper: Mz::from(0.0),
108            ce: 0.0,
109        }
110    }
111}