rustdf/data/
raw.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
use libloading::{Library, Symbol};
use std::os::raw::{c_char, c_double};

//
// A struct that holds a handle to the raw data
//
// # Example
//
// ```
// let bruker_lib_path = "path/to/libtimsdata.so";
// let data_path = "path/to/data.d";
// let tims_data = BrukerTimsDataLibrary::new(bruker_lib_path, data_path);
// ```
pub struct BrukerTimsDataLibrary {
    pub lib: Library,
    pub handle: u64,
}

impl BrukerTimsDataLibrary {
    //
    // Create a new BrukerTimsDataLibrary struct
    //
    // # Arguments
    //
    // * `bruker_lib_path` - A string slice that holds the path to the bruker library
    // * `data_path` - A string slice that holds the path to the data
    //
    // # Example
    //
    // ```
    // let bruker_lib_path = "path/to/libtimsdata.so";
    // let data_path = "path/to/data.d";
    // let tims_data = BrukerTimsDataLibrary::new(bruker_lib_path, data_path);
    // ```
    pub fn new(
        bruker_lib_path: &str,
        data_path: &str,
    ) -> Result<BrukerTimsDataLibrary, Box<dyn std::error::Error>> {
        // Load the library
        let lib = unsafe { Library::new(bruker_lib_path)? };

        // create a handle to the raw data
        let handle = unsafe {
            let func: Symbol<unsafe extern "C" fn(*const c_char, u32) -> u64> =
                lib.get(b"tims_open")?;
            let path = std::ffi::CString::new(data_path)?;
            let handle = func(path.as_ptr(), 0);
            handle
        };

        // return the BrukerTimsDataLibrary struct
        Ok(BrukerTimsDataLibrary { lib, handle })
    }

    //
    // Close the handle to the raw data
    //
    // # Example
    //
    // ```
    // let close = tims_data.tims_close();
    // match close {
    //     Ok(_) => println!("tims_data closed"),
    //     Err(e) => println!("error: {}", e),
    // };
    // ```
    pub fn tims_close(&self) -> Result<(), Box<dyn std::error::Error>> {
        unsafe {
            let func: Symbol<unsafe extern "C" fn(u64) -> ()> = self.lib.get(b"tims_close")?;
            func(self.handle);
        }
        Ok(())
    }

    //
    // Convert the given indices to mz values.
    //
    // # Example
    //
    // ```
    // let indices = vec![...];
    // let mz_values_result = tims_data.tims_index_to_mz(estimation, &mut indices, tof_max_index);
    // match mz_values_result {
    //     Ok(mz_values) => println!("{:?}", mz_values),
    //     Err(e) => println!("error: {}", e),
    // };
    // ```
    pub fn tims_index_to_mz(
        &self,
        frame_id: u32,
        dbl_tofs: &[c_double],
        mzs: &mut [c_double],
    ) -> Result<(), Box<dyn std::error::Error>> {
        unsafe {
            let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
                self.lib.get(b"tims_index_to_mz")?;
            func(
                self.handle,
                frame_id,
                dbl_tofs.as_ptr(),
                mzs.as_mut_ptr(),
                dbl_tofs.len() as u32,
            );
        }
        Ok(())
    }

    //
    // Convert the given mz values to indices.
    //
    // # Example
    //
    // ```
    // let mzs = vec![...];
    // let indices_result = tims_data.tims_mz_to_index(estimation, &mut mzs);
    // match indices_result {
    //     Ok(indices) => println!("{:?}", indices),
    //     Err(e) => println!("error: {}", e),
    // };
    // ```
    pub fn tims_mz_to_index(
        &self,
        frame_id: u32,
        mzs: &[c_double],
        indices: &mut [c_double],
    ) -> Result<(), Box<dyn std::error::Error>> {
        unsafe {
            let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
                self.lib.get(b"tims_mz_to_index")?;
            func(
                self.handle,
                frame_id,
                mzs.as_ptr(),
                indices.as_mut_ptr(),
                mzs.len() as u32,
            );
        }
        Ok(())
    }

    //
    // Convert the given indices to inverse mobility values.
    //
    // # Example
    //
    // ```
    // let indices = vec![...];
    // let scan_values_result = tims_data.tims_scan_to_inv_mob(estimation, &mut indices);
    // match mz_values_result {
    //     Ok(mz_values) => println!("{:?}", mz_values),
    //     Err(e) => println!("error: {}", e),
    // };
    // ```
    pub fn tims_scan_to_inv_mob(
        &self,
        frame_id: u32,
        dbl_scans: &[c_double],
        inv_mob: &mut [c_double],
    ) -> Result<(), Box<dyn std::error::Error>> {
        unsafe {
            let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
                self.lib.get(b"tims_scannum_to_oneoverk0")?;
            func(
                self.handle,
                frame_id,
                dbl_scans.as_ptr(),
                inv_mob.as_mut_ptr(),
                dbl_scans.len() as u32,
            );
        }
        Ok(())
    }

    //
    // Convert the given inverse mobility values to scan values.
    //
    // # Example
    //
    // ```
    // let inv_mob = vec![...];
    // let scan_values_result = tims_data.tims_inv_mob_to_scan(estimation, &mut inv_mob);
    // match mz_values_result {
    //     Ok(mz_values) => println!("{:?}", mz_values),
    //     Err(e) => println!("error: {}", e),
    // };
    // ```
    pub fn inv_mob_to_tims_scan(
        &self,
        frame_id: u32,
        inv_mob: &[c_double],
        scans: &mut [c_double],
    ) -> Result<(), Box<dyn std::error::Error>> {
        unsafe {
            let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
                self.lib.get(b"tims_oneoverk0_to_scannum")?;
            func(
                self.handle,
                frame_id,
                inv_mob.as_ptr(),
                scans.as_mut_ptr(),
                inv_mob.len() as u32,
            );
        }
        Ok(())
    }
}

impl Drop for BrukerTimsDataLibrary {
    fn drop(&mut self) {
        let close = self.tims_close();
        match close {
            Ok(_) => (),
            Err(e) => println!("error: {}", e),
        };
    }
}