def main(argv=sys.argv):
    if len(argv) != 2:
        oechem.OEThrow.Usage("%s <infile (oeb file prefix)>" % argv[0])

    ifs = oechem.oemolistream()
    if not ifs.open(argv[1] + '.oeb'):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % argv[1] +
                             '.oeb')

    ofsff = oechem.oemolostream()
    ofsff.SetFlavor(oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield)
    if not ofsff.open(argv[1] + '_ff.mol2'):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[1] +
                             '_ff.mol2')

    ofsTri = oechem.oemolostream()
    ofsTri.SetFlavor(oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield)
    if not ofsTri.open(argv[1] + '_tripos.mol2'):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[1] +
                             '_tripos.mol2')

    for mol in ifs.GetOEMols():
        oechem.OETriposAtomNames(mol)
        oechem.OEWriteConstMolecule(ofsff, mol)
        oechem.OETriposAtomTypeNames(mol)
        oechem.OEWriteConstMolecule(ofsTri, mol)

    ifs.close()
    ofsff.close()
    ofsTri.close()

    return 0
示例#2
0
def prepare_receptor(complex_pdb_filename, prefix):
    # Read the receptor and identify design units
    from openeye import oespruce, oechem
    complex = read_pdb_file(complex_pdb_filename)
    print('Identifying design units...')
    design_units = list(oespruce.OEMakeDesignUnits(complex))
    for i, design_unit in enumerate(design_units):
        filename = f'DU_{i}.oedu'
        print(f'Writing design unit {i} to {filename}')
        oechem.OEWriteDesignUnit(filename, design_unit)
    if len(design_units) > 1:
        print('More than one design unit found---using first one')
        design_unit = design_units[0]

    # Prepare the receptor
    print('Preparing receptor...')
    from openeye import oedocking
    protein = oechem.OEGraphMol()
    design_unit.GetProtein(protein)
    ligand = oechem.OEGraphMol()
    design_unit.GetLigand(ligand)
    receptor = oechem.OEGraphMol()
    oedocking.OEMakeReceptor(receptor, protein, ligand)
    oedocking.OEWriteReceptorFile(receptor, f'{prefix}-receptor.oeb.gz')

    with oechem.oemolostream(f'{prefix}-protein.pdb') as ofs:
        oechem.OEWriteMolecule(ofs, protein)
    with oechem.oemolostream(f'{prefix}-ligand.mol2') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)
    with oechem.oemolostream(f'{prefix}-ligand.pdb') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)
    with oechem.oemolostream(f'{prefix}-ligand.sdf') as ofs:
        oechem.OEWriteMolecule(ofs, ligand)
示例#3
0
 def write (self , filename, format = "mol2", mode = "w"):
     """                                               
     Writes this structure into a file in the designated format.     
     @type  format: C{str}                  
     @param format: Format must be one of the following case-sensitive strings: "pdb", "mol2", "xyz","sdf" and "smi"                   
     """
     if mode == "a":                                   
         raise ValueError("OeStruc write doesn't support append method")
     elif mode == "w":                                 
         if format == "pdb":                           
             ofs = oechem.oemolostream(filename + '.pdb')
             ofs.SetFormat(oechem.OEFormat_PDB)        
         elif format == "mol2":                        
             ofs = oechem.oemolostream(filename + '.mol2')
             ofs.SetFormat(oechem.OEFormat_MOL2)       
         elif format == "xyz":                         
             ofs = oechem.oemolostream(filename + '.xyz')
             ofs.SetFormat(oechem.OEFormat_XYZ)        
         elif format == "sdf":                         
             ofs = oechem.oemolostream(filename + '.sdf')
             ofs.SetFormat(oechem.OEFormat_SDF)        
         elif format == "smi":                         
             ofs = oechem.oemolostream(filename + '.smi')
             ofs.SetFormat(oechem.OEFormat_SMI)        
     else:                                             
         raise ValueError( "Invalid value for `mode' argument: '%s', should be one of 'a' and 'w'.")
     return oechem.OEWriteMolecule(ofs, self._struc  )
def main(argv=sys.argv):
    if len(argv) != 2:
        oechem.OEThrow.Usage("%s <infile (oeb file prefix)>" % argv[0])

    ifs = oechem.oemolistream()
    if not ifs.open(argv[1]+'.oeb'):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % argv[1]+'.oeb' )
    
    ofsff = oechem.oemolostream()
    ofsff.SetFlavor( oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield )
    if not ofsff.open(argv[1]+'_ff.mol2'):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[1]+'_ff.mol2')

    ofsTri = oechem.oemolostream()
    ofsTri.SetFlavor( oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield )
    if not ofsTri.open(argv[1]+'_tripos.mol2'):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[1]+'_tripos.mol2')

    for mol in ifs.GetOEMols():
        oechem.OETriposAtomNames(mol)
        oechem.OEWriteConstMolecule(ofsff, mol)
        oechem.OETriposAtomTypeNames(mol)
        oechem.OEWriteConstMolecule(ofsTri, mol)

    ifs.close()
    ofsff.close()
    ofsTri.close()
示例#5
0
文件: resp2.py 项目: hrendr/RESP2
def create_conformers(infile=None, outfile=None, resname=None, folder= None, name = None):

    """
    This function takes a mol1 file and runs Openeye's omega to create conformers for the molecules
    The conformers are stored in separated files, adding the number of the conformer at the end of the filename

    :param infile: Path to input file
    :param outfile: Path to output file return
    :param folder: Name of the folder for the target. If not specified. {name}-liquid is used.
    :param resname: Abbreviation of the Residue. Specified in the mol2
    :return: Number of conformers for this molecule
    """
    if folder is None and name is None:
        log.error('Please specify keyword argument folder or name')
        sys.exit(1)
    elif folder is None:
        folder = name +'-liquid'
    infilepath = os.path.join(folder, infile)
    outfilepath = os.path.join(folder, outfile)
    ifs = oechem.oemolistream()
    if not ifs.open(infilepath):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % infilepath)

    ofs = oechem.oemolostream()
    if not ofs.open(outfilepath):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % outfilepath)

    if not oechem.OEIs2DFormat(ofs.GetFormat()):
        oechem.OEThrow.Fatal("Invalid output file format for 2D coordinates!")

    omegaOpts = oeomega.OEOmegaOptions()
    omega = oeomega.OEOmega(omegaOpts)
    omega.SetCommentEnergy(True)
    omega.SetEnumNitrogen(True)
    omega.SetSampleHydrogens(True)
    omega.SetEnergyWindow(9.0)
    omega.SetMaxConfs(5)
    omega.SetRangeIncrement(2)
    omega.SetRMSRange([0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5])
    filename = '{}-conformers'.format(resname)
    for mol in ifs.GetOEMols():
        ret_code = omega.Build(mol)
        if ret_code == oeomega.OEOmegaReturnCode_Success:
            oechem.OEWriteMolecule(ofs, mol)
            for k, conf in enumerate(mol.GetConfs()):
                ofs1 = oechem.oemolostream()
                if not ofs1.open(os.path.join(folder, filename + '_' + str(k + 1) + '.mol2')):
                    oechem.OEThrow.Fatal("Unable to open %s for writing" % os.path.join(folder, filename + '_' + str(k + 1) + '.mol2'))
                oechem.OEWriteMolecule(ofs1, conf)
                nconf = k + 1
            log.info('Created conformations for {} and saved them to {}'.format(infilepath, outfilepath))

        else:
            oechem.OEThrow.Warning("%s: %s" % (mol.GetTitle(), oeomega.OEGetOmegaError(ret_code)))

    return nconf
示例#6
0
def main(argv=[__name__]):
    itf = oechem.OEInterface(InterfaceData)

    if not oechem.OEParseCommandLine(itf, argv):
        oechem.OEThrow.Fatal("Unable to interpret command line!")

    ifs = oechem.oemolistream()

    inputFile = itf.GetString("-in")
    if not ifs.open(inputFile):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % inputFile)

    ofs = oechem.oemolostream()

    outFile = itf.GetString("-out")
    if not ofs.open(outFile):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % outFile)

    chargeName = itf.GetString("-method")

    mol = oechem.OEMol()
    while oechem.OEReadMolecule(ifs, mol):
        if not AssignChargesByName(mol, chargeName):
            oechem.OEThrow.Warning("Unable to assign %s charges to mol %s" %
                                   (chargeName, mol.GetTitle()))
        oechem.OEWriteMolecule(ofs, mol)

    ifs.close()
    ofs.close()
示例#7
0
def traj_conf_extraction(ctx):

    for record in ctx.obj['records']:

        sys_id = check_sys_id(record)

        if not record.has_field(Fields.Analysis.oetraj_rec):
            raise ValueError("Multi Conf Trajectory record field is missing")

        oetraj_rec = record.get_value(Fields.Analysis.oetraj_rec)

        traj_names = ["LigTraj", "ProtTraj_OPLMD", "WatTraj"]

        ofs = oechem.oemolostream(sys_id + "_traj_confs.oeb")

        for fd in oetraj_rec.get_fields():

            name = fd.get_name()

            if name in traj_names:
                mol = oetraj_rec.get_value(fd)
                mol.SetTitle(name)
                oechem.OEWriteConstMolecule(ofs, mol)

        ofs.close()
def main(args):
    if len(args) != 3:
        oechem.OEThrow.Usage("%s <input> <output>" % args[0])

    ifs = oechem.oemolistream()
    if not ifs.open(args[1]):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % args[1])

    ofs = oechem.oemolostream()
    if not ofs.open(args[2]):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % args[2])

    mol = oechem.OEMol()
    oechem.OEReadMolecule(ifs, mol)

    opts = oeszybki.OEFreeFormConfOptions()
    ffconf = oeszybki.OEFreeFormConf(opts)

    # Estimate free energies to ontain the minimum energy conformers
    omol = oechem.OEMol(mol)
    if not (ffconf.EstimateFreeEnergies(omol)
            == oeszybki.OEFreeFormReturnCode_Success):
        oechem.OEThrow.Error("Failed to estimate conformational free energies")

    # Find similar conformers to the ones we started with, from the
    # pool of minimum energy conformers
    fmol = oechem.OEMol(mol)
    for conf in mol.GetConfs():
        ffconf.FindSimilarConfs(fmol, omol, conf, oechem.OESimilarByRMSD(0.05))

    oechem.OEWriteMolecule(ofs, fmol)

    return 0
示例#9
0
def main(argv=[__name__]):
    if len(argv) != 4:
        oechem.OEThrow.Usage("%s <reffile> <rocs_hits_file> <output.sdf>" %
                             argv[0])

    reffs = oechem.oemolistream(argv[1])
    fitfs = oechem.oemolistream(argv[2])
    outfs = oechem.oemolostream(argv[3])

    refmol = oechem.OEGraphMol()
    oechem.OEReadMolecule(reffs, refmol)

    # Prepare reference molecule for calculation
    # With default options this will add required color atoms
    prep = oeshape.OEOverlapPrep()
    prep.Prep(refmol)

    # Get appropriate function to calculate analytic color
    colorFunc = oeshape.OEAnalyticColorFunc()
    colorFunc.SetupRef(refmol)

    res = oeshape.OEOverlapResults()
    for fitmol in fitfs.GetOEGraphMols():
        prep.Prep(fitmol)
        colorFunc.Overlap(fitmol, res)
        oechem.OESetSDData(fitmol, "AnalyticColorTanimoto",
                           "%.2f" % res.GetColorTanimoto())
        oechem.OEWriteMolecule(outfs, fitmol)
        print("Fit Title: %s  Color Tanimoto: %.2f" %
              (fitmol.GetTitle(), res.GetColorTanimoto()))
示例#10
0
def combineSDF(infiles, ftype, outfile):

    ### Glob for input files to combine.
    ext = '*.'+ftype
    molfiles = glob.glob(os.path.join(infiles, ext))

    ### Open output file to write molecules.
    ofs = oechem.oemolostream()
    if os.path.exists(outfile) and os.path.getsize(outfile) > 10:
        sys.exit("Output .sdf file already exists. Exiting.\n")
        return
    if not ofs.open(outfile):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % outfile)

    ### Loop over mols.
    for f in molfiles:
        print(f)

        ifs = oechem.oemolistream()
        if not ifs.open(f):
             oechem.OEThrow.Warning("Unable to open %s for reading" % f)
        try:
            mol = next(ifs.GetOEMols())
        except StopIteration:
            print('No mol loaded for %s' % mol.GetTitle())
        ifs.close()
        mol.SetTitle(f.split('/')[-1].split('.')[0])
        oechem.OEWriteConstMolecule(ofs, mol)

    ofs.close()
