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