#[derive(Debug, Clone)]
pub struct FlatFrame {
pub frame_id: usize,
pub num_scans: usize,
pub scan: Vec<u32>,
pub tof: Vec<u32>,
pub intensity: Vec<u32>,
}
impl FlatFrame {
pub fn from_frame(frame: &timsrust::Frame) -> Self {
let num_scans = frame.scan_offsets.len().saturating_sub(1);
let n = frame.tof_indices.len();
let mut scan = Vec::with_capacity(n);
for s in 0..num_scans {
let count = frame.scan_offsets[s + 1] - frame.scan_offsets[s];
scan.extend(std::iter::repeat_n(s as u32, count));
}
Self {
frame_id: frame.index,
num_scans,
scan,
tof: frame.tof_indices.clone(),
intensity: frame.intensities.clone(),
}
}
pub fn len(&self) -> usize {
self.tof.len()
}
pub fn is_empty(&self) -> bool {
self.tof.is_empty()
}
pub fn survivors(&self, keep: &[bool]) -> Vec<(u32, u32, u32)> {
(0..self.len())
.filter(|&i| keep[i])
.map(|i| (self.scan[i], self.tof[i], self.intensity[i]))
.collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
fn frame(scan: Vec<u32>, tof: Vec<u32>, intensity: Vec<u32>) -> FlatFrame {
FlatFrame {
frame_id: 0,
num_scans: 4,
scan,
tof,
intensity,
}
}
#[test]
fn len_and_is_empty() {
assert_eq!(frame(vec![], vec![], vec![]).len(), 0);
assert!(frame(vec![], vec![], vec![]).is_empty());
let g = frame(vec![0, 1], vec![10, 20], vec![1, 2]);
assert_eq!(g.len(), 2);
assert!(!g.is_empty());
}
#[test]
fn survivors_selects_kept_points_in_order() {
let f = frame(vec![0, 1, 2], vec![100, 200, 300], vec![5, 6, 7]);
assert_eq!(
f.survivors(&[true, false, true]),
vec![(0, 100, 5), (2, 300, 7)]
);
}
#[test]
fn survivors_empty_when_nothing_kept() {
let f = frame(vec![0], vec![1], vec![1]);
assert!(f.survivors(&[false]).is_empty());
}
#[test]
fn from_frame_expands_csr_offsets_into_per_point_scans() {
let src = timsrust::Frame {
scan_offsets: vec![0, 2, 2, 3],
tof_indices: vec![10, 11, 12],
intensities: vec![100, 101, 102],
index: 7,
..Default::default()
};
let flat = FlatFrame::from_frame(&src);
assert_eq!(flat.frame_id, 7);
assert_eq!(flat.num_scans, 3);
assert_eq!(flat.scan, vec![0, 0, 2]);
assert_eq!(flat.tof, vec![10, 11, 12]);
assert_eq!(flat.intensity, vec![100, 101, 102]);
assert_eq!(flat.len(), 3);
}
#[test]
fn from_frame_handles_an_empty_frame() {
let src = timsrust::Frame {
scan_offsets: vec![0, 0, 0],
..Default::default()
};
let flat = FlatFrame::from_frame(&src);
assert_eq!(flat.num_scans, 2);
assert!(flat.is_empty());
}
}