ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/Plot/src/PlotTask.cc
Revision: 1.2
Committed: Sun Oct 3 03:45:47 2010 UTC (14 years, 7 months ago) by paus
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +1 -1 lines
State: FILE REMOVED
Log Message:
Error in cvs use.

File Contents

# Content
1 // $Id: PlotTask.cc,v 1.1 2010/10/03 03:40:00 paus Exp $
2
3 #include <vector>
4 #include <TROOT.h>
5 #include <TSystem.h>
6 #include <TPad.h>
7 #include <TFile.h>
8 #include <TH1D.h>
9 #include <TBox.h>
10 #include <TMarker.h>
11 #include <TLatex.h>
12 #include "MitAna/DataUtil/interface/Debug.h"
13 #include "MitPlots/Style/interface/MitStyle.h"
14 #include "MitPlots/Plot/interface/PlotTask.h"
15
16 ClassImp(mithep::PlotTask)
17
18 using namespace std;
19 using namespace mithep;
20
21 //--------------------------------------------------------------------------------------------------
22 PlotTask::PlotTask(const TaskSamples *taskSamples, const double lumi) :
23 fTask (taskSamples),
24 fTargetLumi (lumi),
25 fIdxHistMax (-1),
26 fNRebin (1),
27 fEmptyHist (0),
28 fDataHist (0),
29 fHistMinimum(0),
30 fAxisTitleX (""),
31 fAxisTitleY ("Number of Events"),
32 fXLegend (60.),
33 fYLegend (98.)
34 {
35 // Constructor
36 }
37
38 //--------------------------------------------------------------------------------------------------
39 PlotTask::~PlotTask()
40 {
41 // Destructor
42
43 if (fEmptyHist)
44 delete fEmptyHist;
45 if (fDataHist)
46 delete fDataHist;
47 }
48
49 //--------------------------------------------------------------------------------------------------
50 void PlotTask::SetAxisTitles(const char* xtit, const char* ytit)
51 {
52 fAxisTitleX = TString(xtit);
53 fAxisTitleY = TString(ytit);
54
55 return;
56 }
57
58 //--------------------------------------------------------------------------------------------------
59 void PlotTask::PlotContributions(const char* dir, const char* hist)
60 {
61 // Show present list of defined samples
62
63 // scale the histograms
64 ScaleHistograms(dir,hist);
65
66 // say what we are doing
67 printf("\n ==== Plotting Contributions -- %s ====\n\n",fTask->Name()->Data());
68 printf(" index of highest histogram %d (0-%d)\n\n",fIdxHistMax,fHists.size()-1);
69
70 // check x-axis title
71 if (fAxisTitleX == TString(""))
72 fAxisTitleX = TString(hist);
73
74 // initialize the largest histogram properly and draw it
75 TH1D* hmax = 0;
76 if (fIdxHistMax == fHists.size())
77 hmax = fDataHist;
78 else
79 hmax = fHists[fHists.size()-1];
80 MitStyle::InitHist(hmax,fAxisTitleX.Data(),fAxisTitleY.Data(),kBlack);
81 hmax->GetXaxis()->SetNdivisions(505);
82 if (fHistMinimum != 0)
83 hmax->SetMinimum(fHistMinimum);
84 if (fIdxHistMax == fHists.size())
85 hmax->Draw("E");
86 else
87 hmax->Draw("hist");
88
89 // loop through samples and draw all histograms
90 int iCol = (EColor) kBlack;
91 int iFill = 3001;
92 for (UInt_t i=0; i<*fTask->NSamples(); i++) {
93 //const Sample *s = fTask->GetSample(i);
94 MitStyle::InitHist(fHists[i],hist,"Number of Events",(EColor) iCol);
95 fHists[i]->SetLineColor(iCol);
96 //fHists[i]->SetFillColor(iCol);
97 //fHists[i]->SetFillStyle(iFill);
98 fHists[i]->Draw("same;Hist");
99
100 iFill++; iCol++;
101 }
102
103 // overlay a frame to put the text and boxes on
104 OverlayFrame();
105
106 return;
107 }
108
109 //--------------------------------------------------------------------------------------------------
110 void PlotTask::PlotStack(const char* dir, const char* hist)
111 {
112 // Show present list of defined samples
113
114 // scale the histograms
115 ScaleHistograms(dir,hist);
116 FindHistMaximum();
117
118 // check basics
119 if (fStackedHists.size() < 1) {
120 printf(" WARNING -- no histograms with name: %s. EXIT!\n",hist);
121 return;
122 }
123
124 // determine the width of one bin
125 double binW = fEmptyHist->GetBinWidth(1);
126 char binWStr[7];
127 sprintf(binWStr," /%7.3f",binW);
128
129 // say what we are doing
130 printf("\n ==== Plotting Stack -- %s (bin width: %7.3f) ====\n\n",fTask->Name()->Data(),binW);
131
132 // check x-axis title
133 if (fAxisTitleX == TString(""))
134 fAxisTitleX = TString(hist);
135
136 // initialize the empty histogram properly and draw it
137 MitStyle::InitHist(fEmptyHist,fAxisTitleX.Data(),(fAxisTitleY+TString(binWStr)).Data(),kBlack);
138 fEmptyHist->GetXaxis()->SetNdivisions(505);
139 if (fHistMinimum != 0)
140 fEmptyHist->SetMinimum(fHistMinimum);
141 fEmptyHist->SetMaximum(fHistMaximum*1.1);
142 fEmptyHist->Draw("");
143
144 // define the text
145 TLatex* text = new TLatex();
146 text->SetTextFont (42);
147 text->SetTextAlign(11);
148 text->SetTextSize (0.045);
149
150 // loop through samples and draw all histograms
151 int iCol = (EColor) kBlack;
152 int iFill = 0;
153 for (UInt_t i=fStackedHists.size(); i>0; i--) {
154 const Sample *s = fTask->GetSample(i);
155 MitStyle::InitHist(fStackedHists[i-1],fAxisTitleX.Data(),fAxisTitleY.Data(),(EColor) iCol);
156
157 fStackedHists[i-1]->SetLineColor(iCol);
158 fStackedHists[i-1]->SetFillColor(iCol);
159 fStackedHists[i-1]->SetFillStyle(iFill);
160
161 if (i == fStackedHists.size()) {
162 fStackedHists[i-1]->Draw("same;Hist");
163 iFill+=4; iCol++;
164 }
165 else {
166 if (*s->Legend() != TString(" ")) {
167 // white out the histogram first
168 fStackedHists[i-1]->SetFillColor(10);
169 fStackedHists[i-1]->SetFillStyle(1001);
170 fStackedHists[i-1]->DrawCopy("same;Hist");
171 // overlay the histogram with proper hatching
172 fStackedHists[i-1]->SetFillColor(iCol);
173 fStackedHists[i-1]->SetFillStyle(iFill);
174 fStackedHists[i-1]->Draw("same;Hist");
175 iFill+=4; iCol++;
176 }
177 }
178 if (i == fStackedHists.size())
179 iFill += 3000;
180 }
181
182 if (fDataHist) {
183 fDataHist->SetMarkerStyle(20);
184 fDataHist->SetMarkerSize (0.8);
185 fDataHist->SetMarkerColor(kBlack);
186 fDataHist->Draw("same;E");
187 }
188
189 // overlay a frame to put the text and boxes on
190 OverlayFrame();
191
192 return;
193 }
194
195 //--------------------------------------------------------------------------------------------------
196 void PlotTask::ScaleHistograms(const char* dir, const char* hist)
197 {
198 // Scale the histograms according to the cross section and the desired lumi and store them
199 // for later use
200
201 if (fHists.size() > 0) {
202 printf(" WARNING - scaled histograms already exist. EXIT.");
203 return;
204 }
205
206 fIdxHistMax = -1;
207
208 // some useful definitions
209 TString *dirFwk = new TString("AnaFwkMod");
210 TString *allEvts = new TString("hDAllEvents");
211 TString slash ("/");
212
213 // keep track who is on top
214 double ymax = 0.0;
215
216 // say what we are doing
217 printf("\n ==== Extracting and Scaling Contributions -- %s ====\n\n",fTask->Name()->Data());
218 printf(" target luminosity %f 1/fb\n\n",fTargetLumi/1000.);
219
220 // loop through samples and determine maximum
221 printf("\n monte carlo \n");
222 for (UInt_t i=0; i<*fTask->NSamples(); i++) {
223 const Sample *s = fTask->GetSample(i);
224 // open file belonging to this sample
225 TFile *fif = new TFile((*fTask->Dir()+slash+*s->File()).Data());
226 // make sure the file exists
227 if (fif->IsOpen() == kFALSE) {
228 printf(" WARNING -- sample %s does not have a histogram file. Continue without!\n",
229 s->Name()->Data());
230 continue;
231 }
232 // read and determine general properties of this sample
233 TDirectory *dirTmp = (TDirectory*) gROOT->FindObject(dirFwk->Data());
234 if (dirTmp)
235 fif->cd(dirFwk->Data());
236 TH1D *hAllEvts = (TH1D*) gROOT->FindObject(allEvts->Data());
237 if (! hAllEvts) {
238 printf(" WARNING -- sample %s does not have a framework file. Next sample!\n",
239 s->Name()->Data());
240 continue;
241 }
242 double nEvts = hAllEvts->GetEntries();
243 double lumi = nEvts / *s->Xsec();
244 double factor,scale = *s->Scale();
245 if (lumi < 0)
246 factor = 1.0;
247 else if (lumi > 0)
248 factor = fTargetLumi/lumi;
249 else
250 factor = 0;
251
252 printf(" -> %-40s -- %16.0f %16.7f: %16.4f (x %f x %f)\n",
253 s->Name()->Data(),nEvts,*s->Xsec(),lumi,factor,scale);
254
255 // access plot we want to work with
256 fif->cd(dir); //fif->ls();
257 TH1D *h = (TH1D*) gROOT->FindObject(hist);
258 if (! h) {
259 printf(" WARNING -- sample %s does not have requested histogram. Next sample!\n",
260 s->Name()->Data());
261 continue;
262 }
263 if (! fEmptyHist) {
264 fEmptyHist = new TH1D(factor * scale * (*h));
265 fEmptyHist->Rebin(fNRebin);
266 fEmptyHist->Reset();
267 }
268 // scale it
269 TH1D *hTmp = new TH1D(factor * scale * (*h));
270 hTmp->Rebin(fNRebin);
271 // put it into our collection
272 fHists.push_back(hTmp);
273 // make a new histogram from the last added one and add the recent
274 if (i == 0)
275 fStackedHists.push_back(hTmp);
276 else {
277 TH1D *hStackedTmp = new TH1D(*fStackedHists[i-1]);
278 // remember the stored histogram is already rebinned
279 hStackedTmp->Add(hTmp);
280 fStackedHists.push_back(hStackedTmp);
281 }
282
283 // determine the maximum
284 if (i == 0 || fHists[i]->GetMaximum() > ymax) {
285 fIdxHistMax = i;
286 ymax = fHists[i]->GetMaximum();
287 }
288 }
289
290 // read the data histograms
291 // loop through data samples and add them up, straight away
292 if (*fTask->NDataSamples() > 0)
293 printf("\n data \n");
294 for (UInt_t i=0; i<*fTask->NDataSamples(); i++) {
295 const Sample *s = fTask->GetDataSample(i);
296 // open file belonging to the data sample
297 TFile *fif = new TFile((*fTask->Dir()+slash+*s->File()).Data());
298 // make sure the file exists
299 if (fif->IsOpen() == kFALSE) {
300 printf(" WARNING -- sample %s does not have a histogram file. Continue without!\n",
301 s->Name()->Data());
302 }
303 else {
304 // read and determine general properties of this sample
305 TDirectory *dirTmp = (TDirectory*) gROOT->FindObject(dirFwk->Data());
306 if (dirTmp)
307 fif->cd(dirFwk->Data());
308 TH1D *hAllEvts = (TH1D*) gROOT->FindObject(allEvts->Data());
309 if (! hAllEvts)
310 printf(" WARNING -- sample %s does not have a framework file. Next sample!\n",
311 s->Name()->Data());
312 else {
313 double nEvts = hAllEvts->GetEntries();
314 printf(" -> %-40s -- %16.0f %16.7f: %16.4f (x %f)\n",
315 s->Name()->Data(),nEvts,*s->Xsec(),fTargetLumi,1.0);
316
317 // access plot we want to work with
318 fif->cd(dir); //fif->ls();
319 TH1D *h = (TH1D*) gROOT->FindObject(hist);
320 if (! h)
321 printf(" WARNING -- sample %s does not have requested histogram. Next sample!\n",
322 s->Name()->Data());
323 else
324 // rebin it
325 h->Rebin(fNRebin);
326
327 // construct the complete data histogram
328 if (! fDataHist)
329 fDataHist = new TH1D(1.0 * (*h));
330 else
331 fDataHist->Add(h);
332 }
333 }
334 }
335
336 // determine the maximum
337 if ( fDataHist && fDataHist->GetMaximum() > ymax) {
338 fIdxHistMax = fHists.size();
339 ymax = fDataHist->GetMaximum();
340 }
341
342 return;
343 }
344
345 //--------------------------------------------------------------------------------------------------
346 void PlotTask::FindHistMaximum()
347 {
348 // Find maximum of all histograms
349
350 // first check whether value was overwritten by hand
351 if (fHistMaximum>0.)
352 return;
353
354 // search through the stacked histograms
355 for (UInt_t i=0; i<fStackedHists.size(); i++) {
356 if (fStackedHists[i]->GetMaximum() > fHistMaximum)
357 fHistMaximum = fStackedHists[i]->GetMaximum();
358 }
359
360 // search through the data histogram is present
361 if (fDataHist && fDataHist->GetMaximum() > fHistMaximum)
362 fHistMaximum = fDataHist->GetMaximum();
363
364 printf(" Histogram maximum is set to be: %f\n",fHistMaximum);
365
366 return;
367 }
368
369 //--------------------------------------------------------------------------------------------------
370 void PlotTask::OverlayEmptyHist() const
371 {
372 // Overlay an empty histogram onto the picture
373 if (fEmptyHist)
374 fEmptyHist->Draw("same");
375
376 return;
377 }
378
379 //--------------------------------------------------------------------------------------------------
380 void PlotTask::OverlayFrame() const
381 {
382 // Overlay a linear frame from user coordinates (0-100,0-100)
383
384 // create new transparent pad for the text
385 TPad *transPad = new TPad("transPad","Transparent Pad",0,0,1,1);
386 transPad->SetFillStyle(4000);
387 transPad->Draw();
388 transPad->cd();
389 // find out the right normalization to define the new range (histogram: 0,0 -> 100,100)
390 double xtot = 1./(1. - transPad->GetLeftMargin() - transPad->GetRightMargin());
391 double ytot = 1./(1. - transPad->GetBottomMargin() - transPad->GetTopMargin());
392 transPad->Range((xtot*transPad->GetLeftMargin() *-100 ),
393 (ytot*transPad->GetBottomMargin()*-100 ),
394 (xtot*transPad->GetRightMargin() * 100 + 100),
395 (ytot*transPad->GetTopMargin() * 100 + 100));
396 MDB(kGeneral,1)
397 printf(" Range: %f %f %f %f\n",
398 (xtot*transPad->GetLeftMargin() *-100 ),
399 (ytot*transPad->GetBottomMargin()*-100 ),
400 (xtot*transPad->GetRightMargin() * 100 + 100),
401 (ytot*transPad->GetTopMargin() * 100 + 100) );
402
403 // define the basic text to be used
404 TLatex* text = new TLatex();
405 text->SetTextFont (42);
406 text->SetTextAlign(12);
407 text->SetTextSize (0.03);
408
409 // define the basic box to be used
410 TBox *box = new TBox();
411 box->SetLineWidth(2);
412 // base coordinates for the text/boxes
413 double xCorner = fXLegend, yCorner = fYLegend, yDelLine = 4.;
414 double xIndent = 1.5*yDelLine;
415 // count samples with non empty legend
416 int nLegends = 0;
417 for (UInt_t i=*fTask->NSamples(); i>0; i--) {
418 // attach to the specific sample
419 const Sample *s = fTask->GetSample(i-1);
420 if (*s->Legend() != TString(" "))
421 nLegends++;
422 }
423 int iDat = 0;
424 if (fDataHist) {
425 iDat = 1;
426 nLegends++;
427 }
428
429 // set start values
430 int iCol = (EColor) kBlack;
431 int iFill = 0;
432 int iLeg = 0;
433 // loop through the sampels
434 for (UInt_t i=*fTask->NSamples(); i>0; i--) {
435 // attach to the specific sample
436 const Sample *s = fTask->GetSample(i-1);
437 // calculate corners for the text
438 double xText = xCorner+xIndent, yText = yCorner-float((iLeg+iDat)+0.5)*yDelLine;
439 // say what goes where
440 MDB(kGeneral,1)
441 printf(" Adding box at: (x1,y1,x2,y2) = (%6.2f,%6.2f,%6.2f,%6.2f)\n",
442 xCorner+0.15*xIndent,yText-0.3*yDelLine,
443 xCorner+0.85*xIndent,yText+0.4*yDelLine);
444 // plot the box
445 if (*s->Legend() != TString(" ")) {
446 box->SetFillStyle(0);
447 box->SetFillColor(iCol);
448 box->SetLineColor(iCol);
449 box->DrawBox(xCorner+0.15*xIndent,yText-0.3*yDelLine,
450 xCorner+0.85*xIndent,yText+0.4*yDelLine);
451 box->SetFillStyle(iFill);
452 box->DrawBox(xCorner+0.15*xIndent,yText-0.3*yDelLine,
453 xCorner+0.85*xIndent,yText+0.4*yDelLine);
454
455 TString pText = *s->Legend();
456 MDB(kGeneral,1)
457 printf(" Adding text \"%s\" at: (x,y) = (%6.2f,%6.2f)\n",pText.Data(),xText,yText);
458 // set the proper text color
459 text->SetTextColor(iCol);
460 // plot the text
461 text->SetTextAlign(12);
462 text->DrawLatex(xText,yText,pText.Data());
463 // keep track of how many were printed
464 iLeg++;
465 if (iLeg == 1)
466 iFill += 3000;
467 // cycle through the colors and hash patterns
468 iFill+=4; iCol++;
469 }
470 }
471
472 // attach to the data sample
473 if (fDataHist) {
474 const Sample *s = fTask->GetDataSample(0);
475 // calculate corners for the text
476 double xText = xCorner+xIndent, yText = yCorner-float(1-0.7)*yDelLine;
477 // say what goes where
478 MDB(kGeneral,1)
479 printf(" Adding marker at: (x,y) = (%6.2f,%6.2f)\n",
480 xCorner+0.5*xIndent,yText);
481 // plot the marker
482 if (*s->Legend() != TString(" ")) {
483 // draw marker
484 TMarker *m = new TMarker(xCorner+0.5*xIndent,yText,20);
485 m->Draw();
486 // draw text
487 char l[1024];
488 sprintf(l,"%4.2f",fTargetLumi);
489 //TString pText = *s->Legend() + TString(" (#int L = ") + TString(l) + TString("/pb)");
490 TString pText = *s->Legend() + TString(" (") + TString(l) + TString("/pb)");
491 MDB(kGeneral,1)
492 printf(" Adding text \"%s\" at: (x,y) = (%6.2f,%6.2f)\n",pText.Data(),xText,yText);
493 // set the proper text color
494 text->SetTextColor(kBlack);
495 // plot the text
496 text->SetTextAlign(12);
497 text->DrawLatex(xText,yText,pText.Data());
498 }
499 }
500
501 // Make sure the histogram frame is nice
502 box->SetFillStyle(0);
503 box->SetLineColor(kBlack);
504 box->DrawBox(0,0,100,100);
505
506 delete text;
507 delete box;
508
509 return;
510 }