use readcon_core::index_proj::{self, FrameIndexProjection};
use readcon_core::types::ConFrame;
pub use index_proj::{
finite_energy, frame_cell_volume, frame_composition_formula, frame_fmax, frame_total_mass,
sections_present_mask, FrameIndexProjection as CoreFrameIndexProjection, SECTIONS_MASK_ENERGIES,
SECTIONS_MASK_FORCES, SECTIONS_MASK_VELOCITIES,
};
pub fn project_frame(frame: &ConFrame) -> FrameIndexProjection {
FrameIndexProjection::from_frame(frame)
}
pub fn frame_pbc_mask(frame: &ConFrame) -> Option<u8> {
let p = frame.header.pbc()?;
Some(crate::keys::pbc_mask_from_bools(p))
}
pub fn frame_time(frame: &ConFrame) -> Option<f64> {
project_frame(frame).time
}
pub fn frame_timestep(frame: &ConFrame) -> Option<f64> {
project_frame(frame).timestep
}
pub fn frame_frame_index(frame: &ConFrame) -> Option<f64> {
project_frame(frame).frame_index
}
pub fn frame_neb_bead(frame: &ConFrame) -> Option<f64> {
project_frame(frame).neb_bead
}
pub fn frame_neb_band(frame: &ConFrame) -> Option<f64> {
project_frame(frame).neb_band
}
pub fn frame_charge(frame: &ConFrame) -> Option<f64> {
project_frame(frame).charge
}
pub fn frame_magmom(frame: &ConFrame) -> Option<f64> {
project_frame(frame).magmom
}
#[cfg(test)]
mod tests {
use super::*;
use readcon_core::iterators::ConFrameIterator;
use std::path::PathBuf;
#[test]
fn mass_and_volume_from_fixture() {
let p = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../readcon-core/resources/test/tiny_cuh2.con");
let text = std::fs::read_to_string(p).unwrap();
let fr = ConFrameIterator::new(&text).next().unwrap().unwrap();
let m = frame_total_mass(&fr);
assert!(m.is_some_and(|x| x > 0.0));
let v = frame_cell_volume(&fr).unwrap();
assert!(v > 0.0);
let [a, b, c] = fr.header.boxl;
let expected = a * b * c;
assert!((v - expected).abs() < 1e-4 * expected.max(1.0));
}
}