示例#1
0
def get_atom_surface_areas(molecule, surface):
    """
    """
    # create empty array to hold area values for all triangles
    areas = oechem.OEFloatArray(surface.GetNumTriangles())

    # fill array with calculated surface areas
    oespicoli.OECalculateTriangleAreas(surface, areas)

    # create empty array to hold atom surface areas
    atom_areas = oechem.OEFloatArray(molecule.GetMaxAtomIdx())

    # fill array with surface contributions for each atom
    for i in xrange(surface.GetNumTriangles()):

        # get the triangle elements
        v1 = surface.GetTrianglesElement(i * 3)
        v2 = surface.GetTrianglesElement(i * 3 + 1)
        v3 = surface.GetTrianglesElement(i * 3 + 2)

        # get the atom indices for each triangle element
        a1 = surface.GetAtomsElement(v1)
        a2 = surface.GetAtomsElement(v2)
        a3 = surface.GetAtomsElement(v3)

        atom_areas[a1] += areas[i] / 3.0
        atom_areas[a2] += areas[i] / 3.0
        atom_areas[a3] += areas[i] / 3.0

    return np.array(atom_areas)
示例#2
0
def generate_grid_conformers(molecule,
                             dihedrals,
                             intervals,
                             max_rotation=360,
                             copy_mol=True):
    """
    Generate conformers using torsion angle grids.

    Parameters
    ----------
    molecule: OEMol
    dihedrals: list of
    intervals

    Returns
    -------

    """
    # molecule must be mapped
    if copy_mol:
        molecule = copy.deepcopy(molecule)
    if cmiles.utils.has_atom_map(molecule):
        remove_map(molecule)
    else:
        raise ValueError("Molecule must have map indices")

    # Check length of dihedrals match length of intervals

    conf_mol = generate_conformers(molecule, max_confs=1)
    conf = conf_mol.GetConfs().next()
    coords = oechem.OEFloatArray(conf.GetMaxAtomIdx() * 3)
    conf.GetCoords(coords)

    torsions = [[conf_mol.GetAtom(oechem.OEHasMapIdx(i + 1)) for i in dih]
                for dih in dihedrals]

    for i, tor in enumerate(torsions):
        copy_conf_mol = copy.deepcopy(conf_mol)
        conf_mol.DeleteConfs()
        for conf in copy_conf_mol.GetConfs():
            coords = oechem.OEFloatArray(conf.GetMaxAtomIdx() * 3)
            conf.GetCoords(coords)
            for angle in range(5, max_rotation + 5, intervals[i]):
                newconf = conf_mol.NewConf(coords)
                oechem.OESetTorsion(newconf, tor[0], tor[1], tor[2], tor[3],
                                    radians(angle))

    restore_map(conf_mol)
    return conf_mol
示例#3
0
def setPositionsInOEMol(oemol, positions):
    """Set the positions in an OEMol using a position array with units from simtk.unit, i.e. from OpenMM. Atoms must have same order.

    Arguments:
    ---------
    oemol : OEMol
        OpenEye molecule
    positions : Nx3 array
        Unit-bearing via simtk.unit Nx3 array of coordinates
    """
    warnings.warn(DEPRECATION_WARNING_TEXT, PendingDeprecationWarning)

    from openeye import oechem

    if oemol.NumAtoms() != len(positions):
        raise ValueError(
            "Number of atoms in molecule does not match length of position array."
        )
    pos_unitless = positions / unit.angstroms

    coordlist = []
    for idx in range(len(pos_unitless)):
        for j in range(3):
            coordlist.append(pos_unitless[idx][j])
    oemol.SetCoords(oechem.OEFloatArray(coordlist))
示例#4
0
def GetMolDetails(mol, label):
    """
    Parameters
    ----------
    mol: single OEChem conformer with coordinates
    label: string - name of the molecule. Can be an empty string.

    Returns
    -------
    optinfo: string - Turbomole input file for autoDefine.py
    xinfo:   string - XYZ format coordinates to feed into Turbomole's x2t

    """
    optinfo = ("$title %s" % label)
    optinfo += ("\n$charge %d" % oechem.OENetCharge(mol))
    optinfo += ("\n$end")

    xinfo = ("%d\n" % mol.NumAtoms())
    xyz = oechem.OEFloatArray(3)
    # get coordinates of each atom
    for atom in mol.GetAtoms():
        mol.GetCoords(atom, xyz)
        xinfo+=( '\n  %s %10.4f %10.4f  %10.4f' \
                  %(oechem.OEGetAtomicSymbol(atom.GetAtomicNum()),
                  xyz[0], xyz[1], xyz[2]) )
    return optinfo, xinfo
示例#5
0
def test_oemol_nhfcl():
    """Test coordinates for NHFCl read in as OEMol."""

    import openeye.oechem as oechem
    import openeye.oeomega as oeomega
    # coordinates for N, F, H, Cl respectively
    # generated after minimization with improper phase of 150 degrees
    coordlist = [
        0.155, -0.088, -0.496, -1.054, -0.776, -0.340, -0.025, 0.906, -0.516,
        1.689, -0.635, -1.263
    ]
    # create OEMol
    mol = oechem.OEMol()
    oechem.OESmilesToMol(mol, 'FNCl')
    omega = oeomega.OEOmega()
    omega.SetMaxConfs(1)
    omega.SetIncludeInput(False)
    omega.SetStrictStereo(False)
    status = omega(mol)
    oechem.OETriposAtomTypes(mol)
    oechem.OETriposAtomNames(mol)
    oechem.OEAddExplicitHydrogens(mol)
    # set provided coordinates
    mol.SetCoords(oechem.OEFloatArray(coordlist))
    # calculate and check improper angle
    crds, names = find_improper_angles(mol)
    ang = calc_improper_angle(crds[0][0], crds[0][1], crds[0][2], crds[0][3])
    if abs(ang - 15.0) > 0.1 and abs(ang - 165.0) > 0.1:
        raise Exception(
            "Error calculating improper of test OEMol. Calculated {} degrees, but should be 15 or 165 degrees."
            .format(ang))
