timsrust_tdf/
precursor_reader.rs1mod dda;
2mod dia;
3
4use std::sync::Arc;
5
6use dda::{DDATDFPrecursorReader, DDATDFPrecursorReaderError};
7use dia::{DIATDFPrecursorReader, DIATDFPrecursorReaderError};
8use timsrust_core::utils::reader::Reader;
9use timsrust_core::{
10 AcquisitionType, Im, InvertibleConverter, Precursor, ScanIndex,
11};
12
13use crate::{
14 FrameWindowSplittingConfiguration, TDFPathLike,
15 file_readers::sql_reader::{
16 ReadableSqlTable, SqlReader, SqlReaderError, frames::SqlFrame,
17 },
18};
19
20use super::{TDFPath, TDFPathError};
21
22pub(crate) struct PrecursorReaderBuilder<ImC> {
23 path: Option<TDFPath>,
24 config: FrameWindowSplittingConfiguration<ImC>,
25 im_converter: Option<Arc<ImC>>,
26}
27
28impl<ImC> Default for PrecursorReaderBuilder<ImC> {
29 fn default() -> Self {
30 Self {
31 path: None,
32 config: FrameWindowSplittingConfiguration::default(),
33 im_converter: None,
34 }
35 }
36}
37
38impl<ImC> Clone for PrecursorReaderBuilder<ImC> {
39 fn clone(&self) -> Self {
40 Self {
41 path: self.path.clone(),
42 config: self.config.clone(),
43 im_converter: self.im_converter.clone(),
44 }
45 }
46}
47
48impl<ImC> PrecursorReaderBuilder<ImC> {
49 pub(crate) fn with_path(&self, path: impl TDFPathLike) -> Self {
50 let path = Some(path.to_timstof_path().unwrap());
51 Self {
52 path,
53 ..self.clone()
54 }
55 }
56
57 pub(crate) fn with_config(
58 &self,
59 config: FrameWindowSplittingConfiguration<ImC>,
60 ) -> Self {
61 Self {
62 config,
63 ..self.clone()
64 }
65 }
66
67 pub(crate) fn with_im_converter(&self, im_converter: Arc<ImC>) -> Self {
68 Self {
69 im_converter: Some(im_converter),
70 ..self.clone()
71 }
72 }
73}
74
75impl<ImC: InvertibleConverter<ScanIndex, Im> + Send + Sync + std::fmt::Debug>
76 PrecursorReaderBuilder<ImC>
77{
78 pub(crate) fn finalize(
79 self,
80 ) -> Result<TDFPrecursorReader<ImC>, TDFPrecursorReaderError> {
81 let path = match self.path {
82 None => return Err(TDFPrecursorReaderError::NoPath),
83 Some(path) => path,
84 };
85 let im_converter = match self.im_converter {
86 None => return Err(TDFPrecursorReaderError::NoImConverter),
87 Some(c) => c,
88 };
89 TDFPrecursorReader::new(path, self.config, im_converter)
90 }
91}
92
93#[derive(Debug)]
94#[allow(clippy::upper_case_acronyms)]
95enum InnerPrecursorReader<ImC> {
96 DDAPASEF(DDATDFPrecursorReader<ImC>),
97 DIAPASEF(DIATDFPrecursorReader<ImC>),
98}
99
100impl<ImC: InvertibleConverter<ScanIndex, Im>> InnerPrecursorReader<ImC> {
101 fn len(&self) -> usize {
102 match self {
103 InnerPrecursorReader::DDAPASEF(reader) => reader.len(),
104 InnerPrecursorReader::DIAPASEF(reader) => reader.len(),
105 }
106 }
107}
108
109#[derive(Debug)]
110pub struct TDFPrecursorReader<ImC> {
111 precursor_reader: InnerPrecursorReader<ImC>,
112}
113
114impl<ImC: InvertibleConverter<ScanIndex, Im> + Send + Sync + std::fmt::Debug>
115 TDFPrecursorReader<ImC>
116{
117 pub(crate) fn build() -> PrecursorReaderBuilder<ImC> {
118 PrecursorReaderBuilder::default()
119 }
120
121 pub fn len(&self) -> usize {
122 self.precursor_reader.len()
123 }
124
125 pub fn is_empty(&self) -> bool {
126 self.len() == 0
127 }
128
129 pub fn new(
130 path: impl TDFPathLike,
131 splitting_strategy: FrameWindowSplittingConfiguration<ImC>,
132 im_converter: Arc<ImC>,
133 ) -> Result<Self, TDFPrecursorReaderError> {
134 let tdf_sql_reader = SqlReader::open(&path)?;
135 let sql_frames = SqlFrame::from_sql_reader(&tdf_sql_reader)?;
136 let acquisition_type = if sql_frames.iter().any(|f| f.scan_mode == 8) {
137 AcquisitionType::DDAPASEF
138 } else if sql_frames.iter().any(|f| f.scan_mode == 9) {
139 AcquisitionType::DIAPASEF
140 } else {
141 AcquisitionType::Unknown
142 };
143 let precursor_reader = match acquisition_type {
144 AcquisitionType::DDAPASEF => InnerPrecursorReader::DDAPASEF(
145 DDATDFPrecursorReader::new(&path, im_converter)?,
146 ),
147 AcquisitionType::DIAPASEF => {
148 InnerPrecursorReader::DIAPASEF(DIATDFPrecursorReader::new(
149 path,
150 splitting_strategy,
151 im_converter,
152 )?)
153 },
154 acquisition_type => {
155 return Err(TDFPrecursorReaderError::UnsupportedAcquisition(
156 format!("{:?}", acquisition_type),
157 ));
158 },
159 };
160 Ok(Self { precursor_reader })
161 }
162}
163
164impl<ImC: InvertibleConverter<ScanIndex, Im>> Reader<Precursor>
165 for TDFPrecursorReader<ImC>
166{
167 type Error = TDFPrecursorReaderError;
168 fn get(&self, index: usize) -> Result<Precursor, Self::Error> {
169 match self.precursor_reader {
170 InnerPrecursorReader::DDAPASEF(ref reader) => {
171 Ok(reader.get(index)?)
172 },
173 InnerPrecursorReader::DIAPASEF(ref reader) => {
174 Ok(reader.get(index)?)
175 },
176 }
177 }
178}
179
180#[allow(private_interfaces)]
181#[derive(Debug, thiserror::Error)]
182pub enum TDFPrecursorReaderError {
183 #[error("{0}")]
184 SqlReaderError(#[from] SqlReaderError),
185 #[error("{0}")]
186 DDATDFPrecursorReaderError(#[from] DDATDFPrecursorReaderError),
187 #[error("{0}")]
188 DIATDFPrecursorReaderError(#[from] DIATDFPrecursorReaderError),
189 #[error("Invalid acquistion type for precursor reader: {0}")]
190 UnsupportedAcquisition(String),
191 #[error("{0}")]
192 TDFPathError(#[from] TDFPathError),
193 #[error("No path provided for precursor reader")]
194 NoPath,
195 #[error("No im_converter provided for precursor reader")]
196 NoImConverter,
197}