1mod dda;
2mod dia;
3mod raw_spectra;
4
5use std::sync::Arc;
6
7use raw_spectra::{RawSpectrum, RawSpectrumReader, RawSpectrumReaderError};
8use rayon::iter::{IntoParallelIterator, ParallelIterator};
9use timsrust_core::utils::reader::Reader;
10use timsrust_core::{Im, InvertibleConverter, ScanIndex, Spectrum};
11
12use crate::{
13 FrameReaderError, FrameWindowSplittingConfiguration, MetadataReaderError,
14 TDFPrecursorReader, TDFPrecursorReaderError,
15 file_readers::sql_reader::{SqlReader, SqlReaderError},
16};
17
18use super::TDFPathLike;
19
20use crate::{TDFPath, TdfFrameReader};
21
22#[derive(Debug)]
23pub struct TDFSpectrumReader<ImC> {
24 precursor_reader: TDFPrecursorReader<ImC>,
25 raw_spectrum_reader: RawSpectrumReader,
26 config: SpectrumReaderConfig<ImC>,
27}
28
29impl<ImC: InvertibleConverter<ScanIndex, Im> + Send + Sync + std::fmt::Debug>
30 TDFSpectrumReader<ImC>
31{
32 pub fn new(
33 path: impl TDFPathLike,
34 config: SpectrumReaderConfig<ImC>,
35 im_converter: Arc<ImC>,
36 ) -> Result<Self, TDFSpectrumReaderError> {
37 let frame_reader = TdfFrameReader::new(&path)?;
38 let tdf_sql_reader = SqlReader::open(&path)?;
39 let precursor_reader = TDFPrecursorReader::build()
40 .with_path(&path)
41 .with_config(config.clone().frame_splitting_params)
42 .with_im_converter(im_converter.clone())
43 .finalize()?;
44 let acquisition_type = frame_reader.get_acquisition();
45 let splitting_strategy = config
46 .clone()
47 .frame_splitting_params
48 .finalize(Some(im_converter));
49 let raw_spectrum_reader = RawSpectrumReader::new(
50 &tdf_sql_reader,
51 frame_reader,
52 acquisition_type,
53 splitting_strategy,
54 )?;
55 Ok(Self {
56 precursor_reader,
57 raw_spectrum_reader,
58 config,
59 })
60 }
61
62 fn read_single_raw_spectrum(
63 &self,
64 index: usize,
65 ) -> Result<RawSpectrum, RawSpectrumReaderError> {
66 let raw_spectrum = self
67 .raw_spectrum_reader
68 .get(index)?
69 .smooth(self.config.spectrum_processing_params.smoothing_window)
70 .centroid(
71 self.config.spectrum_processing_params.centroiding_window,
72 );
73 Ok(raw_spectrum)
74 }
75
76 fn _get(&self, index: usize) -> Result<Spectrum, TDFSpectrumReaderError> {
77 let raw_spectrum = self.read_single_raw_spectrum(index)?;
78 let spectrum = raw_spectrum
79 .finalize(self.precursor_reader.get(index)?);
81 Ok(spectrum)
82 }
83
84 pub fn build() -> SpectrumReaderBuilder<ImC> {
85 SpectrumReaderBuilder::default()
86 }
87
88 pub fn get_all(&self) -> Vec<Result<Spectrum, TDFSpectrumReaderError>> {
89 let mut spectra: Vec<Result<Spectrum, TDFSpectrumReaderError>> = (0
90 ..self.len())
91 .into_par_iter()
92 .map(|index| self._get(index))
93 .collect();
94 spectra.sort_by_key(|x| match x {
95 Ok(spectrum) => match &spectrum.precursor() {
96 Some(precursor) => precursor.index(),
97 None => spectrum.index(),
98 },
99 Err(_) => 0,
100 });
101 spectra
102 }
103
104 pub fn len(&self) -> usize {
105 debug_assert_eq!(
106 self.precursor_reader.len(),
107 self.raw_spectrum_reader.len()
108 );
109 self.raw_spectrum_reader.len()
110 }
111
112 pub fn is_empty(&self) -> bool {
113 self.len() == 0
114 }
115
116 pub fn calibrate(&mut self) {}
117}
118
119impl<ImC: InvertibleConverter<ScanIndex, Im> + Send + Sync + std::fmt::Debug>
120 timsrust_core::utils::reader::Reader<Spectrum> for TDFSpectrumReader<ImC>
121{
122 type Error = TDFSpectrumReaderError;
123 fn get(&self, index: usize) -> Result<Spectrum, Self::Error> {
124 self._get(index)
125 }
126}
127
128impl<ImC: InvertibleConverter<ScanIndex, Im> + Send + Sync + std::fmt::Debug>
129 timsrust_core::utils::reader::IndexedReader<Spectrum>
130 for TDFSpectrumReader<ImC>
131{
132 type Iter = std::ops::Range<usize>;
133 fn iter(&self) -> Self::Iter {
134 0..self.len()
135 }
136}
137
138#[allow(private_interfaces)]
139#[derive(Debug, thiserror::Error)]
140pub enum TDFSpectrumReaderError {
141 #[error("{0}")]
142 SqlReaderError(#[from] SqlReaderError),
143 #[error("{0}")]
144 TDFPrecursorReaderError(#[from] TDFPrecursorReaderError),
145 #[error("{0}")]
146 MetadaReaderError(#[from] MetadataReaderError),
147 #[error("{0}")]
148 FrameReaderError(#[from] FrameReaderError),
149 #[error("{0}")]
150 RawSpectrumReaderError(#[from] RawSpectrumReaderError),
151 #[error("{0}")]
152 FileNotFound(String),
153 #[error("No precursor")]
154 NoPrecursor,
155 #[error("No path")]
156 NoPath,
157 #[error("No im_converter provided")]
158 NoImConverter,
159}
160
161pub struct SpectrumReaderBuilder<ImC> {
162 path: Option<TDFPath>,
163 config: SpectrumReaderConfig<ImC>,
164 im_converter: Option<Arc<ImC>>,
165}
166
167impl<ImC> Default for SpectrumReaderBuilder<ImC> {
168 fn default() -> Self {
169 Self {
170 path: None,
171 config: SpectrumReaderConfig::default(),
172 im_converter: None,
173 }
174 }
175}
176
177impl<ImC> Clone for SpectrumReaderBuilder<ImC> {
178 fn clone(&self) -> Self {
179 Self {
180 path: self.path.clone(),
181 config: self.config.clone(),
182 im_converter: self.im_converter.clone(),
183 }
184 }
185}
186
187impl<ImC> SpectrumReaderBuilder<ImC> {
188 pub fn with_path(&self, path: impl TDFPathLike) -> Self {
189 let path = Some(path.to_timstof_path().unwrap());
190 Self {
191 path,
192 ..self.clone()
193 }
194 }
195
196 pub fn with_config(&self, config: SpectrumReaderConfig<ImC>) -> Self {
197 Self {
198 config,
199 ..self.clone()
200 }
201 }
202
203 pub fn with_im_converter(&self, im_converter: Arc<ImC>) -> Self {
204 Self {
205 im_converter: Some(im_converter),
206 ..self.clone()
207 }
208 }
209}
210
211impl<ImC: InvertibleConverter<ScanIndex, Im> + Send + Sync + std::fmt::Debug>
212 SpectrumReaderBuilder<ImC>
213{
214 pub fn finalize(
215 self,
216 ) -> Result<TDFSpectrumReader<ImC>, TDFSpectrumReaderError> {
217 let path = match self.path {
218 None => return Err(TDFSpectrumReaderError::NoPath),
219 Some(path) => path,
220 };
221 let im_converter = match self.im_converter {
222 None => return Err(TDFSpectrumReaderError::NoImConverter),
223 Some(c) => c,
224 };
225 let mut spectrum_reader =
226 TDFSpectrumReader::new(path, self.config.clone(), im_converter)?;
227 if self.config.spectrum_processing_params.calibrate {
228 spectrum_reader.calibrate();
229 }
230 Ok(spectrum_reader)
231 }
232}
233
234#[derive(Debug, Clone, Copy)]
235pub struct SpectrumProcessingParams {
236 pub smoothing_window: u32,
237 pub centroiding_window: u32,
238 pub calibration_tolerance: f64,
239 pub calibrate: bool,
240}
241
242impl Default for SpectrumProcessingParams {
243 fn default() -> Self {
244 Self {
245 smoothing_window: 1,
246 centroiding_window: 1,
247 calibration_tolerance: 0.1,
248 calibrate: false,
249 }
250 }
251}
252
253#[derive(Debug)]
254pub struct SpectrumReaderConfig<ImC> {
255 pub spectrum_processing_params: SpectrumProcessingParams,
256 pub frame_splitting_params: FrameWindowSplittingConfiguration<ImC>,
257}
258
259impl<ImC> Default for SpectrumReaderConfig<ImC> {
260 fn default() -> Self {
261 Self {
262 spectrum_processing_params: SpectrumProcessingParams::default(),
263 frame_splitting_params: FrameWindowSplittingConfiguration::default(
264 ),
265 }
266 }
267}
268
269impl<ImC> Clone for SpectrumReaderConfig<ImC> {
270 fn clone(&self) -> Self {
271 Self {
272 spectrum_processing_params: self.spectrum_processing_params,
273 frame_splitting_params: self.frame_splitting_params.clone(),
274 }
275 }
276}