1extern crate rusqlite;
2
3use rusqlite::{Connection, Result};
4use std::path::Path;
5
6#[derive(Debug, Clone)]
7pub struct DiaMsMisInfo {
8 pub frame_id: u32,
9 pub window_group: u32,
10}
11
12#[derive(Debug, Clone)]
13pub struct DiaMsMsWindow {
14 pub window_group: u32,
15 pub scan_num_begin: u32,
16 pub scan_num_end: u32,
17 pub isolation_mz: f64,
18 pub isolation_width: f64,
19 pub collision_energy: f64,
20}
21
22#[derive(Debug, Clone)]
23pub struct PasefMsMsMeta {
24 pub frame_id: i64,
25 pub scan_num_begin: i64,
26 pub scan_num_end: i64,
27 pub isolation_mz: f64,
28 pub isolation_width: f64,
29 pub collision_energy: f64,
30 pub precursor_id: i64,
31}
32
33#[derive(Debug, Clone)]
34pub struct DDAPrecursorMeta {
35 pub precursor_id: i64,
36 pub precursor_mz_highest_intensity: f64,
37 pub precursor_mz_average: f64,
38 pub precursor_mz_monoisotopic: Option<f64>,
39 pub precursor_charge: Option<i64>,
40 pub precursor_average_scan_number: f64,
41 pub precursor_total_intensity: f64,
42 pub precursor_frame_id: i64,
43}
44
45#[derive(Debug, Clone)]
46pub struct DDAPrecursor {
47 pub frame_id: i64,
48 pub precursor_id: i64,
49 pub mono_mz: Option<f64>,
50 pub highest_intensity_mz: f64,
51 pub average_mz: f64,
52 pub charge: Option<i64>,
53 pub inverse_ion_mobility: f64,
54 pub collision_energy: f64,
55 pub precuror_total_intensity: f64,
56 pub isolation_mz: f64,
57 pub isolation_width: f64,
58}
59
60#[derive(Debug, Clone)]
61pub struct DDAFragmentInfo {
62 pub frame_id: i64,
63 pub scan_begin: i64,
64 pub scan_end: i64,
65 pub isolation_mz: f64,
66 pub isolation_width: f64,
67 pub collision_energy: f64,
68 pub precursor_id: i64,
69}
70
71pub struct DIAFragmentFrameInfo {}
72
73pub struct DIAWindowGroupInfo {}
74
75#[derive(Debug, Clone)]
78pub struct MzCalibration {
79 pub id: i64,
80 pub model_type: i64,
81 pub digitizer_timebase: f64,
82 pub digitizer_delay: f64,
83 pub t1: f64,
84 pub t2: f64,
85 pub dc1: f64,
86 pub dc2: f64,
87 pub c0: f64,
88 pub c1: f64,
89 pub c2: f64,
90 pub c3: f64,
91 pub c4: f64,
92}
93
94#[derive(Debug, Clone)]
97pub struct TimsCalibration {
98 pub id: i64,
99 pub model_type: i64,
100 pub c0: f64,
101 pub c1: f64,
102 pub c2: f64,
103 pub c3: f64,
104 pub c4: f64,
105 pub c5: f64,
106 pub c6: f64,
107 pub c7: f64,
108 pub c8: f64,
109 pub c9: f64,
110}
111
112#[derive(Debug)]
113pub struct GlobalMetaData {
114 pub schema_type: String,
115 pub schema_version_major: i64,
116 pub schema_version_minor: i64,
117 pub acquisition_software_vendor: String,
118 pub instrument_vendor: String,
119 pub closed_property: i64,
120 pub tims_compression_type: i64,
121 pub max_num_peaks_per_scan: i64,
122 pub mz_acquisition_range_lower: f64,
123 pub mz_acquisition_range_upper: f64,
124 pub one_over_k0_range_lower: f64,
125 pub one_over_k0_range_upper: f64,
126 pub tof_max_index: u32,
127}
128
129#[derive(Debug)]
130pub struct FrameMeta {
131 pub id: i64,
132 pub time: f64,
133 pub polarity: String,
134 pub scan_mode: i64,
135 pub ms_ms_type: i64,
136 pub tims_id: i64,
137 pub max_intensity: f64,
138 pub sum_intensity: f64,
139 pub num_scans: i64,
140 pub num_peaks: i64,
141 pub mz_calibration: i64,
142 pub t_1: f64,
143 pub t_2: f64,
144 pub tims_calibration: i64,
145 pub property_group: i64,
146 pub accumulation_time: f64,
147 pub ramp_time: f64,
148}
149
150struct GlobalMetaInternal {
151 key: String,
152 value: String,
153}
154
155pub fn read_dda_precursor_meta(
156 bruker_d_folder_name: &str,
157) -> Result<Vec<DDAPrecursorMeta>, Box<dyn std::error::Error>> {
158 let db_path = Path::new(bruker_d_folder_name).join("analysis.tdf");
160 let conn = Connection::open(db_path)?;
161
162 let rows: Vec<&str> = vec![
164 "Id",
165 "LargestPeakMz",
166 "AverageMz",
167 "MonoisotopicMz",
168 "Charge",
169 "ScanNumber",
170 "Intensity",
171 "Parent",
172 ];
173 let query = format!("SELECT {} FROM Precursors", rows.join(", "));
174
175 let frames_rows: Result<Vec<DDAPrecursorMeta>, _> = conn
177 .prepare(&query)?
178 .query_map([], |row| {
179 Ok(DDAPrecursorMeta {
180 precursor_id: row.get(0)?,
181 precursor_mz_highest_intensity: row.get(1)?,
182 precursor_mz_average: row.get(2)?,
183 precursor_mz_monoisotopic: row.get(3)?, precursor_charge: row.get(4)?, precursor_average_scan_number: row.get(5)?,
186 precursor_total_intensity: row.get(6)?,
187 precursor_frame_id: row.get(7)?,
188 })
189 })?
190 .collect();
191
192 Ok(frames_rows?)
194}
195
196pub fn read_pasef_frame_ms_ms_info(
197 bruker_d_folder_name: &str,
198) -> Result<Vec<PasefMsMsMeta>, Box<dyn std::error::Error>> {
199 let db_path = Path::new(bruker_d_folder_name).join("analysis.tdf");
201 let conn = Connection::open(db_path)?;
202
203 let rows: Vec<&str> = vec![
205 "Frame",
206 "ScanNumBegin",
207 "ScanNumEnd",
208 "IsolationMz",
209 "IsolationWidth",
210 "CollisionEnergy",
211 "Precursor",
212 ];
213 let query = format!("SELECT {} FROM PasefFrameMsMsInfo", rows.join(", "));
214
215 let frames_rows: Result<Vec<PasefMsMsMeta>, _> = conn
217 .prepare(&query)?
218 .query_map([], |row| {
219 Ok(PasefMsMsMeta {
220 frame_id: row.get(0)?,
221 scan_num_begin: row.get(1)?,
222 scan_num_end: row.get(2)?,
223 isolation_mz: row.get(3)?,
224 isolation_width: row.get(4)?,
225 collision_energy: row.get(5)?,
226 precursor_id: row.get(6)?,
227 })
228 })?
229 .collect();
230
231 Ok(frames_rows?)
233}
234
235pub fn read_global_meta_sql(
237 bruker_d_folder_name: &str,
238) -> Result<GlobalMetaData, Box<dyn std::error::Error>> {
239 let db_path = Path::new(bruker_d_folder_name).join("analysis.tdf");
241 let conn = Connection::open(db_path)?;
242
243 let frames_rows: Result<Vec<GlobalMetaInternal>, _> = conn
245 .prepare("SELECT * FROM GlobalMetadata")?
246 .query_map([], |row| {
247 Ok(GlobalMetaInternal {
248 key: row.get(0)?,
249 value: row.get(1)?,
250 })
251 })?
252 .collect();
253
254 let mut global_meta = GlobalMetaData {
255 schema_type: String::new(),
256 schema_version_major: -1,
257 schema_version_minor: -1,
258 acquisition_software_vendor: String::new(),
259 instrument_vendor: String::new(),
260 closed_property: -1,
261 tims_compression_type: -1,
262 max_num_peaks_per_scan: -1,
263 mz_acquisition_range_lower: -1.0,
264 mz_acquisition_range_upper: -1.0,
265 one_over_k0_range_lower: -1.0,
266 one_over_k0_range_upper: -1.0,
267 tof_max_index: 0,
268 };
269
270 for row in frames_rows? {
272 match row.key.as_str() {
273 "SchemaType" => global_meta.schema_type = row.value,
274 "SchemaVersionMajor" => {
275 global_meta.schema_version_major = row.value.parse::<i64>().unwrap()
276 }
277 "SchemaVersionMinor" => {
278 global_meta.schema_version_minor = row.value.parse::<i64>().unwrap()
279 }
280 "AcquisitionSoftwareVendor" => global_meta.acquisition_software_vendor = row.value,
281 "InstrumentVendor" => global_meta.instrument_vendor = row.value,
282 "ClosedProperly" => global_meta.closed_property = row.value.parse::<i64>().unwrap(),
283 "TimsCompressionType" => {
284 global_meta.tims_compression_type = row.value.parse::<i64>().unwrap()
285 }
286 "MaxNumPeaksPerScan" => {
287 global_meta.max_num_peaks_per_scan = row.value.parse::<i64>().unwrap()
288 }
289 "MzAcqRangeLower" => {
290 global_meta.mz_acquisition_range_lower = row.value.parse::<f64>().unwrap()
291 }
292 "MzAcqRangeUpper" => {
293 global_meta.mz_acquisition_range_upper = row.value.parse::<f64>().unwrap()
294 }
295 "OneOverK0AcqRangeLower" => {
296 global_meta.one_over_k0_range_lower = row.value.parse::<f64>().unwrap()
297 }
298 "OneOverK0AcqRangeUpper" => {
299 global_meta.one_over_k0_range_upper = row.value.parse::<f64>().unwrap()
300 }
301 "DigitizerNumSamples" => {
302 global_meta.tof_max_index = (row.value.parse::<i64>().unwrap() + 1) as u32
303 }
304 _ => (),
305 }
306 }
307 Ok(global_meta)
309}
310
311pub fn read_meta_data_sql(
313 bruker_d_folder_name: &str,
314) -> Result<Vec<FrameMeta>, Box<dyn std::error::Error>> {
315 let db_path = Path::new(bruker_d_folder_name).join("analysis.tdf");
317 let conn = Connection::open(db_path)?;
318
319 let rows: Vec<&str> = vec![
321 "Id",
322 "Time",
323 "ScanMode",
324 "Polarity",
325 "MsMsType",
326 "TimsId",
327 "MaxIntensity",
328 "SummedIntensities",
329 "NumScans",
330 "NumPeaks",
331 "MzCalibration",
332 "T1",
333 "T2",
334 "TimsCalibration",
335 "PropertyGroup",
336 "AccumulationTime",
337 "RampTime",
338 ];
339 let query = format!("SELECT {} FROM Frames", rows.join(", "));
340
341 let frames_rows: Result<Vec<FrameMeta>, _> = conn
343 .prepare(&query)?
344 .query_map([], |row| {
345 Ok(FrameMeta {
346 id: row.get(0)?,
347 time: row.get(1)?,
348 scan_mode: row.get(2)?,
349 polarity: row.get(3)?,
350 ms_ms_type: row.get(4)?,
351 tims_id: row.get(5)?,
352 max_intensity: row.get(6)?,
353 sum_intensity: row.get(7)?,
354 num_scans: row.get(8)?,
355 num_peaks: row.get(9)?,
356 mz_calibration: row.get(10)?,
357 t_1: row.get(11)?,
358 t_2: row.get(12)?,
359 tims_calibration: row.get(13)?,
360 property_group: row.get(14)?,
361 accumulation_time: row.get(15)?,
362 ramp_time: row.get(16)?,
363 })
364 })?
365 .collect();
366
367 Ok(frames_rows?)
369}
370
371pub fn read_dia_ms_ms_info(
372 bruker_d_folder_name: &str,
373) -> Result<Vec<DiaMsMisInfo>, Box<dyn std::error::Error>> {
374 let db_path = Path::new(bruker_d_folder_name).join("analysis.tdf");
376 let conn = Connection::open(db_path)?;
377
378 let rows: Vec<&str> = vec!["Frame", "WindowGroup"];
380 let query = format!("SELECT {} FROM DiaFrameMsMsInfo", rows.join(", "));
381
382 let frames_rows: Result<Vec<DiaMsMisInfo>, _> = conn
384 .prepare(&query)?
385 .query_map([], |row| {
386 Ok(DiaMsMisInfo {
387 frame_id: row.get(0)?,
388 window_group: row.get(1)?,
389 })
390 })?
391 .collect();
392
393 Ok(frames_rows?)
395}
396
397pub fn read_dia_ms_ms_windows(
398 bruker_d_folder_name: &str,
399) -> Result<Vec<DiaMsMsWindow>, Box<dyn std::error::Error>> {
400 let db_path = Path::new(bruker_d_folder_name).join("analysis.tdf");
402 let conn = Connection::open(db_path)?;
403
404 let rows: Vec<&str> = vec![
406 "WindowGroup",
407 "ScanNumBegin",
408 "ScanNumEnd",
409 "IsolationMz",
410 "IsolationWidth",
411 "CollisionEnergy",
412 ];
413 let query = format!("SELECT {} FROM DiaFrameMsMsWindows", rows.join(", "));
414
415 let frames_rows: Result<Vec<DiaMsMsWindow>, _> = conn
417 .prepare(&query)?
418 .query_map([], |row| {
419 Ok(DiaMsMsWindow {
420 window_group: row.get(0)?,
421 scan_num_begin: row.get(1)?,
422 scan_num_end: row.get(2)?,
423 isolation_mz: row.get(3)?,
424 isolation_width: row.get(4)?,
425 collision_energy: row.get(5)?,
426 })
427 })?
428 .collect();
429
430 Ok(frames_rows?)
432}
433
434pub fn read_mz_calibration(
448 bruker_d_folder_name: &str,
449) -> Result<Vec<MzCalibration>, Box<dyn std::error::Error>> {
450 let db_path = Path::new(bruker_d_folder_name).join("analysis.tdf");
451 let conn = Connection::open(db_path)?;
452
453 let query = "SELECT Id, ModelType, DigitizerTimebase, DigitizerDelay, T1, T2, dC1, dC2, C0, C1, C2, C3, C4 FROM MzCalibration";
455
456 let calibrations: Result<Vec<MzCalibration>, _> = conn
457 .prepare(query)?
458 .query_map([], |row| {
459 Ok(MzCalibration {
460 id: row.get(0)?,
461 model_type: row.get(1)?,
462 digitizer_timebase: row.get(2)?,
463 digitizer_delay: row.get(3)?,
464 t1: row.get(4)?,
465 t2: row.get(5)?,
466 dc1: row.get(6)?,
467 dc2: row.get(7)?,
468 c0: row.get(8)?,
469 c1: row.get(9)?,
470 c2: row.get(10)?,
471 c3: row.get(11)?,
472 c4: row.get(12)?,
473 })
474 })?
475 .collect();
476
477 Ok(calibrations?)
478}
479
480pub fn read_tims_calibration(
483 bruker_d_folder_name: &str,
484) -> Result<Vec<TimsCalibration>, Box<dyn std::error::Error>> {
485 let db_path = Path::new(bruker_d_folder_name).join("analysis.tdf");
486 let conn = Connection::open(db_path)?;
487
488 let query =
489 "SELECT Id, ModelType, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9 FROM TimsCalibration";
490
491 let calibrations: Result<Vec<TimsCalibration>, _> = conn
492 .prepare(query)?
493 .query_map([], |row| {
494 Ok(TimsCalibration {
495 id: row.get(0)?,
496 model_type: row.get(1)?,
497 c0: row.get(2)?,
498 c1: row.get(3)?,
499 c2: row.get(4)?,
500 c3: row.get(5)?,
501 c4: row.get(6)?,
502 c5: row.get(7)?,
503 c6: row.get(8)?,
504 c7: row.get(9)?,
505 c8: row.get(10)?,
506 c9: row.get(11)?,
507 })
508 })?
509 .collect();
510
511 Ok(calibrations?)
512}