Beispiel #1
0
def generate_enantiomers(
    molecule: oechem.OEGraphMol,
    max_centers: int = 12,
    force_flip: bool = False,
    enumerate_nitrogens: bool = True,
) -> List[oechem.OEGraphMol]:
    """
    Generate enantiomers of a given molecule.
    Parameters
    ----------
    molecule: oechem.OEGraphMol
        An OpenEye molecule.
    max_centers: int
        The maximal number of stereo centers to enumerate.
    force_flip: bool
        If specified stereo centers should be ignored.
    enumerate_nitrogens: bool
        If nitrogens with invertible pyramidal geometry should be enumerated.
    Returns
    -------
    enantiomers: list of oechem.OEGraphMol
        A list of OpenEye molecules holding the enantiomers.
    """
    from openeye import oechem, oeomega

    enantiomers = [
        oechem.OEGraphMol(enantiomer) for enantiomer in oeomega.OEFlipper(
            molecule, max_centers, force_flip, enumerate_nitrogens)
    ]
    return enantiomers
def expand_stereochemistry(mols):
    """Expand stereochemistry when uncertain

    Parameters
    ----------
    mols : openeye.oechem.OEGraphMol
        Molecules to be expanded

    Returns
    -------
    expanded_mols : openeye.oechem.OEMol
        Expanded molecules
    """
    expanded_mols = list()

    from openeye import oechem, oeomega
    omegaOpts = oeomega.OEOmegaOptions()
    omega = oeomega.OEOmega(omegaOpts)
    maxcenters = 12
    forceFlip = False
    enumNitrogen = True
    warts = True # add suffix for stereoisomers
    for mol in mols:
        for enantiomer in oeomega.OEFlipper(mol, maxcenters, forceFlip, enumNitrogen, warts):
            enantiomer = oechem.OEMol(enantiomer)
            expanded_mols.append(enantiomer)

    return expanded_mols
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.OEOmegaOptions()
    omega = oeomega.OEOmega(omegaOpts)

    for mol in ifs.GetOEMols():
        oechem.OEThrow.Info("Title: %s" % mol.GetTitle())

        for enantiomer in oeomega.OEFlipper(mol.GetActive(), 12, True):
            enantiomer = oechem.OEMol(enantiomer)
            ret_code = omega.Build(enantiomer)
            if ret_code == oeomega.OEOmegaReturnCode_Success:
                oechem.OEWriteMolecule(ofs, enantiomer)
            else:
                oechem.OEThrow.Warning(
                    "%s: %s" %
                    (enantiomer.GetTitle(), oeomega.OEGetOmegaError(ret_code)))

    return 0
Beispiel #4
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
Beispiel #5
0
def enumerate_from_smiles(smiles, oe_options=None):
    oe_options = oe_options or OEOptions()

    omegaOpts = oeomega.OEOmegaOptions(oeomega.OEOmegaSampling_Pose)
    omegaOpts.SetMaxSearchTime(60)
    omega = oeomega.OEOmega(omegaOpts)

    if oe_options.use_tautomer:
        tautomer_options = oequacpac.OETautomerOptions()
        pKa_norm = True
        taut_iter = lambda x: oequacpac.OEGetReasonableTautomers(x, tautomer_options, pKa_norm)
    else:
        taut_iter = lambda x: [x]

    if oe_options.use_flipper:
        flipper = lambda x: oeomega.OEFlipper(x.GetActive(), oe_options.num_sterocenters, oe_options.force_flipper)
    else:
        flipper = lambda x: [x]

    # get molecule
    try:
        molecule = mol_from_smiles(smiles)
    except ValueError:
        return [None]

    results = []
    for enantiomer in flipper(molecule):
        for tautomer in taut_iter(enantiomer):
            tautomer = oechem.OEMol(tautomer)
            omega.Build(tautomer)
            tautomer2 = oechem.OEMol(tautomer)
            results.append(tautomer2)
    return results
