use super::params::MMFFParams;
use crate::ff::mmff::tables::{mmff_angle, mmff_def, mmff_oop};
pub(crate) fn typify_bond(t1: u32, t2: u32, bond_order: f64, params: &MMFFParams) -> u32 {
if (bond_order - 1.5).abs() < 0.1 {
return 1; }
if bond_order < 1.25 {
let p1_sbmb = params.get_prop(t1).map(|p| p.sbmb).unwrap_or(0);
let p2_sbmb = params.get_prop(t2).map(|p| p.sbmb).unwrap_or(0);
if p1_sbmb == 1 && p2_sbmb == 1 {
return 1;
}
}
0
}
pub(crate) fn typify_angle(bt_ij: u32, bt_jk: u32) -> u32 {
match (bt_ij, bt_jk) {
(0, 0) => 0,
(1, 0) | (0, 1) => 1,
(1, 1) => 2,
_ => 0,
}
}
pub(crate) fn typify_dihedral(bt_ij: u32, bt_jk: u32, bt_kl: u32) -> u32 {
if bt_jk == 1 {
return 1;
}
if bt_ij == 1 && bt_kl == 1 {
return 2;
}
0
}
pub(crate) fn resolve_angle_label(angle_type: u32, ti: u32, tj: u32, tk: u32) -> String {
let (at, j) = (angle_type as u8, tj as u8);
let (i, k) = (ti as u8, tk as u8);
for level in 0..4 {
let (mut ci, mut ck) = (eq_level(i, level), eq_level(k, level));
if ci > ck {
std::mem::swap(&mut ci, &mut ck);
}
if mmff_angle(at, ci, j, ck).is_some() {
return format!("{at}_{ci}_{j}_{ck}");
}
}
let (lo, hi) = if i <= k { (i, k) } else { (k, i) };
format!("{at}_{lo}_{j}_{hi}")
}
fn eq_level(atom_type: u8, level: usize) -> u8 {
mmff_def(atom_type)
.map(|d| d.eq_level[level])
.unwrap_or(atom_type)
}
pub(crate) fn resolve_oop_label(center: u32, periph: [u32; 3]) -> Option<String> {
let j = center as u8;
let p = [periph[0] as u8, periph[1] as u8, periph[2] as u8];
for level in 0..4 {
let mut ikl = [
eq_level(p[0], level),
eq_level(p[1], level),
eq_level(p[2], level),
];
ikl.sort_unstable();
if mmff_oop(ikl[0], j, ikl[1], ikl[2]).is_some() {
return Some(format!("{}_{}_{}_{}", ikl[0], j, ikl[1], ikl[2]));
}
}
None
}