rustdf/data/
dia.rs

1use crate::data::acquisition::AcquisitionMode;
2use crate::data::handle::{IndexConverter, TimsData, TimsDataLoader};
3use crate::data::meta::{
4    read_dia_ms_ms_info, read_dia_ms_ms_windows, read_global_meta_sql, read_meta_data_sql,
5    DiaMsMisInfo, DiaMsMsWindow, FrameMeta, GlobalMetaData,
6};
7use mscore::timstof::frame::{RawTimsFrame, TimsFrame};
8use mscore::timstof::slice::TimsSlice;
9use rand::prelude::IteratorRandom;
10
11pub struct TimsDatasetDIA {
12    pub loader: TimsDataLoader,
13    pub global_meta_data: GlobalMetaData,
14    pub meta_data: Vec<FrameMeta>,
15    pub dia_ms_mis_info: Vec<DiaMsMisInfo>,
16    pub dia_ms_ms_windows: Vec<DiaMsMsWindow>,
17}
18
19impl TimsDatasetDIA {
20    pub fn new(
21        bruker_lib_path: &str,
22        data_path: &str,
23        in_memory: bool,
24        use_bruker_sdk: bool,
25    ) -> Self {
26        // TODO: error handling
27        let global_meta_data = read_global_meta_sql(data_path).unwrap();
28        let meta_data = read_meta_data_sql(data_path).unwrap();
29        let dia_ms_mis_info = read_dia_ms_ms_info(data_path).unwrap();
30        let dia_ms_ms_windows = read_dia_ms_ms_windows(data_path).unwrap();
31
32        let scan_max_index = meta_data.iter().map(|x| x.num_scans).max().unwrap() as u32;
33        let im_lower = global_meta_data.one_over_k0_range_lower;
34        let im_upper = global_meta_data.one_over_k0_range_upper;
35
36        let tof_max_index = global_meta_data.tof_max_index;
37        let mz_lower = global_meta_data.mz_acquisition_range_lower;
38        let mz_upper = global_meta_data.mz_acquisition_range_upper;
39
40        let loader = match in_memory {
41            true => TimsDataLoader::new_in_memory(
42                bruker_lib_path,
43                data_path,
44                use_bruker_sdk,
45                scan_max_index,
46                im_lower,
47                im_upper,
48                tof_max_index,
49                mz_lower,
50                mz_upper,
51            ),
52            false => TimsDataLoader::new_lazy(
53                bruker_lib_path,
54                data_path,
55                use_bruker_sdk,
56                scan_max_index,
57                im_lower,
58                im_upper,
59                tof_max_index,
60                mz_lower,
61                mz_upper,
62            ),
63        };
64
65        TimsDatasetDIA {
66            loader,
67            global_meta_data,
68            meta_data,
69            dia_ms_mis_info,
70            dia_ms_ms_windows,
71        }
72    }
73
74    pub fn sample_precursor_signal(
75        &self,
76        num_frames: usize,
77        max_intensity: f64,
78        take_probability: f64,
79    ) -> TimsFrame {
80        // get all precursor frames
81        let precursor_frames = self.meta_data.iter().filter(|x| x.ms_ms_type == 0);
82
83        // randomly sample num_frames
84        let mut rng = rand::thread_rng();
85        let mut sampled_frames: Vec<TimsFrame> = Vec::new();
86
87        // go through each frame and sample the data
88        for frame in precursor_frames.choose_multiple(&mut rng, num_frames) {
89            let frame_id = frame.id;
90            let frame_data = self
91                .loader
92                .get_frame(frame_id as u32)
93                .filter_ranged(0.0, 2000.0, 0, 1000, 0.0, 5.0, 1.0, max_intensity)
94                .generate_random_sample(take_probability);
95            sampled_frames.push(frame_data);
96        }
97
98        // get the first frame
99        let mut sampled_frame = sampled_frames.remove(0);
100
101        // sum all the other frames to the first frame
102        for frame in sampled_frames {
103            sampled_frame = sampled_frame + frame;
104        }
105
106        sampled_frame
107    }
108
109    pub fn sample_fragment_signal(
110        &self,
111        num_frames: usize,
112        window_group: u32,
113        max_intensity: f64,
114        take_probability: f64,
115    ) -> TimsFrame {
116        // get all fragment frames, filter by window_group
117        let fragment_frames: Vec<u32> = self
118            .dia_ms_mis_info
119            .iter()
120            .filter(|x| x.window_group == window_group)
121            .map(|x| x.frame_id)
122            .collect();
123
124        // randomly sample num_frames
125        let mut rng = rand::thread_rng();
126        let mut sampled_frames: Vec<TimsFrame> = Vec::new();
127
128        // go through each frame and sample the data
129        for frame_id in fragment_frames
130            .into_iter()
131            .choose_multiple(&mut rng, num_frames)
132        {
133            let frame_data = self
134                .loader
135                .get_frame(frame_id)
136                .filter_ranged(0.0, 2000.0, 0, 1000, 0.0, 5.0, 1.0, max_intensity)
137                .generate_random_sample(take_probability);
138            sampled_frames.push(frame_data);
139        }
140
141        // get the first frame
142        let mut sampled_frame = sampled_frames.remove(0);
143
144        // sum all the other frames to the first frame
145        for frame in sampled_frames {
146            sampled_frame = sampled_frame + frame;
147        }
148
149        sampled_frame
150    }
151}
152
153impl TimsData for TimsDatasetDIA {
154    fn get_frame(&self, frame_id: u32) -> TimsFrame {
155        self.loader.get_frame(frame_id)
156    }
157
158    fn get_raw_frame(&self, frame_id: u32) -> RawTimsFrame {
159        self.loader.get_raw_frame(frame_id)
160    }
161
162    fn get_slice(&self, frame_ids: Vec<u32>, num_threads: usize) -> TimsSlice {
163        self.loader.get_slice(frame_ids, num_threads)
164    }
165    fn get_acquisition_mode(&self) -> AcquisitionMode {
166        self.loader.get_acquisition_mode().clone()
167    }
168
169    fn get_frame_count(&self) -> i32 {
170        self.loader.get_frame_count()
171    }
172
173    fn get_data_path(&self) -> &str {
174        &self.loader.get_data_path()
175    }
176}
177
178impl IndexConverter for TimsDatasetDIA {
179    fn tof_to_mz(&self, frame_id: u32, tof_values: &Vec<u32>) -> Vec<f64> {
180        self.loader
181            .get_index_converter()
182            .tof_to_mz(frame_id, tof_values)
183    }
184
185    fn mz_to_tof(&self, frame_id: u32, mz_values: &Vec<f64>) -> Vec<u32> {
186        self.loader
187            .get_index_converter()
188            .mz_to_tof(frame_id, mz_values)
189    }
190
191    fn scan_to_inverse_mobility(&self, frame_id: u32, scan_values: &Vec<u32>) -> Vec<f64> {
192        self.loader
193            .get_index_converter()
194            .scan_to_inverse_mobility(frame_id, scan_values)
195    }
196
197    fn inverse_mobility_to_scan(
198        &self,
199        frame_id: u32,
200        inverse_mobility_values: &Vec<f64>,
201    ) -> Vec<u32> {
202        self.loader
203            .get_index_converter()
204            .inverse_mobility_to_scan(frame_id, inverse_mobility_values)
205    }
206}