Beispiel #6
0
def FromMol(mol, use_flipper=True, num_sterocenters=12, force_flipper=False):
    """
    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.SetMaxConfRange("200,800")
    omegaOpts.SetRangeIncrement(8)
    omegaOpts.SetMaxSearchTime(30)
    omega = oeomega.OEOmega(omegaOpts)

    out_conf = []

    for enantiomer in oeomega.OEFlipper(mol.GetActive(), num_sterocenters,
                                        force_flipper):
        enantiomer = oechem.OEMol(enantiomer)
        ret_code = omega.Build(enantiomer)
        if ret_code == oeomega.OEOmegaReturnCode_Success:
            out_conf.append(enantiomer)

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

    return out_conf
Beispiel #7
0
    def from_oemol(self, from_oemol):
        with self.logger("from_oemol") as logger:
            tautomer_options = oequacpac.OETautomerOptions()
            tautomer_options.SetMaxTautomersGenerated(4096)
            tautomer_options.SetMaxTautomersToReturn(16)
            tautomer_options.SetCarbonHybridization(True)
            tautomer_options.SetMaxZoneSize(50)
            tautomer_options.SetApplyWarts(True)

            pKa_norm = True

            omegaOpts = oeomega.OEOmegaOptions(oeomega.OEOmegaSampling_Pose)
            omegaOpts.SetStrictAtomTypes(False)
            omegaOpts.SetSampleHydrogens(True)
            omegaOpts.SetMaxSearchTime(30)
            omegaOpts.SetFixDeleteH(True)
            omega = oeomega.OEOmega(omegaOpts)

            options = oeshape.OEROCSOptions()
            overlayoptions = oeshape.OEOverlayOptions()
            overlayoptions.SetOverlapFunc(
                oeshape.OEOverlapFunc(oeshape.OEAnalyticShapeFunc()))
            options.SetOverlayOptions(overlayoptions)
            # options.SetNumBestHits(10)
            options.SetConfsPerHit(200)
            # options.SetMaxHits(10000)
            rocs = oeshape.OEROCS(options)
            for tautomer in oequacpac.OEGetReasonableTautomers(
                    from_oemol, tautomer_options, pKa_norm):
                logger.log("got enantiomer")
                for enantiomer in oeomega.OEFlipper(tautomer, 4, False):
                    logger.log("got tautomer ")
                    enantiomer_ = oechem.OEMol(enantiomer)
                    ret_code = omega.Build(enantiomer_)
                    if ret_code != oeomega.OEOmegaReturnCode_Success:
                        logger.error("got oemeg_failed",
                                     oeomega.OEGetOmegaError(ret_code))
                    else:
                        rocs.AddMolecule(oechem.OEMol(enantiomer_))

            for res in rocs.Overlay(self.refmol):
                outmol = oechem.OEMol(res.GetOverlayConfs())
                good_mol = oechem.OEMol(outmol)
                oechem.OEAddExplicitHydrogens(good_mol)
                oechem.OEClearSDData(good_mol)
                oeshape.OEDeleteCompressedColorAtoms(good_mol)
                oeshape.OEClearCachedSelfColor(good_mol)
                oeshape.OEClearCachedSelfShape(good_mol)
                oeshape.OERemoveColorAtoms(good_mol)
                return good_mol
            logger.error("Returning None.")

        return None
Beispiel #8
0
def expand_stereochemistry(mols):
    """Expand stereochemistry when uncertain

    Parameters
    ----------
    mols : openeye.oechem.OEGraphMol
        Molecules to be expanded

    Returns
    -------
    expanded_mols : openeye.oechem.OEMol
        Expanded molecules
    """
    expanded_mols = list()

    from openeye import oechem, oeomega
    omegaOpts = oeomega.OEOmegaOptions()
    omega = oeomega.OEOmega(omegaOpts)
    maxcenters = 12
    forceFlip = False
    enumNitrogen = False
    warts = True  # add suffix for stereoisomers
    for mol in mols:
        compound_title = mol.GetTitle()
        compound_smiles = oechem.OEMolToSmiles(mol)

        enantiomers = list()
        for enantiomer in oeomega.OEFlipper(mol, maxcenters, forceFlip,
                                            enumNitrogen, warts):
            enantiomer = oechem.OEMol(enantiomer)
            enantiomer_smiles = oechem.OEMolToSmiles(enantiomer)
            oechem.OESetSDData(enantiomer, 'compound', compound_title)
            oechem.OESetSDData(enantiomer, 'compound_smiles', compound_smiles)
            oechem.OESetSDData(enantiomer, 'enantiomer_smiles',
                               enantiomer_smiles)
            enantiomers.append(enantiomer)

        expanded_mols += enantiomers

        # DEBUG
        if 'EDJ-MED-e4b030d8-2' in mol.GetTitle():
            msg = 'Enumerated microstates for compound: '
            msg += mol.GetTitle() + '\n'
            msg += f'{"":5s}   ' + oechem.OEMolToSmiles(mol) + '\n'
            for index, m in enumerate(enantiomers):
                msg += f'{index:5d} : ' + oechem.OEMolToSmiles(m) + '\n'
            print(msg)

    return expanded_mols
Beispiel #9
0
def gen_conf(mol):
    oemols = []
    omegaOpts = oeomega.OEOmegaOptions(oeomega.OEOmegaSampling_FastROCS)
    omega = oeomega.OEOmega(omegaOpts)
    for enantiomer in oeomega.OEFlipper(mol.GetActive(), 6, True):
        enantiomer = oechem.OEMol(enantiomer)
        ret_code = omega.Build(enantiomer)
        if ret_code == oeomega.OEOmegaReturnCode_Success:
            halfMol = oechem.OEMol(mol, oechem.OEMCMolType_HalfFloatCartesian)
            oemols.append(halfMol)
        else:
            oechem.OEThrow.Warning(
                "%s: %s" %
                (enantiomer.GetTitle(), oeomega.OEGetOmegaError(ret_code)))
    return oemols
def expand_stereochemistry(mols):
    """Expand stereochemistry when uncertain

    Parameters
    ----------
    mols : openeye.oechem.OEGraphMol
        Molecules to be expanded

    Returns
    -------
    expanded_mols : openeye.oechem.OEMol
        Expanded molecules
    """
    expanded_mols = list()

    from openeye import oechem, oeomega
    omegaOpts = oeomega.OEOmegaOptions()
    omega = oeomega.OEOmega(omegaOpts)
    maxcenters = 12
    forceFlip = False
    enumNitrogen = True
    warts = True  # add suffix for stereoisomers
    for mol in mols:
        compound_title = mol.GetTitle()
        compound_smiles = oechem.OEMolToSmiles(mol)

        enantiomers = list()
        for enantiomer in oeomega.OEFlipper(mol, maxcenters, forceFlip,
                                            enumNitrogen, warts):
            enantiomer = oechem.OEMol(enantiomer)
            enantiomer_smiles = oechem.OEMolToSmiles(enantiomer)
            oechem.OESetSDData(enantiomer, 'compound', compound_title)
            oechem.OESetSDData(enantiomer, 'compound_smiles', compound_smiles)
            oechem.OESetSDData(enantiomer, 'enantiomer_smiles',
                               enantiomer_smiles)
            enantiomers.append(enantiomer)

        expanded_mols += enantiomers

    return expanded_mols
Beispiel #11
0
def _enumerate_stereoisomers(molecule,
                             max_states=200,
                             force_flip=True,
                             enum_nitrogen=True,
                             warts=True,
                             verbose=True):
    """
    Enumerate stereoisomers
    Parameters
    ----------
    molecule : OEMol
    max_states : int, optional, default 200
        max number of states to enumerate
    force_flip : bool, optional, default True
        If True, will flip all steocenters. If False, will only flip centers that are undefined
    enum_nitrogen : bool, optional, default True
        Invert non-planar nitrogen
    warts : bool, optional, default True
        If True, add int to molecule name
    verbose : bool, optional, default True

    Returns
    -------
    stereoisomers: list of oemols

    """
    from openeye import oeomega, oechem
    stereoisomers = []
    if verbose:
        logger().debug("Enumerating stereoisomers...")
    i = 0
    for enantiomer in oeomega.OEFlipper(molecule, max_states, force_flip,
                                        enum_nitrogen, warts):
        i += 1
        enantiomer = oechem.OEMol(enantiomer)
        stereoisomers.append(enantiomer)
    return stereoisomers
Beispiel #12
0
def compute_conformers(smiles=None, smiles_file=None, start_index=0, batch_size=0, out_file=None, bad_file=None, save_csv=False,  overwrite=False, save_gzip=False, license=None, timeout=0, max_failures=2):
    import csv
    import os
    from openeye import oechem
    from openeye import oeomega
    from openeye import oemolprop
    import signal

    os.environ['OE_LICENSE'] = license    
    
    if save_gzip or save_csv: 
        raise Exception("GZip and CSV not supported")
 
    if not overwrite and  os.path.exists(out_file):
        raise Exception("File exists: %s" % out_file)

    if smiles_file: 
        with open(smiles_file) as current:
            current.seek(start_index)
            smiles = [current.readline() for i in range(batch_size)]
    
    if len(smiles) == 0: 
        return ""

    # function to compute enantiomers
    # separated out so we can use an alarm to timeout
    def get_enan(omega, enan):
        enan = oechem.OEMol(enan)
        ret = omega.Build(enan)
        return enan, ret


    def alarm_handler(signum, frame):
        #print("ALARM signal received")
        raise Exception()

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

    sep = ","
    bad = []
    mols = []
    for s in smiles:
        mol = s.split(sep)
        if len(mol) > 1: 
            mols.append(mol[2].rstrip())

    # put all mols in a string as we're told it is faster to process this way
    in_smiles = "\n".join(mols)

    ims = oechem.oemolistream()
    ims.SetFormat(oechem.OEFormat_SMI)
    ims.openstring(in_smiles)

    # Turn off logging except errors
    oechem.OEThrow.SetLevel(5)

    filt = oemolprop.OEFilter(oemolprop.OEFilterType_BlockBuster)
    #ofs.open(out_file)
    signal.signal(signal.SIGALRM, alarm_handler)
    oe_results = []
    for mol in ims.GetOEMols():
        if filt(mol):
            oemols = []
            ret_code = None
            omegaOpts = oeomega.OEOmegaOptions(oeomega.OEOmegaSampling_FastROCS)
            omega = oeomega.OEOmega(omegaOpts)
            
            failures = 0
            for enantiomer in oeomega.OEFlipper(mol.GetActive(), 6, True):
                if max_failures > 0 and failures >= max_failures: 
                    break
                if len(oemols) >= 10:
                    break

                ret_code = None
                error = False
                signal.alarm(timeout)
                try: 
                    enantiomer, ret_code = get_enan(omega, enantiomer)
                except:
                    print("Timeout %s" % out_file) 
                    failures += 1
                    error = True
                signal.alarm(0)

                if not error and ret_code == oeomega.OEOmegaReturnCode_Success:
                    halfMol = oechem.OEMol(mol, oechem.OEMCMolType_HalfFloatCartesian)
                    oemols.append(halfMol)
                #else:
                    #oechem.OEThrow.Warning("%s: %s" %
                    #    (enantiomer.GetTitle(), oeomega.OEGetOmegaError(ret_code)))
                oe_results.append(oemols)

    ofs = oechem.oemolostream()
    ofs.SetFormat(oechem.OEFormat_OEB)
    ofs.open(out_file)
    for r in oe_results: 
        for res in r:
            oechem.OEWriteMolecule(ofs, res)

    ofs.close()
 
    return out_file
Beispiel #13
0
def _expand_states(molecules, enumerate='protonation', max_states=200, suppress_hydrogen=True, reasonable=True,
                   carbon_hybridization=True, level=0, verbose=True):
    """
    Expand the state specified by enumerate variable

    Parameters
    ----------
    molecules: OEMol or list of OEMol
        molecule to expand states
    enumerate: str, optional, default='protonation'
        Kind of state to enumerate. Choice of protonation, tautomers, stereoiserms
    suppress_hydrogen: bool, optional, default=True
        If True, will suppress explicit hydrogen
    reasonable: bool, optional, default=True
        If True, will rank tautomers by the most reasonable energetically
    carbon_hybridization: bool, optional, default=True
        If True, will allow carbon to change hybridization
    max_states: int, optional, default=200
    verbose: Bool, optional, deault=TRue

    Returns
    -------
    states: list of OEMol
        enumerated states

    """
    if type(molecules) != type(list()):
        molecules = [molecules]

    states = list()
    for molecule in molecules:
        ostream = oechem.oemolostream()
        ostream.openstring()
        ostream.SetFormat(oechem.OEFormat_SDF)
        states_enumerated = 0
        if suppress_hydrogen:
            oechem.OESuppressHydrogens(molecule)
        if enumerate == 'protonation':
            formal_charge_options = oequacpac.OEFormalChargeOptions()
            formal_charge_options.SetMaxCount(max_states)
            formal_charge_options.SetVerbose(verbose)
            if verbose:
                logger().debug("Enumerating protonation states...")
            for protonation_state in oequacpac.OEEnumerateFormalCharges(molecule, formal_charge_options):
                states_enumerated += 1
                oechem.OEWriteMolecule(ostream, protonation_state)
                states.append(protonation_state)
        if enumerate == 'tautomers':
            #max_zone_size = molecule.GetMaxAtomIdx()
            tautomer_options = oequacpac.OETautomerOptions()
            tautomer_options.SetMaxTautomersGenerated(max_states)
            tautomer_options.SetLevel(level)
            tautomer_options.SetRankTautomers(reasonable)
            tautomer_options.SetCarbonHybridization(carbon_hybridization)
            #tautomer_options.SetMaxZoneSize(max_zone_size)
            tautomer_options.SetApplyWarts(True)
            if verbose:
                logger().debug("Enumerating tautomers...")
            for tautomer in oequacpac.OEEnumerateTautomers(molecule, tautomer_options):
                states_enumerated += 1
                states.append(tautomer)
        if enumerate == 'stereoisomers':
            if verbose:
                logger().debug("Enumerating stereoisomers...")
            for enantiomer in oeomega.OEFlipper(molecule, max_states, True):
                states_enumerated += 1
                enantiomer = oechem.OEMol(enantiomer)
                oechem.OEWriteMolecule(ostream, enantiomer)
                states.append(enantiomer)

    return states