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

# User Rev Content
1 paus 1.2 // $Id: PlotTask.cc,v 1.1 2010/10/03 03:40:00 paus Exp $
2 paus 1.1
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     }