示例#6
0
文件: run.py 项目: AspirinCode/nagl
def process_molecule(smiles: str) -> Tuple[Optional[Molecule], Optional[str]]:

    error = None

    try:
        oe_molecule = smiles_to_molecule(smiles, guess_stereochemistry=True)

        # Generate a set of conformers and charges for the molecule.
        conformers = ConformerGenerator.generate(oe_molecule,
                                                 ConformerSettings())
        charges = ChargeGenerator.generate(oe_molecule, conformers,
                                           ChargeSettings())

        # Add the charges and conformers to the OE object.
        for oe_atom in oe_molecule.GetAtoms():
            oe_atom.SetPartialCharge(charges[oe_atom.GetIdx()].item())

        oe_molecule.DeleteConfs()

        for conformer in conformers:
            oe_molecule.NewConf(oechem.OEFloatArray(conformer.flatten()))

        # Map to an OpenFF molecule object.
        molecule = Molecule.from_openeye(oe_molecule)

        # Compute the WBOs
        molecule.assign_fractional_bond_orders(
            "am1-wiberg", use_conformers=molecule.conformers)

    except (BaseException, Exception) as e:
        molecule = None
        error = f"Failed to process {smiles}: {str(e)}"

    return molecule, error
示例#7
0
def main(argv=[__name__]):
    if len(argv) != 3:
        oechem.OEThrow.Usage("%s <molfile.pdb> <out.srf>" % argv[0])

    mol = oechem.OEGraphMol()
    ifs = oechem.oemolistream(argv[1])
    oechem.OEReadMolecule(ifs, mol)
    if not oechem.OEHasResidues(mol):
        oechem.OEPerceiveResidues(mol, oechem.OEPreserveResInfo_All)

    serials = {}
    for atom in mol.GetAtoms():
        res = oechem.OEAtomGetResidue(atom)
        serials[res.GetSerialNumber()] = atom

    outsurf = oespicoli.OESurface()
    center = oechem.OEFloatArray(3)
    for line in open(argv[1]):
        if line.startswith("ANISOU"):
            serno, factors = ParseFactors(line)
            if serno in serials:
                mol.GetCoords(serials[serno], center)
                surf = GetEllipsoidalSurface(center, factors)
                oespicoli.OEAddSurfaces(outsurf, surf)

    oespicoli.OEWriteSurface(argv[2], outsurf)
示例#8
0
def GetSzmapEnergies(lig, prot):
    """
    run szmap at ligand coordinates in the protein context
    @rtype : None
    @param lig: mol defining coordinates for szmap calcs
    @param prot: context mol for szmap calcs (must have charges and radii)
    """

    print("num\tatom\t%s\t%s\t%s\t%s\t%s" %
          (oeszmap.OEGetEnsembleName(oeszmap.OEEnsemble_NeutralDiffDeltaG),
           oeszmap.OEGetEnsembleName(oeszmap.OEEnsemble_PSolv),
           oeszmap.OEGetEnsembleName(oeszmap.OEEnsemble_WSolv),
           oeszmap.OEGetEnsembleName(oeszmap.OEEnsemble_VDW),
           oeszmap.OEGetEnsembleName(oeszmap.OEEnsemble_OrderParam)))

    coord = oechem.OEFloatArray(3)

    sz = oeszmap.OESzmapEngine(prot)
    rslt = oeszmap.OESzmapResults()

    for i, atom in enumerate(lig.GetAtoms()):
        lig.GetCoords(atom, coord)

        if not oeszmap.OEIsClashing(sz, coord):
            oeszmap.OECalcSzmapResults(rslt, sz, coord)

            print("%2d\t%s\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f" %
                  (i, atom.GetName(),
                   rslt.GetEnsembleValue(oeszmap.OEEnsemble_NeutralDiffDeltaG),
                   rslt.GetEnsembleValue(oeszmap.OEEnsemble_PSolv),
                   rslt.GetEnsembleValue(oeszmap.OEEnsemble_WSolv),
                   rslt.GetEnsembleValue(oeszmap.OEEnsemble_VDW),
                   rslt.GetEnsembleValue(oeszmap.OEEnsemble_OrderParam)))
        else:
            print("%2d\t%s CLASH" % (i, atom.GetName()))
示例#9
0
def molecule_from_record(record: MoleculeESPRecord) -> Molecule:
    """Converts an ``openff-recharge`` ESP record to to an Open Force Field
    molecule."""

    oe_molecule = oechem.OEMol()
    oechem.OESmilesToMol(oe_molecule, record.tagged_smiles)
    ordered_conformer = reorder_conformer(oe_molecule, record.conformer)

    # Clear the records index map.
    for atom in oe_molecule.GetAtoms():
        atom.SetMapIdx(0)

    oe_molecule.DeleteConfs()
    oe_molecule.NewConf(oechem.OEFloatArray(ordered_conformer.flatten()))

    with NamedTemporaryFile(suffix=".mol2") as file:

        # Workaround for stereochemistry being incorrectly perceived.
        molecule = Molecule.from_openeye(oe_molecule,
                                         allow_undefined_stereo=True)

        molecule.to_file(file.name, "mol2")
        molecule = molecule.from_file(file.name)

    return molecule
