use std::collections::HashSet;
use crate::core::{interactor, utils};
pub struct Air(Vec<interactor::Interactor>);
impl Air {
pub fn new(interactors: Vec<interactor::Interactor>) -> Self {
Air(interactors)
}
pub fn find_partners(
&self,
interactor: &interactor::Interactor,
) -> Vec<&interactor::Interactor> {
self.0
.iter()
.filter(|x| x.target().contains(&interactor.id()) && x.id() != interactor.id())
.collect()
}
pub fn gen_tbl(&self) -> Result<String, &str> {
let mut tbl = String::new();
for interactor in self.0.iter() {
match interactor.is_valid() {
Ok(_) => (),
Err(err) => {
eprintln!("## Interactor {} is not valid ##", interactor.id());
return Err(err);
}
}
let partners = self.find_partners(interactor);
if partners.is_empty() {
continue;
}
let target_res = interactor::collect_residues(partners);
let block = interactor.create_block(target_res);
tbl.push_str(&block);
}
Ok(tbl)
}
pub fn gen_pml(&self, output_f: &str) {
let mut pml = String::new();
pml.push_str("set label_size, 0\n");
pml.push_str("set dash_gap, 0\n");
pml.push_str("set dash_color, yellow\n");
let mut active: HashSet<(i16, &str)> = HashSet::new();
let mut passive: HashSet<(i16, &str)> = HashSet::new();
for interactor in self.0.iter() {
let partners = self.find_partners(interactor);
if partners.is_empty() {
continue;
}
interactor.active().iter().for_each(|r| {
active.insert((*r, interactor.chain()));
});
let target_res = interactor::collect_residues(partners);
target_res.iter().for_each(|r| {
let resnum = r.res_number.unwrap_or(0);
passive.insert((resnum, r.chain_id));
});
let block = interactor.make_pml_string(target_res);
pml.push_str(&block);
}
pml.push_str("color white\n");
passive.iter().for_each(|(resnum, chain)| {
pml.push_str(format!("color green, (resi {} and chain {})\n", resnum, chain).as_str())
});
active.iter().for_each(|(resnum, chain)| {
pml.push_str(format!("color red, (resi {} and chain {})\n", resnum, chain).as_str())
});
utils::write_string_to_file(&pml, output_f).expect("Could not write pml")
}
}
fn _append_header(index: usize) -> String {
format!(
"!========================================!\n\
! HADDOCK AIR restraints for selection {} !\n\
!========================================!\n",
index + 1
)
}