diff --git a/src/file_readers/spectrum_readers/dda_reader.rs b/src/file_readers/spectrum_readers/dda_reader.rs index 99c1ce9..1525982 100644 --- a/src/file_readers/spectrum_readers/dda_reader.rs +++ b/src/file_readers/spectrum_readers/dda_reader.rs @@ -1,20 +1,27 @@ -mod precursors; +use std::path::Path; use crate::{ calibration::Tof2MzCalibrator, domain_converters::Tof2MzConverter, file_readers::ReadableSpectra, - io::readers::{frame_reader::FrameReader, metadata_reader::MetadataReader}, + io::readers::{ + file_readers::sql_reader::{ + pasef_frame_msms::SqlPasefFrameMsMs, ReadableSqlTable, SqlReader, + }, + frame_reader::FrameReader, + metadata_reader::MetadataReader, + precursor_reader::PrecursorReader, + }, ms_data::{ - Frame, RawProcessedSpectrumState, RawSpectrum, RawSpectrumProcessor, - Spectrum, + Frame, Precursor, RawProcessedSpectrumState, RawSpectrum, + RawSpectrumProcessor, Spectrum, }, - utils::vec_utils::group_and_sum, + utils::vec_utils::{argsort, group_and_sum}, }; use rayon::prelude::*; -use self::precursors::PrecursorReader; +// use self::precursors::PrecursorReader; const SMOOTHING_WINDOW: u32 = 1; const CENTROIDING_WINDOW: u32 = 1; @@ -25,6 +32,9 @@ pub struct DDASpectrumReader { precursor_reader: PrecursorReader, mz_reader: Tof2MzConverter, ms2_frames: Vec, + pub pasef_frames: Vec, + pub order: Vec, + pub offsets: Vec, } impl DDASpectrumReader { @@ -32,28 +42,47 @@ impl DDASpectrumReader { let frame_reader: FrameReader = FrameReader::new(&path_name); let metadata = MetadataReader::new(&path_name); let mz_reader: Tof2MzConverter = metadata.mz_converter; - + let tdf_sql_reader = + SqlReader::open(Path::new(&path_name).join("analysis.tdf")) + .unwrap(); + let pasef_frames = + SqlPasefFrameMsMs::from_sql_reader(&tdf_sql_reader).unwrap(); let ms2_frames: Vec = frame_reader.parallel_filter(|x| x.msms_type != 0).collect(); let precursor_reader: PrecursorReader = PrecursorReader::new(&path_name); + let pasef_precursors = + &pasef_frames.iter().map(|x| x.precursor).collect(); + let order: Vec = argsort(&pasef_precursors); + let mut offsets: Vec = + Vec::with_capacity(precursor_reader.len() + 1); + offsets.push(0); + for (offset, &index) in order.iter().enumerate().take(order.len() - 1) { + let second_index: usize = order[offset + 1]; + if pasef_precursors[index] != pasef_precursors[second_index] { + offsets.push(offset + 1) + } + } + offsets.push(order.len()); Self { path_name, precursor_reader, mz_reader, ms2_frames, + pasef_frames, + order, + offsets, } } pub fn read_single_raw_spectrum(&self, index: usize) -> RawSpectrum { - let start: usize = self.precursor_reader.offsets[index]; - let end: usize = self.precursor_reader.offsets[index + 1]; - let selection: &[usize] = &self.precursor_reader.order[start..end]; + let start: usize = self.offsets[index]; + let end: usize = self.offsets[index + 1]; + let selection: &[usize] = &self.order[start..end]; let mut tof_indices: Vec = vec![]; let mut intensities: Vec = vec![]; for &index in selection.iter() { - let frame_index: usize = - self.precursor_reader.pasef_frames[index].frame - 1; + let frame_index: usize = self.pasef_frames[index].frame - 1; // TODO OPTIMIZE!!!!! let frame: &Frame = &self .ms2_frames @@ -63,10 +92,8 @@ impl DDASpectrumReader { if frame.intensities.len() == 0 { continue; } - let scan_start: usize = - self.precursor_reader.pasef_frames[index].scan_start; - let scan_end: usize = - self.precursor_reader.pasef_frames[index].scan_end; + let scan_start: usize = self.pasef_frames[index].scan_start; + let scan_end: usize = self.pasef_frames[index].scan_end; let offset_start: usize = frame.scan_offsets[scan_start] as usize; let offset_end: usize = frame.scan_offsets[scan_end] as usize; let tof_selection: &[u32] = @@ -101,7 +128,7 @@ impl DDASpectrumReader { let index: usize = raw_spectrum.index as usize; let spectrum_processer = RawSpectrumProcessor { raw_spectrum }; let spectrum = spectrum_processer - .finalize(self.precursor_reader.precursors[index], mz_reader); + .finalize(self.precursor_reader.get(index), mz_reader); spectrum } } @@ -113,14 +140,17 @@ impl ReadableSpectra for DDASpectrumReader { } fn read_all_spectra(&self) -> Vec { - let raw_spectra: Vec = (0..self.precursor_reader.count) + let raw_spectra: Vec = (0..self.precursor_reader.len()) .into_par_iter() .map(|index| self.read_single_raw_spectrum(index)) .collect(); + let precursors: Vec = (0..self.precursor_reader.len()) + .map(|index| self.precursor_reader.get(index)) + .collect(); let hits = Tof2MzCalibrator::find_unfragmented_precursors( &raw_spectra, &self.mz_reader, - &self.precursor_reader.precursors, + &precursors, 0.1, ); let temp_mz_reader: Tof2MzConverter; diff --git a/src/file_readers/spectrum_readers/dda_reader/precursors.rs b/src/file_readers/spectrum_readers/dda_reader/precursors.rs deleted file mode 100644 index 2fcb309..0000000 --- a/src/file_readers/spectrum_readers/dda_reader/precursors.rs +++ /dev/null @@ -1,83 +0,0 @@ -use std::path::Path; - -use rayon::prelude::*; - -use crate::{ - domain_converters::{ - ConvertableDomain, Frame2RtConverter, Scan2ImConverter, - }, - io::readers::{ - file_readers::sql_reader::{ - pasef_frame_msms::SqlPasefFrameMsMs, precursors::SqlPrecursor, - ReadableSqlTable, SqlReader, - }, - metadata_reader::MetadataReader, - }, - ms_data::Precursor, - utils::vec_utils::argsort, -}; - -#[derive(Debug)] -pub struct PrecursorReader { - pub precursors: Vec, - pub pasef_frames: Vec, - pub order: Vec, - pub offsets: Vec, - pub count: usize, -} - -impl PrecursorReader { - pub fn new(path: &String) -> Self { - let metadata = MetadataReader::new(&path); - let rt_converter: Frame2RtConverter = metadata.rt_converter; - let im_converter: Scan2ImConverter = metadata.im_converter; - let tdf_sql_reader = - SqlReader::open(Path::new(path).join("analysis.tdf")).unwrap(); - let pasef_frames = - SqlPasefFrameMsMs::from_sql_reader(&tdf_sql_reader).unwrap(); - let precursors = - SqlPrecursor::from_sql_reader(&tdf_sql_reader).unwrap(); - let precursors: Vec = (0..precursors.len()) - .into_par_iter() - .map(|index| { - let frame_id: usize = precursors[index].precursor_frame; - let scan_id: f64 = precursors[index].scan_average; - Precursor { - mz: precursors[index].mz, - rt: rt_converter.convert(frame_id as u32), - im: im_converter.convert(scan_id), - charge: precursors[index].charge, - intensity: precursors[index].intensity, - index: index + 1, //TODO? - frame_index: frame_id, - // TODO OPTIMIZE!!!!! - collision_energy: pasef_frames - .iter() - .find(|&x| x.precursor == index + 1) - .unwrap() - .collision_energy, - } - }) - .collect(); - let pasef_precursors = - &pasef_frames.iter().map(|x| x.precursor).collect(); - let order: Vec = argsort(&pasef_precursors); - let count: usize = *pasef_precursors.iter().max().unwrap(); - let mut offsets: Vec = Vec::with_capacity(count + 1); - offsets.push(0); - for (offset, &index) in order.iter().enumerate().take(order.len() - 1) { - let second_index: usize = order[offset + 1]; - if pasef_precursors[index] != pasef_precursors[second_index] { - offsets.push(offset + 1) - } - } - offsets.push(order.len()); - Self { - precursors, - pasef_frames, - order, - offsets, - count, - } - } -} diff --git a/src/io/readers.rs b/src/io/readers.rs index 3d0a4f0..8614127 100644 --- a/src/io/readers.rs +++ b/src/io/readers.rs @@ -2,3 +2,4 @@ pub mod file_readers; pub mod frame_reader; pub mod metadata_reader; +pub mod precursor_reader; diff --git a/src/io/readers/precursor_reader.rs b/src/io/readers/precursor_reader.rs new file mode 100644 index 0000000..e1c27b4 --- /dev/null +++ b/src/io/readers/precursor_reader.rs @@ -0,0 +1,70 @@ +use std::path::{Path, PathBuf}; + +use crate::{ + domain_converters::{ + ConvertableDomain, Frame2RtConverter, Scan2ImConverter, + }, + ms_data::Precursor, +}; + +use super::{ + file_readers::sql_reader::{ + precursors::SqlPrecursor, ReadableSqlTable, SqlReader, + }, + metadata_reader::MetadataReader, +}; + +#[derive(Debug)] +pub struct PrecursorReader { + path: PathBuf, + sql_precursors: Vec, + rt_converter: Frame2RtConverter, + im_converter: Scan2ImConverter, +} + +impl PrecursorReader { + pub fn new(path: impl AsRef) -> Self { + let sql_path = path.as_ref().join("analysis.tdf"); + let tdf_sql_reader = SqlReader::open(sql_path).unwrap(); + let metadata = MetadataReader::new(&path); + let rt_converter: Frame2RtConverter = metadata.rt_converter; + let im_converter: Scan2ImConverter = metadata.im_converter; + let sql_precursors = + SqlPrecursor::from_sql_reader(&tdf_sql_reader).unwrap(); + Self { + path: path.as_ref().to_path_buf(), + sql_precursors, + rt_converter, + im_converter, + } + } + + pub fn get(&self, index: usize) -> Precursor { + let mut precursor: Precursor = Precursor::default(); + let sql_precursor = &self.sql_precursors[index]; + let frame_id: usize = sql_precursor.precursor_frame; + let scan_id: f64 = sql_precursor.scan_average; + precursor.mz = sql_precursor.mz; + precursor.rt = self.rt_converter.convert(frame_id as u32); + precursor.im = self.im_converter.convert(scan_id); + precursor.charge = sql_precursor.charge; + precursor.intensity = sql_precursor.intensity; + precursor.index = index + 1; //TODO; + precursor.frame_index = frame_id; + // TODO OPTIMIZE!!!!! + // precursor.collision_energy = pasef_frames + // .iter() + // .find(|&x| x.precursor == index + 1) + // .unwrap() + // .collision_energy; + precursor + } + + pub fn get_path(&self) -> PathBuf { + self.path.clone() + } + + pub fn len(&self) -> usize { + self.sql_precursors.len() + } +}