示例#10
0
def GenerateSzmapProbes(oms, cumulativeProb, lig, prot):
    """
    generate multiconf probes and data-rich points at ligand coords
    @rtype : None
    @param oms: output mol stream for points and probes
    @param cumulativeProb: cumulative probability for cutoff of point set
    @param lig: mol defining coordinates for szmap calcs
    @param prot: context mol for szmap calcs (must have charges and radii)
    """

    coord = oechem.OEFloatArray(3)

    sz = oeszmap.OESzmapEngine(prot)
    rslt = oeszmap.OESzmapResults()

    points = oechem.OEGraphMol()
    points.SetTitle("points %s" % lig.GetTitle())

    probes = oechem.OEMol()

    for i, atom in enumerate(lig.GetAtoms()):
        lig.GetCoords(atom, coord)

        if not oeszmap.OEIsClashing(sz, coord):
            oeszmap.OECalcSzmapResults(rslt, sz, coord)

            rslt.PlaceNewAtom(points)

            clear = False
            rslt.PlaceProbeSet(probes, cumulativeProb, clear)

    oechem.OEWriteMolecule(oms, points)
    oechem.OEWriteMolecule(oms, probes)
示例#11
0
def optSMIRNOFF(input_Mol, FF_file, output_mol2, log ):
    """

    Creates OpenMM Topology, System, and initial positions of given molecule.

    Parameters
    ----------
    Mol: an OEChem molecule
    FF_file: string name of *.ffxml file with path
    output_mol2: string path/filename.mol2 to save output structure
    log: open file to write output data to

    Returns
    -------
    Boolean: True if output is successfully created

    """
    # make copy of the input_Mol
    Mol = oechem.OEMol(input_Mol)

    # check that the *.ffxml file exists
    if not os.path.exists(FF_file):
        log.write("Cannot find the ffxml file (%s)!\n"\
                % FF_file)
        return

    ff = forcefield.ForceField(FF_file)
    top, syst, pos  = ff_utils.create_system_from_molecule(ff, Mol, verbose = False)

    ### minimize with OpenMM and return the final coordinates in the OEform
    min_pos = minimizeOpenMM(top, syst, pos)
    Mol.SetCoords(oechem.OEFloatArray(min_pos))

    return writeUpdatedMol(Mol, output_mol2, log)
示例#12
0
    def _create_receptor(self):
        """Create an OpenEye receptor from a mol2 file.

        Returns
        -------
        openeye.oedocking.OEReceptor
            The OpenEye receptor object.
        """
        from openeye import oechem, oedocking

        input_stream = oechem.oemolistream(self.receptor_coordinate_file)

        original_receptor_molecule = oechem.OEGraphMol()
        oechem.OEReadMolecule(input_stream, original_receptor_molecule)

        center_of_mass = oechem.OEFloatArray(3)
        oechem.OEGetCenterOfMass(original_receptor_molecule, center_of_mass)

        receptor = oechem.OEGraphMol()
        oedocking.OEMakeReceptor(
            receptor,
            original_receptor_molecule,
            center_of_mass[0],
            center_of_mass[1],
            center_of_mass[2],
        )

        return receptor
示例#13
0
def main(argv=[__name__]):
    if len(argv) != 3:
        oechem.OEThrow.Usage("%s <molfile> <queryfile>" % sys.argv[0])

    molfs = oechem.oemolistream(sys.argv[1])
    mol = oechem.OEGraphMol()
    oechem.OEReadMolecule(molfs, mol)

    if oechem.OEGetFileExtension(sys.argv[2]) != "sq":
        oechem.OEThrow.Fatal(
            "Only can write shape query to .sq output file format")

    # Use OEOverlapPrep to remove hydrogens and add
    # color atoms to the molecule
    prep = oeshape.OEOverlapPrep()
    prep.Prep(mol)

    # Get the color atoms, create gaussians and add them
    # to the shape query
    query = oeshape.OEShapeQuery()
    for atom in oeshape.OEGetColorAtoms(mol):
        coords = oechem.OEFloatArray(3)
        mol.GetCoords(atom, coords)
        gauss = oegrid.OEGaussian(1.0, 1.0, coords,
                                  oeshape.OEGetColorType(atom))
        query.AddColorGaussian(gauss)

    # Remove color atoms from the molecule and add to the query
    oeshape.OERemoveColorAtoms(mol)
    query.SetMolecule(mol)

    oeshape.OEWriteShapeQuery(sys.argv[2], query)
    print("shape query created")
示例#14
0
def to_mapped_xyz(molecule,
                  atom_map=None,
                  conformer=None,
                  xyz_format=True,
                  filename=None):
    """
    Generate xyz coordinates for molecule in the order given by the atom_map. atom_map is a dictionary that maps the
    tag on the SMILES to the atom idex in OEMol.
    Parameters
    ----------
    molecule: OEMol with conformers
    atom_map: dict
        maps tag in SMILES to atom index
    conformer: int
        Which conformer to write xyz file for. If None, write out all conformers. Default is None
    xyz_format: bool
        If True, will write out number of atoms and molecule name. If false, will only write out elements and coordinates
    filename: str
        Name of file to save to. If None, only returns a string.

    Returns
    -------
    str: elements and xyz coordinates (in angstroms) in order of tagged SMILES

    """
    if not atom_map and not cmiles.utils.has_atom_map(molecule):
        raise ValueError(
            "If molecule does not have atom map, you must provide an atom map")
    if not has_conformer(molecule, check_two_dimension=True):
        raise ValueError("Molecule must have conformers")
    xyz = ""
    for k, mol in enumerate(molecule.GetConfs()):
        if k == conformer or conformer is None:
            if xyz_format:
                xyz += "{}\n".format(mol.GetMaxAtomIdx())
                xyz += "{}\n".format(mol.GetTitle())
            coords = oechem.OEFloatArray(mol.GetMaxAtomIdx() * 3)
            mol.GetCoords(coords)
            if k != 0 and not xyz_format:
                xyz += "*"

            for mapping in range(1, molecule.NumAtoms() + 1):
                if not atom_map:
                    atom = molecule.GetAtom(oechem.OEHasMapIdx(mapping))
                    idx = atom.GetIdx()
                else:
                    idx = atom_map[mapping]
                    atom = mol.GetAtom(oechem.OEHasAtomIdx(idx))
                syb = oechem.OEGetAtomicSymbol(atom.GetAtomicNum())
                xyz += "  {}      {:05.3f}   {:05.3f}   {:05.3f}\n".format(
                    syb, coords[idx * 3], coords[idx * 3 + 1],
                    coords[idx * 3 + 2])

    if filename:
        file = open("{}.xyz".format(filename), 'w')
        file.write(xyz)
        file.close()
    else:
        return xyz
