use crate::raw::msscan::SpectrumParams;
use byteorder::{ByteOrder, LittleEndian};
#[derive(Debug, Clone)]
pub struct PeakSpectrum {
pub mz: Vec<f64>,
pub intensity: Vec<f32>,
}
pub fn decode_peak_block(bytes: &[u8], params: &SpectrumParams) -> crate::Result<PeakSpectrum> {
let point_count = params.point_count as usize;
let expected_len = match params.format_id {
3 => point_count * 12,
2 => point_count * 12,
_ => {
return Err(crate::Error::Parse(format!(
"Unknown peak format ID: {}",
params.format_id
)))
}
};
if bytes.len() < expected_len {
return Err(crate::Error::Parse("Truncated MSPeak.bin block".into()));
}
let mut mz = Vec::with_capacity(point_count);
let mut intensity = Vec::with_capacity(point_count);
if params.format_id == 3 {
for i in 0..point_count {
let offset = i * 12;
mz.push(LittleEndian::read_f64(&bytes[offset..offset + 8]));
intensity.push(LittleEndian::read_f32(&bytes[offset + 8..offset + 12]));
}
} else if params.format_id == 2 {
for i in 0..point_count {
let offset = i * 8;
let mz_raw = LittleEndian::read_f64(&bytes[offset..offset + 8]);
mz.push(mz_raw / 100.0);
}
let int_start = point_count * 8;
for i in 0..point_count {
let offset = int_start + i * 4;
intensity.push(LittleEndian::read_f32(&bytes[offset..offset + 4]));
}
}
Ok(PeakSpectrum { mz, intensity })
}