Beispiel #1
0
    def _load_verify_openeye(self, oechemlicensepath=None):
        """Loads required OpenEye libraries and checks licenses

        Parameters
        ----------
        oechemlicensepath : str, optional, default=None
            OpenEye license path to use, or None if environment variables are to be used.

        Raises
        ------
        RuntimeError
            If OE_LICENSE is not found as an environment variable
            If A valid license is missing

        Notes
        -----
        Needs to be run before any of the other functions to assure OpenEye libraries are accessible.

        """

        # Don't do anything if we've already imported OpenEye toolkit.
        if self.oechem: return

        try:
            # Import the OpenEye toolkit components.
            from openeye import oechem     # For chemical objects
            from openeye import oeiupac    # For IUPAC conversion
            from openeye import oeomega    # For conformer generation
            from openeye import oequacpac  # For pKa estimations
        except Exception as e:
            raise Exception("Could not import `openeye` library.  Make sure OpenEye Python Toolkit is installed and on PYTHONPATH.")

        import os

        if oechemlicensepath is not None:
            os.environ['OE_LICENSE'] = oechemlicensepath

        try:
            os.environ['OE_LICENSE']  # See if license path is set.
        except KeyError:
            raise RuntimeError("Environment variable OE_LICENSE needs to be set.")

        if not oechem.OEChemIsLicensed():  # Check for OEchem TK license.
            raise RuntimeError("No valid license available for OEChem TK.")

        if not oeiupac.OEIUPACIsLicensed():  # Check for Lexichem TK license.
            raise RuntimeError("No valid license available for Lexichem TK.")

        if not oeomega.OEOmegaIsLicensed():  # Check for Omega TK license.
            raise RuntimeError("No valid license for Omega TK.")

        if not oequacpac.OEQuacPacIsLicensed():  # Check for Quacpac TK license.
            raise RuntimeError("No valid license for Quacpac TK.")

        #Attach libraries to the instance to only load and check them once at initialization.
        self.oechem = oechem
        self.oeiupac = oeiupac
        self.oeomega = oeomega
        self.oequacpac = oequacpac
        return
Beispiel #2
0
def is_openeye_installed():
    try:
        from openeye import oechem
        from openeye import oequacpac
        from openeye import oeiupac
        from openeye import oeomega

        if not (oechem.OEChemIsLicensed() and oequacpac.OEQuacPacIsLicensed()
                and oeiupac.OEIUPACIsLicensed()
                and oeomega.OEOmegaIsLicensed()):
            raise ImportError
    except ImportError:
        return False
    return True
Beispiel #3
0
def get_unique_protomer(molecule):
    """
    Generate unique protomer for all tuatomers and charge states of the moelcule.

    **Requires openeye license**


    Parameters
    ----------
    molecule: oechem.OEMol
        Will convert `rdkit.Chem.Mol` to `oechem.OEMol` if openeye is installed and license is valid

    Returns
    -------
    str
        unique protomer

    """

    molecule = deepcopy(molecule)
    # This only works for OpenEye
    # Todo There might be a way to use different layers of InChI for this purpose.
    # Not all tautomers are recognized as the same by InChI so it won't capture all tautomers.
    # But if we use only the formula and connectivity level we might be able to capture a larger subset.
    #
    if has_openeye:
        from openeye import oequacpac, oechem
    else:
        raise RuntimeError("Must have OpenEye for unique protomer feature")
    if not oechem.OEChemIsLicensed():
        raise ImportError("Must have OEChem license!")
    if not oequacpac.OEQuacPacIsLicensed():
        raise ImportError("Must have OEQuacPac license!")

    if has_rdkit:
        if isinstance(molecule, rd.Chem.rdchem.Mol):
            # convert to openeye molecule
            # Maybe we shouldn't do this.
            smiles = rd.Chem.MolToSmiles(molecule)
            molecule = oechem.OEMol()
            oechem.OESmilesToMol(molecule, smiles)

    molecule_copy = deepcopy(molecule)
    oequacpac.OEGetUniqueProtomer(molecule_copy, molecule)
    return oechem.OEMolToSmiles(molecule_copy)
Beispiel #4
0
try:
    openmm.Platform.getPlatformByName("CUDA")
    hasCUDA = True
except Exception:
    logging.info("CUDA unavailable on this system.")
    hasCUDA = False

