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