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