Re: [Rdkit-devel] [Rdkit-discuss] python/c++ interface again...
Open-Source Cheminformatics and Machine Learning
Brought to you by:
glandrum
|
From: Paul E. <pau...@bi...> - 2012-06-04 17:29:22
|
On 03/06/12 18:33, Paul Emsley wrote:
> On 02/06/12 04:44, Greg Landrum wrote:
>> Hi Paul,
>>
>> On Fri, Jun 1, 2012 at 1:41 PM, Paul Emsley<pau...@bi...> wrote:
>>> I've been trying to read boost python docs and I am lost...
>>>
>>> I'd like to return a PyObject *. I have a RDKit::RWMol, say - or a
>>> pointer to a new one if need be...
>> If you are using a boost.python interface, and your function is
>> exposed using boost::python::def, then the right thing happens
>> more-or-less automatically if you have a function that returns an
>> RDKit::RWMol *. I say more-or-less because you will probably also have
>> to tell the library what to do about ownership of the pointer; you'll
>> get a very informative compiler error here if you leave that out and
>> it's required.
>>
>> Even if you're not using boost.python for the entire interface, it may
>> be worth trying to use it for the functions where you want to return
>> RDKit objects. I have no idea if this is possible, but it's worth a
>> try.
>>
>> You'd do a function something like this:
>>
>> RDKit::ROMol *
>> coot::regularize(RDKit::ROMol&mol) {
>> .. do stuff ..
>> // construct return value
>> RDKit::RWMol *regularized_mol = new RDKit::RWMol(mol);
>> update_coords(regularized_mol); // replace with refined positions
>> return static_cast<ROMol *>(regularized_mol);
>> }
>>
>> Notice how that has no reference to python objects in it; it's also
>> conceivably useful from your C++ code.
>> To expose to python, you have in the code for your wrapper module:
>> boost::python::def("regularize",coot::regularize,(python::arg("mol")),
>> "docs",
>> boost::python::return_value_policy<boost::python::manage_new_object>());
>>
>> This (obviously) isn't tested in any way, shape, or form. It probably
>> also won't work unless the whole thing is inside a module that's set
>> up using the BOOST_PYTHON_MODULE macro, but it's worth a try.
>>
>> Having said all of that: this is starting to move in a very highly
>> specialized direction that's maybe not interesting to most of the
>> readers of rdkit-discuss (though it's fascinating to me :-). I'd
>> suggest moving this discussion to rdkit-devel. Paul: if the above
>> doesn't work, please post something to rdkit-devel along with a short
>> description of how you're creating your python modules (are you using
>> SWIG? wrapping them by hand? already using Boost.Python?) and I'll try
>> to help more. A pointer to actual code would also help.
>>
> OK, thanks again.
>
> I have done some reading about boost.python. I understand now (as you
> imply) that the idea is not to (have to) use PyObject *s. OK, let's try
> with that for the moment.
>
> I have put the code for how I understand the boost interface should work
> into the repo now, but it doesn't compile for me. I can't determine
> what to do from the compile message - perhaps this is the informative
> compiler message to which you refer.. :)
>
> So my question is: is this the pointer ownership message to which you
> refer? If so, what do I do? Please tell me to RTFM if appropriate...
>
> relevant directory:
> http://coot.googlecode.com/svn/branches/pyro-test/pyrogen/
>
> I added restraints-boost.cc, which contains simply the def of a
> simplified version regularize().
>
> I have added the make log for compile restraints-boost too.
> http://coot.googlecode.com/svn/branches/pyro-test/pyrogen/make.log
>
> If/when we get this to work, I will try also passing a PyObject * (for
> the target geometry description - that may not work - so I may also try
> simply boosting my target geometry class - hmmm!)
>
So, for the record, indeed my trouble compiling was (mostly) that I had
neglected to add
return_value_policy<boost::python::manage_new_object>() to the
arguments. Also, I was trying to keep the swigged functions and the
boost functions in the same file - that was also a mistake. It is
cleaner (in c++) to have the boost functions create different modules
and (in python) import a swigged module and a boosted module.
I *was* able to create a function which took an RDKit Mol & argument and
a PyObject * argument and that worked just fine.
Gory details:
http://code.google.com/p/coot/source/detail?r=4219
Cheers,
Paul.
|