示例#15
0
def mol_from_json(symbols, connectivity, geometry, permute_xyz=False):
    """
    Generate OEMol from QCSchema molecule specs
    Parameters
    ----------
    inp_molecule: dict
        Must have symbols and connectivity and/or geometry
        Note: If geometry is given, the molecule will have a tag indicating that the goemetry came from QCSchema. This
        will ensure that the order of the atoms and configuration is not change for generation of mapped SMILES and
        isomeric SMILES.

    Returns
    -------
    molecule: OEMol

    """

    molecule = oechem.OEMol()
    for s in symbols:
        molecule.NewAtom(_symbols[s])

    # Add connectivity
    for bond in connectivity:
        a1 = molecule.GetAtom(oechem.OEHasAtomIdx(bond[0]))
        a2 = molecule.GetAtom(oechem.OEHasAtomIdx(bond[1]))
        bond_order = bond[-1]
        if not isinstance(bond_order, int) and not bond_order.is_integer():
            raise ValueError(
                "bond order must be a whole number. A bond order of 1.5 is not allowed"
            )
        molecule.NewBond(a1, a2, int(bond_order))

    # Add geometry
    if molecule.NumAtoms() != geometry.shape[0] / 3:
        raise ValueError(
            "Number of atoms in molecule does not match length of position array"
        )

    molecule.SetCoords(oechem.OEFloatArray(geometry))
    molecule.SetDimension(3)

    if not permute_xyz:
        # Add tag that the geometry is from JSON and shouldn't be changed.
        geom_tag = oechem.OEGetTag("json_geometry")
        molecule.SetData(geom_tag, True)
    oechem.OEDetermineConnectivity(molecule)
    oechem.OEFindRingAtomsAndBonds(molecule)
    # No need to perceive Bond Order because the information was added from the connectivity table. Apparently, this
    # function does many different perceptions under the hood and it can add implicit hydrogens to divalent N that should be negatively charged.
    #oechem.OEPerceiveBondOrders(molecule)
    # This seems to add hydrogens that are not in the json
    #oechem.OEAssignImplicitHydrogens(molecule)
    oechem.OEAssignFormalCharges(molecule)
    oechem.OEAssignAromaticFlags(molecule)
    oechem.OEPerceiveChiral(molecule)
    oechem.OE3DToAtomStereo(molecule)
    oechem.OE3DToBondStereo(molecule)

    return molecule
示例#16
0
    def doAlignSs(self, unique=True, maxMatches=20):
        """Test the SS comparison between current reference and fit molecules -
        Return list of corresponding atoms on success or an empty list otherwise.
        """
        atomMapL = []
        fitAtomUnMappedL = []
        #
        nAtomsRef = self.__refmol.NumAtoms()
        nAtomsFit = self.__fitmol.NumAtoms()
        # -------
        oechem.OEAddExplicitHydrogens(self.__refmol)
        oechem.OEAddExplicitHydrogens(self.__fitmol)
        fitAtD = {}
        #
        for at in self.__fitmol.GetAtoms():
            nAtL = at.GetAtoms()
            neighbors = [nAt.GetName() for nAt in nAtL]
            atType = oechem.OEGetAtomicSymbol(at.GetAtomicNum())
            xyzL = oechem.OEFloatArray(3)
            self.__fitmol.GetCoords(at, xyzL)
            fitAtD[at.GetIdx()] = AlignAtomUnMapped(
                fitId=self.__fitId,
                fitAtIdx=at.GetIdx(),
                fitAtName=at.GetName(),
                fitAtType=atType,
                fitAtNo=at.GetAtomicNum(),
                fitAtFormalCharge=at.GetFormalCharge(),
                x=xyzL[0],
                y=xyzL[1],
                z=xyzL[2],
                fitNeighbors=neighbors,
            )

        #
        logger.debug("nAtomsRef %d nAtomsFit %d", nAtomsRef, nAtomsFit)
        #
        # --------
        self.__setupSubStructure(self.__refmol)
        self.__ss.SetMaxMatches(maxMatches)
        miter = self.__ss.Match(self.__fitmol, unique)
        if miter.IsValid():
            match = miter.Target()
            for mAt in match.GetAtoms():
                atomMapL.append(
                    AlignAtomMap(
                        refId=self.__refId,
                        refAtIdx=mAt.pattern.GetIdx(),
                        refAtNo=mAt.pattern.GetAtomicNum(),
                        refAtName=mAt.pattern.GetName(),
                        fitId=self.__fitId,
                        fitAtIdx=mAt.target.GetIdx(),
                        fitAtNo=mAt.target.GetAtomicNum(),
                        fitAtName=mAt.target.GetName(),
                    )
                )
                fitAtD.pop(mAt.target.GetIdx())
            logger.debug("fitAtD %r", fitAtD)
        fitAtomUnMappedL = list(fitAtD.values())
        return (nAtomsRef, self.__refFD, nAtomsFit, self.__fitFD, atomMapL, fitAtomUnMappedL)
示例#17
0
def GetEllipsoidalSurface(center, factors):
    surf = oespicoli.OESurface()
    dir1 = oechem.OEFloatArray(3)
    dir1[0] = factors[0]
    dir1[1] = factors[3]
    dir1[2] = factors[4]
    dir2 = oechem.OEFloatArray(3)
    dir2[0] = factors[3]
    dir2[1] = factors[1]
    dir2[2] = factors[5]
    dir3 = oechem.OEFloatArray(3)
    dir3[0] = factors[4]
    dir3[1] = factors[5]
    dir3[2] = factors[2]
    oespicoli.OEMakeEllipsoidSurface(surf, center, 10.0, 10.0, 10.0, dir1,
                                     dir2, dir3, 4)
    return surf
