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