1pub mod narrow_spectrum_reader;
2pub mod wide_spectrum_reader;
3
4use std::sync::Arc;
5
6use rayon::prelude::*;
7use timsrust_core::{
8 Converter, FrameInfo, FrameIons, FrameReader, Im, InvertibleConverter, Mz,
9 ScanIndex, Spectrum, TofIndex,
10};
11
12pub use narrow_spectrum_reader::NarrowSpectrumReader;
13use timsrust_core::utils::reader::{IndexedReader, ParIterableReader};
14pub use wide_spectrum_reader::WideSpectrumReader;
15
16use crate::{PeakReader, error::TimsResult};
17
18pub enum SpectrumReader<
20 IonReader,
21 InfoReader,
22 IM: InvertibleConverter<ScanIndex, Im>,
23 MZ: Converter<TofIndex, Mz>,
24> {
25 Narrow(NarrowSpectrumReader<IonReader, InfoReader, IM, MZ>),
26 Wide(WideSpectrumReader<IonReader, InfoReader, IM>),
27}
28
29impl<IonReader, InfoReader, IM, MZ>
30 SpectrumReader<IonReader, InfoReader, IM, MZ>
31where
32 IonReader: timsrust_core::utils::reader::Reader<FrameIons> + Sync + Send,
33 InfoReader: timsrust_core::utils::reader::Reader<FrameInfo>
34 + IndexedReader<FrameInfo>
35 + Sync
36 + Send,
37 IM: InvertibleConverter<ScanIndex, Im> + Sync + Send,
38 MZ: Converter<TofIndex, Mz> + Sync + Send,
39{
40 pub fn new(
45 frame_reader: FrameReader<IonReader, InfoReader>,
46 min_ms1_ion_count: f64,
47 min_ms2_ion_count: f64,
48 min_spectrum_size: usize,
49 use_precursors: bool,
50 im_converter: IM,
51 mz_converter: MZ,
52 ) -> TimsResult<Self> {
53 let spectrum_reader = if use_precursors {
54 let peak_reader = PeakReader::new(
55 frame_reader,
56 min_ms1_ion_count,
57 min_ms2_ion_count,
58 )?;
59 let reader = NarrowSpectrumReader::new(
60 peak_reader,
61 min_spectrum_size,
62 Arc::new(im_converter),
63 Arc::new(mz_converter),
64 )?;
65 SpectrumReader::Narrow(reader)
66 } else {
67 let peak_reader =
68 PeakReader::new(frame_reader, -1.0, min_ms2_ion_count)?;
69 let reader = WideSpectrumReader::new(
70 peak_reader,
71 min_spectrum_size,
72 Arc::new(im_converter),
73 )?;
74 SpectrumReader::Wide(reader)
75 };
76 Ok(spectrum_reader)
77 }
78
79 pub fn len(&self) -> usize {
81 match self {
82 SpectrumReader::Narrow(reader) => reader.len(),
83 SpectrumReader::Wide(reader) => reader.len(),
84 }
85 }
86
87 pub fn is_empty(&self) -> bool {
88 self.len() == 0
89 }
90
91 pub fn get_spectra_from_frame(&self, frame_index: usize) -> Vec<Spectrum> {
93 match self {
94 SpectrumReader::Narrow(reader) => {
95 reader.get_spectra_from_frame(frame_index)
96 },
97 SpectrumReader::Wide(reader) => {
98 reader.get_spectra_from_frame(frame_index)
99 },
100 }
101 }
102
103 pub fn frame_count(&self) -> usize {
104 match self {
105 SpectrumReader::Narrow(reader) => reader.frame_count(),
106 SpectrumReader::Wide(reader) => reader.frame_count(),
107 }
108 }
109
110 pub fn tof_fwhm(&self) -> usize {
111 match self {
112 SpectrumReader::Narrow(reader) => reader.tof_fwhm(),
113 SpectrumReader::Wide(reader) => reader.tof_fwhm(),
114 }
115 }
116
117 pub fn scan_fwhm(&self) -> usize {
118 match self {
119 SpectrumReader::Narrow(reader) => reader.scan_fwhm(),
120 SpectrumReader::Wide(reader) => reader.scan_fwhm(),
121 }
122 }
123}
124
125impl<'a, IonReader, InfoReader, IM, MZ> ParIterableReader<'a, Spectrum>
126 for SpectrumReader<IonReader, InfoReader, IM, MZ>
127where
128 IonReader: timsrust_core::utils::reader::Reader<FrameIons> + Sync + Send,
129 InfoReader: timsrust_core::utils::reader::Reader<FrameInfo>
130 + IndexedReader<FrameInfo>
131 + Sync
132 + Send,
133 IM: InvertibleConverter<ScanIndex, Im> + Sync + Send,
134 MZ: Converter<TofIndex, Mz> + Sync + Send,
135{
136 type Error = TimsCentroidError;
137
138 fn par_iter(
139 &'a self,
140 ) -> impl ParallelIterator<Item = Result<Spectrum, Self::Error>> {
141 match self {
142 SpectrumReader::Narrow(reader) => A::Narrow(reader),
143 SpectrumReader::Wide(reader) => A::Wide(reader),
144 }
145 .map(Ok)
146 }
147}
148
149enum A<
150 'a,
151 IonReader,
152 InfoReader,
153 IM: InvertibleConverter<ScanIndex, Im>,
154 MZ: Converter<TofIndex, Mz>,
155> {
156 Narrow(&'a NarrowSpectrumReader<IonReader, InfoReader, IM, MZ>),
157 Wide(&'a WideSpectrumReader<IonReader, InfoReader, IM>),
158}
159
160#[derive(Debug, thiserror::Error)]
161#[error("{0}")]
162pub struct TimsCentroidError(String);
163
164impl<
165 'a,
166 IonReader: timsrust_core::utils::reader::Reader<FrameIons> + Sync + Send,
167 InfoReader: timsrust_core::utils::reader::Reader<FrameInfo>
168 + IndexedReader<FrameInfo>
169 + Sync
170 + Send,
171 IM: InvertibleConverter<ScanIndex, Im> + Sync + Send,
172 MZ: Converter<TofIndex, Mz> + Sync + Send,
173> ParallelIterator for A<'a, IonReader, InfoReader, IM, MZ>
174{
175 type Item = timsrust_core::Spectrum;
176
177 fn drive_unindexed<C>(self, consumer: C) -> C::Result
178 where
179 C: rayon::iter::plumbing::UnindexedConsumer<Self::Item>,
180 {
181 match self {
182 Self::Narrow(reader) => {
183 reader._par_iter().drive_unindexed(consumer)
184 },
185 Self::Wide(reader) => reader._par_iter().drive_unindexed(consumer),
186 }
187 }
188}
189
190impl<
191 IonReader: timsrust_core::utils::reader::Reader<FrameIons> + Sync + Send,
192 InfoReader: timsrust_core::utils::reader::Reader<FrameInfo>
193 + IndexedReader<FrameInfo>
194 + Sync
195 + Send,
196 IM: InvertibleConverter<ScanIndex, Im> + Sync + Send,
197 MZ: Converter<TofIndex, Mz> + Sync + Send,
198> ParallelIterator for SpectrumReader<IonReader, InfoReader, IM, MZ>
199{
200 type Item = timsrust_core::Spectrum;
201
202 fn drive_unindexed<C>(self, consumer: C) -> C::Result
203 where
204 C: rayon::iter::plumbing::UnindexedConsumer<Self::Item>,
205 {
206 match self {
207 Self::Narrow(reader) => {
208 reader._par_iter().drive_unindexed(consumer)
209 },
210 Self::Wide(reader) => reader._par_iter().drive_unindexed(consumer),
211 }
212 }
213}