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

# Content
1 #include "TCanvas.h"
2 #include "TFile.h"
3 #include "TH1.h"
4 #include "TH2.h"
5 #include "THStack.h"
6 #include "TKey.h"
7 #include "TLegend.h"
8 #include "TRegexp.h"
9 #include "histtools.h"
10 #include <TIterator.h>
11
12 #include <iostream>
13
14 using namespace std;
15
16 namespace hist {
17
18 void add(const char* outHistName, const char* patORpfx);
19
20 //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
39 //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
81 ((TH1*)hist)->Add((TH1*)obj);
82 }
83 }
84
85 //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
116 //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
143 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
155 return leg;
156 }
157
158 //Normalize to one all histograms whose names match the given regular exp-
159 //ression pattern or begin with the given prefix.
160
161 void normalize(const char* patORpfx) {
162 TRegexp reg(patORpfx, kFALSE);
163
164 TList* list = gDirectory->GetList() ;
165 TIterator* iter = list->MakeIterator();
166
167 TObject* obj = 0;
168
169 while ( (obj = iter->Next()) ) {
170 if (! obj->InheritsFrom(TH1::Class())) continue;
171
172 TString name = obj->GetName();
173
174 if (TString(patORpfx).MaybeRegexp()) {
175 if (TString(obj->GetName()).Index(reg) < 0 ) continue;
176 } else if (! name.BeginsWith(patORpfx)) continue;
177
178 Double_t integral = 0;
179
180 if (obj->InheritsFrom(TH2::Class()))
181 integral = ((TH2*)obj)->Integral();
182 else
183 integral = ((TH1*)obj)->Integral();
184
185 if (integral) {
186 ((TH1*)obj)->Sumw2();
187 ((TH1*)obj)->Scale(1./integral);
188 }
189 }
190 }
191
192 //Scale by the given value all histograms whose names match the given regular
193 //expression pattern or begin with the given prefix.
194
195 void scale(const char* patORpfx, Double_t scale) {
196 TRegexp reg(patORpfx, kFALSE);
197
198 TList* list = gDirectory->GetList() ;
199 TIterator* iter = list->MakeIterator();
200
201 TObject* obj = 0;
202
203 while ( (obj = iter->Next()) ) {
204 if (! obj->InheritsFrom(TH1::Class())) continue;
205
206 TString name = obj->GetName();
207
208 if (TString(patORpfx).MaybeRegexp()) {
209 if (TString(obj->GetName()).Index(reg) < 0 ) continue;
210 } else if (! name.BeginsWith(patORpfx)) continue;
211
212 if (!(((TH1*)obj)->GetSumw2N()))
213 ((TH1*)obj)->Sumw2();
214 ((TH1*)obj)->Scale(scale);
215 }
216 }
217
218 //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
254 //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
292 if (addColor) {
293 hist::color(obj->GetName(), colorIt);
294 ++colorIt;
295 }
296
297 ((THStack*)stack)->Add((TH1*)obj, drawOption);
298 }
299
300 // Currently breaks .ls
301 //gDirectory->Append(stack);
302 }
303
304 //Set the x-axis title of all histograms whose names match the given regular
305 //expression pattern or begin with the given prefix.
306
307 void xaxis(const char* patORpfx, const char* title) {
308 TRegexp reg(patORpfx, kFALSE);
309
310 TList* list = gDirectory->GetList() ;
311 TIterator* iter = list->MakeIterator();
312
313 TObject* obj = 0;
314
315 while ( (obj = iter->Next()) ) {
316 if (! (obj->InheritsFrom(TH1::Class()) || obj->InheritsFrom(THStack::Class()))) continue;
317
318 TString name = obj->GetName();
319
320 if (TString(patORpfx).MaybeRegexp()) {
321 if (TString(obj->GetName()).Index(reg) < 0 ) continue;
322 } else if (! name.BeginsWith(patORpfx)) continue;
323
324 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
333 //Set the y-axis title of all histograms whose names match the given regular
334 //expression pattern or begin with the given prefix.
335
336 void yaxis(const char* patORpfx, const char* title) {
337 TRegexp reg(patORpfx, kFALSE);
338
339 TList* list = gDirectory->GetList() ;
340 TIterator* iter = list->MakeIterator();
341
342 TObject* obj = 0;
343
344 while ( (obj = iter->Next()) ) {
345 if (! (obj->InheritsFrom(TH1::Class()) || obj->InheritsFrom(THStack::Class()))) continue;
346
347 TString name = obj->GetName();
348
349 if (TString(patORpfx).MaybeRegexp()) {
350 if (TString(obj->GetName()).Index(reg) < 0 ) continue;
351 } else if (! name.BeginsWith(patORpfx)) continue;
352
353 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
362 // 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
369
370 TH1F* eff_bg(TH1F* h1, TH1F* h2, TH1F* h3, TH1F* h4, const char* name){
371
372 // 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
423 // Done
424 return temp;
425 }
426
427 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
438 void histio()
439 {
440 }
441
442 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
460 delete iter ;
461 }
462
463
464 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
490 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
542 }