Skip to main content

mzdata_meta/
data_processing.rs

1#![allow(unused)]
2use std::fmt::Display;
3
4use crate::impl_param_described;
5use crate::params::{ControlledVocabulary, Param, ParamCow, ParamList};
6
7use super::Software;
8
9/// Describe a data processing method stage tied to a specific piece of [`Software`]
10///
11/// See <https://peptideatlas.org/tmp/mzML1.1.0.html#processingMethod>
12#[derive(Debug, Clone, Default, PartialEq, Eq)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14pub struct ProcessingMethod {
15    /// The order of application of this method in the processing pipeline
16    pub order: i8,
17    /// The software used
18    pub software_reference: String,
19    /// Controlled vocabulary and user parameters
20    pub params: ParamList,
21}
22
23/// Describe a complete data processing method, a series of [`ProcessingMethod`] transformations
24/// through a pipeline of [`Software`].
25///
26/// See <https://peptideatlas.org/tmp/mzML1.1.0.html#dataProcessing>
27#[derive(Debug, Clone, Default, PartialEq, Eq)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29pub struct DataProcessing {
30    /// The identifier for this data processing pipeline
31    pub id: String,
32    /// The set of processing steps applied
33    pub methods: Vec<ProcessingMethod>,
34}
35
36impl_param_described!(ProcessingMethod);
37
38impl DataProcessing {
39    pub fn push(&mut self, method: ProcessingMethod) {
40        self.methods.push(method)
41    }
42
43    pub fn iter(&self) -> std::slice::Iter<'_, ProcessingMethod> {
44        self.methods.iter()
45    }
46
47    pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, ProcessingMethod> {
48        self.methods.iter_mut()
49    }
50
51    pub fn len(&self) -> usize {
52        self.methods.len()
53    }
54
55    pub fn is_empty(&self) -> bool {
56        self.methods.is_empty()
57    }
58
59    pub fn highest_order(&self) -> i8 {
60        self.iter().map(|p| p.order).max().unwrap_or_default()
61    }
62
63    pub fn remove(&mut self, index: usize) -> ProcessingMethod {
64        self.methods.remove(index)
65    }
66}
67
68/// A root type for data transformations
69#[derive(Debug, Clone, PartialEq)]
70pub enum DataTransformationAction {
71    FormatConversion(FormatConversion),
72    DataProcessingAction(DataProcessingAction),
73    Other(Param),
74}
75
76impl Display for DataTransformationAction {
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        write!(f, "{:?}", self)
79    }
80}
81
82/// A compile time checkable list mapping to [`MS:1000543|data processing action`](http://purl.obolibrary.org/obo/MS_1000543)
83#[derive(Debug, Clone, Copy, PartialEq, Hash)]
84pub enum DataProcessingAction {
85    Deisotoping,
86    ChargeDeconvolution,
87    PeakPicking,
88    Smoothing,
89    BaselineReduction,
90    ChargeStateCalculation,
91    PrecursorRecalculation,
92    IntensityNormalization,
93    MZCalibration,
94    DataFiltering,
95    AdductDeconvolution,
96    IonMobilityDeconvolution,
97}
98
99impl From<DataProcessingAction> for Param {
100    fn from(value: DataProcessingAction) -> Self {
101        value.as_param_const().into()
102    }
103}
104
105impl From<DataProcessingAction> for ParamCow<'static> {
106    fn from(value: DataProcessingAction) -> Self {
107        value.as_param_const()
108    }
109}
110
111impl Display for DataProcessingAction {
112    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113        write!(f, "{:?}", self)
114    }
115}
116
117impl DataProcessingAction {
118    pub const fn as_param_const(&self) -> ParamCow<'static> {
119        const CV: ControlledVocabulary = ControlledVocabulary::MS;
120
121        match self {
122            DataProcessingAction::Deisotoping => CV.const_param_ident("deisotoping", 1000033),
123            DataProcessingAction::ChargeDeconvolution => {
124                CV.const_param_ident("charge deconvolution", 1000034)
125            }
126            DataProcessingAction::PeakPicking => CV.const_param_ident("peak picking", 1000035),
127            DataProcessingAction::Smoothing => CV.const_param_ident("smoothing", 1000592),
128            DataProcessingAction::BaselineReduction => {
129                CV.const_param_ident("baseline reduction", 1000593)
130            }
131            DataProcessingAction::ChargeStateCalculation => {
132                CV.const_param_ident("charge state calculation", 1000778)
133            }
134            DataProcessingAction::PrecursorRecalculation => {
135                CV.const_param_ident("precursor recalculation", 1000780)
136            }
137            DataProcessingAction::IntensityNormalization => {
138                CV.const_param_ident("intensity normalization", 1001484)
139            }
140            DataProcessingAction::MZCalibration => CV.const_param_ident("m/z calibration", 1001485),
141            DataProcessingAction::DataFiltering => CV.const_param_ident("data filtering", 1001486),
142            DataProcessingAction::AdductDeconvolution => {
143                CV.const_param_ident("adduct deconvolution", 1003220)
144            }
145            DataProcessingAction::IonMobilityDeconvolution => {
146                CV.const_param_ident("ion mobility deconvolution", 1003222)
147            }
148        }
149    }
150
151    pub const fn from_accession(accession: u32) -> Option<DataProcessingAction> {
152        match accession {
153            1000033 => Some(DataProcessingAction::Deisotoping),
154            1000034 => Some(DataProcessingAction::ChargeDeconvolution),
155            1000035 => Some(DataProcessingAction::PeakPicking),
156            1000592 => Some(DataProcessingAction::Smoothing),
157            1000593 => Some(DataProcessingAction::BaselineReduction),
158            1000778 => Some(DataProcessingAction::ChargeStateCalculation),
159            1000780 => Some(DataProcessingAction::PrecursorRecalculation),
160            1001484 => Some(DataProcessingAction::IntensityNormalization),
161            1001485 => Some(DataProcessingAction::MZCalibration),
162            1001486 => Some(DataProcessingAction::DataFiltering),
163            1003220 => Some(DataProcessingAction::AdductDeconvolution),
164            1003222 => Some(DataProcessingAction::IonMobilityDeconvolution),
165            _ => None,
166        }
167    }
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Hash)]
171pub enum FormatConversion {
172    ConversionToMzML,
173    ConversionToMzMLb,
174}
175
176impl Display for FormatConversion {
177    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178        write!(f, "{:?}", self)
179    }
180}
181
182impl From<FormatConversion> for Param {
183    fn from(value: FormatConversion) -> Self {
184        value.to_param_const().into()
185    }
186}
187
188impl From<FormatConversion> for ParamCow<'static> {
189    fn from(value: FormatConversion) -> Self {
190        value.to_param_const()
191    }
192}
193
194impl FormatConversion {
195    pub const fn to_param_const(&self) -> ParamCow<'static> {
196        const CV: ControlledVocabulary = ControlledVocabulary::MS;
197
198        match self {
199            FormatConversion::ConversionToMzML => {
200                CV.const_param_ident("Conversion to mzML", 1000544)
201            }
202            FormatConversion::ConversionToMzMLb => {
203                CV.const_param_ident("Conversion to mzMLb", 1002839)
204            }
205        }
206    }
207
208    pub const fn from_accession(accession: u32) -> Option<FormatConversion> {
209        match accession {
210            1000544 => Some(Self::ConversionToMzML),
211            1002839 => Some(Self::ConversionToMzMLb),
212            _ => None,
213        }
214    }
215}