2D histogram in RDataFrame with parameters on axis

Dear ROOT and RDataFrame experts,

I am wondering and trying to know if it’s possible to book a histogam in a RDataFrame that would contain a parameter on one of the axis.

For example, let’s say that I have a set of variables (var1, var2, var3) in my Tree that are input to a new variable new_var. However this new variable also needs of a parameter par to be built:

double new_var(double var1, double var2, double var3, double par){
    return //some combination of variables

What I want to accomplish is to book and fill a histogram using RDataFrames which will have as axis:

  • x-axis: values of the parameter par
  • y-axis: distribution of the new_var given the value of par.

I know that this could be possibly done using custom actions, but this seemed over-complicated for this simple task. Is it possible to accomplish this? Maybe creating a simple c++ function? It’s obvious that I do not want to create like ~100 extra columns for different values of par

Thank you very much, and any idea/help is highly appreciated.


Please fill also the fields below. Note that root -b -q will tell you this info, and starting from 6.28/06 upwards, you can call .forum bug from the ROOT prompt to pre-populate a topic.

ROOT Version: 6.28
Platform: Linux, macOS

Hi @fsili,

IIUC your post, I see no reason why this cannot be done using a combination of Define() and Histo2D().

I have a question though: is par a compile-time constant or does it come from another column in your dataset?


Hello, and thanks for your response.

The parameter par is a variable that I need to supply its limits and its step size. So for example, if I want my final TH2D to have in the x-axis the parameter, I would say at run-time its limits and how many bins it should have.

How can I do this with define? I mean, I ask this because the new_var will take, on a event-by-event basis, as many values as par will take.

So, I have the following:

  • par will take 100 values between 0 and 0.5
  • for each event I compute new_var for each value of par: 100 new_var values.

Is this possible to do with a simple Define()?

Thanks a lot,


I guess that’s a job for Vary() instead. I’ll invite @vpadulan and @eguiraud here as they may have some suggestions.


Hello @fsili ,

if I understand the situation correctly, for every event you can Define an array of 100 values for par and then compute an array of 100 new_var values, and then simply fill a TH2D with those arrays (which will fill the histogram with each element of the arrays, looping over them in lockstep:

df.Define("pars", [] { /* return a RVecF or RVecD of 100 elements */ })
  .Define("new_vars", { /* return a RVecF/RVecD of 100 elements as a function of */, {"pars"})
  .Histo2D("pars", "new_vars");

Does that help?

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