try:
    from openeye import oechem

    if not oechem.OEChemIsLicensed():
        raise (ImportError("Need License for OEChem!"))
    from openeye import oequacpac

    if not oequacpac.OEQuacPacIsLicensed():
        raise (ImportError("Need License for oequacpac!"))
    from openeye import oeiupac

    if not oeiupac.OEIUPACIsLicensed():
        raise (ImportError("Need License for OEOmega!"))
    from openeye import oeomega

    if not oeomega.OEOmegaIsLicensed():
        raise (ImportError("Need License for OEOmega!"))
    hasOpenEye = True
    openeye_exception_message = str()
except Exception as e:
    hasOpenEye = False
    openeye_exception_message = str(e)
Beispiel #5
0
def get_charges(molecule,
                max_confs=800,
                strict_stereo=True,
                normalize=True,
                keep_confs=None,
                legacy=True):
    """Generate charges for an OpenEye OEMol molecule.
    Parameters
    ----------
    molecule : OEMol
        Molecule for which to generate conformers.
        Omega will be used to generate max_confs conformations.
    max_confs : int, optional, default=800
        Max number of conformers to generate
    strictStereo : bool, optional, default=True
        If False, permits smiles strings with unspecified stereochemistry.
        See https://docs.eyesopen.com/omega/usage.html
    normalize : bool, optional, default=True
        If True, normalize the molecule by checking aromaticity, adding
        explicit hydrogens, and renaming by IUPAC name.
    keep_confs : int, optional, default=None
        If None, apply the charges to the provided conformation and return
        this conformation, unless no conformation is present.
        Otherwise, return some or all of the generated
        conformations. If -1, all generated conformations are returned.
        Otherwise, keep_confs = N will return an OEMol with up to N
        generated conformations.  Multiple conformations are still used to
        *determine* the charges.
    legacy : bool, default=True
        If False, uses the new OpenEye charging engine.
        See https://docs.eyesopen.com/toolkits/python/quacpactk/OEProtonFunctions/OEAssignCharges.html#
    Returns
    -------
    charged_copy : OEMol
        A molecule with OpenEye's recommended AM1BCC charge selection scheme.
    Notes
    -----
    Roughly follows
    http://docs.eyesopen.com/toolkits/cookbook/python/modeling/am1-bcc.html
    """

    # If there is no geometry, return at least one conformation.
    if molecule.GetConfs() == 0:
        keep_confs = 1

    if not oechem.OEChemIsLicensed():
        raise (ImportError("Need License for OEChem!"))
    if not oequacpac.OEQuacPacIsLicensed():
        raise (ImportError("Need License for oequacpac!"))

    if normalize:
        molecule = normalize_molecule(molecule)
    else:
        molecule = oechem.OEMol(molecule)

    charged_copy = generate_conformers(
        molecule, max_confs=max_confs,
        strict_stereo=strict_stereo)  # Generate up to max_confs conformers

    if not legacy:
        # 2017.2.1 OEToolkits new charging function
        status = oequacpac.OEAssignCharges(charged_copy,
                                           oequacpac.OEAM1BCCCharges())
        if not status: raise (RuntimeError("OEAssignCharges failed."))
    else:
        # AM1BCCSym recommended by Chris Bayly to KAB+JDC, Oct. 20 2014.
        status = oequacpac.OEAssignPartialCharges(
            charged_copy, oequacpac.OECharges_AM1BCCSym)
        if not status:
            raise (RuntimeError(
                "OEAssignPartialCharges returned error code %d" % status))

    #Determine conformations to return
    if keep_confs == None:
        #If returning original conformation
        original = molecule.GetCoords()
        #Delete conformers over 1
        for k, conf in enumerate(charged_copy.GetConfs()):
            if k > 0:
                charged_copy.DeleteConf(conf)
        #Copy coordinates to single conformer
        charged_copy.SetCoords(original)
    elif keep_confs > 0:
        logger().debug(
            "keep_confs was set to %s. Molecule positions will be reset." %
            keep_confs)

        #Otherwise if a number is provided, return this many confs if available
        for k, conf in enumerate(charged_copy.GetConfs()):
            if k > keep_confs - 1:
                charged_copy.DeleteConf(conf)
    elif keep_confs == -1:
        #If we want all conformations, continue
        pass
    else:
        #Not a valid option to keep_confs
        raise (ValueError('Not a valid option to keep_confs in get_charges.'))

    return charged_copy