Looping over root file to create histograms on same plot

So I have a root file: output.root, which has a subfolder ‘FirstCut’, containing 2 histograms, differing in a parameter which is 30 for the first histogram and 50 for the second. Now I want to loop over this parameter, and draw both histograms on the same plot. The path of these histograms is FirstCut_30 and FirstCut_50. This is my attempt:

ROOT Version: 6.18/04
Linux

void Function(){
Tfile *f = new TFile ("output.root");
std::vector<double> FirstCut = {30, 50};
for (unsigned i = 0; i < FirstCut.size(); ++i){
  TH1D *h[i] = (TH1D*)f->Get("FirstCut_[i]");
  h[i]->Draw(same); 
  }
}

I get 2 errors:

  • variable sized object may not be initialised (where it points at the h in h[i])
  • use of undeclared identifier ‘same’ (in Draw(same))

Many mistakes in your code…
I do not have your ROOT file, so here is my guess:

void Function(){
   auto f = new TFile ("output.root");
   f->cd("FirstCut"); // you said your histograms are in the subfolder "FisrtCut"
   std::vector<int> FirstCut = {30, 50};
   int n = FirstCut.size();
   TH1D *h[n];
   for (unsigned i = 0; i < n; i++) {
     h[i] = (TH1D*)f->Get(Form("FirstCut_%d",FirstCut[i]));
     if (i==0) h[i]->Draw(); 
     else h[i]->Draw("same")
  }
}
1 Like

Thanks! It worked! Do you know how I can give the different histograms different colours?

Yes you can:

h->SetLineColor(...);
1 Like

I am now trying to divide a histogram (let’s call it k1) by these histograms and plot these ‘ratios’ on the same graph. I tried this:

void Function(){
  auto f = new TFile ("output.root");
  TH1D *k1 = (TH1D*)f->Get("SecondCut");
  std::vector<int> FirstCut = {30, 50};
  int n = FirstCut.size();
  TH1D *h[n];
  TH1D *ratio[n]; 
  for (unsigned i = 0; i < n; i++) {
    h[i] = (TH1D*)f->Get(Form ("FirstCut_%d", FirstCut[i]));
    TH1D *ratio[i] = new TH1D(*k1);
    ratio[i]->Divide(h[i]);
    ratio[i]->SetNameTitle("hratio", "k1/h_%d"); 
    if (i==0) ratio[i]->Draw();
    else ratio[i]->Draw("same")
  }
}

But I get the error that variable-sized object may not be initialised: TH1D *ratio[i] = new TH1D(*k1);

Do you perhaps know what I am doing wrong?

should be:

ratio[i] = new TH1D(*k1);

It works again! Thanks a lot!

1 Like

I am back again… I was just wondering, I am dividing these histograms to obtain an efficiency and so I want the y values to be between 0 and 1. However, the errors exceed these limitations, and I think this might be the case because my k1 histogram is a subset of my h histograms. I read something about using TEfficiency class rather than the Divide function, but I am not sure on how to use that in this case.

I think @moneta can help you with this.

1 Like

See the TEfficiency documentation
https://root.cern.ch/doc/master/classTEfficiency.html

It is very detailed and there you have examples on how to use it .
If you have specific questions, please let us know.

Lorenzo

1 Like

Hello. I have a root file within which there is a folder which contains different histogram. I want to loop those and plot different histogram for all of them. The folder name is Energy spectra and within that there are histograms named Energy ch 1;1 , Energy ch 2;1, Energy ch 3;1, and so on.

I wrote the following code and it did not work

#include
#include <TFile.h>
#include <TH1D.h>
#include <TCanvas.h>
#include

using namespace std;

void tut17() {
//Open an existing ROOT File using the READ command. READ is used so as to not modify the data saved in the ROOT file.
TFile* fileOut = TFile::Open(“C:/root_v5.34.36/macros/run00037_000.root”, “READ”);
//TFile *fileOut = TFile::Open(“ROOT DIRECTORY + /DAQRoot.root”,“READ”);

if (!fileOut) {
	cout << "File not found." << endl;
	return 0;
}

TDirectory* folder = (TDirectory*)fileOut->Get("Energy spectra"); // get the folder from the file

for (int i = 1; i < 33; i++)
{
	//std::cout << file_name << std::endl;
	TH1F* histo[i] = (TH1F*)folder->Get(Form("Energy ch %d",i)); // get the histogram from the folder
	//double counts = histo->Integral(200, 1000);

	TCanvas* canvas = new TCanvas("canvas", "Histogram", 800, 600); // create a canvas for the plot

	histo[i]->Draw("same");// draw the histogram
	//cout << counts << endl;
	//cout << histo[i]->Integral(200, 1000) << endl;


	//canvas->SaveAs("histo.pdf"); // save the plot as a pdf
}

}

Hi @Bikash,

Could you please open a new topic regarding your issue – you posted (3 years later!) on a topic that was marked as resolved. Also, when you do so, could you be more specific about the errors that you are getting?

It seems that there are syntactic errors in the excerpt you posted, e.g. some of the #include lines or the declaration quoted below

Cheers,
J.

The new post is here: Plotting histogram by looping