示例#11
0
def main(argv=[__name__]):

    itf = oechem.OEInterface(InterfaceData)

    if not oechem.OEParseCommandLine(itf, argv):
        oechem.OEThrow.Fatal("Unable to interpret command line!")

    iname = itf.GetString("-i")
    oname = itf.GetString("-o")

    ims = oechem.oemolistream()
    if not ims.open(iname):
        oechem.OEThrow.Fatal("Cannot open input file!")

    oms = oechem.oemolostream()
    if not oms.open(oname):
        oechem.OEThrow.Fatal("Cannot open output file!")

    inmol = oechem.OEGraphMol()
    if not oechem.OEReadMolecule(ims, inmol):
        oechem.OEThrow.Fatal("Cannot read input file!")

    allSites = itf.GetBool("-a")
    splitCovalent = itf.GetBool("-c")
    separateResidues = itf.GetBool("-s")
    combineFilters = itf.GetBool("-pw")
    if combineFilters:
        SplitMolComplexCombineFilters(oms, inmol)
    elif allSites:
        SplitMolComplexAllSites(oms, inmol, splitCovalent)
    else:
        SplitMolComplex(oms, inmol, splitCovalent, separateResidues)

    oms.close()
示例#12
0
def convertSDFfile(reffile, filtfile, writeout):
    refifs = oechem.oemolistream()
    filtifs = oechem.oemolistream()
    ofs = oechem.oemolostream()

    ### Read in reference file, but don't need its old conformers
    if not refifs.open(reffile):
        oechem.OEThrow.Warning("Unable to open %s for reading" % reffile)
        return

    ### Read in filtered file and distinguish each molecule's conformers
    filtifs.SetConfTest( oechem.OEAbsoluteConfTest() )
    if not filtifs.open(filtfile):
        oechem.OEThrow.Warning("Unable to open %s for reading" % filtfile)
        return

    ### Open outstream file.
    if os.path.exists(writeout):
        print("File already exists: %s. Skip getting results.\n" % (writeout))
        return
    if not ofs.open(writeout):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % writeout)

    ### Loop and write molecules. (though refifs should only have ONE mol)
    for rmol in refifs.GetOEMols():
        for fmol in filtifs.GetOEMols():
            for i, conf in enumerate( fmol.GetConfs()):
                rmol.SetCoords(conf.GetCoords())
                oechem.OEWriteConstMolecule(ofs, rmol)

    refifs.close()
    filtifs.close()
    ofs.close()
示例#13
0
def smi2sdf(sdfout, smiles):
    """
    From a file containing smiles strings, generate omega conformers,
       resolve steric clashes, do a quick MM opt, and write SDF output.

    Parameters
    ----------
    sdfout: str - output sdf file. E.g. "name.sdf"
    smiles: str - name of the smiles file. E.g. "name.smi"

    """
    ### Read in smiles file.
    ifs = oechem.oemolistream()
    if not ifs.open(smiles):
        oechem.OEThrow.Warning("Unable to open %s for reading" % smiles)

    ### Open output file to write molecules.
    ofs = oechem.oemolostream()
    if os.path.exists(sdfout):
        #sys.exit("Output .sdf file already exists. Exiting.\n")
        print("Output .sdf file already exists. Exiting.\n")
        return
    if not ofs.open(sdfout):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % sdfout)

    ### For each molecule: label atoms, generate 1 conf, write output.
    for smimol in ifs.GetOEMols():
        oechem.OETriposAtomNames(smimol)
        mol = GenerateConfs(smimol)
        oechem.OEWriteConstMolecule(ofs, mol)

    ### Close files.
    ifs.close()
    ofs.close()
示例#14
0
def main(argv=[__name__]):
    ifs = oechem.oemolistream()
    ofs = oechem.oemolostream()
    path = "Docking_Results/*.oeb"  #Convert ligand poses from oeb to pdb format
    files = glob.glob(path)
    for i in files:
        centroid_number = i[-5:-4]
        if ifs.open(i):
            if ofs.open("ligand_poses_pdbs/" + "pose" + str(centroid_number) +
                        ".pdb"):
                for mol in ifs.GetOEGraphMols():
                    oechem.OEWriteMolecule(ofs, mol)
            else:
                oechem.OEThrow.Fatal("Unable to create output")
        else:
            oechem.OEThrow.Fatal("Unable to open input")
    path2 = "receptor_oebs/*.oeb"  #Convert receptors from oeb to pdb format
    files = glob.glob(path2)
    for j in files:
        centroid_number = j[-5:-4]
        if ifs.open(j):
            if ofs.open("receptor_pdbs_converted_from_oebs/" + "receptor" +
                        str(centroid_number) + ".pdb"):
                for mol in ifs.GetOEGraphMols():
                    oechem.OEWriteMolecule(ofs, mol)
            else:
                oechem.OEThrow.Fatal("Unable to create output")
        else:
            oechem.OEThrow.Fatal("Unable to open input")
    return 0
示例#15
0
def main(args):
    if len(args) != 3:
        oechem.OEThrow.Usage("%s <input> <output>" % args[0])

    ifs = oechem.oemolistream()
    if not ifs.open(args[1]):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % args[1])

    ofs = oechem.oemolostream()
    if not ofs.open(args[2]):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % args[2])

    mol = oechem.OEMol()
    oechem.OEReadMolecule(ifs, mol)

    opts = oeszybki.OEFreeFormConfOptions()
    ffconf = oeszybki.OEFreeFormConf(opts)

    omol = oechem.OEMol(mol)
    if not (ffconf.EstimateFreeEnergies(omol) == oeszybki.OEFreeFormReturnCode_Success):
        oechem.OEThrow.Error("Failed to estimate conformational free energies")

    res = oeszybki.OEFreeFormConfResults(omol)
    oechem.OEThrow.Info("Number of unique conformations: %d" % res.GetNumUniqueConfs())
    oechem.OEThrow.Info("Conf.  Delta_G   Vibrational_Entropy")
    oechem.OEThrow.Info("      [kcal/mol]     [J/(mol K)]")
    for r in res.GetResultsForConformations():
        oechem.OEThrow.Info("%2d %10.2f %14.2f" % (r.GetConfIdx(), r.GetDeltaG(),
                                                   r.GetVibrationalEntropy()))

    oechem.OEWriteMolecule(ofs, omol)

    return 0
示例#16
0
def dock_molecules(receptor_filename, molecules, filename):
    """
    Dock the specified molecules, writing out to specified file

    Parameters
    ----------
    receptor_filename : str
        Receptor .oeb.gz filename
    molecules : list of openeye.oechem.OEMol
        The read molecules to dock
    filename : str
        The filename to stream docked molecules to

    """
    # Read the receptor
    print('Loading receptor...')
    from openeye import oechem, oedocking
    receptor = oechem.OEGraphMol()
    if not oedocking.OEReadReceptorFile(receptor, 'receptor.oeb.gz'):
        oechem.OEThrow.Fatal("Unable to read receptor")

    if oedocking.OEReceptorHasBoundLigand(receptor):
        print("Receptor has a bound ligand")
    else:
        print("Receptor does not have bound ligand")

    print('Initializing receptor...')
    dockMethod = oedocking.OEDockMethod_Hybrid2
    dockResolution = oedocking.OESearchResolution_High
    dock = oedocking.OEDock(dockMethod, dockResolution)
    success = dock.Initialize(receptor)

    # Set up Omega
    from openeye import oeomega
    omegaOpts = oeomega.OEOmegaOptions(oeomega.OEOmegaSampling_Dense)
    #omegaOpts = oeomega.OEOmegaOptions()
    omega = oeomega.OEOmega(omegaOpts)
    omega.SetStrictStereo(False)

    # Dock molecules
    with oechem.oemolostream(filename) as ofs:
        from tqdm import tqdm
        for mol in tqdm(molecules):
            dockedMol = oechem.OEGraphMol()

            # Expand conformers
            omega.Build(mol)

            # Dock molecule
            retCode = dock.DockMultiConformerMolecule(dockedMol, mol)
            if (retCode != oedocking.OEDockingReturnCode_Success):
                oechem.OEThrow.Fatal("Docking Failed with error code " + oedocking.OEDockingReturnCodeGetName(retCode))

            # Store docking data
            sdtag = oedocking.OEDockMethodGetName(dockMethod)
            oedocking.OESetSDScore(dockedMol, dock, sdtag)
            dock.AnnotatePose(dockedMol)

            # Write molecule
            oechem.OEWriteMolecule(ofs, dockedMol)
示例#17
0
    def reload_system(self, ln: str, smis: oechem.OEMol, old_pdb: str, is_oe_already: bool = False):
        with self.logger("reload_system") as logger:
            logger.log("Loading {} with new smiles {}".format(old_pdb, ln))
            with tempfile.TemporaryDirectory() as dirpath:
                ofs = oechem.oemolostream("{}/newlig.mol2".format(dirpath))
                oechem.OEWriteMolecule(ofs, smis)
                ofs.close()
                cmd.reinitialize()
                cmd.load(old_pdb)
                cmd.remove("not polymer")
                cmd.load("{}/newlig.mol2".format(dirpath), "UNL")
                cmd.alter("UNL", "resn='UNL'")
                cmd.alter("UNL", "chain='A'")
                self.config.pdb_file_name = self.config.tempdir() + "reloaded.pdb"
                cmd.save(self.config.pdb_file_name)
                cmd.save(self.config.tempdir() + "apo.pdb")

                with open(self.config.pdb_file_name, 'r') as f:
                    self.pdb = app.PDBFile(f)
                self.positions, self.topology = self.pdb.getPositions(), self.pdb.getTopology()

                if self.config.explicit and self.config.method == 'amber':
                    self.system, self.topology, self.positions = self.__setup_system_ex_amber(
                        pdbfile=self.config.pdb_file_name)
                elif self.config.explicit:
                    self.system, self.topology, self.positions = self.__setup_system_ex_mm()
                else:
                    self.system, self.topology, self.positions = self.__setup_system_im( pdbfile=self.config.pdb_file_name)

        return self.system
def main(argv=[__name__]):

    itf = oechem.OEInterface(InterfaceData, argv)

    ifname = itf.GetString("-in")
    ofname = itf.GetString("-out")

    ifs = oechem.oemolistream()
    if not ifs.open(ifname):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % ifname)

    if not oechem.OEIs2DFormat(ifs.GetFormat()):
        oechem.OEThrow.Fatal("Invalid input format: need 2D coordinates")

    ofs = oechem.oemolostream()
    if not ofs.open(ofname):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % ofname)

    if not oechem.OEIs2DFormat(ofs.GetFormat()):
        oechem.OEThrow.Fatal(
            "Invalid output format: unable to write 2D coordinates")

    nrrings = 0
    for mol in ifs.GetOEGraphMols():
        for ring in oechem.OEExtractRingTemplates(mol):
            nrrings += 1
            oechem.OEWriteMolecule(ofs, ring)

    oechem.OEThrow.Info("%d number of ring templates extracted" % nrrings)
示例#19
0
def main(args):
    if len(args) != 3:
        oechem.OEThrow.Usage("%s input_molecule output_molecule" % args[0])

    ifs = oechem.oemolistream()
    if not ifs.open(args[1]):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % args[1])

    ofs = oechem.oemolostream()
    if not ofs.open(args[2]):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % args[2])

    mol = oechem.OEMol()
    oechem.OEReadMolecule(ifs, mol)

    opts = oeszybki.OESzybkiOptions()
    opts.GetOptOptions().SetOptimizerType(oeszybki.OEOptType_NEWTON)
    opts.GetSolventOptions().SetSolventModel(oeszybki.OESolventModel_Sheffield)

    sz = oeszybki.OESzybki(opts)
    res = oeszybki.OESzybkiResults()
    if (sz(mol, res)):
        oechem.OEWriteMolecule(ofs, mol)
        res.Print(oechem.oeout)

    return 0
示例#20
0
def cluster_extraction(ctx):

    for record in ctx.obj['records']:

        sys_id = check_sys_id(record)

        if not record.has_field(Fields.Analysis.oeclus_rec):
            raise ValueError("Cluster record field is missing")

        oeclus_rec = record.get_value(Fields.Analysis.oeclus_rec)

        clust_names = [
            "ClusLigAvgMol", "ClusProtAvgMol", "ClusLigMedMol",
            "ClusProtMedMol"
        ]

        ofs = oechem.oemolostream(sys_id + "_clusters.oeb")

        for fd in oeclus_rec.get_fields():

            name = fd.get_name()

            if name in clust_names:
                mol = oeclus_rec.get_value(fd)
                mol.SetTitle(name)
                oechem.OEWriteConstMolecule(ofs, mol)

        ofs.close()
示例#21
0
def main(args=[__name__]):
    if len(args) != 3:
        oechem.OEThrow.Usage("%s <molfile> <outfile>" % args[0])

    ifs = oechem.oemolistream()
    if not ifs.open(args[1]):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % args[1])

    ofs = oechem.oemolostream()
    if not ofs.open(args[2]):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % args[2])

    mol = oechem.OEMol()
    oechem.OEReadMolecule(ifs, mol)

    opts = oeszybki.OESzybkiOptions()
    opts.GetGeneralOptions().SetForceFieldType(oeszybki.OEForceFieldType_SMIRNOFF)
    sz = oeszybki.OESzybki(opts)
    results = oeszybki.OESzybkiResults()
    if not sz(mol, results):
        return 1

    oechem.OEWriteMolecule(ofs, mol)
    results.Print(oechem.oeout)

    return 0
