Files
rdkit/Code/GraphMol/GeneralizedSubstruct/XQMol.cpp
Gareth Jones 31de6b09fb Added fingerprints to GeneralizedSubstruct search and extended SWIG wrappers (#6991)
* Added fingerprints to GeneralizedSubstruct search

* Small change to fire tests

* Edits from code review

* Updated swig - newobject not required for GeneralizedSubstruct fingerprint methods

* GeneralizedSubstruct only supports unique_ptr in SWIG4.1
2023-12-19 04:44:06 +01:00

202 lines
6.7 KiB
C++

//
// Copyright (c) 2023, Greg Landrum and other RDKit contributors
//
// @@ 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 <cstdint>
#include <variant>
#include <sstream>
#include <GraphMol/RDKitBase.h>
#include <GraphMol/MolPickler.h>
#include <GraphMol/MolBundle.h>
#include <GraphMol/MolEnumerator/MolEnumerator.h>
#include "XQMol.h"
#include "GraphMol/Fingerprints/Fingerprints.h"
namespace RDKit {
namespace GeneralizedSubstruct {
ExtendedQueryMol::ExtendedQueryMol(const std::string &text, bool isJSON) {
if (!isJSON) {
initFromBinary(text);
} else {
initFromJSON(text);
}
}
void ExtendedQueryMol::initFromOther(const ExtendedQueryMol &other) {
if (std::holds_alternative<ExtendedQueryMol::RWMol_T>(other.xqmol)) {
xqmol = std::make_unique<RWMol>(
*std::get<ExtendedQueryMol::RWMol_T>(other.xqmol));
} else if (std::holds_alternative<ExtendedQueryMol::MolBundle_T>(
other.xqmol)) {
xqmol = std::make_unique<MolBundle>(
*std::get<ExtendedQueryMol::MolBundle_T>(other.xqmol));
} else if (std::holds_alternative<ExtendedQueryMol::TautomerQuery_T>(
other.xqmol)) {
xqmol = std::make_unique<TautomerQuery>(
*std::get<ExtendedQueryMol::TautomerQuery_T>(other.xqmol));
} else if (std::holds_alternative<ExtendedQueryMol::TautomerBundle_T>(
other.xqmol)) {
auto tb = std::make_unique<std::vector<std::unique_ptr<TautomerQuery>>>();
for (const auto &tqp :
*std::get<ExtendedQueryMol::TautomerBundle_T>(other.xqmol)) {
tb->emplace_back(std::make_unique<TautomerQuery>(*tqp));
}
xqmol = std::move(tb);
}
}
std::unique_ptr<ExplicitBitVect> ExtendedQueryMol::patternFingerprintQuery(
unsigned fpSize) const {
if (std::holds_alternative<RWMol_T>(xqmol)) {
const auto raw = PatternFingerprintMol(*std::get<RWMol_T>(xqmol), fpSize, nullptr,
nullptr, true);
std::unique_ptr<ExplicitBitVect> ptr(raw);
return ptr;
} if (std::holds_alternative<MolBundle_T>(xqmol)) {
const auto raw = PatternFingerprintMol(*std::get<MolBundle_T>(xqmol), fpSize, nullptr,
true);
std::unique_ptr<ExplicitBitVect> ptr(raw);
return ptr;
} if (std::holds_alternative<TautomerQuery_T>(xqmol)) {
const auto raw = std::get<TautomerQuery_T>(xqmol)->patternFingerprintTemplate(fpSize);
std::unique_ptr<ExplicitBitVect> ptr(raw);
return ptr;
} if (std::holds_alternative<TautomerBundle_T>(xqmol)) {
const auto &tautomerBundle = std::get<TautomerBundle_T>(xqmol);
ExplicitBitVect *res = nullptr;
for (const auto &tautomer : *tautomerBundle) {
const auto molfp = tautomer->patternFingerprintTemplate(fpSize);
if (!res) {
res = molfp;
} else {
*res &= *molfp;
delete molfp;
}
}
std::unique_ptr<ExplicitBitVect> ptr(res);
return ptr;
}
throw std::invalid_argument("Unknown extended query molecule type");
}
std::vector<MatchVectType> SubstructMatch(
const ROMol &mol, const ExtendedQueryMol &query,
const SubstructMatchParameters &params) {
std::vector<MatchVectType> res;
if (std::holds_alternative<ExtendedQueryMol::RWMol_T>(query.xqmol)) {
res = RDKit::SubstructMatch(
mol, *std::get<ExtendedQueryMol::RWMol_T>(query.xqmol), params);
#ifdef RDK_USE_BOOST_SERIALIZATION
} else if (std::holds_alternative<ExtendedQueryMol::MolBundle_T>(
query.xqmol)) {
res = RDKit::SubstructMatch(
mol, *std::get<ExtendedQueryMol::MolBundle_T>(query.xqmol), params);
} else if (std::holds_alternative<ExtendedQueryMol::TautomerQuery_T>(
query.xqmol)) {
res = std::get<ExtendedQueryMol::TautomerQuery_T>(query.xqmol)
->substructOf(mol, params);
} else if (std::holds_alternative<ExtendedQueryMol::TautomerBundle_T>(
query.xqmol)) {
const auto &vect =
std::get<ExtendedQueryMol::TautomerBundle_T>(query.xqmol);
for (const auto &tq : *vect) {
res = tq->substructOf(mol, params);
if (!res.empty()) {
break;
}
}
#endif
} else {
UNDER_CONSTRUCTION("unrecognized type in ExtendedQueryMol");
}
return res;
}
ExtendedQueryMol createExtendedQueryMol(const RWMol &mol, bool doEnumeration,
bool doTautomers,
bool adjustQueryProperties,
MolOps::AdjustQueryParameters params) {
MolBundle bndl;
if (doEnumeration) {
bndl = MolEnumerator::enumerate(mol);
}
if (bndl.empty()) {
// nothing enumerated, just add the input molecule
bndl.addMol(boost::shared_ptr<ROMol>(new ROMol(mol)));
}
if (bndl.size() == 1) {
const ROMol *lmol = nullptr;
std::unique_ptr<ROMol> holder;
if (adjustQueryProperties) {
holder.reset(MolOps::adjustQueryProperties(*bndl.getMol(0), &params));
lmol = holder.get();
} else {
lmol = bndl.getMol(0).get();
}
if (doTautomers) {
auto tq = std::unique_ptr<TautomerQuery>(TautomerQuery::fromMol(*lmol));
if (tq->getTautomers().size() == 1) {
// no tautomers, just one molecule, return the molecule:
return {std::make_unique<RWMol>(*lmol)};
} else {
// return the tautomers
return {std::move(tq)};
}
} else {
return {std::make_unique<RWMol>(*lmol)};
}
} else {
MolBundle lbndl;
for (auto &bmol : bndl.getMols()) {
if (adjustQueryProperties) {
boost::shared_ptr<ROMol> lmol(
MolOps::adjustQueryProperties(*bmol, &params));
lbndl.addMol(lmol);
} else {
lbndl.addMol(bmol);
}
}
bool hadTautomers = false;
auto tautomerBundle =
std::make_unique<std::vector<std::unique_ptr<TautomerQuery>>>(0);
if (doTautomers) {
for (const auto &bmol : lbndl.getMols()) {
auto tq = std::unique_ptr<TautomerQuery>(TautomerQuery::fromMol(*bmol));
if (tq->getTautomers().size() > 1) {
hadTautomers = true;
}
tautomerBundle->emplace_back(std::move(tq));
}
}
if (!hadTautomers) {
// no tautomers, just return the bundle
return {std::make_unique<MolBundle>(lbndl)};
} else {
// return the tautomer bundle
return {std::move(tautomerBundle)};
}
}
}
std::unique_ptr<ExplicitBitVect> patternFingerprintTargetMol(
const ROMol& mol, unsigned fpSize) {
const auto raw= PatternFingerprintMol(mol, fpSize, nullptr, nullptr, true);
std::unique_ptr<ExplicitBitVect> ptr(raw);
return ptr;
}
} // namespace GeneralizedSubstruct
} // namespace RDKit