mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-03 21:44:30 +08:00
- moved classes that do not need being exposed in Resonance.h to Resonance.cpp - added the ALLOW_CHARGE_SEPARATION flag: now by default charge separation structures are not displayed if there's at least one structure with no charge separation - TODO * add SWIG wrappers * add a few test tp resMolSupplierTest.cpp
159 lines
7.1 KiB
C++
159 lines
7.1 KiB
C++
// $Id$
|
|
//
|
|
// Copyright (C) 2015 Paolo Tosco
|
|
//
|
|
// Copyright (C) 2003-2010 Greg Landrum and Rational Discovery LLC
|
|
//
|
|
// @@ 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.
|
|
//
|
|
|
|
#define NO_IMPORT_ARRAY
|
|
#include <boost/python.hpp>
|
|
#include <string>
|
|
|
|
//ours
|
|
#include <GraphMol/RDKitBase.h>
|
|
#include <GraphMol/Resonance.h>
|
|
#include <GraphMol/Substruct/SubstructMatch.h>
|
|
#include <RDBoost/PySequenceHolder.h>
|
|
#include <RDBoost/iterator_next.h>
|
|
|
|
#include "MolSupplier.h"
|
|
|
|
namespace python = boost::python;
|
|
|
|
namespace RDKit {
|
|
PyObject *convertMatches(MatchVectType &matches);
|
|
PyObject *GetResonanceSubstructMatch(const ResonanceMolSupplier &suppl,
|
|
const ROMol &query,bool useChirality=false,
|
|
bool useQueryQueryMatches=false){
|
|
NOGIL gil;
|
|
MatchVectType matches;
|
|
SubstructMatch(suppl,query,matches,true,useChirality,useQueryQueryMatches);
|
|
return convertMatches(matches);
|
|
}
|
|
|
|
PyObject *GetResonanceSubstructMatches(const ResonanceMolSupplier &suppl,
|
|
const ROMol &query,bool uniquify=false,
|
|
bool useChirality=false,
|
|
bool useQueryQueryMatches=false,
|
|
unsigned int maxMatches = 1000){
|
|
std::vector< MatchVectType > matches;
|
|
int matched = SubstructMatch(suppl,query,matches,uniquify,true,useChirality,useQueryQueryMatches,maxMatches);
|
|
PyObject *res = PyTuple_New(matched);
|
|
for(int idx=0;idx<matched;idx++){
|
|
PyTuple_SetItem(res,idx,convertMatches(matches[idx]));
|
|
}
|
|
return res;
|
|
}
|
|
|
|
std::string resonanceMolSupplierClassDoc="A class which supplies resonance structures (as mols) from a mol.\n \
|
|
\n \
|
|
Usage examples:\n \
|
|
\n \
|
|
1) Lazy evaluation: the resonance structures for each independent\n \
|
|
conjugated group are enumerated upon object creation; however the\n \
|
|
resonance structures of the complete molecule are not constructed\n \
|
|
until we ask for them:\n \
|
|
>>> suppl = ResonanceMolSupplier(mol)\n \
|
|
>>> for resMol in suppl:\n \
|
|
... resMol.GetNumAtoms()\n \
|
|
\n \
|
|
2) Lazy evaluation 2:\n \
|
|
>>> suppl = ResonanceMolSupplier(mol)\n \
|
|
>>> resMol1 = suppl.next()\n \
|
|
>>> resMol2 = suppl.next()\n \
|
|
>>> suppl.reset()\n \
|
|
>>> resMol3 = suppl.next()\n \
|
|
# resMol3 and resMol1 are the same: \n \
|
|
>>> MolToSmiles(resMol3)==MolToSmiles(resMol1)\n \
|
|
\n \
|
|
3) Random Access:\n \
|
|
>>> suppl = ResonanceMolSupplier(mol)\n \
|
|
>>> resMol1 = suppl[0] \n \
|
|
>>> resMol2 = suppl[1] \n \
|
|
NOTE: this will generate an IndexError if the supplier doesn't have that many\n \
|
|
molecules.\n \
|
|
\n \
|
|
4) Random Access 2: looping over all resonance structures\n \
|
|
>>> suppl = ResonanceMolSupplier(mol)\n \
|
|
>>> nResMols = len(suppl)\n \
|
|
>>> for i in range(nResMols):\n \
|
|
... suppl[i].GetNumAtoms()\n \
|
|
\n";
|
|
struct resmolsup_wrap {
|
|
static void wrap() {
|
|
python::enum_<ResonanceMolSupplier::ResonanceFlags>("ResonanceFlags")
|
|
.value("ALLOW_INCOMPLETE_OCTETS", ResonanceMolSupplier::ALLOW_INCOMPLETE_OCTETS)
|
|
.value("ALLOW_CHARGE_SEPARATION", ResonanceMolSupplier::ALLOW_CHARGE_SEPARATION)
|
|
.value("KEKULE_ALL", ResonanceMolSupplier::KEKULE_ALL)
|
|
.value("UNCONSTRAINED_CATIONS", ResonanceMolSupplier::UNCONSTRAINED_CATIONS)
|
|
.value("UNCONSTRAINED_ANIONS", ResonanceMolSupplier::UNCONSTRAINED_ANIONS)
|
|
.export_values()
|
|
;
|
|
python::class_<ResonanceMolSupplier,boost::noncopyable>("ResonanceMolSupplier",
|
|
resonanceMolSupplierClassDoc.c_str(),
|
|
python::init<ROMol &, unsigned int, unsigned int>((python::arg("mol"),
|
|
python::arg("flags") = 0,
|
|
python::arg("maxStructs") = 1000)))
|
|
.def("__iter__", (ResonanceMolSupplier *(*)(ResonanceMolSupplier *))&MolSupplIter,
|
|
python::return_internal_reference<1>() )
|
|
.def(NEXT_METHOD, (ROMol *(*)(ResonanceMolSupplier *))&MolSupplNextAcceptNullLastMolecule,
|
|
"Returns the next resonance structure in the supplier. Raises _StopIteration_ on end.\n",
|
|
python::return_value_policy<python::manage_new_object>())
|
|
.def("__getitem__", (ROMol *(*)(ResonanceMolSupplier *,int))&MolSupplGetItem,
|
|
python::return_value_policy<python::manage_new_object>())
|
|
.def("reset", &ResonanceMolSupplier::reset,
|
|
"Resets our position in the resonance structure supplier to the beginning.\n")
|
|
.def("__len__", &ResonanceMolSupplier::length)
|
|
.def("atEnd", &ResonanceMolSupplier::atEnd,
|
|
"Returns whether or not we have hit the end of the resonance structure supplier.\n")
|
|
.def("GetSubstructMatch",GetResonanceSubstructMatch,
|
|
(python::arg("self"),python::arg("query"),
|
|
python::arg("useChirality")=false,
|
|
python::arg("useQueryQueryMatches")=false),
|
|
"Returns the indices of the molecule's atoms that match a substructure query,\n"
|
|
"taking into account all resonance structures in ResonanceMolSupplier.\n\n"
|
|
" ARGUMENTS:\n"
|
|
" - query: a Molecule\n\n"
|
|
" - useChirality: enables the use of stereochemistry in the matching\n\n"
|
|
" - useQueryQueryMatches: use query-query matching logic\n\n"
|
|
" RETURNS: a tuple of integers\n\n"
|
|
" NOTES:\n"
|
|
" - only a single match is returned\n"
|
|
" - the ordering of the indices corresponds to the atom ordering\n"
|
|
" in the query. For example, the first index is for the atom in\n"
|
|
" this molecule that matches the first atom in the query.\n")
|
|
.def("GetSubstructMatches",
|
|
GetResonanceSubstructMatches,
|
|
(python::arg("self"),python::arg("query"),
|
|
python::arg("uniquify")=false,
|
|
python::arg("useChirality")=false,
|
|
python::arg("useQueryQueryMatches")=false,
|
|
python::arg("maxMatches")=1000),
|
|
"Returns tuples of the indices of the molecule's atoms that match a substructure query,\n"
|
|
"taking into account all resonance structures in ResonanceMolSupplier.\n\n"
|
|
" ARGUMENTS:\n"
|
|
" - query: a Molecule.\n"
|
|
" - uniquify: (optional) determines whether or not the matches are uniquified.\n"
|
|
" Defaults to 1.\n\n"
|
|
" - useChirality: enables the use of stereochemistry in the matching\n\n"
|
|
" - useQueryQueryMatches: use query-query matching logic\n\n"
|
|
" RETURNS: a tuple of tuples of integers\n\n"
|
|
" NOTE:\n"
|
|
" - the ordering of the indices corresponds to the atom ordering\n"
|
|
" in the query. For example, the first index is for the atom in\n"
|
|
" this molecule that matches the first atom in the query.\n")
|
|
;
|
|
};
|
|
};
|
|
}
|
|
|
|
void wrap_resmolsupplier() {
|
|
RDKit::resmolsup_wrap::wrap();
|
|
}
|