rustdf/data/
raw.rs

1use libloading::{Library, Symbol};
2use std::os::raw::{c_char, c_double};
3
4//
5// A struct that holds a handle to the raw data
6//
7// # Example
8//
9// ```
10// let bruker_lib_path = "path/to/libtimsdata.so";
11// let data_path = "path/to/data.d";
12// let tims_data = BrukerTimsDataLibrary::new(bruker_lib_path, data_path);
13// ```
14pub struct BrukerTimsDataLibrary {
15    pub lib: Library,
16    pub handle: u64,
17}
18
19impl BrukerTimsDataLibrary {
20    //
21    // Create a new BrukerTimsDataLibrary struct
22    //
23    // # Arguments
24    //
25    // * `bruker_lib_path` - A string slice that holds the path to the bruker library
26    // * `data_path` - A string slice that holds the path to the data
27    //
28    // # Example
29    //
30    // ```
31    // let bruker_lib_path = "path/to/libtimsdata.so";
32    // let data_path = "path/to/data.d";
33    // let tims_data = BrukerTimsDataLibrary::new(bruker_lib_path, data_path);
34    // ```
35    pub fn new(
36        bruker_lib_path: &str,
37        data_path: &str,
38    ) -> Result<BrukerTimsDataLibrary, Box<dyn std::error::Error>> {
39        // Load the library
40        let lib = unsafe { Library::new(bruker_lib_path)? };
41
42        // create a handle to the raw data
43        let handle = unsafe {
44            let func: Symbol<unsafe extern "C" fn(*const c_char, u32) -> u64> =
45                lib.get(b"tims_open")?;
46            let path = std::ffi::CString::new(data_path)?;
47            let handle = func(path.as_ptr(), 0);
48            handle
49        };
50
51        // return the BrukerTimsDataLibrary struct
52        Ok(BrukerTimsDataLibrary { lib, handle })
53    }
54
55    //
56    // Close the handle to the raw data
57    //
58    // # Example
59    //
60    // ```
61    // let close = tims_data.tims_close();
62    // match close {
63    //     Ok(_) => println!("tims_data closed"),
64    //     Err(e) => println!("error: {}", e),
65    // };
66    // ```
67    pub fn tims_close(&self) -> Result<(), Box<dyn std::error::Error>> {
68        unsafe {
69            let func: Symbol<unsafe extern "C" fn(u64) -> ()> = self.lib.get(b"tims_close")?;
70            func(self.handle);
71        }
72        Ok(())
73    }
74
75    //
76    // Convert the given indices to mz values.
77    //
78    // # Example
79    //
80    // ```
81    // let indices = vec![...];
82    // let mz_values_result = tims_data.tims_index_to_mz(estimation, &mut indices, tof_max_index);
83    // match mz_values_result {
84    //     Ok(mz_values) => println!("{:?}", mz_values),
85    //     Err(e) => println!("error: {}", e),
86    // };
87    // ```
88    pub fn tims_index_to_mz(
89        &self,
90        frame_id: u32,
91        dbl_tofs: &[c_double],
92        mzs: &mut [c_double],
93    ) -> Result<(), Box<dyn std::error::Error>> {
94        unsafe {
95            let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
96                self.lib.get(b"tims_index_to_mz")?;
97            func(
98                self.handle,
99                frame_id,
100                dbl_tofs.as_ptr(),
101                mzs.as_mut_ptr(),
102                dbl_tofs.len() as u32,
103            );
104        }
105        Ok(())
106    }
107
108    //
109    // Convert the given mz values to indices.
110    //
111    // # Example
112    //
113    // ```
114    // let mzs = vec![...];
115    // let indices_result = tims_data.tims_mz_to_index(estimation, &mut mzs);
116    // match indices_result {
117    //     Ok(indices) => println!("{:?}", indices),
118    //     Err(e) => println!("error: {}", e),
119    // };
120    // ```
121    pub fn tims_mz_to_index(
122        &self,
123        frame_id: u32,
124        mzs: &[c_double],
125        indices: &mut [c_double],
126    ) -> Result<(), Box<dyn std::error::Error>> {
127        unsafe {
128            let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
129                self.lib.get(b"tims_mz_to_index")?;
130            func(
131                self.handle,
132                frame_id,
133                mzs.as_ptr(),
134                indices.as_mut_ptr(),
135                mzs.len() as u32,
136            );
137        }
138        Ok(())
139    }
140
141    //
142    // Convert the given indices to inverse mobility values.
143    //
144    // # Example
145    //
146    // ```
147    // let indices = vec![...];
148    // let scan_values_result = tims_data.tims_scan_to_inv_mob(estimation, &mut indices);
149    // match mz_values_result {
150    //     Ok(mz_values) => println!("{:?}", mz_values),
151    //     Err(e) => println!("error: {}", e),
152    // };
153    // ```
154    pub fn tims_scan_to_inv_mob(
155        &self,
156        frame_id: u32,
157        dbl_scans: &[c_double],
158        inv_mob: &mut [c_double],
159    ) -> Result<(), Box<dyn std::error::Error>> {
160        unsafe {
161            let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
162                self.lib.get(b"tims_scannum_to_oneoverk0")?;
163            func(
164                self.handle,
165                frame_id,
166                dbl_scans.as_ptr(),
167                inv_mob.as_mut_ptr(),
168                dbl_scans.len() as u32,
169            );
170        }
171        Ok(())
172    }
173
174    //
175    // Convert the given inverse mobility values to scan values.
176    //
177    // # Example
178    //
179    // ```
180    // let inv_mob = vec![...];
181    // let scan_values_result = tims_data.tims_inv_mob_to_scan(estimation, &mut inv_mob);
182    // match mz_values_result {
183    //     Ok(mz_values) => println!("{:?}", mz_values),
184    //     Err(e) => println!("error: {}", e),
185    // };
186    // ```
187    pub fn inv_mob_to_tims_scan(
188        &self,
189        frame_id: u32,
190        inv_mob: &[c_double],
191        scans: &mut [c_double],
192    ) -> Result<(), Box<dyn std::error::Error>> {
193        unsafe {
194            let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
195                self.lib.get(b"tims_oneoverk0_to_scannum")?;
196            func(
197                self.handle,
198                frame_id,
199                inv_mob.as_ptr(),
200                scans.as_mut_ptr(),
201                inv_mob.len() as u32,
202            );
203        }
204        Ok(())
205    }
206}
207
208impl Drop for BrukerTimsDataLibrary {
209    fn drop(&mut self) {
210        let close = self.tims_close();
211        match close {
212            Ok(_) => (),
213            Err(e) => println!("error: {}", e),
214        };
215    }
216}