# Molecule Depiction¶

The previous chapter introduced how to create images and draw basic geometric elements (such as text, lines rectangles, etc.) Drawing these basic graphical elements provides a framework to construct more complex images such as molecular diagrams.

The molecule depiction is divided into two separate steps (see Figure: Process of Molecule Depiction ):

1. Generating 2D coordinates
2. Rendering molecule that involves
• transforming and scaling coordinates in order to fit the molecule into an image with a specific width and height
• setting atom and bond display properties based on depiction style
• creating an image (such as drawing lines for bonds, drawing text for atomic labels)

Process of molecule depiction

The next example (Listing 1) demonstrates how easy is to depict a molecule using the OEDepict TK. After creating a molecule (for example by parsing a SMILES string) the image can be generated by calling two functions.

1. The OEPrepareDepiction function prepares the molecule for depiction. This process may involve perceiving atom and bond stereo information and suppressing or adding hydrogens. It also calls the OEDepictCoordinates function to generate the 2D coordinates of the molecule.
2. The OERenderMolecule function generates the image of the molecule using the default depiction styles and then writes the image into the given file.

The image created by Listing 1 is shown in Figure: Example of depicting a molecule.

Listing 1: Example of molecule depiction

#!/usr/bin/env python
from openeye.oechem import *
from openeye.oedepict import *

mol = OEGraphMol()
OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1 3-aminobenzenesulfonic acid")
OEPrepareDepiction(mol)
OERenderMolecule("DepictMolSimple.png", mol)
OERenderMolecule("DepictMolSimple.pdf", mol)


Example of molecule depiction

## Customizing Molecule Depiction¶

The previous example showed how to generate a molecule diagram with default parameters. OEDepict TK provides the ability to customize molecule depiction. The Listing 2 example shows how to depict a molecule width specific width and height parameters.

Listing 2: Example of depicting a molecule

#!/usr/bin/env python
from openeye.oechem import *
from openeye.oedepict import *

mol = OEGraphMol()
OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1 3-aminobenzenesulfonic acid")
OEPrepareDepiction(mol)

width, height = 300, 300
opts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)
disp = OE2DMolDisplay(mol, opts)
OERenderMolecule("DepictMolSize.png", disp)
OERenderMolecule("DepictMolSize.pdf", disp)


Apart from defining the dimensions of a depicted molecule, the OE2DMolDisplayOptions class stores all properties that determine how a molecule is depicted. The following example shows how to set various depiction styles before initializing the OE2DMolDisplay object. The image created by Listing 3 is shown in Figure: Example of customizing depiction style.

Listing 3: Example of customizing the depiction style

#!/usr/bin/env python
from openeye.oechem import *
from openeye.oedepict import *

mol = OEGraphMol()
OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1 3-aminobenzenesulfonic acid")
OEPrepareDepiction(mol)

width, height = 200, 200
opts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)

opts.SetAromaticStyle(OEAromaticStyle_Circle)
opts.SetAtomColorStyle(OEAtomColorStyle_BlackCPK)
opts.SetTitleLocation(OETitleLocation_Bottom)

disp = OE2DMolDisplay(mol, opts)
OERenderMolecule("DepictMolStyle.png", disp)
OERenderMolecule("DepictMolStyle.pdf", disp)


Example of customizing the depiction style

Apart from controlling the depiction style through the OE2DMolDisplayOptions class, OEDepict TK also provides access to manipulate individual atom and bond 2D display properties. The OE2DMolDisplay.GetAtomDisplays method returns an iterator over OE2DAtomDisplay objects that store atom display information. Similarly, the OE2DMolDisplay.GetBondDisplays method returns an iterator over OE2DBondDisplay objects that store bond display information.

The following example demonstrates how to change atom and bond display properties and depict the graph of the molecule by ignoring atom labels and setting bond display styles. The image created by Listing 4 is shown in Figure: Example of molecule graph depiction.

