Skip to content

Commit

Permalink
CHORE: refactored converters to be more explicit
Browse files Browse the repository at this point in the history
  • Loading branch information
sander-willems-bruker committed Apr 8, 2024
1 parent 26fc5b8 commit 0211d13
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 95 deletions.
2 changes: 1 addition & 1 deletion src/calibration.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
converters::{ConvertableIndex, Tof2MzConverter},
converters::{ConvertableDomain, Tof2MzConverter},
spectra::RawSpectrum,
Precursor,
};
Expand Down
95 changes: 9 additions & 86 deletions src/converters.rs
Original file line number Diff line number Diff line change
@@ -1,89 +1,12 @@
use linreg::linear_regression;
mod frame_to_rt;
mod scan_to_im;
mod tof_to_mz;

/// Converting from an index domain (e.g. Time of Flight) to a continuous domain (m/z).
pub trait ConvertableIndex {
/// Convert any index (even fractional) to a continuous value.
fn convert<T: Into<f64> + Copy>(&self, index: T) -> f64;
}

/// A converter from TOF -> m/z.
#[derive(Debug, Copy, Clone)]
pub struct Tof2MzConverter {
tof_intercept: f64,
tof_slope: f64,
}

impl Tof2MzConverter {
pub fn new(mz_min: f64, mz_max: f64, tof_max_index: u32) -> Self {
let tof_intercept: f64 = mz_min.sqrt();
let tof_slope: f64 =
(mz_max.sqrt() - tof_intercept) / tof_max_index as f64;
Self {
tof_intercept,
tof_slope,
}
}

pub fn from_unfragmented_precursors(data: &Vec<(f64, u32)>) -> Self {
let x: Vec<u32> = data.iter().map(|(_, x_val)| *x_val).collect();
let y: Vec<f64> =
data.iter().map(|(y_val, _)| (*y_val).sqrt()).collect();
let (tof_slope, tof_intercept) = linear_regression(&x, &y).unwrap();
Self {
tof_intercept,
tof_slope,
}
}
}

impl ConvertableIndex for Tof2MzConverter {
fn convert<T: Into<f64> + Copy>(&self, index: T) -> f64 {
let tof_index_f64: f64 = index.into();
(self.tof_intercept + self.tof_slope * tof_index_f64).powi(2)
}
}

/// A converter from Scan -> ion mobility.
#[derive(Debug, Copy, Clone)]
pub struct Scan2ImConverter {
scan_intercept: f64,
scan_slope: f64,
}

impl Scan2ImConverter {
pub fn new(im_min: f64, im_max: f64, scan_max_index: u32) -> Self {
let scan_intercept: f64 = im_max;
let scan_slope: f64 = (im_min - scan_intercept) / scan_max_index as f64;
Self {
scan_intercept,
scan_slope,
}
}
}

impl ConvertableIndex for Scan2ImConverter {
fn convert<T: Into<f64> + Copy>(&self, index: T) -> f64 {
let scan_index_f64: f64 = index.into();
self.scan_intercept + self.scan_slope * scan_index_f64
}
}

/// A converter from Frame -> retention time.
#[derive(Debug, Clone)]
pub struct Frame2RtConverter {
rt_values: Vec<f64>,
}

impl Frame2RtConverter {
pub fn new(rt_values: Vec<f64>) -> Self {
Self { rt_values }
}
}
pub use frame_to_rt::Frame2RtConverter;
pub use scan_to_im::Scan2ImConverter;
pub use tof_to_mz::Tof2MzConverter;

