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#[derive(Debug, Clone, PartialEq)]
69pub enum DataTransformationAction {
70    FormatConversion(FormatConversion),
71    DataProcessingAction(DataProcessingAction),
72    Other(Param),
73}
74
75impl Display for DataTransformationAction {
76    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77        write!(f, "{:?}", self)
78    }
79}
80
81#[derive(Debug, Clone, Copy, PartialEq, Hash)]
82pub enum DataProcessingAction {
83    Deisotoping,
84    ChargeDeconvolution,
85    PeakPicking,
86    Smoothing,
87    BaselineReduction,
88    ChargeStateCalculation,
89    PrecursorRecalculation,
90    IntensityNormalization,
91    MZCalibration,
92    DataFiltering,
93    AdductDeconvolution,
94    IonMobilityDeconvolution,
95}
96
97impl From<DataProcessingAction> for Param {
98    fn from(value: DataProcessingAction) -> Self {
99        value.as_param_const().into()
100    }
101}
102
103impl From<DataProcessingAction> for ParamCow<'static> {
104    fn from(value: DataProcessingAction) -> Self {
105        value.as_param_const()
106    }
107}
108
109impl Display for DataProcessingAction {
110    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111        write!(f, "{:?}", self)
112    }
113}
114
115impl DataProcessingAction {
116    pub const fn as_param_const(&self) -> ParamCow<'static> {
117        const CV: ControlledVocabulary = ControlledVocabulary::MS;
118
119        match self {
120            DataProcessingAction::Deisotoping => CV.const_param_ident("deisotoping", 1000033),
121            DataProcessingAction::ChargeDeconvolution => {
122                CV.const_param_ident("charge deconvolution", 1000034)
123            }
124            DataProcessingAction::PeakPicking => CV.const_param_ident("peak picking", 1000035),
125            DataProcessingAction::Smoothing => CV.const_param_ident("smoothing", 1000592),
126            DataProcessingAction::BaselineReduction => {
127                CV.const_param_ident("baseline reduction", 1000593)
128            }
129            DataProcessingAction::ChargeStateCalculation => {
130                CV.const_param_ident("charge state calculation", 1000778)
131            }
132            DataProcessingAction::PrecursorRecalculation => {
133                CV.const_param_ident("precursor recalculation", 1000780)
134            }
135            DataProcessingAction::IntensityNormalization => {
136                CV.const_param_ident("intensity normalization", 1001484)
137            }
138            DataProcessingAction::MZCalibration => CV.const_param_ident("m/z calibration", 1001485),
139            DataProcessingAction::DataFiltering => CV.const_param_ident("data filtering", 1001486),
140            DataProcessingAction::AdductDeconvolution => {
141                CV.const_param_ident("adduct deconvolution", 1003220)
142            }
143            DataProcessingAction::IonMobilityDeconvolution => {
144                CV.const_param_ident("ion mobility deconvolution", 1003222)
145            }
146        }
147    }
148
149    pub const fn from_accession(accession: u32) -> Option<DataProcessingAction> {
150        match accession {
151            1000033 => Some(DataProcessingAction::Deisotoping),
152            1000034 => Some(DataProcessingAction::ChargeDeconvolution),
153            1000035 => Some(DataProcessingAction::PeakPicking),
154            1000592 => Some(DataProcessingAction::Smoothing),
155            1000593 => Some(DataProcessingAction::BaselineReduction),
156            1000778 => Some(DataProcessingAction::ChargeStateCalculation),
157            1000780 => Some(DataProcessingAction::PrecursorRecalculation),
158            1001484 => Some(DataProcessingAction::IntensityNormalization),
159            1001485 => Some(DataProcessingAction::MZCalibration),
160            1001486 => Some(DataProcessingAction::DataFiltering),
161            1003220 => Some(DataProcessingAction::AdductDeconvolution),
162            1003222 => Some(DataProcessingAction::IonMobilityDeconvolution),
163            _ => None,
164        }
165    }
166}
167
168#[derive(Debug, Clone, Copy, PartialEq, Hash)]
169pub enum FormatConversion {
170    ConversionToMzML,
171    ConversionToMzMLb,
172}
173
174impl Display for FormatConversion {
175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
176        write!(f, "{:?}", self)
177    }
178}
179
180impl From<FormatConversion> for Param {
181    fn from(value: FormatConversion) -> Self {
182        value.to_param_const().into()
183    }
184}
185
186impl From<FormatConversion> for ParamCow<'static> {
187    fn from(value: FormatConversion) -> Self {
188        value.to_param_const()
189    }
190}
191
192impl FormatConversion {
193    pub const fn to_param_const(&self) -> ParamCow<'static> {
194        const CV: ControlledVocabulary = ControlledVocabulary::MS;
195
196        match self {
197            FormatConversion::ConversionToMzML => {
198                CV.const_param_ident("Conversion to mzML", 1000544)
199            }
200            FormatConversion::ConversionToMzMLb => {
201                CV.const_param_ident("Conversion to mzMLb", 1002839)
202            }
203        }
204    }
205
206    pub const fn from_accession(accession: u32) -> Option<FormatConversion> {
207        match accession {
208            1000544 => Some(Self::ConversionToMzML),
209            1002839 => Some(Self::ConversionToMzMLb),
210            _ => None,
211        }
212    }
213}