1use timsrust_utils::vec::get_top_n;
2
3use super::Precursor;
4use crate::{IsolationWindow, Mz, TofIndex, coordinates::Converter};
5
6#[derive(Debug, PartialEq, Default, Clone)]
8pub struct Spectrum<C = TofIndex> {
9 intensities: Vec<f64>,
10 precursor: Option<Precursor>,
11 index: usize,
12 coordinates: Vec<C>,
13 isolation_window: IsolationWindow,
14}
15
16impl<C> Spectrum<C> {
17 pub fn new(
18 intensities: Vec<f64>,
19 index: usize,
20 precursor: Option<Precursor>,
21 coordinates: Vec<C>,
22 isolation_window: IsolationWindow,
23 ) -> Self {
24 assert!(
25 intensities.len() == coordinates.len(),
26 "Intensities and coordinates must have the same length"
27 );
28 Spectrum {
29 intensities,
30 precursor,
31 index,
32 coordinates,
33 isolation_window,
34 }
35 }
36
37 pub fn intensities(&self) -> &Vec<f64> {
38 &self.intensities
39 }
40
41 pub fn precursor(&self) -> &Option<Precursor> {
42 &self.precursor
43 }
44
45 pub fn index(&self) -> usize {
46 self.index
47 }
48
49 pub fn isolation_window(&self) -> &IsolationWindow {
50 &self.isolation_window
51 }
52
53 pub fn len(&self) -> usize {
54 self.intensities.len()
55 }
56
57 pub fn is_empty(&self) -> bool {
58 self.len() == 0
59 }
60
61 pub fn coordinates(&self) -> &Vec<C> {
62 &self.coordinates
63 }
64
65 pub fn convert_to<X>(self, converter: impl Converter<C, X>) -> Spectrum<X>
66 where
67 C: Copy,
68 {
69 Spectrum {
70 intensities: self.intensities,
71 precursor: self.precursor,
72 index: self.index,
73 coordinates: converter.batch_convert(&self.coordinates),
74 isolation_window: self.isolation_window,
75 }
76 }
77
78 pub fn get_top_n(&self, n: usize) -> Self
79 where
80 C: Clone,
81 {
82 let top_indices = get_top_n(&self.intensities, n);
83 Self {
84 intensities: top_indices
85 .iter()
86 .map(|&index| self.intensities[index])
87 .collect(),
88 precursor: self.precursor.clone(),
89 index: self.index,
90 coordinates: top_indices
91 .iter()
92 .map(|&index| self.coordinates[index].clone())
93 .collect(),
94 isolation_window: self.isolation_window.clone(),
95 }
96 }
97}
98
99impl Spectrum<TofIndex> {
100 pub fn tof_indices(&self) -> &Vec<TofIndex> {
101 &self.coordinates
102 }
103
104 pub fn mz_values(
105 &self,
106 converter: impl Converter<TofIndex, Mz>,
107 ) -> Vec<Mz> {
108 converter.batch_convert(&self.coordinates)
109 }
110
111 pub fn to_mz_spectrum(
112 self,
113 converter: impl Converter<TofIndex, Mz>,
114 ) -> Spectrum<Mz> {
115 self.convert_to(converter)
116 }
117}
118
119impl Spectrum<Mz> {
120 pub fn mz_values(&self) -> &Vec<Mz> {
121 &self.coordinates
122 }
123
124 pub fn to_tof_spectrum(
125 self,
126 converter: impl Converter<Mz, TofIndex>,
127 ) -> Spectrum<TofIndex> {
128 self.convert_to(converter)
129 }
130}