Access to histograms from cuts of ntuple

I have a large ntuple that records energy deposits in a 3D matrix (the columns are CopyNo (a kind of global index) and Edep). I need to cut the tuple into 2D slices, create a histogram for each slice, and use bin center values and frequency values from these histograms in further analysis.

This is essentially what I have tried (showing only one slice for simplicity):

import ROOT
rootfile = ROOT.TFile("data.root")
mytuple = rootfile.Get("tuplename")
mytuple.Draw("Edep>>histoname", "CopyNo % 275 == 10")

This nicely(!) creates a plot of a histogram for the single slice, however I need:

  1. Access to the actual histogram ‘histoname’ itself (eg, to get frequency values)

  2. Be able to rebin the histogram with a uniform number of bins (or create the histogram from the slice with the proper number of bins in the first place (??? by another method instead of using ‘>>’ ???). This is necessary because each slice must to use the exact same bins

This might help to clarify:

Before I starting using the ROOT ntuple as a data source, I created histograms from an array using code like this:

import numpy as np
...
#energy_data is an numpy array of Edep values
energy_counts, energy_bins = np.histogram(energy_data, bins=np.arange(np.floor(min_energy), np.ceil(max_energy) + 1))

# now, use energy_counts, etc in analysis

So, I essentially want to use the ROOT histograms to get energy_counts for a fixed set of bins from each slice of the ntuple.

I am new to ROOT, and would greatly appreciate suggestions on how proceed.

[quote][/quote]

Ok, it looks like this allows access to histogram objects with specified bin number etc. for each slice:

import ROOT
rootfile = ROOT.TFile("data.root")
mytuple = rootfile.Get("tuplename")
histos = []
nslices = 5
for i in range(nslices) :
    histoname = "histo_%d" % (i, )
    mytuple.Draw("Edep>>" + histoname + "(1000, 0, 1e-5)", "CopyNo % 275 == " + str(i))
    h = getattr(ROOT, histoname)
    histos.append(h)

Now I just need to get the bin centers and bin counts …

Continuing work on this, I have three questions:

  1. Am I correct that the only way to get frequency and bin center values from a TH1 histogram is looping through it by bin number? Ie, something like:
h = getattr(ROOT, histoname)
xaxis = h.GetXaxis()
freq = []
bincenters = []
for i in range (1, numberOfBins + 1) :
    freq.append(h.GetBinContent(i))
    bincenters.append(xaxis.BetBinCenter(i))
  1. I like that I can automatically cut my ntuple and create a histogram of the cut at the same time using Draw() method, eg:
mytuple.Draw("Edep>>histoname", "CopyNo % 275 == 10")

However, this also opens a canvas window. I will soon be running my script on a machine with no graphics. Can I somehow tell ROOT not to open a window? The ROOT documentation mentions in section 3.8:

However, I don’t see how to disconnect the graphics for a batch mode.

  1. Just in case there is no way to use the Draw() method as above and disconnect the graphics (see question 2): Other than looping through all the Events in the ntuple, is there another way to i) create a cut of an ntuple, and ii) create a TH1 object from the cut?

Help with these three questions would be much appreciated.

Hi,

sorry for the late reply, but I’m traveling (and will be for a couple more weeks).

Not sure of some of the details, as it seems to me one of those cases that have been done before, so there must be a clean solution already. :slight_smile: Just that I don’t know of it, and you may have better luck on the ROOT support forum.

Anyway, ad 1) I’d argue you’re better of creating your own histograms, so that you can control the number of bins and the range. Ad 2) gROOT.SetBatch() should do the trick. Ad 3) that would depend on the structure of the ntuple (it may even be worth it, depending on size), to read the whole thing in, or to read it into a 2D histo and slice that.

Cheers,
Wim

Thanks Wim, this is helpful.