示例#18
0
    def doAlignMcss(self, unique=True, minFrac=1.0, useExhaustive=True):
        """Test the MCSS comparison between current reference and fit molecules -
        Return list of corresponding atoms on success or an empty list otherwise.
        """
        atomMapL = []
        fitAtomUnMappedL = []
        #
        nAtomsRef = self.__refmol.NumAtoms()
        nAtomsFit = self.__fitmol.NumAtoms()
        fitAtD = {}
        for at in self.__fitmol.GetAtoms():
            nAtL = at.GetAtoms()
            neighbors = [nAt.GetName() for nAt in nAtL]
            atType = oechem.OEGetAtomicSymbol(at.GetAtomicNum())
            xyzL = oechem.OEFloatArray(3)
            self.__fitmol.GetCoords(at, xyzL)
            fitAtD[at.GetIdx()] = AlignAtomUnMapped(
                fitId=self.__fitId,
                fitAtIdx=at.GetIdx(),
                fitAtName=at.GetName(),
                fitAtType=atType,
                fitAtNo=at.GetAtomicNum(),
                fitAtFormalCharge=at.GetFormalCharge(),
                x=xyzL[0],
                y=xyzL[1],
                z=xyzL[2],
                fitNeighbors=neighbors,
            )
        minAtoms = int(min(nAtomsRef, nAtomsFit) * minFrac)
        # -------
        self.__setupMCSS(self.__refmol, useExhaustive=useExhaustive)
        self.__mcss.SetMCSFunc(oechem.OEMCSMaxAtoms())
        self.__mcss.SetMinAtoms(minAtoms)
        oechem.OEAddExplicitHydrogens(self.__refmol)
        oechem.OEAddExplicitHydrogens(self.__fitmol)
        #
        # --------
        miter = self.__mcss.Match(self.__fitmol, unique)
        if miter.IsValid():
            match = miter.Target()
            for mAt in match.GetAtoms():

                atomMapL.append(
                    AlignAtomMap(
                        refId=self.__refId,
                        refAtIdx=mAt.pattern.GetIdx(),
                        refAtNo=mAt.pattern.GetAtomicNum(),
                        refAtName=mAt.pattern.GetName(),
                        fitId=self.__fitId,
                        fitAtIdx=mAt.target.GetIdx(),
                        fitAtNo=mAt.target.GetAtomicNum(),
                        fitAtName=mAt.target.GetName(),
                    )
                )
                fitAtD.pop(mAt.target.GetIdx())
        fitAtomUnMappedL = list(fitAtD.values())
        return (nAtomsRef, self.__refFD, nAtomsFit, self.__fitFD, atomMapL, fitAtomUnMappedL)
示例#19
0
def optGAFFx(mol, gaffdir, output_mol2, log):
    """
    Uses OEMol and GAFF input files to minimize the system and write
    output mol2

    Parameters
    ----------
    mol: OEMol
    gaffdir: directory with GAFF input files
    output_mol2: string, path/to/mol2 where output structure should be saved
    log: open file to write log data

    Returns
    -------
    boolean: True minimization succeeded, False otherwise

    """
    ### Check: optimized file not existing, gaff dependencies present, gaff files have content
    if os.path.exists(output_mol2):
        log.write('Optimization file %s already exists\n' % (output_mol2))
        return False

    ### Locate GAFF input files
    prmFile = os.path.join(gaffdir,mol.GetTitle()+'.prmtop')
    inpFile = os.path.join(gaffdir,mol.GetTitle()+'.inpcrd')

    # Check prmtop file
    if not os.path.exists(prmFile):
        log.write("%s does not exist, skipping minimization\n" % prmFile)
        return False
    elif not os.path.getsize(prmFile) > 40:
        log.write("%s is empty, skipping minimization\n" % prmFile)
        return False

    # Check inpcrd file
    if not os.path.exists(inpFile):
        log.write("%s does not exist, skipping minimization\n" % inpFile)
        return False
    elif not os.path.getsize(inpFile) > 40:
        log.write("%s is empty, skipping minimization\n" % inpFile)
        return False

    # make copy of mol2 file
    tmpmol = oechem.OEMol(mol)

    # load input files and create parmed system
    parm = parmed.load_file(prmFile, inpFile)
    Topology = parm.topology
    Positions = parm.positions
    System = parm.createSystem(nonbondedMethod=app.NoCutoff)

    ### Use parmed to write out mol2 file from optimized coordinates.
    minimized_positions = minimizeOpenMM(Topology, System, Positions)
    tmpmol.SetCoords(oechem.OEFloatArray(minimized_positions))

    return writeUpdatedMol(tmpmol, output_mol2, log)
示例#20
0
def set_conf_data(mol, props, calctype):

    # Set last coordinates from optimization. skip if missing.
    if 'coords' in props and len(props['coords']) != 0:
        mol.SetCoords(oechem.OEFloatArray(props['coords']))

    # Set SD tags for this molecule
    pt.set_sd_tags(mol, props, calctype)

    return mol
