Files
rdkit/Code/GraphMol/Wrap/ResonanceMolSupplier.cpp
Paolo Tosco 72de596280 - implemented correct resonance structure sorting for degenerate cases
- 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
2015-10-23 18:41:53 +01:00

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();
}