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 #ifndef _RESONANCE_H__
11 #define _RESONANCE_H__
12 
13 #include <vector>
14 #include <stack>
15 #include <map>
16 #include <boost/unordered_map.hpp>
17 
18 namespace RDKit {
19 class ROMol;
20 class Atom;
21 class Bond;
22 class BondElectrons;
23 class AtomElectrons;
24 class ConjElectrons;
25 class CEVect2;
26 typedef std::map<unsigned int, BondElectrons *> ConjBondMap;
27 typedef std::map<unsigned int, AtomElectrons *> ConjAtomMap;
28 typedef std::vector<ConjElectrons *> CEVect;
29 typedef std::vector<CEVect2 *> CEVect3;
30 typedef std::vector<boost::uint8_t> ConjFP;
31 typedef boost::unordered_map<std::size_t, ConjElectrons *> CEMap;
33  public:
34  typedef enum {
35  /*! include resonance structures whose octets are less complete
36  * than the the most octet-complete structure */
38  /*! include resonance structures featuring charge separation also
39  * when uncharged resonance structures exist */
41  /*! enumerate all possible degenerate Kekule resonance structures
42  * (the default is to include just one) */
43  KEKULE_ALL = (1 << 2),
44  /*! if the UNCONSTRAINED_CATIONS flag is not set, positively
45  * charged atoms left and right of N with an incomplete octet are
46  * acceptable only if the conjugated group has a positive total
47  * formal charge */
49  /*! if the UNCONSTRAINED_ANIONS flag is not set, negatively
50  * charged atoms left of N are acceptable only if the conjugated
51  * group has a negative total formal charge */
54  /*!
55  * \param mol - the starter molecule
56  * \param flags - flags which influence criteria to generate
57  * resonance structures
58  * \param maxStructs - maximum number of complete resonance
59  * structures generated
60  * \param numThreads - the number of threads used to carry out the
61  * resonance structure enumeration (defaults
62  * to 1; 0 selects the number of concurrent
63  * threads supported by the hardware; negative
64  * values are added to the number of
65  * concurrent threads supported by the
66  * hardware)
67  */
68  ResonanceMolSupplier(ROMol &mol, unsigned int flags = 0,
69  unsigned int maxStructs = 1000);
71  /*! Returns a reference to the Kekulized form of the ROMol the
72  * ResonanceMolSupplier was initialized with */
73  const ROMol &mol() const { return *d_mol; }
74  /*! Returns the flags the ResonanceMolSupplier was initialized with
75  */
76  unsigned int flags() const { return d_flags; }
77  /*! Returns the number of individual conjugated groups
78  in the molecule */
79  unsigned int getNumConjGrps() const { return d_nConjGrp; };
80  /*! Given a bond index, it returns the index of the conjugated
81  * group the bond belongs to, or -1 if it is not conjugated */
82  int getBondConjGrpIdx(unsigned int bi) const;
83  /*! Given an atom index, it returns the index of the conjugated
84  * group the atom belongs to, or -1 if it is not conjugated */
85  int getAtomConjGrpIdx(unsigned int ai) const;
86  /*! Sets the number of threads to be used to enumerate resonance
87  * structures (defaults to 1; 0 selects the number of concurrent
88  * threads supported by the hardware; negative values are added
89  * to the number of concurrent threads supported by the hardware)
90  */
91  void setNumThreads(int numThreads = 1);
92  /*! Ask ResonanceMolSupplier to enumerate resonance structures
93  * (automatically done as soon as any attempt to access them is
94  * made) */
95  void enumerate();
96  /*! Returns true if resonance structure enumeration has already
97  * happened */
98  bool getIsEnumerated() { return d_isEnumerated; };
99  /*! Returns the number of resonance structures in the
100  * ResonanceMolSupplier */
101  unsigned int length();
102  /*! Resets the ResonanceMolSupplier index */
103  void reset();
104  /*! Returns true if there are no more resonance structures left */
105  bool atEnd();
106  /*! Returns a pointer to the next resonance structure as a ROMol,
107  * or NULL if there are no more resonance structures left.
108  * The caller is responsible for freeing memory associated to
109  * the pointer */
110  ROMol *next();
111  /*! Sets the ResonanceMolSupplier index to idx */
112  void moveTo(unsigned int idx);
113  /*! Returns a pointer to the resonance structure with index idx as
114  * a ROMol. The index generates complete resonance structures by
115  * combining ConjElectrons objects for the respective conjugated
116  * groups in a breadth-first fashion, in order to return the most
117  * stable complete resonance structures first.
118  * The caller is responsible for freeing memory associated to
119  * the pointer */
120  ROMol *operator[](unsigned int idx);
121 
122  private:
123  typedef struct CEPerm {
124  unsigned int idx;
125  std::vector<unsigned int> v;
126  } CEPerm;
127  unsigned int d_nConjGrp;
128  unsigned int d_length;
129  unsigned int d_flags;
130  unsigned int d_maxStructs;
131  unsigned int d_idx;
132  unsigned int d_numThreads;
133  bool d_isEnumerated;
134  CEVect3 d_ceVect3;
135  void buildCEMap(CEMap &ceMap, unsigned int conjGrpIdx);
136  const ROMol *d_mol;
137  std::vector<int> d_bondConjGrpIdx;
138  std::vector<int> d_atomConjGrpIdx;
139  std::vector<unsigned int> d_enumIdx;
140  // disable copy constructor and assignment operator
142  ResonanceMolSupplier &operator=(const ResonanceMolSupplier &);
143  void mainLoop(unsigned int ti, unsigned int nt);
144  void assignConjGrpIdx();
145  void resizeCeVect();
146  void trimCeVect2();
147  void prepEnumIdxVect();
148  void idxToCEPerm(unsigned int idx, std::vector<unsigned int> &c) const;
149  void setResonanceMolSupplierLength();
150  void storeCEMap(CEMap &ceMap, unsigned int conjGrpIdx);
151  void enumerateNbArrangements(CEMap &ceMap, CEMap &ceMapTmp);
152  void pruneStructures(CEMap &ceMap);
153  void assignBondsFormalChargesHelper(ROMol &mol,
154  std::vector<unsigned int> &c) const;
155  ROMol *assignBondsFormalCharges(std::vector<unsigned int> &c) const;
156  static bool cePermCompare(const CEPerm *a, const CEPerm *b);
157 };
158 }
159 #endif
ResonanceMolSupplier(ROMol &mol, unsigned int flags=0, unsigned int maxStructs=1000)
int getAtomConjGrpIdx(unsigned int ai) const
unsigned int flags() const
Definition: Resonance.h:76
void setNumThreads(int numThreads=1)
unsigned int getNumConjGrps() const
Definition: Resonance.h:79
std::vector< boost::uint8_t > ConjFP
Definition: Resonance.h:30
std::map< unsigned int, AtomElectrons * > ConjAtomMap
Definition: Resonance.h:27
ROMol * operator[](unsigned int idx)
void moveTo(unsigned int idx)
std::vector< CEVect2 * > CEVect3
Definition: Resonance.h:29
boost::unordered_map< std::size_t, ConjElectrons * > CEMap
Definition: Resonance.h:31
const ROMol & mol() const
Definition: Resonance.h:73
ROMol is a molecule class that is intended to have a fixed topology.
Definition: ROMol.h:103
std::vector< ConjElectrons * > CEVect
Definition: Resonance.h:28
int getBondConjGrpIdx(unsigned int bi) const
Includes a bunch of functionality for handling Atom and Bond queries.
Definition: Atom.h:29
std::map< unsigned int, BondElectrons * > ConjBondMap
Definition: Resonance.h:25