示例#22
0
def main(argv=[__name__]):
    itf = oechem.OEInterface(InterfaceData, argv)

    ifs = oechem.oemolistream()
    if not ifs.open(itf.GetString("-i")):
        oechem.OEThrow.Fatal("Unable to open %s for reading" %
                             itf.GetString("-i"))

    ofs = oechem.oemolostream(".ism")
    if itf.HasString("-o"):
        if not ofs.open(itf.GetString("-o")):
            oechem.OEThrow.Fatal("Unable to open %s for writing" %
                                 itf.GetString("-o"))

    minhac = float("-inf")
    if itf.HasInt("-minhac"):
        minhac = itf.GetInt("-minhac")
    maxhac = float("inf")
    if itf.HasInt("-maxhac"):
        maxhac = itf.GetInt("-maxhac")
    minwt = float("-inf")
    if itf.HasDouble("-minwt"):
        minwt = itf.GetDouble("-minwt")
    maxwt = float("inf")
    if itf.HasDouble("-maxwt"):
        maxwt = itf.GetDouble("-maxwt")

    for mol in ifs.GetOEMols():
        if not IsMoleculeInHeavyAtomCountRange(minhac, maxhac, mol):
            continue
        if not IsMoleculeInMolWtRange(minwt, maxwt, mol):
            continue

        oechem.OEWriteMolecule(ofs, mol)
示例#23
0
def test_ncmc_engine_molecule():
    """
    Check alchemical elimination for alanine dipeptide in vacuum with 0, 1, 2, and 50 switching steps.
    """
    molecule_names = ['pentane', 'biphenyl', 'imatinib']
    #if os.environ.get("TRAVIS", None) == 'true':
    #    molecule_names = ['pentane']

    for molecule_name in molecule_names:
        from perses.tests.utils import createSystemFromIUPAC
        [molecule, system, positions, topology] = createSystemFromIUPAC(molecule_name)
        natoms = system.getNumParticles()

        # DEBUG
        print(molecule_name)
        from openeye import oechem
        ofs = oechem.oemolostream('%s.mol2' % molecule_name)
        oechem.OEWriteMol2File(ofs, molecule)
        ofs.close()

        # Eliminate half of the molecule
        # TODO: Use a more rigorous scheme to make sure we are really cutting the molecule in half and not just eliminating hydrogens or something.
        new_to_old_atom_map = { atom.index : atom.index for atom in topology.atoms() if str(atom.element.name) in ['carbon','nitrogen'] }

        # DEBUG
        print(new_to_old_atom_map)

        from perses.rjmc.topology_proposal import TopologyProposal
        topology_proposal = TopologyProposal(
            new_topology=topology, new_system=system, old_topology=topology, old_system=system,
            old_chemical_state_key='', new_chemical_state_key='', logp_proposal=0.0, new_to_old_atom_map=new_to_old_atom_map, metadata={'test':0.0})
        for ncmc_nsteps in [0, 1, 50]:
            f = partial(check_alchemical_null_elimination, topology_proposal, positions, ncmc_nsteps=ncmc_nsteps)
            f.description = "Testing alchemical null elimination for '%s' with %d NCMC steps" % (molecule_name, ncmc_nsteps)
            yield f
示例#24
0
def write_mols(mols_dict, outfile):
    """
    Save all mols in the given dictionary to 'outfile'.

    Parameters
    ----------
    mols_dict : dict of dicts
        the first level key is the SMILES string and the value of that key is
        a dict with the following key/value pairs--
            metric      geometric measurement
            structure   OEGraphMol of the structure
    outfile : string
        name of output file
    """

    # open an outstream file
    ofs = oechem.oemolostream()
    if not ofs.open(outfile):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % outfile)

    # go through all the molecules
    for key in mols_dict:
        print(f"writing out {key}")
        mymol = mols_dict[key]['structure']
        oechem.OEWriteConstMolecule(ofs, mymol)
示例#25
0
def run_select_final(args):
    """Generates an SMI file with final selected molecules from SELECT mode."""
    logging.info("STARTING SELECT-FINAL")

    directory = args["select_final_dir"]
    output_file = args["select_final_output_file"]
    ofs = oechem.oemolostream(output_file)
    n = args["select_final_n"]

    logging.info(
        f"Reading molecules in {directory}, selecting and writing to {output_file}"
    )

    for f in glob.iglob(f"{directory}/*.smi"):
        ifs = oechem.oemolistream(f)
        mols = []
        mol = oechem.OEMol()
        while oechem.OEReadMolecule(ifs, mol):
            mols.append(oechem.OEMol(mol))
        ifs.close()
        logging.debug(f"Found {len(mols)} mols in {f}")
        mols.sort(key=lambda m: m.NumAtoms())
        for m in mols[:n]:
            oechem.OEWriteMolecule(ofs, m)
    ofs.close()

    logging.info("FINISHED SELECT-FINAL")
示例#26
0
def write_guest_molecules(old_molecule: oechem.OEMol, new_molecule: oechem.OEMol, filepath: str):
    """
    Write out a file containing the guest molecules with the "old molecule" first.

    Parameters
    ----------
    old_molecule : oechem.OEMol
        The molecule to be written first. It should have coordinates placing it within the guest
    new_molecule : oechem.OEMol
        The molecule to be written next. It does not need to have coordinates, as these will be generated
    filepath : str
        The path to the file that is being written
    """
    ostream = oechem.oemolostream()
    ostream.open(filepath)

    # set molecule names to avoid template name collision:
    old_molecule.SetTitle("oldmol")
    new_molecule.SetTitle("newmol")

    # set tripos atom names
    oechem.OETriposAtomNames(old_molecule)
    oechem.OETriposAtomNames(new_molecule)

    # write the molecules in order:
    oechem.OEWriteMolecule(ostream, old_molecule)
    oechem.OEWriteMolecule(ostream, new_molecule)

    ostream.close()
def main(argv=[__name__]):
    itf = oechem.OEInterface(InterfaceData, argv)

    cutoff = itf.GetFloat("-cutoff")

    ofs = oechem.oemolostream()
    if not ofs.open(itf.GetString("-clusters")):
        oechem.OEThrow.Fatal("Unable to open '%s'" % itf.GetString("-clusters"))

    if ofs.GetFormat() != oechem.OEFormat_OEB:
        oechem.OEThrow.Fatal("Output file must be OEB")

    sdtag = "TanimotoComboFromHead"
    if itf.GetBool("-shapeOnly"):
        sdtag = "ShapeTanimotoFromHead"
    getter = GetScoreGetter(itf.GetBool("-shapeOnly"))

    cluster = ShapeCluster(itf.GetString("-dbase"), cutoff, itf.GetBool("-shapeOnly"))

    # do the clustering
    while cluster.HasRemainingMolecules():
        clusterHead = cluster.GetNextClusterHead()
        print("Searching for neighbors of %s" % clusterHead.GetTitle())

        for nbrMol, score in cluster.GetCluster(clusterHead):
            oechem.OESetSDData(nbrMol, sdtag, "%.4f" % getter(score))

            score.Transform(nbrMol)

            clusterHead.AddData(nbrMol.GetTitle(), nbrMol)

        oechem.OEWriteMolecule(ofs, clusterHead)

    return 0
示例#28
0
def main(argv=[__name__]):
    if len(argv) != 3:
        oechem.OEThrow.Usage("%s <infile> <outfile>" % argv[0])

    ifs = oechem.oemolistream()
    if not ifs.open(argv[1]):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % argv[1])

    ofs = oechem.oemolostream()
    if not ofs.open(argv[2]):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[2])

    if not oechem.OEIs3DFormat(ofs.GetFormat()):
        oechem.OEThrow.Fatal("Invalid output file format for 3D coordinates!")

    omegaOpts = oeomega.OEMacrocycleOmegaOptions()
    mcomega = oeomega.OEMacrocycleOmega(omegaOpts)

    for mol in ifs.GetOEMols():
        oechem.OEThrow.Info("Title: %s" % mol.GetTitle())
        ret_code = mcomega.Build(mol)
        if ret_code == oeomega.OEOmegaReturnCode_Success:
            oechem.OEWriteMolecule(ofs, mol)
        else:
            oechem.OEThrow.Warning("%s: %s" % (mol.GetTitle(), oeomega.OEGetOmegaError(ret_code)))

    return 0
示例#29
0
    def add_dataset(self):
        url = self.args.url + "/datasets/"
        act_mol_idx = {}
        dataset = None
        parameters = {}

        self.dataset = tempfile.NamedTemporaryFile(suffix='.oeb',
                                                   mode='wb',
                                                   delete=False)
        with oechem.oemolostream(self.dataset.name) as ofs:
            for idx, mol in enumerate(self.act_list):
                act_mol_idx[mol.GetTitle()] = idx
                oechem.OEWriteMolecule(ofs, mol)
        self.dataset.flush()

        dataset = open(self.dataset.name, 'rb')
        parameters["dataset"] = (self.dataset.name, dataset,
                                 'application/octet-stream')
        parameters["name"] = 'dataset of active molecules'

        multipart_data = MultipartEncoder(fields=parameters)

        response = requests.post(
            url,
            data=multipart_data,
            headers={"content-type": multipart_data.content_type})

        if dataset is not None:
            dataset.close()
        os.remove(self.dataset.name)

        data = response.json()
        dataset_infos = (data["id"], act_mol_idx)
        return dataset_infos
示例#30
0
def main(argv=[__name__]):
    itf = oechem.OEInterface(InterfaceData, argv)
    haslist = itf.HasString("-list")
    hastitle = itf.HasString("-title")
    if not (haslist ^ hastitle):
        oechem.OEThrow.Usage("Must give either -list or -title")

    ifs = oechem.oemolistream()
    if not ifs.open(itf.GetString("-i")):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % itf.GetString("-i"))

    ofs = oechem.oemolostream()
    if not ofs.open(itf.GetString("-o")):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % itf.GetString("-o"))

    # collect names
    nameset = set()
    if itf.HasString("-list"):
        try:
            lfs = open(itf.GetString("-list"))
        except IOError:
            oechem.OEThrow.Fatal("Unable to open %s for reading" % itf.GetString("-list"))
        for name in lfs.readlines():
            name = name.strip()
            nameset.add(name)
    elif itf.HasString("-title"):
        nameset.add(itf.GetString("-title"))

    if len(nameset) == 0:
        oechem.OEThrow.Fatal("No titles requested")

    MolExtract(ifs, ofs, nameset)
示例#31
0
def write_guest_molecules(old_molecule: oechem.OEMol, new_molecule: oechem.OEMol, filepath: str):
    """
    Write out a file containing the guest molecules with the "old molecule" first.
    
    Parameters
    ----------
    old_molecule : oechem.OEMol
        The molecule to be written first. It should have coordinates placing it within the guest
    new_molecule : oechem.OEMol
        The molecule to be written next. It does not need to have coordinates, as these will be generated
    filepath : str
        The path to the file that is being written
    """
    ostream = oechem.oemolostream()
    ostream.open(filepath)

    #set molecule names to avoid template name collision:
    old_molecule.SetTitle("oldmol")
    new_molecule.SetTitle("newmol")

    #set tripos atom names
    oechem.OETriposAtomNames(old_molecule)
    oechem.OETriposAtomNames(new_molecule)

    #write the molecules in order:
    oechem.OEWriteMolecule(ostream, old_molecule)
    oechem.OEWriteMolecule(ostream, new_molecule)

    ostream.close()
示例#32
0
def main():
    args = parse_args()

    start_time = time.time()
    ifs = oechem.oemolistream()
    if ifs.open(args.infile):
        mols = [oechem.OEMol(mol) for mol in ifs.GetOEGraphMols()]
        ifs.close()
    else:
        oechem.OEThrow.Fatal(f"Unable to open {args.infile}")

    out_mols = generate_ml_profiles(mols, args.model_file, args.scaler_file)
    count = len(out_mols)

    ofs = oechem.oemolostream()
    if ofs.open(args.outfile):
        for mol in out_mols:
            oechem.OEWriteMolecule(ofs, mol)
        ofs.close()
    else:
        oechem.OEThrow.Fatal(f"Unable to open {args.outfile}")

    time_elapsed = time.time() - start_time
    logging.warning('Generated profiles for %d molecules in %.1f seconds',
                    count, time_elapsed)
示例#33
0
def FromMol(mol, isomer=True, num_enantiomers=-1):
    """
    Generates a set of conformers as an OEMol object
    Inputs:
        mol is an OEMol
        isomers is a boolean controling whether or not the various diasteriomers of a molecule are created
        num_enantiomers is the allowable number of enantiomers. For all, set to -1
    """
    omegaOpts = oeomega.OEOmegaOptions()
    omegaOpts.SetMaxConfs(199)
    omega = oeomega.OEOmega(omegaOpts)
    out_conf = []
    ofs = oechem.oemolostream("test.sdf")
    if not isomer:
        ret_code = omega.Build(mol)
        if ret_code == oeomega.OEOmegaReturnCode_Success:
            out_conf.append(mol)
        else:
            oechem.OEThrow.Warning("%s: %s" % (mol.GetTitle(), oeomega.OEGetOmegaError(ret_code)))

    elif isomer:
        for enantiomer in oeomega.OEFlipper(mol.GetActive(), 12, True):
            enantiomer = oechem.OEMol(enantiomer)
            ret_code = omega.Build(enantiomer)
            if ret_code == oeomega.OEOmegaReturnCode_Success:
                out_conf.append(enantiomer)
                num_enantiomers -= 1
                oechem.OEWriteMolecule(ofs, mol)
                if num_enantiomers == 0:
                    break
            else:
                oechem.OEThrow.Warning("%s: %s" % (mol.GetTitle(), oeomega.OEGetOmegaError(ret_code)))

    return out_conf
