Exemplo n.º 1
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
Exemplo n.º 2
0
def generate_tautomers(molecule: oechem.OEGraphMol) -> List[oechem.OEGraphMol]:
    """
    Generate reasonable tautomers of a given molecule.
    Parameters
    ----------
    molecule: oechem.OEGraphMol
        An OpenEye molecule.
    Returns
    -------
    tautomers: list of oechem.OEGraphMol
        A list of OpenEye molecules holding the tautomers.
    """
    from openeye import oechem, oequacpac

    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
    tautomers = [
        oechem.OEGraphMol(tautomer)
        for tautomer in oequacpac.OEGetReasonableTautomers(
            molecule, tautomer_options, pKa_norm)
    ]
    return tautomers
def main(argv=[__name__]):
    if len(argv) != 3:
        oechem.OEThrow.Usage("%s <mol-infile> <mol-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])

    # @ <SNIPPET-EnumerateTautomersWithOptions>
    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

    for mol in ifs.GetOEGraphMols():
        for tautomer in oequacpac.OEGetReasonableTautomers(
                mol, tautomer_options, pKa_norm):
            # work with tautomer
            # @ </SNIPPET-EnumerateTautomersWithOptions>
            oechem.OEWriteMolecule(ofs, tautomer)
    return 0
Exemplo n.º 4
0
def _enumerate_tautomers(molecule, max_states=200, pka_norm=True, warts=True):
    """
    Expand reasonable tautomer states. This function generates tautomers (which might be different ionization states
    than parent) that are normalized to the predominant state at pH ~7.4
    Parameters
    ----------
    molecule : OEMol to expand states
    max_states : int
        max number of states
    pka_norm: bool, optional, default True
    warts: bool, optional default True

    Returns
    -------
    tautomers: list of oemols

    """
    from openeye import oequacpac

    tautomers = []
    tautomer_options = oequacpac.OETautomerOptions()
    tautomer_options.SetApplyWarts(warts)
    tautomer_options.SetMaxTautomersGenerated(max_states)
    for tautomer in oequacpac.OEGetReasonableTautomers(molecule,
                                                       tautomer_options,
                                                       pka_norm):
        tautomers.append(tautomer)
    return tautomers
Exemplo n.º 5
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
def dock_molecule_to_receptor(molecule, receptor_filename, covalent=False):
    """
    Dock the specified molecules, writing out to specified file

    Parameters
    ----------
    molecule : oechem.OEMol
        The molecule to dock
    receptor_filename : str
        Receptor to dock to
    covalent : bool, optional, default=False
        If True, try to place covalent warheads in proximity to CYS145

    Returns
    -------
    docked_molecule : openeye.oechem.OEMol
        Returns the best tautomer/protomer in docked geometry, annotated with docking score
        None is returned if no viable docked pose found
    """
    import os

    # Extract the fragment name for the receptor
    fragment = extract_fragment_from_filename(receptor_filename)

    # Read the receptor
    from openeye import oechem, oedocking
    receptor = oechem.OEGraphMol()
    if not oedocking.OEReadReceptorFile(receptor, receptor_filename):
        oechem.OEThrow.Fatal("Unable to read receptor")
    #print(f'Receptor has {receptor.NumAtoms()} atoms')

    if not oedocking.OEReceptorHasBoundLigand(receptor):
        raise Exception("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)

    # Add covalent restraint if specified
    warheads_found = find_warheads(molecule)
    if covalent and len(warheads_found) > 0:
        warheads_found = set(warheads_found.keys())

        # Initialize covalent constraints
        customConstraints = oedocking.OEReceptorGetCustomConstraints(receptor)

        # Find CYS145 SG atom
        hv = oechem.OEHierView(receptor)
        hres = hv.GetResidue("A", "CYS", 145)
        proteinHeavyAtom = None
        for atom in hres.GetAtoms():
            if atom.GetName().strip() == 'SG':
                proteinHeavyAtom = atom
                break
        if proteinHeavyAtom is None:
            raise Exception('Could not find CYS145 SG')

        # Add the constraint
        feature = customConstraints.AddFeature()
        feature.SetFeatureName("CYS145 proximity")
        for warhead_type in warheads_found:
            smarts = covalent_warhead_smarts[warhead_type]
            print(f'Adding constraint for SMARTS pattern {smarts}')
            feature.AddSmarts(smarts)
        sphereRadius = 4.0 # Angstroms
        sphereCenter = oechem.OEFloatArray(3)
        receptor.GetCoords(proteinHeavyAtom, sphereCenter)
        sphere = feature.AddSphere()
        sphere.SetRad(sphereRadius)
        sphere.SetCenter(sphereCenter[0], sphereCenter[1], sphereCenter[2])
        oedocking.OEReceptorSetCustomConstraints(receptor, customConstraints)

    # Enumerate tautomers
    from openeye import oequacpac
    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
    tautomers = [ oechem.OEMol(tautomer) for tautomer in oequacpac.OEGetReasonableTautomers(molecule, tautomer_options, pKa_norm) ]

    # Set up Omega
    #print('Expanding conformers...')
    from openeye import oeomega
    #omegaOpts = oeomega.OEOmegaOptions(oeomega.OEOmegaSampling_Dense)
    omegaOpts = oeomega.OEOmegaOptions()
    #omegaOpts.SetMaxConfs(5000)
    omegaOpts.SetMaxSearchTime(60.0) # time out
    omega = oeomega.OEOmega(omegaOpts)
    omega.SetStrictStereo(False) # enumerate sterochemistry if uncertain

    # Dock tautomers
    docked_molecules = list()
    from tqdm import tqdm
    for mol in tautomers:
        dockedMol = oechem.OEGraphMol()

        # Expand conformers
        omega.Build(mol)

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

        # Store docking data
        sdtag = oedocking.OEDockMethodGetName(dockMethod)
        oedocking.OESetSDScore(dockedMol, dock, sdtag)
        oechem.OESetSDData(dockedMol, "docked_fragment", fragment)
        dock.AnnotatePose(dockedMol)

        docked_molecules.append( dockedMol.CreateCopy() )

    if len(docked_molecules) == 0:
        return None

    # Select the best-ranked molecule and pose
    # Note that this ignores protonation state and tautomer penalties
    docked_molecules.sort(key=score)
    best_molecule = docked_molecules[0]

    return best_molecule
Exemplo n.º 7
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
Exemplo n.º 8
0
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
Exemplo n.º 9
0
def run_docking(receptor,
                molecules,
                dock_method,
                num_poses=1,
                docking_poses_save_path=None):
    """
    Dock molecules into a prepared receptor.

    Parameters
    ----------
    receptor: oechem.OEGraphMol
        An oechem.OEGraphMol object holding the prepared receptor.

    molecules: list of oechem.OEGraphMol
        A list of oechem.OEGraphMol objects holding prepared molecules for docking.

    dock_method: int
        Constant defining the docking method.

    num_poses: int
        Number of docking poses to generate per molecule.

    docking_poses_save_path: str
        File path for saving docking poses. If docking_poses_save_path is not provided, docking poses will not be saved.

    Returns
    -------
    docked_molecules: list of oechem.OEGraphMol
        A list of oechem.OEGraphMol objects holding the docked molecules.
    """
    # Standard libraries
    import pathlib

    # External libraries
    from openeye import oechem, oedocking, oequacpac, oeomega

    # initialize receptor
    dock_resolution = oedocking.OESearchResolution_High
    dock = oedocking.OEDock(dock_method, dock_resolution)
    dock.Initialize(receptor)

    def score(molecule, dock=dock):
        """Return the docking score."""
        value = oechem.OEGetSDData(molecule, dock.GetName())
        return float(value)

    docked_molecules = list()

    # dock molecules
    for molecule in molecules:
        # enumerate tautomers
        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
        tautomers = [
            oechem.OEMol(tautomer)
            for tautomer in oequacpac.OEGetReasonableTautomers(
                molecule, tautomer_options, pKa_norm)
        ]

        # set up omega
        omega_options = oeomega.OEOmegaOptions()
        omega_options.SetMaxSearchTime(60.0)  # time out
        omega = oeomega.OEOmega(omega_options)
        omega.SetStrictStereo(False)  # enumerate stereochemistry if uncertain

        docked_tautomers = list()
        # dock tautomers
        for mol in tautomers:
            docked_mol = oechem.OEMol()
            # expand conformers
            omega.Build(mol)

            # dock molecule
            return_code = dock.DockMultiConformerMolecule(
                docked_mol, mol, num_poses)
            if return_code != oedocking.OEDockingReturnCode_Success:
                print(
                    f'Docking failed for molecule with title {mol.GetTitle()} with error code '
                    f'{oedocking.OEDockingReturnCodeGetName(return_code)}.')
                continue

            # store docking data
            oedocking.OESetSDScore(docked_mol, dock, dock.GetName())

            # expand conformations
            for conformation in docked_mol.GetConfs():
                docked_tautomers.append(oechem.OEGraphMol(conformation))

        # sort all conformations of all tautomers by score
        docked_tautomers.sort(key=score)

        # keep number of conformations as specified by num_poses
        docked_molecules += docked_tautomers[:num_poses]

    if len(docked_molecules) == 0:
        return None

    # save docking poses
    if docking_poses_save_path is not None:
        write_mols(docked_molecules,
                   str(pathlib.Path(docking_poses_save_path).absolute()))

    return docked_molecules