Filling histograms from a Chain

Hi everyone,

I’m sure I’m doing something silly wrong! I’ve made a TChain out of two files and then run MakeClass on it using this:

void analysis(){
    TChain chain("outTree"); 
    chain.Add("SherpaJZ7.root");
    chain.Add("SherpaJZ8.root"); 
    chain.MakeClass("HistogramChain");
}

I’ve edited the resulting .C file so it reads as follows:

void HistogramChain::Loop()
{
if (fChain == 0) return;

   Long64_t nentries = fChain->GetEntriesFast();

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      nb = fChain->GetEntry(jentry);   nbytes += nb;
      // if (Cut(ientry) < 0) continue;
   }
  
   
   Long64_t N = fChain->GetEntries();
   std::cout <<  N << std::endl;
   TH1F *h = new TH1F("h", "Jet pT", 100, 50, 2500.);
   
  for (Long64_t i = 0; i < N; i++) {
    GetEntry(i);
    for (unsigned long j = 0; j <jet_pt->size(); j++) {
        h->Fill(jet_pt->at(j),1.);
    }
  }
  
}

The number of entries it returns is the sum of the entries in each individual file, and it doesn’t give any error messages, but it doesn’t produce a histogram either! I’ve looked at similar topics on this forum but the answers seemed to involve complicated modifications to the header file and I don’t understand why it won’t work as is… I’ve added a link to my two root files. Thank you for any help, I really appreciate it!

Hi @KatR,
your code creates the histogram (TH1F *h = new TH1F("h", "Jet pT", 100, 50, 2500.);) and fills the histogram (h->Fill(jet_pt->at(j),1.);) but as far as I can tell there is no code to save or draw the histogram.

You can save a histogram to a file by creating a TFile and then calling h->Write(), or you can draw it with h->Draw(). Both operations should be performed after the for loop over entries, at the very end of your Loop function.

Also note that with a recent-enough ROOT version, it’s much simpler to produce such a histogram with RDataFrame. At the ROOT prompt it’s just one line (no MakeClass editing required):

root [0] auto h = ROOT::RDataFrame("treename", {"file1.root", "file2.root"}).Histo1D("jet_pt");
root [1] h->Draw()

Hope this helps!
Enrico

Oh dear, that really was a stupid mistake… Thanks for your help Enrico, I’ll look into RDataFrame too!

1 Like