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
|
//
// 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 <RDGeneral/export.h>
#pragma once
#include <map>
#include <boost/dynamic_bitset.hpp>
#include "../RDKitBase.h"
// algorithm optimisation definitions
#include "DebugTrace.h"
#include "Graph.h"
#include "DuplicatedSeedCache.h"
#include "SubstructMatchCustom.h"
namespace RDKit {
namespace FMCS {
class MaximumCommonSubgraph;
struct TargetMatch;
// Reference to a fragment of source molecule
struct RDKIT_FMCS_EXPORT MolFragment {
std::vector<const Atom *> Atoms;
std::vector<const Bond *> Bonds;
// Full Query Molecule to Seed indices backward conversionmap
std::map<unsigned int, unsigned int> SeedAtomIdxMap;
};
struct RDKIT_FMCS_EXPORT NewBond {
// index in qmol of new bond scheduled to be added into
// seed. This is outgoing bond from SourceAtomIdx
unsigned int BondIdx{0};
// index in qmol of new atom scheduled to be
// added into seed. Another end of new bond
unsigned int NewAtomIdx{0};
// index in the seed. RING. "New" Atom on the another
// end of new bond if it already exists in the seed.
unsigned int EndAtomIdx{0};
// pointer to qmol's new atom scheduled to be
// added into seed. Another end of new bond
const Atom *NewAtom{nullptr};
NewBond()
{}
NewBond(unsigned int bond_idx, unsigned int new_atom, unsigned int to_atom,
const Atom *a)
: BondIdx(bond_idx),
NewAtomIdx(new_atom),
EndAtomIdx(to_atom),
NewAtom(a) {}
};
class RDKIT_FMCS_EXPORT Seed {
private:
boost::dynamic_bitset<> addNewBondsToSeed(const ROMol &qmol,
Seed &seed) const;
bool canAddAllNonFusedRingBondsConnectedToBond(
const Atom &srcAtom, const Bond &bond, MaximumCommonSubgraph &mcs) const;
void addNewBondFromAtom(const Atom &srcAtom, const Bond &bond) const;
// for multistage growing. all directly connected outgoing bonds
mutable std::vector<NewBond> NewBonds;
bool StoreAllDegenerateMCS = false;
public:
// this seed has been completely copied into list.
// postponed non-locked copy for MULTI_THREAD
bool CopyComplete{false};
// 0 new seed; -1 finished; n>0 in
// progress, exact stage of growing for SDF
mutable unsigned int GrowingStage{0};
// Reference to a fragment of source molecule
MolFragment MoleculeFragment;
// seed topology with references to source molecule
Graph Topology;
boost::dynamic_bitset<> ExcludedBonds;
// in this subgraph for improving performance of future growing
unsigned int LastAddedAtomsBeginIdx{0};
// in this subgraph for DEBUG ONLY
unsigned int LastAddedBondsBeginIdx{0};
unsigned int RemainingBonds{0};
unsigned int RemainingAtoms{0};
#ifdef DUP_SUBSTRUCT_CACHE
DuplicatedSeedCache::TKey DupCacheKey;
#endif
// for each target
std::vector<TargetMatch> MatchResult;
public:
Seed()
{}
void setMoleculeFragment(const Seed &src) {
MoleculeFragment = src.MoleculeFragment;
}
Seed &operator=(const Seed &src) {
NewBonds = src.NewBonds;
GrowingStage = src.GrowingStage;
MoleculeFragment = src.MoleculeFragment;
Topology = src.Topology;
ExcludedBonds = src.ExcludedBonds;
LastAddedAtomsBeginIdx = src.LastAddedAtomsBeginIdx;
LastAddedBondsBeginIdx = src.LastAddedBondsBeginIdx;
RemainingBonds = src.RemainingBonds;
RemainingAtoms = src.RemainingAtoms;
StoreAllDegenerateMCS = src.StoreAllDegenerateMCS;
#ifdef DUP_SUBSTRUCT_CACHE
DupCacheKey = src.DupCacheKey;
#endif
MatchResult = src.MatchResult;
CopyComplete = true; // LAST
return *this;
}
void createFromParent(const Seed *parent) {
MoleculeFragment = parent->MoleculeFragment;
Topology = parent->Topology;
ExcludedBonds = parent->ExcludedBonds;
RemainingBonds = parent->RemainingBonds;
RemainingAtoms = parent->RemainingAtoms;
StoreAllDegenerateMCS = parent->StoreAllDegenerateMCS;
#ifdef DUP_SUBSTRUCT_CACHE
DupCacheKey = parent->DupCacheKey;
#endif
LastAddedAtomsBeginIdx = getNumAtoms(); // previous size
LastAddedBondsBeginIdx = getNumBonds(); // previous size
GrowingStage = 0;
}
unsigned int getNumAtoms() const { return MoleculeFragment.Atoms.size(); }
unsigned int getNumBonds() const { return MoleculeFragment.Bonds.size(); }
void grow(MaximumCommonSubgraph &mcs) const;
bool canGrowBiggerThan(unsigned int maxBonds, unsigned int maxAtoms) const {
return RemainingBonds + getNumBonds() > maxBonds ||
(RemainingBonds + getNumBonds() == maxBonds &&
(RemainingAtoms + getNumAtoms() > maxAtoms ||
(StoreAllDegenerateMCS &&
RemainingAtoms + getNumAtoms() == maxAtoms)));
}
void computeRemainingSize(const ROMol &qmol);
unsigned int addAtom(const Atom *atom);
unsigned int addBond(const Bond *bond);
void fillNewBonds(const ROMol &qmol,
MaximumCommonSubgraph *mcs = nullptr) const;
void setStoreAllDegenerateMCS(bool value) { StoreAllDegenerateMCS = value; }
};
} // namespace FMCS
} // namespace RDKit
|