Problems with precompiled C++ library in jupyter notebook using RDataFrame

Dear Experts,

I’ve made a simple library in C++ which I try to include in my python3 jupyter-notebook and use with RDataFrame. I compile the library in root

.L Cfunctions.cxx+

In the jupyter-notebook I do

R.gSystem.Load("./Cfunctions_cxx.so")
R.gInterpreter.Declare('#include "Cfunctions.h"')

However, when I try to use the function in the notebook with my RDataFrame

sum = df.Filter("myFilter(nVtx)").Sum("mu")

I get the error message below. Does anyone understand what I am doing wrong? I’m using ROOT version 6.22/09. Example code can be found here: CERNBox

Thanks a lot for any help!

best,
Eirik

---------------------------------------------------------------------------
runtime_error                             Traceback (most recent call last)
<ipython-input-9-a5c3de41fe1a> in <module>
----> 1 sum = df.Filter("myFilter(nVtx)").Sum("mu")

runtime_error: Template method resolution failed:
  ROOT::RDF::RInterface<ROOT::Detail::RDF::RJittedFilter,void> ROOT::RDF::RInterface<ROOT::Detail::RDF::RJittedFilter,void>::Filter(experimental::basic_string_view<char,char_traits<char> > expression, experimental::basic_string_view<char,char_traits<char> > name = "") =>
    runtime_error: 
RDataFrame: An error occurred during just-in-time compilation. The lines above might indicate the cause of the crash
 All RDF objects that have not run an event loop yet should be considered in an invalid state.

  ROOT::RDF::RInterface<ROOT::Detail::RDF::RJittedFilter,void> ROOT::RDF::RInterface<ROOT::Detail::RDF::RJittedFilter,void>::Filter(experimental::basic_string_view<char,char_traits<char> > expression, experimental::basic_string_view<char,char_traits<char> > name = "") =>
    runtime_error: 
RDataFrame: An error occurred during just-in-time compilation. The lines above might indicate the cause of the crash
 All RDF objects that have not run an event loop yet should be considered in an invalid state.


input_line_98:2:39: error: use of undeclared identifier 'myFilter'
auto lambda5 = [](Int_t& var0){return myFilter(var0)

Hi Erik,
and welcome to the ROOT forum!

myFilter (at global scope) does not exist as you defined it as a method of class Cfunctions.

As a minimal example, this should work:

// functions.cxx
bool myfilter(float x) {
   return x > 5;
}
# test.py
import ROOT
ROOT.gInterpreter.ProcessLine(".L functions.cxx+")
print(ROOT.myfilter(4))
print(ROOT.RDataFrame(1).Define("x", "42").Filter("myfilter(x)").Count().GetValue())

and python test.py prints:

False
1

Cheers,
Enrico

EDIT:
@etejedor maybe Python interface: PyROOT - ROOT might benefit from a simple example like this

Thanks for the prompt reply @eguiraud !

Your example seems to work. Thanks.
However, I’m curious to understand how exactly the library myLibrary.h would look like for this example to work:

ROOT.gSystem.Load("path/to/myLibrary.so") # Library with the myFilter function
ROOT.gInterpreter.Declare('#include "myLibrary.h"') # Header with the definition of the myFilter function
df = ROOT.RDataFrame("myTree", "myFile.root")
sum = df.Filter("myFilter(x)").Sum("y")
print(sum.GetValue())

(taken from ROOT: ROOT::RDataFrame Class Reference)

best,
Eirik

For example:

[eguiraud@lxplus745 test_gsystem_load]$ cat myLibrary.h
bool myFilter(float);
[eguiraud@lxplus745 test_gsystem_load]$ cat myLibrary.cxx
#include "myLibrary.h"

bool myFilter(float x) {
    return x > 0;
}
[eguiraud@lxplus745 test_gsystem_load]$ cat foo.py
import ROOT
ROOT.gInterpreter.Declare('#include "myLibrary.h"')
ROOT.gSystem.Load("myLibrary.so")
print(ROOT.myFilter(-5))
print(ROOT.myFilter(42))
[eguiraud@lxplus745 test_gsystem_load]$ g++ -shared -fPIC -o myLibrary.so myLibrary.cxx
[eguiraud@lxplus745 test_gsystem_load]$ python foo.py
False
True

Cheers,
Enrico

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.