Source code for nanome.beta.nanome_sdk.session.bonding

import logging
import subprocess
import tempfile
from nanome.api.structure import Bond, Complex
from nanome.util import Logs
from distutils.spawn import find_executable


logger = logging.getLogger(__name__)


[docs]class Bonding:
[docs] @classmethod def start(cls, complex_list): """Start the bonding process.""" for input_comp in complex_list: # is_conformer = len(next(input_comp.atoms).in_conformer) > 1 # input_comp.convert_to_frames() input_file = tempfile.NamedTemporaryFile(suffix='.pdb', delete=False) output_file = tempfile.NamedTemporaryFile(suffix='.mol', delete=False) input_comp.io.to_pdb(input_file.name) popen = cls.start_bonding_process(input_file.name, output_file.name) popen.wait() bonded_comp = Complex.io.from_sdf(path=output_file.name) assert len(list(input_comp.molecules)) == len(list(bonded_comp.molecules)) for input_mol, bonded_mol in zip(input_comp.molecules, bonded_comp.molecules): assert sum(1 for _ in input_mol.atoms) == sum(1 for _ in bonded_mol.atoms) cls._match_and_bond(input_mol, bonded_mol)
[docs] @classmethod def start_bonding_process(cls, input_filepath: str, output_filepath: str): NANOBABEL_PATH = find_executable('nanobabel') OBABEL_PATH = find_executable('obabel') Logs.debug(f'OBABEL_PATH={OBABEL_PATH}') cmd = [] if OBABEL_PATH: cmd = [OBABEL_PATH, '-ipdb', input_filepath, '-osdf', '-O' + output_filepath] elif NANOBABEL_PATH: cmd = [NANOBABEL_PATH, 'bonding', '-i', input_filepath, '-o', output_filepath] if cmd: proc = subprocess.Popen(cmd) return proc else: raise Exception("Bonding program not found.")
@staticmethod def _match_and_bond(unbonded_mol, bonded_mol): """Copy all the bonds from bonded_mol to unbonded_mol.""" # Serial numbering may be different between the two complexes, # so make mapping of atoms based on position bonded_serial_to_unbonded_atom = dict() def sort_key(atm): return str(atm.position.unpack()) # noqa: E731 sorted_unbonded_atoms = sorted(list(unbonded_mol.atoms), key=sort_key) sorted_bonded_atoms = sorted(list(bonded_mol.atoms), key=sort_key) for unbonded_atom, bonded_atom in zip(sorted_unbonded_atoms, sorted_bonded_atoms): assert unbonded_atom.position.unpack() == bonded_atom.position.unpack() bonded_serial_to_unbonded_atom[bonded_atom.serial] = unbonded_atom # make bonds for each atom in unbonded_mol for bond in bonded_mol.bonds: serial1 = bond._atom1._serial serial2 = bond._atom2._serial if serial1 > serial2: serial1, serial2 = serial2, serial1 if serial1 in bonded_serial_to_unbonded_atom and serial2 in bonded_serial_to_unbonded_atom: atom1 = bonded_serial_to_unbonded_atom[serial1] atom2 = bonded_serial_to_unbonded_atom[serial2] residue = atom1._residue new_bond = None for old_bond in atom1.bonds: if old_bond._atom2 == atom2: new_bond = old_bond break if new_bond is None: new_bond = Bond._create() new_bond._kind = bond._kind new_bond._atom1 = atom1 new_bond._atom2 = atom2 residue._add_bond(new_bond)