RDKit
Open-source cheminformatics and machine learning.
Resonance.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2015 Paolo Tosco
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 #include <RDGeneral/export.h>
11 #ifndef _RESONANCE_H__
12 #define _RESONANCE_H__
13 
14 #include <vector>
15 #include <stack>
16 #include <map>
17 #include <unordered_map>
18 
19 namespace RDKit {
20 class ROMol;
21 class Atom;
22 class Bond;
23 class BondElectrons;
24 class AtomElectrons;
25 class ConjElectrons;
26 class CEVect2;
27 typedef std::map<unsigned int, BondElectrons *> ConjBondMap;
28 typedef std::map<unsigned int, AtomElectrons *> ConjAtomMap;
29 typedef std::vector<ConjElectrons *> CEVect;
30 typedef std::vector<CEVect2 *> CEVect3;
31 typedef std::vector<std::uint8_t> ConjFP;
32 typedef std::unordered_map<std::size_t, ConjElectrons *> CEMap;
33 
34 /*!
35  * Create a derived class from this abstract base class
36  * and implement the operator()() method.
37  * The operator()() method is called at each iteration of the
38  * algorithm, and provides a mechanism to monitor or stop
39  * its progress.
40  * To have your callback called, pass an instance of your
41  * derived class to ResonanceMolSupplier::setProgressCallback().
42  */
44  friend class ResonanceMolSupplier;
45 
46  public:
49  /*! Get the number of conjugated groups this molecule has. */
50  unsigned int getNumConjGrps() const { return d_progress.size(); }
51  /*! Get the maximum number of resonance structures the supplier
52  is allowed to generate.
53  \return The number of structures.
54  */
55  size_t getMaxStructures() const { return d_maxStructs; }
56  /*! Get the number of resonance structures generated so far
57  for a certain conjugated group.
58  \param conjGrpIdx the conjugated group index.
59  \return the number of resonance structures generated so far
60  for this group.
61  */
62  size_t getNumStructures(unsigned int conjGrpIdx) const;
63  /*! Get the number of resonance structures with a different score
64  (i.e., non-degenerate) generated so far for a certain conjugated
65  group.
66  \param conjGrpIdx the conjugated group index.
67  \return the number of non-degenrate resonance structures generated
68  so far for this group.
69  */
70  size_t getNumDiverseStructures(unsigned int conjGrpIdx) const;
71  /*! Pure virtual; this must be implemented in the derived class.
72  \return true if the resonance structure generation should continue;
73  false if the resonance structure generation should stop.
74  */
75  virtual bool operator()() = 0;
76 
77  private:
78  struct ResonanceProgress {
79  size_t d_totalStructs;
80  size_t d_diverseStructs;
81  };
82  size_t d_maxStructs{0};
83  std::vector<ResonanceProgress> d_progress;
84 };
85 
87  public:
88  typedef enum {
89  /*! include resonance structures whose octets are less complete
90  * than the most octet-complete structure */
91  ALLOW_INCOMPLETE_OCTETS = (1 << 0),
92  /*! include resonance structures featuring charge separation also
93  * when uncharged resonance structures exist */
94  ALLOW_CHARGE_SEPARATION = (1 << 1),
95  /*! enumerate all possible degenerate Kekule resonance structures
96  * (the default is to include just one) */
97  KEKULE_ALL = (1 << 2),
98  /*! if the UNCONSTRAINED_CATIONS flag is not set, positively
99  * charged atoms left and right of N with an incomplete octet are
100  * acceptable only if the conjugated group has a positive total
101  * formal charge.
102  * UNCONSTRAINED_CATIONS implies ALLOW_INCOMPLETE_OCTETS
103  * and ALLOW_CHARGE_SEPARATION.
104  */
105  UNCONSTRAINED_CATIONS = (1 << 3),
106  /*! if the UNCONSTRAINED_ANIONS flag is not set, negatively
107  * charged atoms left of N are acceptable only if the conjugated
108  * group has a negative total formal charge.
109  * UNCONSTRAINED_ANIONS implies ALLOW_CHARGE_SEPARATION.
110  */
111  UNCONSTRAINED_ANIONS = (1 << 4)
112  } ResonanceFlags;
113  /*!
114  * \param mol - the starter molecule
115  * \param flags - flags which influence criteria to generate
116  * resonance structures
117  * \param maxStructs - maximum number of complete resonance
118  * structures generated
119  * \param numThreads - the number of threads used to carry out the
120  * resonance structure enumeration (defaults
121  * to 1; 0 selects the number of concurrent
122  * threads supported by the hardware; negative
123  * values are added to the number of
124  * concurrent threads supported by the
125  * hardware)
126  */
127  ResonanceMolSupplier(ROMol &mol, unsigned int flags = 0,
128  unsigned int maxStructs = 1000);
130  /*! Returns a reference to the Kekulized form of the ROMol the
131  * ResonanceMolSupplier was initialized with */
132  const ROMol &mol() const { return *d_mol; }
133  /*! Returns the flags the ResonanceMolSupplier was initialized with
134  */
135  unsigned int flags() const { return d_flags; }
136  /*! Returns the number of individual conjugated groups
137  in the molecule */
138  unsigned int getNumConjGrps() const { return d_nConjGrp; }
139  /*! Given a bond index, it returns the index of the conjugated
140  * group the bond belongs to, or -1 if it is not conjugated */
141  int getBondConjGrpIdx(unsigned int bi) const;
142  /*! Given an atom index, it returns the index of the conjugated
143  * group the atom belongs to, or -1 if it is not conjugated */
144  int getAtomConjGrpIdx(unsigned int ai) const;
145  /*! Sets the number of threads to be used to enumerate resonance
146  * structures (defaults to 1; 0 selects the number of concurrent
147  * threads supported by the hardware; negative values are added
148  * to the number of concurrent threads supported by the hardware)
149  */
150  void setNumThreads(int numThreads = 1);
151  /*! Pass a pointer to an instance of a class derived from
152  * ResonanceMolSupplierCallback, which must implement the callback()
153  * method. The ResonanceMolSupplier takes ownership of the pointer,
154  * which must not be deleted.
155  */
157  /*! Get the pointer to the ResonanceMolSupplierCallback subclass
158  * instance (do not delete it, has the ResonanceMolSupplier takes
159  * ownership of the pointer), or nullptr if none was set.
160  */
162  return d_callback.get();
163  }
164  /*! Returns true if the resonance structure generation was canceled
165  * before completion due to the ResMolSupplierProgressCallback
166  * having returned false.
167  */
168  bool wasCanceled() const { return d_wasCanceled; }
169  /*! Ask ResonanceMolSupplier to enumerate resonance structures
170  * (automatically done as soon as any attempt to access them is
171  * made) */
172  void enumerate();
173  /*! Returns true if resonance structure enumeration has already
174  * happened */
175  bool getIsEnumerated() { return d_isEnumerated; }
176  /*! Returns the number of resonance structures in the
177  * ResonanceMolSupplier */
178  unsigned int length();
179  /*! Resets the ResonanceMolSupplier index */
180  void reset();
181  /*! Returns true if there are no more resonance structures left */
182  bool atEnd();
183  /*! Returns a pointer to the next resonance structure as a ROMol,
184  * or NULL if there are no more resonance structures left.
185  * The caller is responsible for freeing memory associated to
186  * the pointer */
188  /*! Sets the ResonanceMolSupplier index to idx */
189  void moveTo(unsigned int idx);
190  /*! Returns a pointer to the resonance structure with index idx as
191  * a ROMol. The index generates complete resonance structures by
192  * combining ConjElectrons objects for the respective conjugated
193  * groups in a breadth-first fashion, in order to return the most
194  * stable complete resonance structures first.
195  * The caller is responsible for freeing memory associated to
196  * the pointer */
197  ROMol *operator[](unsigned int idx);
198 
199  private:
200  typedef struct CEPerm {
201  unsigned int idx;
202  std::vector<unsigned int> v;
203  } CEPerm;
204  unsigned int d_nConjGrp;
205  unsigned int d_length;
206  unsigned int d_flags;
207  unsigned int d_maxStructs;
208  unsigned int d_idx;
209  unsigned int d_numThreads;
210  bool d_isEnumerated;
211  bool d_wasCanceled;
212  CEVect3 d_ceVect3;
213  const ROMol *d_mol;
214  std::vector<int> d_bondConjGrpIdx;
215  std::vector<int> d_atomConjGrpIdx;
216  std::vector<size_t> d_enumIdx;
217  std::unique_ptr<ResonanceMolSupplierCallback> d_callback;
218  // disable copy constructor and assignment operator
220  ResonanceMolSupplier &operator=(const ResonanceMolSupplier &);
221  void mainLoop(unsigned int ti, unsigned int nt);
222  void assignConjGrpIdx();
223  void resizeCeVect();
224  void trimCeVect2();
225  void prepEnumIdxVect();
226  void idxToCEPerm(size_t idx, std::vector<unsigned int> &c) const;
227  void setResonanceMolSupplierLength();
228  void buildCEMap(CEMap &ceMap, unsigned int conjGrpIdx);
229  void storeCEMap(const CEMap &ceMap, unsigned int conjGrpIdx);
230  void assignBondsFormalChargesHelper(ROMol &mol,
231  std::vector<unsigned int> &c) const;
232  ROMol *assignBondsFormalCharges(std::vector<unsigned int> &c) const;
233  static bool cePermCompare(const CEPerm *a, const CEPerm *b);
234 };
235 } // namespace RDKit
236 #endif
size_t getNumDiverseStructures(unsigned int conjGrpIdx) const
size_t getNumStructures(unsigned int conjGrpIdx) const
unsigned int getNumConjGrps() const
Definition: Resonance.h:50
const ROMol & mol() const
Definition: Resonance.h:132
ResonanceMolSupplier(ROMol &mol, unsigned int flags=0, unsigned int maxStructs=1000)
void setProgressCallback(ResonanceMolSupplierCallback *callback)
ResonanceMolSupplierCallback * getProgressCallback() const
Definition: Resonance.h:161
int getAtomConjGrpIdx(unsigned int ai) const
ROMol * operator[](unsigned int idx)
void setNumThreads(int numThreads=1)
unsigned int flags() const
Definition: Resonance.h:135
unsigned int getNumConjGrps() const
Definition: Resonance.h:138
int getBondConjGrpIdx(unsigned int bi) const
void moveTo(unsigned int idx)
#define RDKIT_GRAPHMOL_EXPORT
Definition: export.h:217
Std stuff.
Definition: Abbreviations.h:18
std::vector< CEVect2 * > CEVect3
Definition: Resonance.h:30
std::unordered_map< std::size_t, ConjElectrons * > CEMap
Definition: Resonance.h:32
std::vector< std::uint8_t > ConjFP
Definition: Resonance.h:31
std::vector< ConjElectrons * > CEVect
Definition: Resonance.h:29
std::map< unsigned int, AtomElectrons * > ConjAtomMap
Definition: Resonance.h:28
std::map< unsigned int, BondElectrons * > ConjBondMap
Definition: Resonance.h:26