Eon Examples

The following table lists the currently available Eon TK examples:

Program

Description

overlap

Computing Eon Overlap

simple overlay

Simple Eon Overlay

pb overlay

Eon PB Overlay

Computing Eon Overlap

This example reads in a reference molecule and fit molecules and performs static shape charge similarity calculations. Results are outputted to a file.

Listing 1: Computing Eon Overlap

#!/usr/bin/env python
# (C) 2024 OpenEye Scientific Software Inc. All rights reserved.
#
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of OpenEye products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. OpenEye claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable OpenEye offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall OpenEye be
# liable for any damages or liability in connection with the Sample Code
# or its use.


'''
This script performs simple eon charge overlap calculations on input reference and fit molecules
molecules, scores each conformer with a charge tanimoto and outputs results.

Usage:
python eon_overlap.py -query query.sdf -in database_molecules.oeb.gz -out output.oeb.gz

python eon_overlap.py -query query.sdf -in database_molecules.oeb.gz -out output.oeb.gz -charges existing

python eon_overlap.py -query query.sdf -in database_molecules.oeb.gz -out output.oeb.gz -charges mmff94
'''

from openeye import oechem
from openeye import oeet
from openeye import oeshape
from openeye import oequacpac

class EonOverlapOption(oechem.OEOptions):
    def __init__(self):
        oechem.OEOptions.__init__(self, "EonOverlapOptions")

        chargesParam = oechem.OEStringParameter("-charges", "mmff94")
        chargesParam.SetRequired(True)
        chargesParam.SetVisibility(oechem.OEParamVisibility_Simple)
        chargesParam.SetBrief("Choices for this parameter are mmff94 (fix pka and set charges to mmff94), or existing (assume input has charges)")

        self._chargesParam = self.AddParameter(chargesParam)
        pass

    def CreateCopy(self):
        return self

    def GetCharges(self):
        value = self._chargesParam.GetStringValue()
        if value != "":
            return value

        return self._chargesParam.GetStringDefault()


def prep_mol(inmol):
    # remove color atoms if present
    if oeshape.OEHasColorAtoms(inmol):
        oeshape.OERemoveColorAtoms(inmol)

    # add explicit hydrogens and assign radii
    oechem.OEAddExplicitHydrogens(inmol)
    oechem.OEAssignBondiVdWRadii(inmol)

    oequacpac.OESetNeutralpHModel(inmol)
    oequacpac.OEAssignCharges(inmol, oequacpac.OEMMFF94Charges())

    inmol.Sweep()


def main(argv=[__name__]):
    eonOpts = EonOverlapOption()

    opts = oechem.OERefInputAppOptions(
        eonOpts, "EonOverlapOptions",
        oechem.OEFileStringType_Mol3D,
        oechem.OEFileStringType_Mol3D,
        oechem.OEFileStringType_Mol3D, "-query")

    if oechem.OEConfigureOpts(opts, argv, False) == oechem.OEOptsConfigureStatus_Help:
        return 0

    eonOpts.UpdateValues(opts)

    inputFilename       = opts.GetInFile()
    outputFilename      = opts.GetOutFile()
    queryFilename       = opts.GetRefFile()
    charges             = eonOpts.GetCharges()

    qfs = oechem.oemolistream()
    if not qfs.open(queryFilename):
        oechem.OEThrow.Fatal(f'Unable to open {queryFilename} for reading')

    ifs = oechem.oemolistream()
    if not ifs.open(inputFilename):
        oechem.OEThrow.Fatal(f'Unable to open {inputFilename} for reading')

    ofs = oechem.oemolostream()
    if not ofs.open(outputFilename):
        oechem.OEThrow.Fatal(f'Unable to open {outputFilename} for writing')
   
    chargeFunc = oeet.OEExactChargeFunc()
   
    # set up query
    refmol = oechem.OEMol()
    oechem.OEReadMolecule(qfs, refmol)

    if (charges == "mmff94"):
        prep_mol(refmol)

    chargeFunc.SetupRef(refmol)

    # write query to output file
    oechem.OEWriteMolecule(ofs, refmol)

    for mol in ifs.GetOEMols():
        if (charges == "mmff94"):
            prep_mol(mol)
        score = oeet.OEEonOverlapScore()
        for conf in mol.GetConfs():
            chargeFunc.Overlap(conf, score)
            oechem.OESetSDData(conf, '(Static) Charge Tanimoto', f'{score.GetETTanimoto():.4f}')
        oechem.OEWriteMolecule(ofs, mol)

    qfs.close()
    ifs.close()
    ofs.close()

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