def create_molecule(name, filename):
    # Open output file.
    ofs = oechem.oemolostream()
    ofs.open(filename)

    # Create molecule.
    mol = oechem.OEMol()

    # Speculatively reorder CAS permuted index names
    str = oeiupac.OEReorderIndexName(name)
    if len(str)==0:
        str=name

    done = oeiupac.OEParseIUPACName(mol, str)

    # Create conformation.
    omega = oeomega.OEOmega()
    omega.SetIncludeInput(False) # don't include input
    omega.SetMaxConfs(1) # set maximum number of conformations to 1
    omega(mol)

    # Set molecule name
    mol.SetTitle(name)
    
    # Write molecule.
    oechem.OEWriteMolecule(ofs, mol)

    # Close stream.
    ofs.close()
    
    return
def hasAmberParams( mol, cmd_string):
    ofslig = oechem.oemolostream( 'lig.mol2')
    ofslig.SetFlavor( oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield );
    oechem.OEWriteConstMolecule(ofslig, mol)
    ofslig.close()
    os.system( cmd_string)
    paramsNotSaved = 'Parameter file was not saved'
    leaplog = open( 'leap_lig.stdout', 'r' ).read()
    hasParams = not paramsNotSaved in leaplog
    return hasParams
示例#36
0
def ProtonateLig_openeye(file_in,file_out,protonate=True,type_in=None,type_out=None):
    """
    Function to protonate small molecule using OpenEye's python libraries. Requires OpenEye licence.
    More information found https://docs.eyesopen.com/toolkits/python/quickstart-python/index.html

    Also doubles as a file conversion script. Files types can be specified or detected via the file extension. File types
    supported by OpenEye listed here: https://docs.eyesopen.com/toolkits/python/oechemtk/molreadwrite.html

    Parameters
    ----------
    file_in: str
        Name of the input file containing the coordinates of the molecule. One molecule expected.
    file_out: str
        Name of the output file.
    type_in: str
        File type of input file. Typically the file extension.
    type_out: str
        File type of the output file. Typically the file extension.

    Returns
    -------
    The output is written to a file
    """
    try:
        import openeye.oechem as oechem

        if type_in == None:
            type_in = file_in.split('.')[-1]
        if type_out == None:
            type_out = file_out.split('.')[-1]

        mol = oechem.OEGraphMol()           # initialising molecule object
        ifs = oechem.oemolistream()         # initialising input stream for reading in data
        ofs = oechem.oemolostream()         # initialising the OUTPUT stream for writing data

        ifs.SetFormat(eval('oechem.OEFormat_' + type_in.upper()))
        ofs.SetFormat(eval('oechem.OEFormat_' + type_out.upper()))

        ifs.open(file_in)
        if oechem.OEReadMolecule(ifs,mol):  # this function automatically returns True or False, to help spot for errors.
            pass
        else:
            print "Problem loading molecule!"

        mol = oechem.OEMol(mol)
        oechem.OEAssignAromaticFlags(mol, oechem.OEAroModelOpenEye)

        if protonate==True: oechem.OEAddExplicitHydrogens(mol)

        ofs.open(file_out)
        oechem.OEWriteMolecule(ofs,mol)

    except ImportError:
        print 'OpenEye python bindings not found'
def write_mol2_preserving_atomnames(filename, molecules, residue_name):
    ofs = oechem.oemolostream()
    ofs.open(filename)
    ofs.SetFlavor(oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_GeneralFFFormat)
    try:
        for molecule in molecules:
            oechem.OEWriteMolecule(ofs, molecule)
    except:
        oechem.OEWriteMolecule(ofs, molecules)
    ofs.close()
    fix_mol2_resname(filename, residue_name)
示例#38
0
def setup_yank_calculation(receptor_file_name, ligand_file_name, setup_directory_name, solvate=False):

    # Cleanup setup directory
    if os.path.exists(setup_directory_name):
        shutil.rmtree(setup_directory_name)
    os.makedirs(setup_directory_name)

    # Read ligand and receptor molecule
    ifs_mol2 = oechem.oemolistream()
    ifs_mol2.open(ligand_file_name)
    ligand_oemol = oechem.OEGraphMol()
    oechem.OEReadMolecule(ifs_mol2, ligand_oemol)
    ifs_mol2.close()

    ifs_mol2 = oechem.oemolistream()
    ifs_mol2.open(receptor_file_name)
    receptor_oemol = oechem.OEGraphMol()
    oechem.OEReadMolecule(ifs_mol2, receptor_oemol)
    ifs_mol2.close()

    # Push ligand close to receptor
    pull_close(receptor_oemol, ligand_oemol, MIN_DISTANCE, MAX_DISTANCE)

    # Add residue name 'MOL'
    residue = oechem.OEResidue()
    residue.SetName('MOL')
    for atom in ligand_oemol.GetAtoms():
        oechem.OEAtomSetResidue(atom, residue)

    # Parametrize ligand
    with working_directory(setup_directory_name):

        # Save translated ligand
        ofs = oechem.oemolostream()
        ofs.open('ligand.mol2')
        oechem.OEWriteMolecule(ofs, ligand_oemol)
        ofs.close()

        # Parametrize ligand
        print "Parameterizing ligand with GAFF..."
        run_command('antechamber -fi mol2 -i ligand.mol2 -fo mol2 -o ligand.gaff.mol2')
        run_command('parmchk -i ligand.gaff.mol2 -o ligand.gaff.frcmod -f mol2')

        # Copy receptor so that leap will know the PDB file name
        shutil.copyfile(receptor_file_name, 'receptor.pdb')

        # Create AMBER prmtop/inpcrd files.
        print "Creating AMBER prmtop/inpcrd files..."
        cmd = 'tleap -f {!s} > setup.leap.out'
        if solvate:
            run_command(cmd.format(LEAP_IN_EXPLICIT))
        else:
            run_command(cmd.format(LEAP_IN_IMPLICIT))
def normalize_molecule(mol):
    # Assign aromaticity.
    oechem.OEAssignAromaticFlags(mol, oechem.OEAroModelOpenEye)

    # Add hydrogens.
    oechem.OEAddExplicitHydrogens(mol)

    # Check for any missing atom names, if found reassign all of them.
    if any([atom.GetName() == '' for atom in mol.GetAtoms()]):
        oechem.OETriposAtomNames(mol)

    ofs = oechem.oemolostream('out.mol2')
    ofs.SetFormat(oechem.OEFormat_MOL2H)
    oechem.OEWriteMolecule(ofs, mol)
    ofs.close()

    return mol
示例#40
0
def new_output_stream(outname):
    """
    This function creates a new oechem.oemolostream.
    Parameters
    ----------
    outname: str
        name of outputfile.

    Returns
    -------
    ofs: oechem.oemolostream

    """
    ofs = oechem.oemolostream()
    if not ofs.open(outname):
        oechem.OEThrow.Fatal("Unable to open {} for writing".format(outname))
    return ofs
def hasAmberParams( mol, leaprc_string):
    # write mol2 file
    title = mol.GetTitle()
    ofsmol2 = oechem.oemolostream(title+'.mol2')
    ofsmol2.SetFlavor( oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield );
    oechem.OEWriteConstMolecule(ofsmol2, mol)
    ofsmol2.close()
    # write tleap input file
    os.system( 'echo """lig = loadMol2 '+title+'.mol2""" >| '+title+'.leap_in')
    os.system( 'echo """saveAmberParm lig '+title+'.top '+title+'.crd""" >> '+title+'.leap_in')
    os.system( 'echo quit >> '+title+'.leap_in')
    # run tleap
    #print( 'tleap -f '+leaprc_string+' -f '+title+'.leap_in >| leap_lig.stdout' )
    os.system( 'tleap -f '+leaprc_string+' -f '+title+'.leap_in >| leap_lig.stdout' )
    # check if param file was not saved (implies parameterization problems)
    paramsNotSaved = 'Parameter file was not saved'
    leaplog = open( 'leap_lig.stdout', 'r' ).read()
    hasParams = not paramsNotSaved in leaplog
    return hasParams
def write_tripos_mol2(molecule, filename, substructure_name='MOL', nconfs=None):
    """
    Write the molecule as a Tripos mol2 file.

    Parameters
    ----------
    molecule : openeye.oechem.OEMol
       The molecule to be written.
    filename : str
       The file to write to.
    substructure_name : str, optional, default='MOL'
       The name of the substructure to write.
    nconfs : int, optional, default=None
       The number of conformers to write.

    """

    # Avoid changing molecule by making a deep copy.
    molecule = oechem.OEMol(molecule)

    # Select number of conformers to write.
    if nconfs is None: nconfs = molecule.GetConfs()

    # Write the molecule in Tripos mol2 format.
    ofs = oechem.oemolostream(filename)
    ofs.SetFormat(oechem.OEFormat_MOL2H)
    for k, mol in enumerate(molecule.GetConfs()):
        if (k < nconfs):
            oechem.OEWriteMolecule(ofs, mol)
    ofs.close()

    # Replace <0> substructure names with valid text.
    if substructure_name:
        infile = open(filename, 'r')
        lines = infile.readlines()
        infile.close()
        newlines = [line.replace('<0>', substructure_name) for line in lines]
        outfile = open(filename, 'w')
        outfile.writelines(newlines)
        outfile.close()

    return
def main(argv=sys.argv):
    if len(argv) != 3:
        oechem.OEThrow.Usage("%s <infile (forcefield types)> <outfile (Tripos types)>" % argv[0])

    ifs = oechem.oemolistream()
    flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield
    ifs.SetFlavor(oechem.OEFormat_MOL2, flavor)
    if not ifs.open(argv[1]):
        oechem.OEThrow.Fatal("Unable to open %s for reading" % argv[1])

    ofs = oechem.oemolostream()
    if not ofs.open(argv[2]):
        oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[2])

    for mol in ifs.GetOEMols():
        oechem.OETriposAtomNames(mol)
        oechem.OEWriteConstMolecule(ofs, mol)

    ifs.close()
    ofs.close()
示例#44
0
def write_host(host_oemol : oechem.OEMol, filepath: str):
    """
    Write out the host molecule on its own.

    Parameters
    ----------
    host_oemol : oechem.OEMol
        the OEMol containing the host
    filepath : str
        where to write the OEMol
    """
    ostream = oechem.oemolostream()
    ostream.open(filepath)

    #set title to avoid template name collision:
    host_oemol.SetTitle("host")

    #set tripos atom names
    oechem.OETriposAtomNames(host_oemol)

    oechem.OEWriteMolecule(ostream, host_oemol)

    ostream.close()
示例#45
0
def write_oe_molecule(oe_mol, file_path, mol2_resname=None):
    """Write all conformations in a file and automatically detects format."""
    from openeye import oechem

    # Get correct OpenEye format
    extension = os.path.splitext(file_path)[1][1:]  # remove dot
    oe_format = getattr(oechem, 'OEFormat_' + extension.upper())

    # Open stream and write molecule
    ofs = oechem.oemolostream()
    ofs.SetFormat(oe_format)
    if not ofs.open(file_path):
        oechem.OEThrow.Fatal('Unable to create {}'.format(file_path))
    oechem.OEWriteMolecule(ofs, oe_mol)
    ofs.close()

    # If this is a mol2 file, we need to replace the resname
    # TODO when you merge to openmoltools, incapsulate this and add to molecule_to_mol2()
    if mol2_resname is not None and extension == 'mol2':
        with open(file_path, 'r') as f:
            lines = f.readlines()
        lines = [line.replace('<0>', mol2_resname) for line in lines]
        with open(file_path, 'w') as f:
            f.writelines(lines)
示例#46
0
def mol_to_tagged_smiles(infile, outfile):
    """
    Generate .smi from input mol with index-tagged explicit hydrogen SMILES
    Parameters
    ----------
    infile: str
        input molecule file
    outfile: str
        output smi file. Must be smi or ism

    """
    ifs = oechem.oemolistream()
    if not ifs.open(infile):
        oechem.OEThrow.Fatal("Unable to open {} for reading".format(infile))

    ofs = oechem.oemolostream()
    if not ofs.open(outfile):
        oechem.OEThrow.Fatal("Unable to open {} for writing".format(outfile))
    if ofs.GetFormat() not in [oechem.OEFormat_ISM, oechem.OEFormat_SMI]:
        oechem.OEThrow.Fatal("Output format must be SMILES")

    for mol in ifs.GetOEMols():
        smiles = create_mapped_smiles(mol)
        oechem.OEWriteMolecule(ofs, mol)