impl ConvertableIndex for Frame2RtConverter {
fn convert<T: Into<f64> + Copy>(&self, index: T) -> f64 {
let lower_value: f64 = self.rt_values[index.into().floor() as usize];
let upper_value: f64 = self.rt_values[index.into().ceil() as usize];
(lower_value + upper_value) / 2.
}
/// Convert from one domain (e.g. Time of Flight) to a another (m/z).
pub trait ConvertableDomain {
fn convert<T: Into<f64> + Copy>(&self, value: T) -> f64;
}
19 changes: 19 additions & 0 deletions src/converters/frame_to_rt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/// A converter from Frame -> retention time.
#[derive(Debug, Clone)]
pub struct Frame2RtConverter {
rt_values: Vec<f64>,
}

impl Frame2RtConverter {
pub fn from_values(rt_values: Vec<f64>) -> Self {
Self { rt_values }
}
}

impl super::ConvertableDomain for Frame2RtConverter {
fn convert<T: Into<f64> + Copy>(&self, value: T) -> f64 {
let lower_value: f64 = self.rt_values[value.into().floor() as usize];
let upper_value: f64 = self.rt_values[value.into().ceil() as usize];
(lower_value + upper_value) / 2.
}
}
28 changes: 28 additions & 0 deletions src/converters/scan_to_im.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/// A converter from Scan -> (inversed) ion mobility.
#[derive(Debug, Copy, Clone)]
pub struct Scan2ImConverter {
scan_intercept: f64,
scan_slope: f64,
}

impl Scan2ImConverter {
pub fn from_boundaries(
im_min: f64,
im_max: f64,
scan_max_index: u32,
) -> Self {
let scan_intercept: f64 = im_max;
let scan_slope: f64 = (im_min - scan_intercept) / scan_max_index as f64;
Self {
scan_intercept,
scan_slope,
}
}
}

impl super::ConvertableDomain for Scan2ImConverter {
fn convert<T: Into<f64> + Copy>(&self, value: T) -> f64 {
let scan_index_f64: f64 = value.into();
self.scan_intercept + self.scan_slope * scan_index_f64
}
}
42 changes: 42 additions & 0 deletions src/converters/tof_to_mz.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use linreg::linear_regression;

/// A converter from TOF -> m/z.
#[derive(Debug, Copy, Clone)]
pub struct Tof2MzConverter {
tof_intercept: f64,
tof_slope: f64,
}

impl Tof2MzConverter {
pub fn from_boundaries(
mz_min: f64,
mz_max: f64,
tof_max_index: u32,
) -> Self {
let tof_intercept: f64 = mz_min.sqrt();
let tof_slope: f64 =
(mz_max.sqrt() - tof_intercept) / tof_max_index as f64;
Self {
tof_intercept,
tof_slope,
}
}

pub fn from_pairs(data: &Vec<(f64, u32)>) -> Self {
let x: Vec<u32> = data.iter().map(|(_, x_val)| *x_val).collect();
let y: Vec<f64> =
data.iter().map(|(y_val, _)| (*y_val).sqrt()).collect();
let (tof_slope, tof_intercept) = linear_regression(&x, &y).unwrap();
Self {
tof_intercept,
tof_slope,
}
}
}

impl super::ConvertableDomain for Tof2MzConverter {
fn convert<T: Into<f64> + Copy>(&self, value: T) -> f64 {
let tof_index_f64: f64 = value.into();
(self.tof_intercept + self.tof_slope * tof_index_f64).powi(2)
}
}
4 changes: 2 additions & 2 deletions src/file_readers/common/sql_reader/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ impl SqlReader {
impl ReadableFromSql for Tof2MzConverter {
fn from_sql(sql_reader: &SqlReader) -> Self {
let (tof_max_index, mz_min, mz_max) = sql_reader.read_mz_information();
Tof2MzConverter::new(mz_min, mz_max, tof_max_index)
Tof2MzConverter::from_boundaries(mz_min, mz_max, tof_max_index)
}
}

impl ReadableFromSql for Scan2ImConverter {
fn from_sql(sql_reader: &SqlReader) -> Self {
let (scan_max_index, im_min, im_max) = sql_reader.read_im_information();
Scan2ImConverter::new(im_min, im_max, scan_max_index)
Scan2ImConverter::from_boundaries(im_min, im_max, scan_max_index)
}
}
4 changes: 2 additions & 2 deletions src/file_readers/frame_readers/tdf_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use {
crate::{
acquisition::AcquisitionType,
converters::{
ConvertableIndex, Frame2RtConverter, Scan2ImConverter,
ConvertableDomain, Frame2RtConverter, Scan2ImConverter,
Tof2MzConverter,
},
file_readers::{
Expand Down Expand Up @@ -68,7 +68,7 @@ impl TDFReader {

fn get_rt_converter(frame_table: &FrameTable) -> Frame2RtConverter {
let retention_times: Vec<f64> = frame_table.rt.clone();
Frame2RtConverter::new(retention_times)
Frame2RtConverter::from_values(retention_times)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/file_readers/spectrum_readers/dda_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl ReadableSpectra for DDASpectrumReader {
);
let mz_reader: Tof2MzConverter;
if hits.len() >= 2 {
mz_reader = Tof2MzConverter::from_unfragmented_precursors(&hits);
mz_reader = Tof2MzConverter::from_pairs(&hits);
} else {
mz_reader = self.mz_reader
}
Expand Down
2 changes: 1 addition & 1 deletion src/file_readers/spectrum_readers/dda_reader/precursors.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rayon::prelude::*;

use crate::{
converters::{ConvertableIndex, Scan2ImConverter},
converters::{ConvertableDomain, Scan2ImConverter},
file_readers::{
common::sql_reader::{
PasefFrameMsMsTable, PrecursorTable, ReadableFromSql,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ mod vec_utils;
pub use crate::{
acquisition::AcquisitionType,
converters::{
ConvertableIndex, Frame2RtConverter, Scan2ImConverter, Tof2MzConverter,
ConvertableDomain, Frame2RtConverter, Scan2ImConverter, Tof2MzConverter,
},
errors::*,
file_readers::FileReader,
Expand Down
2 changes: 1 addition & 1 deletion src/spectra.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
converters::{ConvertableIndex, Tof2MzConverter},
converters::{ConvertableDomain, Tof2MzConverter},
precursors::QuadrupoleEvent,
vec_utils::{filter_with_mask, find_sparse_local_maxima_mask},
Precursor,
Expand Down

0 comments on commit 0211d13

Please sign in to comment.