示例#21
0
def CullClashPts(mol, nbrList, scalefac, pts, moltype='OEMol'):
    '''Culls out points in the list which are within scaled vdw radii of any other
    atom in the OEMol mol.
    Input arguments:
      mol: the OEMol(or RDMol) whose neighbors are examined.
      nbrList: a list of OEAtoms which are neighbors of the point list.
      scalefac: the scale factor for the atomic radii.
      pts: the list of points to cull
    Returns the list of points outside the scaled radii of the neighboring atoms.'''
    # precalculate neighbor coords
    nbrXyz = []
    if moltype is 'OEMol':
        xyztmp = oechem.OEFloatArray(3)
        for atom in nbrList:
            if not mol.GetCoords(atom, xyztmp):
                print('cannot get coords for atom', atom.GetName())
            nbrXyz.append(list(xyztmp))
        # precalculate neighbor scaled squared radii
        nbrRadiusSq = [
            atom.GetRadius() * scalefac * atom.GetRadius() * scalefac
            for atom in nbrList
        ]
    elif moltype is 'RDMol':
        xyztmp = np.zeros(3)
        pos = mol.GetConformer().GetPositions()
        for atom in nbrList:
            xyztmp = pos[atom.GetIdx()]
            nbrXyz.append(list(xyztmp))
        # precalculate neighbor scaled squared radii
        nbrRadiusSq = [
            float(atom.GetProp('radius')) * scalefac *
            float(atom.GetProp('radius')) * scalefac for atom in nbrList
        ]

    culled = []
    # iterate over each point in the point list
    for pt in pts:
        #print(pt)
        goodPt = True
        # iterate over all atoms in the neighborlist; precalculated coords and radiusSq
        for i, (xyz, radiusSq) in enumerate(zip(nbrXyz, nbrRadiusSq)):
            #print(xyz)
            dx = pt[0] - xyz[0]
            dy = pt[1] - xyz[1]
            dz = pt[2] - xyz[2]
            distSq = dx * dx + dy * dy + dz * dz
            #print( i, distSq, radiusSq)
            if distSq < radiusSq:
                #print('bad point; breaking')
                goodPt = False
                break
        if goodPt:
            #print('good point; adding')
            culled.append(pt)
    return culled
示例#22
0
def make_psi_input(mol, label, method, basisset, SPE=False, mem=None):
    """
    Parameters
    ----------
    mol: single OEChem conformer with coordinates
    label: string - name of the molecule. Can be an empty string.
    method: string - specification of method (see Psi4 website for options)
    basisset: string - specification of basis set
    SPE: boolean - False (default) for geom opt. True for single point E calcns
    mem: string - specify Psi4 job memory. E.g. "2 Gb" "2000 Mb" "2000000 Kb"

    Returns
    -------
    inputstring: string - containing contents of whole input file for this conf

    """
    inputstring = ""
    xyz = oechem.OEFloatArray(3)
    # specify memory requirements, if defined
    if mem != None:
        inputstring += "memory %s\n" % mem
    inputstring+=( 'molecule %s {\n' % label )
    # charge and multiplicity; multiplicity hardwired to singlet (usually is)
    netCharge = oechem.OENetCharge( mol)
    inputstring+=( '  %s 1' % netCharge )
    # get coordinates of each atom
    for atom in mol.GetAtoms():
        mol.GetCoords( atom, xyz)
        inputstring+=( '\n  %s %10.4f %10.4f  %10.4f' \
                       %(oechem.OEGetAtomicSymbol(atom.GetAtomicNum()),
                       xyz[0], xyz[1], xyz[2]) )
    inputstring+=( '\n  units angstrom\n}')
    # check if mol has a "freeze" tag
    for x in oechem.OEGetSDDataPairs(mol):
        if "atoms to freeze" in x.GetTag():
            freeze_list = x.GetValue()
            inputstring += "\n\nfreeze_list = \"\"\"\n  {} xyz\n  {} xyz\n  {} xyz\n  {} xyz\n\"\"\"".format(freeze_list[1], freeze_list[4],
                freeze_list[7], freeze_list[10])
            inputstring += "\nset optking frozen_cartesian $freeze_list"
            inputstring += "\nset optking dynamic_level = 1\nset optking consecutive_backsteps = 2\nset optking intrafrag_step_limit = 0.1\nset optking interfrag_step_limit = 0.1"
    # explicitly specify MP2 RI-auxiliary basis for Ahlrichs basis set
    # http://www.psicode.org/psi4manual/master/basissets_byfamily.html
    if method.lower()=='mp2' and 'def' in basisset and basisset.lower()!='def2-qzvpd':
        inputstring+=('\n\nset basis %s' % (basisset))
        inputstring+=('\nset df_basis_mp2 %s-ri' % (basisset))
        inputstring+=('\nset freeze_core True')
    else:
        inputstring+=('\n\nset basis %s' % (basisset))
        inputstring+=('\nset freeze_core True')
    # specify command for type of calculation
    if SPE is False:
        inputstring+=('\noptimize(\'%s\')' % (method))
    else:
        inputstring+=('\nenergy(\'%s\')' % (method))
    return inputstring
示例#23
0
def mol_from_json(symbols, connectivity, geometry, permute_xyz=False):
    """
    Generate OEMol from QCSchema molecule specs
    Parameters
    ----------
    inp_molecule: dict
        Must have symbols and connectivity and/or geometry
        Note: If geometry is given, the molecule will have a tag indicating that the goemetry came from QCSchema. This
        will ensure that the order of the atoms and configuration is not change for generation of mapped SMILES and
        isomeric SMILES.

    Returns
    -------
    molecule: OEMol

    """

    molecule = oechem.OEMol()
    for s in symbols:
        molecule.NewAtom(_symbols[s])

    # Add connectivity
    for bond in connectivity:
        a1 = molecule.GetAtom(oechem.OEHasAtomIdx(bond[0]))
        a2 = molecule.GetAtom(oechem.OEHasAtomIdx(bond[1]))
        molecule.NewBond(a1, a2, bond[-1])

    # Add geometry
    if molecule.NumAtoms() != geometry.shape[0] / 3:
        raise ValueError(
            "Number of atoms in molecule does not match length of position array"
        )

    molecule.SetCoords(oechem.OEFloatArray(geometry))
    molecule.SetDimension(3)

    if not permute_xyz:
        # Add tag that the geometry is from JSON and shouldn't be changed.
        geom_tag = oechem.OEGetTag("json_geometry")
        molecule.SetData(geom_tag, True)
    oechem.OEDetermineConnectivity(molecule)
    oechem.OEFindRingAtomsAndBonds(molecule)
    oechem.OEPerceiveBondOrders(molecule)
    # This seems to add hydrogens that are not in the json
    #oechem.OEAssignImplicitHydrogens(molecule)
    oechem.OEAssignFormalCharges(molecule)
    oechem.OEAssignAromaticFlags(molecule)
    oechem.OEPerceiveChiral(molecule)
    oechem.OE3DToAtomStereo(molecule)
    oechem.OE3DToBondStereo(molecule)

    return molecule