Listing 4: Example of molecule graph depiction

#!/usr/bin/env python
from openeye.oechem import *
from openeye.oedepict import *

mol = OEGraphMol()
OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1")
OEPrepareDepiction(mol)

width, height = 200, 200
opts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)

opts.SetAtomColorStyle(OEAtomColorStyle_WhiteMonochrome)
opts.SetTitleLocation(OETitleLocation_Hidden)
opts.SetAtomColor(OEElemNo_C, OEDarkGreen)
pen = OEPen(OEBlack, OEBlack, OEFill_On, 3.0)
opts.SetDefaultBondPen(pen)

disp = OE2DMolDisplay(mol, opts)

for adisp in disp.GetAtomDisplays():

for bdisp in disp.GetBondDisplays():
bdisp.SetDisplayType(OEBondDisplayType_Single)

OERenderMolecule("DepictMolGraph.png", disp)
OERenderMolecule("DepictMolGraph.pdf", disp)


Example of molecule graph depiction

Hint

Even though OEDepict TK provides the ability to manipulate atom and bond display properties of after the OE2DMolDisplay object is constructed, it is highly recommended to set the depiction properties using the OE2DMolDisplayOptions class. Only by knowing all properties (such as labels, font styles and sizes etc.) in advance can one ensure the best depiction layout i.e. that the molecule diagram is rendered without any label clippings and the labels are displayed with the minimum number of overlaps.

## Controlling the Size of Depicted Molecules¶

The dimensions of a depicted molecule are controlled by the width, height and scale parameters of the OE2DMolDisplayOptions that is used to initialized the OE2DMolDisplay object. (See example in Listing 2)

If the width and the height of the image is not specified (set to be zero), then scaling value determine the dimensions of the image. (See examples in Examples of image scaling). The default scale is defined to be OEScale_Default constant, and the image may be enlarged or shrunk by specifying a floating point scaling value. For example, the scaling OEScale_Default * 0.5 generates an image a half of the default size, and scaling OEScale_Default * 1.5 generates an image one and a half times the default.

Examples of image scaling (width = 0.0, height = 0.0)
OEScale::Default * 0.5 OEScale::Default OEScale::Default * 1.5

If an OE2DMolDisplayOptions object is initialized with zero width and / or height, then the real dimensions of the image can be accessed after creating an OE2DMolDisplay object.

width, height, scale = 0.0, 0.0, 50.0
opts = OE2DMolDisplayOptions(width, height, scale)
disp = OE2DMolDisplay(mol, opts)
print("width  %.1f" % disp.GetWidth())
print("height %.1f" % disp.GetHeight())
print("scale  %.1f" % disp.GetScale())


The output of the preceding snippet is the following:

width  137.0
height 181.0
scale  50.0


If both the width and the height of are specified, then OEScale_AutoScale scaling indicates that the molecule is scaled to maximally fit the given dimensions. The specified width and height will not be altered, not even if the given scaling would require it i.e if necessary the scaling will be reduced in order to fit the molecule into the given dimension. (See examples in Examples of image scaling).

Examples of fixed sized image (width = 120.0, height = 120.0)
OEScale::Default * 0.5 OEScale::Default OEScale::Default * 1.5

Note

Specifying a width and / or height larger than what is required by the scale, causes the molecule to float in the middle of the image of the requested size.

If only either the width or the height of the image is specified, then the unspecified dimension will be set based on the scaling and the specified width / height, respectively.

OEScale::Default, width = 250.0, height = 0.0 OEScale::Default, width = 0.0, height = 250.0

## Molecule Depiction with Transparent Background¶

The following code snippet shows how to generate a molecule depiction with transparent background. First, the OEImage object, onto which the depiction is going to be rendered, has to be constructed with the OETransparentColor color. Then the OERenderMolecule function has to be called with a parameter that insures that the background in not cleared prior to rendering the molecule.

