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