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