Does anyone know how to create and pass a C++ function of the type
std:function<double(double, double, double)>
into PyROOT?
I have tried using ROOT.gInterpreter.ProcessLine() to do this, but I get a TypeError when I try to use the function that I created. From python I get that my function is of the type
<type 'ROOT.MethodProxy'>
Any ideas on how to correctly define a C++ function inside PyROOT?
Unfortunately, there is no support in PyROOT to pass a Python callable that represents a C++ callable (the MethodProxy) to a C++ function that expects an std::function.
If you want to do this dynamically, you need to do everything in C++, something like:
res = ROOT.gInterpreter.ProcessLine("reduce(genData(), myOwnFitEF)")
print(res)
All you seem to want to do and more is possible with cppyy (“experimental PyROOT”), so that’s coming.
That said, things are not impossible in PyROOT, but most of what you want has to go through C++ land (i.e. gInterpreter/Cling). Which is, of course, what cppyy does under the hood (just with much higher performance: a few quick measurements of a couple of different scenarios shows cppyy to outperform PyROOT in the range of 3.5x-6x!).
Anyway, the code below makes your example above work.
@Luke_K: no, it’s a separate option, see this other post. I’ve never perused it myself, though.
@ibles: in the world outside HEP, the two most desired features are automatic template instantiations and callbacks. The latter both as in the example here, and cross-inheritance. Needless to say that those are the two corners with the most functional improvements. Below is an example with cppyy master, covering the same as above (where it needs to be said that callbacks into Python are (a lot) more expensive then callbacks into C++, so even as it looks more nice, for simple functions like this, JIT-ing a C++ function should still be preferred).