def mk_conformers(options, molecule, maxconf=99, verbose=True):
    """
    Enumerate the list of conformers and associated properties for each protonation and tautomeric state.

    Parameters
    ----------
    options
    molecule : openeye.oechem
        The molecule read from the PDB whose protomer and tautomer states are to be enumerated.
    maxconf : int, optional, default=128
        Maximum number of protomers/tautomers to generate.

    Returns
    -------
    conformers : list of Conformer
        The list of protomers/tautomers generated.

    """
    conformers = list()

    formalChargeOptions = oequacpac.OEFormalChargeOptions(maxconf)
    tautomerOptions = oequacpac.OETautomerOptions(maxconf)
    # enumerate pka states
    index = 0
    for pkaState in oequacpac.OEEnumerateFormalCharges(molecule, formalChargeOptions):
        if (index > maxconf): break
        # enumerate tautomers of pka states
        for tautomer in oequacpac.OEEnumerateTautomers(pkaState, tautomerOptions):
            if (index > maxconf): break
            # Assign conformer name.
            name = options.ligand+'%02d' % index
            tautomer.SetTitle(name)
            # DEBUG: Write molecule before charging.
            ofs = oechem.oemolostream()
            ofs.open(name + '-before.mol2')
            outmol = oechem.OEMol(tautomer)
            oechem.OEWriteMolecule(ofs, outmol)
            ofs.close()
            # Compute formal charge.
            oechem.OEAssignFormalCharges(tautomer)
            formal_charge = 0.0
            for atom in tautomer.GetAtoms():
                formal_charge += atom.GetFormalCharge()
            if verbose: print "formal charge: %d" % formal_charge
            # Assign canonical AM1BCC charges.
            assign_canonical_am1bcc_charges(tautomer)
            # DEBUG: Write molecule after charging.
            ofs = oechem.oemolostream()
            outmol = oechem.OEMol(tautomer)
            ofs.open(name + '-after.mol2')
            oechem.OEWriteMolecule(ofs, outmol)
            ofs.close()
            # Create conformer.
            conformer = Conformer(name, formal_charge, tautomer)
            # Append to protomer/tautomer list.
            conformers.append(conformer)
            # Keep count of protomers/tautomers.
            index += 1
            # Show output if requested.
            if verbose:
                print "%12s %+5d %8d atoms" % (name, conformer.charge, conformer.natoms)

    if verbose: print "%d protomer/tautomer states were enumerated" % len(conformers)

    return conformers
def enumerate_conformations(name, smiles=None, pdbname=None):
    """Run Epik to get protonation states using PDB residue templates for naming.

    Parameters
    ----------
    name : str
       Common name of molecule (used to create subdirectory)
    smiles : str
       Isomeric SMILES string
    pdbname : str
       Three-letter PDB code (e.g. 'DB8')
    """
    # Create output subfolder
    output_basepath = os.path.join(output_dir, name)
    if not os.path.isdir(output_basepath):
        os.mkdir(output_basepath)
    output_basepath = os.path.join(output_basepath, name)

    if pdbname:
        # Make sure to only use one entry if there are mutliple
        if ' ' in pdbname:
            pdbnames = pdbname.split(' ')
            print("Splitting '%s' into first entry only: '%s'" % (pdbname, pdbnames[0]))
            pdbname = pdbnames[0]

        # Retrieve PDB (for atom names)
        url = 'http://ligand-expo.rcsb.org/reports/%s/%s/%s_model.pdb' % (pdbname[0], pdbname, pdbname)
        pdb_filename = output_basepath + '-input.pdb'
        retrieve_url(url, pdb_filename)
        pdb_molecule = read_molecule(pdb_filename)

        # Retrieve SDF (for everything else)
        url = 'http://ligand-expo.rcsb.org/reports/%s/%s/%s_model.sdf' % (pdbname[0], pdbname, pdbname)
        sdf_filename = output_basepath + '-input.sdf'
        retrieve_url(url, sdf_filename)
        sdf_molecule = read_molecule(sdf_filename)

        # Replace atom names in SDF
        for (sdf_atom, pdb_atom) in zip(sdf_molecule.GetAtoms(), pdb_molecule.GetAtoms()):
            sdf_atom.SetName(pdb_atom.GetName())
        # Assign Tripos atom types
        oechem.OETriposAtomTypeNames(sdf_molecule)
        oechem.OETriposBondTypeNames(sdf_molecule)

        oe_molecule = sdf_molecule

        # We already know the residue name
        residue_name = pdbname
    elif smiles:
        # Generate molecule geometry with OpenEye
        print("Generating molecule {}".format(name))
        oe_molecule = openeye.smiles_to_oemol(smiles)
        # Assign Tripos atom types
        oechem.OETriposAtomTypeNames(oe_molecule)
        oechem.OETriposBondTypeNames(oe_molecule)
        try:
            oe_molecule = openeye.get_charges(oe_molecule, keep_confs=1)
        except RuntimeError as e:
            traceback.print_exc()
            print("Skipping molecule " + name)
            return
        residue_name = re.sub('[^A-Za-z]+', '', name.upper())[:3]
    else:
        raise Exception('Must provide SMILES string or pdbname')

    # Save mol2 file, preserving atom names
    print("Running epik on molecule {}".format(name))
    mol2_file_path = output_basepath + '-input.mol2'
    write_mol2_preserving_atomnames(mol2_file_path, oe_molecule, residue_name)

    # Run epik on mol2 file
    mae_file_path = output_basepath + '-epik.mae'
    schrodinger.run_epik(mol2_file_path, mae_file_path, tautomerize=False,
                         max_structures=100, min_probability=np.exp(-MAX_ENERGY_PENALTY), ph=7.4)

    # Convert maestro file to sdf and mol2
    output_sdf_filename = output_basepath + '-epik.sdf'
    output_mol2_filename = output_basepath + '-epik.mol2'
    schrodinger.run_structconvert(mae_file_path, output_sdf_filename)
    schrodinger.run_structconvert(mae_file_path, output_mol2_filename)

    # Read SDF file.
    ifs_sdf = oechem.oemolistream()
    ifs_sdf.SetFormat(oechem.OEFormat_SDF)
    ifs_sdf.open(output_sdf_filename)
    sdf_molecule = oechem.OEGraphMol()

    # Read MOL2 file.
    ifs_mol2 = oechem.oemolistream()
    ifs_mol2.open(output_mol2_filename)
    mol2_molecule = oechem.OEMol()

    # Assign charges.
    charged_molecules = list()
    index = 0
    while oechem.OEReadMolecule(ifs_sdf, sdf_molecule):
        oechem.OEReadMolecule(ifs_mol2, mol2_molecule)

        index += 1
        print("Charging molecule %d" % (index))
        try:
            # Charge molecule.
            charged_molecule = openeye.get_charges(mol2_molecule, max_confs=800, strictStereo=False, normalize=True, keep_confs=None)
            # Assign Tripos types
            oechem.OETriposAtomTypeNames(charged_molecule)
            oechem.OETriposBondTypeNames(charged_molecule)
            # Store tags.
            oechem.OECopySDData(charged_molecule, sdf_molecule)
            # Store molecule
            charged_molecules.append(charged_molecule)
        except Exception as e:
            print(e)
            print("Skipping protomer/tautomer because of failed charging.")

    # Clean up
    ifs_sdf.close()
    ifs_mol2.close()

    # Write state penalites.
    outfile = open(output_basepath + '-state-penalties.out', 'w')
    for (index, charged_molecule) in enumerate(charged_molecules):
        # Get Epik data.
        epik_Ionization_Penalty = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty"))
        epik_Ionization_Penalty_Charging = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty_Charging"))
        epik_Ionization_Penalty_Neutral = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty_Neutral"))
        epik_State_Penalty = float(oechem.OEGetSDData(charged_molecule, "r_epik_State_Penalty"))
        epik_Tot_Q = int(oechem.OEGetSDData(charged_molecule, "i_epik_Tot_Q"))

        outfile.write('%16.8f\n' % epik_State_Penalty)
    outfile.close()

    # Write as PDB
    charged_pdb_filename = output_basepath + '-epik-charged.pdb'
    ofs = oechem.oemolostream(charged_pdb_filename)
    flavor = oechem.OEOFlavor_PDB_CurrentResidues | oechem.OEOFlavor_PDB_ELEMENT | oechem.OEOFlavor_PDB_BONDS | oechem.OEOFlavor_PDB_HETBONDS | oechem.OEOFlavor_PDB_BOTH
    ofs.SetFlavor(oechem.OEFormat_PDB, flavor)
    for (index, charged_molecule) in enumerate(charged_molecules):
        # Fix residue names
        for atom in charged_molecule.GetAtoms():
            residue = oechem.OEAtomGetResidue(atom)
            residue.SetName(residue_name)
            oechem.OEAtomSetResidue(atom, residue)

        #oechem.OEWritePDBFile(ofs, charged_molecule, flavor)
        oechem.OEWriteMolecule(ofs, charged_molecule)
    ofs.close()

    # Write molecules as mol2.
    charged_mol2_filename = output_basepath + '-epik-charged.mol2'
    write_mol2_preserving_atomnames(charged_mol2_filename, charged_molecules, residue_name)
示例#49
0
def generate_torsions(mol, path, interval):
    """
    This function takes a 3D molecule (pdf, mol2 or sd file) and generates structures for a torsion drive on all torsions
    in the molecule. This function uses OpenEye
    Parameters
    ----------
    mol : str
        path to molecule file (pdb, mol2, sd, etc.)
    path: str
        path to output files
    interval: int
        angle (in degrees) of interval for torsion drive

    """
    filename = mol.split('/')[-1].split('.')[0]
    ifs = oechem.oemolistream(mol)
    inp_mol = oechem.OEMol()
    oechem.OEReadMolecule(ifs, inp_mol)
    ifs.close()

    mid_tors = [[tor.a, tor.b, tor.c, tor.d ] for tor in oechem.OEGetTorsions(inp_mol)]

    # This smarts should match terminal torsions such as -CH3, -NH2, -NH3+, -OH, and -SH
    smarts = '[*]~[*]-[X2H1,X3H2,X4H3]-[#1]'
    qmol=oechem.OEQMol()
    if not oechem.OEParseSmarts(qmol, smarts):
        warnings.warn('OEParseSmarts failed')
    ss = oechem.OESubSearch(qmol)
    mol = oechem.OEMol(inp_mol)
    h_tors = []
    oechem.OEPrepareSearch(mol, ss)
    unique = True
    for match in ss.Match(mol, unique):
        tor = []
        for ma in match.GetAtoms():
            tor.append(ma.target)
        h_tors.append(tor)

    # Combine middle and terminal torsions
    all_tors = mid_tors + h_tors
    # Sort all_tors so that it's grouped by central bond
    central_bonds = np.zeros((len(all_tors), 3), dtype=int)
    for i, tor in enumerate(all_tors):
        central_bonds[i][0] = i
        central_bonds[i][1] = tor[1].GetIdx()
        central_bonds[i][2] = tor[2].GetIdx()

    grouped = central_bonds[central_bonds[:, 2].argsort()]
    sorted_tors = [all_tors[i] for i in grouped[:, 0]]

    # Keep only one torsion per rotatable bond
    tors = []
    best_tor = [sorted_tors[0][0], sorted_tors[0][0], sorted_tors[0][0], sorted_tors[0][0]]
    first_pass = True
    for tor in sorted_tors:
        logger().info("Idxs: {} {} {} {}".format(tor[0].GetIdx(), tor[1].GetIdx(), tor[2].GetIdx(), tor[3].GetIdx()))
        logger().info("Atom Numbers: {} {} {} {}".format(tor[0].GetAtomicNum(), tor[1].GetAtomicNum(), tor[2].GetAtomicNum(), tor[3].GetAtomicNum()))
        if tor[1].GetIdx() != best_tor[1].GetIdx() or tor[2].GetIdx() != best_tor[2].GetIdx():
            new_tor = True
            if not first_pass:
                logger().info("Adding to list: {} {} {} {}".format(best_tor[0].GetIdx(), best_tor[1].GetIdx(), best_tor[2].GetIdx(), best_tor[3].GetIdx()))
                tors.append(best_tor)
            first_pass = False
            best_tor = tor
            best_tor_order = tor[0].GetAtomicNum() + tor[3].GetAtomicNum()
            logger().info("new_tor with central bond across atoms: {} {}".format(tor[1].GetIdx(), tor[2].GetIdx()))
        else:
            logger().info("Not a new_tor but now with end atoms: {} {}".format(tor[0].GetIdx(), tor[3].GetIdx()))
            tor_order = tor[0].GetAtomicNum() + tor[3].GetAtomicNum()
            if tor_order > best_tor_order:
                best_tor = tor
                best_tor_order = tor_order
    logger().info("Adding to list: {} {} {} {}".format(best_tor[0].GetIdx(), best_tor[1].GetIdx(), best_tor[2].GetIdx(), best_tor[3].GetIdx()))
    tors.append(best_tor)

    logger().info("List of torsion to drive:")
    for tor in tors:
        logger().info("Idx: {} {} {} {}".format(tor[0].GetIdx(), tor[1].GetIdx(), tor[2].GetIdx(), tor[3].GetIdx()))
        logger().info("Atom numbers: {} {} {} {}".format(tor[0].GetAtomicNum(), tor[1].GetAtomicNum(), tor[2].GetAtomicNum(), tor[3].GetAtomicNum()))

    conf = mol.GetConfs().next()
    coords = oechem.OEFloatArray(conf.GetMaxAtomIdx() * 3)
    conf.GetCoords(coords)
    mol.DeleteConfs()

    for tor in tors:
        tor_name = str((tor[0].GetIdx())+1) + '_' + str((tor[1].GetIdx())+1) + '_' + str((tor[2].GetIdx())+1) + '_' + str((tor[3].GetIdx())+1)
        folder = os.path.join(path, tor_name)
        try:
            os.makedirs(folder)
        except FileExistsError:
            logger().info("Overwriting existing directory {}".format(tor_name))
        for angle in range(0, 360, interval):
            angle_folder = os.path.join(folder, str(angle))
            os.makedirs(angle_folder)
            newconf = mol.NewConf(coords)
            oechem.OESetTorsion(newconf, tor[0], tor[1], tor[2], tor[3], radians(angle))
            pdb = oechem.oemolostream('{}/{}_{}_{}.pdb'.format(angle_folder, filename, tor_name, angle))
            oechem.OEWritePDBFile(pdb, newconf)
