ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/RootMacros/plotCorrespondingHists.C
Revision: 1.1
Committed: Tue Sep 29 22:17:18 2009 UTC (15 years, 7 months ago) by anderson
Content type: text/plain
Branch: MAIN
Log Message:
Auto plot all histograms from multiple files together

File Contents

# User Rev Content
1 anderson 1.1 /*************************************************
2     Automatically plots histograms from two or more
3     files onto the same plot and saves them.
4    
5     This first looks for ALL histograms in the first
6     file then and plots the corresponding histograms
7     from the rest of the files onto the sample plot.
8    
9     Images are saved into a directory structure
10     that copies the structure of the root files.
11    
12     Can be run from a bash prompt as well:
13     root -b -l -q "plotCorrespondingHists.C(\"fileA.root\",\"fileB.root\")"
14     root -b -l -q "plotCorrespondingHists.C(\"fileA.root\",\"fileB.root\",\"fileC.root\")"
15    
16     Michael B. Anderson
17     Sept 29, 2009
18     *************************************************/
19    
20    
21    
22     // *******************************************
23     // Variables
24     TString imageType = "gif";
25     TString outputFolder = "HistogramsTogether/";
26     int plotWidth = 480;
27     int plotHeight = 360;
28     bool plotLogY = false;
29     bool areaNormalize = false;
30     // Turn off stats box
31     gStyle->SetOptStat(0);
32     // End of Variables
33     // *******************************************
34    
35     void plotCorrespondingHists(TString fileName1, TString fileName2) {
36     vector<TString> fileNames;
37     fileNames.push_back( fileName1 ) ;
38     fileNames.push_back( fileName2 ) ;
39     plotCorrespondingHists( fileNames );
40     }
41    
42     void plotCorrespondingHists(TString fileName1, TString fileName2, TString fileName3) {
43     vector<TString> fileNames;
44     fileNames.push_back( fileName1 ) ;
45     fileNames.push_back( fileName2 ) ;
46     fileNames.push_back( fileName3 ) ;
47     plotCorrespondingHists( fileNames );
48     }
49    
50     void plotCorrespondingHists(TString fileName1, TString fileName2, TString fileName3, TString fileName4) {
51     vector<TString> fileNames;
52     fileNames.push_back( fileName1 ) ;
53     fileNames.push_back( fileName2 ) ;
54     fileNames.push_back( fileName3 ) ;
55     fileNames.push_back( fileName4 ) ;
56     plotCorrespondingHists( fileNames );
57     }
58    
59     void plotCorrespondingHists(vector<TString> fileName) {
60    
61     TString firstFileName = fileName[0];
62    
63     if (firstFileName == "" ) return;
64    
65     // Open all the files & create a list of Labels
66     TList *fileList = new TList();
67     TList *listOfLabels = new TList();
68     for (int i=0; i<fileName.size(); i++) {
69     cout << "Opening " << fileName[i] << " ..." << endl;
70     fileList->Add( new TFile(fileName[i]) );
71     listOfLabels->Add( new TObjString(fileName[i].ReplaceAll(".root","")) );
72     }
73    
74     // Create a list of all the histograms in the file
75     TList *listOfHistograms = new TList();
76     TFile *firstFile = (TFile*)fileList->First();
77     gSystem->MakeDirectory(outputFolder);
78     recurseOverKeys( firstFile, listOfHistograms );
79    
80     cout << "Found " << listOfHistograms->GetSize() << " histograms in " << firstFileName << endl;
81    
82     // Loop over histograms, then loop over files
83     // plot the same histogram from all the files together
84     // save the canvas
85     TCanvas *c1 = new TCanvas("c1", "c1",0,0,plotWidth,plotHeight);
86     TObjString *currentHistString = (TObjString*)listOfHistograms->First();
87     for (int i_hist=0; i_hist<listOfHistograms->GetSize(); i_hist++) {
88     TFile *current_file = (TFile*)fileList->First();
89    
90     // Loop over the files, building list of histograms
91     TList *listOfHistsToPlot = new TList();
92     for (int i_file=0; i_file<fileName.size(); i_file++) {
93     TH1* htemp;
94     //cout << currentHistString->GetString() << endl;
95     current_file->GetObject(currentHistString->GetString(), htemp);
96    
97     listOfHistsToPlot->Add(htemp);
98     current_file = (TFile*)fileList->After( current_file );
99     }
100    
101     // Created a list of histograms to plot, now plot and save file
102     plotHists(listOfHistsToPlot, listOfLabels, c1);
103     c1->SaveAs(outputFolder+currentHistString->GetString()+"."+imageType);
104    
105     currentHistString = (TObjString*)listOfHistograms->After(currentHistString);
106     }
107    
108     // Close all the files
109     TFile *current_file = (TFile*)fileList->First();
110     for (int i=0; i<fileName.size(); i++) {
111     cout << "Closing " << fileName[i] << " ..." << endl;
112     current_file->Close();
113     current_file = (TFile*)fileList->After( current_file );
114     }
115     }
116    
117     void recurseOverKeys( const TDirectory *target, TList *listOfHistograms) {
118    
119     // Figure out where we are
120     TString path( (char*)strstr( target->GetPath(), ":" ) );
121     path.Remove( 0, 2 );
122    
123     TDirectory *current_sourcedir = gDirectory;
124    
125     TKey *key;
126     TIter nextkey(current_sourcedir->GetListOfKeys());
127    
128     while (key = (TKey*)nextkey()) {
129    
130     obj = key->ReadObj();
131    
132     // Check if this is a 1D histogram or a directory
133     if (obj->IsA()->InheritsFrom("TH1F")) {
134    
135     TH1F *htemp = (TH1F*)obj;
136     TString histName = htemp->GetName();
137     TObjString *histToAdd = new TObjString(path+"/"+histName);
138     listOfHistograms->Add(histToAdd);
139    
140     } else if ( obj->IsA()->InheritsFrom( "TDirectory" ) ) {
141     // it's a subdirectory
142    
143     const TDirectory *tempDir = (TDirectory*)obj;
144     current_sourcedir->cd ( tempDir->GetName() );
145    
146     gSystem->MakeDirectory(outputFolder+path+"/"+tempDir->GetName());
147    
148     // obj still knows its depth within the target file via
149     // GetPath(), so we can still figure out where we are in the recursion
150     recurseOverKeys( tempDir , listOfHistograms );
151    
152     } // end of IF a TDriectory
153     }
154     }
155    
156     void plotHists(TList *histogramsToPlot,
157     TList *histogramLabels,
158     TCanvas *c1) {
159    
160    
161     //*************************************************
162     // Variables
163     vector<int> histColors;
164     histColors.push_back(kBlack); // change colors as you like
165     histColors.push_back(kBlue);
166     histColors.push_back(kRed);
167     histColors.push_back(kGreen-1);
168    
169     float histLineWidth = 2.0;
170    
171     bool useMarkers = false; // search online for TAttMarker
172     vector<int> histMarkerStyles; // to see all available markers
173     histMarkerStyles.push_back( 20 );
174     histMarkerStyles.push_back( 22 );
175     histMarkerStyles.push_back( 21 );
176     histMarkerStyles.push_back( 23 );
177     float histMarkerSize = 0.9;
178    
179     // END of Variables
180     //*************************************************
181    
182     // Create copies of histograms provided
183     // and area normalize, if requested
184     TList *hists = new TList();
185     TH1* currentHistogram = (TH1*)histogramsToPlot->First();
186     for (int i=0; i<histogramsToPlot->GetSize(); i++) {
187     TH1* tempCurrentClone = (TH1*)currentHistogram->Clone();
188     hists->Add( tempCurrentClone );
189     if (areaNormalize) {
190     Double_t integral = tempCurrentClone->Integral();
191     if (integral>0.0) tempCurrentClone->Scale(1/integral);
192     }
193     currentHistogram = (TH1*)histogramsToPlot->After( currentHistogram );
194     }
195    
196    
197     // Set histogram plotting variables
198     // and add them to the histogram stack & legend
199     THStack *tempStack = new THStack();
200     TLegend *infoBox = new TLegend(0.75, 0.83, 0.99, 0.99, "");
201     currentHistogram = (TH1*)hists->First();
202     TObjString *currentHistString = (TObjString*)histogramLabels->First();
203     for (int i=0; i<histogramsToPlot->GetSize(); i++) {
204    
205     currentHistogram->SetLineColor(histColors[i]);
206     currentHistogram->SetLineWidth(histLineWidth);
207    
208     if (useMarkers) {
209     currentHistogram->SetMarkerStyle(histMarkerStyles[i]);
210     currentHistogram->SetMarkerColor(histColors[i]);
211     currentHistogram->SetMarkerSize(histMarkerSize);
212     }
213    
214     infoBox->AddEntry(currentHistogram,currentHistString->GetString(),"LP");
215     currentHistString = (TObjString*)histogramLabels->After( currentHistString);
216    
217     tempStack->Add(currentHistogram);
218    
219     currentHistogram = (TH1*)hists->After( currentHistogram );
220     }
221    
222     // Draw the stack of histograms
223     tempStack->Draw("nostack");
224    
225     // Set title/label sizes and offsets
226     tempStack->GetXaxis()->SetTitleOffset(0.9);
227     tempStack->GetYaxis()->SetTitleOffset(1.2);
228     tempStack->GetXaxis()->SetLabelSize(0.04);
229     tempStack->GetYaxis()->SetLabelSize(0.05);
230     tempStack->GetXaxis()->SetTitleSize(0.06);
231     tempStack->GetYaxis()->SetTitleSize(0.05);
232    
233     // Set axis titles
234     TString title = ((TH1*)hists->First())->GetTitle();
235     TString xTitle = ((TH1*)hists->First())->GetXaxis()->GetTitle();
236     TString yTitle = ((TH1*)hists->First())->GetYaxis()->GetTitle();
237     tempStack->SetTitle(title+";"+xTitle+";"+yTitle);
238    
239     // Draw legend
240     infoBox->SetShadowColor(0); // 0 = transparent
241     //infoBox->SetLineColor(0);
242     infoBox->SetFillColor(kWhite);
243     //infoBox->SetFillStyle(0);
244     infoBox->Draw();
245    
246     c1->SetLogy(plotLogY);
247     }