Download code

eon_overlap.py

Simple Eon Overlay

This example reads in a reference molecule and fit molecules and overlays them according to their shape and charge density similarity.

Listing 2: Computing Simple Eon Overlay

#!/usr/bin/env python
# (C) 2024 OpenEye Scientific Software Inc. All rights reserved.
#
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of OpenEye products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. OpenEye claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable OpenEye offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall OpenEye be
# liable for any damages or liability in connection with the Sample Code
# or its use.


'''
This script performs a shape and charge overlay optimization between a reference molecule and a series of fit
molecules and writes the hits to the output file. The hits are sorted by highest Shape+Charge Tanimoto.

Usage:
python eon_simple_overlay.py -query query.sdf -in database_molecules.oeb.gz -out output.oeb.gz

python eon_simple_overlay.py -query query.sdf -in database_molecules.oeb.gz -out output.oeb.gz -charges existing

'''

from openeye import oechem
from openeye import oeet
from openeye import oeshape
from openeye import oequacpac


class EonOverlayOptions(oechem.OEOptions):
    def __init__(self):
        oechem.OEOptions.__init__(self, "EonSimpleOverlayOptions")
        self._hitOpts = oeet.ToEonHitlistOptions(self.AddOption(oeet.OEEonHitlistOptions()))

        chargesParam = oechem.OEStringParameter("-charges", "mmff94")
        chargesParam.SetRequired(True)
        chargesParam.SetVisibility(oechem.OEParamVisibility_Simple)
        chargesParam.SetBrief("Choices for this parameter are mmff94 (fix pka and set charges to mmff94), or existing (assume input has charges)")

        self._chargesParam = self.AddParameter(chargesParam)
        pass

    def CreateCopy(self):
        return self

    def GetCharges(self):
        value = self._chargesParam.GetStringValue()
        if value != "":
            return value

        return self._chargesParam.GetStringDefault()

    def  GetHitlistOptions(self):
        return self._hitOpts


def prep_mol(inmol):
    # remove color atoms if present
    if oeshape.OEHasColorAtoms(inmol):
        oeshape.OERemoveColorAtoms(inmol)

    # add explicit hydrogens and assign radii
    oechem.OEAddExplicitHydrogens(inmol)
    oechem.OEAssignBondiVdWRadii(inmol)

    oequacpac.OESetNeutralpHModel(inmol)
    oequacpac.OEAssignCharges(inmol, oequacpac.OEMMFF94Charges())

    inmol.Sweep()


