pub use dnoise_core::msms::{
MsmsKeep, MsmsKeepBuilder, MsmsKeepParts, PrecursorSpectrum, combine_and_filter,
};
use crate::error::{DnoiseError, Result};
use crate::frame::FlatFrame;
use crate::params::{HaloParams, MsmsFilterParams};
use crate::tdf::{FrameMeta, PasefWindow};
use crate::tsr::FrameReader;
use rayon::prelude::*;
use std::collections::HashSet;
pub(crate) fn build_msms_keep(
reader: &FrameReader,
meta: &[FrameMeta],
windows: &[PasefWindow],
params: &MsmsFilterParams,
halo: Option<&HaloParams>,
cancel: Option<&std::sync::atomic::AtomicBool>,
) -> Result<MsmsKeep> {
let mut builder = MsmsKeepBuilder::new(windows);
for (i, m) in meta.iter().enumerate() {
if cancel.is_some_and(|c| c.load(std::sync::atomic::Ordering::Relaxed)) {
return Err(DnoiseError::Cancelled);
}
if m.num_peaks == 0 || !builder.wants_frame(m.id) {
continue;
}
let frame = reader.get(i).map_err(|e| DnoiseError::FrameRead {
index: i,
message: e.to_string(),
})?;
builder.add_frame(m.id, &FlatFrame::from_frame(&frame));
}
let fp = params.as_filter_params();
let (spectra, parts) = builder.into_spectra();
let keep: Vec<HashSet<u64>> = spectra
.into_par_iter()
.map(|s| {
if cancel.is_some_and(|c| c.load(std::sync::atomic::Ordering::Relaxed)) {
return Err(DnoiseError::Cancelled);
}
Ok(s.filter(&fp, halo))
})
.collect::<Result<_>>()?;
Ok(parts.finish(keep))
}