RDKit
Open-source cheminformatics and machine learning.
Loading...
Searching...
No Matches
Atom.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/*! \file Atom.h
11
12 \brief Defines the Atom class and associated typedefs
13
14*/
15#include <RDGeneral/export.h>
16#ifndef _RD_ATOM_H
17#define _RD_ATOM_H
18
19// Std stuff
20#include <iostream>
21
22// ours
23#include <RDGeneral/Invariant.h>
24#include <Query/QueryObjects.h>
25#include <RDGeneral/types.h>
26#include <RDGeneral/RDProps.h>
27#include <GraphMol/details.h>
28
29namespace RDKit {
30class Atom;
31}
32//! allows Atom objects to be dumped to streams
33RDKIT_GRAPHMOL_EXPORT std::ostream &operator<<(std::ostream &target,
34 const RDKit::Atom &at);
35
36namespace RDKit {
37class ROMol;
38class RWMol;
39class AtomMonomerInfo;
40
41//! The class for representing atoms
42/*!
43
44 <b>Notes:</b>
45 - many of the methods of Atom require that the Atom be associated
46 with a molecule (an ROMol).
47 - each Atom maintains a Dict of \c properties:
48 - Each \c property is keyed by name and can store an
49 arbitrary type.
50 - \c Properties can be marked as \c calculated, in which case
51 they will be cleared when the \c clearComputedProps() method
52 is called.
53 - Because they have no impact upon chemistry, all \c property
54 operations are \c const, this allows extra flexibility for
55 clients who need to store extra data on Atom objects.
56 - Atom objects are lazy about computing their explicit and implicit valence
57 values. These will not be computed until their values are requested.
58
59 <b>Chirality:</b>
60
61 The chirality of an Atom is determined by two things:
62 - its \c chiralTag
63 - the input order of its bonds (see note below for handling of
64 implicit Hs)
65
66 For tetrahedral coordination, the \c chiralTag tells you what
67 direction you have to rotate to get from bond 2 to bond 3 while looking
68 down bond 1. This is pretty much identical to the SMILES representation of
69 chirality.
70
71 NOTE: if an atom has an implicit H, the bond to that H is considered to be
72 at the *end* of the list of other bonds.
73
74*/
76 friend class MolPickler; //!< the pickler needs access to our privates
77 friend class ROMol;
78 friend class RWMol;
79 friend std::ostream &(::operator<<)(std::ostream &target, const Atom &at);
80
81 public:
82 // FIX: grn...
84
85 //! store hybridization
86 typedef enum {
87 UNSPECIFIED = 0, //!< hybridization that hasn't been specified
95 OTHER //!< unrecognized hybridization
96 } HybridizationType;
97
98 //! store type of chirality
99 typedef enum {
100 CHI_UNSPECIFIED = 0, //!< chirality that hasn't been specified
101 CHI_TETRAHEDRAL_CW, //!< tetrahedral: clockwise rotation (SMILES \@\@)
102 CHI_TETRAHEDRAL_CCW, //!< tetrahedral: counter-clockwise rotation (SMILES
103 //\@)
104 CHI_OTHER, //!< some unrecognized type of chirality
105 CHI_TETRAHEDRAL, //!< tetrahedral, use permutation flag
106 CHI_ALLENE, //!< allene, use permutation flag
107 CHI_SQUAREPLANAR, //!< square planar, use permutation flag
108 CHI_TRIGONALBIPYRAMIDAL, //!< trigonal bipyramidal, use permutation flag
109 CHI_OCTAHEDRAL //!< octahedral, use permutation flag
110 } ChiralType;
111
113 //! construct an Atom with a particular atomic number
114 explicit Atom(unsigned int num);
115 //! construct an Atom with a particular symbol (looked up in the
116 /// PeriodicTable)
117 explicit Atom(const std::string &what);
118 Atom(const Atom &other);
119 Atom &operator=(const Atom &other);
120 // NOTE: the move methods are somewhat fraught for atoms associated with
121 // molecules since the molecule will still be pointing to the original object
122 Atom(Atom &&other) = default;
123 Atom &operator=(Atom &&other) = default;
124
125 virtual ~Atom();
126
127 //! makes a copy of this Atom and returns a pointer to it.
128 /*!
129 <b>Note:</b> the caller is responsible for <tt>delete</tt>ing the result
130 */
131 virtual Atom *copy() const;
132
133 //! returns our atomic number
134 int getAtomicNum() const { return d_atomicNum; }
135 //! sets our atomic number
136 void setAtomicNum(int newNum) { d_atomicNum = newNum; }
137
138 //! returns our symbol (determined by our atomic number)
139 std::string getSymbol() const;
140
141 //! returns whether or not this instance belongs to a molecule
142 bool hasOwningMol() const { return dp_mol != nullptr; }
143
144 //! returns a reference to the ROMol that owns this instance
146 PRECONDITION(dp_mol, "no owner");
147 return *dp_mol;
148 }
149
150 //! returns our index within the ROMol
151 unsigned int getIdx() const { return d_index; }
152 //! sets our index within the ROMol
153 /*!
154 <b>Notes:</b>
155 - this makes no sense if we do not have an owning molecule
156 - the index should be <tt>< this->getOwningMol()->getNumAtoms()</tt>
157 */
158 void setIdx(unsigned int index) { d_index = index; }
159 //! overload
160 template <class U>
161 void setIdx(const U index) {
162 setIdx(rdcast<unsigned int>(index));
163 }
164 //! returns the explicit degree of the Atom (number of bonded
165 //! neighbors in the graph)
166 /*!
167 <b>Notes:</b>
168 - requires an owning molecule
169 */
170 unsigned int getDegree() const;
171
172 //! returns the total degree of the Atom (number of bonded
173 //! neighbors + number of Hs)
174 /*!
175 <b>Notes:</b>
176 - requires an owning molecule
177 */
178 unsigned int getTotalDegree() const;
179
180 //! \brief returns the total number of Hs (implicit and explicit) that
181 //! this Atom is bound to
182 /*!
183 <b>Notes:</b>
184 - requires an owning molecule
185 */
186 unsigned int getTotalNumHs(bool includeNeighbors = false) const;
187
188 //! \brief returns the total valence (implicit and explicit)
189 //! for an atom
190 /*!
191 <b>Notes:</b>
192 - requires an owning molecule
193 */
194 unsigned int getTotalValence() const;
195
196 //! returns the number of implicit Hs this Atom is bound to
197 /*!
198 <b>Notes:</b>
199 - requires an owning molecule
200 */
201 unsigned int getNumImplicitHs() const;
202
203 //! returns the explicit valence (including Hs) of this atom
205
206 //! returns the implicit valence for this Atom
207 /*!
208 <b>Notes:</b>
209 - requires an owning molecule
210 */
212
213 //! returns whether the atom has a valency violation or not
214 /*!
215 <b>Notes:</b>
216 - requires an owning molecule
217 */
219
220 //! returns the number of radical electrons for this Atom
221 /*!
222 <b>Notes:</b>
223 - requires an owning molecule
224 */
225 unsigned int getNumRadicalElectrons() const { return d_numRadicalElectrons; }
226 void setNumRadicalElectrons(unsigned int num) { d_numRadicalElectrons = num; }
227
228 //! returns the formal charge of this atom
229 int getFormalCharge() const { return d_formalCharge; }
230 //! set's the formal charge of this atom
231 void setFormalCharge(int what) { d_formalCharge = what; }
232
233 //! \brief sets our \c noImplicit flag, indicating whether or not
234 //! we are allowed to have implicit Hs
235 void setNoImplicit(bool what) { df_noImplicit = what; }
236 //! returns the \c noImplicit flag
237 bool getNoImplicit() const { return df_noImplicit; }
238
239 //! sets our number of explicit Hs
240 void setNumExplicitHs(unsigned int what) { d_numExplicitHs = what; }
241 //! returns our number of explicit Hs
242 unsigned int getNumExplicitHs() const { return d_numExplicitHs; }
243
244 //! sets our \c isAromatic flag, indicating whether or not we are aromatic
245 void setIsAromatic(bool what) { df_isAromatic = what; }
246 //! returns our \c isAromatic flag
247 bool getIsAromatic() const { return df_isAromatic; }
248
249 //! returns our mass
250 double getMass() const;
251
252 //! sets our isotope number
253 void setIsotope(unsigned int what);
254 //! returns our isotope number
255 unsigned int getIsotope() const { return d_isotope; }
256
257 //! sets our \c chiralTag
258 void setChiralTag(ChiralType what) { d_chiralTag = what; }
259 //! inverts our \c chiralTag, returns whether or not a change was made
261 //! returns our \c chiralTag
263 return static_cast<ChiralType>(d_chiralTag);
264 }
265
266 //! sets our hybridization
267 void setHybridization(HybridizationType what) { d_hybrid = what; }
268 //! returns our hybridization
270 return static_cast<HybridizationType>(d_hybrid);
271 }
272
273 // ------------------------------------
274 // Some words of explanation before getting down into
275 // the query stuff.
276 // These query functions are really only here so that they
277 // can have real functionality in subclasses (like QueryAtoms).
278 // Since pretty much it's gonna be a mistake to call any of these
279 // (ever), we're saddling them all with a precondition which
280 // is guaranteed to fail. I'd like to have them be pure virtual,
281 // but that doesn't work since we need to be able to instantiate
282 // Atoms.
283 // ------------------------------------
284
285 // This method can be used to distinguish query atoms from standard atoms:
286 virtual bool hasQuery() const { return false; }
287
288 virtual std::string getQueryType() const { return ""; }
289
290 //! NOT CALLABLE
291 virtual void setQuery(QUERYATOM_QUERY *what);
292
293 //! NOT CALLABLE
294 virtual QUERYATOM_QUERY *getQuery() const;
295 //! NOT CALLABLE
296 virtual void expandQuery(
297 QUERYATOM_QUERY *what,
299 bool maintainOrder = true);
300
301 //! returns whether or not we match the argument
302 /*!
303 <b>Notes:</b>
304 The general rule is that if a property on this atom has a non-default
305 value,
306 the property on the other atom must have the same value.
307 The exception to this is H counts, which are ignored. These turns out to
308 be
309 impossible to handle generally, so rather than having odd and
310 hard-to-explain
311 exceptions, we ignore them entirely.
312
313 Here are the rules for atom-atom matching:
314 | This | Other | Match | Reason
315 | CCO | CCO | Yes |
316 | CCO | CC[O-] | Yes |
317 | CC[O-] | CCO | No | Charge
318 | CC[O-] | CC[O-] | Yes |
319 | CC[OH] | CC[O-] | Yes |
320 | CC[OH] | CCOC | Yes |
321 | CCO | CCOC | Yes |
322 | CCC | CCC | Yes |
323 | CCC | CC[14C] | Yes |
324 | CC[14C] | CCC | No | Isotope
325 | CC[14C] | CC[14C] | Yes |
326 | C | OCO | Yes |
327 | [CH] | OCO | Yes |
328 | [CH2] | OCO | Yes |
329 | [CH3] | OCO | No | Radical
330 | C | O[CH2]O | Yes |
331 | [CH2] | O[CH2]O | Yes |
332 */
333 virtual bool Match(Atom const *what) const;
334
335 //! returns the perturbation order for a list of integers
336 /*!
337
338 This value is associated with chirality.
339
340 \param probe a list of bond indices. This must be the same
341 length as our number of incoming bonds (our degree).
342
343 \return the number of swaps required to convert the ordering
344 of the probe list to match the order of our incoming bonds:
345 e.g. if our incoming bond order is: <tt>[0,1,2,3]</tt>
346 \verbatim
347 getPerturbationOrder([1,0,2,3]) = 1
348 getPerturbationOrder([1,2,3,0]) = 3
349 getPerturbationOrder([1,2,0,3]) = 2
350 \endverbatim
351
352 See the class documentation for a more detailed description
353 of our representation of chirality.
354
355 <b>Notes:</b>
356 - requires an owning molecule
357
358 */
359 int getPerturbationOrder(const INT_LIST &probe) const;
360
361 //! calculates any of our lazy \c properties
362 /*!
363 <b>Notes:</b>
364 - requires an owning molecule
365 - the current lazy \c properties are implicit and explicit valence
366 */
367 void updatePropertyCache(bool strict = true);
368
370
371 //! calculates and returns our explicit valence
372 /*!
373 <b>Notes:</b>
374 - requires an owning molecule
375 */
376 int calcExplicitValence(bool strict = true);
377
378 //! calculates and returns our implicit valence
379 /*!
380 <b>Notes:</b>
381 - requires an owning molecule
382 */
383 int calcImplicitValence(bool strict = true);
384
385 AtomMonomerInfo *getMonomerInfo() { return dp_monomerInfo; }
386 const AtomMonomerInfo *getMonomerInfo() const { return dp_monomerInfo; }
387 //! takes ownership of the pointer
389
390 //! Set the atom map Number of the atom
391 void setAtomMapNum(int mapno, bool strict = true) {
393 !strict || (mapno >= 0 && mapno < 1000),
394 "atom map number out of range [0..1000], use strict=false to override");
395 if (mapno) {
396 setProp(common_properties::molAtomMapNumber, mapno);
397 } else if (hasProp(common_properties::molAtomMapNumber)) {
398 clearProp(common_properties::molAtomMapNumber);
399 }
400 }
401 //! Gets the atom map Number of the atom, if no atom map exists, 0 is
402 //! returned.
403 int getAtomMapNum() const {
404 int mapno = 0;
405 getPropIfPresent(common_properties::molAtomMapNumber, mapno);
406 return mapno;
407 }
408
409 protected:
410 //! sets our owning molecule
411 void setOwningMol(ROMol *other);
412 //! sets our owning molecule
413 void setOwningMol(ROMol &other) { setOwningMol(&other); }
414
417 std::uint8_t d_numExplicitHs;
418 std::int8_t d_formalCharge;
419 std::uint8_t d_atomicNum;
420 // NOTE that these cannot be signed, they are calculated using
421 // a lazy scheme and are initialized to -1 to indicate that the
422 // calculation has not yet been done.
423 std::int8_t d_implicitValence, d_explicitValence;
425 std::uint8_t d_chiralTag;
426 std::uint8_t d_hybrid;
427
428 std::uint16_t d_isotope;
430
433 void initAtom();
434 void initFromOther(const Atom &other);
435};
436
437//! Set the atom's MDL integer RLabel
438/// Setting to 0 clears the rlabel. Rlabel must be in the range [0..99]
441
442//! Set the atom's MDL atom alias
443/// Setting to an empty string clears the alias
444RDKIT_GRAPHMOL_EXPORT void setAtomAlias(Atom *atom, const std::string &alias);
445RDKIT_GRAPHMOL_EXPORT std::string getAtomAlias(const Atom *atom);
446
447//! Set the atom's MDL atom value
448/// Setting to an empty string clears the value
449/// This is where recursive smarts get stored in MolBlock Queries
450RDKIT_GRAPHMOL_EXPORT void setAtomValue(Atom *atom, const std::string &value);
451RDKIT_GRAPHMOL_EXPORT std::string getAtomValue(const Atom *atom);
452
453//! Sets the supplemental label that will follow the atom when writing
454/// smiles strings.
456 const std::string &label);
458
459//! returns true if the atom is to the left of C
461//! returns true if the atom is aromatic or has an aromatic bond
463//! returns the number of pi electrons on the atom
464RDKIT_GRAPHMOL_EXPORT unsigned int numPiElectrons(const Atom &atom);
465}; // namespace RDKit
466
467//! allows Atom objects to be dumped to streams
468RDKIT_GRAPHMOL_EXPORT std::ostream &operator<<(std::ostream &target,
469 const RDKit::Atom &at);
470#endif
RDKIT_GRAPHMOL_EXPORT std::ostream & operator<<(std::ostream &target, const RDKit::Atom &at)
allows Atom 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 abstract base class for atom-level monomer info.
Definition MonomerInfo.h:26
The class for representing atoms.
Definition Atom.h:75
virtual Atom * copy() const
makes a copy of this Atom and returns a pointer to it.
ChiralType getChiralTag() const
returns our chiralTag
Definition Atom.h:262
AtomMonomerInfo * getMonomerInfo()
Definition Atom.h:385
void setNumExplicitHs(unsigned int what)
sets our number of explicit Hs
Definition Atom.h:240
Atom & operator=(const Atom &other)
void initAtom()
void setHybridization(HybridizationType what)
sets our hybridization
Definition Atom.h:267
ROMol & getOwningMol() const
returns a reference to the ROMol that owns this instance
Definition Atom.h:145
Queries::Query< int, Atom const *, true > QUERYATOM_QUERY
Definition Atom.h:83
bool needsUpdatePropertyCache() const
virtual void expandQuery(QUERYATOM_QUERY *what, Queries::CompositeQueryType how=Queries::COMPOSITE_AND, bool maintainOrder=true)
NOT CALLABLE.
bool invertChirality()
inverts our chiralTag, returns whether or not a change was made
atomindex_t d_index
Definition Atom.h:429
bool getNoImplicit() const
returns the noImplicit flag
Definition Atom.h:237
Atom(unsigned int num)
construct an Atom with a particular atomic number
bool hasValenceViolation() const
returns whether the atom has a valency violation or not
unsigned int getIdx() const
returns our index within the ROMol
Definition Atom.h:151
unsigned int getNumExplicitHs() const
returns our number of explicit Hs
Definition Atom.h:242
unsigned int getNumRadicalElectrons() const
returns the number of radical electrons for this Atom
Definition Atom.h:225
bool df_isAromatic
Definition Atom.h:415
void setNoImplicit(bool what)
sets our noImplicit flag, indicating whether or not we are allowed to have implicit Hs
Definition Atom.h:235
Atom(const Atom &other)
ROMol * dp_mol
Definition Atom.h:431
virtual void setQuery(QUERYATOM_QUERY *what)
NOT CALLABLE.
virtual std::string getQueryType() const
Definition Atom.h:288
int getExplicitValence() const
returns the explicit valence (including Hs) of this atom
HybridizationType
store hybridization
Definition Atom.h:86
@ SP3D2
Definition Atom.h:94
int getImplicitValence() const
returns the implicit valence for this Atom
void updatePropertyCache(bool strict=true)
calculates any of our lazy properties
Atom(Atom &&other)=default
void setIdx(unsigned int index)
sets our index within the ROMol
Definition Atom.h:158
void setAtomicNum(int newNum)
sets our atomic number
Definition Atom.h:136
unsigned int getTotalNumHs(bool includeNeighbors=false) const
returns the total number of Hs (implicit and explicit) that this Atom is bound to
void initFromOther(const Atom &other)
int calcExplicitValence(bool strict=true)
calculates and returns our explicit valence
const AtomMonomerInfo * getMonomerInfo() const
Definition Atom.h:386
void setIsotope(unsigned int what)
sets our isotope number
std::uint16_t d_isotope
Definition Atom.h:428
void setOwningMol(ROMol &other)
sets our owning molecule
Definition Atom.h:413
std::uint8_t d_atomicNum
Definition Atom.h:419
int getAtomicNum() const
returns our atomic number
Definition Atom.h:134
int calcImplicitValence(bool strict=true)
calculates and returns our implicit valence
ChiralType
store type of chirality
Definition Atom.h:99
@ CHI_OTHER
some unrecognized type of chirality
Definition Atom.h:104
@ CHI_TETRAHEDRAL
tetrahedral, use permutation flag
Definition Atom.h:105
@ CHI_ALLENE
allene, use permutation flag
Definition Atom.h:106
@ CHI_TETRAHEDRAL_CW
tetrahedral: clockwise rotation (SMILES @@)
Definition Atom.h:101
@ CHI_TETRAHEDRAL_CCW
tetrahedral: counter-clockwise rotation (SMILES
Definition Atom.h:102
@ CHI_TRIGONALBIPYRAMIDAL
trigonal bipyramidal, use permutation flag
Definition Atom.h:108
@ CHI_SQUAREPLANAR
square planar, use permutation flag
Definition Atom.h:107
unsigned int getNumImplicitHs() const
returns the number of implicit Hs this Atom is bound to
bool df_noImplicit
Definition Atom.h:416
int getPerturbationOrder(const INT_LIST &probe) const
returns the perturbation order for a list of integers
AtomMonomerInfo * dp_monomerInfo
Definition Atom.h:432
int getAtomMapNum() const
Definition Atom.h:403
void setAtomMapNum(int mapno, bool strict=true)
Set the atom map Number of the atom.
Definition Atom.h:391
virtual bool hasQuery() const
Definition Atom.h:286
void setFormalCharge(int what)
set's the formal charge of this atom
Definition Atom.h:231
std::int8_t d_formalCharge
Definition Atom.h:418
std::uint8_t d_hybrid
Definition Atom.h:426
std::string getSymbol() const
returns our symbol (determined by our atomic number)
virtual bool Match(Atom const *what) const
returns whether or not we match the argument
void setChiralTag(ChiralType what)
sets our chiralTag
Definition Atom.h:258
void setMonomerInfo(AtomMonomerInfo *info)
takes ownership of the pointer
HybridizationType getHybridization() const
returns our hybridization
Definition Atom.h:269
bool getIsAromatic() const
returns our isAromatic flag
Definition Atom.h:247
unsigned int getTotalValence() const
returns the total valence (implicit and explicit) for an atom
Atom(const std::string &what)
std::uint8_t d_numRadicalElectrons
Definition Atom.h:424
void setIsAromatic(bool what)
sets our isAromatic flag, indicating whether or not we are aromatic
Definition Atom.h:245
int getFormalCharge() const
returns the formal charge of this atom
Definition Atom.h:229
Atom & operator=(Atom &&other)=default
double getMass() const
returns our mass
unsigned int getIsotope() const
returns our isotope number
Definition Atom.h:255
unsigned int getTotalDegree() const
std::int8_t d_explicitValence
Definition Atom.h:423
void setIdx(const U index)
overload
Definition Atom.h:161
virtual QUERYATOM_QUERY * getQuery() const
NOT CALLABLE.
void setNumRadicalElectrons(unsigned int num)
Definition Atom.h:226
bool hasOwningMol() const
returns whether or not this instance belongs to a molecule
Definition Atom.h:142
void setOwningMol(ROMol *other)
sets our owning molecule
std::uint8_t d_chiralTag
Definition Atom.h:425
std::uint8_t d_numExplicitHs
Definition Atom.h:417
virtual ~Atom()
unsigned int getDegree() const
handles pickling (serializing) molecules
Definition MolPickler.h:68
RWMol is a molecule class that is intended to be edited.
Definition RWMol.h:32
#define RDKIT_GRAPHMOL_EXPORT
Definition export.h:233
@ COMPOSITE_AND
Std stuff.
std::list< int > INT_LIST
Definition types.h:297
RDKIT_GRAPHMOL_EXPORT std::string getAtomValue(const Atom *atom)
bool rdvalue_is(const RDValue_cast_t)
RDKIT_GRAPHMOL_EXPORT std::string getAtomAlias(const Atom *atom)
RDKIT_GRAPHMOL_EXPORT void setAtomRLabel(Atom *atm, int rlabel)
RDKIT_GRAPHMOL_EXPORT bool isAromaticAtom(const Atom &atom)
returns true if the atom is aromatic or has an aromatic bond
RDKIT_GRAPHMOL_EXPORT std::string getSupplementalSmilesLabel(const Atom *atom)
RDKIT_GRAPHMOL_EXPORT void setAtomAlias(Atom *atom, const std::string &alias)
RDKIT_GRAPHMOL_EXPORT int getAtomRLabel(const Atom *atm)
RDKIT_GRAPHMOL_EXPORT void setAtomValue(Atom *atom, const std::string &value)
RDKIT_GRAPHMOL_EXPORT unsigned int numPiElectrons(const Atom &atom)
returns the number of pi electrons on the atom
RDKIT_GRAPHMOL_EXPORT bool isEarlyAtom(int atomicNum)
returns true if the atom is to the left of C
std::uint32_t atomindex_t
Definition details.h:14
RDKIT_GRAPHMOL_EXPORT void setSupplementalSmilesLabel(Atom *atom, const std::string &label)