use crate::{
errors::ParseTprError,
structures::{Atom, Bond, Precision},
};
use super::{moltypes::MoleculeType, xdr::XdrFile};
#[derive(Debug, Clone)]
pub(super) struct MolBlock {
pub molecule_type: i32,
pub n_molecules: i32,
}
impl MolBlock {
pub(super) fn parse(
xdrfile: &mut XdrFile,
precision: Precision,
) -> Result<Self, ParseTprError> {
let molecule_type = xdrfile.read_i32()?;
let n_molecules = xdrfile.read_i32()?;
xdrfile.jump(4)?;
for _ in 0..2 {
let n_posres = xdrfile.read_i32()?;
xdrfile.skip_multiple_reals(precision, crate::DIM as i64 * n_posres as i64)?;
}
Ok(MolBlock {
molecule_type,
n_molecules,
})
}
pub(super) fn unpack2molecules(
&self,
molecule_types: &[MoleculeType],
atom_counter: &mut i32,
residue_counter: &mut i32,
) -> Result<(Vec<Atom>, Vec<Bond>), ParseTprError> {
let moltype = match molecule_types.get(self.molecule_type as usize) {
Some(x) => x,
None => return Err(ParseTprError::CouldNotConstructTopology),
};
let mut atoms = Vec::with_capacity(moltype.atoms.len() * self.n_molecules as usize);
let mut bonds = Vec::new();
for _ in 0..self.n_molecules {
let (new_atoms, new_bonds) = moltype.unpack2molecule(atom_counter, residue_counter)?;
atoms.extend(new_atoms);
bonds.extend(new_bonds);
}
Ok((atoms, bonds))
}
}