InertialAtHeavyAtoms

OEFastROCSOrientation.InertialAtHeavyAtoms translates the center of mass (COM) of each database molecule to each heavy atom of the query molecule and to the query molecule’s COM. 4 inertial orientations are then optimized at each translation.

The figures below demonstrate the starting positions optimized for the first 2 heavy atoms in the query molecule:

../../../_images/Tutorial_1_Figure_4a.png

Inertial starts optimized at heavy atom 1 (highlighted green)

../../../_images/Tutorial_1_Figure_4b.png

Inertial starts optimized at heavy atom 2 (highlighted green)

Inertial starts continue to be optimized for the remaining atoms of the query molecule and it’s COM.

Below is a python script demonstrating the most basic usage of FastROCS TK. After explaining this simple script it will be modified to make use of the OEFastROCSOrientation.InertialAtHeavyAtoms funtion.

#!/usr/bin/env python
from __future__ import print_function
import sys, os

oepy = os.path.join(os.path.dirname(__file__), "..", "python")
sys.path.insert(0, os.path.realpath(oepy))

from openeye.oechem import *
from openeye.oefastrocs import *

def main(argv=[__name__]):
    if len(argv) < 3:
        OEThrow.Usage("%s <database> [<queries> ... ]" % argv[0])
        return 0

    # check system 
    if not OEFastROCSIsGPUReady():
        OEThrow.Info("No supported GPU available!")
        return 0

    # read in database
    dbname = argv[1]
    print("Opening database file %s ..." % dbname)
    dbase = OEShapeDatabase()
    moldb = OEMolDatabase()

    if not moldb.Open(dbname):
        OEThrow.Fatal("Unable to open '%s'" % dbname)

    dots  = OEThreadedDots(10000, 200, "conformers")
    if not dbase.Open(moldb, dots):
        OEThrow.Fatal("Unable to initialize OEShapeDatabase on '%s'" % dbname)

    # customize search options
    opts = OEShapeDatabaseOptions()

    opts.SetLimit(5)    

    for qfname in argv[2:]:
        # read in query
        qfs = oemolistream()
        if not qfs.open(qfname):
            OEThrow.Fatal("Unable to open '%s'" % qfname)

        query = OEGraphMol()
        if not OEReadMolecule(qfs, query):
            OEThrow.Fatal("Unable to read query from '%s'" % qfname)

        ext = OEGetFileExtension(qfname)
        base = qfname[:-(len(ext) + 1)]

        # write out everthing to a similary named file
        ofs = oemolostream()
        ofname = base + "_results." + ext
        if not ofs.open(ofname):
            OEThrow.Fatal("Unable to open '%s'" % argv[4])
        OEWriteMolecule(ofs, query)

        print("Searching for", qfname)
        for score in dbase.GetSortedScores(query, opts):
            print("Score for mol %u(conf %u) %f shape %f color" % (
                   score.GetMolIdx(), score.GetConfIdx(),
                   score.GetShapeTanimoto(), score.GetColorTanimoto()))
            dbmol = OEMol()
            molidx = score.GetMolIdx()
            if not moldb.GetMolecule(dbmol, molidx):
                print("Unable to retrieve molecule '%u' from the database" % molidx)
                continue

            mol = OEGraphMol(dbmol.GetConf(OEHasConfIdx(score.GetConfIdx())))
            OESetSDData(mol, "ShapeTanimoto", "%.4f" % score.GetShapeTanimoto())
            OESetSDData(mol, "ColorTanimoto", "%.4f" % score.GetColorTanimoto())
            OESetSDData(mol, "TanimotoCombo", "%.4f" % score.GetTanimotoCombo())
            score.Transform(mol)

            OEWriteMolecule(ofs, mol) 
        print("Wrote results to", ofname)

    return 0

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

The script creates an OEMolDatabase and an OEShapeDatabase object. The database file is first opened as an OEMolDatabase object, which is used to load the molecules into OEShapeDatabase via OEShapeDatabase.Open. This is the simplest example of loading a database. The database is now ready for either combo or shape-only searches.

Note

To restrict searches to shape-only, create a shape-ony database object:

shapeOnlyDB = OEShapeDatabase(OEShapeDatabaseType_Shape)

While this reduces the memory footprint of the database as color data is no longer stored, the database cannot be searched for color scores.

In this example, an OEShapeDatabaseOptions object is also created and the number of results is limited to 5 via the OEShapeDatabaseOptions.SetLimit method.

Next, the query molecule is set up is using a molecule stream and the OEReadMolecule function. Queries are used to search the loaded database via the OEShapeDatabase.GetSortedScores method. The OEShapeDatabaseOptions class is passed to customize the search options. In this example, a subset of the eMolecules database was searched against a benzene query molecule. The top 5 scores are shown below.

Opening database file eMolecules.2015.1_100subset.oeb ...
Searching for benzene.oeb
Score for mol 65(conf 1) 0.530182 shape 0.237350 color
Score for mol 45(conf 1) 0.678128 shape 0.085376 color
Score for mol 49(conf 1) 0.596801 shape 0.153465 color
Score for mol 92(conf 0) 0.503204 shape 0.155330 color
Score for mol 33(conf 1) 0.442559 shape 0.175599 color

To make use of the OEFastROCSOrientation.InertialAtHeavyAtoms feature, modify the OEShapeDatabaseOptions object as follows:

opts = OEShapeDatabaseOptions()
opts.SetLimit(5)
opts.SetInitialOrientation(OEFastROCSOrientation_InertialAtHeavyAtoms)

An additional option, OEShapeDatabaseOptions.SetInitialOrientation, is also set to the desired method, OEFastROCSOrientation.InertialAtHeavyAtoms. The resultant scores reflect the change in starting points:

Opening database file eMolecules.2015.1_100subset.oeb ...
Searching for benzene.oeb
Score for mol 45(conf 1) 0.669345 shape 0.121420 color
Score for mol 65(conf 1) 0.530182 shape 0.237350 color
Score for mol 49(conf 1) 0.596801 shape 0.153465 color
Score for mol 92(conf 0) 0.503204 shape 0.155330 color
Score for mol 33(conf 1) 0.442559 shape 0.175599 color

Warning

If using OEShapeDatabaseOptions.SetNumInertialStarts with OEShapeDatabaseOptions.SetInitialOrientation, set the number of inertial starts after the initial orientation is defined. Otherwise, the number of inertial starts will be overridden with the default value of 4.

The OEShapeDatabaseOptions.GetNumHeavyAtomStarts method can be used to find out how many heavy atom starts are being optimized. This method requires the query molecule in order to return the number of starts:

query = OEGraphMol()
OEReadMolecule(qfs, query)
if opts.GetInitialOrientation() == OEFastROCSOrientation_InertialAtHeavyAtoms:
    numStarts = opts.GetNumHeavyAtomStarts(query)
    print("This example will use %u starts" % numStarts)

When this code snippet is added to the Python script, the output should look like this:

This example will use 7 starts
Searching for benzene.oeb
Score for mol 45(conf 1) 0.669345 shape 0.121420 color
Score for mol 65(conf 1) 0.530182 shape 0.237350 color
Score for mol 49(conf 1) 0.596801 shape 0.153465 color
Score for mol 92(conf 0) 0.503204 shape 0.155330 color
Score for mol 33(conf 1) 0.442559 shape 0.175599 color

See also

The fully modified python script used in this tutorial can be found here InertialAtHeavyAtomStartsExample.py