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