width, height, scale = 200.0, 200.0, OEScale_AutoScale
image = OEImage(width, height, OETransparentColor)

opts = OE2DMolDisplayOptions(width, height, scale)
disp = OE2DMolDisplay(mol, opts)

clearbackground = True
OERenderMolecule("DepictMolTransparent.png", disp, not clearbackground)


## Displaying Atom Properties¶

OEDepict TK provides ability the display atom properties as strings. When a OE2DMolDisplay object is created, the positions where atom properties can be displayed are calculated. (see Figure: Example of generating atom property positions.)

Example of generating atom property positions

The following example shows how to display the atom indices by using the OEDisplayAtomIdx functor. The font used to depict the atom property strings also can be modified by using the OE2DMolDisplayOptions.SetAtomPropLabelFont method. The image created by Listing 5 is shown in Figure: Example of displaying atom indices.

Listing 5: Example of depicting atom indices

#!/usr/bin/env python
from openeye.oechem import *
from openeye.oedepict import *

mol = OEGraphMol()
OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1")
OEPrepareDepiction(mol)

width, height = 300, 200

opts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)
opts.SetAtomPropertyFunctor(OEDisplayAtomIdx())
opts.SetAtomPropLabelFont(OEFont(OEDarkGreen))

disp = OE2DMolDisplay(mol, opts)
OERenderMolecule("AtomPropIndex.png", disp)
OERenderMolecule("AtomPropIndex.pdf", disp)


Example of displaying atom indices

Hint

It is recommended to use the OE2DMolDisplayOptions.SetAtomPropertyFunctor method to define the atom property labels when the OE2DMolDisplay object is constructed. All labels displayed on the molecule diagram have to be known in advance in order to be able to minimize the number of label clashes and clippings when calculating the positions of the atom property labels.

OEDepict TK provides the following built-in atom property functors:

In order to display user-defined atom properties, the functor that is passed to the OE2DMolDisplayOptions.SetAtomPropertyFunctor method has to be derived from the OEDisplayAtomPropBase abstract base class. The Listing 6 example shows how to implement a user-defined functor that marks aromatic atoms. The image created by Listing 6 is shown in Figure: Example of displaying user-defined atom properties.

Listing 6: Example of depicting user-defined atom properties

#!/usr/bin/env python
from openeye.oechem import *
from openeye.oedepict import *

class LabelAromaticAtoms(OEDisplayAtomPropBase):
def __init__(self):
OEDisplayAtomPropBase.__init__(self)

def __call__(self, atom):
if atom.IsAromatic():
return "(A)"
return ""

def CreateCopy(self):
# __disown__ is required to allow C++ to take
# ownership of this object and its memory
copy = LabelAromaticAtoms()
return copy.__disown__()

mol = OEGraphMol()
OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1")
OEPrepareDepiction(mol)

width, height = 300, 200

opts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)

atomlabel = LabelAromaticAtoms()
opts.SetAtomPropertyFunctor(atomlabel)

disp = OE2DMolDisplay(mol, opts)
OERenderMolecule("AtomPropUser.png", disp)
OERenderMolecule("AtomPropUser.pdf", disp)


Example of displaying user-defined atom properties

## Displaying Bond Properties¶

Similarly to atom properties, bond properties can be displayed as strings. (see Figure: Example of generating bond property positions.)

Example of generating bond property positions

The Listing 7 demonstrates how to display bond indices by using the OEDisplayBondIdx functor. The font used to depict the bond property strings can be set by using the OE2DMolDisplayOptions.SetBondPropLabelFont method. The image created by Listing 7 is shown in Figure: Example of displaying bond indices.

Listing 7: Example of depicting bond indices

#!/usr/bin/env python
from openeye.oechem import *
from openeye.oedepict import *

mol = OEGraphMol()
OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1")
OEPrepareDepiction(mol)

width, height = 300, 200

