RDKit
Open-source cheminformatics and machine learning.
ROMol.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2003-2022 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 ROMol.h
11 
12  \brief Defines the primary molecule class \c ROMol as well as associated
13  typedefs
14 
15 */
16 
17 #include <RDGeneral/export.h>
18 #ifndef RD_ROMOL_H
19 #define RD_ROMOL_H
20 
21 /// Std stuff
22 #include <cstddef>
23 #include <iterator>
24 #include <utility>
25 #include <map>
26 
27 // boost stuff
29 #include <boost/graph/adjacency_list.hpp>
30 #include <boost/smart_ptr.hpp>
31 #include <boost/dynamic_bitset.hpp>
32 
33 #ifdef RDK_USE_BOOST_SERIALIZATION
34 #include <boost/serialization/split_member.hpp>
35 #endif
37 
38 // our stuff
39 #include <RDGeneral/types.h>
40 #include <RDGeneral/RDProps.h>
41 #include "Atom.h"
42 #include "Bond.h"
43 #include "Conformer.h"
44 #include "SubstanceGroup.h"
45 #include "StereoGroup.h"
46 #include "RingInfo.h"
47 
48 namespace RDKit {
49 class SubstanceGroup;
50 class Atom;
51 class Bond;
52 //! This is the BGL type used to store the topology:
53 typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
54  Atom *, Bond *>
56 class MolPickler;
57 class RWMol;
58 class QueryAtom;
59 class QueryBond;
60 class RingInfo;
61 
62 template <class T1, class T2>
63 class AtomIterator_;
64 class BondIterator_;
65 class ConstBondIterator_;
66 
67 template <class T1, class T2>
69 template <class T1, class T2>
71 template <class T1, class T2>
72 class QueryAtomIterator_;
73 template <class T1, class T2>
75 
77 RDKIT_GRAPHMOL_EXPORT extern const int ci_LEADING_BOND;
78 RDKIT_GRAPHMOL_EXPORT extern const int ci_ATOM_HOLDER;
79 
80 //! ROMol is a molecule class that is intended to have a fixed topology
81 /*!
82  This is the primary class for most molecule operations.
83 
84  If you need to be manipulating the molecule (e.g. adding or deleting
85  atoms or bonds, use an RWMol instead.
86 
87  <b>Notes:</b>
88  - each ROMol maintains a Dict of \c properties:
89  - Each \c property is keyed by name and can store an
90  arbitrary type.
91  - \c Properties can be marked as \c calculated, in which case
92  they will be cleared when the \c clearComputedProps() method
93  is called.
94  - Because they have no impact upon chemistry, all \c property
95  operations are \c const, this allows extra flexibility for
96  clients who need to store extra data on ROMol objects.
97 
98  - each ROMol has collections of \c bookmarks for Atoms and Bonds:
99  - the Atom bookmarks and Bond bookmarks are stored separately
100  from each other
101  - each \c bookmark, an integer, can map to more than one
102  Atom or Bond
103  - these are currently used in molecule construction, but
104  could also be useful for reaction mapping and the like
105 
106  - information about rings (SSSR and the like) is stored in the
107  molecule's RingInfo pointer.
108 
109  */
110 
111 //! \name C++11 Iterators
112 
113 template <class Graph, class Vertex,
114  class Iterator = typename Graph::vertex_iterator>
116  Graph *graph;
117  Iterator vstart, vend;
118 
119  struct CXXAtomIter {
120  using iterator_category = std::forward_iterator_tag;
121  using difference_type = std::ptrdiff_t;
122  using value_type = Vertex;
123  using pointer = Vertex *;
124  using reference = Vertex &;
125 
126  Graph *graph;
127  Iterator pos;
129 
130  CXXAtomIter(Graph *graph, Iterator pos)
131  : graph(graph), pos(pos), current(nullptr) {}
132 
134  current = (*graph)[*pos];
135  return current;
136  }
138  ++pos;
139  return *this;
140  }
141  bool operator==(const CXXAtomIter &it) const { return pos == it.pos; }
142  bool operator!=(const CXXAtomIter &it) const { return pos != it.pos; }
143  };
144 
146  auto vs = boost::vertices(*graph);
147  vstart = vs.first;
148  vend = vs.second;
149  }
150  CXXAtomIterator(Graph *graph, Iterator start, Iterator end)
151  : graph(graph), vstart(start), vend(end){};
152  CXXAtomIter begin() { return {graph, vstart}; }
153  CXXAtomIter end() { return {graph, vend}; }
154 };
155 
156 template <class Graph, class Edge,
157  class Iterator = typename Graph::edge_iterator>
159  Graph *graph;
160  Iterator vstart, vend;
161 
162  struct CXXBondIter {
163  using iterator_category = std::forward_iterator_tag;
164  using difference_type = std::ptrdiff_t;
165  using value_type = Edge;
166  using pointer = Edge *;
167  using reference = Edge &;
168 
169  Graph *graph;
170  Iterator pos;
172 
173  CXXBondIter(Graph *graph, Iterator pos)
174  : graph(graph), pos(pos), current(nullptr) {}
175 
177  current = (*graph)[*pos];
178  return current;
179  }
181  ++pos;
182  return *this;
183  }
184  bool operator==(const CXXBondIter &it) const { return pos == it.pos; }
185  bool operator!=(const CXXBondIter &it) const { return pos != it.pos; }
186  };
187 
189  auto vs = boost::edges(*graph);
190  vstart = vs.first;
191  vend = vs.second;
192  }
193  CXXBondIterator(Graph *graph, Iterator start, Iterator end)
194  : graph(graph), vstart(start), vend(end){};
195  CXXBondIter begin() { return {graph, vstart}; }
196  CXXBondIter end() { return {graph, vend}; }
197 };
198 
200  public:
201  friend class MolPickler;
202  friend class RWMol;
203 
204  //! \cond TYPEDEFS
205 
206  //! \name typedefs
207  //! @{
208  typedef MolGraph::vertex_descriptor vertex_descriptor;
209  typedef MolGraph::edge_descriptor edge_descriptor;
210 
211  typedef MolGraph::edge_iterator EDGE_ITER;
212  typedef MolGraph::out_edge_iterator OEDGE_ITER;
213  typedef MolGraph::vertex_iterator VERTEX_ITER;
214  typedef MolGraph::adjacency_iterator ADJ_ITER;
215  typedef std::pair<EDGE_ITER, EDGE_ITER> BOND_ITER_PAIR;
216  typedef std::pair<OEDGE_ITER, OEDGE_ITER> OBOND_ITER_PAIR;
217  typedef std::pair<VERTEX_ITER, VERTEX_ITER> ATOM_ITER_PAIR;
218  typedef std::pair<ADJ_ITER, ADJ_ITER> ADJ_ITER_PAIR;
219 
220  typedef std::vector<Atom *> ATOM_PTR_VECT;
221  typedef ATOM_PTR_VECT::iterator ATOM_PTR_VECT_I;
222  typedef ATOM_PTR_VECT::const_iterator ATOM_PTR_VECT_CI;
223  typedef std::vector<Bond *> BOND_PTR_VECT;
224  typedef BOND_PTR_VECT::iterator BOND_PTR_VECT_I;
225  typedef BOND_PTR_VECT::const_iterator BOND_PTR_VECT_CI;
226 
227  typedef std::list<Atom *> ATOM_PTR_LIST;
228  typedef ATOM_PTR_LIST::iterator ATOM_PTR_LIST_I;
229  typedef ATOM_PTR_LIST::const_iterator ATOM_PTR_LIST_CI;
230  typedef std::list<Bond *> BOND_PTR_LIST;
231  typedef BOND_PTR_LIST::iterator BOND_PTR_LIST_I;
232  typedef BOND_PTR_LIST::const_iterator BOND_PTR_LIST_CI;
233 
234  // list of conformations
235  typedef std::list<CONFORMER_SPTR> CONF_SPTR_LIST;
236  typedef CONF_SPTR_LIST::iterator CONF_SPTR_LIST_I;
237  typedef CONF_SPTR_LIST::const_iterator CONF_SPTR_LIST_CI;
238  typedef std::pair<CONF_SPTR_LIST_I, CONF_SPTR_LIST_I> CONFS_I_PAIR;
239 
240  // ROFIX: these will need to be readonly somehow?
241  typedef std::map<int, ATOM_PTR_LIST> ATOM_BOOKMARK_MAP;
242  typedef std::map<int, BOND_PTR_LIST> BOND_BOOKMARK_MAP;
243 
244  typedef class AtomIterator_<Atom, ROMol> AtomIterator;
245  typedef class AtomIterator_<const Atom, const ROMol> ConstAtomIterator;
246  typedef class BondIterator_ BondIterator;
247  typedef class ConstBondIterator_ ConstBondIterator;
248  typedef class AromaticAtomIterator_<Atom, ROMol> AromaticAtomIterator;
249  typedef class AromaticAtomIterator_<const Atom, const ROMol>
250  ConstAromaticAtomIterator;
251  typedef class HeteroatomIterator_<Atom, ROMol> HeteroatomIterator;
252  typedef class HeteroatomIterator_<const Atom, const ROMol>
253  ConstHeteroatomIterator;
254  typedef class QueryAtomIterator_<Atom, ROMol> QueryAtomIterator;
255  typedef class QueryAtomIterator_<const Atom, const ROMol>
256  ConstQueryAtomIterator;
257  typedef class MatchingAtomIterator_<Atom, ROMol> MatchingAtomIterator;
258  typedef class MatchingAtomIterator_<const Atom, const ROMol>
259  ConstMatchingAtomIterator;
260 
261  typedef CONF_SPTR_LIST_I ConformerIterator;
262  typedef CONF_SPTR_LIST_CI ConstConformerIterator;
263 
264  //! @}
265  //! \endcond
266 
267  //! C++11 Range iterator
268  /*!
269  <b>Usage</b>
270  \code
271  for(auto atom : mol.atoms()) {
272  atom->getIdx();
273  };
274  \endcode
275  */
276 
277  CXXAtomIterator<MolGraph, Atom *> atoms() { return {&d_graph}; }
278 
280  return {&d_graph};
281  }
282 
284  atomNeighbors(Atom const *at) const {
285  auto pr = getAtomNeighbors(at);
286  return {&d_graph, pr.first, pr.second};
287  }
288 
290  Atom const *at) {
291  auto pr = getAtomNeighbors(at);
292  return {&d_graph, pr.first, pr.second};
293  }
294 
296  atomBonds(Atom const *at) const {
297  auto pr = getAtomBonds(at);
298  return {&d_graph, pr.first, pr.second};
299  }
300 
302  Atom const *at) {
303  auto pr = getAtomBonds(at);
304  return {&d_graph, pr.first, pr.second};
305  }
306 
307  /*!
308  <b>Usage</b>
309  \code
310  for(auto bond : mol.bonds()) {
311  bond->getIdx();
312  };
313  \endcode
314  */
315 
316  CXXBondIterator<MolGraph, Bond *> bonds() { return {&d_graph}; }
317 
319  return {&d_graph};
320  }
321 
322  ROMol() : RDProps() { initMol(); }
323 
324  //! copy constructor with a twist
325  /*!
326  \param other the molecule to be copied
327  \param quickCopy (optional) if this is true, the resulting ROMol will not
328  copy any of the properties or bookmarks and conformers from \c other.
329  This can
330  make the copy substantially faster (thus the name).
331  \param confId (optional) if this is >=0, the resulting ROMol will contain
332  only
333  the specified conformer from \c other.
334  */
335  ROMol(const ROMol &other, bool quickCopy = false, int confId = -1)
336  : RDProps() {
337  dp_ringInfo = nullptr;
338  initFromOther(other, quickCopy, confId);
339  numBonds = rdcast<unsigned int>(boost::num_edges(d_graph));
340  }
341  //! construct a molecule from a pickle string
342  ROMol(const std::string &binStr);
343  //! construct a molecule from a pickle string
344  ROMol(const std::string &binStr, unsigned int propertyFlags);
345 
346  ROMol(ROMol &&o) noexcept
347  : RDProps(std::move(o)),
348  d_graph(std::move(o.d_graph)),
349  d_atomBookmarks(std::move(o.d_atomBookmarks)),
350  d_bondBookmarks(std::move(o.d_bondBookmarks)),
351  d_confs(std::move(o.d_confs)),
352  d_sgroups(std::move(o.d_sgroups)),
353  d_stereo_groups(std::move(o.d_stereo_groups)),
354  numBonds(o.numBonds) {
355  for (auto atom : atoms()) {
356  atom->setOwningMol(this);
357  }
358  for (auto bond : bonds()) {
359  bond->setOwningMol(this);
360  }
361  for (auto conf : d_confs) {
362  conf->setOwningMol(this);
363  }
364  o.d_graph.clear();
365  o.numBonds = 0;
366  dp_ringInfo = std::exchange(o.dp_ringInfo, nullptr);
367  dp_delAtoms = std::exchange(o.dp_delAtoms, nullptr);
368  dp_delBonds = std::exchange(o.dp_delBonds, nullptr);
369  }
370  ROMol &operator=(ROMol &&o) noexcept {
371  if (this == &o) {
372  return *this;
373  }
374  RDProps::operator=(std::move(o));
375  d_graph = std::move(o.d_graph);
376  d_atomBookmarks = std::move(o.d_atomBookmarks);
377  d_bondBookmarks = std::move(o.d_bondBookmarks);
378  if (dp_ringInfo) {
379  delete dp_ringInfo;
380  }
381  dp_ringInfo = std::exchange(o.dp_ringInfo, nullptr);
382 
383  d_confs = std::move(o.d_confs);
384  d_sgroups = std::move(o.d_sgroups);
385  d_stereo_groups = std::move(o.d_stereo_groups);
386  dp_delAtoms = std::exchange(o.dp_delAtoms, nullptr);
387  dp_delBonds = std::exchange(o.dp_delBonds, nullptr);
388  numBonds = o.numBonds;
389  o.numBonds = 0;
390 
391  for (auto atom : atoms()) {
392  atom->setOwningMol(this);
393  }
394  for (auto bond : bonds()) {
395  bond->setOwningMol(this);
396  }
397  for (auto conf : d_confs) {
398  conf->setOwningMol(this);
399  }
400 
401  o.d_graph.clear();
402  return *this;
403  }
404 
405  ROMol &operator=(const ROMol &) =
406  delete; // disable assignment, RWMol's support assignment
407 
408  virtual ~ROMol() { destroy(); }
409 
410  //! @}
411  //! \name Atoms
412  //! @{
413 
414  //! returns our number of atoms
415  inline unsigned int getNumAtoms() const {
416  return rdcast<unsigned int>(boost::num_vertices(d_graph));
417  }
418  unsigned int getNumAtoms(bool onlyExplicit) const;
419  //! returns our number of heavy atoms (atomic number > 1)
420  unsigned int getNumHeavyAtoms() const;
421  //! returns a pointer to a particular Atom
422  Atom *getAtomWithIdx(unsigned int idx);
423  //! \overload
424  const Atom *getAtomWithIdx(unsigned int idx) const;
425  //! \overload
426  template <class U>
427  Atom *getAtomWithIdx(const U idx) {
428  return getAtomWithIdx(rdcast<unsigned int>(idx));
429  }
430  //! \overload
431  template <class U>
432  const Atom *getAtomWithIdx(const U idx) const {
433  return getAtomWithIdx(rdcast<unsigned int>(idx));
434  }
435  //! returns the degree (number of neighbors) of an Atom in the graph
436  unsigned int getAtomDegree(const Atom *at) const;
437  //! @}
438 
439  //! \name Bonds
440  //! @{
441 
442  //! returns our number of Bonds
443  unsigned int getNumBonds(bool onlyHeavy = 1) const;
444  //! returns a pointer to a particular Bond
445  Bond *getBondWithIdx(unsigned int idx);
446  //! \overload
447  const Bond *getBondWithIdx(unsigned int idx) const;
448  //! \overload
449  template <class U>
450  Bond *getBondWithIdx(const U idx) {
451  return getBondWithIdx(rdcast<unsigned int>(idx));
452  }
453  //! \overload
454  template <class U>
455  const Bond *getBondWithIdx(const U idx) const {
456  return getBondWithIdx(rdcast<unsigned int>(idx));
457  }
458  //! returns a pointer to the bond between two atoms, Null on failure
459  Bond *getBondBetweenAtoms(unsigned int idx1, unsigned int idx2);
460  //! \overload
461  const Bond *getBondBetweenAtoms(unsigned int idx1, unsigned int idx2) const;
462  //! \overload
463  template <class U, class V>
464  Bond *getBondBetweenAtoms(const U idx1, const V idx2) {
465  return getBondBetweenAtoms(rdcast<unsigned int>(idx1),
466  rdcast<unsigned int>(idx2));
467  }
468  //! \overload
469  template <class U, class V>
470  const Bond *getBondBetweenAtoms(const U idx1, const V idx2) const {
471  return getBondBetweenAtoms(rdcast<unsigned int>(idx1),
472  rdcast<unsigned int>(idx2));
473  }
474 
475  //! @}
476 
477  //! \name Bookmarks
478  //! @{
479 
480  //! associates an Atom pointer with a bookmark
481  void setAtomBookmark(Atom *at, int mark) {
482  d_atomBookmarks[mark].push_back(at);
483  }
484  //! associates an Atom pointer with a bookmark
485  void replaceAtomBookmark(Atom *at, int mark) {
486  d_atomBookmarks[mark].clear();
487  d_atomBookmarks[mark].push_back(at);
488  }
489  //! returns the first Atom associated with the \c bookmark provided
491  //! returns the Atom associated with the \c bookmark provided
492  //! a check is made to ensure it is the only atom with that bookmark
494  //! returns all Atoms associated with the \c bookmark provided
495  ATOM_PTR_LIST &getAllAtomsWithBookmark(int mark);
496  //! removes a \c bookmark from our collection
497  void clearAtomBookmark(int mark);
498  //! removes a particular Atom from the list associated with the \c bookmark
499  void clearAtomBookmark(int mark, const Atom *atom);
500 
501  //! blows out all atomic \c bookmarks
502  void clearAllAtomBookmarks() { d_atomBookmarks.clear(); }
503  //! queries whether or not any atoms are associated with a \c bookmark
504  bool hasAtomBookmark(int mark) const { return d_atomBookmarks.count(mark); }
505  //! returns a pointer to all of our atom \c bookmarks
506  ATOM_BOOKMARK_MAP *getAtomBookmarks() { return &d_atomBookmarks; }
507 
508  //! associates a Bond pointer with a bookmark
509  void setBondBookmark(Bond *bond, int mark) {
510  d_bondBookmarks[mark].push_back(bond);
511  }
512  //! returns the first Bond associated with the \c bookmark provided
514  //! returns the Bond associated with the \c bookmark provided
515  //! a check is made to ensure it is the only bond with that bookmark
517  //! returns all bonds associated with the \c bookmark provided
518  BOND_PTR_LIST &getAllBondsWithBookmark(int mark);
519  //! removes a \c bookmark from our collection
520  void clearBondBookmark(int mark);
521  //! removes a particular Bond from the list associated with the \c bookmark
522  void clearBondBookmark(int mark, const Bond *bond);
523 
524  //! blows out all bond \c bookmarks
525  void clearAllBondBookmarks() { d_bondBookmarks.clear(); }
526  //! queries whether or not any bonds are associated with a \c bookmark
527  bool hasBondBookmark(int mark) const { return d_bondBookmarks.count(mark); }
528  //! returns a pointer to all of our bond \c bookmarks
529  BOND_BOOKMARK_MAP *getBondBookmarks() { return &d_bondBookmarks; }
530 
531  //! @}
532 
533  //! \name Conformers
534  //! @{
535 
536  //! return the conformer with a specified ID
537  //! if the ID is negative the first conformation will be returned
538  const Conformer &getConformer(int id = -1) const;
539 
540  //! return the conformer with a specified ID
541  //! if the ID is negative the first conformation will be returned
542  Conformer &getConformer(int id = -1);
543 
544  //! Delete the conformation with the specified ID
545  void removeConformer(unsigned int id);
546 
547  //! Clear all the conformations on the molecule
548  void clearConformers() { d_confs.clear(); }
549 
550  //! Add a new conformation to the molecule
551  /*!
552  \param conf - conformation to be added to the molecule, this molecule takes
553  ownership
554  of the conformer
555  \param assignId - a unique ID will be assigned to the conformation if
556  true
557  otherwise it is assumed that the conformation already has
558  an (unique) ID set
559  */
560  unsigned int addConformer(Conformer *conf, bool assignId = false);
561 
562  inline unsigned int getNumConformers() const {
563  return rdcast<unsigned int>(d_confs.size());
564  }
565 
566  //! \name Topology
567  //! @{
568 
569  //! returns a pointer to our RingInfo structure
570  //! <b>Note:</b> the client should not delete this.
571  RingInfo *getRingInfo() const { return dp_ringInfo; }
572 
573  //! provides access to all neighbors around an Atom
574  /*!
575  \param at the atom whose neighbors we are looking for
576 
577  <b>Usage</b>
578  \code
579  ... mol is a const ROMol & ...
580  ... atomPtr is a const Atom * ...
581  ... requires #include <boost/range/iterator_range.hpp>
582  for (const auto &nbri :
583  boost::make_iterator_range(m.getAtomNeighbors(atomPtr))) {
584  const auto &nbr = (*m)[nbri];
585  // nbr is an atom pointer
586  }
587 
588  \endcode
589 
590  */
591  ADJ_ITER_PAIR getAtomNeighbors(Atom const *at) const;
592 
593  //! provides access to all Bond objects connected to an Atom
594  /*!
595  \param at the atom whose neighbors we are looking for
596 
597  <b>Usage</b>
598  \code
599  ... mol is a const ROMol & ...
600  ... atomPtr is a const Atom * ...
601  ... requires #include <boost/range/iterator_range.hpp>
602  for (const auto &nbri :
603  boost::make_iterator_range(m.getAtomBonds(atomPtr))) {
604  const auto &nbr = (*m)[nbri];
605  // nbr is a bond pointer
606  }
607  \endcode
608  or, if you need a non-const Bond *:
609  \code
610  ... mol is a const ROMol & ...
611  ... atomPtr is a const Atom * ...
612  ... requires #include <boost/range/iterator_range.hpp>
613  for (const auto &nbri :
614  boost::make_iterator_range(m.getAtomBonds(atomPtr))) {
615  auto nbr = (*m)[nbri];
616  // nbr is a bond pointer
617  }
618  \endcode
619 
620 
621  */
622  OBOND_ITER_PAIR getAtomBonds(Atom const *at) const;
623 
624  //! returns an iterator pair for looping over all Atoms
625  /*!
626 
627  <b>Usage</b>
628  \code
629 
630  ROMol::VERTEX_ITER atBegin,atEnd;
631  boost::tie(atBegin,atEnd) = mol.getVertices();
632  while(atBegin!=atEnd){
633  ATOM_SPTR at2=mol[*atBegin];
634  ... do something with the Atom ...
635  ++atBegin;
636  }
637  \endcode
638  */
639  ATOM_ITER_PAIR getVertices();
640  //! returns an iterator pair for looping over all Bonds
641  /*!
642 
643  <b>Usage</b>
644  \code
645 
646  ROMol::EDGE_ITER firstB,lastB;
647  boost::tie(firstB,lastB) = mol.getEdges();
648  while(firstB!=lastB){
649  BOND_SPTR bond = mol[*firstB];
650  ... do something with the Bond ...
651  ++firstB;
652  }
653  \endcode
654  */
655  BOND_ITER_PAIR getEdges();
656  //! \overload
657  ATOM_ITER_PAIR getVertices() const;
658  //! \overload
659  BOND_ITER_PAIR getEdges() const;
660 
661  //! brief returns a pointer to our underlying BGL object
662  /*!
663  This can be useful if you need to call other BGL algorithms:
664 
665  Here's an example:
666  \code
667  ... mol is a const ROMol ...
668  ... mapping is an INT_VECT ...
669  mapping.resize(mol.getNumAtoms());
670  const MolGraph &G_p = mol.getTopology();
671  int res = boost::connected_components(G_p,&mapping[0]);
672  \endcode
673  */
674  MolGraph const &getTopology() const { return d_graph; }
675  //! @}
676 
677  //! \name Iterators
678  //! @{
679 
680  //! get an AtomIterator pointing at our first Atom
681  AtomIterator beginAtoms();
682  //! \overload
683  ConstAtomIterator beginAtoms() const;
684  //! get an AtomIterator pointing at the end of our Atoms
685  AtomIterator endAtoms();
686  //! \overload
687  ConstAtomIterator endAtoms() const;
688  //! get a BondIterator pointing at our first Bond
689  BondIterator beginBonds();
690  //! \overload
691  ConstBondIterator beginBonds() const;
692  //! get a BondIterator pointing at the end of our Bonds
693  BondIterator endBonds();
694  //! \overload
695  ConstBondIterator endBonds() const;
696 
697  //! get an AtomIterator pointing at our first aromatic Atom
698  AromaticAtomIterator beginAromaticAtoms();
699  //! \overload
700  ConstAromaticAtomIterator beginAromaticAtoms() const;
701  //! get an AtomIterator pointing at the end of our Atoms
702  AromaticAtomIterator endAromaticAtoms();
703  //! \overload
704  ConstAromaticAtomIterator endAromaticAtoms() const;
705 
706  //! get an AtomIterator pointing at our first hetero Atom
707  HeteroatomIterator beginHeteros();
708  //! \overload
709  ConstHeteroatomIterator beginHeteros() const;
710  //! get an AtomIterator pointing at the end of our Atoms
711  HeteroatomIterator endHeteros();
712  //! \overload
713  ConstHeteroatomIterator endHeteros() const;
714 
715  //! get an AtomIterator pointing at our first Atom that matches \c query
716  QueryAtomIterator beginQueryAtoms(QueryAtom const *query);
717  //! \overload
718  ConstQueryAtomIterator beginQueryAtoms(QueryAtom const *) const;
719  //! get an AtomIterator pointing at the end of our Atoms
720  QueryAtomIterator endQueryAtoms();
721  //! \overload
722  ConstQueryAtomIterator endQueryAtoms() const;
723 
724  //! get an AtomIterator pointing at our first Atom that matches \c query
725  MatchingAtomIterator beginMatchingAtoms(bool (*query)(Atom *));
726  //! \overload
727  ConstMatchingAtomIterator beginMatchingAtoms(
728  bool (*query)(const Atom *)) const;
729  //! get an AtomIterator pointing at the end of our Atoms
730  MatchingAtomIterator endMatchingAtoms();
731  //! \overload
732  ConstMatchingAtomIterator endMatchingAtoms() const;
733 
734  inline ConformerIterator beginConformers() { return d_confs.begin(); }
735 
736  inline ConformerIterator endConformers() { return d_confs.end(); }
737 
738  inline ConstConformerIterator beginConformers() const {
739  return d_confs.begin();
740  }
741 
742  inline ConstConformerIterator endConformers() const { return d_confs.end(); }
743 
744  //! @}
745 
746  //! \name Properties
747  //! @{
748 
749  //! clears all of our \c computed \c properties
750  void clearComputedProps(bool includeRings = true) const;
751  //! calculates any of our lazy \c properties
752  /*!
753  <b>Notes:</b>
754  - this calls \c updatePropertyCache() on each of our Atoms and Bonds
755  */
756  void updatePropertyCache(bool strict = true);
757 
759 
760  //! @}
761 
762  //! \name Misc
763  //! @{
764  //! sends some debugging info to a stream
765  void debugMol(std::ostream &str) const;
766  //! @}
767 
768  Atom *operator[](const vertex_descriptor &v) { return d_graph[v]; }
769  const Atom *operator[](const vertex_descriptor &v) const {
770  return d_graph[v];
771  }
772 
773  Bond *operator[](const edge_descriptor &e) { return d_graph[e]; }
774  const Bond *operator[](const edge_descriptor &e) const { return d_graph[e]; }
775 
776  //! Gets a reference to the groups of atoms with relative stereochemistry
777  /*!
778  Stereo groups are also called enhanced stereochemistry in the SDF/Mol3000
779  file format.
780  */
781  const std::vector<StereoGroup> &getStereoGroups() const {
782  return d_stereo_groups;
783  }
784 
785  //! Sets groups of atoms with relative stereochemistry
786  /*!
787  \param stereo_groups the new set of stereo groups. All will be replaced.
788 
789  Stereo groups are also called enhanced stereochemistry in the SDF/Mol3000
790  file format. stereo_groups should be std::move()ed into this function.
791  */
792  void setStereoGroups(std::vector<StereoGroup> stereo_groups);
793 
794 #ifdef RDK_USE_BOOST_SERIALIZATION
795  //! \name boost::serialization support
796  //! @{
797  template <class Archive>
798  void save(Archive &ar, const unsigned int version) const;
799  template <class Archive>
800  void load(Archive &ar, const unsigned int version);
801  BOOST_SERIALIZATION_SPLIT_MEMBER()
802  //! @}
803 #endif
804 
805  private:
806  MolGraph d_graph;
807  ATOM_BOOKMARK_MAP d_atomBookmarks;
808  BOND_BOOKMARK_MAP d_bondBookmarks;
809  RingInfo *dp_ringInfo = nullptr;
810  CONF_SPTR_LIST d_confs;
811  std::vector<SubstanceGroup> d_sgroups;
812  std::vector<StereoGroup> d_stereo_groups;
813  std::unique_ptr<boost::dynamic_bitset<>> dp_delAtoms = nullptr;
814  std::unique_ptr<boost::dynamic_bitset<>> dp_delBonds = nullptr;
815 
816  friend RDKIT_GRAPHMOL_EXPORT std::vector<SubstanceGroup> &getSubstanceGroups(
817  ROMol &);
818  friend RDKIT_GRAPHMOL_EXPORT const std::vector<SubstanceGroup>
820  void clearSubstanceGroups() { d_sgroups.clear(); }
821 
822  protected:
823  unsigned int numBonds{0};
824 #ifndef WIN32
825  private:
826 #endif
827  void initMol();
828  virtual void destroy();
829  //! adds an Atom to our collection
830  /*!
831  \param atom pointer to the Atom to add
832  \param updateLabel (optional) if this is true, the new Atom will be
833  our \c activeAtom
834  \param takeOwnership (optional) if this is true, we take ownership of \c
835  atom
836  instead of copying it.
837 
838  \return the index of the new atom
839  */
840  unsigned int addAtom(Atom *atom, bool updateLabel = true,
841  bool takeOwnership = false);
842  //! adds a Bond to our collection
843  /*!
844  \param bond pointer to the Bond to add
845  \param takeOwnership (optional) if this is true, we take ownership of \c
846  bond
847  instead of copying it.
848 
849  \return the new number of bonds
850  */
851  unsigned int addBond(Bond *bond, bool takeOwnership = false);
852 
853  //! adds a Bond to our collection
854  /*!
855  \param bond pointer to the Bond to add
856 
857  \return the new number of bonds
858 
859  <b>Note:</b> since this is using a smart pointer, we don't need to worry
860  about
861  issues of ownership.
862  */
863  void initFromOther(const ROMol &other, bool quickCopy, int confId);
864 };
865 
866 typedef std::vector<ROMol> MOL_VECT;
867 typedef boost::shared_ptr<ROMol> ROMOL_SPTR;
868 typedef std::vector<ROMol *> MOL_PTR_VECT;
869 typedef std::vector<ROMOL_SPTR> MOL_SPTR_VECT;
870 
871 typedef MOL_PTR_VECT::const_iterator MOL_PTR_VECT_CI;
872 typedef MOL_PTR_VECT::iterator MOL_PTR_VECT_I;
873 
874 }; // namespace RDKit
875 #endif
Defines the Atom class and associated typedefs.
Defines the class StereoGroup which stores relationships between the absolute configurations of atoms...
Defines the SubstanceGroup class.
Iterate over aromatic atoms, this is bidirectional.
A general random access iterator.
Definition: AtomIterators.h:31
The class for representing atoms.
Definition: Atom.h:68
iterator for a molecule's bonds, currently BiDirectional, but it theoretically ought to be RandomAcce...
Definition: BondIterators.h:27
class for representing a bond
Definition: Bond.h:47
The class for representing 2D or 3D conformation of a molecule.
Definition: Conformer.h:45
const iterator for a molecule's bonds, currently BiDirectional, but it theoretically ought to be Rand...
Definition: BondIterators.h:52
Iterate over heteroatoms, this is bidirectional.
Definition: AtomIterators.h:74
Iterate over atoms matching a query function. This is bidirectional.
handles pickling (serializing) molecules
Definition: MolPickler.h:68
Iterate over atoms matching a query. This is bidirectional.
Class for storing atomic queries.
Definition: QueryAtom.h:28
Class for storing Bond queries.
Definition: QueryBond.h:28
void clear()
Definition: RDProps.h:34
RDProps & operator=(const RDProps &rhs)
Definition: RDProps.h:24
ConstAromaticAtomIterator endAromaticAtoms() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
CXXBondIterator< MolGraph, Bond * > bonds()
Definition: ROMol.h:316
ADJ_ITER_PAIR getAtomNeighbors(Atom const *at) const
provides access to all neighbors around an Atom
ConstQueryAtomIterator endQueryAtoms() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
const Bond * operator[](const edge_descriptor &e) const
Definition: ROMol.h:774
bool needsUpdatePropertyCache() const
OBOND_ITER_PAIR getAtomBonds(Atom const *at) const
provides access to all Bond objects connected to an Atom
unsigned int getNumBonds(bool onlyHeavy=1) const
returns our number of Bonds
CXXBondIterator< const MolGraph, Bond *const > bonds() const
Definition: ROMol.h:318
void clearAtomBookmark(int mark)
removes a bookmark from our collection
Bond * getBondBetweenAtoms(const U idx1, const V idx2)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: ROMol.h:464
unsigned int getNumHeavyAtoms() const
returns our number of heavy atoms (atomic number > 1)
void clearAtomBookmark(int mark, const Atom *atom)
removes a particular Atom from the list associated with the bookmark
const Atom * getAtomWithIdx(const U idx) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: ROMol.h:432
unsigned int getNumConformers() const
Definition: ROMol.h:562
AtomIterator endAtoms()
get an AtomIterator pointing at the end of our Atoms
Bond * getBondWithIdx(unsigned int idx)
returns a pointer to a particular Bond
RingInfo * getRingInfo() const
Definition: ROMol.h:571
ConstAtomIterator endAtoms() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
BondIterator beginBonds()
get a BondIterator pointing at our first Bond
bool hasAtomBookmark(int mark) const
queries whether or not any atoms are associated with a bookmark
Definition: ROMol.h:504
MolGraph const & getTopology() const
brief returns a pointer to our underlying BGL object
Definition: ROMol.h:674
ConstQueryAtomIterator beginQueryAtoms(QueryAtom const *) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
unsigned int getNumAtoms() const
returns our number of atoms
Definition: ROMol.h:415
ConstConformerIterator endConformers() const
Definition: ROMol.h:742
ConstMatchingAtomIterator beginMatchingAtoms(bool(*query)(const Atom *)) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
ROMol(const ROMol &other, bool quickCopy=false, int confId=-1)
copy constructor with a twist
Definition: ROMol.h:335
ConstMatchingAtomIterator endMatchingAtoms() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
BOND_ITER_PAIR getEdges()
returns an iterator pair for looping over all Bonds
void clearConformers()
Clear all the conformations on the molecule.
Definition: ROMol.h:548
void setBondBookmark(Bond *bond, int mark)
associates a Bond pointer with a bookmark
Definition: ROMol.h:509
void updatePropertyCache(bool strict=true)
calculates any of our lazy properties
ROMol & operator=(const ROMol &)=delete
ATOM_PTR_LIST & getAllAtomsWithBookmark(int mark)
returns all Atoms associated with the bookmark provided
Bond * getBondWithBookmark(int mark)
returns the first Bond associated with the bookmark provided
const Bond * getBondBetweenAtoms(const U idx1, const V idx2) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: ROMol.h:470
BOND_BOOKMARK_MAP * getBondBookmarks()
returns a pointer to all of our bond bookmarks
Definition: ROMol.h:529
Atom * getAtomWithIdx(const U idx)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: ROMol.h:427
const Bond * getBondWithIdx(const U idx) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: ROMol.h:455
QueryAtomIterator endQueryAtoms()
get an AtomIterator pointing at the end of our Atoms
BOND_PTR_LIST & getAllBondsWithBookmark(int mark)
returns all bonds associated with the bookmark provided
unsigned int addConformer(Conformer *conf, bool assignId=false)
Add a new conformation to the molecule.
Bond * getBondWithIdx(const U idx)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: ROMol.h:450
void clearAllBondBookmarks()
blows out all bond bookmarks
Definition: ROMol.h:525
ATOM_ITER_PAIR getVertices()
returns an iterator pair for looping over all Atoms
BOND_ITER_PAIR getEdges() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
friend RDKIT_GRAPHMOL_EXPORT std::vector< SubstanceGroup > & getSubstanceGroups(ROMol &)
void clearComputedProps(bool includeRings=true) const
clears all of our computed properties
Atom * operator[](const vertex_descriptor &v)
Definition: ROMol.h:768
ROMol(const std::string &binStr, unsigned int propertyFlags)
construct a molecule from a pickle string
ConstAtomIterator beginAtoms() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
const Bond * getBondWithIdx(unsigned int idx) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
ConstAromaticAtomIterator beginAromaticAtoms() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void debugMol(std::ostream &str) const
const Bond * getBondBetweenAtoms(unsigned int idx1, unsigned int idx2) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void setAtomBookmark(Atom *at, int mark)
associates an Atom pointer with a bookmark
Definition: ROMol.h:481
const std::vector< StereoGroup > & getStereoGroups() const
Gets a reference to the groups of atoms with relative stereochemistry.
Definition: ROMol.h:781
MatchingAtomIterator endMatchingAtoms()
get an AtomIterator pointing at the end of our Atoms
ConstBondIterator beginBonds() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
CXXAtomIterator< MolGraph, Atom * > atoms()
C++11 Range iterator.
Definition: ROMol.h:277
BondIterator endBonds()
get a BondIterator pointing at the end of our Bonds
ROMol(const std::string &binStr)
construct a molecule from a pickle string
Atom * getUniqueAtomWithBookmark(int mark)
QueryAtomIterator beginQueryAtoms(QueryAtom const *query)
get an AtomIterator pointing at our first Atom that matches query
ConstHeteroatomIterator endHeteros() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Atom * getAtomWithIdx(unsigned int idx)
returns a pointer to a particular Atom
Atom * getAtomWithBookmark(int mark)
returns the first Atom associated with the bookmark provided
CXXAtomIterator< const MolGraph, Atom *const > atoms() const
Definition: ROMol.h:279
void replaceAtomBookmark(Atom *at, int mark)
associates an Atom pointer with a bookmark
Definition: ROMol.h:485
CXXBondIterator< MolGraph, Bond *, MolGraph::out_edge_iterator > atomBonds(Atom const *at)
Definition: ROMol.h:301
unsigned int getAtomDegree(const Atom *at) const
returns the degree (number of neighbors) of an Atom in the graph
void setStereoGroups(std::vector< StereoGroup > stereo_groups)
Sets groups of atoms with relative stereochemistry.
AromaticAtomIterator endAromaticAtoms()
get an AtomIterator pointing at the end of our Atoms
void clearAllAtomBookmarks()
blows out all atomic bookmarks
Definition: ROMol.h:502
virtual ~ROMol()
Definition: ROMol.h:408
ConformerIterator beginConformers()
Definition: ROMol.h:734
ConstBondIterator endBonds() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
unsigned int getNumAtoms(bool onlyExplicit) const
CXXBondIterator< const MolGraph, Bond *const, MolGraph::out_edge_iterator > atomBonds(Atom const *at) const
Definition: ROMol.h:296
const Atom * operator[](const vertex_descriptor &v) const
Definition: ROMol.h:769
HeteroatomIterator endHeteros()
get an AtomIterator pointing at the end of our Atoms
ROMol(ROMol &&o) noexcept
Definition: ROMol.h:346
Bond * getBondBetweenAtoms(unsigned int idx1, unsigned int idx2)
returns a pointer to the bond between two atoms, Null on failure
ConstConformerIterator beginConformers() const
Definition: ROMol.h:738
void clearBondBookmark(int mark, const Bond *bond)
removes a particular Bond from the list associated with the bookmark
ROMol & operator=(ROMol &&o) noexcept
Definition: ROMol.h:370
Conformer & getConformer(int id=-1)
friend RDKIT_GRAPHMOL_EXPORT const std::vector< SubstanceGroup > & getSubstanceGroups(const ROMol &)
ATOM_BOOKMARK_MAP * getAtomBookmarks()
returns a pointer to all of our atom bookmarks
Definition: ROMol.h:506
MatchingAtomIterator beginMatchingAtoms(bool(*query)(Atom *))
get an AtomIterator pointing at our first Atom that matches query
CXXAtomIterator< const MolGraph, Atom *const, MolGraph::adjacency_iterator > atomNeighbors(Atom const *at) const
Definition: ROMol.h:284
bool hasBondBookmark(int mark) const
queries whether or not any bonds are associated with a bookmark
Definition: ROMol.h:527
Bond * operator[](const edge_descriptor &e)
Definition: ROMol.h:773
CXXAtomIterator< MolGraph, Atom *, MolGraph::adjacency_iterator > atomNeighbors(Atom const *at)
Definition: ROMol.h:289
AtomIterator beginAtoms()
get an AtomIterator pointing at our first Atom
Bond * getUniqueBondWithBookmark(int mark)
void removeConformer(unsigned int id)
Delete the conformation with the specified ID.
AromaticAtomIterator beginAromaticAtoms()
get an AtomIterator pointing at our first aromatic Atom
ConstHeteroatomIterator beginHeteros() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
const Conformer & getConformer(int id=-1) const
ConformerIterator endConformers()
Definition: ROMol.h:736
ATOM_ITER_PAIR getVertices() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void clearBondBookmark(int mark)
removes a bookmark from our collection
HeteroatomIterator beginHeteros()
get an AtomIterator pointing at our first hetero Atom
const Atom * getAtomWithIdx(unsigned int idx) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
RWMol is a molecule class that is intended to be edited.
Definition: RWMol.h:32
A class to store information about a molecule's rings.
Definition: RingInfo.h:28
#define RDKIT_GRAPHMOL_EXPORT
Definition: export.h:225
Std stuff.
Definition: Abbreviations.h:19
std::vector< ROMol > MOL_VECT
Definition: ROMol.h:866
MOL_PTR_VECT::const_iterator MOL_PTR_VECT_CI
Definition: ROMol.h:871
RDKIT_GRAPHMOL_EXPORT const int ci_RIGHTMOST_ATOM
RDKIT_GRAPHMOL_EXPORT const int ci_ATOM_HOLDER
std::vector< ROMol * > MOL_PTR_VECT
Definition: ROMol.h:868
boost::shared_ptr< ROMol > ROMOL_SPTR
MOL_PTR_VECT::iterator MOL_PTR_VECT_I
Definition: ROMol.h:872
boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, Atom *, Bond * > MolGraph
This is the BGL type used to store the topology:
Definition: ROMol.h:51
std::vector< boost::shared_ptr< ROMol > > MOL_SPTR_VECT
Definition: FragCatParams.h:20
RDKIT_GRAPHMOL_EXPORT const int ci_LEADING_BOND
std::forward_iterator_tag iterator_category
Definition: ROMol.h:120
std::ptrdiff_t difference_type
Definition: ROMol.h:121
bool operator==(const CXXAtomIter &it) const
Definition: ROMol.h:141
CXXAtomIter(Graph *graph, Iterator pos)
Definition: ROMol.h:130
bool operator!=(const CXXAtomIter &it) const
Definition: ROMol.h:142
CXXAtomIter end()
Definition: ROMol.h:153
CXXAtomIterator(Graph *graph, Iterator start, Iterator end)
Definition: ROMol.h:150
CXXAtomIterator(Graph *graph)
Definition: ROMol.h:145
CXXAtomIter begin()
Definition: ROMol.h:152
std::forward_iterator_tag iterator_category
Definition: ROMol.h:163
CXXBondIter(Graph *graph, Iterator pos)
Definition: ROMol.h:173
bool operator==(const CXXBondIter &it) const
Definition: ROMol.h:184
std::ptrdiff_t difference_type
Definition: ROMol.h:164
bool operator!=(const CXXBondIter &it) const
Definition: ROMol.h:185
CXXBondIter begin()
Definition: ROMol.h:195
CXXBondIterator(Graph *graph)
Definition: ROMol.h:188
CXXBondIterator(Graph *graph, Iterator start, Iterator end)
Definition: ROMol.h:193
CXXBondIter end()
Definition: ROMol.h:196