Files
rdkit/Code/GraphMol/Fingerprints/Wrap/FingerprintGeneratorWrapper.cpp

782 lines
32 KiB
C++

//
// Copyright (C) 2018-2025 Boran Adas 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/Wrap.h>
#include <string>
#include <boost/python.hpp>
#include <RDBoost/boost_numpy.h>
#include <numpy/npy_common.h>
#include <numpy/ndarrayobject.h>
#include <RDBoost/import_array.h>
#include <GraphMol/RDKitBase.h>
#include <GraphMol/Fingerprints/FingerprintGenerator.h>
#include <GraphMol/Fingerprints/Wrap/AtomPairWrapper.cpp>
#include <GraphMol/Fingerprints/Wrap/MorganWrapper.cpp>
#include <GraphMol/Fingerprints/Wrap/RDKitFPWrapper.cpp>
#include <GraphMol/Fingerprints/Wrap/TopologicalTorsionWrapper.cpp>
#include <cstdint>
#include <RDGeneral/RDThreads.h>
#ifdef RDK_BUILD_THREADSAFE_SSS
#include <thread>
#include <future>
#endif
namespace python = boost::python;
namespace np = boost::python::numpy;
namespace RDKit {
namespace FingerprintWrapper {
FingerprintGenerator<std::uint64_t> *generatorFromJSONHelper(
const std::string &jsonStr) {
return generatorFromJSON(jsonStr).release();
}
void convertPyArguments(
python::object py_fromAtoms, python::object py_ignoreAtoms,
python::object py_atomInvs, python::object py_bondInvs,
std::unique_ptr<std::vector<std::uint32_t>> &fromAtoms,
std::unique_ptr<std::vector<std::uint32_t>> &ignoreAtoms,
std::unique_ptr<std::vector<std::uint32_t>> &customAtomInvariants,
std::unique_ptr<std::vector<std::uint32_t>> &customBondInvariants) {
if (!py_fromAtoms.is_none()) {
unsigned int len = python::len(py_fromAtoms);
if (len) {
fromAtoms.reset(new std::vector<std::uint32_t>());
fromAtoms->reserve(len);
for (unsigned int i = 0; i < len; ++i) {
fromAtoms->push_back(python::extract<std::uint32_t>(py_fromAtoms[i]));
}
}
}
if (!py_ignoreAtoms.is_none()) {
unsigned int len = python::len(py_ignoreAtoms);
if (len) {
ignoreAtoms.reset(new std::vector<std::uint32_t>());
ignoreAtoms->reserve(len);
for (unsigned int i = 0; i < len; ++i) {
ignoreAtoms->push_back(
python::extract<std::uint32_t>(py_ignoreAtoms[i]));
}
}
}
if (!py_atomInvs.is_none()) {
unsigned int len = python::len(py_atomInvs);
if (len) {
customAtomInvariants.reset(new std::vector<std::uint32_t>());
customAtomInvariants->reserve(len);
for (unsigned int i = 0; i < len; ++i) {
customAtomInvariants->push_back(
python::extract<std::uint32_t>(py_atomInvs[i]));
}
}
}
if (!py_bondInvs.is_none()) {
unsigned int len = python::len(py_bondInvs);
if (len) {
customBondInvariants.reset(new std::vector<std::uint32_t>());
customBondInvariants->reserve(len);
for (unsigned int i = 0; i < len; ++i) {
customBondInvariants->push_back(
python::extract<std::uint32_t>(py_bondInvs[i]));
}
}
}
return;
}
template <typename OutputType>
SparseIntVect<OutputType> *getSparseCountFingerprint(
const FingerprintGenerator<OutputType> *fpGen, const ROMol &mol,
python::object py_fromAtoms, python::object py_ignoreAtoms,
const int confId, python::object py_atomInvs, python::object py_bondInvs,
python::object py_additionalOutput) {
std::unique_ptr<std::vector<std::uint32_t>> fromAtoms;
std::unique_ptr<std::vector<std::uint32_t>> ignoreAtoms;
std::unique_ptr<std::vector<std::uint32_t>> customAtomInvariants;
std::unique_ptr<std::vector<std::uint32_t>> customBondInvariants;
convertPyArguments(py_fromAtoms, py_ignoreAtoms, py_atomInvs, py_bondInvs,
fromAtoms, ignoreAtoms, customAtomInvariants,
customBondInvariants);
AdditionalOutput *additionalOutput = nullptr;
if (!py_additionalOutput.is_none()) {
additionalOutput = python::extract<AdditionalOutput *>(py_additionalOutput);
}
FingerprintFuncArguments args(fromAtoms.get(), ignoreAtoms.get(), confId,
additionalOutput, customAtomInvariants.get(),
customBondInvariants.get());
auto result = fpGen->getSparseCountFingerprint(mol, args);
return result.release();
}
template <typename OutputType>
SparseBitVect *getSparseFingerprint(
const FingerprintGenerator<OutputType> *fpGen, const ROMol &mol,
python::object py_fromAtoms, python::object py_ignoreAtoms,
const int confId, python::object py_atomInvs, python::object py_bondInvs,
python::object py_additionalOutput) {
std::unique_ptr<std::vector<std::uint32_t>> fromAtoms;
std::unique_ptr<std::vector<std::uint32_t>> ignoreAtoms;
std::unique_ptr<std::vector<std::uint32_t>> customAtomInvariants;
std::unique_ptr<std::vector<std::uint32_t>> customBondInvariants;
convertPyArguments(py_fromAtoms, py_ignoreAtoms, py_atomInvs, py_bondInvs,
fromAtoms, ignoreAtoms, customAtomInvariants,
customBondInvariants);
AdditionalOutput *additionalOutput = nullptr;
if (!py_additionalOutput.is_none()) {
additionalOutput = python::extract<AdditionalOutput *>(py_additionalOutput);
}
FingerprintFuncArguments args(fromAtoms.get(), ignoreAtoms.get(), confId,
additionalOutput, customAtomInvariants.get(),
customBondInvariants.get());
auto result = fpGen->getSparseFingerprint(mol, args);
return result.release();
}
template <typename OutputType>
SparseIntVect<std::uint32_t> *getCountFingerprint(
const FingerprintGenerator<OutputType> *fpGen, const ROMol &mol,
python::object py_fromAtoms, python::object py_ignoreAtoms,
const int confId, python::object py_atomInvs, python::object py_bondInvs,
python::object py_additionalOutput) {
std::unique_ptr<std::vector<std::uint32_t>> fromAtoms;
std::unique_ptr<std::vector<std::uint32_t>> ignoreAtoms;
std::unique_ptr<std::vector<std::uint32_t>> customAtomInvariants;
std::unique_ptr<std::vector<std::uint32_t>> customBondInvariants;
convertPyArguments(py_fromAtoms, py_ignoreAtoms, py_atomInvs, py_bondInvs,
fromAtoms, ignoreAtoms, customAtomInvariants,
customBondInvariants);
AdditionalOutput *additionalOutput = nullptr;
if (!py_additionalOutput.is_none()) {
additionalOutput = python::extract<AdditionalOutput *>(py_additionalOutput);
}
FingerprintFuncArguments args(fromAtoms.get(), ignoreAtoms.get(), confId,
additionalOutput, customAtomInvariants.get(),
customBondInvariants.get());
auto result = fpGen->getCountFingerprint(mol, args);
return result.release();
}
template <typename OutputType>
ExplicitBitVect *getFingerprint(const FingerprintGenerator<OutputType> *fpGen,
const ROMol &mol, python::object py_fromAtoms,
python::object py_ignoreAtoms, const int confId,
python::object py_atomInvs,
python::object py_bondInvs,
python::object py_additionalOutput) {
std::unique_ptr<std::vector<std::uint32_t>> fromAtoms;
std::unique_ptr<std::vector<std::uint32_t>> ignoreAtoms;
std::unique_ptr<std::vector<std::uint32_t>> customAtomInvariants;
std::unique_ptr<std::vector<std::uint32_t>> customBondInvariants;
convertPyArguments(py_fromAtoms, py_ignoreAtoms, py_atomInvs, py_bondInvs,
fromAtoms, ignoreAtoms, customAtomInvariants,
customBondInvariants);
AdditionalOutput *additionalOutput = nullptr;
if (!py_additionalOutput.is_none()) {
additionalOutput = python::extract<AdditionalOutput *>(py_additionalOutput);
}
FingerprintFuncArguments args(fromAtoms.get(), ignoreAtoms.get(), confId,
additionalOutput, customAtomInvariants.get(),
customBondInvariants.get());
auto result = fpGen->getFingerprint(mol, args);
return result.release();
}
template <typename ReturnType, typename FuncType>
python::tuple mtgetFingerprints(FuncType func, python::object mols,
int numThreads) {
unsigned int nmols = python::len(mols);
std::vector<const ROMol *> tmols;
for (auto i = 0u; i < nmols; ++i) {
tmols.push_back(python::extract<const ROMol *>(mols[i])());
}
typename decltype(std::function{
func})::result_type fps; // sometimes you really have to love C++ syntax
{
NOGIL gil;
fps = std::move(func(tmols, numThreads));
}
python::list result;
for (auto &fp : fps) {
result.append(boost::shared_ptr<ReturnType>(fp.release()));
}
return python::tuple(result);
}
template <typename OutputType>
python::tuple getFingerprints(const FingerprintGenerator<OutputType> *fpGen,
python::object mols, int numThreads) {
auto fpfunc = [&fpGen](const std::vector<const ROMol *> &tmols,
int numThreads) {
return fpGen->getFingerprints(tmols, numThreads);
};
return mtgetFingerprints<ExplicitBitVect, decltype(fpfunc)>(fpfunc, mols,
numThreads);
}
template <typename OutputType>
python::tuple getCountFingerprints(
const FingerprintGenerator<OutputType> *fpGen, python::object mols,
int numThreads) {
auto fpfunc = [&fpGen](const std::vector<const ROMol *> &tmols,
int numThreads) {
return fpGen->getCountFingerprints(tmols, numThreads);
};
return mtgetFingerprints<SparseIntVect<std::uint32_t>, decltype(fpfunc)>(
fpfunc, mols, numThreads);
}
template <typename OutputType>
python::tuple getSparseFingerprints(
const FingerprintGenerator<OutputType> *fpGen, python::object mols,
int numThreads) {
auto fpfunc = [&fpGen](const std::vector<const ROMol *> &tmols,
int numThreads) {
return fpGen->getSparseFingerprints(tmols, numThreads);
};
return mtgetFingerprints<SparseBitVect, decltype(fpfunc)>(fpfunc, mols,
numThreads);
}
template <typename OutputType>
python::tuple getSparseCountFingerprints(
const FingerprintGenerator<OutputType> *fpGen, python::object mols,
int numThreads) {
auto fpfunc = [&fpGen](const std::vector<const ROMol *> &tmols,
int numThreads) {
return fpGen->getSparseCountFingerprints(tmols, numThreads);
};
return mtgetFingerprints<SparseIntVect<OutputType>, decltype(fpfunc)>(
fpfunc, mols, numThreads);
}
template <typename OutputType>
python::object getNumPyFingerprint(
const FingerprintGenerator<OutputType> *fpGen, const ROMol &mol,
python::object py_fromAtoms, python::object py_ignoreAtoms,
const int confId, python::object py_atomInvs, python::object py_bondInvs,
python::object py_additionalOutput) {
std::unique_ptr<ExplicitBitVect> ebv{
getFingerprint(fpGen, mol, py_fromAtoms, py_ignoreAtoms, confId,
py_atomInvs, py_bondInvs, py_additionalOutput)};
npy_intp size[1] = {static_cast<npy_intp>(ebv->size())};
PyObject *arr = PyArray_ZEROS(1, size, NPY_UINT8, 0);
PyObject *one = PyInt_FromLong(1);
for (auto i = 0u; i < ebv->size(); ++i) {
if ((*ebv)[i]) {
PyArray_SETITEM(
(PyArrayObject *)arr,
static_cast<char *>(PyArray_GETPTR1((PyArrayObject *)arr, i)), one);
}
}
Py_DECREF(one);
python::handle<> res(arr);
return python::object(res);
}
template <typename OutputType>
python::object getNumPyCountFingerprint(
const FingerprintGenerator<OutputType> *fpGen, const ROMol &mol,
python::object py_fromAtoms, python::object py_ignoreAtoms,
const int confId, python::object py_atomInvs, python::object py_bondInvs,
python::object py_additionalOutput) {
std::unique_ptr<SparseIntVect<uint32_t>> fp{
getCountFingerprint(fpGen, mol, py_fromAtoms, py_ignoreAtoms, confId,
py_atomInvs, py_bondInvs, py_additionalOutput)};
npy_intp size[1] = {static_cast<npy_intp>(fp->size())};
PyObject *arr = PyArray_ZEROS(1, size, NPY_UINT32, 0);
for (auto i = 0u; i < fp->size(); ++i) {
auto v = (*fp)[i];
if (v) {
PyObject *val = PyInt_FromLong(v);
PyArray_SETITEM(
(PyArrayObject *)arr,
static_cast<char *>(PyArray_GETPTR1((PyArrayObject *)arr, i)), val);
Py_DECREF(val);
}
}
python::handle<> res(arr);
return python::object(res);
}
template <typename OutputType>
std::string getInfoString(const FingerprintGenerator<OutputType> *fpGen) {
return std::string(fpGen->infoString());
}
template <typename OutputType>
FingerprintArguments *getOptions(FingerprintGenerator<OutputType> *fpGen) {
return fpGen->getOptions();
}
const std::vector<const ROMol *> convertPyArgumentsForBulk(
const python::list &py_molVect) {
std::vector<const ROMol *> molVect;
if (!py_molVect.is_none()) {
unsigned int len = python::len(py_molVect);
if (len) {
for (unsigned int i = 0; i < len; ++i) {
molVect.push_back(python::extract<const ROMol *>(py_molVect[i]));
}
}
}
return molVect;
}
python::list getSparseCountFPBulkPy(python::list &py_molVect, FPType fPType) {
const auto molVect = convertPyArgumentsForBulk(py_molVect);
auto tempResult = getSparseCountFPBulk(molVect, fPType);
python::list result;
for (auto &it : *tempResult) {
result.append(boost::shared_ptr<SparseIntVect<std::uint64_t>>(it));
}
delete tempResult;
return result;
}
python::list getSparseFPBulkPy(python::list &py_molVect, FPType fpType) {
const std::vector<const ROMol *> molVect =
convertPyArgumentsForBulk(py_molVect);
auto tempResult = getSparseFPBulk(molVect, fpType);
python::list result;
for (auto &it : *tempResult) {
// todo every other bulk method casts results to boost::shared_ptr, except
// this one. It should also be boost::shared_ptr
result.append(boost::shared_ptr<SparseBitVect>(it));
}
delete tempResult;
return result;
}
python::list getCountFPBulkPy(python::list &py_molVect, FPType fPType) {
const std::vector<const ROMol *> molVect =
convertPyArgumentsForBulk(py_molVect);
auto tempResult = getCountFPBulk(molVect, fPType);
python::list result;
for (auto &it : *tempResult) {
result.append(boost::shared_ptr<SparseIntVect<std::uint32_t>>(it));
}
delete tempResult;
return result;
}
python::list getFPBulkPy(python::list &py_molVect, FPType fPType) {
const std::vector<const ROMol *> molVect =
convertPyArgumentsForBulk(py_molVect);
auto tempResult = getFPBulk(molVect, fPType);
python::list result;
for (auto &it : *tempResult) {
result.append(boost::shared_ptr<ExplicitBitVect>(it));
}
delete tempResult;
return result;
}
python::object getAtomCountsHelper(const AdditionalOutput &ao) {
if (!ao.atomCounts) {
return python::object();
}
python::list res;
for (const auto v : *ao.atomCounts) {
res.append(v);
}
return python::tuple(res);
}
python::object getAtomToBitsHelper(const AdditionalOutput &ao) {
if (!ao.atomToBits) {
return python::object();
}
python::list res;
for (const auto &lst : *ao.atomToBits) {
python::list local;
for (const auto v : lst) {
local.append(v);
}
res.append(python::tuple(local));
}
return python::tuple(res);
}
python::object getBitPathsHelper(const AdditionalOutput &ao) {
if (!ao.bitPaths) {
return python::object();
}
python::dict res;
for (const auto &pr : *ao.bitPaths) {
python::list local;
for (const auto &lst : pr.second) {
python::list inner;
for (const auto v : lst) {
inner.append(v);
}
local.append(python::tuple(inner));
}
res[pr.first] = python::tuple(local);
}
return res;
}
python::object getBitInfoMapHelper(const AdditionalOutput &ao) {
if (!ao.bitInfoMap) {
return python::object();
}
python::dict res;
for (const auto &pr : *ao.bitInfoMap) {
python::list local;
for (const auto &v : pr.second) {
python::tuple inner = python::make_tuple(v.first, v.second);
local.append(inner);
}
res[pr.first] = python::tuple(local);
}
return res;
}
python::object getAtomsPerBitHelper(const AdditionalOutput &ao) {
if (!ao.atomsPerBit) {
return python::object();
}
python::dict res;
for (const auto &pr : *ao.atomsPerBit) {
python::list local;
for (const auto &lst : pr.second) {
python::list inner;
for (const auto v : lst) {
inner.append(v);
}
local.append(python::tuple(inner));
}
res[pr.first] = python::tuple(local);
}
return res;
}
namespace {
template <typename T>
void wrapGenerator(const std::string &nm) {
python::class_<FingerprintGenerator<T>, boost::noncopyable>(nm.c_str(),
python::no_init)
.def("GetSparseCountFingerprint", getSparseCountFingerprint<T>,
((python::arg("self"), python::arg("mol")),
python::arg("fromAtoms") = python::list(),
python::arg("ignoreAtoms") = python::list(),
python::arg("confId") = -1,
python::arg("customAtomInvariants") = python::list(),
python::arg("customBondInvariants") = python::list(),
python::arg("additionalOutput") = python::object()),
"Generates a sparse count fingerprint\n\n"
" ARGUMENTS:\n"
" - mol: molecule to be fingerprinted\n"
" - fromAtoms: indices of atoms to use while generating the "
"fingerprint\n"
" - ignoreAtoms: indices of atoms to exclude while generating "
"the fingerprint\n"
" - confId: 3D confirmation to use, only used by AtomPair "
"fingerprint\n"
" - customAtomInvariants: custom atom invariants to be used, "
"overrides invariants from the invariant generator\n"
" - customBondInvariants: custom bond invariants to be used, "
"overrides invariants from the invariant generator\n\n"
" - additionalOutput: AdditionalOutput instance used to return "
"extra information about the bits\n\n"
" RETURNS: a SparseIntVect containing fingerprint\n\n",
python::return_value_policy<python::manage_new_object>())
.def("GetSparseFingerprint", getSparseFingerprint<T>,
((python::arg("self"), python::arg("mol")),
python::arg("fromAtoms") = python::list(),
python::arg("ignoreAtoms") = python::list(),
python::arg("confId") = -1,
python::arg("customAtomInvariants") = python::list(),
python::arg("customBondInvariants") = python::list(),
python::arg("additionalOutput") = python::object()),
"Generates a sparse fingerprint\n\n"
" ARGUMENTS:\n"
" - mol: molecule to be fingerprinted\n"
" - fromAtoms: indices of atoms to use while generating the "
"fingerprint\n"
" - ignoreAtoms: indices of atoms to exclude while generating "
"the fingerprint\n"
" - confId: 3D confirmation to use, only used by AtomPair "
"fingerprint\n"
" - customAtomInvariants: custom atom invariants to be used, "
"overrides invariants from the invariant generator\n"
" - customBondInvariants: custom bond invariants to be used, "
"overrides invariants from the invariant generator\n\n"
" - additionalOutput: AdditionalOutput instance used to return "
"extra information about the bits\n\n"
" RETURNS: a SparseBitVect containing fingerprint\n\n",
python::return_value_policy<python::manage_new_object>())
.def("GetCountFingerprint", getCountFingerprint<T>,
((python::arg("self"), python::arg("mol")),
python::arg("fromAtoms") = python::list(),
python::arg("ignoreAtoms") = python::list(),
python::arg("confId") = -1,
python::arg("customAtomInvariants") = python::list(),
python::arg("customBondInvariants") = python::list(),
python::arg("additionalOutput") = python::object()),
"Generates a count fingerprint\n\n"
" ARGUMENTS:\n"
" - mol: molecule to be fingerprinted\n"
" - fromAtoms: indices of atoms to use while generating the "
"fingerprint\n"
" - ignoreAtoms: indices of atoms to exclude while generating "
"the fingerprint\n"
" - confId: 3D confirmation to use, only used by AtomPair "
"fingerprint\n"
" - customAtomInvariants: custom atom invariants to be used, "
"overrides invariants from the invariant generator\n"
" - customBondInvariants: custom bond invariants to be used, "
"overrides invariants from the invariant generator\n\n"
" - additionalOutput: AdditionalOutput instance used to return "
"extra information about the bits\n\n"
" RETURNS: a SparseIntVect containing fingerprint\n\n",
python::return_value_policy<python::manage_new_object>())
.def("GetCountFingerprintAsNumPy", getNumPyCountFingerprint<T>,
((python::arg("self"), python::arg("mol")),
python::arg("fromAtoms") = python::list(),
python::arg("ignoreAtoms") = python::list(),
python::arg("confId") = -1,
python::arg("customAtomInvariants") = python::list(),
python::arg("customBondInvariants") = python::list(),
python::arg("additionalOutput") = python::object()),
"Generates a count fingerprint\n\n"
" ARGUMENTS:\n"
" - mol: molecule to be fingerprinted\n"
" - fromAtoms: indices of atoms to use while generating the "
"fingerprint\n"
" - ignoreAtoms: indices of atoms to exclude while generating "
"the fingerprint\n"
" - confId: 3D confirmation to use, only used by AtomPair "
"fingerprint\n"
" - customAtomInvariants: custom atom invariants to be used, "
"overrides invariants from the invariant generator\n"
" - customBondInvariants: custom bond invariants to be used, "
"overrides invariants from the invariant generator\n\n"
" - additionalOutput: AdditionalOutput instance used to return "
"extra information about the bits\n\n"
" RETURNS: a numpy array containing the fingerprint\n\n")
.def("GetFingerprint", getFingerprint<T>,
((python::arg("self"), python::arg("mol")),
python::arg("fromAtoms") = python::list(),
python::arg("ignoreAtoms") = python::list(),
python::arg("confId") = -1,
python::arg("customAtomInvariants") = python::list(),
python::arg("customBondInvariants") = python::list(),
python::arg("additionalOutput") = python::object()),
"Generates a fingerprint\n\n"
" ARGUMENTS:\n"
" - mol: molecule to be fingerprinted\n"
" - fromAtoms: indices of atoms to use while generating the "
"fingerprint\n"
" - ignoreAtoms: indices of atoms to exclude while generating "
"the fingerprint\n"
" - confId: 3D confirmation to use, only used by AtomPair "
"fingerprint\n"
" - customAtomInvariants: custom atom invariants to be used, "
"overrides invariants from the invariant generator\n"
" - customBondInvariants: custom bond invariants to be used, "
"overrides invariants from the invariant generator\n\n"
" - additionalOutput: AdditionalOutput instance used to return "
"extra information about the bits\n\n"
" RETURNS: a ExplicitBitVect containing fingerprint\n\n",
python::return_value_policy<python::manage_new_object>())
.def("GetFingerprintAsNumPy", getNumPyFingerprint<T>,
((python::arg("self"), python::arg("mol")),
python::arg("fromAtoms") = python::list(),
python::arg("ignoreAtoms") = python::list(),
python::arg("confId") = -1,
python::arg("customAtomInvariants") = python::list(),
python::arg("customBondInvariants") = python::list(),
python::arg("additionalOutput") = python::object()),
"Generates a fingerprint\n\n"
" ARGUMENTS:\n"
" - mol: molecule to be fingerprinted\n"
" - fromAtoms: indices of atoms to use while generating the "
"fingerprint\n"
" - ignoreAtoms: indices of atoms to exclude while generating "
"the fingerprint\n"
" - confId: 3D confirmation to use, only used by AtomPair "
"fingerprint\n"
" - customAtomInvariants: custom atom invariants to be used, "
"overrides invariants from the invariant generator\n"
" - customBondInvariants: custom bond invariants to be used, "
"overrides invariants from the invariant generator\n\n"
" - additionalOutput: AdditionalOutput instance used to return "
"extra information about the bits\n\n"
" RETURNS: a numpy array containing the fingerprint\n\n")
.def("GetFingerprints", getFingerprints<T>,
((python::arg("self"), python::arg("mols")),
python::arg("numThreads") = 1),
"Generates fingerprints for a sequence of molecules\n\n"
" ARGUMENTS:\n"
" - mol: molecule to be fingerprinted\n"
" - numThreads: number of threads to use\n\n"
" RETURNS: a tuple of ExplicitBitVects\n\n")
.def("GetCountFingerprints", getCountFingerprints<T>,
((python::arg("self"), python::arg("mols")),
python::arg("numThreads") = 1),
"Generates count fingerprints for a sequence of molecules\n\n"
" ARGUMENTS:\n"
" - mol: molecule to be fingerprinted\n"
" - numThreads: number of threads to use\n\n"
" RETURNS: a tuple of SparseIntVects\n\n")
.def("GetSparseFingerprints", getSparseFingerprints<T>,
((python::arg("self"), python::arg("mols")),
python::arg("numThreads") = 1),
"Generates sparse fingerprints for a sequence of molecules\n\n"
" ARGUMENTS:\n"
" - mol: molecule to be fingerprinted\n"
" - numThreads: number of threads to use\n\n"
" RETURNS: a tuple of SparseBitVects\n\n")
.def("GetSparseCountFingerprints", getSparseCountFingerprints<T>,
((python::arg("self"), python::arg("mols")),
python::arg("numThreads") = 1),
"Generates sparse count fingerprints for a sequence of molecules\n\n"
" ARGUMENTS:\n"
" - mol: molecule to be fingerprinted\n"
" - numThreads: number of threads to use\n\n"
" RETURNS: a tuple of SparseIntVects\n\n")
.def("GetInfoString", getInfoString<T>, python::args("self"),
"Returns a string containing information about the fingerprint "
"generator\n\n"
" RETURNS: an information string\n\n")
.def("GetOptions", getOptions<T>,
python::return_internal_reference<
1, python::with_custodian_and_ward_postcall<0, 1>>(),
python::args("self"), "return the fingerprint options object")
.def("ToJSON", &generatorToJSON<T>, (python::arg("self")),
"Serialize a FingerprintGenerator to JSON");
}
void setCountBoundsHelper(FingerprintArguments &opts, python::object bounds) {
pythonObjectToVect(bounds, opts.d_countBounds);
}
} // namespace
BOOST_PYTHON_MODULE(rdFingerprintGenerator) {
rdkit_import_array();
python::class_<AtomInvariantsGenerator, boost::noncopyable>(
"AtomInvariantsGenerator", python::no_init);
python::class_<BondInvariantsGenerator, boost::noncopyable>(
"BondInvariantsGenerator", python::no_init);
python::class_<AdditionalOutput, boost::noncopyable>("AdditionalOutput")
.def("AllocateAtomToBits", &AdditionalOutput::allocateAtomToBits,
python::args("self"), "synonym for CollectAtomToBits()")
.def("AllocateBitInfoMap", &AdditionalOutput::allocateBitInfoMap,
python::args("self"), "synonym for CollectBitInfoMap()")
.def("AllocateBitPaths", &AdditionalOutput::allocateBitPaths,
python::args("self"), "synonym for CollectBitPaths()")
.def("AllocateAtomCounts", &AdditionalOutput::allocateAtomCounts,
python::args("self"), "synonym for CollectAtomCounts()")
.def("AllocateAtomsPerBit", &AdditionalOutput::allocateAtomsPerBit,
python::args("self"), "synonym for CollectAtomsPerBit()")
.def(
"CollectAtomToBits", &AdditionalOutput::allocateAtomToBits,
python::args("self"),
"toggle collection of information mapping each atom to the bits it is involved in.")
.def(
"CollectBitInfoMap", &AdditionalOutput::allocateBitInfoMap,
python::args("self"),
"toggles collection of information mapping each atom to more detail about the atom environment (not available from all fingerprints)")
.def(
"CollectBitPaths", &AdditionalOutput::allocateBitPaths,
python::args("self"),
"toggles collection of information matching each atom to information about the paths it is involved in (not available from all fingerprints).")
.def(
"CollectAtomCounts", &AdditionalOutput::allocateAtomCounts,
python::args("self"),
"toggles collection of information about the number of bits each atom is involved in")
.def(
"CollectAtomsPerBit", &AdditionalOutput::allocateAtomsPerBit,
python::args("self"),
"toggles collection of information about all atoms involved in setting each bit")
.def("GetAtomToBits", &getAtomToBitsHelper, python::args("self"))
.def("GetBitInfoMap", &getBitInfoMapHelper, python::args("self"))
.def("GetBitPaths", &getBitPathsHelper, python::args("self"))
.def("GetAtomCounts", &getAtomCountsHelper, python::args("self"))
.def("GetAtomsPerBit", &getAtomsPerBitHelper, python::args("self"));
python::class_<FingerprintArguments, boost::noncopyable>("FingerprintOptions",
python::no_init)
.def_readwrite("countSimulation",
&FingerprintArguments::df_countSimulation,
"use count simulation")
.def_readwrite(
"includeChirality", &FingerprintArguments::df_includeChirality,
"include chirality in atom invariants (not for all fingerprints)")
.def_readwrite("fpSize", &FingerprintArguments::d_fpSize,
"size of the fingerprints created")
.def_readwrite("numBitsPerFeature",
&FingerprintArguments::d_numBitsPerFeature,
"number of bits to set for each feature")
.def("SetCountBounds", &setCountBoundsHelper,
python::args("self", "bounds"), "set the bins for the count bounds");
wrapGenerator<std::uint32_t>("FingerprintGenerator32");
wrapGenerator<std::uint64_t>("FingerprintGenerator64");
python::enum_<FPType>("FPType")
.value("RDKitFP", FPType::RDKitFP)
.value("MorganFP", FPType::MorganFP)
.value("AtomPairFP", FPType::AtomPairFP)
.value("TopologicalTorsionFP", FPType::TopologicalTorsionFP)
.export_values();
;
python::def("GetSparseCountFPs", &getSparseCountFPBulkPy,
(python::arg("molecules") = python::list(),
python::arg("fpType") = FPType::MorganFP),
"");
python::def("GetSparseFPs", &getSparseFPBulkPy,
(python::arg("molecules") = python::list(),
python::arg("fpType") = FPType::MorganFP),
"");
python::def("GetCountFPs", &getCountFPBulkPy,
(python::arg("molecules") = python::list(),
python::arg("fpType") = FPType::MorganFP),
"");
python::def("GetFPs", &getFPBulkPy,
(python::arg("molecules") = python::list(),
python::arg("fpType") = FPType::MorganFP),
"");
python::def("FingerprintGeneratorFromJSON", &generatorFromJSONHelper,
(python::arg("jsonString")),
"Deserialize a FingerprintGenerator from a JSON string",
python::return_value_policy<python::manage_new_object>());
AtomPairWrapper::exportAtompair();
MorganWrapper::exportMorgan();
RDKitFPWrapper::exportRDKit();
TopologicalTorsionWrapper::exportTopologicalTorsion();
}
} // namespace FingerprintWrapper
} // namespace RDKit