Annotating Atoms and Bonds

The Grapheme TK provides a framework to annotate atoms and bonds i.e. mark them based on their properties. The following Listing 1 example shows how to mark \(sp^2\) and \(sp^3\) hybridized atoms of depicted molecules. After preparing the molecule for 2D depiction and calculating the atom hybridizations, the molecule display object is created (OE2DMolDisplay) that stores the depiction information of a molecule The OEAddGlyph function is then called to add glyph to those atoms for which the given OEIsAtomHybridization functor returns true. In this example, the built-in OEAtomGlyphCircle class is used to mark atoms by drawings a circle around them with a specific style (OECircleStyle). Finally, the image is written out to a file by calling the OEWriteImage function. The image created by Listing 1 example is shown in Figure: Example of atom annotation.

Listing 1: Example of using a built-in atom annotation style

public class AnnotateAtomPredicate {
    public static void main(String argv[]) {
        OEGraphMol mol = new OEGraphMol();
        oechem.OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1");
        oechem.OEAssignHybridization(mol);
        oedepict.OEPrepareDepiction(mol);

        OE2DMolDisplayOptions opts = new OE2DMolDisplayOptions(350, 250, OEScale.AutoScale);
        opts.SetTitleLocation(OETitleLocation.Hidden);
        OE2DMolDisplay disp = new OE2DMolDisplay(mol, opts);

        OEPen penSP2 = new OEPen(oechem.getOEWhite(), oechem.getOEBlueTint(), OEFill.Off, 1.5);
        OEAtomGlyphCircle glyphSP2 = new OEAtomGlyphCircle(penSP2, OECircleStyle.Sun, 1.2);
        oegrapheme.OEAddGlyph(disp, glyphSP2, new OEIsAtomHybridization(OEHybridization.sp2));

        OEPen penSP3 = new OEPen(oechem.getOEWhite(), oechem.getOEPinkTint(), OEFill.Off, 1.5);
        OEAtomGlyphCircle glyphSP3 = new OEAtomGlyphCircle(penSP3, OECircleStyle.Eyelash, 1.2);
        oegrapheme.OEAddGlyph(disp, glyphSP3, new OEIsAtomHybridization(OEHybridization.sp3));

        oedepict.OERenderMolecule("AnnotateAtomPredicate.png", disp);
    }
}
../_images/AnnotateAtomPredicate.png

Example of atom annotation

See also

Similarly, the following example shows how to annotate bonds. The bonds being highlighted are specified by the bond predicate passed to the OEAddGlyph function. For each bond the predicate returns true, i.e. if it is a rotatable bond, the OEBondGlyphArrow.RenderGlyph method is invoked that draws an arrow across the middle of the specific bond. The image created by Listing 2 is shown in Figure: Example of bond annotation.

Listing 2: Example of using a built-in bond annotation style

public class AnnotateBondPredicate {
    public static void main(String argv[]) {
        OEGraphMol mol = new OEGraphMol();
        oechem.OESmilesToMol(mol, "c1cc(NCC)cc(CS(=O)(=O)O)c1");
        oedepict.OEPrepareDepiction(mol);

        OE2DMolDisplayOptions opts = new OE2DMolDisplayOptions(400, 250, OEScale.AutoScale);
        opts.SetTitleLocation(OETitleLocation.Hidden);
        OE2DMolDisplay disp = new OE2DMolDisplay(mol, opts);

        OEPen pen = new OEPen(oechem.getOEDarkPurple(), oechem.getOEDarkPurple(), OEFill.Off, 2.0);
        OEBondGlyphArrow glyph = new OEBondGlyphArrow(pen, 0.5);
        oegrapheme.OEAddGlyph(disp, glyph, new OEIsRotor());

        oedepict.OERenderMolecule("AnnotateBondPredicate.png", disp);
    }
}
../_images/AnnotateBondPredicate.png

Example of bond annotation

The following table lists the customizable bond glyphs that are currently available in Grapheme TK.

