def added_atoms(session, atoms, to_atoms): amap = {(a.residue.chain_id, a.residue.number, a.name): a for a in atoms} from chimerax.atomic import Atoms added = Atoms([ a for a in to_atoms if (a.residue.chain_id, a.residue.number, a.name) not in amap ]) session.selection.clear() added.selected = True session.logger.status('Added %d atoms' % len(added), log=True) return added
def replace_residue(session, residue, new_residue_name): block_if_sim_running(session) from chimerax.core.errors import UserError from chimerax.isolde.cmd import isolde_start isolde_start(session) from chimerax.atomic import Residues if isinstance(residue, Residues): if len(residue) != 1: raise UserError('Must have a single residue selected!') residue = residue[0] if len(residue.neighbors): raise UserError( 'Replacement by graph matching is currently only ' 'supported for ligands with no covalent bonds to other residues!') from ..template_utils import (fix_residue_from_template, fix_residue_to_match_md_template) from chimerax import mmcif try: cif_template = mmcif.find_template_residue(session, new_residue_name) except: err_str = ( 'Could not find a mmCIF template for residue name {}. ' 'For novel residues not in the Chemical Components Dictionary, ' 'you will need to provide this first.').format(new_residue_name) raise UserError(err_str) fix_residue_from_template(residue, cif_template, rename_residue=True, match_by='element') ff = session.isolde.forcefield_mgr[session.isolde.sim_params.forcefield] ligand_db = session.isolde.forcefield_mgr.ligand_db( session.isolde.sim_params.forcefield) from chimerax.isolde.openmm.openmm_interface import find_residue_templates from chimerax.atomic import Residues tdict = find_residue_templates(Residues([residue]), ff, ligand_db=ligand_db, logger=session.logger) md_template_name = tdict.get(0) if md_template_name is not None: fix_residue_to_match_md_template(session, residue, ff._templates[md_template_name], cif_template=cif_template) from chimerax.atomic import Atoms, Atom chiral_centers = Atoms( [a for a in residue.atoms if residue.ideal_chirality(a.name) != 'N']) if len(chiral_centers): warn_str = ( 'Rebuilt ligand {} has chiral centres at atoms {} ' '(highlighted). Since the current algorithm used to match topologies ' 'is not chirality aware, you should check these sites carefully to ' 'ensure they are sensible. If in doubt, it is best to delete with ' '"del #{}/{}:{}{}" and replace with "isolde add ligand {}".' ).format(residue.name, ','.join(chiral_centers.names), residue.structure.id_string, residue.chain_id, residue.number, residue.insertion_code, residue.name) session.selection.clear() chiral_centers.selected = True chiral_centers.draw_modes = Atom.BALL_STYLE from chimerax.isolde.view import focus_on_selection focus_on_selection(session, chiral_centers) session.logger.warning(warn_str)
def select_pick(self, pick, set_sel): if set_sel: self.session.selection.clear() if pick: atoms = Atoms() bonds = Bonds() if not hasattr(pick, "__iter__"): pick = [pick] first_selected = None for p in pick: if isinstance(p, PickedAtoms): for atom in p.atoms: if atom in atoms: continue connected_atoms = get_fragment( atom, max_len=atom.structure.num_atoms) atoms = atoms.merge(connected_atoms) if first_selected is None: first_selected = atoms[0].selected elif isinstance(p, PickedAtom): if p.atom in atoms: continue connected_atoms = get_fragment( p.atom, max_len=p.atom.structure.num_atoms) atoms = atoms.merge(connected_atoms) if first_selected is None: first_selected = atoms[0].selected elif isinstance(p, PickedBonds): for bond in p.bonds: if bond.atoms[0] in atoms: continue connected_atoms = get_fragment( bond.atoms[0], max_len=bond.structure.num_atoms) atoms = atoms.merge(connected_atoms) if first_selected is None: first_selected = atoms[0].selected elif isinstance(p, PickedBond): if p.bond.atoms[0] in atoms: continue connected_atoms = get_fragment( p.bond.atoms[0], max_len=p.bond.structure.num_atoms) atoms = atoms.merge(connected_atoms) if first_selected is None: first_selected = atoms[0].selected elif isinstance(p, PickedResidues): for res in p.residues: for atom in res: if atom in atoms: continue connected_atoms = get_fragment( atom, max_len=res.structure.num_atoms) atoms = atoms.merge(connected_atoms) if first_selected is None: first_selected = atoms[0].selected elif isinstance(p, PickedResidue): for atom in p.residue.atoms: if atoms in atoms: continue connected_atoms = get_fragment( atom, max_len=p.residue.structure.num_atoms) atoms = atoms.merge(connected_atoms) if first_selected is None: first_selected = atoms[0].selected for atom in atoms: for neighbor, bond in zip(atom.neighbors, atom.bonds): bonds = bonds.merge(Bonds([bond])) if first_selected is not None: atoms.selected = not first_selected bonds.selected = not first_selected else: run(self.session, "select clear")