Creating a column of std::vector<ROOT::Math::PtEtaPhiEVector> with RDataFrame

Dear experts,

I am currently trying out RDataFrame using pyROOT. At the moment, I am able to create simple variables as new columns from the available vector<float> branches in my ttree such as the number of elements of a vector and the first element stored in a vector. What I want to do next is to create a new column which consists of a std::vector <ROOT::Math::PtEtaPhiEVector> from the following std::vector<float> branches:

std::vector<float> refpt
std::vector<float> rephi
std::vector<float refeta
std::vector<float> refe

I tried to do the following:

import ROOT

ROOT.gROOT.SetBatch()
ROOT.ROOT.EnableImplicitMT()

treeName="t"
fileName="ntuples.root"

df = ROOT.ROOT.RDataFrame(treeName,fileName)
df_defined = df.Define("nrefjet","refpt.size()")\
               .Define("ref0pt", "refpt[0]")\
               .Define("refjetvec","VecOps::Construct<ROOT::Math::PtEtaPhiEVector> v(refpt,refeta,refphi,refe); return v;")

and it produces the following error:

input_line_61:5:1: error: use of undeclared identifier 'VecOps'
VecOps::Construct<ROOT::Math::PtEtaPhiEVector> v(refpt,refeta,refphi,refe); return v;
^
input_line_61:5:46: error: expected '(' for function-style cast or type construction
VecOps::Construct<ROOT::Math::PtEtaPhiEVector> v(refpt,refeta,refphi,refe); return v;
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~^
input_line_61:5:48: error: use of undeclared identifier 'v'
VecOps::Construct<ROOT::Math::PtEtaPhiEVector> v(refpt,refeta,refphi,refe); return v;
                                               ^
input_line_61:5:84: error: use of undeclared identifier 'v'
VecOps::Construct<ROOT::Math::PtEtaPhiEVector> v(refpt,refeta,refphi,refe); return v;
                                                                                   ^
Traceback (most recent call last):
  File "TryOutRDataFrame.py", line 15, in <module>
    .Define("refjetvec","VecOps::Construct<ROOT::Math::PtEtaPhiEVector> v(refpt,refeta,refphi,refe); return v;")
Exception: ROOT::RDF::RInterface<ROOT::Detail::RDF::RLoopManager,void> ROOT::RDF::RInterface<ROOT::Detail::RDF::RLoopManager,void>::Define(experimental::basic_string_view<char,char_traits<char> > name, experimental::basic_string_view<char,char_traits<char> > expression) =>
    Cannot interpret the following expression:
VecOps::Construct<ROOT::Math::PtEtaPhiEVector> v(refpt,refeta,refphi,refe); return v;

Make sure it is valid C++. (C++ exception of type runtime_error)

Obviously the syntax is wrong but I’m not too sure what is the right way to do this.

I am running on lxplus 7 with ROOT version 6.14.00.

Cheers,
Fikri

Hi Fikri,
v6.14 does not have ROOT::VecOps::Construct, it’s a very new feature. In fact, not even v6.16 has it: https://root.cern/doc/v616/namespaceROOT_1_1VecOps.html.

You can use ROOT master from one of our nightly builds available on lxplus, or wait for v6.18 to be released and, in the meanwhile, manually construct the vector.

To use ROOT nightlies on lxplus7 (not always stable, but fairly stable, but use at your own risk):

source /cvmfs/sft-nightlies.cern.ch/lcg/views/dev3/latest/x86_64-centos7-gcc62-opt/setup.sh

Cheers,
Enrico

Hi Enrico,

Thanks for pointing it out. Will wait for v6.18 to be released. In the meantime, I have defined and use the following function:

RVec<ROOT::Math::PtEtaPhiEVector> ConstructP4Vector(RVec<float>& pt, RVec<float>& eta, RVec<float>& phi, RVec<float>& e){
  RVec<ROOT::Math::PtEtaPhiEVector> vec;
  const auto size = pt.size();
  vec.reserve(size);
  for (auto i = 0; i < size; ++i) {
    vec.emplace_back(pt.at(i),eta.at(i),phi.at(i),e.at(i));
  }
  return vec;
}

and call it in Define:

import ROOT

ROOT.gROOT.SetBatch()
ROOT.ROOT.EnableImplicitMT()

treeName="t"
fileName="ntuples.root"

df = ROOT.ROOT.RDataFrame(treeName,fileName)
df_defined = df.Define("refjetvec","ConstructP4Vector(refpt,refeta,refphi,refe)")

Many thanks again!

Cheers,
Fikri

2 Likes

Well done!

Cheers,
Enrico

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