[cctbxbb] Passing array between python and C++

Nathaniel Echols nechols at lbl.gov
Sat Dec 7 20:45:10 PST 2013


On Sat, Dec 7, 2013 at 8:25 PM, Zhenwei Luo <tluozhenwei at gmail.com> wrote:

>         I am writing a refinement program using the cctbx. I have
> encountered with a problem when I wanted to pass an array between c++ and
> python. The type of array I used in my c++ source file is
> af::shared<af::shared<vec3> >, I would like to pass it into my python
> script, thus I could do some other operations to this array.
> I wrote a method in my class to return this array.
>
>  af::shared<af::shared<vec3<double> > return_modes( ) { return modes; }
>
> I wrote another method in the *_ext file to wrap this method to make it
> callable from python.
>
> .def("return_modes", &nm_init::return_modes)
>
> But when I use it in python,
> eigenvector = nm_init_manager.return_modes()
> It gave me an error:
> TypeError: No to_python (by-value) converter found for c++ type:
> scitbx::af::shared<scitbx::af::shared<scitbx::vec3<double> > >
>

What that error means is that boost.python doesn't know how to present this
new type to Python.  For the data structures that we pass back and forth,
we have to explicitly provide wrappers for them - including new
instantiations of scitbx::array_family templates.

What I want to realize is just creating an two dimensional array using vec3
> as its element. I can also using the select method  in this array to select
> some elements from its column, just like in the af::shared<vec3<double> >
> array. Namely, the column of this array should have some same properties
> like af::shared<vec3<double> >. Can anyone help me figure out what I should
> do?
>

In general the scitbx::array_family templates aren't really intended to
every be multidimensional; for inherently 2D and 3D data types like images
and maps, we use flex.grid to provide a multi-dimensional accessor on top
of the 1D array.  The grid may not be the most appropriate in your case but
if I'm making the correct assumptions about the data you're trying to pass
back and forth, I think it might be easiest to simply define a custom class
that contains a std::vector of af::shared<vec3> arrays, and add an index
parameter to the return_modes method, which would be modified to return
only a single array of modes at a time.  You can also do things like
wrapping a method as __getitem__ with boost.python, which would mimic a 2D
array.  (I can probably dig up/cook up some code examples tomorrow if this
is unclear, since it was certainly not intuitive to me when I started
working with CCTBX and it would be nice to have documentation for the
future.)

-Nat
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://phenix-online.org/pipermail/cctbxbb/attachments/20131207/91a774e3/attachment.htm>


More information about the cctbxbb mailing list