RDKit
Open-source cheminformatics and machine learning.
RingMatchTableSet.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2014 Novartis Institutes for BioMedical Research
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 #include <list>
12 #include <algorithm>
13 #include <cmath>
14 #include "SubstructMatchCustom.h"
15 
16 namespace RDKit {
17 namespace FMCS {
19  class RingMatchTable {
20  FMCS::MatchTable MatchMatrix;
21  std::map<const INT_VECT*, unsigned> RingIndex;
22 
23  public:
24  inline void clear() {
25  MatchMatrix.clear();
26  RingIndex.clear();
27  }
28  inline void resize(unsigned s1, unsigned s2) {
29  MatchMatrix.resize(s1, s2);
30  for (size_t i = 0; i < s1; i++) {
31  for (size_t j = 0; j < s2; j++) {
32  MatchMatrix.set(i, j, false);
33  }
34  }
35  }
36  inline void makeRingIndex(const ROMol* mol2) {
37  unsigned i = 0;
38  // for each TARGET ring
39  const RingInfo::VECT_INT_VECT& rings2 = mol2->getRingInfo()->bondRings();
40  for (RingInfo::VECT_INT_VECT::const_iterator r2 = rings2.begin();
41  r2 != rings2.end(); r2++) {
42  RingIndex[&*r2] = i++;
43  }
44  }
45  inline bool isEqual(unsigned i, const INT_VECT* r2) const {
46  return MatchMatrix.at(i, getRingIndex(r2));
47  }
48  inline void setMatch(unsigned i, const INT_VECT* r2) {
49  MatchMatrix.set(i, getRingIndex(r2), true);
50  }
51 
52  private:
53  inline unsigned getRingIndex(const INT_VECT* r2) const {
54  std::map<const INT_VECT*, unsigned>::const_iterator j =
55  RingIndex.find(r2);
56  if (RingIndex.end() == j) {
57  throw -1;
58  }
59  return j->second;
60  }
61  };
62 
63  private:
64  std::vector<std::vector<size_t>>* QueryBondRingsIndeces{nullptr};
65  std::map<const ROMol*, std::vector<std::vector<size_t>>>
66  TargetBondRingsIndecesSet; // by target molecules
67 
68  std::map<const ROMol*, RingMatchTable> MatchMatrixSet; // by target molecules
69  std::map<const INT_VECT*, unsigned> QueryRingIndex;
70 
71  public:
73 
74  inline void clear() {
75  if (QueryBondRingsIndeces) {
76  QueryBondRingsIndeces->clear();
77  }
78  TargetBondRingsIndecesSet.clear();
79  MatchMatrixSet.clear();
80  QueryRingIndex.clear();
81  }
82 
83  inline bool isQueryBondInRing(unsigned bi) const {
84  return (*QueryBondRingsIndeces)[bi].empty();
85  }
86  inline const std::vector<size_t>& getQueryBondRings(unsigned bi) const {
87  return (*QueryBondRingsIndeces)[bi];
88  }
89 
90  inline bool isTargetBondInRing(const ROMol* target, unsigned bi) const {
91  std::map<const ROMol*, std::vector<std::vector<size_t>>>::const_iterator i =
92  TargetBondRingsIndecesSet.find(target);
93  if (TargetBondRingsIndecesSet.end() == i) {
94  throw -1; // never
95  }
96  return i->second[bi].empty();
97  }
98  inline const std::vector<size_t>& getTargetBondRings(const ROMol* target,
99  unsigned bi) const {
100  std::map<const ROMol*, std::vector<std::vector<size_t>>>::const_iterator i =
101  TargetBondRingsIndecesSet.find(target);
102  if (TargetBondRingsIndecesSet.end() == i) {
103  throw -1; // never
104  }
105  return i->second[bi];
106  }
107 
108  inline bool isEqual(const INT_VECT* r1, const INT_VECT* r2,
109  const ROMol* mol2) const {
110  const RingMatchTable& m = getTargetMatchMatrix(mol2);
111  unsigned i = getQueryRingIndex(r1);
112  return m.isEqual(i, r2);
113  }
114 
115  void init(const ROMol* query) {
116  MatchMatrixSet.clear();
117  // fill out QueryRingIndex
118  unsigned i = 0;
119  const RingInfo::VECT_INT_VECT& rings = query->getRingInfo()->bondRings();
120  for (RingInfo::VECT_INT_VECT::const_iterator r = rings.begin();
121  r != rings.end(); r++) {
122  QueryRingIndex[&*r] = i++;
123  }
124  TargetBondRingsIndecesSet.clear();
125  QueryBondRingsIndeces = &TargetBondRingsIndecesSet[query];
126  QueryBondRingsIndeces->resize(query->getNumBonds());
127  size_t ri = 0;
128  for (RingInfo::VECT_INT_VECT::const_iterator r = rings.begin();
129  r != rings.end(); r++, ri++) {
130  for (INT_VECT::const_iterator bi = r->begin(); bi != r->end();
131  bi++) { // all bonds in the ring
132  (*QueryBondRingsIndeces)[*bi].push_back(ri);
133  }
134  }
135  }
136  inline void addTargetBondRingsIndeces(const ROMol* mol2) {
137  std::vector<std::vector<size_t>>& m = TargetBondRingsIndecesSet[mol2];
138  m.resize(mol2->getNumBonds());
139 
140  size_t ri = 0;
141  const RingInfo::VECT_INT_VECT& rings = mol2->getRingInfo()->bondRings();
142  for (RingInfo::VECT_INT_VECT::const_iterator r = rings.begin();
143  r != rings.end(); r++, ri++) {
144  for (INT_VECT::const_iterator bi = r->begin(); bi != r->end();
145  bi++) { // all bonds in the ring
146  m[*bi].push_back(ri);
147  }
148  }
149  }
150 
152  const ROMol* query, const ROMol* targetMolecule,
153  const MCSParameters& parameters) { // call it for all targets
154  const RingInfo::VECT_INT_VECT& rings1 = query->getRingInfo()->bondRings();
155  const RingInfo::VECT_INT_VECT& rings2 =
156  targetMolecule->getRingInfo()->bondRings();
157  RingMatchTable& m =
158  addTargetMatchMatrix(targetMolecule, rings1.size(), rings2.size());
159  unsigned i = 0;
160  // for each query ring
161  for (RingInfo::VECT_INT_VECT::const_iterator r1 = rings1.begin();
162  r1 != rings1.end(); r1++, i++) {
163  FMCS::Graph graph1;
164  makeRingGraph(graph1, *r1,
165  query); // for each query ring bond ADD all atoms and bonds
166 
167  // for each TARGET ring
168  for (RingInfo::VECT_INT_VECT::const_iterator r2 = rings2.begin();
169  r2 != rings2.end(); r2++) {
170  if (r1->size() != r2->size()) { // rings are different
171  continue;
172  }
173  FMCS::Graph graph2;
174  makeRingGraph(
175  graph2, *r2,
176  targetMolecule); // for each TAG ring bond ADD all atoms and bonds
177 
178  // check ring substruct match
180  bp.RingMatchesRingOnly = false;
181  bp.CompleteRingsOnly = false;
182  bool match =
183 #ifdef NEVER_xxx_PRECOMPUTED_TABLES_MATCH // not computed yet, because
184  // MatchTable computation uses this
185  // ring info table
186  FMCS::SubstructMatchCustomTable(graph2, graph1, tag->AtomMatchTable,
187  tag->BondMatchTable);
188 #else // noticeable slowly:
190  graph2, *targetMolecule, graph1, *query, parameters.AtomTyper,
191  parameters.BondTyper, nullptr, parameters.AtomCompareParameters,
192  bp, parameters.CompareFunctionsUserData);
193 #endif
194  if (match) {
195  m.setMatch(i, &*r2);
196  }
197  }
198  }
199  }
200 
201  private:
202  void makeRingGraph(FMCS::Graph& g, const INT_VECT& ring,
203  const ROMol* mol) const { // ADD all atoms and bonds
204  std::map<const Atom*, unsigned> atomMap;
205 
206  for (size_t i = 0; i < ring.size(); i++) {
207  const Bond* bond = mol->getBondWithIdx(ring[i]);
208  const Atom* atom1 = bond->getBeginAtom();
209  const Atom* atom2 = bond->getEndAtom();
210  unsigned j1 = NotSet;
211  unsigned j2 = NotSet;
212  std::map<const Atom*, unsigned>::const_iterator ai;
213  ai = atomMap.find(atom1);
214  if (atomMap.end() != ai) {
215  j1 = ai->second;
216  }
217  ai = atomMap.find(atom2);
218  if (atomMap.end() != ai) {
219  j2 = ai->second;
220  }
221  if (NotSet == j1) {
222  j1 = g.m_vertices.size();
223  atomMap[atom1] = j1;
224  g.addAtom(atom1->getIdx());
225  }
226  if (NotSet == j2) {
227  j2 = g.m_vertices.size();
228  atomMap[atom2] = j2;
229  g.addAtom(atom2->getIdx());
230  }
231  g.addBond(ring[i], j1, j2);
232  }
233  }
234 
235  inline unsigned getQueryRingIndex(const INT_VECT* r1) const {
236  std::map<const INT_VECT*, unsigned>::const_iterator i =
237  QueryRingIndex.find(r1);
238  if (QueryRingIndex.end() == i) {
239  throw -1; // never
240  }
241  return i->second;
242  }
243  inline const RingMatchTable& getTargetMatchMatrix(const ROMol* mol2) const {
244  std::map<const ROMol*, RingMatchTable>::const_iterator mi =
245  MatchMatrixSet.find(mol2);
246  if (MatchMatrixSet.end() == mi) {
247  throw -1; // never
248  }
249  return mi->second;
250  }
251 
252  inline RingMatchTable& addTargetMatchMatrix(const ROMol* mol2, unsigned s1,
253  unsigned s2) {
254  RingMatchTable& m = MatchMatrixSet[mol2];
255  m.resize(s1, s2);
256  m.makeRingIndex(mol2);
257  return m;
258  }
259 };
260 } // namespace FMCS
261 } // namespace RDKit
The class for representing atoms.
Definition: Atom.h:68
unsigned int getIdx() const
returns our index within the ROMol
Definition: Atom.h:143
class for representing a bond
Definition: Bond.h:47
Atom * getEndAtom() const
returns a pointer to our end Atom
Atom * getBeginAtom() const
returns a pointer to our begin Atom
void addBond(unsigned bond, unsigned beginAtom, unsigned endAtom)
Definition: Graph.h:35
void addAtom(unsigned atom)
Definition: Graph.h:31
void addTargetBondRingsIndeces(const ROMol *mol2)
void computeRingMatchTable(const ROMol *query, const ROMol *targetMolecule, const MCSParameters &parameters)
bool isTargetBondInRing(const ROMol *target, unsigned bi) const
bool isQueryBondInRing(unsigned bi) const
bool isEqual(const INT_VECT *r1, const INT_VECT *r2, const ROMol *mol2) const
void init(const ROMol *query)
const std::vector< size_t > & getTargetBondRings(const ROMol *target, unsigned bi) const
const std::vector< size_t > & getQueryBondRings(unsigned bi) const
unsigned int getNumBonds(bool onlyHeavy=1) const
returns our number of Bonds
Bond * getBondWithIdx(unsigned int idx)
returns a pointer to a particular Bond
RingInfo * getRingInfo() const
Definition: ROMol.h:569
const VECT_INT_VECT & bondRings() const
Definition: RingInfo.h:177
std::vector< INT_VECT > VECT_INT_VECT
Definition: RingInfo.h:35
#define RDKIT_FMCS_EXPORT
Definition: export.h:153
const unsigned int NotSet
RDKIT_FMCS_EXPORT bool SubstructMatchCustom(const FMCS::Graph &target, const ROMol &mol, const FMCS::Graph &query, const ROMol &querySrc, MCSAtomCompareFunction atomCompare, MCSBondCompareFunction bondCompare, MCSFinalMatchCheckFunction finalCompare, const MCSAtomCompareParameters &acp, const MCSBondCompareParameters &bcp, void *user_data, match_V_t *match=nullptr)
RDKIT_FMCS_EXPORT bool SubstructMatchCustomTable(const FMCS::Graph &target, const ROMol &target_mol, const FMCS::Graph &query, const ROMol &querySrc, const MatchTable &atomMatchTable, const MatchTable &bondMatchTable, const MCSParameters *parameters=nullptr, match_V_t *match=nullptr)
Std stuff.
Definition: Abbreviations.h:19
std::vector< int > INT_VECT
Definition: types.h:278
MCSAtomCompareFunction AtomTyper
Definition: FMCS.h:145
MCSBondCompareFunction BondTyper
Definition: FMCS.h:146
MCSAtomCompareParameters AtomCompareParameters
Definition: FMCS.h:143
void * CompareFunctionsUserData
Definition: FMCS.h:147
MCSBondCompareParameters BondCompareParameters
Definition: FMCS.h:144