use molrs::Atomistic;
use crate::ff::forcefield::ForceField;
use crate::ff::forcefield::readers::{ForceFieldReader, opls::OplsXmlReader};
use crate::ff::potential::{Potentials, intramolecular_pairs};
use super::Typifier;
pub mod assign;
pub mod deps;
pub mod layered;
pub mod meta;
pub mod typing;
pub use assign::{
BondedTerm, CandidateTables, Estimator, NoMatch, typify_bonded, typify_bonded_with,
};
pub use meta::{LAYER_PRIORITY_STRIDE, OplsTypeRow, OplsTypingMeta};
pub use typing::typify_atoms;
pub struct OPLSAATypifier {
meta: OplsTypingMeta,
ff: ForceField,
tables: CandidateTables,
no_match: NoMatch,
}
impl OPLSAATypifier {
pub fn from_xml_str(xml: &str) -> Result<Self, String> {
let meta = crate::ff::forcefield::xml::read_opls_typing_xml_str(xml)?;
let ff = OplsXmlReader::new().read_str(xml)?;
Ok(Self::new(meta, ff))
}
pub fn oplsaa() -> Result<Self, String> {
Self::from_xml_str(molrs::data::OPLSAA_XML)
}
pub fn new(meta: OplsTypingMeta, ff: ForceField) -> Self {
let tables = CandidateTables::build(&ff, &meta);
Self {
meta,
ff,
tables,
no_match: NoMatch::Error,
}
}
pub fn with_strict(mut self, strict: bool) -> Self {
self.no_match = if strict {
NoMatch::Error
} else {
NoMatch::Skip
};
self
}
pub fn meta(&self) -> &OplsTypingMeta {
&self.meta
}
pub fn ff(&self) -> &ForceField {
&self.ff
}
fn typify_labeled_graph(&self, mol: &Atomistic) -> Result<Atomistic, String> {
let typed = typify_atoms(mol, &self.meta, &self.ff)?;
typify_bonded(&typed, &self.tables, self.no_match)
}
pub fn typify(&self, mol: &Atomistic) -> Result<Atomistic, String> {
self.typify_labeled_graph(mol)
}
pub fn build(&self, mol: &Atomistic) -> Result<Potentials, String> {
let mut frame = self.typify(mol)?.to_frame();
let pairs = intramolecular_pairs(&frame);
frame.insert("pairs", pairs);
self.ff.to_potentials(&frame)
}
}
impl Typifier for OPLSAATypifier {
type Mol = Atomistic;
fn typify(&self, mol: &Atomistic) -> Result<Atomistic, String> {
OPLSAATypifier::typify(self, mol)
}
}