opts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)
opts.SetBondPropertyFunctor(OEDisplayBondIdx())
opts.SetBondPropLabelFont(OEFont(OEDarkBlue))

disp = OE2DMolDisplay(mol, opts)
OERenderMolecule("BondPropIndex.png", disp)
OERenderMolecule("BondPropIndex.pdf", disp)


Example of displaying bond indices

Hint

It is recommended to use the OE2DMolDisplayOptions.SetBondPropertyFunctor method to define the bond property labels when the OE2DMolDisplay object is constructed. All labels displayed on the molecule diagram have to be known in advance in order to be able to minimize the number of label clashes and clippings when calculating the positions of the bond property labels.

OEDepict TK provides the following built-in bond property functors:

In order to display user-defined bond properties, the functor that is passed to the OE2DMolDisplayOptions.SetBondPropertyFunctor method has to be derived from the OEDisplayBondPropBase abstract base class. The Listing 8 example shows how to implement a user-defined functor that marks chain and ring bonds. The image created by Listing 8 is shown in Figure: Example of displaying user-defined bond properties.

Listing 8: Example of depicting user-defined bond properties

#!/usr/bin/env python
from openeye.oechem import *
from openeye.oedepict import *

class LabelRingChainBonds(OEDisplayBondPropBase):
def __init__(self):
OEDisplayBondPropBase.__init__(self)

def __call__(self, bond):
if bond.IsInRing():
return "R"
return "C"

def CreateCopy(self):
# __disown__ is required to allow C++ to take
# ownership of this object and its memory
copy = LabelRingChainBonds()
return copy.__disown__()

mol = OEGraphMol()
OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1")
OEPrepareDepiction(mol)

width, height = 300, 200

opts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)

bondlabel = LabelRingChainBonds()
opts.SetBondPropertyFunctor(bondlabel)

disp = OE2DMolDisplay(mol, opts)
OERenderMolecule("BondPropUser.png", disp)
OERenderMolecule("BondPropUser.pdf", disp)


Example of displaying user-defined bond properties

## Hiding Atoms and Bonds¶

OEDepict TK provides ability the suppress the display of specific atom and bonds. When a OE2DMolDisplay object is created, the visibility of every atom is evaluated. Bonds with both atom endpoints visible are also displayed. (see Figure: Example of hiding a portion of a structure.)

The following example shows how to selectively display only a portion of the structure by using a custom class derived from the OEUnaryAtomPred functor. The images created by Listing 9 is shown in Figure: Example of hiding a portion of a structure.

Hint

It is recommended to use the OE2DMolDisplayOptions.SetAtomVisibilityFunctor method to identify the visible atoms when the OE2DMolDisplay object is constructed. All objects displayed on the molecule diagram have to be known in advance in order to be able to correctly size and scale the molecule.

Listing 9: Example of selectively displaying atoms

#!/usr/bin/env python

from openeye.oechem import *
from openeye.oedepict import *
import sys

class OEAtomVisibilityShowRxnRole(OEUnaryAtomPred):
def __init__(self,role):
self.rxnrole = role
OEUnaryAtomPred.__init__(self)

def __call__(self, atom):
# return True if the atom should be visible, otherwise return False
if self.rxnrole == OERxnRole_None:
return True
return (self.rxnrole == atom.GetRxnRole())

def CreateCopy(self):
# __disown__ is required to allow C++ to take
# ownership of this object and its memory
return OEAtomVisibilityShowRxnRole(self.rxnrole).__disown__()

if len(sys.argv) != 3:
OEThrow.Usage("%s <rxnfile> <imagefile>" % sys.argv[0])

ifs = oemolistream(sys.argv[1])

mol = OEGraphMol()
OEThrow.Fatal("%s error reading reaction file" % sys.argv[0])

OEPrepareDepiction(mol)

image = OEImage(900, 100)

rows, cols = 1, 3
grid = OEImageGrid(image, rows, cols)

