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