RDKit
Open-source cheminformatics and machine learning.
MolDraw2DHelpers.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2014-2021 David Cosgrove and other RDKit contributors
3 //
4 // @@ All Rights Reserved @@
5 // This file is part of the RDKit.
6 // The contents are covered by the terms of the BSD license
7 // which is included in the file license.txt, found at the root
8 // of the RDKit source tree.
9 //
10 // Original author: David Cosgrove (CozChemIx Limited)
11 //
12 // A load of helper classes used by MolDraw2D.
13 
14 #ifndef RDKIT_MOLDRAW2DHELPERS_H
15 #define RDKIT_MOLDRAW2DHELPERS_H
16 
17 #include <Geometry/point.h>
18 
19 using RDGeom::Point2D;
20 
21 namespace RDKit {
22 
23 namespace MolDraw2D_detail {
24 // for aligning the drawing of text to the passed in coords.
25 enum class OrientType : unsigned char { C = 0, N, E, S, W };
26 enum class TextAlignType : unsigned char { MIDDLE = 0, START, END };
27 } // namespace MolDraw2D_detail
28 
29 struct DrawColour {
30  double r = 0.0, g = 0.0, b = 0.0, a = 1.0;
31  DrawColour() = default;
32  DrawColour(double r, double g, double b, double a = 1.0)
33  : r(r), g(g), b(b), a(a) {}
34  bool operator==(const DrawColour &other) const {
35  return r == other.r && g == other.g && b == other.b && a == other.a;
36  }
37  bool operator!=(const DrawColour &other) const { return !(*this == other); }
38  bool feq(const DrawColour &other, double tol = 0.001,
39  bool ignoreAlpha = true) const {
40  return fabs(r - other.r) <= tol && fabs(g - other.g) <= tol &&
41  fabs(b - other.b) <= tol &&
42  (ignoreAlpha || fabs(a - other.a) <= tol);
43  }
44  DrawColour operator+(const DrawColour &other) const {
45  return {r + other.r, g + other.g, b + other.b, a + other.a};
46  }
47  DrawColour operator-(const DrawColour &other) const {
48  return {r - other.r, g - other.g, b - other.b, a - other.a};
49  }
50  DrawColour operator/(double v) const {
51  PRECONDITION(v != 0.0, "divide by zero");
52  return {r / v, g / v, b / v, a / v};
53  }
54  DrawColour operator*(double v) const { return {r * v, g * v, b * v, a * v}; }
55 };
56 
57 typedef std::map<int, DrawColour> ColourPalette;
58 typedef std::vector<double> DashPattern;
59 
60 // This is used to convert the line width into something that SVG and
61 // Cairo use. It was picked by eye, and was formerly hidden in
62 // MolDraw2D::getDrawLineWidth().
63 static const double lineWidthScaleFactor = 0.02;
64 
65 //! use the RDKit's default palette r
66 // 201 is for hydrogens when atom symbols are not being drawn.
67 inline void assignDefaultPalette(ColourPalette &palette) {
68  palette.clear();
69  palette[-1] = DrawColour(0, 0, 0);
70  palette[0] = DrawColour(0.1, 0.1, 0.1);
71  palette[1] = palette[6] = DrawColour(0.0, 0.0, 0.0);
72  palette[7] = DrawColour(0.0, 0.0, 1.0);
73  palette[8] = DrawColour(1.0, 0.0, 0.0);
74  palette[9] = DrawColour(0.2, 0.8, 0.8);
75  palette[15] = DrawColour(1.0, 0.5, 0.0);
76  palette[16] = DrawColour(0.8, 0.8, 0.0);
77  palette[17] = DrawColour(0.0, 0.802, 0.0);
78  palette[35] = DrawColour(0.5, 0.3, 0.1);
79  palette[53] = DrawColour(0.63, 0.12, 0.94);
80  palette[201] = DrawColour(0.68, 0.85, 0.90);
81 };
82 
83 //! use the color palette from the Avalon renderer
84 // 201 is for hydrogens when atom symbols are not being drawn.
85 inline void assignAvalonPalette(ColourPalette &palette) {
86  palette.clear();
87  palette[-1] = DrawColour(0, 0, 0);
88  palette[0] = DrawColour(0.1, 0.1, 0.1);
89  palette[1] = palette[6] = DrawColour(0.0, 0.0, 0.0);
90  palette[7] = DrawColour(0.0, 0.0, 1.0);
91  palette[8] = DrawColour(1.0, 0.0, 0.0);
92  palette[9] = DrawColour(0.0, 0.498, 0.0);
93  palette[15] = DrawColour(0.498, 0.0, 0.498);
94  palette[16] = DrawColour(0.498, 0.247, 0.0);
95  palette[17] = DrawColour(0.0, 0.498, 0.0);
96  palette[35] = DrawColour(0.0, 0.498, 0.0);
97  palette[53] = DrawColour(0.247, 0.0, 0.498);
98  palette[201] = DrawColour(0.68, 0.85, 0.90);
99 };
100 
101 //! use (part of) the CDK color palette
102 /*!
103  data source:
104  https://github.com/cdk/cdk/blob/master/display/render/src/main/java/org/openscience/cdk/renderer/color/CDK2DAtomColors.java
105 */
106 // 201 is for hydrogens when atom symbols are not being drawn.
107 inline void assignCDKPalette(ColourPalette &palette) {
108  palette.clear();
109  palette[-1] = DrawColour(0, 0, 0);
110  palette[0] = DrawColour(0.1, 0.1, 0.1);
111  palette[1] = palette[6] = DrawColour(0.0, 0.0, 0.0);
112  palette[7] = DrawColour(0.188, 0.314, 0.972);
113  palette[8] = DrawColour(1.0, 0.051, 0.051);
114  palette[9] = DrawColour(0.565, 0.878, 0.314);
115  palette[15] = DrawColour(1.0, 0.5, 0.0);
116  palette[16] = DrawColour(0.776, 0.776, 0.173);
117  palette[17] = DrawColour(0.122, 0.498, 0.122);
118  palette[35] = DrawColour(0.651, 0.161, 0.161);
119  palette[53] = DrawColour(0.580, 0.0, 0.580);
120  palette[5] = DrawColour(1.000, 0.710, 0.710);
121  palette[201] = DrawColour(0.68, 0.85, 0.90);
122 };
123 
124 // 201 is for hydrogens when atom symbols are not being drawn.
125 inline void assignDarkModePalette(ColourPalette &palette) {
126  palette.clear();
127  palette[-1] = DrawColour(0.8, 0.8, 0.8);
128  palette[0] = DrawColour(0.9, 0.9, 0.9);
129  palette[1] = palette[6] = DrawColour(0.9, 0.9, 0.9);
130  palette[7] = DrawColour(0.33, 0.41, 0.92);
131  palette[8] = DrawColour(1.0, 0.2, 0.2);
132  palette[9] = DrawColour(0.2, 0.8, 0.8);
133  palette[15] = DrawColour(1.0, 0.5, 0.0);
134  palette[16] = DrawColour(0.8, 0.8, 0.0);
135  palette[17] = DrawColour(0.0, 0.802, 0.0);
136  palette[35] = DrawColour(0.71, 0.4, 0.07);
137  palette[53] = DrawColour(0.89, 0.004, 1);
138  palette[201] = DrawColour(0.68, 0.85, 0.90);
139 };
140 
141 inline void assignBWPalette(ColourPalette &palette) {
142  palette.clear();
143  palette[-1] = DrawColour(0, 0, 0);
144 };
145 
147  bool atomLabelDeuteriumTritium =
148  false; // toggles replacing 2H with D and 3H with T
149  bool dummiesAreAttachments = false; // draws "breaks" at dummy atoms
150  bool circleAtoms = true; // draws circles under highlighted atoms
151  bool splitBonds = false; // split bonds into per atom segments
152  // most useful for dynamic manipulation of drawing
153  // especially for svg
154  DrawColour highlightColour{1.0, 0.5, 0.5, 1.0}; // default highlight color
155  bool continuousHighlight = true; // highlight by drawing an outline
156  // *underneath* the molecule
157  bool fillHighlights = true; // fill the areas used to highlight atoms and
158  // atom regions
159  double highlightRadius = 0.3; // default if nothing given for a particular
160  // atom. units are "Angstrom"
161  int flagCloseContactsDist = 3; // if positive, this will be used as a cutoff
162  // (in pixels) for highlighting close contacts
163  bool includeAtomTags =
164  false; // toggles inclusion of atom tags in the output. does
165  // not make sense for all renderers.
166  bool clearBackground = true; // toggles clearing the background before
167  // drawing a molecule
168  DrawColour backgroundColour{
169  1.0, 1.0, 1.0, 1.0}; // color to be used while clearing the background
170  DrawColour queryColour{0.5, 0.5, 0.5,
171  1.0}; // color to be used for query bonds
172  int legendFontSize = 16; // font size (in pixels) to be used for the legend
173  // (if present)
174  double legendFraction =
175  0.1; // fraction of the draw panel to be used for the legend if present
176  int maxFontSize = 40; // maximum size in pixels for font in drawn molecule.
177  // -1 means no max.
178  int minFontSize = 6; // likewise for -1.
179  int fixedFontSize =
180  -1; // font size to use, in pixels. Default -1 means not fixed. If set,
181  // always used irrespective of scale, minFontSize and maxFontSize.
182  double annotationFontScale = 0.5; // scales font relative to atom labels for
183  // atom and bond annotation.
184  std::string fontFile = ""; // name of font file for freetype rendering. If
185  // given, over-rides default
186  // (BuiltinTelexRegular). Can also be
187  // BuiltinRobotoRegular.
188  DrawColour legendColour{0, 0,
189  0}; // color to be used for the legend (if present)
190  double multipleBondOffset = 0.15; // offset for the extra lines
191  // in a multiple bond as a fraction of
192  // mean bond length
193  double padding =
194  0.05; // fraction of empty space to leave around the molecule
195  double additionalAtomLabelPadding = 0.0; // additional padding to leave
196  // around atom labels. Expressed as
197  // a fraction of the font size.
198  std::map<int, std::string> atomLabels; // replacement labels for atoms
199  bool noAtomLabels =
200  false; // disables inclusion of atom labels in the rendering
201  std::vector<std::vector<int>> atomRegions; // regions
202  DrawColour symbolColour{
203  0.0, 0.0, 0.0,
204  1.0}; // color to be used for the symbols and arrows in reactions
205  DrawColour annotationColour{0.0, 0.0, 0.0,
206  1.0}; // color to be used for annotations
207  double bondLineWidth = 2.0; // default line width when drawing bonds
208  bool scaleBondWidth = false; // whether to apply scale() to the bond width
209  bool scaleHighlightBondWidth = true; // likewise with bond highlights.
210  int highlightBondWidthMultiplier = 8; // what to multiply standard bond width
211  // by for highlighting.
212  bool prepareMolsBeforeDrawing = true; // call prepareMolForDrawing() on each
213  // molecule passed to drawMolecules()
214  std::vector<DrawColour> highlightColourPalette; // defining 10 default colors
215  // for highlighting atoms and bonds
216  // or reactants in a reactions
217  ColourPalette atomColourPalette; // the palette used to assign
218  // colors to atoms based on
219  // atomic number.
220  double fixedScale =
221  -1.0; // fixes scale to this fraction of draw window width, so
222  // an average bond is this fraction of the width. If
223  // scale comes out smaller than this, reduces scale, but
224  // won't make it larger. The default of -1.0 means no fix.
225  double fixedBondLength =
226  -1.0; // fixes the bond length (and hence the scale) to
227  // always be this number of pixels. Assuming a bond
228  // length in coordinates is 1, as is normal. If
229  // scale comes out smaller than this, reduces scale,
230  // but won't make it larger. The default -1.0 means no
231  // fix. If both fixedScale and fixedBondLength are >
232  // 0.0, fixedScale wins.
233  double rotate = 0.0; // angle in degrees to rotate coords by about centre
234  // before drawing.
235  bool addAtomIndices = false; // adds atom indices to drawings.
236  bool addBondIndices = false; // adds bond indices to drawings.
237  bool isotopeLabels = true; // adds isotope to non-dummy atoms.
238  bool dummyIsotopeLabels = true; // adds isotope labels to dummy atoms.
239 
240  bool addStereoAnnotation = false; // adds E/Z and R/S to drawings.
241  bool atomHighlightsAreCircles = false; // forces atom highlights always to be
242  // circles. Default (false) is to put
243  // ellipses round longer labels.
244  bool centreMoleculesBeforeDrawing = false; // moves the centre of the drawn
245  // molecule to (0,0)
246  bool explicitMethyl = false; // draw terminal methyl and related as CH3
247  bool includeRadicals =
248  true; // include radicals in the drawing (it can be useful to turn this
249  // off for reactions and queries)
250  bool includeMetadata =
251  true; // when possible include metadata about molecules and reactions in
252  // the output to allow them to be reconstructed
253  bool comicMode = false; // simulate hand-drawn lines for bonds. When combined
254  // with a font like Comic-Sans or Comic-Neue, this
255  // gives xkcd-like drawings.
256  int variableBondWidthMultiplier = 16; // what to multiply standard bond width
257  // by for variable attachment points.
258  double variableAtomRadius = 0.4; // radius value to use for atoms involved in
259  // variable attachment points.
260  DrawColour variableAttachmentColour = {
261  0.8, 0.8, 0.8, 1.0}; // colour to use for variable attachment points
262  bool includeChiralFlagLabel =
263  false; // add a molecule annotation with "ABS" if the chiral flag is set
264  bool simplifiedStereoGroupLabel =
265  false; // if all specified stereocenters are in a single StereoGroup,
266  // show a molecule-level annotation instead of the individual
267  // labels
268  bool unspecifiedStereoIsUnknown = false; // if true, double bonds with
269  // unspecified stereo are drawn
270  // crossed, potential stereocenters
271  // with unspecified stereo are drawn
272  // with a wavy bond.
273  bool singleColourWedgeBonds =
274  false; // if true wedged and dashed bonds are drawn
275  // using symbolColour rather than inheriting
276  // their colour from the atoms
277  bool useMolBlockWedging = false; // If the molecule came from a MolBlock,
278  // prefer the wedging information that
279  // provides. If false, use RDKit rules.
280  double scalingFactor = 20.0; // scaling factor used for pixels->angstrom
281  // when auto scaling is being used
282  double baseFontSize =
283  -1.0; // when > 0 this is used to set the baseFontSize used for text
284  // drawing. As a reference point: the default value for
285  // DrawText::baseFontSize is 0.6
286  bool drawMolsSameScale = true; // when drawing multiple molecules with
287  // DrawMolecules, forces them to use the same
288  // scale. Default is true.
289  bool useComplexQueryAtomSymbols =
290  true; // replace any atom, any hetero, any halo queries
291  // with complex query symbols A, Q, X, M, optionally followed
292  // by H if hydrogen is included (except for AH, which stays *).
293  // Default is true.
294 
296  highlightColourPalette.emplace_back(
297  DrawColour(1., 1., .67)); // popcorn yellow
298  highlightColourPalette.emplace_back(DrawColour(1., .8, .6)); // sand
299  highlightColourPalette.emplace_back(
300  DrawColour(1., .71, .76)); // light pink
301  highlightColourPalette.emplace_back(
302  DrawColour(.8, 1., .8)); // offwhitegreen
303  highlightColourPalette.emplace_back(DrawColour(.87, .63, .87)); // plum
304  highlightColourPalette.emplace_back(
305  DrawColour(.76, .94, .96)); // pastel blue
306  highlightColourPalette.emplace_back(
307  DrawColour(.67, .67, 1.)); // periwinkle
308  highlightColourPalette.emplace_back(DrawColour(.64, .76, .34)); // avocado
309  highlightColourPalette.emplace_back(
310  DrawColour(.56, .93, .56)); // light green
311  highlightColourPalette.emplace_back(DrawColour(.20, .63, .79)); // peacock
312  assignDefaultPalette(atomColourPalette);
313  }
314 };
315 
316 } // namespace RDKit
317 
318 #endif // RDKIT_MOLDRAW2DHELPERS_H
#define PRECONDITION(expr, mess)
Definition: Invariant.h:109
#define RDKIT_MOLDRAW2D_EXPORT
Definition: export.h:281
RDKIT_MOLDRAW2D_EXPORT void addBondIndices(const ROMol &mol)
add annotations with bond indices.
RDKIT_MOLDRAW2D_EXPORT void addAtomIndices(const ROMol &mol)
add annotations with atom indices.
RDKIT_MOLDRAW2D_EXPORT void addStereoAnnotation(const ROMol &mol, bool includeRelativeCIP=false)
add R/S, relative stereo, and E/Z annotations to atoms and bonds
Std stuff.
Definition: Abbreviations.h:19
std::vector< double > DashPattern
static const double lineWidthScaleFactor
void assignDefaultPalette(ColourPalette &palette)
use the RDKit's default palette r
void assignAvalonPalette(ColourPalette &palette)
use the color palette from the Avalon renderer
void assignDarkModePalette(ColourPalette &palette)
std::map< int, DrawColour > ColourPalette
void assignBWPalette(ColourPalette &palette)
void assignCDKPalette(ColourPalette &palette)
use (part of) the CDK color palette
bool feq(const DrawColour &other, double tol=0.001, bool ignoreAlpha=true) const
DrawColour()=default
DrawColour operator+(const DrawColour &other) const
DrawColour operator/(double v) const
DrawColour operator*(double v) const
DrawColour(double r, double g, double b, double a=1.0)
bool operator!=(const DrawColour &other) const
DrawColour operator-(const DrawColour &other) const
bool operator==(const DrawColour &other) const
std::vector< std::vector< int > > atomRegions
std::map< int, std::string > atomLabels
ColourPalette atomColourPalette
std::vector< DrawColour > highlightColourPalette