RDKit
Open-source cheminformatics and machine learning.
Loading...
Searching...
No Matches
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>
15
16namespace RDKit {
17namespace 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:
189 FMCS::SubstructMatchCustom(
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
const std::vector< size_t > & getTargetBondRings(const ROMol *target, unsigned bi) const
const std::vector< size_t > & getQueryBondRings(unsigned bi) const
bool isEqual(const INT_VECT *r1, const INT_VECT *r2, const ROMol *mol2) const
void init(const ROMol *query)
unsigned int getNumBonds(bool onlyHeavy=1) const
returns our number of Bonds
RingInfo * getRingInfo() const
Definition: ROMol.h:569
Bond * getBondWithIdx(unsigned int idx)
returns a pointer to a particular Bond
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
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