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