Dear experts,
I’m trying to define functions in C++ that I can compile to make my code run a little bit faster. I’m taking inspiration from the PyRoot manual to know what I should do and transpose it to RDF. The issue is that it is not working as I would like it to.
Basically, I have two files helper.h
and helper.cpp
. Their content is as follows
helper.h
#include "ROOT/RVec.hxx"
using namespace ROOT::VecOps;
class muon {
public:
RVec<float> dimuonKinematics(RVec<float>pt , RVec<float> eta, RVec<float> phi, RVec<float> m);
};
helper.cpp
#include "helper.h"
#include "ROOT/RVec.hxx"
#include "Math/LorentzVector.h"
#include "Math/Vector4D.h"
using namespace ROOT::VecOps;
template <typename T>
RVec<T> dimuonKinematics(const RVec<T>& pt, const RVec<T>& eta, const RVec<T>& phi){
using PtEtaPhiMVectorD = ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<T>>;
T muonRestMass = 0.1056583715;
if (pt.size() != 2) return RVec<T> {};
else{
PtEtaPhiMVectorD P(0.,0.,0.,0.);
PtEtaPhiMVectorD p1(pt[0], eta[0], phi[0], muonRestMass);
PtEtaPhiMVectorD p2(pt[1], eta[1], phi[1], muonRestMass);
P = p1 + p2;
T Pt = P.Pt();
T Pz = P.Pz();
T M = P.M();
T E = P.E();
T Eta = P.Eta();
T Y = log( (E + Pz) / pow( pow(M, 2) + pow(Pt, 2) , 1/2) );
T Phi = P.Phi();
RVec<T> dimuon {Pt, Eta, Phi, M, Y};
return dimuon;
};
};
I try from the CLI the following
>> import ROOT
>>> ROOT.gInterpreter.ProcessLine('#include "helper.h"')
0
>>> ROOT.gInterpreter.Load('libHelper.so')
0
>>> d = ROOT.RDataFrame("Events", "~/pnfs/ScoutingSkim/2022/DY/M-10to50/GenPartInfo/output_3844.1.root")
>>> d = d.Define("dimuonKinematics", 'muon().dimuonKinematics(ScoutingMuon_pt, ScoutingMuon_eta, ScoutingMuon_phi, ScoutingMuon_m)')
IncrementalExecutor::executeFunction: symbol '_ZN4muon16dimuonKinematicsEN4ROOT6VecOps4RVecIfEES3_S3_S3_' unresolved while linking [cling interface function]!
You are probably missing the definition of muon::dimuonKinematics(ROOT::VecOps::RVec<float>, ROOT::VecOps::RVec<float>, ROOT::VecOps::RVec<float>, ROOT::VecOps::RVec<float>)
Maybe you need to load the corresponding shared library?
terminate called after throwing an instance of 'std::runtime_error'
what():
An error occurred during just-in-time compilation in RLoopManager::Run. The lines above might indicate the cause of the crash
All RDF objects that have not run their event loop yet should be considered in an invalid state.
I know the function works because I’ve compiled it without issue using g++ -o libHelper.so -shared -fPIC `root-config --libs --cflags` helper.cxx -I ./
(getting this line from this post and when I’m just putting it in the header file it behaves as expected.
I think the solution should be something like suggested here.
Thanks for your help.
Please read tips for efficient and successful posting and posting code
ROOT Version: 6.32.06
Platform: EL9
Compiler: ?