RDKit
Open-source cheminformatics and machine learning.
Bond.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2021 Greg Landrum 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 #include <RDGeneral/export.h>
11 #ifndef RD_BOND_H
12 #define RD_BOND_H
13 
14 // std stuff
15 #include <iostream>
16 #include <utility>
17 
18 // Ours
19 #include <RDGeneral/Invariant.h>
20 #include <Query/QueryObjects.h>
21 #include <RDGeneral/types.h>
22 #include <RDGeneral/RDProps.h>
23 #include <GraphMol/details.h>
24 
25 namespace RDKit {
26 class ROMol;
27 class RWMol;
28 class Atom;
29 
30 //! class for representing a bond
31 /*!
32 
33  <b>Notes:</b>
34  - many of the methods of Atom require that the Atom be associated
35  with a molecule (an ROMol).
36  - each Bond maintains a Dict of \c properties:
37  - Each \c property is keyed by name and can store an
38  arbitrary type.
39  - \c Properties can be marked as \c calculated, in which case
40  they will be cleared when the \c clearComputedProps() method
41  is called.
42  - Because they have no impact upon chemistry, all \c property
43  operations are \c const, this allows extra flexibility for
44  clients who need to store extra data on Bond objects.
45 
46 */
48  friend class RWMol;
49  friend class ROMol;
50 
51  public:
52  // FIX: grn...
54 
55  //! the type of Bond
56  typedef enum {
57  UNSPECIFIED = 0,
73  DATIVEONE, //!< one-electron dative (e.g. from a C in a Cp ring to a metal)
74  DATIVE, //!< standard two-electron dative
75  DATIVEL, //!< standard two-electron dative
76  DATIVER, //!< standard two-electron dative
78  ZERO //!< Zero-order bond (from
79  // http://pubs.acs.org/doi/abs/10.1021/ci200488k)
80  } BondType;
81 
82  //! the bond's direction (for chirality)
83  typedef enum {
84  NONE = 0, //!< no special style
85  BEGINWEDGE, //!< wedged: narrow at begin
86  BEGINDASH, //!< dashed: narrow at begin
87  // FIX: this may not really be adequate
88  ENDDOWNRIGHT, //!< for cis/trans
89  ENDUPRIGHT, //!< ditto
90  EITHERDOUBLE, //!< a "crossed" double bond
91  UNKNOWN, //!< intentionally unspecified stereochemistry
92  } BondDir;
93 
94  //! the nature of the bond's stereochem (for cis/trans)
95  typedef enum { // stereochemistry of double bonds
96  STEREONONE = 0, // no special style
97  STEREOANY, // intentionally unspecified
98  // -- Put any true specifications about this point so
99  // that we can do comparisons like if(bond->getStereo()>Bond::STEREOANY)
100  STEREOZ, // Z double bond
101  STEREOE, // E double bond
102  STEREOCIS, // cis double bond
103  STEREOTRANS // trans double bond
104  } BondStereo;
105 
106  Bond();
107  //! construct with a particular BondType
108  explicit Bond(BondType bT);
109  Bond(const Bond &other);
110  virtual ~Bond();
111  Bond &operator=(const Bond &other);
112 
113  Bond(Bond &&o) noexcept : RDProps(std::move(o)) {
114  df_isAromatic = o.df_isAromatic;
115  df_isConjugated = o.df_isConjugated;
116  d_bondType = o.d_bondType;
117  d_dirTag = o.d_dirTag;
118  d_stereo = o.d_stereo;
119  d_index = o.d_index;
120  d_beginAtomIdx = o.d_beginAtomIdx;
121  d_endAtomIdx = o.d_endAtomIdx;
122  // NOTE: this is somewhat fraught for bonds associated with molecules since
123  // the molecule will still be pointing to the original object
124  dp_mol = std::exchange(o.dp_mol, nullptr);
125  dp_stereoAtoms = std::exchange(o.dp_stereoAtoms, nullptr);
126  }
127  Bond &operator=(Bond &&o) noexcept {
128  if (this == &o) {
129  return *this;
130  }
131  RDProps::operator=(std::move(o));
132  df_isAromatic = o.df_isAromatic;
133  df_isConjugated = o.df_isConjugated;
134  d_bondType = o.d_bondType;
135  d_dirTag = o.d_dirTag;
136  d_stereo = o.d_stereo;
137  d_index = o.d_index;
138  d_beginAtomIdx = o.d_beginAtomIdx;
139  d_endAtomIdx = o.d_endAtomIdx;
140  // NOTE: this is somewhat fraught for bonds associated with molecules since
141  // the molecule will still be pointing to the original object
142  delete dp_stereoAtoms;
143  dp_mol = std::exchange(o.dp_mol, nullptr);
144  dp_stereoAtoms = std::exchange(o.dp_stereoAtoms, nullptr);
145  return *this;
146  }
147 
148  //! returns a copy
149  /*!
150  <b>Note:</b> the caller is responsible for <tt>delete</tt>ing
151  the returned pointer.
152  */
153  virtual Bond *copy() const;
154 
155  //! returns our \c bondType
156  BondType getBondType() const { return static_cast<BondType>(d_bondType); }
157  //! sets our \c bondType
158  void setBondType(BondType bT) { d_bondType = bT; }
159  //! \brief returns our \c bondType as a double
160  //! (e.g. SINGLE->1.0, AROMATIC->1.5, etc.)
161  double getBondTypeAsDouble() const;
162 
163  //! returns our contribution to the explicit valence of an Atom
164  /*!
165  <b>Notes:</b>
166  - requires an owning molecule
167  */
168  virtual double getValenceContrib(const Atom *at) const;
169 
170  //! sets our \c isAromatic flag
171  void setIsAromatic(bool what) { df_isAromatic = what; }
172  //! returns the status of our \c isAromatic flag
173  bool getIsAromatic() const { return df_isAromatic; }
174 
175  //! sets our \c isConjugated flag
176  void setIsConjugated(bool what) { df_isConjugated = what; }
177  //! returns the status of our \c isConjugated flag
178  bool getIsConjugated() const { return df_isConjugated; }
179 
180  //! returns whether or not this instance belongs to a molecule
181  bool hasOwningMol() const { return dp_mol != nullptr; }
182 
183  //! returns a reference to the ROMol that owns this instance
184  ROMol &getOwningMol() const {
185  PRECONDITION(dp_mol, "no owner");
186  return *dp_mol;
187  }
188  //! sets our owning molecule
189  void setOwningMol(ROMol *other);
190  //! sets our owning molecule
191  void setOwningMol(ROMol &other) { setOwningMol(&other); }
192 
193  //! returns our index within the ROMol
194  /*!
195  <b>Notes:</b>
196  - this makes no sense if we do not have an owning molecule
197 
198  */
199  unsigned int getIdx() const { return d_index; }
200  //! sets our index within the ROMol
201  /*!
202  <b>Notes:</b>
203  - this makes no sense if we do not have an owning molecule
204  - the index should be <tt>< this->getOwningMol()->getNumBonds()</tt>
205  */
206  void setIdx(unsigned int index) { d_index = index; }
207 
208  //! returns the index of our begin Atom
209  /*!
210  <b>Notes:</b>
211  - this makes no sense if we do not have an owning molecule
212  */
213  unsigned int getBeginAtomIdx() const { return d_beginAtomIdx; }
214 
215  //! returns the index of our end Atom
216  /*!
217  <b>Notes:</b>
218  - this makes no sense if we do not have an owning molecule
219  */
220  unsigned int getEndAtomIdx() const { return d_endAtomIdx; }
221 
222  //! given the index of one Atom, returns the index of the other
223  /*!
224  <b>Notes:</b>
225  - this makes no sense if we do not have an owning molecule
226  */
227  unsigned int getOtherAtomIdx(unsigned int thisIdx) const;
228 
229  //! sets the index of our begin Atom
230  /*!
231  <b>Notes:</b>
232  - requires an owning molecule
233  */
234  void setBeginAtomIdx(unsigned int what);
235  //! sets the index of our end Atom
236  /*!
237  <b>Notes:</b>
238  - requires an owning molecule
239  */
240  void setEndAtomIdx(unsigned int what);
241 
242  //! sets our begin Atom
243  /*!
244  <b>Notes:</b>
245  - requires an owning molecule
246  */
247  void setBeginAtom(Atom *at);
248  //! sets our end Atom
249  /*!
250  <b>Notes:</b>
251  - requires an owning molecule
252  */
253  void setEndAtom(Atom *at);
254 
255  //! returns a pointer to our begin Atom
256  /*!
257  <b>Notes:</b>
258  - requires an owning molecule
259  */
260  Atom *getBeginAtom() const;
261  //! returns a pointer to our end Atom
262  /*!
263  <b>Notes:</b>
264  - requires an owning molecule
265  */
266  Atom *getEndAtom() const;
267  //! returns a pointer to the other Atom
268  /*!
269  <b>Notes:</b>
270  - requires an owning molecule
271  */
272  Atom *getOtherAtom(Atom const *what) const;
273 
274  // ------------------------------------
275  // Please see the note in Atom.h for some explanation
276  // of these methods
277  // ------------------------------------
278 
279  // This method can be used to distinguish query bonds from standard bonds
280  virtual bool hasQuery() const { return false; }
281 
282  // FIX: the const crap here is all mucked up.
283  //! NOT CALLABLE
284  virtual void setQuery(QUERYBOND_QUERY *what);
285  //! NOT CALLABLE
286  virtual QUERYBOND_QUERY *getQuery() const;
287 
288  //! NOT CALLABLE
289  virtual void expandQuery(
290  QUERYBOND_QUERY *what,
292  bool maintainOrder = true);
293 
294  //! returns whether or not we match the argument
295  /*!
296  <b>Notes:</b>
297  - for Bond objects, "match" means that either one of the Bonds
298  has \c bondType Bond::UNSPECIFIED or both Bonds have the
299  same \c bondType.
300  */
301  virtual bool Match(Bond const *what) const;
302 
303  //! sets our direction
304  void setBondDir(BondDir what) { d_dirTag = what; }
305  //! returns our direction
306  BondDir getBondDir() const { return static_cast<BondDir>(d_dirTag); }
307 
308  //! sets our stereo code
309  /*!
310  STEREONONE, STEREOANY, STEREOE and STEREOZ can be set without
311  neighboring atoms specified in getStereoAtoms since they are
312  defined by the topology of the molecular graph. In order to set
313  STEREOCIS or STEREOTRANS the neighboring atoms must be set first
314  (using setStereoBonds()) to know what atoms are being considered.
315 
316  <b>Notes:</b>
317  - MolOps::findPotentialStereoBonds can be used to set
318  getStereoAtoms before setting CIS/TRANS
319  */
320  void setStereo(BondStereo what) {
321  PRECONDITION(what <= STEREOE || getStereoAtoms().size() == 2,
322  "Stereo atoms should be specified before specifying CIS/TRANS "
323  "bond stereochemistry")
324  d_stereo = what;
325  }
326  //! returns our stereo code
327  BondStereo getStereo() const { return static_cast<BondStereo>(d_stereo); }
328 
329  //! sets the atoms to be considered as reference points for bond stereo
330  /*!
331  These do not necessarily need to be the highest 'ranking' atoms
332  like CIP stereo requires. They can be any arbitrary atoms
333  neighboring the begin and end atoms of this bond
334  respectively. STEREOCIS or STEREOTRANS is then set relative to
335  only these atoms.
336 
337  If CIP rankings are desired, use
338  MolOps::findPotentialStereoBonds, but this is a more costly
339  function as it takes the whole molecule topology into account.
340  */
341  void setStereoAtoms(unsigned int bgnIdx, unsigned int endIdx);
342 
343  //! returns the indices of our stereo atoms
344  const INT_VECT &getStereoAtoms() const {
345  if (!dp_stereoAtoms) {
346  const_cast<Bond *>(this)->dp_stereoAtoms = new INT_VECT();
347  }
348  return *dp_stereoAtoms;
349  }
350  //! \overload
352  if (!dp_stereoAtoms) {
353  dp_stereoAtoms = new INT_VECT();
354  }
355  return *dp_stereoAtoms;
356  }
357 
358  //! calculates any of our lazy \c properties
359  /*!
360  <b>Notes:</b>
361  - requires an owning molecule
362  */
363  void updatePropertyCache(bool strict = true) { (void)strict; }
364 
365  protected:
366  //! sets our owning molecule
367  /// void setOwningMol(ROMol *other);
368  //! sets our owning molecule
369  /// void setOwningMol(ROMol &other) { setOwningMol(&other); }
372  std::uint8_t d_bondType;
373  std::uint8_t d_dirTag;
374  std::uint8_t d_stereo;
379 
380  void initBond();
381 };
382 
383 //! returns twice the \c bondType
384 //! (e.g. SINGLE->2, AROMATIC->3, etc.)
386 
387 }; // namespace RDKit
388 
389 //! allows Bond objects to be dumped to streams
390 RDKIT_GRAPHMOL_EXPORT extern std::ostream &operator<<(std::ostream &target,
391  const RDKit::Bond &b);
392 
393 #endif
RDKIT_GRAPHMOL_EXPORT std::ostream & operator<<(std::ostream &target, const RDKit::Bond &b)
allows Bond objects to be dumped to streams
#define PRECONDITION(expr, mess)
Definition: Invariant.h:109
Pulls in all the query types.
Base class for all queries.
Definition: Query.h:45
The class for representing atoms.
Definition: Atom.h:68
class for representing a bond
Definition: Bond.h:47
unsigned int getBeginAtomIdx() const
returns the index of our begin Atom
Definition: Bond.h:213
atomindex_t d_index
Definition: Bond.h:375
void updatePropertyCache(bool strict=true)
calculates any of our lazy properties
Definition: Bond.h:363
double getBondTypeAsDouble() const
returns our bondType as a double (e.g. SINGLE->1.0, AROMATIC->1.5, etc.)
void setEndAtomIdx(unsigned int what)
sets the index of our end Atom
unsigned int getOtherAtomIdx(unsigned int thisIdx) const
given the index of one Atom, returns the index of the other
INT_VECT * dp_stereoAtoms
Definition: Bond.h:378
virtual ~Bond()
BondType
the type of Bond
Definition: Bond.h:56
@ DATIVER
standard two-electron dative
Definition: Bond.h:76
@ QUINTUPLE
Definition: Bond.h:62
@ TWOANDAHALF
Definition: Bond.h:65
@ HYDROGEN
Definition: Bond.h:71
@ THREECENTER
Definition: Bond.h:72
@ FIVEANDAHALF
Definition: Bond.h:68
@ QUADRUPLE
Definition: Bond.h:61
@ FOURANDAHALF
Definition: Bond.h:67
@ AROMATIC
Definition: Bond.h:69
@ THREEANDAHALF
Definition: Bond.h:66
@ IONIC
Definition: Bond.h:70
@ DOUBLE
Definition: Bond.h:59
@ HEXTUPLE
Definition: Bond.h:63
@ TRIPLE
Definition: Bond.h:60
@ ONEANDAHALF
Definition: Bond.h:64
@ DATIVE
standard two-electron dative
Definition: Bond.h:74
@ SINGLE
Definition: Bond.h:58
@ OTHER
Definition: Bond.h:77
@ DATIVEONE
one-electron dative (e.g. from a C in a Cp ring to a metal)
Definition: Bond.h:73
@ DATIVEL
standard two-electron dative
Definition: Bond.h:75
Bond & operator=(const Bond &other)
Bond(const Bond &other)
ROMol & getOwningMol() const
returns a reference to the ROMol that owns this instance
Definition: Bond.h:184
void initBond()
void setIsAromatic(bool what)
sets our isAromatic flag
Definition: Bond.h:171
Atom * getOtherAtom(Atom const *what) const
returns a pointer to the other Atom
const INT_VECT & getStereoAtoms() const
returns the indices of our stereo atoms
Definition: Bond.h:344
unsigned int getIdx() const
returns our index within the ROMol
Definition: Bond.h:199
void setBeginAtom(Atom *at)
sets our begin Atom
bool getIsConjugated() const
returns the status of our isConjugated flag
Definition: Bond.h:178
Bond & operator=(Bond &&o) noexcept
Definition: Bond.h:127
bool hasOwningMol() const
returns whether or not this instance belongs to a molecule
Definition: Bond.h:181
virtual bool hasQuery() const
Definition: Bond.h:280
void setStereoAtoms(unsigned int bgnIdx, unsigned int endIdx)
sets the atoms to be considered as reference points for bond stereo
void setBeginAtomIdx(unsigned int what)
sets the index of our begin Atom
void setIsConjugated(bool what)
sets our isConjugated flag
Definition: Bond.h:176
Queries::Query< int, Bond const *, true > QUERYBOND_QUERY
Definition: Bond.h:53
BondType getBondType() const
returns our bondType
Definition: Bond.h:156
virtual void setQuery(QUERYBOND_QUERY *what)
NOT CALLABLE.
void setOwningMol(ROMol *other)
sets our owning molecule
INT_VECT & getStereoAtoms()
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: Bond.h:351
void setBondType(BondType bT)
sets our bondType
Definition: Bond.h:158
bool df_isAromatic
Definition: Bond.h:370
atomindex_t d_beginAtomIdx
Definition: Bond.h:376
BondDir
the bond's direction (for chirality)
Definition: Bond.h:83
@ EITHERDOUBLE
a "crossed" double bond
Definition: Bond.h:90
@ BEGINWEDGE
wedged: narrow at begin
Definition: Bond.h:85
@ ENDUPRIGHT
ditto
Definition: Bond.h:89
@ UNKNOWN
intentionally unspecified stereochemistry
Definition: Bond.h:91
@ ENDDOWNRIGHT
for cis/trans
Definition: Bond.h:88
@ BEGINDASH
dashed: narrow at begin
Definition: Bond.h:86
virtual Bond * copy() const
returns a copy
Bond(Bond &&o) noexcept
Definition: Bond.h:113
virtual void expandQuery(QUERYBOND_QUERY *what, Queries::CompositeQueryType how=Queries::COMPOSITE_AND, bool maintainOrder=true)
NOT CALLABLE.
void setOwningMol(ROMol &other)
sets our owning molecule
Definition: Bond.h:191
Atom * getEndAtom() const
returns a pointer to our end Atom
std::uint8_t d_stereo
Definition: Bond.h:374
BondStereo getStereo() const
returns our stereo code
Definition: Bond.h:327
void setStereo(BondStereo what)
sets our stereo code
Definition: Bond.h:320
void setIdx(unsigned int index)
sets our index within the ROMol
Definition: Bond.h:206
unsigned int getEndAtomIdx() const
returns the index of our end Atom
Definition: Bond.h:220
std::uint8_t d_dirTag
Definition: Bond.h:373
std::uint8_t d_bondType
Definition: Bond.h:372
virtual double getValenceContrib(const Atom *at) const
returns our contribution to the explicit valence of an Atom
void setEndAtom(Atom *at)
sets our end Atom
virtual QUERYBOND_QUERY * getQuery() const
NOT CALLABLE.
ROMol * dp_mol
Definition: Bond.h:377
void setBondDir(BondDir what)
sets our direction
Definition: Bond.h:304
BondStereo
the nature of the bond's stereochem (for cis/trans)
Definition: Bond.h:95
@ STEREOE
Definition: Bond.h:101
@ STEREOZ
Definition: Bond.h:100
@ STEREOCIS
Definition: Bond.h:102
@ STEREOANY
Definition: Bond.h:97
bool getIsAromatic() const
returns the status of our isAromatic flag
Definition: Bond.h:173
Atom * getBeginAtom() const
returns a pointer to our begin Atom
virtual bool Match(Bond const *what) const
returns whether or not we match the argument
BondDir getBondDir() const
returns our direction
Definition: Bond.h:306
Bond(BondType bT)
construct with a particular BondType
bool df_isConjugated
Definition: Bond.h:371
RDProps & operator=(const RDProps &rhs)
Definition: RDProps.h:24
RWMol is a molecule class that is intended to be edited.
Definition: RWMol.h:32
#define RDKIT_GRAPHMOL_EXPORT
Definition: export.h:225
CompositeQueryType
Definition: QueryObjects.h:36
@ COMPOSITE_AND
Definition: QueryObjects.h:36
Std stuff.
Definition: Abbreviations.h:19
std::vector< int > INT_VECT
Definition: types.h:278
std::uint32_t atomindex_t
Definition: details.h:14
RDKIT_GRAPHMOL_EXPORT uint8_t getTwiceBondType(const RDKit::Bond &b)