opts = OE2DMolDisplayOptions(grid.GetCellWidth(), grid.GetCellHeight(), OEScale_AutoScale)

cell = grid.GetCell(1,1)
mol.SetTitle("Reaction display")
opts.SetAtomVisibilityFunctor(OEIsTrueAtom())  # explicitly set the default
disp = OE2DMolDisplay(mol, opts)
rxnscale = disp.GetScale()
OERenderMolecule(cell, disp)

cell = grid.GetCell(1,2)
mol.SetTitle("Reactant display")
opts.SetAtomVisibilityFunctor(OEAtomVisibilityShowRxnRole(OERxnRole_Reactant))
opts.SetScale(rxnscale)
disp = OE2DMolDisplay(mol, opts)
OERenderMolecule(cell, disp)

cell = grid.GetCell(1,3)
mol.SetTitle("Product display")
opts.SetAtomVisibilityFunctor(OEAtomVisibilityShowRxnRole(OERxnRole_Product))
opts.SetScale(rxnscale)
disp = OE2DMolDisplay(mol, opts)
OERenderMolecule(cell, disp)

OEWriteImage(sys.argv[2], image)


Example of hiding a portion of a structure

## Configuring Molecule Display¶

OEDepict TK provides a mechanism to generate a standard interface that allows configuration of molecule displays. By calling the OEConfigureImageOptions function, “-height” and “width” parameters are added to the interface (OEInterface), at run-time the value of these parameters can be obtained by calling the OEGetImageHeight and OEGetImageWidth functions, respectively. (See the standard interface displayed when calling the Listing 10 example with the “–help” parameter)

The OEConfigure2DMolDisplayOptions function generates an interface that allows setting of various molecule display options (such as aromatic style, atom and bond coloring etc.) The OE2DMolDisplayOptions object, that stores properties determine the molecule depiction style, can initialized based on to the command line parameters by calling the OESetup2DMolDisplayOptions function.

Listing 10: Example of configuring mol display

#!/usr/bin/env python
from openeye.oechem import *
from openeye.oedepict import *
import sys

def main(argv=[__name__]):
# import configuration file
itf = OEInterface()
OEConfigure(itf, InterfaceData)
# add configuration for image size and display options
OEConfigureImageOptions(itf)
OEConfigure2DMolDisplayOptions(itf)

if not OEParseCommandLine(itf, argv):
OEThrow.Fatal("Unable to interpret command line!")

ifname = itf.GetString("-in")
ofname = itf.GetString("-out")

ifs = oemolistream(ifname)
mol = OEGraphMol()
OEPrepareDepiction(mol)

width, height = OEGetImageWidth(itf), OEGetImageHeight(itf)
opts = OE2DMolDisplayOptions(width, height, OEScale_AutoScale)
# set up display options from command line parameters
OESetup2DMolDisplayOptions(opts, itf)

disp = OE2DMolDisplay(mol, opts)
OERenderMolecule(ofname, disp)

InterfaceData = """
!CATEGORY "input/output options :"

!PARAMETER -in
!ALIAS -i
!TYPE string
!REQUIRED true
!BRIEF Input filename
!END

!PARAMETER -out
!ALIAS -o
!TYPE string
!REQUIRED true
!BRIEF Output filename
!END

!END
"""

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

prompt> python DepictMolConfigure.py --help


will generate the following standard interface:

Simple parameter list
image options
-height : Height of output image
-width : Width of output image

input/output
-in : Input filename
-out : Output filename

molecule display options
-aromstyle : Aromatic ring display style
-atomcolor : Atom coloring style
-atomprop : Atom property display
-atomstereostyle : Atom stereo display style
-bondcolor : Bond coloring style
-bondprop : Bond property display
-bondstereostyle : Bond stereo display style
-hydrstyle : Hydrogen display style
-linewidth : Default bond line width
-scale : Scaling of the depicted molecule
-superdisp : Super atom display style
-titleloc : Location of the molecule title