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

int main()
{
  OEGraphMol mol;
  OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1");
  OEAssignHybridization(mol);
  OEPrepareDepiction(mol);

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

  OEPen sp2pen(OEWhite, OEBlueTint, OEFill::Off, 1.5);
  OEAtomGlyphCircle glyphSP2(sp2pen, OECircleStyle::Sun, 1.2);
  OEAddGlyph(disp, glyphSP2, OEIsAtomHybridization(OEHybridization::sp2));

  OEPen sp3pen(OEWhite, OEPinkTint, OEFill::Off, 1.5);
  OEAtomGlyphCircle glyphSP3(sp3pen, OECircleStyle::Eyelash, 1.2);
  OEAddGlyph(disp, glyphSP3, OEIsAtomHybridization(OEHybridization::sp3));

  OERenderMolecule("AnnotateAtomPredicate.png", disp);

  return 0;
}
../_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

int main()
{
  OEGraphMol mol;
  OESmilesToMol(mol, "c1cc(NCC)cc(CS(=O)(=O)O)c1");
  OEPrepareDepiction(mol);

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

  OEPen pen(OEDarkPurple, OEDarkPurple, OEFill::Off, 2.0);
  OEBondGlyphArrow glyph(pen, 0.5);
  OEAddGlyph(disp, glyph, OEIsRotor());

  OERenderMolecule("AnnotateBondPredicate.png", disp);
  return 0;
}
../_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

class ColorCharge : public OEAtomGlyphBase
{
public :
  ColorCharge(const OELinearColorGradient cg) : colorg(cg) {}
  ~ColorCharge() {}
  bool RenderGlyph(OE2DMolDisplay& disp, const OEAtomBase* atom) const
  {
    OE2DAtomDisplay* adisp = disp.GetAtomDisplay(atom);
    if (adisp == nullptr || !adisp->IsVisible())
      return false;

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

    OEPen pen;
    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);
    OEDrawCircle(layer, OECircleStyle::Simpson, adisp->GetCoords(), radius, pen);

    return true;
  }
  OEAtomGlyphBase* CreateCopy() const
  {
    return new ColorCharge(colorg);
  }
private :
  OELinearColorGradient colorg;
};

int main()
{
  OEGraphMol mol;
  OESmilesToMol(mol, "Cc1cc(cc(c1[N+](=O)[O-])F)[N+]#C");
  OEMMFFAtomTypes(mol);
  OEMMFF94PartialCharges(mol);

  OEPrepareDepiction(mol);

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

  OEColorStop coloranion(-1.0, OEColor(OEDarkRed));
  OEColorStop colorcation(+1.0, OEColor(OEDarkBlue));
  OELinearColorGradient colorg(coloranion, colorcation);
  colorg.AddStop(OEColorStop(0.0, OEColor(OEWhite)));

  ColorCharge colorcharge(colorg);

  OEAddGlyph(disp, colorcharge, OESystem::OEUnaryTrue<OEAtomBase>());

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

Example of user-defined annotation

See also