RDKit
Open-source cheminformatics and machine learning.
DepictUtils.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2003-2010 Greg Landrum and Rational Discovery LLC
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 #include <RDGeneral/export.h>
11 #ifndef _RD_DEPICT_UTILS_H_
12 #define _RD_DEPICT_UTILS_H_
13 
14 // REVIEW: remove extra headers here
15 #include <RDGeneral/types.h>
16 #include <GraphMol/RDKitBase.h>
17 #include <GraphMol/RWMol.h>
18 #include <GraphMol/ROMol.h>
19 #include <Geometry/Transform2D.h>
20 #include <Geometry/point.h>
21 #include <queue>
22 
23 namespace RDDepict {
24 RDKIT_DEPICTOR_EXPORT extern double BOND_LEN;
26 RDKIT_DEPICTOR_EXPORT extern double BOND_THRES;
27 RDKIT_DEPICTOR_EXPORT extern double ANGLE_OPEN;
28 RDKIT_DEPICTOR_EXPORT extern unsigned int MAX_COLL_ITERS;
30 RDKIT_DEPICTOR_EXPORT extern unsigned int NUM_BONDS_FLIPS;
31 
32 typedef std::vector<const RDGeom::Point2D *> VECT_C_POINT;
33 
34 typedef std::pair<int, int> PAIR_I_I;
35 typedef std::vector<PAIR_I_I> VECT_PII;
37  bool operator()(const PAIR_I_I &pd1, const PAIR_I_I &pd2) const {
38  return pd1.first > pd2.first;
39  }
40 };
41 
42 typedef std::priority_queue<PAIR_I_I, VECT_PII, gtIIPair> PR_QUEUE;
43 
44 typedef std::pair<double, PAIR_I_I> PAIR_D_I_I;
45 typedef std::list<PAIR_D_I_I> LIST_PAIR_DII;
46 
47 //! Some utility functions used in generating 2D coordinates
48 
49 //! Embed a ring as a convex polygon in 2D
50 /*!
51  The process here is very straightforward:
52 
53  We take the center of the ring to lie at the origin, so put the first
54  point at the origin and then sweep
55  anti-clockwise by an angle A = 360/n for the next point.
56 
57  The length of the arm (l) we want to sweep is easy to compute given the
58  bond length (b) we want to use for each bond in the ring (for now
59  we will assume that this bond legnth is the same for all bonds in the ring:
60 
61  l = b/sqrt(2*(1 - cos(A))
62 
63  the above formula derives from the triangle formula, where side 'c' is given
64  in terms of sides 'a' and 'b' as:
65 
66  c = a^2 + b^2 - 2.a.b.cos(A)
67 
68  where A is the angle between a and b
69  */
71  const RDKit::INT_VECT &ring);
72 
74  const RDGeom::Transform2D &trans);
75 
76 //! Find a point that bisects the angle at rcr
77 /*!
78  The new point lies between nb1 and nb2. The line (rcr, newPt) bisects the
79  angle
80  'ang' at rcr
81 */
83  const RDGeom::Point2D &rcr, double ang, const RDGeom::Point2D &nb1,
84  const RDGeom::Point2D &nb2);
85 
86 //! Reflect a set of point through a the line joining two point
87 /*!
88  ARGUMENTS:
89  \param coordMap a map of <int, point2D> going from atom id to current
90  coordinates of the points that need to be reflected:
91  The coordinates are overwritten
92  \param loc1 the first point of the line that is to be used as a
93  mirror
94  \param loc2 the second point of the line to be used as a mirror
95  */
97  const RDGeom::Point2D &loc1,
98  const RDGeom::Point2D &loc2);
99 
101  const RDGeom::Point2D &loc1,
102  const RDGeom::Point2D &loc2);
103 
104 //! Set the neighbors yet to added to aid such that the atoms with the most subs
105 // fall on opposite sides
106 /*!
107  Ok this needs some explanation
108  - Let A, B, C, D be the substituent on the central atom X (given
109  by atom index aid)
110  - also let A be the atom that is already embedded
111  - Now we want the order in which the remaining neighbors B,C,D are
112  added to X such that the atoms with atom with largest number of
113  substituent fall on opposite sides of X so as to minimize atom
114  clashes later in the depiction
115 
116  E.g. let say we have the following situation
117 <pre>
118  B
119  | |
120  A--X--C
121  | |
122  --D--
123  |
124 </pre>
125  In this case the number substituent of A, B, C, D are 3, 1, 1,
126  4 respectively so want to A and D to go opposite sides and so that
127  we draw
128 <pre>
129  B
130  | | |
131  A--X--D--
132  | | |
133  C
134 </pre>
135  And the correct ordering of the neighbors is B,D,C
136 */
138  const RDKit::INT_VECT &nbrs,
139  const RDKit::ROMol &mol);
140 
141 //! \brief From a given set of rings find the ring the largest common elements
142 // with other rings
143 /*
144  Bit of a weird function - this is typically called once we have embedded some
145  of the
146  rings in a fused system and we are looking for the ring that must be embedded
147  (or merged)
148  next. The heuristic used here is to pick the rings with the maximum number of
149  atoms
150  in common with the rings that are already embedded.
151 
152  \param doneRings a vertor of ring IDs that have been embedded already
153  \param fusedRings list of all the rings in the fused system
154  \param nextId this is where the ID for the next ring is written
155 
156  \return list of atom ids that are common
157 */
159  const RDKit::INT_VECT &doneRings, const RDKit::VECT_INT_VECT &fusedRings,
160  int &nextId);
161 
162 typedef std::pair<int, int> INT_PAIR;
163 typedef std::vector<INT_PAIR> INT_PAIR_VECT;
164 typedef INT_PAIR_VECT::const_iterator INT_PAIR_VECT_CI;
165 
166 typedef std::pair<double, INT_PAIR> DOUBLE_INT_PAIR;
167 
168 //! Sort a list of atoms by their CIP rank
169 /*!
170  \param mol molecule of interest
171  \param commAtms atoms that need to be ranked
172  \param ascending sort to an ascending order or a descending order
173 */
174 template <class T>
176  const T &commAtms,
177  bool ascending = true);
178 
179 //! computes a subangle for an atom of given hybridization and degree
180 /*!
181  \param degree the degree of the atom (number of neighbors)
182  \param htype the atom's hybridization
183 
184  \return the subangle (in radians)
185 */
186 inline double computeSubAngle(unsigned int degree,
188  double angle = M_PI;
189  switch (htype) {
191  case RDKit::Atom::SP3:
192  if (degree == 4) {
193  angle = M_PI / 2;
194  } else {
195  angle = 2 * M_PI / 3;
196  }
197  break;
198  case RDKit::Atom::SP2:
199  angle = 2 * M_PI / 3;
200  break;
201  default:
202  angle = 2. * M_PI / degree;
203  }
204  return angle;
205 }
206 
207 //! computes the rotation direction between two vectors
208 /*!
209 
210  Let:
211 
212  v1 = loc1 - center
213 
214  v2 = loc2 - center
215 
216  If remaining angle(v1, v2) is < 180 and corss(v1, v2) > 0.0 then the rotation
217  dir is +1.0
218 
219  else if remAngle(v1, v2) is > 180 and cross(v1, v2) < 0.0 then rotation dir is
220  -1.0
221 
222  else if remAngle(v1, v2) is < 180 and cross(v1, v2) < 0.0 then rotation dir is
223  -1.0
224 
225  finally if remAngle(v1, v2) is > 180 and cross(v1, v2) < 0.0 then rotation dir
226  is +1.0
227 
228  \param center the common point
229  \param loc1 endpoint 1
230  \param loc2 endpoint 2
231  \param remAngle the remaining angle about center in radians
232 
233  \return the rotation direction (1 or -1)
234 */
235 inline int rotationDir(const RDGeom::Point2D &center,
236  const RDGeom::Point2D &loc1, const RDGeom::Point2D &loc2,
237  double remAngle) {
238  RDGeom::Point2D pt1 = loc1 - center;
239  RDGeom::Point2D pt2 = loc2 - center;
240  double cross = pt1.x * pt2.y - pt1.y * pt2.x;
241  double diffAngle = M_PI - remAngle;
242  cross *= diffAngle;
243  if (cross >= 0.0) {
244  return -1;
245  } else {
246  return 1;
247  }
248 }
249 
250 //! computes and return the normal of a vector between two points
251 /*!
252  \param center the common point
253  \param other the endpoint
254 
255  \return the normal
256 */
258  const RDGeom::Point2D &other) {
259  RDGeom::Point2D res = other - center;
260  res.normalize();
261  double tmp = res.x;
262  res.x = -res.y;
263  res.y = tmp;
264  return res;
265 }
266 
267 //! computes the rotation angle between two vectors
268 /*!
269  \param center the common point
270  \param loc1 endpoint 1
271  \param loc2 endpoint 2
272 
273  \return the angle (in radians)
274 */
275 inline double computeAngle(const RDGeom::Point2D &center,
276  const RDGeom::Point2D &loc1,
277  const RDGeom::Point2D &loc2) {
278  RDGeom::Point2D v1 = loc1 - center;
279  RDGeom::Point2D v2 = loc2 - center;
280  return v1.angleTo(v2);
281 }
282 
283 //! \brief pick the ring to embed first in a fused system
284 /*!
285  \param mol the molecule of interest
286  \param fusedRings the collection of the molecule's fused rings
287 
288  \return the index of the ring with the least number of substitutions
289 */
291  const RDKit::ROMol &mol, const RDKit::VECT_INT_VECT &fusedRings);
292 
293 //! \brief find the rotatable bonds on the shortest path between two atoms
294 //! we will ignore ring atoms, and double bonds which are marked cis/trans
295 /*!
296  <b>Note</b> that rotatable in this context doesn't connect to the
297  standard chemical definition of a rotatable bond; we're just talking
298  about bonds than can be flipped in order to clean up the depiction.
299 
300  \param mol the molecule of interest
301  \param aid1 index of the first atom
302  \param aid2 index of the second atom
303 
304  \return a set of the indices of the rotatable bonds
305 */
307  unsigned int aid1,
308  unsigned int aid2);
309 
310 //! \brief find all the rotatable bonds in a molecule
311 //! we will ignore ring atoms, and double bonds which are marked cis/trans
312 /*!
313  <b>Note</b> that rotatable in this context doesn't connect to the
314  standard chemical definition of a rotatable bond; we're just talking
315  about bonds than can be flipped in order to clean up the depiction.
316 
317  \param mol the molecule of interest
318 
319  \return a set of the indices of the rotatable bonds
320 */
322  const RDKit::ROMol &mol);
323 
324 //! Get the ids of the atoms and bonds that are connected to aid
325 RDKIT_DEPICTOR_EXPORT void getNbrAtomAndBondIds(unsigned int aid,
326  const RDKit::ROMol *mol,
327  RDKit::INT_VECT &aids,
328  RDKit::INT_VECT &bids);
329 
330 //! Find pairs of bonds that can be permuted at a non-ring degree 4 atom
331 /*!
332  This function will return only those pairs that cannot be
333  permuted by flipping a rotatble bond
334 
335  D
336  |
337  b3
338  |
339  A-b1-B-b2-C
340  |
341  b4
342  |
343  E
344  For example in teh above situation on the pairs (b1, b3) and (b1, b4) will be
345  returned
346  All other permutations can be achieved via a rotatable bond flip.
347 
348  ARGUMENTS:
349  \param center - location of the central atom
350  \param nbrBids - a vector (of length 4) containing the ids of the bonds to
351  the neighbors
352  \param nbrLocs - locations of the neighbors
353 */
355  const RDGeom::Point2D &center, const RDKit::INT_VECT &nbrBids,
356  const VECT_C_POINT &nbrLocs);
357 
358 //! returns the rank of the atom for determining draw order
359 inline int getAtomDepictRank(const RDKit::Atom *at) {
360  const int maxAtNum = 1000;
361  const int maxDeg = 100;
362  int anum = at->getAtomicNum();
363  anum = anum == 1 ? maxAtNum : anum; // favor non-hydrogen atoms
364  int deg = at->getDegree();
365  return maxDeg * anum + deg;
366 }
367 } // namespace RDDepict
368 
369 #endif
RDKIT_DEPICTOR_EXPORT
#define RDKIT_DEPICTOR_EXPORT
Definition: export.h:125
RDDepict::rankAtomsByRank
RDKIT_DEPICTOR_EXPORT T rankAtomsByRank(const RDKit::ROMol &mol, const T &commAtms, bool ascending=true)
Sort a list of atoms by their CIP rank.
RDDepict::PR_QUEUE
std::priority_queue< PAIR_I_I, VECT_PII, gtIIPair > PR_QUEUE
Definition: DepictUtils.h:42
RDKit::VECT_INT_VECT
std::vector< INT_VECT > VECT_INT_VECT
Definition: types.h:268
RDDepict::setNbrOrder
RDKIT_DEPICTOR_EXPORT RDKit::INT_VECT setNbrOrder(unsigned int aid, const RDKit::INT_VECT &nbrs, const RDKit::ROMol &mol)
Set the neighbors yet to added to aid such that the atoms with the most subs.
point.h
RDDepict::INT_PAIR_VECT_CI
INT_PAIR_VECT::const_iterator INT_PAIR_VECT_CI
Definition: DepictUtils.h:164
RDDepict::MAX_COLL_ITERS
RDKIT_DEPICTOR_EXPORT unsigned int MAX_COLL_ITERS
ROMol.h
Defines the primary molecule class ROMol as well as associated typedefs.
RDKit::INT_VECT
std::vector< int > INT_VECT
Definition: types.h:254
types.h
RDDepict::LIST_PAIR_DII
std::list< PAIR_D_I_I > LIST_PAIR_DII
Definition: DepictUtils.h:45
RDDepict::INT_PAIR
std::pair< int, int > INT_PAIR
Definition: DepictUtils.h:162
RDKit::Atom::HybridizationType
HybridizationType
store hybridization
Definition: Atom.h:79
RDDepict::getAllRotatableBonds
RDKIT_DEPICTOR_EXPORT RDKit::INT_VECT getAllRotatableBonds(const RDKit::ROMol &mol)
find all the rotatable bonds in a molecule we will ignore ring atoms, and double bonds which are mark...
RDGeom::Point2D::y
double y
Definition: point.h:260
RDGeom::Transform2D
Definition: Transform2D.h:21
RDDepict::transformPoints
RDKIT_DEPICTOR_EXPORT void transformPoints(RDGeom::INT_POINT2D_MAP &nringCor, const RDGeom::Transform2D &trans)
RDDepict::computeBisectPoint
RDKIT_DEPICTOR_EXPORT RDGeom::Point2D computeBisectPoint(const RDGeom::Point2D &rcr, double ang, const RDGeom::Point2D &nb1, const RDGeom::Point2D &nb2)
Find a point that bisects the angle at rcr.
RDKit::Atom::getAtomicNum
int getAtomicNum() const
returns our atomic number
Definition: Atom.h:116
RDKit::Atom::SP3
@ SP3
Definition: Atom.h:84
Transform2D.h
RDGeom::Point2D::angleTo
double angleTo(const Point2D &other) const
Definition: point.h:357
RDDepict::gtIIPair::operator()
bool operator()(const PAIR_I_I &pd1, const PAIR_I_I &pd2) const
Definition: DepictUtils.h:37
RDDepict::rotationDir
int rotationDir(const RDGeom::Point2D &center, const RDGeom::Point2D &loc1, const RDGeom::Point2D &loc2, double remAngle)
computes the rotation direction between two vectors
Definition: DepictUtils.h:235
RDDepict::computeAngle
double computeAngle(const RDGeom::Point2D &center, const RDGeom::Point2D &loc1, const RDGeom::Point2D &loc2)
computes the rotation angle between two vectors
Definition: DepictUtils.h:275
RDKit::Atom
The class for representing atoms.
Definition: Atom.h:69
RDGeom::Point2D::normalize
void normalize()
Definition: point.h:329
RDDepict::findNextRingToEmbed
RDKIT_DEPICTOR_EXPORT RDKit::INT_VECT findNextRingToEmbed(const RDKit::INT_VECT &doneRings, const RDKit::VECT_INT_VECT &fusedRings, int &nextId)
From a given set of rings find the ring the largest common elements.
RDDepict::computeSubAngle
double computeSubAngle(unsigned int degree, RDKit::Atom::HybridizationType htype)
computes a subangle for an atom of given hybridization and degree
Definition: DepictUtils.h:186
M_PI
#define M_PI
Definition: MMFF/Params.h:27
RDKit::ROMol
Definition: ROMol.h:171
RDDepict::NUM_BONDS_FLIPS
RDKIT_DEPICTOR_EXPORT unsigned int NUM_BONDS_FLIPS
RDKit::Atom::getDegree
unsigned int getDegree() const
RDKitBase.h
pulls in the core RDKit functionality
RDDepict::embedRing
RDKIT_DEPICTOR_EXPORT RDGeom::INT_POINT2D_MAP embedRing(const RDKit::INT_VECT &ring)
Some utility functions used in generating 2D coordinates.
RDDepict::getNbrAtomAndBondIds
RDKIT_DEPICTOR_EXPORT void getNbrAtomAndBondIds(unsigned int aid, const RDKit::ROMol *mol, RDKit::INT_VECT &aids, RDKit::INT_VECT &bids)
Get the ids of the atoms and bonds that are connected to aid.
RDKit::Atom::SP2
@ SP2
Definition: Atom.h:83
RDDepict::getAtomDepictRank
int getAtomDepictRank(const RDKit::Atom *at)
returns the rank of the atom for determining draw order
Definition: DepictUtils.h:359
RDDepict::VECT_C_POINT
std::vector< const RDGeom::Point2D * > VECT_C_POINT
Definition: DepictUtils.h:32
RDDepict::PAIR_D_I_I
std::pair< double, PAIR_I_I > PAIR_D_I_I
Definition: DepictUtils.h:44
RDDepict::VECT_PII
std::vector< PAIR_I_I > VECT_PII
Definition: DepictUtils.h:35
RDDepict::BOND_THRES
RDKIT_DEPICTOR_EXPORT double BOND_THRES
RDDepict::computeNormal
RDGeom::Point2D computeNormal(const RDGeom::Point2D &center, const RDGeom::Point2D &other)
computes and return the normal of a vector between two points
Definition: DepictUtils.h:257
RDDepict::COLLISION_THRES
RDKIT_DEPICTOR_EXPORT double COLLISION_THRES
RDGeom::INT_POINT2D_MAP
std::map< int, Point2D > INT_POINT2D_MAP
Definition: point.h:518
RDDepict::findBondsPairsToPermuteDeg4
RDKIT_DEPICTOR_EXPORT INT_PAIR_VECT findBondsPairsToPermuteDeg4(const RDGeom::Point2D &center, const RDKit::INT_VECT &nbrBids, const VECT_C_POINT &nbrLocs)
Find pairs of bonds that can be permuted at a non-ring degree 4 atom.
RDDepict::reflectPoints
RDKIT_DEPICTOR_EXPORT void reflectPoints(RDGeom::INT_POINT2D_MAP &coordMap, const RDGeom::Point2D &loc1, const RDGeom::Point2D &loc2)
Reflect a set of point through a the line joining two point.
RDDepict::gtIIPair
Definition: DepictUtils.h:36
RDDepict::getRotatableBonds
RDKIT_DEPICTOR_EXPORT RDKit::INT_VECT getRotatableBonds(const RDKit::ROMol &mol, unsigned int aid1, unsigned int aid2)
find the rotatable bonds on the shortest path between two atoms we will ignore ring atoms,...
RDDepict::reflectPoint
RDKIT_DEPICTOR_EXPORT RDGeom::Point2D reflectPoint(const RDGeom::Point2D &point, const RDGeom::Point2D &loc1, const RDGeom::Point2D &loc2)
RDGeom::Point2D
Definition: point.h:258
RDDepict::BOND_LEN
RDKIT_DEPICTOR_EXPORT double BOND_LEN
RWMol.h
Defines the editable molecule class RWMol.
RDDepict::ANGLE_OPEN
RDKIT_DEPICTOR_EXPORT double ANGLE_OPEN
RDDepict::PAIR_I_I
std::pair< int, int > PAIR_I_I
Definition: DepictUtils.h:34
RDDepict::INT_PAIR_VECT
std::vector< INT_PAIR > INT_PAIR_VECT
Definition: DepictUtils.h:163
RDDepict
Definition: Reaction.h:444
RDDepict::HETEROATOM_COLL_SCALE
RDKIT_DEPICTOR_EXPORT double HETEROATOM_COLL_SCALE
RDDepict::pickFirstRingToEmbed
RDKIT_DEPICTOR_EXPORT int pickFirstRingToEmbed(const RDKit::ROMol &mol, const RDKit::VECT_INT_VECT &fusedRings)
pick the ring to embed first in a fused system
RDKit::Atom::UNSPECIFIED
@ UNSPECIFIED
hybridization that hasn't been specified
Definition: Atom.h:80
RDGeom::Point2D::x
double x
Definition: point.h:260
RDDepict::DOUBLE_INT_PAIR
std::pair< double, INT_PAIR > DOUBLE_INT_PAIR
Definition: DepictUtils.h:166
export.h