rustdf/sim/
containers.rs

1use mscore::data::peptide::PeptideSequence;
2use mscore::data::spectrum::{MsType, MzSpectrum};
3use rand::distributions::{Distribution, Uniform};
4use serde::{Deserialize, Serialize};
5
6#[derive(Serialize, Deserialize, Debug, Clone)]
7pub struct SignalDistribution {
8    pub mean: f32,
9    pub variance: f32,
10    pub error: f32,
11    pub occurrence: Vec<u32>,
12    pub abundance: Vec<f32>,
13}
14
15impl SignalDistribution {
16    pub fn new(
17        mean: f32,
18        variance: f32,
19        error: f32,
20        occurrence: Vec<u32>,
21        abundance: Vec<f32>,
22    ) -> Self {
23        SignalDistribution {
24            mean,
25            variance,
26            error,
27            occurrence,
28            abundance,
29        }
30    }
31
32    pub fn add_noise(&self, noise_level: f32) -> Vec<f32> {
33        let mut rng = rand::thread_rng();
34        let noise_dist = Uniform::new(0.0, noise_level);
35
36        let noise: Vec<f32> = self
37            .abundance
38            .iter()
39            .map(|_| noise_dist.sample(&mut rng))
40            .collect();
41        let noise_relative: Vec<f32> = self
42            .abundance
43            .iter()
44            .zip(noise.iter())
45            .map(|(&abu, &noise)| abu * noise)
46            .collect();
47        let noised_signal: Vec<f32> = self
48            .abundance
49            .iter()
50            .zip(noise_relative.iter())
51            .map(|(&abu, &noise_rel)| abu + noise_rel)
52            .collect();
53
54        let sum_noised_signal: f32 = noised_signal.iter().sum();
55        let sum_rt_abu: f32 = self.abundance.iter().sum();
56
57        noised_signal
58            .iter()
59            .map(|&x| (x / sum_noised_signal) * sum_rt_abu)
60            .collect()
61    }
62}
63
64#[derive(Debug, Clone)]
65pub struct PeptidesSim {
66    pub protein_id: u32,
67    pub peptide_id: u32,
68    pub sequence: PeptideSequence,
69    pub proteins: String,
70    pub decoy: bool,
71    pub missed_cleavages: i8,
72    pub n_term: Option<bool>,
73    pub c_term: Option<bool>,
74    pub mono_isotopic_mass: f32,
75    pub retention_time: f32,
76    pub events: f32,
77    pub frame_start: u32,
78    pub frame_end: u32,
79    pub frame_distribution: SignalDistribution,
80}
81
82impl PeptidesSim {
83    pub fn new(
84        protein_id: u32,
85        peptide_id: u32,
86        sequence: String,
87        proteins: String,
88        decoy: bool,
89        missed_cleavages: i8,
90        n_term: Option<bool>,
91        c_term: Option<bool>,
92        mono_isotopic_mass: f32,
93        retention_time: f32,
94        events: f32,
95        frame_start: u32,
96        frame_end: u32,
97        frame_occurrence: Vec<u32>,
98        frame_abundance: Vec<f32>,
99    ) -> Self {
100        PeptidesSim {
101            protein_id,
102            peptide_id,
103            sequence: PeptideSequence::new(sequence, Some(peptide_id as i32)),
104            proteins,
105            decoy,
106            missed_cleavages,
107            n_term,
108            c_term,
109            mono_isotopic_mass,
110            retention_time,
111            events,
112            frame_start,
113            frame_end,
114            frame_distribution: SignalDistribution::new(
115                0.0,
116                0.0,
117                0.0,
118                frame_occurrence,
119                frame_abundance,
120            ),
121        }
122    }
123}
124
125#[derive(Debug, Clone)]
126pub struct WindowGroupSettingsSim {
127    pub window_group: u32,
128    pub scan_start: u32,
129    pub scan_end: u32,
130    pub isolation_mz: f32,
131    pub isolation_width: f32,
132    pub collision_energy: f32,
133}
134
135impl WindowGroupSettingsSim {
136    pub fn new(
137        window_group: u32,
138        scan_start: u32,
139        scan_end: u32,
140        isolation_mz: f32,
141        isolation_width: f32,
142        collision_energy: f32,
143    ) -> Self {
144        WindowGroupSettingsSim {
145            window_group,
146            scan_start,
147            scan_end,
148            isolation_mz,
149            isolation_width,
150            collision_energy,
151        }
152    }
153}
154
155#[derive(Debug, Clone)]
156pub struct FrameToWindowGroupSim {
157    pub frame_id: u32,
158    pub window_group: u32,
159}
160
161impl FrameToWindowGroupSim {
162    pub fn new(frame_id: u32, window_group: u32) -> Self {
163        FrameToWindowGroupSim {
164            frame_id,
165            window_group,
166        }
167    }
168}
169
170#[derive(Debug, Clone)]
171pub struct IonSim {
172    pub ion_id: u32,
173    pub peptide_id: u32,
174    pub sequence: String,
175    pub charge: i8,
176    pub relative_abundance: f32,
177    pub mobility: f32,
178    pub simulated_spectrum: MzSpectrum,
179    pub scan_distribution: SignalDistribution,
180}
181
182impl IonSim {
183    pub fn new(
184        ion_id: u32,
185        peptide_id: u32,
186        sequence: String,
187        charge: i8,
188        relative_abundance: f32,
189        mobility: f32,
190        simulated_spectrum: MzSpectrum,
191        scan_occurrence: Vec<u32>,
192        scan_abundance: Vec<f32>,
193    ) -> Self {
194        IonSim {
195            ion_id,
196            peptide_id,
197            sequence,
198            charge,
199            relative_abundance,
200            mobility,
201            simulated_spectrum,
202            scan_distribution: SignalDistribution::new(
203                0.0,
204                0.0,
205                0.0,
206                scan_occurrence,
207                scan_abundance,
208            ),
209        }
210    }
211}
212
213#[derive(Debug, Clone)]
214pub struct ScansSim {
215    pub scan: u32,
216    pub mobility: f32,
217}
218
219impl ScansSim {
220    pub fn new(scan: u32, mobility: f32) -> Self {
221        ScansSim { scan, mobility }
222    }
223}
224
225#[derive(Debug, Clone)]
226pub struct FramesSim {
227    pub frame_id: u32,
228    pub time: f32,
229    pub ms_type: i64,
230}
231
232impl FramesSim {
233    pub fn new(frame_id: u32, time: f32, ms_type: i64) -> Self {
234        FramesSim {
235            frame_id,
236            time,
237            ms_type,
238        }
239    }
240    pub fn parse_ms_type(&self) -> MsType {
241        match self.ms_type {
242            0 => MsType::Precursor,
243            8 => MsType::FragmentDda,
244            9 => MsType::FragmentDia,
245            _ => MsType::Unknown,
246        }
247    }
248}
249
250pub struct FragmentIonSim {
251    pub peptide_id: u32,
252    pub ion_id: u32,
253    pub collision_energy: f64,
254    pub charge: i8,
255    pub indices: Vec<u32>,
256    pub values: Vec<f64>,
257}
258
259impl FragmentIonSim {
260    pub fn new(
261        peptide_id: u32,
262        ion_id: u32,
263        collision_energy: f64,
264        charge: i8,
265        indices: Vec<u32>,
266        values: Vec<f64>,
267    ) -> Self {
268        FragmentIonSim {
269            peptide_id,
270            ion_id,
271            charge,
272            collision_energy,
273            indices,
274            values,
275        }
276    }
277
278    pub fn to_dense(&self, length: usize) -> Vec<f64> {
279        let mut dense = vec![0.0; length];
280        for (i, &idx) in self.indices.iter().enumerate() {
281            dense[idx as usize] = self.values[i];
282        }
283        dense
284    }
285}