示例#24
0
def GenerateMSKShellPts(mol, options, moltype='OEMol'):
    '''Generates a set of points around the molecule, based on scaled atomic radii,
    according to the Merz-Singh-Kollman (MSK) scheme for ESP points. The MSK scheme
    is based on Bondi atomic radii, with four Connolly-sphere shells of points set at
    scaled atomic radii with scale factors 1.4, 1.6, 1.8, and 2.0 with a targeted
    surface density of 1 point per angstrom squared on each shell. This function offers
    flexibility in that it uses the atomic radii on the molecule and the options object
    to specify target surface spacing (inverse of density) and lower and upper scale
    factors (incrementing by 0.2 for each shell).
    Input arguments:
      mol: the OEMol(or RDMol) molecule for which we want the MSK point set.
      options: a dictionary with keys "space", "inner", and "outer", pointing to
        values for the target surface spacing, inner and outer vdw scale factors,
        respectively, all in angstrom units.
    Returns the MSK set as a list of xyz triples (in angstroms)'''
    density = 1 / options['space']
    print('MSK points with density', density)
    if moltype is 'OEMol':
        xyz = oechem.OEFloatArray(3)
    elif moltype is 'RDMol':
        xyz = np.zeros(3)
        pos = mol.GetConformer().GetPositions()
    molPts = []
    shellScale = options['inner']
    # increment atom radius shellScale by 0.2 placing a shell of points each time
    # the "while" test has a tiny increment to prevent premature termination
    while shellScale < (options['outer'] + .000001):
        shellPts = []
        for atom in mol.GetAtoms():
            if atom.GetAtomicNum() < 1:
                # dummy atoms are ignored
                continue
            if moltype is 'OEMol':
                if not mol.GetCoords(atom, xyz):
                    print('cannot get coords for atom', atom.GetName())
                scaledRad = atom.GetRadius() * shellScale
            elif moltype is 'RDMol':
                xyz = pos[atom.GetIdx()]
                scaledRad = float(atom.GetProp('radius')) * shellScale
            nbrs = GenerateVdwNeighborList(mol, atom, shellScale, moltype)
            atomPts = GenerateConnollySphere(scaledRad, xyz, density)
            culledPts = CullClashPts(mol, nbrs, shellScale, atomPts, moltype)
            #print( atom.GetName(), atom.GetRadius(), 'numPts pre-cull:', len(atomPts), 'post-cull:', len(culledPts))
            shellPts += culledPts
        print('MSK shell scaling vdW by {0:5.2f}: {1:d} points'.format(
            shellScale, len(shellPts)))
        # molPts += shellPts
        molPts.append(shellPts)  # changed
        shellScale += 0.2

    return molPts
示例#25
0
def MoleculeCenter(mol, moltype='OEMol'):
    if moltype is 'OEMol':
        xyzs = []
        for atom in mol.GetAtoms():
            xyz = oechem.OEFloatArray(3)
            mol.GetCoords(atom, xyz)
            xyzs.append(xyz)
        xyzs = np.array(xyzs)
        center = np.average(xyzs, axis=0)

    elif moltype is 'RDMol':
        xyzs = mol.GetConformer().GetPositions()
        center = np.average(xyzs, axis=0)
    return center
示例#26
0
def CalcBindingEnergy(zap, protein, ligand, cmplx):
    stopwatch = oechem.OEStopwatch()
    stopwatch.Start()

    ppot = oechem.OEFloatArray(protein.GetMaxAtomIdx())
    zap.SetMolecule(protein)
    zap.CalcAtomPotentials(ppot)
    proteinEnergy = 0.0
    for atom in protein.GetAtoms():
        proteinEnergy += ppot[atom.GetIdx()] * atom.GetPartialCharge()
    proteinEnergy *= 0.5

    lpot = oechem.OEFloatArray(ligand.GetMaxAtomIdx())
    zap.SetMolecule(ligand)
    zap.CalcAtomPotentials(lpot)
    ligandEnergy = 0.0
    for atom in ligand.GetAtoms():
        ligandEnergy += lpot[atom.GetIdx()] * atom.GetPartialCharge()
    ligandEnergy *= 0.5

    cpot = oechem.OEFloatArray(cmplx.GetMaxAtomIdx())
    zap.SetMolecule(cmplx)
    zap.CalcAtomPotentials(cpot)
    cmplxEnergy = 0.0
    for atom in cmplx.GetAtoms():
        cmplxEnergy += cpot[atom.GetIdx()] * atom.GetPartialCharge()
    cmplxEnergy *= 0.5

    energy = cmplxEnergy - ligandEnergy - proteinEnergy
    time = stopwatch.Elapsed()

    if zap.IsFocusTargetSet():
        focused = "Yes"
    else:
        focused = "No"

    PrintInfo(focused, energy, time)
def SetCustomConstraints(receptor, proteinHeavyAtom):
    # @ <SNIPPET-RECEPTOR-CUSTOM-CONSTRAINT-EDITING-3>
    customConstraints = oedocking.OEReceptorGetCustomConstraints(receptor)

    feature = customConstraints.AddFeature()
    feature.SetFeatureName("Example protein contact constraint")

    sphereRadius = 4.0
    sphereCenter = oechem.OEFloatArray(3)
    receptor.GetCoords(proteinHeavyAtom, sphereCenter)
    sphere = feature.AddSphere()
    sphere.SetRad(sphereRadius)
    sphere.SetCenter(sphereCenter[0], sphereCenter[1], sphereCenter[2])

    oedocking.OEReceptorSetCustomConstraints(receptor, customConstraints)
