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