RooAbsReal with python callback


I’m trying to write a C++ class inheriting from RooAbsReal that will do a python callback (to use something from scikit-learn). Originally I found this:
[url]TSelector in Python but it is very old. The gcc command there to build the shared library gives rise to a lot of linking problems, so I tried to make a small shared library instead.

I’m having problems early on in making a shared library since rootcint either can’t find Python.h or it gets confused.

I put my current code here: … /sharedLib

When I try make, I get

rootcint -f SciKitLearnWrapperDict.cxx -c MyHelpers.h SciKitLearnWrapper.h LinkDef.h Error: cannot open file "Python.h" SciKitLearnWrapper.h:17:
I’m not sure how to indicate to rootcint what the include path should be.
(My pyroot setup works fine, and I’m using OS X builtin python currently)

So instead I try to forward declare in the header files with:

#ifndef PyObject_HEAD struct _object; typedef _object PyObject; #endif

but that leads to this error

clang++ `python-config --include` -O2 -pipe -Wall -W -Woverloaded-virtual -pthread -stdlib=libc++ -m64 -I/Users/cranmer/projects/roostats/root-v5-34/include -c SciKitLearnWrapperDict.cxx In file included from SciKitLearnWrapperDict.cxx:17: In file included from ./SciKitLearnWrapperDict.h:32: In file included from /Users/cranmer/projects/roostats/root-v5-34/include/TObject.h:232: /Users/cranmer/projects/roostats/root-v5-34/include/TBuffer.h:378:35: error: 'typeid' of incomplete type '_object' TClass *cl = TBuffer::GetClass(typeid(Tmpl)); ^ SciKitLearnWrapperDict.cxx:128:12: note: in instantiation of function template specialization 'operator>><_object>' requested here R__b >> m_callback;

So I’m currently stuck even with the simple example.



some progress…

If I by-hand add #include “Python.h” into the generated dictionary code (SciKitLearnWrapperDict.cxx) and modify the generic Makefile to add the -lRooFit -lRooFitCore, then the compilation warnings go away, but I’m left with this problem.

clang++ `python-config --include` -O2 -pipe -Wall -W -Woverloaded-virtual -pthread -stdlib=libc++ -m64 -I/Users/cranmer/projects/roostats/root-v5-34/include -c SciKitLearnWrapperDict.cxx clang++ -dynamiclib -single_module -install_name /Users/cranmer/projects/gitHub/parametrized-learning/sharedLib/ -O2 -mmacosx-version-min=10.9 -m64 MyHelpers.o SciKitLearnWrapper.o SciKitLearnWrapperDict.o -o -L/Users/cranmer/projects/roostats/root-v5-34/lib -lGui -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lpthread -Wl,-rpath,/Users/cranmer/projects/roostats/root-v5-34/lib -stdlib=libc++ -lm -ldl -lRooFit -lRooFitCore Undefined symbols for architecture x86_64: "_PyObject_CallFunction", referenced from: SciKitLearnWrapper::evaluate() const in SciKitLearnWrapper.o ld: symbol(s) not found for architecture x86_64

FYI: my python seems to be built in 64 bit mode:

python -c 'import struct;print( 8 * struct.calcsize("P"))' 64
updated link to code … 981530f590

Hi Kyle,

is the fact that you inherit from RooAbsReal crucial here? For the sake of simplicity, I removed the RooFit dependency and let the class inherit from TNamed. guarding the python include and PyObject_CallFunction call with ifndef CINT, makes rootcint shut up and I get with this python code

from ROOT import *
gSystem.Load( 'libSciKitLearnWrapper' )
gROOT.LoadMacro( 'MyHelpers.h+' )

def SayHi():
   print 'Hi from python!'

s = CreateMyClass()
RegisterCallBack( SayHi );

this output:

lukasmba-2 /Users/lukas/Code/scratch/parametrized-learning/sharedLib python 

RooFit v3.60 -- Developed by Wouter Verkerke and David Kirkby 
                Copyright (C) 2000-2013 NIKHEF, University of California & Stanford University
                All rights reserved, please read

Hi from C++!
Hi from python!


PS: also had to add -lPython in the linking.
PPS: see my pull request for a working rooabsreal example

Thanks Lukas,

It seems like the helper is not necessary anymore. This works:

from ROOT import *
gSystem.Load( 'libSciKitLearnWrapper' )

def SayHi():
   print 'Hi from python!'

x = RooRealVar('x','x',0,1)
s = SciKitLearnWrapper('s','s',x)
s.RegisterCallBack( SayHi );
print s.getVal()

Just to close this topic completely, I’ve made a small GitHub repository that is a minimal working example of a shared library with this python callback for a RooAbsReal