def main(argv=[__name__]):

    eonOpts = EonOverlayOptions()
    opts = oechem.OERefInputAppOptions(
        eonOpts, "EonOverlayOptions",
        oechem.OEFileStringType_Mol3D,
        oechem.OEFileStringType_Mol3D,
        oechem.OEFileStringType_Mol3D, "-query")

    if oechem.OEConfigureOpts(opts, argv, False) == oechem.OEOptsConfigureStatus_Help:
        return 0

    eonOpts.UpdateValues(opts)

    qname = opts.GetRefFile()
    iname = opts.GetInFile()
    oname = opts.GetOutFile()

    charges = eonOpts.GetCharges()

    qfs = oechem.oemolistream()
    if not qfs.open(qname):
        oechem.OEThrow.Fatal(f'Unable to open {qname} for reading')

    ifs = oechem.oemolistream()
    if not ifs.open(iname):
        oechem.OEThrow.Fatal(f'Unable to open {iname} for reading')
    
    ofs = oechem.oemolostream()
    if not ofs.open(oname):
        oechem.OEThrow.Fatal(f'Unable to open {oname} for writing')

    overlapFunc = oeet.OEEonOverlapFunc() #this by default picks up grid versions for shape and charge funcs
    overlayOpts = oeshape.OEOverlayOptions()
    overlayOpts.SetOverlapFunc(overlapFunc)
    eon_overlay_obj = oeet.OEEonOverlay(overlayOpts)

    # set up query
    refmol = oechem.OEMol()
    oechem.OEReadMolecule(qfs, refmol)

    if (charges == "mmff94"):
        prep_mol(refmol)
    eon_overlay_obj.SetupRef(refmol)

    # write query to output file
    oechem.OEWriteMolecule(ofs, refmol)

    hitlist = oeet.OEEonHitlistBuilder(eonOpts.GetHitlistOptions())

    for mol in ifs.GetOEMols():
        if (charges == "mmff94"):
            prep_mol(mol)
        score = oeet.OEEonOverlayScore()
        eon_overlay_obj.BestOverlay(score, mol)
        hitlist.AddScore(score, mol)
    # sort by scores and then write to output file
    
    hitlist.Build()

    for hit in hitlist.GetHits():
        hitMol = hit.GetMol()
        oechem.OESetSDData(hitMol, 'Shape Tanimoto', f'{hit.GetTanimoto():.4f}')
        oechem.OESetSDData(hitMol, 'Charge Tanimoto', f'{hit.GetETTanimoto():.4f}')
        oechem.OESetSDData(hitMol, 'Shape + Charge Tanimoto Combo', f'{hit.GetTanimotoCombo():.4f}')
        oechem.OEWriteMolecule(ofs, hitMol)


if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

Download code

eon_simple_overlay.py

Eon PB Overlay

This example reads in a reference molecule and fit molecules and overlays them according to their shape and potential similarity.

Listing 3: Computing Eon PB Overlay

#!/usr/bin/env python
# (C) 2024 OpenEye Scientific Software Inc. All rights reserved.
#
# TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is
# provided to current licensees or subscribers of OpenEye products or
# SaaS offerings (each a "Customer").
# Customer is hereby permitted to use, copy, and modify the Sample Code,
# subject to these terms. OpenEye claims no rights to Customer's
# modifications. Modification of Sample Code is at Customer's sole and
# exclusive risk. Sample Code may require Customer to have a then
# current license or subscription to the applicable OpenEye offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall OpenEye be
# liable for any damages or liability in connection with the Sample Code
# or its use.


'''
This script performs calculation of shape and PB potential similarity. At first it overlays the reference and
fit molecules with shape and charge overlay, and later selected top hits are rescored with shape and PB potential similarity.

Usage:
python eon_pb_overlay.py -query query.sdf -in database_molecules.oeb.gz -out output.oeb.gz

python eon_pb_overlay.py -query query.sdf -in database_molecules.oeb.gz -out output.oeb.gz -numtophits 2
'''

from openeye import oechem
from openeye import oeet
from openeye import oeshape
from openeye import oequacpac


class EonPBOverlayOptions(oechem.OEOptions):
    def __init__(self):
        oechem.OEOptions.__init__(self, "EonPBOverlayOptions")
        self._hitOpts = oeet.ToEonHitlistOptions(self.AddOption(oeet.OEEonHitlistOptions()))
        self._pbOpts = oeet.ToEonPBOptions(self.AddOption(oeet.OEEonPBOptions()))

        chargesParam = oechem.OEStringParameter("-charges", "mmff94")
        chargesParam.SetRequired(True)
        chargesParam.SetVisibility(oechem.OEParamVisibility_Simple)
        chargesParam.SetBrief("Choices for this parameter are mmff94 (fix pka and set charges to mmff94), or existing (assume input has charges)")
        self._chargesParam = self.AddParameter(chargesParam)

        numTopHitsParam = oechem.OEUIntParameter("-numtophits", 5)
        numTopHitsParam.SetIsList(False)
        numTopHitsParam.SetRequired(True)
        numTopHitsParam.SetVisibility(oechem.OEParamVisibility_Simple)
        numTopHitsParam.SetBrief("Number of shape charge overlay hits to rescore with shape and PB potential similarity")
        self._numTopHitsParam = self.AddParameter(numTopHitsParam)
        pass

    def CreateCopy(self):
        return self

    def GetCharges(self):
        value = self._chargesParam.GetStringValue()
        if value != "":
            return value
        return self._chargesParam.GetStringDefault()

    def GetNumTopHits(self):
        if self._numTopHitsParam.GetHasValue():
            return int(self._numTopHitsParam.GetStringValue())
        return int(self._numTopHitsParam.GetStringDefault())

    def  GetHitlistOptions(self):
        return self._hitOpts

    def  GetPBOptions(self):
        return self._pbOpts