Supported bond glyphs
../_images/OEBondGlyphArrow_Default.png ../_images/OEBondGlyphCircle_Default.png ../_images/OEBondGlyphCross_Default.png ../_images/OEBondGlyphCurvedArrow_Default.png

OEBondGlyphArrow

OEBondGlyphCircle

OEBondGlyphCross

OEBondGlyphCurvedArrow

../_images/OEBondGlyphScissors_Default.png ../_images/OEBondGlyphStitch_Default.png ../_images/OEBondGlyphZigZag_Default.png

OEBondGlyphScissors

OEBondGlyphStitch

OEBondGlyphZigZag

See also

The last example shows how to depict non-boolean properties by implementing a user-defined annotation style. User-defined atom and bond annotations can be implemented by deriving from the OEAtomGlyphBase and the OEBondGlyphBase abstract classes and implementing the OEAtomGlyphBase.RenderGlyph and the OEBondGlyphBase.RenderGlyph methods, respectively.

In the Listing 3 example, after calculating the MMFF charges, the atoms are annotated by their charge using the OELinearColorGradient class that interpolates colors. Atoms with negative and positive charge are highlighted by red and blue colors, respectively. The image created by Listing 3 is shown in Figure: Example of user-defined annotation.

Listing 3: Example of user-defined annotation

public class AnnotatePartialCharge {
    private static class ColorCharge extends OEAtomGlyphBase {
        private OELinearColorGradient colorg;

        private ColorCharge() {}
        public ColorCharge(OELinearColorGradient cg) {
            colorg = new OELinearColorGradient(cg);
        }

        @Override
        public boolean RenderGlyph(OE2DMolDisplay disp, OEAtomBase atom) {
            OE2DAtomDisplay adisp = disp.GetAtomDisplay(atom);
            if (adisp == null || !adisp.IsVisible())
                return false;

            double charge = atom.GetPartialCharge();
            if (charge == 0.0)
                return true;
            OEColor color = colorg.GetColorAt(charge);

            OEPen pen = new OEPen();
            pen.SetForeColor(color);
            color.SetA(100);
            pen.SetBackColor(color);
            pen.SetFill(OEFill.On);
            double radius = disp.GetScale()/2.5;

            OEImage layer = disp.GetLayer(OELayerPosition.Below);
            oegrapheme.OEDrawCircle(layer, OECircleStyle.Simpson, adisp.GetCoords(), radius, pen);

            return true;
        }

        @Override
        public OEAtomGlyphBase CreateCopy() {
            ColorCharge copy = new ColorCharge(colorg);
            copy.swigReleaseOwnership();
            return copy;
        }
    }

    public static void main(String argv[]) {
        OEGraphMol mol = new OEGraphMol();
        oechem.OESmilesToMol(mol, "Cc1cc(cc(c1[N+](=O)[O-])F)[N+]#C");
        oechem.OEMMFFAtomTypes(mol);
        oechem.OEMMFF94PartialCharges(mol);

        oedepict.OEPrepareDepiction(mol);

        OE2DMolDisplayOptions opts = new OE2DMolDisplayOptions(350, 250, OEScale.AutoScale);
        opts.SetAtomColorStyle(OEAtomColorStyle.WhiteMonochrome);
        opts.SetTitleLocation(OETitleLocation.Hidden);
        OE2DMolDisplay disp = new OE2DMolDisplay(mol, opts);

        OEColorStop coloranion = new OEColorStop(-1.0, oechem.getOEDarkRed());
        OEColorStop colorcation = new OEColorStop(+1.0, oechem.getOEDarkBlue());
        OELinearColorGradient grad = new OELinearColorGradient(coloranion, colorcation);
        grad.AddStop(new OEColorStop(0.0, oechem.getOEWhite()));

        ColorCharge colorcharge = new ColorCharge(grad);

        oegrapheme.OEAddGlyph(disp, colorcharge, new OEIsTrueAtom());

        oedepict.OERenderMolecule("AnnotatePartialCharge.png", disp);
    }
}
../_images/AnnotatePartialCharge.png

Example of user-defined annotation

See also