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