// // 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 #include #include #include #include #include #include #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(other.xqmol)) { xqmol = std::make_unique( *std::get(other.xqmol)); } else if (std::holds_alternative( other.xqmol)) { xqmol = std::make_unique( *std::get(other.xqmol)); } else if (std::holds_alternative( other.xqmol)) { xqmol = std::make_unique( *std::get(other.xqmol)); } else if (std::holds_alternative( other.xqmol)) { auto tb = std::make_unique>>(); for (const auto &tqp : *std::get(other.xqmol)) { tb->emplace_back(std::make_unique(*tqp)); } xqmol = std::move(tb); } } std::unique_ptr ExtendedQueryMol::patternFingerprintQuery( unsigned fpSize) const { if (std::holds_alternative(xqmol)) { const auto raw = PatternFingerprintMol(*std::get(xqmol), fpSize, nullptr, nullptr, true); std::unique_ptr ptr(raw); return ptr; } if (std::holds_alternative(xqmol)) { const auto raw = PatternFingerprintMol(*std::get(xqmol), fpSize, nullptr, true); std::unique_ptr ptr(raw); return ptr; } if (std::holds_alternative(xqmol)) { const auto raw = std::get(xqmol)->patternFingerprintTemplate(fpSize); std::unique_ptr ptr(raw); return ptr; } if (std::holds_alternative(xqmol)) { const auto &tautomerBundle = std::get(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 ptr(res); return ptr; } throw std::invalid_argument("Unknown extended query molecule type"); } std::vector SubstructMatch( const ROMol &mol, const ExtendedQueryMol &query, const SubstructMatchParameters ¶ms) { std::vector res; if (std::holds_alternative(query.xqmol)) { res = RDKit::SubstructMatch( mol, *std::get(query.xqmol), params); #ifdef RDK_USE_BOOST_SERIALIZATION } else if (std::holds_alternative( query.xqmol)) { res = RDKit::SubstructMatch( mol, *std::get(query.xqmol), params); } else if (std::holds_alternative( query.xqmol)) { res = std::get(query.xqmol) ->substructOf(mol, params); } else if (std::holds_alternative( query.xqmol)) { const auto &vect = std::get(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(new ROMol(mol))); } if (bndl.size() == 1) { const ROMol *lmol = nullptr; std::unique_ptr holder; if (adjustQueryProperties) { holder.reset(MolOps::adjustQueryProperties(*bndl.getMol(0), ¶ms)); lmol = holder.get(); } else { lmol = bndl.getMol(0).get(); } if (doTautomers) { auto tq = std::unique_ptr(TautomerQuery::fromMol(*lmol)); if (tq->getTautomers().size() == 1) { // no tautomers, just one molecule, return the molecule: return {std::make_unique(*lmol)}; } else { // return the tautomers return {std::move(tq)}; } } else { return {std::make_unique(*lmol)}; } } else { MolBundle lbndl; for (auto &bmol : bndl.getMols()) { if (adjustQueryProperties) { boost::shared_ptr lmol( MolOps::adjustQueryProperties(*bmol, ¶ms)); lbndl.addMol(lmol); } else { lbndl.addMol(bmol); } } bool hadTautomers = false; auto tautomerBundle = std::make_unique>>(0); if (doTautomers) { for (const auto &bmol : lbndl.getMols()) { auto tq = std::unique_ptr(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(lbndl)}; } else { // return the tautomer bundle return {std::move(tautomerBundle)}; } } } std::unique_ptr patternFingerprintTargetMol(const ROMol &mol, unsigned fpSize) { const auto raw = PatternFingerprintMol(mol, fpSize, nullptr, nullptr, true); std::unique_ptr ptr(raw); return ptr; } } // namespace GeneralizedSubstruct } // namespace RDKit