use crate::{
errors::ParseTprError,
structures::{Precision, TprHeader},
};
use super::xdr::XdrFile;
impl TprHeader {
pub(super) fn parse(xdrfile: &mut XdrFile) -> Result<TprHeader, ParseTprError> {
let gromacs_version = xdrfile.read_string_4byte()?;
if !gromacs_version.contains("VERSION") {
return Err(ParseTprError::NotTpr);
}
let precision = match xdrfile.read_i32()? {
4 => Precision::Single,
8 => Precision::Double,
x => return Err(ParseTprError::UnsupportedPrecision(x)),
};
let tpr_version = xdrfile.read_i32()?;
if tpr_version < 103 {
return Err(ParseTprError::UnsupportedVersion(tpr_version));
}
let tpr_generation = xdrfile.read_i32()?;
let file_tag = xdrfile.read_string_4byte()?;
let n_atoms = xdrfile.read_i32()?;
let n_coupling_groups = xdrfile.read_i32()?;
let fep_state = xdrfile.read_i32()?;
let lambda = xdrfile.read_real(precision)?;
let has_input_record = xdrfile.read_bool_header()?;
let has_topology = xdrfile.read_bool_header()?;
let has_positions = xdrfile.read_bool_header()?;
let has_velocities = xdrfile.read_bool_header()?;
let has_forces = xdrfile.read_bool_header()?;
let has_box = xdrfile.read_bool_header()?;
let body_size = if tpr_version >= 119 && tpr_generation >= 27 {
Some(xdrfile.read_i64()?)
} else {
None
};
Ok(TprHeader {
gromacs_version,
precision,
tpr_version,
tpr_generation,
file_tag,
n_atoms,
n_coupling_groups,
fep_state,
lambda,
has_input_record,
has_topology,
has_positions,
has_velocities,
has_forces,
has_box,
body_size,
})
}
}