RDataFrame conditional weight assignment

Dear community, i am using RDataFrame with python 3.6 in order to get a weighted histogram.
The thing is that i have to assign a weight depending on the eta of the particle. So I am defining a new column with the weights as a function of the eta with the following syntax that seems not being accepted by the RDF interface.

RDF_TTree.Define( “weight”, “10[Particle Cuts]”)

In this case, 10 is the weight value that i want to assign to the particles which fits the cuts between [ ]. The printed error says that the int 10 does not provide a subscript operator, the cuts. How can I assign an int to a particular set of tracks?

Kind regards,
Imanol


Please read tips for efficient and successful posting and posting code

ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided


Hi @imanol097 ,
indeed 10[...] is not valid code. I guess what you want is this (or something along these lines):

df.Define("weights", "ROOT::RVec<float> weights(particles.size()); weights[cuts] = 10; return weights;")
  .Histo1D("values", "weights");

Cheers,
Enrico

I tried that, but , error: no viable overloaded ‘=’

Ah, my bad. One sec!

I think the nicest way to write it is to use this Where overload:

Define("weights", "Where(<cut>, 10, ROOT::RVec<float>(particles.size(), 1))"

You can try this a a ROOT or Python prompt first. What Where does is that it returns a new vector that contains 10 for the elements where the <cut> condition is true, otherwise it returns the original element of the RVec we pass as third argument (which is simply an RVec of the appropriate size filled with ones).

I hope this helps!

This would be the solution for my problem, but sth seems to be wrong with Where syntax.

If a write:

Define(“weights”, “Where(mcPart_eta > 2, 10, ROOT::RVec(mcPart_eta.size(), 1))”)

Shows an error: no matching function for call to ‘Where’

Can you copy-paste the full error message? It should also say which overloads it tried and why they don’t match. Also note that ROOT::RVec(mcPart_eta.size(), 1) should be ROOT::RVec<float>(mcPart_eta.size(), 1).

The error is:

input_line_85:2:61: error: no matching function for call to ‘Where’
auto lambda0 = [](ROOT::VecOps::RVec<Float_t>& var0){return Where(var0 > 2, 10, ROOT::RVec(var0.size(), 1))
^~~~~
/cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.22.08/x86_64-centos7-gcc48-opt/include/ROOT/RVec.hxx:1374:9: note: candidate template ignored: deduced conflicting types for parameter ‘T’ (‘int’ vs. ‘float’)
RVec Where(const RVec& c, T v1, const RVec& v2)
^
/cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.22.08/x86_64-centos7-gcc48-opt/include/ROOT/RVec.hxx:1400:9: note: candidate template ignored: deduced conflicting types for parameter ‘T’ (‘int’ vs. ‘ROOT::VecOps::RVec’)
RVec Where(const RVec& c, T v1, T v2)
^
/cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.22.08/x86_64-centos7-gcc48-opt/include/ROOT/RVec.hxx:1318:9: note: candidate template ignored: could not match ‘RVec’ against ‘int’
RVec Where(const RVec& c, const RVec& v1, const RVec& v2)
^
/cvmfs/sft.cern.ch/lcg/app/releases/ROOT/6.22.08/x86_64-centos7-gcc48-opt/include/ROOT/RVec.hxx:1346:9: note: candidate template ignored: could not match ‘RVec’ against ‘int’
RVec Where(const RVec& c, const RVec& v1, T v2)
^
*** Break *** segmentation violation

Oh boy, C++ is being a bit too strict about types, I’ll see if we can relax that a bit.

It should be enough to use 10.f (float) instead of 10 (int).

RVec usage should be more ergonomic than this, I’ll se what I can do about it.

Yes, now it is working.

Define("weights", "WherePreformatted text(<cut>, 10.f, ROOT::RVec<float>(particles.size(), 1))"

@eguiraud Thanks so much for your help!
Imanol

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