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-2024 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,
80 const ::RDKit::Atom &at);
81 friend int calculateImplicitValence(const Atom &, bool, bool);
82
83 public:
84 // FIX: grn...
86
87 //! store hybridization
88 typedef enum {
89 UNSPECIFIED = 0, //!< hybridization that hasn't been specified
97 OTHER //!< unrecognized hybridization
98 } HybridizationType;
99
100 //! store type of chirality
101 typedef enum {
102 CHI_UNSPECIFIED = 0, //!< chirality that hasn't been specified
103 CHI_TETRAHEDRAL_CW, //!< tetrahedral: clockwise rotation (SMILES \@\@)
104 CHI_TETRAHEDRAL_CCW, //!< tetrahedral: counter-clockwise rotation (SMILES
105 //\@)
106 CHI_OTHER, //!< some unrecognized type of chirality
107 CHI_TETRAHEDRAL, //!< tetrahedral, use permutation flag
108 CHI_ALLENE, //!< allene, use permutation flag
109 CHI_SQUAREPLANAR, //!< square planar, use permutation flag
110 CHI_TRIGONALBIPYRAMIDAL, //!< trigonal bipyramidal, use permutation flag
111 CHI_OCTAHEDRAL //!< octahedral, use permutation flag
112 } ChiralType;
113
114 enum class ValenceType : std::uint8_t {
115 IMPLICIT = 0,
116 EXPLICIT
117 };
118
120 //! construct an Atom with a particular atomic number
121 explicit Atom(unsigned int num);
122 //! construct an Atom with a particular symbol (looked up in the
123 /// PeriodicTable)
124 explicit Atom(const std::string &what);
125 Atom(const Atom &other);
126 Atom &operator=(const Atom &other);
127 // NOTE: the move methods are somewhat fraught for atoms associated with
128 // molecules since the molecule will still be pointing to the original object
129 Atom(Atom &&other) = default;
130 Atom &operator=(Atom &&other) = default;
131
132 virtual ~Atom();
133
134 //! makes a copy of this Atom and returns a pointer to it.
135 /*!
136 <b>Note:</b> the caller is responsible for <tt>delete</tt>ing the result
137 */
138 virtual Atom *copy() const;
139
140 //! returns our atomic number
141 int getAtomicNum() const { return d_atomicNum; }
142 //! sets our atomic number
143 void setAtomicNum(int newNum) { d_atomicNum = newNum; }
144
145 //! returns our symbol (determined by our atomic number)
146 std::string getSymbol() const;
147
148 //! returns whether or not this instance belongs to a molecule
149 bool hasOwningMol() const { return dp_mol != nullptr; }
150
151 //! returns a reference to the ROMol that owns this instance
153 PRECONDITION(dp_mol, "no owner");
154 return *dp_mol;
155 }
156
157 //! returns our index within the ROMol
158 unsigned int getIdx() const { return d_index; }
159 //! sets our index within the ROMol
160 /*!
161 <b>Notes:</b>
162 - this makes no sense if we do not have an owning molecule
163 - the index should be <tt>< this->getOwningMol()->getNumAtoms()</tt>
164 */
165 void setIdx(unsigned int index) { d_index = index; }
166 //! overload
167 template <class U>
168 void setIdx(const U index) {
169 setIdx(rdcast<unsigned int>(index));
170 }
171 //! returns the explicit degree of the Atom (number of bonded
172 //! neighbors in the graph)
173 unsigned int getDegree() const;
174
175 //! returns the total degree of the Atom (number of bonded
176 //! neighbors + number of Hs)
177 unsigned int getTotalDegree() const;
178
179 //! \brief returns the total number of Hs (implicit and explicit) that
180 //! this Atom is bound to
181 unsigned int getTotalNumHs(bool includeNeighbors = false) const;
182
183 //! \brief returns the total valence (implicit and explicit)
184 //! for an atom
185 unsigned int getTotalValence() const;
186
187 //! returns the number of implicit Hs this Atom is bound to
188 unsigned int getNumImplicitHs() const;
189
190 //! returns the valence (explicit or implicit) of this atom
191 unsigned int getValence(ValenceType which) const;
192
193 //! returns the explicit valence (including Hs) of this atom
194 [[deprecated("please use getValence(true)")]] int getExplicitValence() const;
195
196 //! returns the implicit valence for this Atom
197 [[deprecated("please use getValence(false)")]] int getImplicitValence() const;
198
199 //! returns whether the atom has a valency violation or not
201
202 //! returns the number of radical electrons for this Atom
203 unsigned int getNumRadicalElectrons() const { return d_numRadicalElectrons; }
204 void setNumRadicalElectrons(unsigned int num) { d_numRadicalElectrons = num; }
205
206 //! returns the formal charge of this atom
207 int getFormalCharge() const { return d_formalCharge; }
208 //! set's the formal charge of this atom
209 void setFormalCharge(int what) { d_formalCharge = what; }
210
211 //! \brief sets our \c noImplicit flag, indicating whether or not
212 //! we are allowed to have implicit Hs
213 void setNoImplicit(bool what) { df_noImplicit = what; }
214 //! returns the \c noImplicit flag
215 bool getNoImplicit() const { return df_noImplicit; }
216
217 //! sets our number of explicit Hs
218 void setNumExplicitHs(unsigned int what) { d_numExplicitHs = what; }
219 //! returns our number of explicit Hs
220 unsigned int getNumExplicitHs() const { return d_numExplicitHs; }
221
222 //! sets our \c isAromatic flag, indicating whether or not we are aromatic
223 void setIsAromatic(bool what) { df_isAromatic = what; }
224 //! returns our \c isAromatic flag
225 bool getIsAromatic() const { return df_isAromatic; }
226
227 //! returns our mass
228 double getMass() const;
229
230 //! sets our isotope number
231 void setIsotope(unsigned int what);
232 //! returns our isotope number
233 unsigned int getIsotope() const { return d_isotope; }
234
235 //! sets our \c chiralTag
236 void setChiralTag(ChiralType what) { d_chiralTag = what; }
237 //! inverts our \c chiralTag, returns whether or not a change was made
239 //! returns our \c chiralTag
241 return static_cast<ChiralType>(d_chiralTag);
242 }
243
244 //! sets our hybridization
245 void setHybridization(HybridizationType what) { d_hybrid = what; }
246 //! returns our hybridization
248 return static_cast<HybridizationType>(d_hybrid);
249 }
250
251 // ------------------------------------
252 // Some words of explanation before getting down into
253 // the query stuff.
254 // These query functions are really only here so that they
255 // can have real functionality in subclasses (like QueryAtoms).
256 // Since pretty much it's gonna be a mistake to call any of these
257 // (ever), we're saddling them all with a precondition which
258 // is guaranteed to fail. I'd like to have them be pure virtual,
259 // but that doesn't work since we need to be able to instantiate
260 // Atoms.
261 // ------------------------------------
262
263 // This method can be used to distinguish query atoms from standard atoms:
264 virtual bool hasQuery() const { return false; }
265
266 virtual std::string getQueryType() const { return ""; }
267
268 //! NOT CALLABLE
269 virtual void setQuery(QUERYATOM_QUERY *what);
270
271 //! NOT CALLABLE
272 virtual QUERYATOM_QUERY *getQuery() const;
273 //! NOT CALLABLE
274 virtual void expandQuery(
275 QUERYATOM_QUERY *what,
277 bool maintainOrder = true);
278
279 //! returns whether or not we match the argument
280 /*!
281 <b>Notes:</b>
282 The general rule is that if a property on this atom has a non-default
283 value,
284 the property on the other atom must have the same value.
285 The exception to this is H counts, which are ignored. These turns out to
286 be
287 impossible to handle generally, so rather than having odd and
288 hard-to-explain
289 exceptions, we ignore them entirely.
290
291 Here are the rules for atom-atom matching:
292 | This | Other | Match | Reason
293 | CCO | CCO | Yes |
294 | CCO | CC[O-] | Yes |
295 | CC[O-] | CCO | No | Charge
296 | CC[O-] | CC[O-] | Yes |
297 | CC[OH] | CC[O-] | Yes |
298 | CC[OH] | CCOC | Yes |
299 | CCO | CCOC | Yes |
300 | CCC | CCC | Yes |
301 | CCC | CC[14C] | Yes |
302 | CC[14C] | CCC | No | Isotope
303 | CC[14C] | CC[14C] | Yes |
304 | C | OCO | Yes |
305 | [CH] | OCO | Yes |
306 | [CH2] | OCO | Yes |
307 | [CH3] | OCO | No | Radical
308 | C | O[CH2]O | Yes |
309 | [CH2] | O[CH2]O | Yes |
310 */
311 virtual bool Match(Atom const *what) const;
312
313 //! returns the perturbation order for a list of integers
314 /*!
315
316 This value is associated with chirality.
317
318 \param probe a list of bond indices. This must be the same
319 length as our number of incoming bonds (our degree).
320
321 \return the number of swaps required to convert the ordering
322 of the probe list to match the order of our incoming bonds:
323 e.g. if our incoming bond order is: <tt>[0,1,2,3]</tt>
324 \verbatim
325 getPerturbationOrder([1,0,2,3]) = 1
326 getPerturbationOrder([1,2,3,0]) = 3
327 getPerturbationOrder([1,2,0,3]) = 2
328 \endverbatim
329
330 See the class documentation for a more detailed description
331 of our representation of chirality.
332
333 <b>Notes:</b>
334 - requires an owning molecule
335
336 */
337 int getPerturbationOrder(const INT_LIST &probe) const;
338
339 //! calculates any of our lazy \c properties
340 /*!
341 <b>Notes:</b>
342 - requires an owning molecule
343 - the current lazy \c properties are implicit and explicit valence
344 */
345 void updatePropertyCache(bool strict = true);
346
348
349 //! calculates and returns our explicit valence
350 /*!
351 <b>Notes:</b>
352 - requires an owning molecule
353 */
354 int calcExplicitValence(bool strict = true);
355
356 //! calculates and returns our implicit valence
357 /*!
358 <b>Notes:</b>
359 - requires an owning molecule
360 */
361 int calcImplicitValence(bool strict = true);
362
363 AtomMonomerInfo *getMonomerInfo() { return dp_monomerInfo; }
364 const AtomMonomerInfo *getMonomerInfo() const { return dp_monomerInfo; }
365 //! takes ownership of the pointer
367
368 //! Set the atom map Number of the atom
369 void setAtomMapNum(int mapno, bool strict = true) {
371 !strict || (mapno >= 0 && mapno < 1000),
372 "atom map number out of range [0..1000], use strict=false to override");
373 if (mapno) {
374 setProp(common_properties::molAtomMapNumber, mapno);
375 } else if (hasProp(common_properties::molAtomMapNumber)) {
376 clearProp(common_properties::molAtomMapNumber);
377 }
378 }
379 //! Gets the atom map Number of the atom, if no atom map exists, 0 is
380 //! returned.
381 int getAtomMapNum() const {
382 int mapno = 0;
383 getPropIfPresent(common_properties::molAtomMapNumber, mapno);
384 return mapno;
385 }
386
387 protected:
388 //! sets our owning molecule
389 void setOwningMol(ROMol *other);
390 //! sets our owning molecule
391 void setOwningMol(ROMol &other) { setOwningMol(&other); }
392
395 std::uint8_t d_numExplicitHs;
396 std::int8_t d_formalCharge;
397 std::uint8_t d_atomicNum;
398 // NOTE that these cannot be signed, they are calculated using
399 // a lazy scheme and are initialized to -1 to indicate that the
400 // calculation has not yet been done.
401 std::int8_t d_implicitValence, d_explicitValence;
403 std::uint8_t d_chiralTag;
404 std::uint8_t d_hybrid;
405
406 std::uint16_t d_isotope;
408
411 void initAtom();
412 void initFromOther(const Atom &other);
413};
414
415//! Set the atom's MDL integer RLabel
416/// Setting to 0 clears the rlabel. Rlabel must be in the range [0..99]
419
420//! Set the atom's MDL atom alias
421/// Setting to an empty string clears the alias
422RDKIT_GRAPHMOL_EXPORT void setAtomAlias(Atom *atom, const std::string &alias);
423RDKIT_GRAPHMOL_EXPORT std::string getAtomAlias(const Atom *atom);
424
425//! Set the atom's MDL atom value
426/// Setting to an empty string clears the value
427/// This is where recursive smarts get stored in MolBlock Queries
428RDKIT_GRAPHMOL_EXPORT void setAtomValue(Atom *atom, const std::string &value);
429RDKIT_GRAPHMOL_EXPORT std::string getAtomValue(const Atom *atom);
430
431//! Sets the supplemental label that will follow the atom when writing
432/// smiles strings.
434 const std::string &label);
436
437//! returns true if the atom is to the left of C
439//! returns true if the atom is aromatic or has an aromatic bond
441//! returns the number of pi electrons on the atom
442RDKIT_GRAPHMOL_EXPORT unsigned int numPiElectrons(const Atom &atom);
443}; // namespace RDKit
444
445//! allows Atom objects to be dumped to streams
446RDKIT_GRAPHMOL_EXPORT std::ostream &operator<<(std::ostream &target,
447 const RDKit::Atom &at);
448#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:240
AtomMonomerInfo * getMonomerInfo()
Definition Atom.h:363
void setNumExplicitHs(unsigned int what)
sets our number of explicit Hs
Definition Atom.h:218
Atom & operator=(const Atom &other)
void initAtom()
void setHybridization(HybridizationType what)
sets our hybridization
Definition Atom.h:245
ROMol & getOwningMol() const
returns a reference to the ROMol that owns this instance
Definition Atom.h:152
Queries::Query< int, Atom const *, true > QUERYATOM_QUERY
Definition Atom.h:85
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:407
bool getNoImplicit() const
returns the noImplicit flag
Definition Atom.h:215
friend int calculateImplicitValence(const Atom &, bool, bool)
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:158
unsigned int getValence(ValenceType which) const
returns the valence (explicit or implicit) of this atom
unsigned int getNumExplicitHs() const
returns our number of explicit Hs
Definition Atom.h:220
unsigned int getNumRadicalElectrons() const
returns the number of radical electrons for this Atom
Definition Atom.h:203
bool df_isAromatic
Definition Atom.h:393
void setNoImplicit(bool what)
sets our noImplicit flag, indicating whether or not we are allowed to have implicit Hs
Definition Atom.h:213
Atom(const Atom &other)
ROMol * dp_mol
Definition Atom.h:409
virtual void setQuery(QUERYATOM_QUERY *what)
NOT CALLABLE.
virtual std::string getQueryType() const
Definition Atom.h:266
int getExplicitValence() const
returns the explicit valence (including Hs) of this atom
HybridizationType
store hybridization
Definition Atom.h:88
@ SP3D2
Definition Atom.h:96
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:165
void setAtomicNum(int newNum)
sets our atomic number
Definition Atom.h:143
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:364
void setIsotope(unsigned int what)
sets our isotope number
std::uint16_t d_isotope
Definition Atom.h:406
void setOwningMol(ROMol &other)
sets our owning molecule
Definition Atom.h:391
std::uint8_t d_atomicNum
Definition Atom.h:397
int getAtomicNum() const
returns our atomic number
Definition Atom.h:141
int calcImplicitValence(bool strict=true)
calculates and returns our implicit valence
ChiralType
store type of chirality
Definition Atom.h:101
@ CHI_OTHER
some unrecognized type of chirality
Definition Atom.h:106
@ CHI_TETRAHEDRAL
tetrahedral, use permutation flag
Definition Atom.h:107
@ CHI_ALLENE
allene, use permutation flag
Definition Atom.h:108
@ CHI_TETRAHEDRAL_CW
tetrahedral: clockwise rotation (SMILES @@)
Definition Atom.h:103
@ CHI_TETRAHEDRAL_CCW
tetrahedral: counter-clockwise rotation (SMILES
Definition Atom.h:104
@ CHI_TRIGONALBIPYRAMIDAL
trigonal bipyramidal, use permutation flag
Definition Atom.h:110
@ CHI_SQUAREPLANAR
square planar, use permutation flag
Definition Atom.h:109
unsigned int getNumImplicitHs() const
returns the number of implicit Hs this Atom is bound to
bool df_noImplicit
Definition Atom.h:394
int getPerturbationOrder(const INT_LIST &probe) const
returns the perturbation order for a list of integers
AtomMonomerInfo * dp_monomerInfo
Definition Atom.h:410
int getAtomMapNum() const
Definition Atom.h:381
void setAtomMapNum(int mapno, bool strict=true)
Set the atom map Number of the atom.
Definition Atom.h:369
virtual bool hasQuery() const
Definition Atom.h:264
void setFormalCharge(int what)
set's the formal charge of this atom
Definition Atom.h:209
std::int8_t d_formalCharge
Definition Atom.h:396
std::uint8_t d_hybrid
Definition Atom.h:404
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:236
void setMonomerInfo(AtomMonomerInfo *info)
takes ownership of the pointer
HybridizationType getHybridization() const
returns our hybridization
Definition Atom.h:247
bool getIsAromatic() const
returns our isAromatic flag
Definition Atom.h:225
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:402
void setIsAromatic(bool what)
sets our isAromatic flag, indicating whether or not we are aromatic
Definition Atom.h:223
int getFormalCharge() const
returns the formal charge of this atom
Definition Atom.h:207
Atom & operator=(Atom &&other)=default
double getMass() const
returns our mass
unsigned int getIsotope() const
returns our isotope number
Definition Atom.h:233
unsigned int getTotalDegree() const
std::int8_t d_explicitValence
Definition Atom.h:401
void setIdx(const U index)
overload
Definition Atom.h:168
virtual QUERYATOM_QUERY * getQuery() const
NOT CALLABLE.
void setNumRadicalElectrons(unsigned int num)
Definition Atom.h:204
bool hasOwningMol() const
returns whether or not this instance belongs to a molecule
Definition Atom.h:149
void setOwningMol(ROMol *other)
sets our owning molecule
std::uint8_t d_chiralTag
Definition Atom.h:403
std::uint8_t d_numExplicitHs
Definition Atom.h:395
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:298
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)