def prep_mol(inmol):
    # remove color atoms if present
    if oeshape.OEHasColorAtoms(inmol):
        oeshape.OERemoveColorAtoms(inmol)

    # add explicit hydrogens and assign radii
    oechem.OEAddExplicitHydrogens(inmol)
    oechem.OEAssignBondiVdWRadii(inmol)

    oequacpac.OESetNeutralpHModel(inmol)
    oequacpac.OEAssignCharges(inmol, oequacpac.OEMMFF94Charges())

    inmol.Sweep()


def main(argv=[__name__]):

    eonOpts = EonPBOverlayOptions()
    opts = oechem.OERefInputAppOptions(
        eonOpts, "EonPBOverlayOptions",
        oechem.OEFileStringType_Mol3D,
        oechem.OEFileStringType_Mol3D,
        oechem.OEFileStringType_Mol3D, "-query")

    if oechem.OEConfigureOpts(opts, argv, False) == oechem.OEOptsConfigureStatus_Help:
        return 0

    eonOpts.UpdateValues(opts)

    qname       = opts.GetRefFile()
    iname       = opts.GetInFile()
    oname       = opts.GetOutFile()
    charges     = eonOpts.GetCharges()
    numtophits  = eonOpts.GetNumTopHits()

    qfs = oechem.oemolistream()
    if not qfs.open(qname):
        oechem.OEThrow.Fatal(f'Unable to open {qname} for reading')

    ifs = oechem.oemolistream()
    if not ifs.open(iname):
        oechem.OEThrow.Fatal(f'Unable to open {iname} for reading')
    
    ofs = oechem.oemolostream()
    if not ofs.open(oname):
        oechem.OEThrow.Fatal(f'Unable to open {oname} for writing')

    # setup eon calculation
    shapeOpts = oeshape.OEShapeOptions()
    shapeOpts.SetScoreType(oeshape.OEOverlapResultType_Tanimoto)

    # set up the Shape/Charge Overlap Func

    shapeFunc = oeshape.OEGridShapeFunc()
    chargeFunc = oeet.OEGridChargeFunc()
    overlapFunc = oeet.OEEonOverlapFunc(shapeFunc, chargeFunc)
    overlayOpts = oeshape.OEOverlayOptions()
    overlayOpts.SetOverlapFunc(overlapFunc)

    eon_pb_overlay_obj = oeet.OEEonPBOverlay(overlayOpts, eonOpts.GetPBOptions())

    # set up query
    refmol = oechem.OEMol()
    oechem.OEReadMolecule(qfs, refmol)

    if (charges == "mmff94"):
        prep_mol(refmol)
    eon_pb_overlay_obj.SetupRef(refmol)

    # write query to output file
    oechem.OEWriteMolecule(ofs, refmol)
    hitlist = oeet.OEEonHitlistBuilder(eonOpts.GetHitlistOptions())

    for mol in ifs.GetOEMols():
        if (charges == "mmff94"):
            prep_mol(mol)
        score = oeet.OEEonOverlayScore()
        eon_pb_overlay_obj.BestOverlay(score, mol, numtophits)
        hitlist.AddScore(score, mol)

    hitlist.Build()

    for hit in hitlist.GetHits():
        hitMol = hit.GetMol()
        oechem.OESetSDData(hitMol, 'Shape Tanimoto', f'{hit.GetTanimoto():.4f}')
        oechem.OESetSDData(hitMol, 'Potential Tanimoto', f'{hit.GetETTanimoto():.4f}')
        oechem.OESetSDData(hitMol, 'Shape + Potential Tanimoto Combo', f'{hit.GetTanimotoCombo():.4f}')
        oechem.OEWriteMolecule(ofs, hitMol)

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

Download code

eon_pb_overlay.py