Files
rdkit/Code/GraphMol/GeneralizedSubstruct/Wrap/rdGeneralizedSubstruct.cpp
Greg Landrum b325b3a9bb Support TautomerQuery and MolBundle queries in the cartridge (#6393)
* framework for extended query.

serialization works
to/from text doesn't work

* first pass at getting substructure search working

basic tests

improved error handling (try not to take down the server thread!)

* add serialization to MolBundle

* we really need to pickle mol properties

* basic support for molbundle

including substructure search

* tautomer and molbundle queries to JSON

* remove debug msg

* cleanup debug
initial index steps (not tested)

* remove indexing stuff since it wasn't working

will try to come back to that

* add xqm to update script

* add c++ testing for molbundle serialization

* add serialization of molbundles to python interface

* support expanding molbundles to arrays of tautomer queries

* edge cases

Signed-off-by: greg landrum <greg.landrum@gmail.com>

* change in response to review

* a bunch of updates

* make sure the mol props needed for XQMs are being serialized

* update update script

* fix binary string output from ExtendedQueryMols in python

* tautomer queries should serialize properties

* more testing never hurts

* combo of generic groups and generalized queries works

* Update Code/PgSQL/rdkit/adapter.cpp

Co-authored-by: Paolo Tosco <paolo.tosco.mail@gmail.com>

* Update Code/PgSQL/rdkit/adapter.cpp

Co-authored-by: Paolo Tosco <paolo.tosco.mail@gmail.com>

* Update Code/PgSQL/rdkit/adapter.cpp

Co-authored-by: Paolo Tosco <paolo.tosco.mail@gmail.com>

* Fix weird quotes?

---------

Signed-off-by: greg landrum <greg.landrum@gmail.com>
Co-authored-by: Paolo Tosco <paolo.tosco.mail@gmail.com>
2023-08-23 06:32:06 +02:00

147 lines
4.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 <RDBoost/python.h>
#include <GraphMol/GraphMol.h>
#include <RDBoost/Wrap.h>
#include <GraphMol/GeneralizedSubstruct/XQMol.h>
#include <GraphMol/Wrap/substructmethods.h>
namespace python = boost::python;
using namespace RDKit;
using namespace RDKit::GeneralizedSubstruct;
namespace {
python::object XQMolToBinary(const ExtendedQueryMol &self) {
std::string res;
{
NOGIL gil;
res = self.toBinary();
}
python::object retval = python::object(
python::handle<>(PyBytes_FromStringAndSize(res.c_str(), res.length())));
return retval;
}
bool hasSubstructHelper(const ROMol &mol, const ExtendedQueryMol &query,
SubstructMatchParameters *iparams) {
SubstructMatchParameters params;
if (iparams) {
params = *iparams;
}
bool res;
{
NOGIL gil;
res = hasSubstructMatch(mol, query, params);
}
return res;
}
PyObject *getSubstructHelper(const ROMol &mol, const ExtendedQueryMol &query,
SubstructMatchParameters *iparams) {
std::vector<MatchVectType> matches;
SubstructMatchParameters params;
if (iparams) {
params = *iparams;
}
{
NOGIL gil;
params.maxMatches = 1;
matches = SubstructMatch(mol, query, params);
}
if (matches.empty()) {
matches.push_back(MatchVectType());
}
return convertMatches(matches[0]);
}
PyObject *getSubstructsHelper(const ROMol &mol, const ExtendedQueryMol &query,
SubstructMatchParameters *iparams) {
std::vector<MatchVectType> matches;
SubstructMatchParameters params;
if (iparams) {
params = *iparams;
}
{
NOGIL gil;
matches = SubstructMatch(mol, query, params);
}
PyObject *res = PyTuple_New(matches.size());
for (auto idx = 0u; idx < matches.size(); idx++) {
PyTuple_SetItem(res, idx, convertMatches(matches[idx]));
}
return res;
}
ExtendedQueryMol *createExtendedQueryMolHelper(
const ROMol &mol, bool doEnumeration, bool doTautomers,
bool adjustQueryProperties, MolOps::AdjustQueryParameters *ps) {
MolOps::AdjustQueryParameters defaults;
if (!ps) {
ps = &defaults;
}
return new ExtendedQueryMol(std::move(createExtendedQueryMol(
mol, doEnumeration, doTautomers, adjustQueryProperties, *ps)));
}
} // namespace
BOOST_PYTHON_MODULE(rdGeneralizedSubstruct) {
python::scope().attr("__doc__") =
"Module containing functions for generalized substructure searching";
python::class_<ExtendedQueryMol, boost::noncopyable>(
"ExtendedQueryMol",
"Extended query molecule for use in generalized substructure searching.",
python::init<const std::string &, bool>(
(python::args("text"), python::args("isJSON") = false),
"constructor from either a binary string (from ToBinary()) or a JSON string."))
.def("InitFromBinary", &ExtendedQueryMol::initFromBinary)
.def("InitFromJSON", &ExtendedQueryMol::initFromJSON)
.def("ToBinary", XQMolToBinary)
.def("ToJSON", &ExtendedQueryMol::toJSON);
python::def(
"MolHasSubstructMatch", &hasSubstructHelper,
(python::arg("mol"), python::arg("query"),
python::arg("params") = python::object()),
"determines whether or not a molecule is a match to a generalized substructure query");
python::def(
"MolGetSubstructMatch", &getSubstructHelper,
(python::arg("mol"), python::arg("query"),
python::arg("params") = python::object()),
"returns first match (if any) of a molecule to a generalized substructure query");
python::def(
"MolGetSubstructMatches", &getSubstructsHelper,
(python::arg("mol"), python::arg("query"),
python::arg("params") = python::object()),
"returns all matches (if any) of a molecule to a generalized substructure query");
python::def("CreateExtendedQueryMol", createExtendedQueryMolHelper,
(python::arg("mol"), python::arg("doEnumeration") = true,
python::arg("doTautomers") = true,
python::arg("adjustQueryProperties") = false,
python::arg("adjustQueryParameters") = python::object()),
python::return_value_policy<python::manage_new_object>(),
R"DOC(Creates an ExtendedQueryMol from the input molecule
This takes a query molecule and, conceptually, performs the following steps to
produce an ExtendedQueryMol:
1. Enumerates features like Link Nodes and SRUs
2. Converts everything into TautomerQueries
3. Runs adjustQueryProperties()
Each step is optional
)DOC");
}