RDKit
Open-source cheminformatics and machine learning.
MolDraw2D.h
Go to the documentation of this file.
1 //
2 // @@ All Rights Reserved @@
3 // This file is part of the RDKit.
4 // The contents are covered by the terms of the BSD license
5 // which is included in the file license.txt, found at the root
6 // of the RDKit source tree.
7 //
8 // Original author: David Cosgrove (AstraZeneca)
9 // 27th May 2014
10 //
11 // This class makes a 2D drawing of an RDKit molecule.
12 // It draws heavily on $RDBASE/GraphMol/MolDrawing/MolDrawing.h.
13 // One purpose of this is to make it easier to overlay annotations on top of
14 // the molecule drawing, which is difficult to do from the output of
15 // MolDrawing.h
16 // The class design philosophy echoes a standard one:
17 // a virtual base class defines the interface and does all
18 // the heavy lifting and concrete derived classes implement
19 // library-specific drawing code such as drawing lines, writing strings
20 // etc.
21 
22 #ifndef RDKITMOLDRAW2D_H
23 #define RDKITMOLDRAW2D_H
24 
25 #include <vector>
26 
27 #include <Geometry/point.h>
28 #include <GraphMol/RDKitBase.h>
29 
30 #include <boost/tuple/tuple.hpp>
31 
32 // ****************************************************************************
33 using RDGeom::Point2D;
34 
35 namespace RDKit {
36 
37 typedef boost::tuple<float, float, float> DrawColour;
38 typedef std::vector<unsigned int> DashPattern;
39 
41  bool atomLabelDeuteriumTritium; // toggles replacing 2H with D and 3H with T
42  bool dummiesAreAttachments; // draws "breaks" at dummy atoms
43  bool circleAtoms; // draws circles under highlighted atoms
44  DrawColour highlightColour; // default highlight color
45  bool continuousHighlight; // highlight by drawing an outline *underneath* the
46  // molecule
47  int flagCloseContactsDist; // if positive, this will be used as a cutoff (in
48  // pixels) for highlighting close contacts
49  bool includeAtomTags; // toggles inclusion of atom tags in the output. does
50  // not make sense for all renderers.
51  bool clearBackground; // toggles clearing the background before drawing a
52  // molecule
53  DrawColour
54  backgroundColour; // color to be used while clearing the background
55  int legendFontSize; // font size (in pixels) to be used for the legend (if
56  // present)
57  DrawColour legendColour; // color to be used for the legend (if present)
58  double multipleBondOffset; // offset (in Angstroms) for the extra lines in a
59  // multiple bond
60  double padding; // fraction of empty space to leave around the molecule
61  double additionalAtomLabelPadding; // additional padding to leave around atom
62  // labels. Expressed as a fraction of the
63  // font size.
64  std::map<int, std::string> atomLabels; // replacement labels for atoms
65  std::vector<std::vector<int> > atomRegions; // regions
66 
68  : atomLabelDeuteriumTritium(false),
69  dummiesAreAttachments(false),
70  circleAtoms(true),
71  highlightColour(1, .5, .5),
72  continuousHighlight(true),
73  flagCloseContactsDist(3),
74  includeAtomTags(false),
75  clearBackground(true),
76  backgroundColour(1, 1, 1),
77  legendFontSize(12),
78  legendColour(0, 0, 0),
79  multipleBondOffset(0.15),
80  padding(0.05),
81  additionalAtomLabelPadding(0.0){};
82 };
83 
84 class MolDraw2D {
85  public:
86  typedef enum { C = 0, N, E, S, W } OrientType;
87  typedef enum {
88  TextDrawNormal = 0,
90  TextDrawSubscript
91  } TextDrawType;
92 
93  MolDraw2D(int width, int height, int panelWidth = -1, int panelHeight = -1);
94 
95  virtual ~MolDraw2D() {}
96 
97  virtual void drawMolecule(
98  const ROMol &mol, const std::vector<int> *highlight_atoms = NULL,
99  const std::map<int, DrawColour> *highlight_map = NULL,
100  const std::map<int, double> *highlight_radii = NULL, int confId = -1);
101 
102  virtual void drawMolecule(
103  const ROMol &mol, const std::string &legend,
104  const std::vector<int> *highlight_atoms = NULL,
105  const std::map<int, DrawColour> *highlight_map = NULL,
106  const std::map<int, double> *highlight_radii = NULL, int confId = -1);
107 
108  virtual void drawMolecule(
109  const ROMol &mol, const std::vector<int> *highlight_atoms,
110  const std::vector<int> *highlight_bonds,
111  const std::map<int, DrawColour> *highlight_atom_map = NULL,
112  const std::map<int, DrawColour> *highlight_bond_map = NULL,
113  const std::map<int, double> *highlight_radii = NULL, int confId = -1);
114 
115  virtual void drawMolecule(
116  const ROMol &mol, const std::string &legend,
117  const std::vector<int> *highlight_atoms,
118  const std::vector<int> *highlight_bonds,
119  const std::map<int, DrawColour> *highlight_atom_map = NULL,
120  const std::map<int, DrawColour> *highlight_bond_map = NULL,
121  const std::map<int, double> *highlight_radii = NULL, int confId = -1);
122 
123  virtual void drawMolecules(
124  const std::vector<ROMol *> &mols,
125  const std::vector<std::string> *legends = NULL,
126  const std::vector<std::vector<int> > *highlight_atoms = NULL,
127  const std::vector<std::vector<int> > *highlight_bonds = NULL,
128  const std::vector<std::map<int, DrawColour> > *highlight_atom_maps = NULL,
129  const std::vector<std::map<int, DrawColour> > *highlight_bond_maps = NULL,
130  const std::vector<std::map<int, double> > *highlight_radii = NULL,
131  const std::vector<int> *confIds = NULL);
132 
133  // transform a set of coords in the molecule's coordinate system
134  // to drawing system coordinates and vice versa. Note that the coordinates
135  // have
136  // the origin in the top left corner, which is how Qt and Cairo have it, no
137  // doubt a holdover from X Windows. This means that a higher y value will be
138  // nearer the bottom of the screen. This doesn't really matter except when
139  // doing text superscripts and subscripts.
140  virtual Point2D getDrawCoords(const Point2D &mol_cds) const;
141  virtual Point2D getDrawCoords(int at_num) const;
142  virtual Point2D getAtomCoords(const std::pair<int, int> &screen_cds) const;
143  virtual Point2D getAtomCoords(
144  const std::pair<double, double> &screen_cds) const;
145  virtual Point2D getAtomCoords(int at_num) const;
146 
147  virtual int width() const { return width_; }
148  virtual int height() const { return height_; }
149  virtual int panelWidth() const { return panel_width_; }
150  virtual int panelHeight() const { return panel_height_; }
151 
152  double scale() const { return scale_; }
153  void calculateScale(int width, int height);
154  void calculateScale() { calculateScale(panel_width_, panel_height_); };
155  void setScale(int width, int height, const Point2D &minv,
156  const Point2D &maxv);
157  void setOffset(int x, int y) {
158  x_offset_ = x;
159  y_offset_ = y;
160  }
161  Point2D offset() { return Point2D(x_offset_, y_offset_); }
162 
163  virtual double fontSize() const { return font_size_; }
164  // set font size in molecule coordinate units. That's probably Angstrom for
165  // RDKit.
166  virtual void setFontSize(double new_size);
167 
168  virtual void setColour(const DrawColour &col) { curr_colour_ = col; }
169  virtual DrawColour colour() const { return curr_colour_; }
170 
171  virtual void setDash(const DashPattern &patt) { curr_dash_ = patt; }
172  virtual const DashPattern &dash() const { return curr_dash_; }
173 
174  virtual void setLineWidth(int width) { curr_width_ = width; }
175  virtual int lineWidth() const { return curr_width_; }
176 
177  // establishes whether to put string draw mode into super- or sub-script
178  // mode based on contents of instring from i onwards. Increments i
179  // appropriately
180  // and returns true or false depending on whether it did something or not
181  bool setStringDrawMode(const std::string &instring, TextDrawType &draw_mode,
182  int &i) const;
183 
184  virtual void clearDrawing() = 0;
185 
186  virtual void drawLine(const Point2D &cds1, const Point2D &cds2) = 0;
187 
188  // using the current scale, work out the size of the label in molecule
189  // coordinates.
190  // Bear in mind when implementing this, that, for example, NH2 will appear as
191  // NH<sub>2</sub> to convey that the 2 is a subscript, and this needs to
192  // accounted
193  // for in the width and height.
194  virtual void getStringSize(const std::string &label, double &label_width,
195  double &label_height) const = 0;
196  // drawString centres the string on cds.
197  virtual void drawString(const std::string &str, const Point2D &cds);
198 
199  // draw polygons:
200  virtual void drawPolygon(const std::vector<Point2D> &cds) = 0;
201  virtual void drawTriangle(const Point2D &cds1, const Point2D &cds2,
202  const Point2D &cds3);
203  virtual void drawEllipse(const Point2D &cds1, const Point2D &cds2);
204  virtual void drawRect(const Point2D &cds1, const Point2D &cds2);
205  virtual void drawAttachmentLine(const Point2D &cds1, const Point2D &cds2,
206  const DrawColour &col, double len = 1.0,
207  unsigned int nSegments = 16);
208  virtual void drawWavyLine(const Point2D &cds1, const Point2D &cds2,
209  const DrawColour &col1, const DrawColour &col2,
210  unsigned int nSegments = 16,
211  double vertOffset = 0.05);
212  virtual void tagAtoms(const ROMol &mol) { RDUNUSED_PARAM(mol); };
213 
214  virtual bool fillPolys() const { return fill_polys_; }
215  virtual void setFillPolys(bool val) { fill_polys_ = val; }
216 
217  MolDrawOptions &drawOptions() { return options_; }
218  const MolDrawOptions &drawOptions() const { return options_; }
219 
220  const std::vector<Point2D> &atomCoords() const {
221  PRECONDITION(activeMolIdx_ >= 0, "no index");
222  return at_cds_[activeMolIdx_];
223  };
224  const std::vector<std::pair<std::string, OrientType> > &atomSyms() const {
225  PRECONDITION(activeMolIdx_ >= 0, "no index");
226  return atom_syms_[activeMolIdx_];
227  };
228 
229  private:
230  bool needs_scale_;
231  int width_, height_, panel_width_, panel_height_;
232  double scale_;
233  double x_min_, y_min_, x_range_, y_range_;
234  double x_trans_, y_trans_;
235  int x_offset_, y_offset_; // translation in screen coordinates
236  // font_size_ in molecule coordinate units. Default 0.5 (a bit bigger
237  // than the default width of a double bond)
238  double font_size_;
239  int curr_width_;
240  bool fill_polys_;
241  int activeMolIdx_;
242 
243  DrawColour curr_colour_;
244  DashPattern curr_dash_;
245  MolDrawOptions options_;
246 
247  std::vector<std::vector<Point2D> > at_cds_; // from mol
248  std::vector<std::vector<int> > atomic_nums_;
249  std::vector<std::vector<std::pair<std::string, OrientType> > > atom_syms_;
250  Point2D bbox_[2];
251 
252  // draw the char, with the bottom left hand corner at cds
253  virtual void drawChar(char c, const Point2D &cds) = 0;
254 
255  // return a DrawColour based on the contents of highlight_atoms or
256  // highlight_map, falling back to atomic number by default
257  DrawColour getColour(int atom_idx,
258  const std::vector<int> *highlight_atoms = NULL,
259  const std::map<int, DrawColour> *highlight_map = NULL);
260  DrawColour getColourByAtomicNum(int atomic_num);
261 
262  void extractAtomCoords(const ROMol &mol, int confId, bool updateBBox);
263  void extractAtomSymbols(const ROMol &mol);
264 
265  virtual void drawLine(const Point2D &cds1, const Point2D &cds2,
266  const DrawColour &col1, const DrawColour &col2);
267  void drawBond(const ROMol &mol, const BOND_SPTR &bond, int at1_idx,
268  int at2_idx, const std::vector<int> *highlight_atoms = NULL,
269  const std::map<int, DrawColour> *highlight_atom_map = NULL,
270  const std::vector<int> *highlight_bonds = NULL,
271  const std::map<int, DrawColour> *highlight_bond_map = NULL);
272  void drawWedgedBond(const Point2D &cds1, const Point2D &cds2,
273  bool draw_dashed, const DrawColour &col1,
274  const DrawColour &col2);
275  void drawAtomLabel(int atom_num,
276  const std::vector<int> *highlight_atoms = NULL,
277  const std::map<int, DrawColour> *highlight_map = NULL);
278  // cds1 and cds2 are 2 atoms in a ring. Returns the perpendicular pointing
279  // into
280  // the ring.
281  Point2D bondInsideRing(const ROMol &mol, const BOND_SPTR &bond,
282  const Point2D &cds1, const Point2D &cds2);
283  // cds1 and cds2 are 2 atoms in a chain double bond. Returns the
284  // perpendicular
285  // pointing into the inside of the bond
286  Point2D bondInsideDoubleBond(const ROMol &mol, const BOND_SPTR &bond);
287  // calculate normalised perpendicular to vector between two coords, such
288  // that
289  // it's inside the angle made between (1 and 2) and (2 and 3).
290  Point2D calcInnerPerpendicular(const Point2D &cds1, const Point2D &cds2,
291  const Point2D &cds3);
292 
293  // take the coords for atnum, with neighbour nbr_cds, and move cds out to
294  // accommodate
295  // the label associated with it.
296  void adjustBondEndForLabel(int atnum, const Point2D &nbr_cds,
297  Point2D &cds) const;
298 
299  // adds LaTeX-like annotation for super- and sub-script.
300  std::pair<std::string, OrientType> getAtomSymbolAndOrientation(
301  const Atom &atom, const Point2D &nbr_sum);
302 
303  protected:
304  virtual void doContinuousHighlighting(
305  const ROMol &mol, const std::vector<int> *highlight_atoms,
306  const std::vector<int> *highlight_bonds,
307  const std::map<int, DrawColour> *highlight_atom_map,
308  const std::map<int, DrawColour> *highlight_bond_map,
309  const std::map<int, double> *highlight_radii);
310 
311  virtual void highlightCloseContacts();
312 
313  // calculate normalised perpendicular to vector between two coords
314  Point2D calcPerpendicular(const Point2D &cds1, const Point2D &cds2);
315 };
316 }
317 
318 #endif // RDKITMOLDRAW2D_H
virtual void setColour(const DrawColour &col)
Definition: MolDraw2D.h:168
virtual void setLineWidth(int width)
Definition: MolDraw2D.h:174
boost::shared_ptr< Bond > BOND_SPTR
Definition: ROMol.h:42
virtual int height() const
Definition: MolDraw2D.h:148
std::pair< std::string, OrientType > getAtomSymbolAndOrientation(const Atom &atom, RDGeom::Point2D nbrSum)
Definition: MolDrawing.h:58
void calculateScale()
Definition: MolDraw2D.h:154
virtual DrawColour colour() const
Definition: MolDraw2D.h:169
std::vector< unsigned int > DashPattern
Definition: MolDraw2D.h:38
virtual void setDash(const DashPattern &patt)
Definition: MolDraw2D.h:171
DrawColour legendColour
Definition: MolDraw2D.h:57
virtual void setFillPolys(bool val)
Definition: MolDraw2D.h:215
virtual int panelHeight() const
Definition: MolDraw2D.h:150
virtual const DashPattern & dash() const
Definition: MolDraw2D.h:172
pulls in the core RDKit functionality
void setOffset(int x, int y)
Definition: MolDraw2D.h:157
ROMol is a molecule class that is intended to have a fixed topology.
Definition: ROMol.h:103
MolDrawOptions & drawOptions()
Definition: MolDraw2D.h:217
DrawColour backgroundColour
Definition: MolDraw2D.h:54
virtual bool fillPolys() const
Definition: MolDraw2D.h:214
const MolDrawOptions & drawOptions() const
Definition: MolDraw2D.h:218
virtual int lineWidth() const
Definition: MolDraw2D.h:175
double scale() const
Definition: MolDraw2D.h:152
double additionalAtomLabelPadding
Definition: MolDraw2D.h:61
Includes a bunch of functionality for handling Atom and Bond queries.
Definition: Atom.h:29
virtual ~MolDraw2D()
Definition: MolDraw2D.h:95
virtual int width() const
Definition: MolDraw2D.h:147
#define RDUNUSED_PARAM(x)
Definition: Invariant.h:194
virtual int panelWidth() const
Definition: MolDraw2D.h:149
double multipleBondOffset
Definition: MolDraw2D.h:58
#define PRECONDITION(expr, mess)
Definition: Invariant.h:107
std::map< int, std::string > atomLabels
Definition: MolDraw2D.h:64
std::vector< std::vector< int > > atomRegions
Definition: MolDraw2D.h:65
DrawColour highlightColour
Definition: MolDraw2D.h:44
virtual double fontSize() const
Definition: MolDraw2D.h:163
const std::vector< std::pair< std::string, OrientType > > & atomSyms() const
Definition: MolDraw2D.h:224
const std::vector< Point2D > & atomCoords() const
Definition: MolDraw2D.h:220
Point2D offset()
Definition: MolDraw2D.h:161
The class for representing atoms.
Definition: Atom.h:68
boost::tuple< float, float, float > DrawColour
Definition: MolDraw2D.h:37
void drawLine(std::vector< ElementType > &res, int atnum1, int atnum2, int lineWidth, int dashed, double x1, double y1, double x2, double y2)
Definition: MolDrawing.h:45
bool atomLabelDeuteriumTritium
Definition: MolDraw2D.h:41
virtual void tagAtoms(const ROMol &mol)
Definition: MolDraw2D.h:212