ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/FGolf/Tools/histtools.C
Revision: 1.4
Committed: Tue Mar 20 19:09:18 2012 UTC (13 years, 1 month ago) by fgolf
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +0 -0 lines
State: FILE REMOVED
Log Message:
replace .C with .cc

File Contents

# User Rev Content
1 fgolf 1.2 #include "TCanvas.h"
2     #include "TFile.h"
3 fgolf 1.1 #include "TH1.h"
4     #include "TH2.h"
5 fgolf 1.2 #include "THStack.h"
6     #include "TKey.h"
7 fgolf 1.1 #include "TLegend.h"
8     #include "TRegexp.h"
9 fgolf 1.3 #include "histtools.h"
10     #include <TIterator.h>
11 fgolf 1.2
12 fgolf 1.1 #include <iostream>
13    
14 fgolf 1.2 using namespace std;
15    
16 fgolf 1.1 namespace hist {
17    
18 fgolf 1.3 void add(const char* outHistName, const char* patORpfx);
19 fgolf 1.2
20 fgolf 1.3 //Add all histograms whose names match one of ten possible regular expression
21     //patterns or begin with one of ten possible given prefixes. Feel free to
22     //mix and match regular expression patterns and prefixes. If the final hist-
23     //ogram named outHistName does not exist it is created.
24    
25     void add(const char* outHistName, const char* patORpfx0, const char* patORpfx1, const char* patORpfx2, const char* patORpfx3, const char* patORpfx4, const char* patORpfx5, const char* patORpfx6, const char* patORpfx7, const char* patORpfx8, const char* patORpfx9)
26     {
27     add(outHistName, patORpfx0);
28     add(outHistName, patORpfx1);
29     if (patORpfx2) add(outHistName, patORpfx2);
30     if (patORpfx3) add(outHistName, patORpfx3);
31     if (patORpfx4) add(outHistName, patORpfx4);
32     if (patORpfx5) add(outHistName, patORpfx5);
33     if (patORpfx6) add(outHistName, patORpfx6);
34     if (patORpfx7) add(outHistName, patORpfx7);
35     if (patORpfx8) add(outHistName, patORpfx8);
36     if (patORpfx9) add(outHistName, patORpfx9);
37     }
38 fgolf 1.1
39 fgolf 1.3 //Add all histograms whose names match the given regular expression pattern
40     //or begin with the given prefix. If the final histogram named outHistName
41     //does not exist it is created.
42    
43     void add(const char* outHistName, const char* patORpfx) {
44     TRegexp reg(patORpfx, kFALSE);
45    
46     TList* list = gDirectory->GetList() ;
47     TIterator* iter = list->MakeIterator();
48    
49     TObject* obj = 0;
50     TObject* hist = 0;
51     Bool_t makeOutHist = false;
52    
53     hist = gDirectory->Get(outHistName);
54     //If out hist does not exist, remember to create it
55     if (! hist) makeOutHist = true;
56    
57     while ( (obj = iter->Next()) ) {
58     if (! obj->InheritsFrom(TH1::Class())) continue;
59    
60     TString name = obj->GetName();
61     //Don't add out hist
62     if (name == TString(outHistName)) continue;
63    
64     if (TString(patORpfx).MaybeRegexp()) {
65     if (TString(obj->GetName()).Index(reg) < 0 ) continue;
66     } else if (! name.BeginsWith(patORpfx)) continue;
67    
68     if (makeOutHist) {
69     hist = obj->Clone(outHistName);
70    
71     if (hist->InheritsFrom(TH2::Class()))
72     ((TH2*)hist)->Reset();
73     else
74     ((TH1*)hist)->Reset();
75    
76     ((TH1*)hist)->SetTitle(outHistName);
77     ((TH1*)hist)->Sumw2();
78     makeOutHist = false;
79     }
80 fgolf 1.1
81 fgolf 1.3 ((TH1*)hist)->Add((TH1*)obj);
82     }
83     }
84 fgolf 1.1
85 fgolf 1.3 //For all histograms whose names match the given regular expression pattern
86     //or begin with the given prefix, set the fill, line and marker colors to the
87     //given value.
88    
89     void color(const char* patORpfx, Color_t color) {
90     TRegexp reg(patORpfx, kFALSE);
91    
92     TList* list = gDirectory->GetList() ;
93     if (!list) {
94     cout << "Failed to set color for " << patORpfx << endl;
95     return;
96     }
97     TIterator* iter = list->MakeIterator();
98    
99     TObject* obj = 0;
100    
101     while ( (obj = iter->Next()) ) {
102     if (! obj->InheritsFrom(TH1::Class())) continue;
103    
104     TString name = obj->GetName();
105    
106     if (TString(patORpfx).MaybeRegexp()) {
107     if (TString(obj->GetName()).Index(reg) < 0 ) continue;
108     } else if (! name.BeginsWith(patORpfx)) continue;
109    
110     ((TH1*)obj)->SetFillColor(color);
111     ((TH1*)obj)->SetLineColor(color);
112     ((TH1*)obj)->SetMarkerColor(color);
113     }
114     }
115 fgolf 1.1
116 fgolf 1.3 //Return a pointer to a TLegend with an entry for each histogram drawn on a
117     //given TCanvas. Display either the line, point or fill values. Optionally
118     //apply colors to all histograms. By default, entry labels are the names of
119     //their respective histograms. Optionally, if histogram names are of the
120     //form XX_YY_ZZ_WW, entry labels can be XX (token=0), YY (token=1), etc.
121    
122     TLegend* legend(TCanvas* canvas, Option_t* option, Bool_t addColor, Int_t token,
123     Float_t xmin, Float_t ymin, Float_t xmax, Float_t ymax) {
124     if(! canvas) return 0;
125    
126     TLegend* leg = new TLegend(xmin, ymin, xmax, ymax);
127     TList* list = canvas->GetListOfPrimitives();
128     TIterator* iter = list->MakeIterator();
129    
130     TObject* obj = 0;
131    
132     //Hist color iterator
133     Int_t colorIt = 1;
134    
135     while ( (obj = iter->Next()) ) {
136     if (! obj->InheritsFrom(TH1::Class())) continue;
137    
138     if (addColor) {
139     hist::color(obj->GetName(), colorIt);
140     ++colorIt;
141     }
142 fgolf 1.2
143 fgolf 1.3 if (token == -1)
144     leg->AddEntry(obj, obj->GetName(), option);
145     else {
146     TString name(obj->GetName());
147     TObjArray* a = name.Tokenize("_");
148     if (a->GetEntries() <= token)
149     leg->AddEntry(obj, obj->GetName(), option);
150     else
151     leg->AddEntry(obj, a->At(token)->GetName(), option);
152     }
153     }
154 fgolf 1.2
155 fgolf 1.3 return leg;
156     }
157 fgolf 1.2
158 fgolf 1.3 //Normalize to one all histograms whose names match the given regular exp-
159     //ression pattern or begin with the given prefix.
160 fgolf 1.2
161 fgolf 1.3 void normalize(const char* patORpfx) {
162     TRegexp reg(patORpfx, kFALSE);
163 fgolf 1.2
164 fgolf 1.3 TList* list = gDirectory->GetList() ;
165     TIterator* iter = list->MakeIterator();
166 fgolf 1.2
167 fgolf 1.3 TObject* obj = 0;
168 fgolf 1.1
169 fgolf 1.3 while ( (obj = iter->Next()) ) {
170     if (! obj->InheritsFrom(TH1::Class())) continue;
171 fgolf 1.1
172 fgolf 1.3 TString name = obj->GetName();
173 fgolf 1.1
174 fgolf 1.3 if (TString(patORpfx).MaybeRegexp()) {
175     if (TString(obj->GetName()).Index(reg) < 0 ) continue;
176     } else if (! name.BeginsWith(patORpfx)) continue;
177 fgolf 1.1
178 fgolf 1.3 Double_t integral = 0;
179 fgolf 1.1
180 fgolf 1.3 if (obj->InheritsFrom(TH2::Class()))
181     integral = ((TH2*)obj)->Integral();
182     else
183     integral = ((TH1*)obj)->Integral();
184 fgolf 1.1
185 fgolf 1.3 if (integral) {
186     ((TH1*)obj)->Sumw2();
187     ((TH1*)obj)->Scale(1./integral);
188     }
189     }
190     }
191 fgolf 1.1
192 fgolf 1.3 //Scale by the given value all histograms whose names match the given regular
193     //expression pattern or begin with the given prefix.
194 fgolf 1.1
195 fgolf 1.3 void scale(const char* patORpfx, Double_t scale) {
196     TRegexp reg(patORpfx, kFALSE);
197 fgolf 1.1
198 fgolf 1.3 TList* list = gDirectory->GetList() ;
199     TIterator* iter = list->MakeIterator();
200 fgolf 1.1
201 fgolf 1.3 TObject* obj = 0;
202 fgolf 1.1
203 fgolf 1.3 while ( (obj = iter->Next()) ) {
204     if (! obj->InheritsFrom(TH1::Class())) continue;
205 fgolf 1.1
206 fgolf 1.3 TString name = obj->GetName();
207 fgolf 1.1
208 fgolf 1.3 if (TString(patORpfx).MaybeRegexp()) {
209     if (TString(obj->GetName()).Index(reg) < 0 ) continue;
210     } else if (! name.BeginsWith(patORpfx)) continue;
211 fgolf 1.1
212 fgolf 1.3 if (!(((TH1*)obj)->GetSumw2N()))
213     ((TH1*)obj)->Sumw2();
214     ((TH1*)obj)->Scale(scale);
215     }
216     }
217 fgolf 1.1
218 fgolf 1.3 //Don't you hate it when you draw multiple histograms on the same canvas only
219     //to find that the bottom histogram's range does not encompass those of the
220     //histograms drawn on top? This method determines the maximum and minimum y
221     //range of all the histograms drawn on a given TCanvas and appropriately re-
222     //sizes the bottom histogram.
223    
224     void setrangey(TCanvas* canvas) {
225     if(! canvas) return;
226    
227     TList* list = canvas->GetListOfPrimitives();
228     TIterator* iter = list->MakeIterator();
229    
230     TObject* obj = 0;
231     TObject* top = 0;
232    
233     //Extremes
234     Double_t maxy = -999999;
235     Double_t miny = 999999;
236    
237     while ( (obj = iter->Next()) ) {
238     if (! obj->InheritsFrom(TH1::Class())) continue;
239    
240     if (! top) top = obj;
241    
242     if (((TH1*)obj)->GetMaximum() > maxy) maxy = ((TH1*)obj)->GetMaximum();
243     if (((TH1*)obj)->GetMinimum() < miny) miny = ((TH1*)obj)->GetMinimum();
244     }
245    
246     ((TH1*)top)->SetMaximum(maxy*1.9);
247     //Protect against log scale
248     if (canvas->GetLogy() && ! miny)
249     ((TH1*)top)->SetMinimum(1E-4);
250     else
251     ((TH1*)top)->SetMinimum(miny*0.7);
252     }
253 fgolf 1.1
254 fgolf 1.3 //Create a stacked histogram consisting of all histograms whose names match
255     //the given regular expression pattern or begin with the given prefix. If
256     //the THStack named stackHistName does not exist it is created. Optionally
257     //apply colors to all histograms. Set drawOption to "nostack" if you do not
258     //want to stack, to "hist" to display histograms without errors, to "histe"
259     //to display histograms with errors, etc.
260    
261     void stack(const char* stackHistName, const char* patORpfx, Bool_t addColor, Option_t* drawOption) {
262     TRegexp reg(patORpfx, kFALSE);
263    
264     TList* list = gDirectory->GetList() ;
265     TIterator* iter = list->MakeIterator();
266    
267     TObject* obj = 0;
268     TObject* stack = 0;
269     Bool_t makeStackHist = false;
270    
271     stack = gDirectory->Get(stackHistName);
272     //If stack hist does not exist, remember to create it
273     if (! stack) makeStackHist = true;
274    
275     //Hist color iterator
276     Int_t colorIt = 1;
277    
278     while ( (obj = iter->Next()) ) {
279     if (! obj->InheritsFrom(TH1::Class())) continue;
280    
281     TString name = obj->GetName();
282    
283     if (TString(patORpfx).MaybeRegexp()) {
284     if (TString(obj->GetName()).Index(reg) < 0 ) continue;
285     } else if (! name.BeginsWith(patORpfx)) continue;
286    
287     if (makeStackHist) {
288     stack = new THStack(stackHistName, stackHistName);
289     makeStackHist = false;
290     }
291 fgolf 1.1
292 fgolf 1.3 if (addColor) {
293     hist::color(obj->GetName(), colorIt);
294     ++colorIt;
295     }
296 fgolf 1.1
297 fgolf 1.3 ((THStack*)stack)->Add((TH1*)obj, drawOption);
298     }
299 fgolf 1.1
300 fgolf 1.3 // Currently breaks .ls
301     //gDirectory->Append(stack);
302     }
303 fgolf 1.1
304 fgolf 1.3 //Set the x-axis title of all histograms whose names match the given regular
305     //expression pattern or begin with the given prefix.
306 fgolf 1.2
307 fgolf 1.3 void xaxis(const char* patORpfx, const char* title) {
308     TRegexp reg(patORpfx, kFALSE);
309 fgolf 1.1
310 fgolf 1.3 TList* list = gDirectory->GetList() ;
311     TIterator* iter = list->MakeIterator();
312 fgolf 1.1
313 fgolf 1.3 TObject* obj = 0;
314 fgolf 1.1
315 fgolf 1.3 while ( (obj = iter->Next()) ) {
316     if (! (obj->InheritsFrom(TH1::Class()) || obj->InheritsFrom(THStack::Class()))) continue;
317 fgolf 1.1
318 fgolf 1.3 TString name = obj->GetName();
319 fgolf 1.1
320 fgolf 1.3 if (TString(patORpfx).MaybeRegexp()) {
321     if (TString(obj->GetName()).Index(reg) < 0 ) continue;
322     } else if (! name.BeginsWith(patORpfx)) continue;
323 fgolf 1.1
324 fgolf 1.3 if (obj->InheritsFrom(TH1::Class()))
325     ((TH1*)obj)->GetXaxis()->SetTitle(title);
326     if (obj->InheritsFrom(THStack::Class())) {
327     ((THStack*)obj)->Draw();
328     ((THStack*)obj)->GetXaxis()->SetTitle(title);
329     }
330     }
331     }
332 fgolf 1.1
333 fgolf 1.3 //Set the y-axis title of all histograms whose names match the given regular
334     //expression pattern or begin with the given prefix.
335 fgolf 1.1
336 fgolf 1.3 void yaxis(const char* patORpfx, const char* title) {
337     TRegexp reg(patORpfx, kFALSE);
338 fgolf 1.1
339 fgolf 1.3 TList* list = gDirectory->GetList() ;
340     TIterator* iter = list->MakeIterator();
341 fgolf 1.1
342 fgolf 1.3 TObject* obj = 0;
343 fgolf 1.1
344 fgolf 1.3 while ( (obj = iter->Next()) ) {
345     if (! (obj->InheritsFrom(TH1::Class()) || obj->InheritsFrom(THStack::Class()))) continue;
346 fgolf 1.1
347 fgolf 1.3 TString name = obj->GetName();
348 fgolf 1.1
349 fgolf 1.3 if (TString(patORpfx).MaybeRegexp()) {
350     if (TString(obj->GetName()).Index(reg) < 0 ) continue;
351     } else if (! name.BeginsWith(patORpfx)) continue;
352 fgolf 1.2
353 fgolf 1.3 if (obj->InheritsFrom(TH1::Class()))
354     ((TH1*)obj)->GetYaxis()->SetTitle(title);
355     if (obj->InheritsFrom(THStack::Class())) {
356     ((THStack*)obj)->Draw();
357     ((THStack*)obj)->GetYaxis()->SetTitle(title);
358     }
359     }
360     }
361 fgolf 1.1
362 fgolf 1.2 // Input: 4 histogram
363     // Output: one histogram which is the BG subtracted efficiency:
364     // h1 : TOTAL NUMBER OF EVENTS, SIGNAL REGION
365     // h2 : NUMBER OF EVENTS THAT PASS, SIGNAL REGION
366     // h3 : TOTAL NUMBER OF EVENTS, SIDE BAND
367     // h4 : NUMBER OF EVENTS THAT PASS, SIDE BAND
368 fgolf 1.1
369    
370 fgolf 1.3 TH1F* eff_bg(TH1F* h1, TH1F* h2, TH1F* h3, TH1F* h4, const char* name){
371 fgolf 1.1
372 fgolf 1.3 // first, verify that all histograms have same binning
373     // nx is the number of visible bins
374     // nxtot = nx+2 includes underflow and overflow
375     Int_t nx = h1->GetNbinsX();
376     Int_t nxtot = nx + 2;
377     if (h2->GetNbinsX() != nx) {
378     cout << "Histograms must have same number of bins" << endl;
379     return 0;
380     }
381     if (h3->GetNbinsX() != nx) {
382     cout << "Histograms must have same number of bins" << endl;
383     return 0;
384     }
385     if (h3->GetNbinsX() != nx) {
386     cout << "Histograms must have same number of bins" << endl;
387     return 0;
388     }
389    
390     // get the new histogram
391     TH1F* temp = (TH1F*) h1->Clone(name);
392     temp->SetTitle(name);
393     temp->Reset();
394     temp->Sumw2();
395    
396     // Loop over bins, calculate efficiency and error, put it in histogram
397     for (Int_t i=0; i<nxtot; i++) {
398     Double_t x1 = h1->GetBinContent(i);
399     Double_t x2 = h2->GetBinContent(i);
400     Double_t x3 = h3->GetBinContent(i);
401     Double_t x4 = h4->GetBinContent(i);
402     Double_t denom = x1 - x3;
403     Double_t eff;
404     if (denom == 0.) {
405     eff = 0;
406     } else {
407     eff = (x2-x4)/denom;
408     }
409     Double_t failSig = x1 - x2;
410     Double_t failBg = x3 - x4;
411     Double_t blah = (1-eff)*(1-eff)*(x2+x4) + eff*eff*(failSig+failBg);
412     if (blah <= 0.) blah=0.0;
413     Double_t err;
414     if (denom == 0) {
415     err = 0.;
416     } else {
417     err = sqrt(blah)/denom;
418     }
419     temp->SetBinContent(i,eff);
420     temp->SetBinError(i,err);
421     }
422 fgolf 1.1
423 fgolf 1.3 // Done
424     return temp;
425     }
426 fgolf 1.1
427 fgolf 1.3 void deleteHistos() {
428     // Delete all existing histograms in memory
429     TObject* obj;
430     TList* list = gDirectory->GetList() ;
431     TIterator* iter = list->MakeIterator();
432     while ( (obj=iter->Next()) ) {
433     if (obj->IsA()->InheritsFrom(TH1::Class()) ||
434     obj->IsA()->InheritsFrom(TH2::Class()) ) {delete obj;}
435     }
436     }
437 fgolf 1.1
438 fgolf 1.3 void histio()
439     {
440     }
441 fgolf 1.1
442 fgolf 1.3 void saveHist(const char* filename, const char* pat)
443     {
444     TList* list = gDirectory->GetList() ;
445     TIterator* iter = list->MakeIterator();
446    
447     TRegexp re(pat,kTRUE) ;
448    
449     TFile outf(filename,"RECREATE") ;
450     while(TObject *obj=iter->Next()) {
451     if (TString(obj->GetName()).Index(re)>=0) {
452     obj->Write() ;
453     cout << "." ;
454     cout.flush() ;
455     }
456     }
457     cout << endl ;
458     outf.Close() ;
459 fgolf 1.2
460 fgolf 1.3 delete iter ;
461     }
462 fgolf 1.1
463    
464 fgolf 1.3 void loadHist(const char* filename, const char* pfx, const char* pat, Bool_t verbose, Bool_t doAdd)
465     {
466     TFile inf(filename) ;
467     //inf.ReadAll() ;
468     TList* list = inf.GetListOfKeys() ;
469     TIterator* iter = list->MakeIterator();
470    
471     TRegexp re(pat,kTRUE) ;
472     if (verbose)
473     std::cout << "pat = " << pat << std::endl;
474    
475     gDirectory->cd("Rint:") ;
476    
477     TObject* obj ;
478     TKey* key ;
479     if (verbose) {
480     std::cout << "doAdd = " << (doAdd?"T":"F") << std::endl;
481     std::cout << "loadHist: reading.";
482     }
483     while( (key=(TKey*)iter->Next()) ) {
484    
485     Int_t ridx = TString(key->GetName()).Index(re) ;
486     if (ridx==-1) {
487     continue ;
488     }
489 fgolf 1.1
490 fgolf 1.3 obj = inf.Get(key->GetName()) ;
491     TObject* clone ;
492     if (pfx) {
493    
494     // Find existing TH1-derived objects
495     TObject* oldObj = 0 ;
496     if (doAdd){
497     oldObj = gDirectory->Get(Form("%s_%s",pfx,obj->GetName())) ;
498     if (oldObj && !oldObj->IsA()->InheritsFrom(TH1::Class())) {
499     oldObj = 0 ;
500     }
501     }
502     if (oldObj) {
503     clone = oldObj ;
504     ((TH1*)clone)->Add((TH1*)obj) ;
505     } else {
506     clone = obj->Clone(Form("%s_%s",pfx,obj->GetName())) ;
507     }
508    
509    
510     } else {
511    
512     // Find existing TH1-derived objects
513     TObject* oldObj = 0 ;
514     if (doAdd){
515     oldObj = gDirectory->Get(key->GetName()) ;
516     if (oldObj && !oldObj->IsA()->InheritsFrom(TH1::Class())) {
517     oldObj = 0 ;
518     }
519     }
520    
521     if (oldObj) {
522     clone = oldObj ;
523     ((TH1*)clone)->Add((TH1*)obj) ;
524     } else {
525     clone = obj->Clone() ;
526     }
527     }
528     if (!gDirectory->GetList()->FindObject(clone)) {
529     gDirectory->Append(clone) ;
530     }
531     if (verbose) {
532     std::cout << ".";
533     std::cout.flush();
534     }
535     }
536     if (verbose)
537     std::cout << std::endl;
538     inf.Close() ;
539     delete iter ;
540     }
541 fgolf 1.1
542     }