Source code for schrodinger.ui.sketcher_extensions

from schrodinger.forcefield import OPLSVersion
from schrodinger.structutils import minimize
from schrodinger.thirdparty import rdkit_adapter

CONSTRAINT_FORCE_CONSTANT = 200.0
COORDINATES_LIMIT = 10000000.0


[docs]def get_2D_structure(sketcher): """ :param sketcher: given sketcher instance :return: extracted Structure object with sketcher-generated 2D coordinates """ rdmol = sketcher.getRDKitStructure() return rdkit_adapter.from_rdkit(rdmol)
[docs]def get_3D_structure(sketcher): """ :param sketcher: given sketcher instance :return: extracted Structure object with sketcher-generated 3D coordinates :raises RuntimeError: if 3D coordinates are not available """ rdmol = sketcher.getRDKitStructure() if rdmol.GetNumConformers() < 2: raise RuntimeError("No 3D coordinates available") # 3D coordinates should be in the second conformer st = rdkit_adapter.from_rdkit(rdmol, conformer=1) # mmffld minization has a hard time with many atoms overlapping # at the same position; update atoms with invalid coordinates # to the 2D coordinates generated by the sketcher, and freeze all others fixed_atom_indices = [] st_2d = get_2D_structure(sketcher) for atom in st.atom: if any(c > COORDINATES_LIMIT for c in (atom.x, atom.y, atom.z)): atom.xyz = st_2d.atom[atom.index].xyz else: fixed_atom_indices.append(atom.index) if len(fixed_atom_indices) == st.atom_total: return st minimizer = minimize.Minimizer(ffld_version=OPLSVersion.F16, struct=st, honor_pbc=False, nonbonded_cutoff=10.0) for index in fixed_atom_indices: minimizer.addPosRestraint(index, force_constant=CONSTRAINT_FORCE_CONSTANT) minimizer.minimize() return st
[docs]def set_structure(sketcher, st): """ :param sketcher: given sketcher instance :param st: Structure to set into the sketcher """ rdmol = rdkit_adapter.to_rdkit(st, implicitH=True, sanitize=False) sketcher.clearStructure() sketcher.setStructure(rdmol)