On Sat, Dec 7, 2013 at 8:25 PM, Zhenwei Luo <tluozhenwei@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