Overlaying histograms from root file in loop

Hey,

I can open several root files and overlay the histograms in them. However, I have 50 root files (which I can open simultaneously and access a particular histogram in them), however, I am not sure how best to take 5 files at a time (and therefore 5 histograms) and overlay them, then move onto the next 5 histograms and overlay them. I want to take the first 5 root files, open them, access a histogram and overlay them, then move onto the next 5 root files and repeat.

I am giving a short snippet (i.e only going to list 10 files rather than all 50) of what I have.

        void Overlaying_Plots() { //OPENING BRACE

       std::vector<std::string> File_Names = { "mc_Plots_Cos_CS_Theta_Mu0Mu0Y0.root",      
					  "mc_Plots_Cos_CS_Theta_Mu0Mu0Y1.root",
					  "mc_Plots_Cos_CS_Theta_Mu0Mu0Y2.root",
					  "mc_Plots_Cos_CS_Theta_Mu0Mu0Y3.root",
					  "mc_Plots_Cos_CS_Theta_Mu0Mu0Y4.root",
					  "mc_Plots_Cos_CS_Theta_Mu0Mu0Y5.root"
		       
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y0.root",
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y1.root",
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y2.root",
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y3.root",
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y4.root",
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y5.root",
					  };
   
       std::vector<std::string> Histogram_Names = {"mc23099"};					          
      const int numFiles = sizeof(File_Names)/sizeof(File_Names[0]);
       const int numHistograms = 2;

      TFile *f[numFiles];
      TCanvas *c[numHistograms];
      for (int i=0; i< numFiles; i++){

        f[i] = TFile::Open(File_Names[i].c_str());

        TH1D *h[i];
         f[i]->GetObject(Histogram_Names[0].c_str(),h[i]);

           h[i]->SetLineColor(i+2);
          TString options = (j>0? "SAME C" : "C" );
          h[i]->DrawCopy(options);
          c[i]->SetLogy();
          c[i]->Update();
      }
    }//Closing Brace

ROOT Version (e.g. 6.12/02):
Platform, compiler (e.g. CentOS 7.3, gcc6.2):


You do not open any canvas … you only create an array of pointer to canvases.
You can create a canvas in the loop print it and then delete it when your plot is finished (5 histogram overlayed) unless you want to have the 10 canvases on screen ? You can also open one canvas and used Divide you make several overlaid plots on the same page.

Hey,

I have made a couple of changes, however it only seems to access the 0th and 6th root file, and only plots the 0th histogram:

    std::vector<std::string> File_Names = { "mc_Plots_Cos_CS_Theta_Mu0Mu0Y0.root",      //Declare the file names in the file File_Names.c_str
					  "mc_Plots_Cos_CS_Theta_Mu0Mu0Y1.root",
					  "mc_Plots_Cos_CS_Theta_Mu0Mu0Y2.root",
					  "mc_Plots_Cos_CS_Theta_Mu0Mu0Y3.root",
					  "mc_Plots_Cos_CS_Theta_Mu0Mu0Y4.root",
					  "mc_Plots_Cos_CS_Theta_Mu0Mu0Y5.root"
			       
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y0.root",
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y1.root",
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y2.root",
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y3.root",
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y4.root",
					  "mc_Plots_Cos_CS_Theta_Mu1Mu1Y5.root",

					};
  
        std::vector<std::string> Histogram_Names = {"mc23099"};					     
           const int numHistograms = 6;

       TFile *f[File_Names.size()];
      TCanvas *c[numHistograms];

      cout << "nFiles: " << File_Names.size() << endl;
  
      for (int i=0; i< File_Names.size(); i+=5){
   
       f[0] = TFile::Open(File_Names[i].c_str());
       f[0]->Print();

       TH1D *h[5];
       f[0]->GetObject(Histogram_Names[0].c_str(),h[0]);   
     h[0]->Print();
     

     c[0] = new TCanvas(TString::Format("Overlay_Cos_CS_Theta_%i", i), TString::Format("Overlay_Cos_CS_Theta_%i", i), 700, 500);  //Declaring TCanvas on which to superimpose the two histograms.
     h[0]->SetLineColor(i+2);
     TString options = (i>0 ? "SAME C" : "C" );
     h[0]->DrawCopy(options);
     c[0]->SetLogy();
     c[0]->Update();

     }    
     

    }//Closing Brace

i+=5 is the reason why it does that.

And you (re)create your canvas for each i (so the old contents is deleted and you always see just one histogram drawn).

Hey,

I have managed to solve all my problems with this for the moment, and can now iterate through all 50 files, open them in blocks of 5 and overlay them.

Thanks for the tips!

You need to loop on the 50 files and every 5 plots you reset the canvas or you cd() to the next pad if you are using a Divided canvas. But now the code you posted if far to do anything like that. I think your problem is more in the C++ logic of your loop(s) than on ROOT itself.

Try this one. It kind of simulate what you are asking for:

{

   TCanvas *c = new TCanvas("c","c",1800,500);
   c->Divide(10,1);
   TH1F *h;
   int n=0; 
   int p=1;
   for (int i=1; i<=50; i++) {
      n++;
      h = new TH1F(Form("h%d",i), Form("h%d",i), 50, 0, 51);
      h->SetLineColor(i);
      h->Fill(i);
      if (n==1) {
         c->cd(p);
         h->Draw();
      } else if (n==5) {
         n = 0;
         p++;
         h->Draw("SAME");
      } else {
         h->Draw("SAME");
      }
   }
}

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