Is it possibile to fill a histogram with non uniform binning with a RDataframe?

Hello,
I have to fill many histograms with variables from a TTree, and I figured a RDataFrame would speed up the computation.
However, I wish to produce histogram with non uniform bin widths, which I understand is the default behavior when doing something like:

df = RDataFrame(tree_name,file_name)
h = df.Histo1D({h_name,h_title,n_bins,min,max},variable_name)

I couldn’t find any info on how to possibly fill histograms with custom binning schemes.
Thanks in advance,
Andrea


ROOT Version: 6.18.04
Platform: CentOS 7
Compiler: gcc 8.3.0


Hi @avilla,
welcome to the ROOT forum!
As per the docs, the first argument to Histo1D is a TH1DModel, that you can construct in pretty much all the same ways you can construct a TH1D, including with custom bins, or even just from a TH1D object itself.

Cheers,
Enrico

Hi @eguiraud,
Thanks for the response, I somehow missed that.
I did some experimenting and now I have an additional question: what is the best way to declare the bin edges when creating the histogram in Python?
In C++, I would usually declare an array containing the bin edges and create a histogram like

float edges [5] = {1,2,3,4,5};
auto h = new TH1D("h", "h", 4, edges);

I tried to do the same in Python with either a list or a numpy array, using

edges = range(6) #list
edges = np.arange(1,6) #numpy array
df.Histo1({h_name, h_title, 4, edges}, variable_name)

but in both cases I get the error TypeError: unhashable type: 'list' or TypeError: unhashable type: 'numpy.ndarray'
What should I do to define the histogram bin edges correctly?
Thanks again,
Andrea

Hi,
almost there, there’s just two things:

  • you can use {} to implicitly construct objects in C++, but not in Python. In PyROOT we use () to mimic the C++ feature
  • whenever the C++ interfaces require a pointer, you can pass an array in PyROOT
from array import array
df.Histo1D(("h", "h", 4, array('d', [1,2,3,4,5])), "x")

or

bins = array('d', [1,2,3,4,5])
model = ROOT.RDF.TH1DModel("h", "h", 4, bins)
df.Histo1D(model, "x")

Hope this helps!
Enrico

2 Likes

Hi Enrico,
yes, that does exactly what I wanted. Thank you so much.
Cheers,
Andrea

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