Passing python lists instead of std::vector to C++ class


I wrote a class that takes two std::vector as arguments. I compile it fine, generate a dictionary for it and then use gSystem to load it in my python script. So far so good. I know that in this case, we are supposed to use the std module from ROOT and provide the class with std.vector(TLorentzVector). I am wondering if it is possible to compile the dictionary (python wrapper) in a different way so that the python manifestation of the class will take python lists of TLorentzVector instead of std.vector(TLorentzVector).

I have even tried using SWIG to do this, but somehow my class would not recognize the TLorentzVectors I get by doing ‘from ROOT import TLorentzVector’. I know that SWIG can do what I require, it just seems like a SWIG wrapper has some problem talking to the python wrappers already in place in ROOT.

Is there any solution to this problem from within ROOT? Or do I need to consider external solutions like SWIG or boost.python?



there is no such option: the problem is that the layout from an std::vector is vastly different from that of a python list. Hence, for this to work, you’d have to copy over all elements of the list into a vector and v.v., which besides ownership and life-time problems, would be quite some overhead.

Of course, copying an std::vector into a list is simple:mylist = list(myvector) so if you prefer to work with python lists, then that’ll be one way.

As for communicating with SWIG: python only defines one C-pointer type that can be generally used, which is CObject. Hence, to pass objects between SWIG (or SIP, or boost.python, or …) and PyROOT, use ROOT.AsCObject(mylorentz) to obtain a CObject and to turn it back for use with ROOT, do ROOT.BindObject(mylorentz, ROOT.TLorentzVector).


Thank you so much for the info! Looks like I have a design choice to make…