Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:27

0001 /*************************************************
0002   Automatically plots histograms from two files
0003   onto the same plot and saves them.
0004   It looksfor ALL histograms in the first file
0005   and plots the corresponding histogram in the 2nd
0006   file onto the sample plot.
0007   
0008   Can be run from a bash prompt as well:
0009     root -b -l -q "plotHistogramsTogether.C(\"fileA.root\",\"fileB.root\")"
0010     root -b -l -q "plotHistogramsTogether.C(\"fileA.root\",\"fileB.root\",\"Signal\",\"Background\",10,2,1)"
0011 
0012   Michael B. Anderson
0013   Sept 5, 2008
0014 *************************************************/
0015 
0016 #include <string.h>
0017 #include "TFile.h"
0018 #include "TH1.h"
0019 #include "TKey.h"
0020 #include "Riostream.h"
0021 
0022 // Accesable everywhere
0023 TObject *obj;
0024 TFile *sourceFile1, *sourceFile2;
0025 TString label1, label2;
0026 TString outputFolder, outputFilename;
0027 TCanvas *canvasDefault;
0028 Float_t scale1, scale2;
0029 bool showStatsBoxes;
0030 
0031 // *******************************************
0032 // Variables
0033 TString imageType = "png";
0034 int outputWidth = 480;
0035 int outputHeight = 360;
0036 bool yAxisLogScale = false;
0037 // End of Variables
0038 // *******************************************
0039 
0040 void recurseOverKeys(TDirectory *target1);
0041 void plot2Histograms(TH1 *htemp1, TH1 *htemp2, TString filename);
0042 
0043 void plotHistogramsTogether(TString fileName1,
0044                             TString fileName2,
0045                             TString fileLabel1 = "",
0046                             TString fileLabel2 = "",
0047                             Float_t fileScale1 = 1.0,
0048                             Float_t fileScale2 = 1.0,
0049                             bool showStats = false) {
0050   // If file labels were not given as argument,
0051   // use the filename as a label
0052   if (fileLabel1 == "") {
0053     fileLabel1 = fileName1;
0054     fileLabel2 = fileName2;
0055     fileLabel1.ReplaceAll(".root", "");
0056     fileLabel1.ReplaceAll(".root", "");
0057   }
0058   label1 = fileLabel1;
0059   label2 = fileLabel2;
0060 
0061   // Set the scale of the histograms.
0062   // If they are < 0.0, they will be area normalized
0063   scale1 = fileScale1;
0064   scale2 = fileScale2;
0065   showStatsBoxes = showStats;
0066 
0067   sourceFile1 = TFile::Open(fileName1);
0068   sourceFile2 = TFile::Open(fileName2);
0069 
0070   outputFolder = "HistogramsTogether/";  // Blank to use current directory,
0071                                          // or, for a specific dir type
0072                                          // something like "images/"
0073 
0074   gSystem->MakeDirectory(outputFolder);
0075 
0076   canvasDefault = new TCanvas("canvasDefault", "testCanvas", outputWidth, outputHeight);
0077 
0078   // This function will plot all histograms from
0079   // file1 against matching histogram from file2
0080   recurseOverKeys(sourceFile1);
0081 
0082   sourceFile1->Close();
0083   sourceFile2->Close();
0084 
0085   TString currentDir = gSystem->pwd();
0086   cout << "Done. See images in:" << endl << currentDir << "/" << outputFolder << endl;
0087 }
0088 
0089 void recurseOverKeys(TDirectory *target1) {
0090   // Figure out where we are
0091   TString path((char *)strstr(target1->GetPath(), ":"));
0092   path.Remove(0, 2);
0093 
0094   sourceFile1->cd(path);
0095 
0096   TDirectory *current_sourcedir = gDirectory;
0097 
0098   TKey *key;
0099   TIter nextkey(current_sourcedir->GetListOfKeys());
0100 
0101   while (key = (TKey *)nextkey()) {
0102     obj = key->ReadObj();
0103 
0104     // Check if this is a 1D histogram or a directory
0105     if (obj->IsA()->InheritsFrom("TH1")) {
0106       // **************************
0107       // Plot & Save this Histogram
0108       TH1 *htemp1, *htemp2;
0109 
0110       htemp1 = (TH1 *)obj;
0111       TString histName = htemp1->GetName();
0112 
0113       if (path != "") {
0114         sourceFile2->GetObject(path + "/" + histName, htemp2);
0115       } else {
0116         sourceFile2->GetObject(histName, htemp2);
0117       }
0118 
0119       outputFilename = histName;
0120       plot2Histograms(htemp1, htemp2, outputFolder + path + "/" + outputFilename + "." + imageType);
0121 
0122     } else if (obj->IsA()->InheritsFrom("TDirectory")) {
0123       // it's a subdirectory
0124 
0125       cout << "Found subdirectory " << obj->GetName() << endl;
0126       gSystem->MakeDirectory(outputFolder + path + "/" + obj->GetName());
0127 
0128       // obj is now the starting point of another round of merging
0129       // obj still knows its depth within the target file via
0130       // GetPath(), so we can still figure out where we are in the recursion
0131       recurseOverKeys((TDirectory *)obj);
0132 
0133     }  // end of IF a TDriectory
0134   }
0135 }
0136 
0137 void plot2Histograms(TH1 *htemp1, TH1 *htemp2, TString filename) {
0138   //TString title = htemp1->GetName();
0139   TString title = htemp1->GetTitle();
0140 
0141   // Make sure histograms exist
0142   if (!htemp2) {
0143     cout << "Histogram missing from 2nd file: " << htemp1->GetName() << endl;
0144     return;
0145   }
0146 
0147   // Scale by given factor.
0148   // If given factor is negative, area normalize
0149   if (scale1 > 0.0) {
0150     htemp1->Scale(scale1);
0151   } else {
0152     Double_t integral = htemp1->Integral();
0153     if (integral > 0.0)
0154       htemp1->Scale(1 / integral);
0155   }
0156   if (scale2 > 0.0) {
0157     htemp2->Scale(scale2);
0158   } else {
0159     Double_t integral = htemp2->Integral();
0160     if (integral > 0.0)
0161       htemp2->Scale(1 / integral);
0162   }
0163 
0164   // Set the histogram colors & lines
0165   htemp1->SetLineColor(kRed);
0166   htemp2->SetLineColor(kBlue);
0167   htemp1->SetLineWidth(1);
0168   htemp2->SetLineWidth(2);
0169 
0170   // Turn off stats
0171   if (!showStatsBoxes) {
0172     gStyle->SetOptStat(0);
0173   }
0174 
0175   // Create TStack but we will draw without stacking
0176   THStack *tempStack = new THStack();
0177   tempStack->Add(htemp1, "sames");
0178   tempStack->Add(htemp2, "sames");
0179 
0180   // Draw the histogram and titles
0181   tempStack->Draw("hist nostack");
0182   tempStack->SetTitle(title);
0183   tempStack->GetXaxis()->SetTitle(htemp1->GetXaxis()->GetTitle());
0184 
0185   // Draw the legend
0186   TLegend *infoBox = new TLegend(0.75, 0.83, 0.99, 0.99, "");
0187   infoBox->AddEntry(htemp1, label1, "L");
0188   infoBox->AddEntry(htemp2, label2, "L");
0189   infoBox->SetShadowColor(0);  // 0 = transparent
0190   infoBox->SetFillColor(kWhite);
0191   infoBox->Draw();
0192 
0193   // Place the stats boxes to be non-overlapping
0194   if (showStatsBoxes) {
0195     canvasDefault->SetRightMargin(0.2);
0196     canvasDefault->Update();
0197     TPaveStats *st1 = (TPaveStats *)htemp1->GetListOfFunctions()->FindObject("stats");
0198     TPaveStats *st2 = (TPaveStats *)htemp2->GetListOfFunctions()->FindObject("stats");
0199     st1->SetX1NDC(.79);
0200     st1->SetX2NDC(.99);
0201     st1->SetY1NDC(.6);
0202     st1->SetY2NDC(.8);
0203     st2->SetX1NDC(.79);
0204     st2->SetX2NDC(.99);
0205     st2->SetY1NDC(.38);
0206     st2->SetY2NDC(.58);
0207     canvasDefault->Modified();
0208   }
0209 
0210   // Set log y axis
0211   if (yAxisLogScale)
0212     canvasDefault->SetLogy(1);
0213   // Save the canvas
0214   canvasDefault->SaveAs(filename);
0215 }