示例#50
0
def generate_torsions(inp_mol, output_path, interval, base_name=None, tar=True):
    """
    This function takes a 3D molecule (pdf, mol2 or sd file) and generates structures for a torsion drive on all torsions
    in the molecule. This function uses OpenEye
    Parameters
    ----------
    mol : OEMol
        molecule to generate 1D torsion scans
    output_path: str
        path to output file directory
    interval: int
        angle (in degrees) of interval for torsion drive
    base_name: str
        base name for file. Default is None. If default, use title in OEMol for base name
    tar: bool
        If true, will compress output

    """
    if not base_name:
        base_name = inp_mol.GetTitle()

    mid_tors = [[tor.a, tor.b, tor.c, tor.d ] for tor in oechem.OEGetTorsions(inp_mol)]

    # This smarts should match terminal torsions such as -CH3, -NH2, -NH3+, -OH, and -SH
    smarts = '[*]~[*]-[X2H1,X3H2,X4H3]-[#1]'
    qmol=oechem.OEQMol()
    if not oechem.OEParseSmarts(qmol, smarts):
        warnings.warn('OEParseSmarts failed')
    ss = oechem.OESubSearch(qmol)
    mol = oechem.OEMol(inp_mol)
    h_tors = []
    oechem.OEPrepareSearch(mol, ss)
    unique = True
    for match in ss.Match(mol, unique):
        tor = []
        for ma in match.GetAtoms():
            tor.append(ma.target)
        h_tors.append(tor)

    # Combine middle and terminal torsions
    all_tors = mid_tors + h_tors
    # Sort all_tors so that it's grouped by central bond
    central_bonds = np.zeros((len(all_tors), 3), dtype=int)
    for i, tor in enumerate(all_tors):
        central_bonds[i][0] = i
        central_bonds[i][1] = tor[1].GetIdx()
        central_bonds[i][2] = tor[2].GetIdx()

    grouped = central_bonds[central_bonds[:, 2].argsort()]
    sorted_tors = [all_tors[i] for i in grouped[:, 0]]

    # Keep only one torsion per rotatable bond
    tors = []
    best_tor = [sorted_tors[0][0], sorted_tors[0][0], sorted_tors[0][0], sorted_tors[0][0]]
    first_pass = True
    for tor in sorted_tors:
        logger().info("Idxs: {} {} {} {}".format(tor[0].GetIdx(), tor[1].GetIdx(), tor[2].GetIdx(), tor[3].GetIdx()))
        logger().info("Atom Numbers: {} {} {} {}".format(tor[0].GetAtomicNum(), tor[1].GetAtomicNum(), tor[2].GetAtomicNum(), tor[3].GetAtomicNum()))
        if tor[1].GetIdx() != best_tor[1].GetIdx() or tor[2].GetIdx() != best_tor[2].GetIdx():
            new_tor = True
            if not first_pass:
                logger().info("Adding to list: {} {} {} {}".format(best_tor[0].GetIdx(), best_tor[1].GetIdx(), best_tor[2].GetIdx(), best_tor[3].GetIdx()))
                tors.append(best_tor)
            first_pass = False
            best_tor = tor
            best_tor_order = tor[0].GetAtomicNum() + tor[3].GetAtomicNum()
            logger().info("new_tor with central bond across atoms: {} {}".format(tor[1].GetIdx(), tor[2].GetIdx()))
        else:
            logger().info("Not a new_tor but now with end atoms: {} {}".format(tor[0].GetIdx(), tor[3].GetIdx()))
            tor_order = tor[0].GetAtomicNum() + tor[3].GetAtomicNum()
            if tor_order > best_tor_order:
                best_tor = tor
                best_tor_order = tor_order
    logger().info("Adding to list: {} {} {} {}".format(best_tor[0].GetIdx(), best_tor[1].GetIdx(), best_tor[2].GetIdx(), best_tor[3].GetIdx()))
    tors.append(best_tor)

    logger().info("List of torsion to drive:")
    for tor in tors:
        logger().info("Idx: {} {} {} {}".format(tor[0].GetIdx(), tor[1].GetIdx(), tor[2].GetIdx(), tor[3].GetIdx()))
        logger().info("Atom numbers: {} {} {} {}".format(tor[0].GetAtomicNum(), tor[1].GetAtomicNum(), tor[2].GetAtomicNum(), tor[3].GetAtomicNum()))

    conf = mol.GetConfs().next()
    coords = oechem.OEFloatArray(conf.GetMaxAtomIdx() * 3)
    conf.GetCoords(coords)
    # Check if coordinates are not zero
    values = np.asarray([coords.__getitem__(i) == 0 for i in range(coords.__len__())])
    if values.all():
        # Generate new coordinates.
        mol2 = generate_conformers(mol, max_confs=1)
        conf = mol2.GetConfs().next()
        coords = oechem.OEFloatArray(conf.GetMaxAtomIdx() * 3)
        conf.GetCoords(coords)
        mol2.DeleteConfs()
    mol.DeleteConfs()

    for tor in tors:
        tor_name = str((tor[0].GetIdx())+1) + '_' + str((tor[1].GetIdx())+1) + '_' + str((tor[2].GetIdx())+1) + '_' + str((tor[3].GetIdx())+1)
        folder = os.path.join(output_path, tor_name)
        try:
            os.makedirs(folder)
        except FileExistsError:
            logger().info("Overwriting existing directory {}".format(tor_name))
        for angle in range(0, 360, interval):
            angle_folder = os.path.join(folder, str(angle))
            try:
                os.mkdir(angle_folder)
            except FileExistsError:
                logger().info("Overwriting existing directory {}".format(tor_name))
            newconf = mol.NewConf(coords)
            oechem.OESetTorsion(newconf, tor[0], tor[1], tor[2], tor[3], radians(angle))
            pdb = oechem.oemolostream('{}/{}_{}_{}.pdb'.format(angle_folder, base_name, tor_name, angle))
            oechem.OEWritePDBFile(pdb, newconf)
    if tar:
        # tar archive output
        out = tarfile.open('{}.tar.gz'.format(output_path), mode='w:gz')
        os.chdir(output_path)
        os.chdir('../')
        out.add('{}'.format(base_name))
        out.close()
def generateOEMolFromTopologyResidue(residue):
    """
    Generate an OpenEye OEMol molecule from an OpenMM Topology Residue.

    Parameters
    ----------
    residue : simtk.openmm.app.topology.Residue
        The topology Residue from which an OEMol is to be created.
        An Exception will be thrown if this residue has external bonds.

    Returns
    -------
    molecule : openeye.oechem.OEMol
        The OEMol molecule corresponding to the topology.
        Atom order will be preserved and bond orders assigned.

    The Antechamber `bondtype` program will be used to assign bond orders, and these
    will be converted back into OEMol bond type assignments.

    Note that there is no way to preserve stereochemistry since `Residue` does
    not note stereochemistry in any way.

    """
    # Raise an Exception if this residue has external bonds.
    if len(list(residue.external_bonds())) > 0:
        raise Exception("Cannot generate an OEMol from residue '%s' because it has external bonds." % residue.name)

    from openeye import oechem
    # Create OEMol where all atoms have bond order 1.
    molecule = oechem.OEMol()
    molecule.SetTitle(residue.name) # name molecule after first residue
    for atom in residue.atoms():
        oeatom = molecule.NewAtom(atom.element.atomic_number)
        oeatom.SetName(atom.name)
    oeatoms = { oeatom.GetName() : oeatom for oeatom in molecule.GetAtoms() }
    for (atom1, atom2) in residue.bonds():
        order = 1
        molecule.NewBond(oeatoms[atom1.name], oeatoms[atom2.name], order)

    # Write out a mol2 file without altering molecule.
    import tempfile
    tmpdir = tempfile.mkdtemp()
    mol2_input_filename = os.path.join(tmpdir,'molecule-before-bond-perception.mol2')
    ac_output_filename = os.path.join(tmpdir,'molecule-after-bond-perception.ac')
    ofs = oechem.oemolostream(mol2_input_filename)
    m2h = True
    substruct = False
    oechem.OEWriteMol2File(ofs, molecule, m2h, substruct)
    ofs.close()
    # Run Antechamber bondtype
    import subprocess
    #command = 'bondtype -i %s -o %s -f mol2 -j full' % (mol2_input_filename, ac_output_filename)
    command = 'antechamber -i %s -fi mol2 -o %s -fo ac -j 2' % (mol2_input_filename, ac_output_filename)
    [status, output] = getstatusoutput(command)

    # Define mapping from GAFF bond orders to OpenEye bond orders.
    order_map = { 1 : 1, 2 : 2, 3: 3, 7 : 1, 8: 2, 9 : 5, 10 : 5 }
    # Read bonds.
    infile = open(ac_output_filename)
    lines = infile.readlines()
    infile.close()
    antechamber_bond_types = list()
    for line in lines:
        elements = line.split()
        if elements[0] == 'BOND':
            antechamber_bond_types.append(int(elements[4]))
    for (bond, antechamber_bond_type) in zip(molecule.GetBonds(), antechamber_bond_types):
        bond.SetOrder(order_map[antechamber_bond_type])

    # Clean up.
    os.unlink(mol2_input_filename)
    os.unlink(ac_output_filename)
    os.rmdir(tmpdir)

    # Set aromaticity.
    # TODO: Is this necessary?
    oechem.OEClearAromaticFlags(molecule)
    oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye)

    # Assign Tripos atom types.
    # TODO: Is this necessary?
    oechem.OETriposAtomTypeNames(molecule)
    oechem.OETriposBondTypeNames(molecule)

    # Assign geometry
    # TODO: Is this necessary?
    from openeye import oeomega
    omega = oeomega.OEOmega()
    omega.SetMaxConfs(1)
    omega.SetIncludeInput(False)
    omega.SetStrictStereo(False)
    omega(molecule)

    return molecule
    os.system( cmd_string)
    paramsNotSaved = 'Parameter file was not saved'
    leaplog = open( 'leap_lig.stdout', 'r' ).read()
    hasParams = not paramsNotSaved in leaplog
    return hasParams


# In[4]:

fileprefix= 'AlkEthOH_chain_filt1'
#fileprefix= 'AlkEthOH_rings_filt1'
#fileprefix= 'test_filt1'
#fileprefix= 'AlkEthOH_r21'
#fileprefix= 'thp23diol'
ifs = oechem.oemolistream(fileprefix+'.oeb')
ofs = oechem.oemolostream(fileprefix+'_hasParam.oeb')
ofsFail = oechem.oemolostream(fileprefix+'_lacksParam.oeb')
#ofs.SetFlavor( oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield );


# In[5]:

cmd_string = 'tleap -f leaprc.Frosst_AlkEthOH -f lig.leap_in >| leap_lig.stdout'
mol = oechem.OEMol()
for mol in ifs.GetOEMols():
    if hasAmberParams(mol,cmd_string):
        print( 'Has   Amber params: %s' % mol.GetTitle() )
        oechem.OEWriteConstMolecule(ofs, mol)
    else:
        print( 'Lacks Amber params: %s' % mol.GetTitle() )
        oechem.OEWriteConstMolecule(ofsFail, mol)
示例#53
0
    oequacpac.OEAssignCharges(mol_multiconf, oequacpac.OEAM1BCCELF10Charges())

    # Get total charge
    conf = mol_multiconf.GetConf(oechem.OEHasConfIdx(0))
    absFCharge = 0
    sumFCharge = 0
    sumPCharge = 0.0
    for atm in mol_multiconf.GetAtoms():
        sumFCharge += atm.GetFormalCharge()
        absFCharge += abs(atm.GetFormalCharge())
        sumPCharge += atm.GetPartialCharge()
    oechem.OEThrow.Info("%s: %d formal charges give total charge %d ; Sum of Partial Charges %5.4f"
                             % (mol_multiconf.GetTitle(), absFCharge, sumFCharge, sumPCharge))

    # Output file
    ofs = oechem.oemolostream(charged_FN)
    ofs.SetFormat(oechem.OEFormat_MOL2H)
    oechem.OEWriteMolecule(ofs, conf)
    ofs.close()
  else:
    # Conformer generation failed. Use Ballon + Chimera
    print 'Conformer generation with OETools failed.'