示例#28
0
def to_mapped_xyz(molecule,
                  atom_map,
                  conformer=None,
                  xyz_format=False,
                  filename=None):
    """
    Generate xyz coordinates for molecule in the order given by the atom_map. atom_map is a dictionary that maps the
    tag on the SMILES to the atom idex in OEMol.
    Parameters
    ----------
    molecule: OEMol with conformers
    atom_map: dict
        maps tag in SMILES to atom index
    conformer: int
        Which conformer to write xyz file for. If None, write out all conformers. Default is None
    xyz_format: bool
        If True, will write out number of atoms and molecule name. If false, will only write out elements and coordinates
    filename: str
        Name of file to save to. If None, only returns a string.

    Returns
    -------
    str: elements and xyz coordinates in order of tagged SMILES

    """
    xyz = ""
    for k, mol in enumerate(molecule.GetConfs()):
        if k == conformer or conformer is None:
            if xyz_format:
                xyz += "{}\n".format(mol.GetMaxAtomIdx())
                xyz += "{}\n".format(mol.GetTitle())
            coords = oechem.OEFloatArray(mol.GetMaxAtomIdx() * 3)
            mol.GetCoords(coords)
            if k != 0 and not xyz_format:
                xyz += "*"
            for mapping in range(1, len(atom_map) + 1):
                idx = atom_map[mapping]
                atom = mol.GetAtom(oechem.OEHasAtomIdx(idx))
                syb = oechem.OEGetAtomicSymbol(atom.GetAtomicNum())
                xyz += "  {}      {:05.3f}   {:05.3f}   {:05.3f}\n".format(
                    syb, coords[idx * 3], coords[idx * 3 + 1],
                    coords[idx * 3 + 2])

    if filename:
        file = open("{}.xyz".format(filename, 'w'))
        file.write(xyz)
        file.close()
    return xyz
示例#29
0
def min_ffxml(mol, ofs, ffxml):
    """
    Minimize the mol with force field input from FFXML file.

    Parameters
    ----------
    mol : OpenEye single-conformer molecule
    ofs : OpenEye output filestream
    ffxml : string
        name of FFXML file

    """

    # make copy of the input mol
    oe_mol = oechem.OEGraphMol(mol)

    try:
        # create openforcefield molecule ==> prone to triggering Exception
        off_mol = Molecule.from_openeye(oe_mol)

        # load in force field
        ff = ForceField(ffxml)

        # create components for OpenMM system
        topology = Topology.from_molecules(molecules=[off_mol])

        # create openmm system ==> prone to triggering Exception
        #system = ff.create_openmm_system(topology, charge_from_molecules=[off_mol])
        system = ff.create_openmm_system(topology)

    except Exception as e:
        smilabel = oechem.OEGetSDData(oe_mol, "SMILES QCArchive")
        print( ' >>> openforcefield failed to create OpenMM system: '
               f'{oe_mol.GetTitle()} {smilabel}: {e}')
        return

    positions = structure.extractPositionsFromOEMol(oe_mol)

    # minimize structure with ffxml
    newpos, energy = run_openmm(topology, system, positions)

    # save geometry, save energy as tag, write mol to file
    oe_mol.SetCoords(oechem.OEFloatArray(newpos))
    oechem.OESetSDData(oe_mol, "Energy FFXML", str(energy))
    oechem.OEWriteConstMolecule(ofs, oe_mol)

    return
示例#30
0
def GenerateBoxMinMax(mol, moltype='OEMol'):
    '''finds the smallest box dimension to enclose the molecule around the
    outer boundary radius of all the atoms. Each atom's outer boundary radius
    is stored in the atom's Generic Data with tag "PointSetOuterRad".
    Input arguments:
      mol: the OEMol(or RDMol) molecule for which the box dimensions are desired.
    Returns two tuples of xyz coords, the first is the box minimum coords and
      the second is the the box maximum coords.'''
    if moltype is 'OEMol':
        xyzOEArr = oechem.OEFloatArray(3)
    elif moltype is 'RDMol':
        xyzOEArr = np.zeros(3)
        pos = mol.GetConformer().GetPositions()
        # print(pos)
        # input()
    boxmin = np.array([1.e10, 1.e10, 1.e10])
    boxmax = np.array([-1.e10, -1.e10, -1.e10])
    for atom in mol.GetAtoms():
        # dummy atoms are ignored
        atomicNum = atom.GetAtomicNum()
        if atomicNum < 1:
            continue
        # get xyz coords for atom
        if moltype is 'OEMol':
            if not mol.GetCoords(atom, xyzOEArr):
                print('Molecule', mol.GetTitle(), 'cannot get coords for atom',
                      atom.GetName())
            xyz = np.array(xyzOEArr)
            # get outer (larger) radius for atom to use for outer limit of box
            outer = atom.GetRadius()
            if atom.HasData('PointSetOuterRad'):
                outer = atom.GetData('PointSetOuterRad')
        elif moltype is 'RDMol':
            xyzOEArr = pos[atom.GetIdx()]
            xyz = np.array(xyzOEArr)
            outer = float(atom.GetProp('radius'))
            if atom.GetProp('PointSetOuterRad') is not None:
                outer = float(atom.GetProp('PointSetOuterRad'))
        # find atom min and max vdw
        atomMin = xyz - outer
        atomMax = xyz + outer
        for crd in [0, 1, 2]:
            if atomMin[crd] < boxmin[crd]:
                boxmin[crd] = atomMin[crd]
            if atomMax[crd] > boxmax[crd]:
                boxmax[crd] = atomMax[crd]
    return boxmin, boxmax