diff --git a/src/io.rs b/src/io.rs index ed0ae09..85e3087 100644 --- a/src/io.rs +++ b/src/io.rs @@ -27,7 +27,8 @@ pub use crate::io::mzmlb::{MzMLbError, MzMLbReader}; pub use crate::io::offset_index::OffsetIndex; pub use crate::io::traits::{ MZFileReader, RandomAccessSpectrumIterator, SpectrumSource, SpectrumWriter, SpectrumAccessError, - SpectrumGrouping, SpectrumIterator, StreamingSpectrumIterator, + SpectrumGrouping, SpectrumIterator, StreamingSpectrumIterator, SpectrumReceiver, RandomAccessSpectrumSource, + SpectrumSourceWithMetadata, MemorySpectrumSource, RandomAccessSpectrumGroupingIterator, }; pub use crate::io::utils::{DetailLevel, PreBufferedStream, checksum_file}; pub use compression::RestartableGzDecoder; diff --git a/src/io/mgf.rs b/src/io/mgf.rs index e3e3249..b9c91c1 100644 --- a/src/io/mgf.rs +++ b/src/io/mgf.rs @@ -200,12 +200,12 @@ pub struct MGFReaderType< pub state: MGFParserState, pub offset: usize, pub error: Option, - pub index: OffsetIndex, + index: OffsetIndex, file_description: FileDescription, instrument_configurations: HashMap, softwares: Vec, data_processings: Vec, - pub run: MassSpectrometryRun, + run: MassSpectrometryRun, pub detail_level: DetailLevel, centroid_type: PhantomData, deconvoluted_type: PhantomData, @@ -672,6 +672,9 @@ impl< } } + +/// The MGF format does not contain any consistent metadata, but additional +/// information can be included after creation. impl< R: io::Read, C: CentroidPeakAdapting + From, @@ -712,7 +715,7 @@ const TITLE_CV: CURIE = ControlledVocabulary::MS.curie(1000796); const MS_LEVEL_CV: CURIE = ControlledVocabulary::MS.curie(1000511); const MSN_SPECTRUM_CV: CURIE = ControlledVocabulary::MS.curie(1000580); -/// An MGF writer type +/// An MGF writer type that only writes centroided MSn spectra pub struct MGFWriterType< W: io::Write, C: CentroidPeakAdapting + From = CentroidPeak, @@ -957,7 +960,6 @@ impl< } impl< - 'a, W: io::Write, C: CentroidPeakAdapting + From + 'static, D: DeconvolutedPeakAdapting + From + 'static, diff --git a/src/lib.rs b/src/lib.rs index 5a13b13..9f7daf5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,10 +23,11 @@ //! ```rust //! use std::fs; //! use mzdata::prelude::*; -//! use mzpeaks::{Tolerance, prelude::*}; +//! use mzpeaks::Tolerance; //! use mzdata::io::MzMLReader; -//! use mzdata::spectrum::{SignalContinuity}; -//! let reader = MzMLReader::new(fs::File::open("./test/data/small.mzML").unwrap()); +//! use mzdata::spectrum::SignalContinuity; +//! +//! let reader = MzMLReader::open_path("./test/data/small.mzML").unwrap(); //! for spectrum in reader { //! println!("Scan {} => BP {}", spectrum.id(), spectrum.peaks().base_peak().mz); //! diff --git a/src/meta.rs b/src/meta.rs index 8fe5ad4..242dd9a 100644 --- a/src/meta.rs +++ b/src/meta.rs @@ -10,8 +10,11 @@ mod run; mod traits; pub use data_processing::{DataProcessing, ProcessingMethod}; +pub use software::Software; + pub use file_description::{FileDescription, SourceFile}; + pub use instrument::{Component, ComponentType, InstrumentConfiguration}; -pub use software::Software; + pub use traits::MSDataFileMetadata; pub use run::MassSpectrometryRun; diff --git a/src/meta/data_processing.rs b/src/meta/data_processing.rs index e1c1317..4e7df9f 100644 --- a/src/meta/data_processing.rs +++ b/src/meta/data_processing.rs @@ -4,6 +4,11 @@ use std::fmt::Display; use crate::impl_param_described; use crate::params::{ControlledVocabulary, Param, ParamCow, ParamList}; +use super::Software; + +/// Describe a data processing method stage tied to a specific piece of [`Software`] +/// +/// See #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct ProcessingMethod { pub order: i8, @@ -11,6 +16,10 @@ pub struct ProcessingMethod { pub params: ParamList, } +/// Describe a complete data processing method, a series of [`ProcessingMethod`] transformations +/// through a pipeline of [`Software`]. +/// +/// See #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct DataProcessing { pub id: String, diff --git a/src/meta/software.rs b/src/meta/software.rs index 6eee6d2..05a9a78 100644 --- a/src/meta/software.rs +++ b/src/meta/software.rs @@ -1,6 +1,8 @@ use crate::impl_param_described; use crate::params::ParamList; +/// A piece of software that was associated with the acquisition, transformation or otherwise +/// processing of mass spectrometry data. See #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct Software { /// A unique identifier for the software within processing metadata diff --git a/src/meta/traits.rs b/src/meta/traits.rs index 2d30497..cac032b 100644 --- a/src/meta/traits.rs +++ b/src/meta/traits.rs @@ -75,36 +75,52 @@ pub trait MSDataFileMetadata { #[macro_export] /// Assumes a field for the non-`Option` facets of the [`MSDataFileMetadata`] -/// implementation are present. +/// implementation are present. Passing an extra level `extended` token implements +/// the optional methods. macro_rules! impl_metadata_trait { + (extended) => { + $crate::impl_metadata_trait(); + + fn spectrum_count_hint(&self) -> Option { + self.num_spectra + } + + fn run_description(&self) -> Option<&$crate::meta::MassSpectrometryRun> { + Some(&self.run) + } + + fn run_description_mut(&mut self) -> Option<&mut $crate::meta::MassSpectrometryRun> { + Some(&mut self.run) + } + }; () => { - fn data_processings(&self) -> &Vec { + fn data_processings(&self) -> &Vec<$crate::meta::DataProcessing> { &self.data_processings } - fn instrument_configurations(&self) -> &HashMap { + fn instrument_configurations(&self) -> &std::collections::HashMap { &self.instrument_configurations } - fn file_description(&self) -> &FileDescription { + fn file_description(&self) -> &$crate::meta::FileDescription { &self.file_description } - fn softwares(&self) -> &Vec { + fn softwares(&self) -> &Vec<$crate::meta::Software> { &self.softwares } - fn data_processings_mut(&mut self) -> &mut Vec { + fn data_processings_mut(&mut self) -> &mut Vec<$crate::meta::DataProcessing> { &mut self.data_processings } - fn instrument_configurations_mut(&mut self) -> &mut HashMap { + fn instrument_configurations_mut(&mut self) -> &mut std::collections::HashMap { &mut self.instrument_configurations } - fn file_description_mut(&mut self) -> &mut FileDescription { + fn file_description_mut(&mut self) -> &mut $crate::meta::FileDescription { &mut self.file_description } - fn softwares_mut(&mut self) -> &mut Vec { + fn softwares_mut(&mut self) -> &mut Vec<$crate::meta::Software> { &mut self.softwares } }; @@ -112,39 +128,55 @@ macro_rules! impl_metadata_trait { #[macro_export] -/// Delegates the implementation of [`MSDataFileMetadata`] to an field +/// Delegates the implementation of [`MSDataFileMetadata`] to a member. Passing an extra +/// level `extended` token implements the optional methods. macro_rules! delegate_impl_metadata_trait { + ($src:tt, extended) => { + $crate::delegate_impl_metadata_trait($src); + + fn spectrum_count_hint(&self) -> Option { + self.$src.spectrum_count_hint() + } + + fn run_description(&self) -> Option<&$crate::meta::MassSpectrometryRun> { + self.$src.run_description() + } + + fn run_description_mut(&mut self) -> Option<&mut $crate::meta::MassSpectrometryRun> { + self.$src.run_description_mut() + } + }; ($src:tt) => { - fn data_processings(&self) -> &Vec { + fn data_processings(&self) -> &Vec<$crate::meta::DataProcessing> { self.$src.data_processings() } - fn instrument_configurations(&self) -> &std::collections::HashMap { + fn instrument_configurations(&self) -> &std::collections::HashMap { self.$src.instrument_configurations() } - fn file_description(&self) -> &crate::meta::FileDescription { + fn file_description(&self) -> &$crate::meta::FileDescription { self.$src.file_description() } - fn softwares(&self) -> &Vec { + fn softwares(&self) -> &Vec<$crate::meta::Software> { self.$src.softwares() } - fn data_processings_mut(&mut self) -> &mut Vec { + fn data_processings_mut(&mut self) -> &mut Vec<$crate::meta::DataProcessing> { self.$src.data_processings_mut() } - fn instrument_configurations_mut(&mut self) -> &mut std::collections::HashMap { + fn instrument_configurations_mut(&mut self) -> &mut std::collections::HashMap { self.$src.instrument_configurations_mut() } - fn file_description_mut(&mut self) -> &mut crate::meta::FileDescription { + fn file_description_mut(&mut self) -> &mut $crate::meta::FileDescription { self.$src.file_description_mut() } - fn softwares_mut(&mut self) -> &mut Vec { + fn softwares_mut(&mut self) -> &mut Vec<$crate::meta::Software> { self.$src.softwares_mut() } @@ -152,11 +184,11 @@ macro_rules! delegate_impl_metadata_trait { self.$src.spectrum_count_hint() } - fn run_description(&self) -> Option<&crate::meta::MassSpectrometryRun> { + fn run_description(&self) -> Option<&$crate::meta::MassSpectrometryRun> { self.$src.run_description() } - fn run_description_mut(&mut self) -> Option<&mut crate::meta::MassSpectrometryRun> { + fn run_description_mut(&mut self) -> Option<&mut $crate::meta::MassSpectrometryRun> { self.$src.run_description_mut() } diff --git a/src/params.rs b/src/params.rs index d71d570..e5406f8 100644 --- a/src/params.rs +++ b/src/params.rs @@ -668,6 +668,8 @@ impl ParamDescribed for ParamList { } } +/// Implement the [`ParamDescribed`] trait for type `$t`, referencing a `params` member +/// of type `Vec<`[`Param`]`>`. #[macro_export] macro_rules! impl_param_described { ($($t:ty), +) => {$( @@ -687,6 +689,9 @@ macro_rules! impl_param_described { #[doc(hidden)] pub const _EMPTY_PARAM: &[Param] = &[]; +/// Implement the [`ParamDescribed`] trait for type `$t`, referencing a `params` member +/// that is an `Option>` that will lazily be initialized automatically +/// when it is accessed mutably. #[macro_export] macro_rules! impl_param_described_deferred { ($($t:ty), +) => {$( @@ -722,6 +727,7 @@ pub enum Unit { MZ, Mass, PartsPerMillion, + Nanometer, // Time diff --git a/src/spectrum.rs b/src/spectrum.rs index ed83899..2cb1459 100644 --- a/src/spectrum.rs +++ b/src/spectrum.rs @@ -32,15 +32,15 @@ The [`SpectrumDescription`] trait is included in the crate prelude, and gives th read-only access to components that describe a spectrum's metadata. ```rust -use std::fs::File; +use mzpeaks::Tolerance; +use mzdata::MzMLReader; use mzdata::prelude::*; -use mzpeaks::{Tolerance, prelude::*}; -use mzdata::io::MzMLReader; -use mzdata::spectrum::{SignalContinuity}; +use mzdata::spectrum::SignalContinuity; -let reader = MzMLReader::new(File::open("./test/data/small.mzML").unwrap()); +let reader = MzMLReader::open_path("./test/data/small.mzML").unwrap(); for spectrum in reader { println!("Scan {} => BP {}", spectrum.id(), spectrum.peaks().base_peak().mz); + if spectrum.signal_continuity() < SignalContinuity::Profile { let peak_picked = spectrum.into_centroid().unwrap(); println!("Matches for 579.155: {:?}",