if (args.UseOpenEye=='N') or not step_complete(charged_FN):
  if not step_complete(balloon_FN):
      # Run Balloon to convert from a SMILES string to a 3D structure
      MMFF94_FN = os.path.join(os.path.dirname(command_paths['balloon']),'MMFF94.mff')
      command = command_paths['balloon'] + ' -f ' + MMFF94_FN + \
        ' --nconfs 1 --nGenerations 300 "' + smi + '" ' + balloon_FN
      os.system(command)
示例#54
0
def run_epik(name, filename, residue_name, perceive_bonds=False):
    """Generate conformer with OpenEye omega, protonation states with Schrodinger Epik, and charges with OpenEye AM1-BCC.

    Parameters
    ----------
    name : str
       The name of the output directory to generate.
    filename : str
       The mol2, PDB, or SDF file to read in.
    residue_name : str
       Three uppercase letters to name residue.
    perceive_bonds : bool, optional, default=False
       If True, will use geometry to perceive connectivity.
       This is necessary for PDB files.

    """
    # Generate molecule geometry with OpenEye
    print("Generating molecule %s from %s" % (name, filename))
    oe_molecule = read_molecules(filename)
    if perceive_bonds:
        oechem.OEDetermineConnectivity(oe_molecule)

    # Assign geometry and charges with Omega
    oe_molecule = openeye.get_charges(oe_molecule, max_confs=1, strictStereo=False, normalize=True, keep_confs=1)

    # Create output subfolder
    output_basepath = os.path.join(output_dir, name)
    if not os.path.isdir(output_basepath):
        os.mkdir(output_basepath)
    output_basepath = os.path.join(output_basepath, name)

    # Save mol2 file with residue name = first three uppercase letters
    print "Running epik on molecule {}".format(name)
    mol2_file_path = output_basepath + '-input.mol2'
    residue_name = re.sub('[^A-Za-z]+', '', name.upper())[:3]
    #openeye.molecule_to_mol2(oe_molecule, mol2_file_path, residue_name=residue_name)
    from openeye import oechem
    ofs = oechem.oemolostream(mol2_file_path)
    oechem.OEWriteMol2File(ofs, oe_molecule, True, False)
    ofs.close()

    # Run epik on mol2 file
    mae_file_path = output_basepath + '-epik.mae'
    schrodinger.run_epik(mol2_file_path, mae_file_path, tautomerize=False,
                         max_structures=100, min_probability=np.exp(-6), ph=7.4)

    # Convert maestro file to sdf and mol2
    output_sdf_filename = output_basepath + '-epik.sdf'
    output_mol2_filename = output_basepath + '-epik.mol2'
    schrodinger.run_structconvert(mae_file_path, output_sdf_filename)
    schrodinger.run_structconvert(mae_file_path, output_mol2_filename)

    # Read SDF file.
    ifs_sdf = oechem.oemolistream()
    ifs_sdf.SetFormat(oechem.OEFormat_SDF)
    ifs_sdf.open(output_sdf_filename)
    sdf_molecule = oechem.OEMol()
    uncharged_molecules = read_molecules(output_sdf_filename)

    # Read MOL2 file.
    ifs_mol2 = oechem.oemolistream()
    ifs_mol2.open(output_mol2_filename)
    mol2_molecule = oechem.OEMol()
    uncharged_molecules = read_molecules(output_sdf_filename)

    # Assign charges.
    charged_molecules = list()
    index = 0
    while oechem.OEReadMolecule(ifs_sdf, sdf_molecule):
        molecule = oechem.OEReadMolecule(ifs_mol2, mol2_molecule)
        index += 1
        print "Charging molecule %d / %d" % (index, len(uncharged_molecules))
        try:
            # Charge molecule.
            charged_molecule = openeye.get_charges(sdf_molecule, max_confs=800, strictStereo=False, normalize=True, keep_confs=None)

            # Store tags.
            oechem.OECopySDData(charged_molecule, sdf_molecule)

            charged_molecules.append(charged_molecule)
        except Exception as e:
            print(e)
            print("Skipping protomer/tautomer because of failed charging.")

    # Clean up
    ifs_sdf.close()
    ifs_mol2.close()

    # Write molecules.
    charged_mol2_filename = output_basepath + '-epik-charged.mol2'
    ofs = oechem.oemolostream(charged_mol2_filename)
    for (index, charged_molecule) in enumerate(charged_molecules):
        oechem.OEWriteMolecule(ofs, charged_molecule)
    ofs.close()

    # Write state penalites.
    outfile = open(output_basepath + '-state-penalties.out', 'w')
    for (index, charged_molecule) in enumerate(charged_molecules):

        # Get Epik data.
        epik_Ionization_Penalty = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty"))
        epik_Ionization_Penalty_Charging = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty_Charging"))
        epik_Ionization_Penalty_Neutral = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty_Neutral"))
        epik_State_Penalty = float(oechem.OEGetSDData(charged_molecule, "r_epik_State_Penalty"))
        epik_Tot_Q = int(oechem.OEGetSDData(charged_molecule, "i_epik_Tot_Q"))

        outfile.write('%16.8f\n' % epik_State_Penalty)
    outfile.close()
def pack_box(molecules, n_copies, tolerance=2.0, box_size=None, mass_density=None, verbose=False):
    """Run packmol to generate a box containing a mixture of molecules.

    Parameters
    ----------
    molecules : list of OEMol
        Molecules in the system (with 3D geometries)
    n_copies : list of int (same length as 'molecules')
        Number of copies of the molecules
    tolerance : float, optional, default=2.0
        The mininum spacing between molecules during packing.  In ANGSTROMS!
    box_size : simtk.unit.Quantity in units compatible with angstroms
        The size of the box to generate.
        Default generates boxes that are very large for increased stability.
        May require extra time for energy minimization and equilibration.
    mass_density : simtk.unit.Quantity with units compatible with grams/milliliters, optional, default = 1.0*grams/milliliters
        Target mass density for final system, if available.
    verbose : bool, optional, default=False
        If True, verbose output is written.

    Returns
    -------
    topology : simtk.openmm.Topology
        Topology of the resulting system
    positions : simtk.unit.Quantity wrapped [natoms,3] numpy array with units compatible with angstroms
        Single frame trajectory with mixture box.

    """
    assert len(molecules) == len(n_copies), "Length of 'molecules' and 'n_copies' must be identical"

    # Create PDB files for all components
    pdb_filenames = list()
    pdb_flavor = oechem.OEOFlavor_PDB_CurrentResidues | oechem.OEOFlavor_PDB_ELEMENT | oechem.OEOFlavor_PDB_BONDS | oechem.OEOFlavor_PDB_HETBONDS | oechem.OEOFlavor_PDB_BOTH
    for molecule in molecules:
        tmp_filename = tempfile.mktemp(suffix=".pdb")
        pdb_filenames.append(tmp_filename)
        # Write PDB file
        mol_copy = copy.deepcopy(molecule)
        ofs = oechem.oemolostream(tmp_filename)
        ofs.SetFlavor(oechem.OEFormat_PDB, pdb_flavor)
        # Fix residue names
        residue_name = "".join([random.choice(string.ascii_uppercase) for i in range(3)])
        for atom in mol_copy.GetAtoms():
            residue = oechem.OEAtomGetResidue(atom)
            residue.SetName(residue_name)
            oechem.OEAtomSetResidue(atom, residue)
        oechem.OEWriteMolecule(ofs, mol_copy)
        ofs.close()

    # Run packmol
    PACKMOL_PATH = find_executable("packmol")
    if PACKMOL_PATH is None:
        raise(IOError("Packmol not found, cannot run pack_box()"))

    output_filename = tempfile.mktemp(suffix=".pdb")

    # Approximate volume to initialize box
    if (box_size is None):
        if (mass_density is not None):
            # Estimate box_size from mass density.
            box_size = approximate_volume_by_density(molecules, n_copies, mass_density=mass_density)
        else:
            # Use vdW radii to estimate box_size
            box_size = approximate_volume(molecules, n_copies)

    header = HEADER_TEMPLATE % (tolerance, output_filename)
    for (pdb_filename, molecule, count) in zip(pdb_filenames, molecules, n_copies):
        header = header + BOX_TEMPLATE % (pdb_filename, count, box_size / unit.angstroms, box_size / unit.angstroms, box_size / unit.angstroms)

    pwd = os.getcwd()

    if verbose: print(header)

    # Write packmol input
    packmol_filename = "packmol_input.txt"
    packmol_filename = tempfile.mktemp(suffix=".txt")
    file_handle = open(packmol_filename, 'w')
    file_handle.write(header)
    file_handle.close()

    os.system("%s < %s" % (PACKMOL_PATH, packmol_filename))

    # Read the resulting PDB file.
    pdbfile = app.PDBFile(output_filename)

    # Extract topology and positions
    topology = pdbfile.getTopology()
    positions = pdbfile.getPositions()

    return [topology, positions]
示例#56
0
    oechem.OEAddExplicitHydrogens(molecule)
    oechem.OETriposAtomNames(molecule)
    oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye)

    # Create configuration.
    omega = oeomega.OEOmega()
    omega.SetStrictStereo(True)
    omega.SetIncludeInput(False)
    omega(molecule)

    # Create charges.
    oequacpac.OEAssignPartialCharges(molecule, oequacpac.OECharges_AM1BCCSym)

    # Write molecule.
    filename = '%s.tripos.mol2' % name
    print filename
    ofs = oechem.oemolostream()
    ofs.open(filename)
    oechem.OEWriteMolecule(ofs, molecule)
    ofs.close()

    # Replace <0> with resname.
    infile = open(filename, 'r')
    lines = infile.readlines()
    infile.close()
    newlines = [line.replace('<0>', resname) for line in lines]
    outfile = open(filename, 'w')
    outfile.writelines(newlines)
    outfile.close()

def create_openeye_molecule(pdb, options, verbose=True):
    """
    Create OpenEye molecule from PDB representation.

    The molecule will have hydrogens added and be normalized, but the overall geometry will not be altered.

    Parameters
    ----------
    pdb : Pdb
       The PDB-extracted entries for the ligand.

    Returns
    -------
    molecule : openeye.oechem.OEMol
        Molecule representation.
    options : options struct
        Options structure.

    """

    # Create a molecule container.
    molecule = oechem.OEGraphMol()

    # Open a PDB file reader from the stored PDB string representation of HETATM and CONECT records.
    print pdb.pdb_extract
    ifs = oechem.oemolistream()
    ifs.openstring(pdb.pdb_extract)
    flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_PDB_Default | oechem.OEIFlavor_PDB_ALL
    ifs.SetFlavor(oechem.OEFormat_PDB, flavor)
    oechem.OEReadPDBFile(ifs, molecule)

    # Add explicit hydrogens.
    oechem.OEDetermineConnectivity(molecule)
    oechem.OEFindRingAtomsAndBonds(molecule)
    oechem.OEAssignAromaticFlags(molecule) # check aromaticity
    oechem.OEPerceiveBondOrders(molecule)

    # We must assign implicit hydrogens first so that the valence model will be correct.
    oechem.OEAssignImplicitHydrogens(molecule)
    oechem.OEAssignFormalCharges(molecule)

    # Now add explicit hydrogens.
    polarOnly = False
    set3D = True
    oechem.OEAddExplicitHydrogens(molecule, polarOnly, set3D)

    # TODO: Sequentially number hydrogen atoms.

    # Perceive stereochemostry.
    oechem.OEPerceiveChiral(molecule)

    # Set title.
    molecule.SetTitle(options.ligand)

    # Write out PDB form of this molecule.
    # TODO: Fix atom numbering.
    #if verbose: print "Writing input molecule as PDB..."
    #outmol = oechem.OEMol(molecule)
    #ofs = oechem.oemolostream()
    #flavor = oechem.OEOFlavor_Generic_Default | oechem.OEOFlavor_PDB_Default
    #ofs.SetFlavor(oechem.OEFormat_PDB, flavor)
    #ofs.open(options.ligand + '.pdb')
    #oechem.OEWriteMolecule(ofs, outmol)
    #ofs.close()

    # Write mol2 file for this molecule.
    if verbose: print "Writing input molecule as mol2..."
    outmol = oechem.OEMol(molecule)
    ofs = oechem.oemolostream()
    filename = options.ligand + '.mol2'
    ofs.open(filename)
    oechem.OEWriteMolecule(ofs, outmol)
    ofs.close()
    # Use low level writer to get atom names correct.
    ofs = oechem.oemolostream()
    ofs.open(filename)
    for (dest_atom, src_atom) in zip(outmol.GetAtoms(), molecule.GetAtoms()):
        dest_atom.SetName(src_atom.GetName())
    oechem.OEWriteMol2File(ofs, outmol, True)
    ofs.close()
    # Read and write in PDB format.
    if verbose: print "Converting mol2 to PDB..."
    ifs = oechem.oemolistream()
    ofs = oechem.oemolostream()
    if ifs.open(options.ligand + '.mol2'):
        if ofs.open(options.ligand + '.pdb'):
            for mol in ifs.GetOEGraphMols():
                oechem.OEWriteMolecule(ofs, mol)

    return molecule
    return Image(data = "".join(ofs.str()))


# In[15]:

# filters for peroxides, 3-memb-rings, ketals
badSmarts = [ 'OO', '[r3]', '[O&H1]C[O&H1]' ]
badSSlst = [ oechem.OESubSearch( smarts) for smarts in badSmarts]


