use ndarray::Array1;
use readcon_core::iterators::read_first_frame;
use crate::error::SaddleError;
use crate::mic::Cell;
pub struct MolecularFrame {
pub positions: Array1<f64>,
pub masses: Array1<f64>,
pub cell: Option<Cell>,
}
pub fn frame_from_con(path: impl AsRef<std::path::Path>) -> Result<MolecularFrame, SaddleError> {
let frame = read_first_frame(path.as_ref()).map_err(|e| SaddleError::Surface(e.to_string()))?;
let n = frame.positions.nrows();
if n == 0 || frame.positions.ncols() != 3 {
return Err(SaddleError::Shape("CON frame must be N by 3".into()));
}
let mut positions = Array1::zeros(n * 3);
for i in 0..n {
let row = frame.positions.as_f64_row(i);
positions[3 * i] = row[0];
positions[3 * i + 1] = row[1];
positions[3 * i + 2] = row[2];
}
let masses = if frame.masses.len() == n {
Array1::from((0..n).map(|i| frame.masses.get_f64(i)).collect::<Vec<_>>())
} else {
Array1::ones(n)
};
let boxl = frame.header.boxl;
let cell = if boxl.iter().all(|l| *l > 0.0) {
Cell::ortho(boxl[0], boxl[1], boxl[2]).ok()
} else {
None
};
Ok(MolecularFrame {
positions,
masses,
cell,
})
}