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 dummiesAreAttachments; // draws "breaks" at dummy atoms
42  bool circleAtoms; // draws circles under highlighted atoms
43  DrawColour highlightColour; // default highlight color
44  bool continuousHighlight; // highlight by drawing an outline *underneath* the
45  // molecule
46  int flagCloseContactsDist; // if positive, this will be used as a cutoff (in
47  // pixels) for highlighting close contacts
48  bool includeAtomTags; // toggles inclusion of atom tags in the output. does
49  // not make sense for all renderers.
50  bool clearBackground; // toggles clearing the background before drawing a
51  // molecule
52  DrawColour
53  backgroundColour; // color to be used while clearing the background
54  int legendFontSize; // font size (in pixels) to be used for the legend (if
55  // present)
56  DrawColour legendColour; // color to be used for the legend (if present)
57  double multipleBondOffset; // offset (in Angstroms) for the extra lines in a
58  // multiple bond
59  std::map<int, std::string> atomLabels; // replacement labels for atoms
60  std::vector<std::vector<int> > atomRegions; // regions
61 
63  : dummiesAreAttachments(false),
64  circleAtoms(true),
65  highlightColour(1, .5, .5),
66  continuousHighlight(true),
67  flagCloseContactsDist(3),
68  includeAtomTags(false),
69  clearBackground(true),
70  backgroundColour(1, 1, 1),
71  legendFontSize(12),
72  legendColour(0, 0, 0),
73  multipleBondOffset(0.15){};
74 };
75 
76 class MolDraw2D {
77  public:
78  typedef enum { C = 0, N, E, S, W } OrientType;
79  typedef enum {
80  TextDrawNormal = 0,
82  TextDrawSubscript
83  } TextDrawType;
84 
85  MolDraw2D(int width, int height);
86  virtual ~MolDraw2D() {}
87 
88  virtual void drawMolecule(
89  const ROMol &mol, const std::vector<int> *highlight_atoms = NULL,
90  const std::map<int, DrawColour> *highlight_map = NULL,
91  const std::map<int, double> *highlight_radii = NULL, int confId = -1);
92 
93  virtual void drawMolecule(
94  const ROMol &mol, const std::string &legend,
95  const std::vector<int> *highlight_atoms = NULL,
96  const std::map<int, DrawColour> *highlight_map = NULL,
97  const std::map<int, double> *highlight_radii = NULL, int confId = -1);
98 
99  virtual void drawMolecule(
100  const ROMol &mol, const std::vector<int> *highlight_atoms,
101  const std::vector<int> *highlight_bonds,
102  const std::map<int, DrawColour> *highlight_atom_map = NULL,
103  const std::map<int, DrawColour> *highlight_bond_map = NULL,
104  const std::map<int, double> *highlight_radii = NULL, int confId = -1);
105 
106  virtual void drawMolecule(
107  const ROMol &mol, const std::string &legend,
108  const std::vector<int> *highlight_atoms,
109  const std::vector<int> *highlight_bonds,
110  const std::map<int, DrawColour> *highlight_atom_map = NULL,
111  const std::map<int, DrawColour> *highlight_bond_map = NULL,
112  const std::map<int, double> *highlight_radii = NULL, int confId = -1);
113 
114  // transform a set of coords in the molecule's coordinate system
115  // to drawing system coordinates and vice versa. Note that the coordinates
116  // have
117  // the origin in the top left corner, which is how Qt and Cairo have it, no
118  // doubt a holdover from X Windows. This means that a higher y value will be
119  // nearer the bottom of the screen. This doesn't really matter except when
120  // doing text superscripts and subscripts.
121  virtual Point2D getDrawCoords(const Point2D &mol_cds) const;
122  virtual Point2D getDrawCoords(int at_num) const;
123  virtual Point2D getAtomCoords(const std::pair<int, int> &screen_cds) const;
124  virtual Point2D getAtomCoords(
125  const std::pair<double, double> &screen_cds) const;
126  virtual Point2D getAtomCoords(int at_num) const;
127 
128  virtual int width() const { return width_; }
129  virtual int height() const { return height_; }
130 
131  virtual double scale() const { return scale_; }
132  virtual void calculateScale();
133 
134  virtual double fontSize() const { return font_size_; }
135  // set font size in molecule coordinate units. That's probably Angstrom for
136  // RDKit.
137  virtual void setFontSize(double new_size);
138 
139  virtual void setColour(const DrawColour &col) { curr_colour_ = col; }
140  virtual DrawColour colour() const { return curr_colour_; }
141 
142  virtual void setDash(const DashPattern &patt) { curr_dash_ = patt; }
143  virtual const DashPattern &dash() const { return curr_dash_; }
144 
145  virtual void setLineWidth(int width) { curr_width_ = width; }
146  virtual int lineWidth() const { return curr_width_; }
147 
148  // establishes whether to put string draw mode into super- or sub-script
149  // mode based on contents of instring from i onwards. Increments i
150  // appropriately
151  // and returns true or false depending on whether it did something or not
152  bool setStringDrawMode(const std::string &instring, TextDrawType &draw_mode,
153  int &i) const;
154 
155  virtual void clearDrawing() = 0;
156 
157  virtual void drawLine(const Point2D &cds1, const Point2D &cds2) = 0;
158 
159  // using the current scale, work out the size of the label in molecule
160  // coordinates.
161  // Bear in mind when implementing this, that, for example, NH2 will appear as
162  // NH<sub>2</sub> to convey that the 2 is a subscript, and this needs to
163  // accounted
164  // for in the width and height.
165  virtual void getStringSize(const std::string &label, double &label_width,
166  double &label_height) const = 0;
167  // drawString centres the string on cds.
168  virtual void drawString(const std::string &str, const Point2D &cds);
169 
170  // draw polygons:
171  virtual void drawPolygon(const std::vector<Point2D> &cds) = 0;
172  virtual void drawTriangle(const Point2D &cds1, const Point2D &cds2,
173  const Point2D &cds3);
174  virtual void drawEllipse(const Point2D &cds1, const Point2D &cds2);
175  virtual void drawRect(const Point2D &cds1, const Point2D &cds2);
176  virtual void drawAttachmentLine(const Point2D &cds1, const Point2D &cds2,
177  const DrawColour &col, double len = 1.0,
178  unsigned int nSegments = 8);
179 
180  virtual void tagAtoms(const ROMol &mol) { RDUNUSED_PARAM(mol); };
181 
182  virtual bool fillPolys() const { return fill_polys_; }
183  virtual void setFillPolys(bool val) { fill_polys_ = val; }
184 
185  MolDrawOptions &drawOptions() { return options_; }
186  const MolDrawOptions &drawOptions() const { return options_; }
187 
188  const std::vector<Point2D> &atomCoords() const { return at_cds_; };
189  const std::vector<std::pair<std::string, OrientType> > &atomSyms() const {
190  return atom_syms_;
191  };
192 
193  private:
194  int width_, height_;
195  double scale_;
196  double x_min_, y_min_, x_range_, y_range_;
197  double x_trans_, y_trans_;
198  // font_size_ in molecule coordinate units. Default 0.5 (a bit bigger
199  // than the default width of a double bond)
200  double font_size_;
201  int curr_width_;
202  bool fill_polys_;
203  DrawColour curr_colour_;
204  DashPattern curr_dash_;
205  MolDrawOptions options_;
206 
207  std::vector<Point2D> at_cds_; // from mol
208  std::vector<int> atomic_nums_;
209  std::vector<std::pair<std::string, OrientType> > atom_syms_;
210  Point2D bbox_[2];
211 
212  // draw the char, with the bottom left hand corner at cds
213  virtual void drawChar(char c, const Point2D &cds) = 0;
214 
215  // return a DrawColour based on the contents of highlight_atoms or
216  // highlight_map, falling back to atomic number by default
217  DrawColour getColour(int atom_idx,
218  const std::vector<int> *highlight_atoms = NULL,
219  const std::map<int, DrawColour> *highlight_map = NULL);
220  DrawColour getColourByAtomicNum(int atomic_num);
221 
222  void extractAtomCoords(const ROMol &mol, int confId);
223  void extractAtomSymbols(const ROMol &mol);
224 
225  virtual void drawLine(const Point2D &cds1, const Point2D &cds2,
226  const DrawColour &col1, const DrawColour &col2);
227  void drawBond(const ROMol &mol, const BOND_SPTR &bond, int at1_idx,
228  int at2_idx, const std::vector<int> *highlight_atoms = NULL,
229  const std::map<int, DrawColour> *highlight_atom_map = NULL,
230  const std::vector<int> *highlight_bonds = NULL,
231  const std::map<int, DrawColour> *highlight_bond_map = NULL);
232  void drawWedgedBond(const Point2D &cds1, const Point2D &cds2,
233  bool draw_dashed, const DrawColour &col1,
234  const DrawColour &col2);
235  void drawAtomLabel(int atom_num,
236  const std::vector<int> *highlight_atoms = NULL,
237  const std::map<int, DrawColour> *highlight_map = NULL);
238 
239  // calculate normalised perpendicular to vector between two coords
240  Point2D calcPerpendicular(const Point2D &cds1, const Point2D &cds2);
241  // cds1 and cds2 are 2 atoms in a ring. Returns the perpendicular pointing
242  // into
243  // the ring.
244  Point2D bondInsideRing(const ROMol &mol, const BOND_SPTR &bond,
245  const Point2D &cds1, const Point2D &cds2);
246  // cds1 and cds2 are 2 atoms in a chain double bond. Returns the
247  // perpendicular
248  // pointing into the inside of the bond
249  Point2D bondInsideDoubleBond(const ROMol &mol, const BOND_SPTR &bond);
250  // calculate normalised perpendicular to vector between two coords, such that
251  // it's inside the angle made between (1 and 2) and (2 and 3).
252  Point2D calcInnerPerpendicular(const Point2D &cds1, const Point2D &cds2,
253  const Point2D &cds3);
254 
255  // take the coords for atnum, with neighbour nbr_cds, and move cds out to
256  // accommodate
257  // the label associated with it.
258  void adjustBondEndForLabel(int atnum, const Point2D &nbr_cds,
259  Point2D &cds) const;
260 
261  // adds LaTeX-like annotation for super- and sub-script.
262  std::pair<std::string, OrientType> getAtomSymbolAndOrientation(
263  const Atom &atom, const Point2D &nbr_sum);
264 
265  virtual void doContinuousHighlighting(
266  const ROMol &mol, const std::vector<int> *highlight_atoms,
267  const std::vector<int> *highlight_bonds,
268  const std::map<int, DrawColour> *highlight_atom_map,
269  const std::map<int, DrawColour> *highlight_bond_map,
270  const std::map<int, double> *highlight_radii);
271 
272  virtual void highlightCloseContacts();
273 };
274 }
275 
276 #endif // RDKITMOLDRAW2D_H
virtual void setColour(const DrawColour &col)
Definition: MolDraw2D.h:139
virtual int lineWidth() const
Definition: MolDraw2D.h:146
virtual void setLineWidth(int width)
Definition: MolDraw2D.h:145
boost::shared_ptr< Bond > BOND_SPTR
Definition: ROMol.h:41
virtual double fontSize() const
Definition: MolDraw2D.h:134
std::pair< std::string, OrientType > getAtomSymbolAndOrientation(const Atom &atom, RDGeom::Point2D nbrSum)
Definition: MolDrawing.h:58
virtual int height() const
Definition: MolDraw2D.h:129
std::vector< unsigned int > DashPattern
Definition: MolDraw2D.h:38
virtual void setDash(const DashPattern &patt)
Definition: MolDraw2D.h:142
DrawColour legendColour
Definition: MolDraw2D.h:56
const std::vector< Point2D > & atomCoords() const
Definition: MolDraw2D.h:188
virtual void setFillPolys(bool val)
Definition: MolDraw2D.h:183
virtual DrawColour colour() const
Definition: MolDraw2D.h:140
virtual bool fillPolys() const
Definition: MolDraw2D.h:182
pulls in the core RDKit functionality
ROMol is a molecule class that is intended to have a fixed topology.
Definition: ROMol.h:102
MolDrawOptions & drawOptions()
Definition: MolDraw2D.h:185
DrawColour backgroundColour
Definition: MolDraw2D.h:53
const MolDrawOptions & drawOptions() const
Definition: MolDraw2D.h:186
Includes a bunch of functionality for handling Atom and Bond queries.
Definition: Atom.h:28
virtual ~MolDraw2D()
Definition: MolDraw2D.h:86
#define RDUNUSED_PARAM(x)
Definition: Invariant.h:190
virtual double scale() const
Definition: MolDraw2D.h:131
virtual const DashPattern & dash() const
Definition: MolDraw2D.h:143
double multipleBondOffset
Definition: MolDraw2D.h:57
virtual int width() const
Definition: MolDraw2D.h:128
std::map< int, std::string > atomLabels
Definition: MolDraw2D.h:59
std::vector< std::vector< int > > atomRegions
Definition: MolDraw2D.h:60
DrawColour highlightColour
Definition: MolDraw2D.h:43
The class for representing atoms.
Definition: Atom.h:67
const std::vector< std::pair< std::string, OrientType > > & atomSyms() const
Definition: MolDraw2D.h:189
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
virtual void tagAtoms(const ROMol &mol)
Definition: MolDraw2D.h:180