# In[16]:

fileprefix= 'AlkEthOH_chain'
#fileprefix= 'AlkEthOH_rings'
ifs = oechem.oemolistream(fileprefix+'.smi')
ofs = oechem.oemolostream(fileprefix+'_filt1.smi')
#molLst1 = [ mol for mol in ifs.GetOEMols() ]


# In[17]:

mol = oechem.OEMol()
for mol in ifs.GetOEMols():
    goodMol = True
    for badSS in badSSlst:
        oechem.OEPrepareSearch(mol, badSS)
        if badSS.SingleMatch(mol):
            goodMol = False
            display( depict(mol))
    if goodMol:
        oechem.OEWriteConstMolecule(ofs, mol)
def mk_conformers_epik(options, molecule, maxconf=99, verbose=True, pH=7):
    """
    Enumerate the list of conformers and associated properties for each protonation and tautomeric state using epik from the Schrodinger Suite.

    Parameters
    ----------
    options
    molecule : openeye.oechem
        The molecule read from the PDB whose protomer and tautomer states are to be enumerated.
    maxconf : int, optional, default=128
        Maximum number of protomers/tautomers to generate.
    pH : float, optional, default=7.0
        pH to use for conformer enumeration

    Returns
    -------
    conformers : list of Conformer
        The list of protomers/tautomers generated.

    """

    from schrodinger import structure # Requires Schrodinger Suite

    # Write mol2 file.
    if verbose: print "Writing input file as mol2..."
    outmol = oechem.OEMol(molecule)
    ofs = oechem.oemolostream()
    ofs.open('epik-input.mol2')
    oechem.OEWriteMolecule(ofs, outmol)
    ofs.close()
    # Use low level writer to get atom names correct.
    ofs = oechem.oemolostream()
    ofs.open('epik-input.mol2')
    for (dest_atom, src_atom) in zip(outmol.GetAtoms(), molecule.GetAtoms()):
        dest_atom.SetName(src_atom.GetName())
    oechem.OEWriteMol2File(ofs, outmol, True)
    ofs.close()

    # Write mol2 file.
    if verbose: print "Writing input file as sdf..."
    outmol = oechem.OEMol(molecule)
    ofs = oechem.oemolostream()
    ofs.open('epik-input.sdf')
    oechem.OEWriteMolecule(ofs, outmol)
    ofs.close()

    # Write pdb file.
    if verbose: print "Writing input file as pdb..."
    outmol = oechem.OEMol(molecule)
    ofs = oechem.oemolostream()
    ofs.open('epik-input.pdb')
    oechem.OEWriteMolecule(ofs, outmol)
    ofs.close()

    # Write input for epik.
    if verbose: print "Converting input file to Maestro format..."
    reader = structure.StructureReader("epik-input.mol2")
    writer = structure.StructureWriter("epik-input.mae")
    for st in reader:
        writer.append(st)
    reader.close()
    writer.close()

    # Run epik to enumerate protomers/tautomers and get associated state penalties.
    if verbose: print "Running Epik..."
    cmd = '%s/epik -imae epik-input.mae -omae epik-output.mae -pht 10.0 -ms 100 -nt -pKa_atom -ph %f -WAIT' % (os.environ['SCHRODINGER'], pH)
    output = commands.getoutput(cmd)
    if verbose: print output

    # Convert output from epik from .mae to .sdf.
    if verbose: print "Converting output file to SDF..."
    reader = structure.StructureReader("epik-output.mae")
    writer = structure.StructureWriter("epik-output.sdf")
    for st in reader:
        writer.append(st)
    reader.close()
    writer.close()

    # Also convert to .mol2.
    if verbose: print "Converting output file to MOL2..."
    reader = structure.StructureReader("epik-output.mae")
    writer = structure.StructureWriter("epik-output.mol2")
    for st in reader:
        writer.append(st)
    reader.close()
    writer.close()

    # Find minimum charge.
    ifs = oechem.oemolistream()
    ifs.open('epik-output.mol2')
    molecule = oechem.OEGraphMol()
    min_formal_charge = 1000
    while oechem.OEReadMolecule(ifs, molecule):
        # Check aromaticity.
        oechem.OEAssignAromaticFlags(molecule)

        # Assign formal charge
        oechem.OEAssignFormalCharges(molecule)
        formal_charge = 0
        for atom in molecule.GetAtoms():
            formal_charge += atom.GetFormalCharge()
        # Keep most negative formal charge
        min_formal_charge = min(min_formal_charge, formal_charge)

    ifs.close()
    if verbose: print "Minimum formal charge = %d" % min_formal_charge

    # Read conformers from SDF and mol2 (converted from Epik).
    if verbose: print "Reading conformers from SDF..."
    ifs_sdf = oechem.oemolistream()
    ifs_sdf.SetFormat(oechem.OEFormat_SDF)
    ifs_sdf.open('epik-output.sdf')
    sdf_molecule = oechem.OEGraphMol()

    ifs_mol2 = oechem.oemolistream()
    ifs_mol2.open('epik-output.mol2')
    mol2_molecule = oechem.OEGraphMol()

    conformer_index = 1
    conformers = list()
    while oechem.OEReadMolecule(ifs_sdf, sdf_molecule):
        if verbose: print "Conformer %d" % conformer_index

        # Read corresponding mol2 molecule.
        oechem.OEReadMolecule(ifs_mol2, mol2_molecule)
        oechem.OEAssignAromaticFlags(mol2_molecule) # check aromaticity

        # Make a copy of the mol2 molecule.
        molecule = oechem.OEMol(mol2_molecule)

        # Set name
        name = options.ligand+'%02d' % conformer_index
        molecule.SetTitle(name)

        # Assign formal charge
        oechem.OEAssignFormalCharges(molecule)
        formal_charge = 0.0
        for atom in molecule.GetAtoms():
            formal_charge += atom.GetFormalCharge()
        if verbose: print "formal charge: %d" % formal_charge

        # DEBUG: Write mol2 file before assigning charges.
        if verbose: print "Writing %s to mol2..." % name
        outmol = oechem.OEMol(molecule)
        ofs = oechem.oemolostream()
        ofs.open(name + '.mol2')
        oechem.OEWriteMolecule(ofs, outmol)
        ofs.close()

        # Assign canonical AM1BCC charges.
        try:
            if verbose: print "Assigning AM1-BCC charges..."
            #assign_canonical_am1bcc_charges(molecule)
            assign_simple_am1bcc_charges(molecule)
        except Exception as e:
            print str(e)
            continue

        # Get Epik data.
        epik_Ionization_Penalty = float(oechem.OEGetSDData(sdf_molecule, "r_epik_Ionization_Penalty"))
        epik_Ionization_Penalty_Charging = float(oechem.OEGetSDData(sdf_molecule, "r_epik_Ionization_Penalty_Charging"))
        epik_Ionization_Penalty_Neutral = float(oechem.OEGetSDData(sdf_molecule, "r_epik_Ionization_Penalty_Neutral"))
        epik_State_Penalty = float(oechem.OEGetSDData(sdf_molecule, "r_epik_State_Penalty"))
        epik_Tot_Q = int(oechem.OEGetSDData(sdf_molecule, "i_epik_Tot_Q"))

        # Compute number of protons.
        nprotons = epik_Tot_Q - min_formal_charge + 1

        # Compute effective pKa.
        import numpy as np
        kT = 298 * 6.022e23 * 1.381e-23 / 4184 # kcal/mol for 298 K
        pKa = options.pH - epik_State_Penalty / (nprotons * kT * np.log(10))
        print "effective pKa = %8.3f" % pKa

        # DEBUG
        print "%24s : pKa penalty %8.3f kcal/mol | tautomer penalty %8.3f kcal/mol | total state penalty %8.3f\n" % (name, epik_Ionization_Penalty, epik_State_Penalty - epik_Ionization_Penalty, epik_State_Penalty)

        # Create a conformer and append it to the list.
        conformer = Conformer(name, epik_Tot_Q, molecule, state_penalty=epik_State_Penalty)
        conformers.append(conformer)
        print epik_Tot_Q # DEBUG
        # Increment counter.
        conformer_index += 1

    ifs_sdf.close()
    ifs_mol2.close()

    if verbose: print "%d protomer/tautomer states were enumerated" % len(conformers)

    return conformers
def generateResidueTemplate(molecule, residue_atoms=None):
    """
    Generate an residue template for simtk.openmm.app.ForceField using GAFF/AM1-BCC.

    This requires the OpenEye toolkit.

    Parameters
    ----------
    molecule : openeye.oechem.OEMol
        The molecule to be parameterized.
        The molecule must have explicit hydrogens.
        Charge will be inferred from the net formal charge.
    residue_atomset : set of OEAtom, optional, default=None
        If not None, only the atoms in this set will be used to construct the residue template

    Returns
    -------
    template : simtk.openmm.app.forcefield._TemplateData
        Residue template for ForceField using atom types and parameters from `gaff.xml`.
    additional_parameters_ffxml : str
        Contents of ForceField `ffxml` file defining additional parameters from parmchk(2).

    Note that this method preserves stereochemistry during AM1-BCC charge parameterization.

    """
    # Generate a unique residue template name to avoid namespace collisions.
    # TODO: Can we come up with a more intelligent name?
    #from uuid import uuid4
    #template_name = str(uuid4())
    template_name = molecule.GetTitle()

    # Compute net formal charge.
    from openeye import oechem
    oechem.OEAssignFormalCharges(molecule)
    charges = [ atom.GetFormalCharge() for atom in molecule.GetAtoms() ]
    net_charge = np.array(charges).sum()

    # Generate canonical AM1-BCC charges and a reference conformation.
    molecule = get_charges(molecule, strictStereo=False, keep_confs=1)

    # Create temporary directory for running antechamber.
    import tempfile
    tmpdir = tempfile.mkdtemp()
    input_mol2_filename = os.path.join(tmpdir, template_name + '.tripos.mol2')
    gaff_mol2_filename = os.path.join(tmpdir, template_name + '.gaff.mol2')
    frcmod_filename = os.path.join(tmpdir, template_name + '.frcmod')

    # Write Tripos mol2 file as antechamber input.
    ofs = oechem.oemolostream(input_mol2_filename)
    oechem.OEWriteMolecule(ofs, molecule)
    ofs.close()

    # Parameterize the molecule with antechamber.
    run_antechamber(template_name, input_mol2_filename, charge_method=None, net_charge=net_charge, gaff_mol2_filename=gaff_mol2_filename, frcmod_filename=frcmod_filename)

    # Read the resulting GAFF mol2 file as a ParmEd structure.
    ifs = oechem.oemolistream(gaff_mol2_filename)
    ifs.SetFlavor(oechem.OEFormat_MOL2, oechem.OEIFlavor_MOL2_DEFAULT | oechem.OEIFlavor_MOL2_M2H | oechem.OEIFlavor_MOL2_Forcefield)
    m2h = True
    oechem.OEReadMolecule(ifs, molecule)
    ifs.close()

    # If residue_atoms = None, add all atoms to the residues
    if residue_atoms == None:
        residue_atoms = [ atom for atom in molecule.GetAtoms() ]

    # Modify partial charges so that charge on residue atoms is integral.
    residue_charge = 0.0
    sum_of_absolute_charge = 0.0
    for atom in residue_atoms:
        charge = atom.GetPartialCharge()
        residue_charge += charge
        sum_of_absolute_charge += abs(charge)
    excess_charge = residue_charge - net_charge
    if sum_of_absolute_charge == 0.0:
        sum_of_absolute_charge = 1.0
    for atom in residue_atoms:
        charge = atom.GetPartialCharge()
        atom.SetPartialCharge( charge + excess_charge * (abs(charge) / sum_of_absolute_charge) )

    # Create residue template.
    template = ForceField._TemplateData(template_name)
    for (index, atom) in enumerate(molecule.GetAtoms()):
        atomname = atom.GetName()
        typename = atom.GetType()
        element = Element.getByAtomicNumber(atom.GetAtomicNum())
        charge = atom.GetPartialCharge()
        parameters = { 'charge' : charge }
        atom_template = ForceField._TemplateAtomData(atomname, typename, element, parameters)
        template.atoms.append(atom_template)
    for bond in molecule.GetBonds():
        if (bond.GetBgn() in residue_atoms) and (bond.GetEnd() in residue_atoms):
            template.addBondByName(bond.GetBgn().GetName(), bond.GetEnd().GetName())
        elif (bond.GetBgn() in residue_atoms) and (bond.GetEnd() not in residue_atoms):
            template.addExternalBondByName(bond.GetBgn().GetName())
        elif (bond.GetBgn() not in residue_atoms) and (bond.GetEnd() in residue_atoms):
            template.addExternalBondByName(bond.GetEnd().GetName())

    # Generate ffxml file contents for parmchk-generated frcmod output.
    leaprc = StringIO("parm = loadamberparams %s" % frcmod_filename)
    params = parmed.amber.AmberParameterSet.from_leaprc(leaprc)
    params = parmed.openmm.OpenMMParameterSet.from_parameterset(params)
    ffxml = StringIO()
    params.write(ffxml)

    return template, ffxml.getvalue()