ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/UHHAnalysis/SFramePlotter/SPlotter.cxx
Revision: 1.12
Committed: Tue May 14 13:14:27 2013 UTC (11 years, 11 months ago) by rkogler
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.11: +23 -4 lines
Log Message:
added normalisation uncertainty for different processes

File Contents

# User Rev Content
1 rkogler 1.1 #include <iostream>
2     #include <iomanip>
3    
4     #include <TObjArray.h>
5     #include <TObjString.h>
6     #include <TStyle.h>
7     #include <TROOT.h>
8     #include <TPaveText.h>
9     #include <TLegend.h>
10     #include <TLegendEntry.h>
11     #include <TLatex.h>
12 rkogler 1.11 #include <TEllipse.h>
13 rkogler 1.7 #include <TF1.h>
14     #include <TMath.h>
15     #include <TColor.h>
16 rkogler 1.1 #include "SPlotter.h"
17    
18     using namespace std;
19    
20     SPlotter::SPlotter()
21     {
22     m_can = NULL;
23     m_ps = NULL;
24     m_ps_name = "default.ps";
25    
26     m_pad1 = NULL;
27 rkogler 1.5 m_pad2 = NULL;
28    
29     m_rp1_top = NULL;
30 dagonzal 1.4 m_rp1 = NULL;
31 rkogler 1.5 m_rp2_top = NULL;
32 rkogler 1.1 m_rp2 = NULL;
33    
34     m_page = 0;
35 rkogler 1.7 m_lumi = 0;
36 rkogler 1.8 m_syserr = -1;
37 rkogler 1.1 debug = false;
38     bShapeNorm = false;
39     bPortrait = true;
40     bDrawEntries = false;
41     bDrawLumi = true;
42     bDrawLegend = true;
43     bPlotRatio = false;
44 rkogler 1.10 bSingleEPS = false;
45 rkogler 1.1 need_update = true;
46    
47     }
48    
49     SPlotter::~SPlotter()
50     {
51     Cleanup();
52     }
53    
54     void SPlotter::SetPsFilename(TString name)
55     {
56     if (!name.EndsWith(".ps")){
57     cerr << "SPlotter::SetPsFilename, given filename: " << name
58     << " does not end with .ps, intention? Please correct steering." << endl;
59     exit(EXIT_FAILURE);
60     }
61     m_ps_name = name;
62    
63     }
64    
65     void SPlotter::DoStacking(vector<TObjArray*>& hists, TObjArray* StackNames)
66     {
67     if (hists.size()==0){
68     cerr << "SPlotter::DoStacking: Empty array of histograms. Aborting." << endl;
69     exit(EXIT_FAILURE);
70     }
71    
72     if (!StackNames){ // trivial case: do nothing
73     return;
74     }
75    
76     // loop over all histogram arrays
77     int narr = hists.size();
78     for (int i=narr-1; i>=0; --i){
79     TObjArray* ha = hists[i];
80     if (ha->GetEntries()<1) continue;
81     TString proc = ((SHist*)ha->At(0))->GetProcessName();
82     if (debug) cout << "SPlotter::DoStacking, hist array = " << i
83     << " process name = " << proc << endl;
84    
85     // loop over all stack-names
86     for (int j=0; j<StackNames->GetEntries(); ++j){
87     TString sname = ((TObjString*)StackNames->At(j))->GetString();
88     if (debug) cout << " stack name = " << sname << endl;
89     if (proc.Contains(sname)){
90     if (debug) cout << " -> found match, stacking this array." << endl;
91     StackHists(hists, i);
92     break;
93     }
94     }
95     }
96    
97     if (debug) cout << "SPlotter::DoStacking: Done." << endl;
98    
99     return;
100    
101     }
102    
103     void SPlotter::StackHists(std::vector<TObjArray*>& hists, int index)
104     {
105     // stack histograms at position 'index' with an existing array of stacks
106     // in hists
107     // if the stacks don't exist, they are created and added to the array
108    
109     // get the stack (create a new one if it doesn't exist yet)
110     TObjArray* stacks = GetStacks(hists, index);
111    
112     // add the histograms at 'index' to the stack
113     for (int i=0; i<stacks->GetEntries(); ++i){
114     SHist* stack = (SHist*)stacks->At(i);
115     SHist* hist = (SHist*)hists[index]->At(i);
116     if (!stack || !hist){
117     cerr << "SPlotter::StackHists: stack or hist at position " << i
118     << " does not exist! Abort." << endl;
119 mmeyer 1.6 cerr << "index of hists = " << hists.size() << " histograms = " << hists[index]->GetEntries() << endl;
120 rkogler 1.1 exit(EXIT_FAILURE);
121     }
122     // sanity check: compare names
123     TString stackname = stack->GetStack()->GetName();
124     TString histname = hist->GetHist()->GetName();
125     if (!stackname.Contains(histname)){
126     cerr << "SPlotter::StackHists: incompatible histograms at position " << i
127     << ", stackname = " << stackname << " histname = " << histname
128     << ". Prefer to exit because of consistency." << endl;
129     exit(EXIT_FAILURE);
130     }
131     // still here? do the stackin'!
132     hist->GetHist()->SetFillColor(hist->GetHist()->GetLineColor());
133     hist->GetHist()->SetFillStyle(1001);
134     stack->GetStack()->Add(hist->GetHist());
135     hist->SetIsUsedInStack(true);
136     hist->SetDoDraw(false);
137 rkogler 1.12 stack->SetUnc(hist->GetUnc(), stack->GetStack()->GetHists()->GetSize()-1);
138     if (debug) cout << "stacking hist " << histname << " on " << stackname << " for process " << hist->GetProcessName()
139 rkogler 1.1 << " (dir = " << stack->GetDir() << ")" << endl;
140 rkogler 1.12 if (i==0){
141     cout << "stacking process " << hist->GetProcessName() << " with weight " << hist->GetWeight() << " and uncertainty " << hist->GetUnc() << endl;
142     }
143 rkogler 1.1 }
144 rkogler 1.12
145 rkogler 1.1 return;
146    
147     }
148    
149     TObjArray* SPlotter::GetStacks(std::vector<TObjArray*>& hists, int index)
150     {
151     // get the array of stacks from the input hists
152     // if it doesn't exist, a new array will be created if index>0
153     // and the hists at position 'index' will be used as blue-print
154    
155     // try to find a stack in the array
156     TObjArray* arr = NULL;
157     int narr = hists.size();
158     for (int i=0; i<narr; ++i){
159     if (hists[i]->GetEntries()==0){
160     cerr << "SPlotter::GetStacks: Got no histograms in array " << i
161     << " unexpected behaviour - abort." << endl;
162     exit(EXIT_FAILURE);
163     }
164    
165     arr = hists[i];
166     SHist* sh = (SHist*) arr->At(i);
167     if (sh->IsStack()){
168     if (debug) cout << "SPlotter::GetStacks: Found stack at position " << i << endl;
169     return arr;
170     }
171     }
172    
173     // no stack found, create a new array with THStacks -> use position 'index'
174     // in the array as a blue-print
175     if (index>-1){
176     if (debug) cout << "SPlotter::GetStacks: Creating new array of THStacks "
177     << "using position " << index << " as blueprint." << endl;
178     if (index>narr){
179     cerr << "SPlotter::GetStacks: Can not create an array of stacks from array"
180     << " index " << index << ", since size is only " << hists.size()
181     << ". Unexpected behaviour - abort." << endl;
182     exit(EXIT_FAILURE);
183     }
184    
185     arr = new TObjArray();
186     for (int i=0; i<hists[index]->GetEntries();++i){
187     TString hname = ((SHist*)hists[index]->At(i))->GetHist()->GetName();
188     TString name = hname + "_stack";
189     THStack* st = new THStack(name, "");
190     SHist* sh = new SHist(st);
191     sh->SetDir(((SHist*)hists[index]->At(i))->GetDir());
192     sh->SetProcessName("SM");
193     sh->SetDoDraw(true);
194     arr->Add(sh);
195     if (debug) cout << "SPlotter::GetStacks: Adding stack with name " << name
196     << " in directory " << sh->GetDir() << " at position " << i << endl;
197     }
198    
199     hists.push_back(arr);
200     if (debug) cout << "SPlotter::GetStacks: Added stack array to collection. "
201     << "New size = " << hists.size() << ", old = " << narr << endl;
202     }
203    
204     return arr;
205    
206     }
207    
208     void SPlotter::CopyStyle(TH1& h1, TH1* h2)
209     {
210     // copy the style from hist2 to hist1
211     h1.SetMarkerStyle(h2->GetMarkerStyle());
212     h1.SetMarkerSize(h2->GetMarkerSize());
213     h1.SetMarkerColor(h2->GetMarkerColor());
214     h1.SetLineWidth(h2->GetLineWidth());
215     h1.SetLineStyle(h2->GetLineStyle());
216     h1.SetLineColor(h2->GetLineColor());
217     h1.SetFillColor(h2->GetFillColor());
218     return;
219     }
220    
221     void SPlotter::SetupGlobalStyle()
222     {
223     // general appearance and style
224    
225     gROOT->SetStyle("Plain");
226     gStyle->SetOptStat(0);
227     gStyle -> SetPadTickX(1);
228     gStyle -> SetPadTickY(1);
229    
230     gStyle->SetPadBorderMode(0);
231     gStyle->SetPadColor(kWhite);
232     gStyle->SetPadGridX(false);
233     gStyle->SetPadGridY(false);
234     gStyle->SetGridColor(0);
235     gStyle->SetGridStyle(3);
236     gStyle->SetGridWidth(1);
237    
238     gStyle->SetFrameBorderMode(0);
239     gStyle->SetFrameBorderSize(1);
240     gStyle->SetFrameFillColor(0);
241     gStyle->SetFrameFillStyle(0);
242     gStyle->SetFrameLineColor(1);
243     gStyle->SetFrameLineStyle(1);
244     gStyle->SetFrameLineWidth(1);
245    
246     gStyle->SetTitleFont(42, "XYZ");
247     gStyle->SetLabelFont(42, "XYZ");
248    
249     gStyle->SetAxisColor(1, "XYZ");
250     gStyle->SetStripDecimals(kTRUE);
251     gStyle->SetTickLength(0.03, "XYZ");
252     gStyle->SetNdivisions(510, "XYZ");
253    
254     gStyle->UseCurrentStyle();
255    
256     }
257    
258     void SPlotter::Cleanup()
259     {
260     // do what the name suggests
261    
262     ClosePostscript();
263     if (m_can){
264     delete m_can;
265     m_can = NULL;
266     }
267     }
268    
269     void SPlotter::SetupCanvas()
270     {
271     // set up a canvas, different possibilities
272     // to take into account portrait/landscape
273     // and ratio/no ratio plots
274    
275     Int_t CanWidth;
276     Int_t CanHeight;
277     if (bPortrait){
278     CanWidth = 600;
279     CanHeight = 830;
280     } else {
281     CanWidth = 800;
282     CanHeight = 600;
283     }
284    
285     // set up the canvas
286     m_can = new TCanvas("canvas","Control Plots", CanWidth, CanHeight);
287    
288     Float_t yplot = 0.3;
289     Float_t yratio = 0.17;
290    
291     // coordinates:
292     //
293     // set up the coordinates of the two pads: // y6 +-------------+
294     Float_t y1, y2, y3, y4, y5, y6; // | |
295     y6 = 0.97; // | pad1 |
296     y5 = y6-yplot; // y5 |-------------|
297     y4 = y5-yratio; // | rp1 |
298     y3 = 0.49; // y4 +-------------+
299     y2 = y3-yplot; //
300     y1 = y2-yratio; // y3 +-------------+
301     Float_t x1, x2; // | |
302     x1 = 0.01; // | pad2 |
303     x2 = 0.99; // y2 |-------------|
304     // | rp2 |
305     // y1 +-------------+
306     // x1 x2
307    
308    
309    
310 rkogler 1.5 m_rp1_top = new TPad("pad1", "Control Plots 1", x1, y5, x2, y6);
311     m_rp1 = new TPad("rp1", "Ratio1", x1, y4, x2, y5);
312    
313     m_rp2_top = new TPad("pad2", "Control Plots 2", x1, y2, x2, y3);
314     m_rp2 = new TPad("rp2", "Ratio2", x1, y1, x2, y2);
315 rkogler 1.1
316    
317 rkogler 1.5 m_pad1 = new TPad("pad1", "Control Plots 1", x1, y4, x2, y6);
318     m_pad2 = new TPad("pad2", "Control Plots 2", x1, y1, x2, y3);
319    
320 rkogler 1.1 // set margins for portrait mode
321     if (bPortrait){
322 rkogler 1.10
323 rkogler 1.7 m_pad1->SetTopMargin(0.05); m_pad1->SetBottomMargin(0.16); m_pad1->SetLeftMargin(0.19); m_pad1->SetRightMargin(0.05);
324     m_pad2->SetTopMargin(0.05); m_pad2->SetBottomMargin(0.16); m_pad2->SetLeftMargin(0.19); m_pad2->SetRightMargin(0.05);
325 rkogler 1.10
326 rkogler 1.7 m_rp1_top->SetTopMargin(0.065); m_rp1_top->SetBottomMargin(0.0); m_rp1_top->SetLeftMargin(0.19); m_rp1_top->SetRightMargin(0.05);
327     m_rp2_top->SetTopMargin(0.065); m_rp2_top->SetBottomMargin(0.0); m_rp2_top->SetLeftMargin(0.19); m_rp2_top->SetRightMargin(0.05);
328 rkogler 1.5 m_rp1->SetTopMargin(0.0); m_rp1->SetBottomMargin(0.35); m_rp1->SetLeftMargin(0.19); m_rp1->SetRightMargin(0.05);
329     m_rp2->SetTopMargin(0.0); m_rp2->SetBottomMargin(0.35); m_rp2->SetLeftMargin(0.19); m_rp2->SetRightMargin(0.05);
330 rkogler 1.10
331     // margins for landscape
332 rkogler 1.1 } else {
333 rkogler 1.10
334 rkogler 1.7 m_rp1_top->SetTopMargin(0.065); m_rp1_top->SetBottomMargin(0.0); m_rp1_top->SetLeftMargin(0.13); m_rp1_top->SetRightMargin(0.05);
335     m_rp2_top->SetTopMargin(0.065); m_rp2_top->SetBottomMargin(0.0); m_rp2_top->SetLeftMargin(0.13); m_rp2_top->SetRightMargin(0.05);
336 rkogler 1.1
337     if (bPlotRatio){
338 rkogler 1.10 m_rp1->SetTopMargin(0.0); m_rp1->SetBottomMargin(0.35); m_rp1->SetLeftMargin(0.13); m_rp1->SetRightMargin(0.05);
339     m_rp2->SetTopMargin(0.0); m_rp2->SetBottomMargin(0.35); m_rp2->SetLeftMargin(0.13); m_rp2->SetRightMargin(0.05);
340 rkogler 1.1 }
341     }
342 rkogler 1.10
343 rkogler 1.1
344 rkogler 1.10 if (debug){
345     m_rp1_top->SetFillColor(kYellow);
346     m_rp2_top->SetFillColor(kOrange);
347     if (bPlotRatio){
348     m_rp1->SetFillColor(kGray);
349     m_rp2->SetFillColor(kGray);
350     }
351     }
352    
353     m_pad1->Draw();
354     m_pad2->Draw();
355 rkogler 1.1
356 rkogler 1.10 m_rp1_top->Draw();
357     m_rp2_top->Draw();
358    
359     if (bPlotRatio){
360     m_rp1->Draw();
361     m_rp2->Draw();
362     }
363    
364     return;
365    
366     }
367    
368     void SPlotter::SetupCanvasForEPS()
369     {
370     // set up a canvas for single EPS files
371     // optimised plots for including in theses or publications and documents
372     // different possibilities
373     // ratio/no ratio plots
374    
375     Int_t CanWidth;
376     Int_t CanHeight;
377     CanWidth = 400;
378     CanHeight = 400;
379    
380     // set up the canvas
381     m_can = new TCanvas("canvas","Control Plots", CanWidth, CanHeight);
382    
383     Float_t yplot = 0.65;
384     Float_t yratio = 0.34;
385    
386     // coordinates:
387     // set up the coordinates of the two pads: //
388     Float_t y1, y2, y3; // y3 +-------------+
389     y3 = 0.99; // | |
390     y2 = y3-yplot; // | pad1 |
391     y1 = y2-yratio; // y2 |-------------|
392     Float_t x1, x2; // | rp1 |
393     x1 = 0.01; // y1 +-------------+
394     x2 = 0.99; // x1 x2
395     //
396     // No Pad 2!
397    
398    
399     m_rp1_top = new TPad("pad1", "Control Plots 2", x1, y2, x2, y3);
400     m_rp1 = new TPad("rp1", "Ratio2", x1, y1, x2, y2);
401     m_pad1 = new TPad("pad1", "Control Plots 2", x1, y1, x2, y3);
402    
403     m_rp2_top = new TPad("pad1", "Control Plots 2", x1, y2, x2, y3);
404     m_rp2 = new TPad("rp1", "Ratio2", x1, y1, x2, y2);
405     m_pad2 = new TPad("pad1", "Control Plots 2", x1, y1, x2, y3);
406    
407    
408     m_pad1->SetTopMargin(0.05); m_pad1->SetBottomMargin(0.16); m_pad1->SetLeftMargin(0.19); m_pad1->SetRightMargin(0.05);
409     m_pad2->SetTopMargin(0.05); m_pad2->SetBottomMargin(0.16); m_pad2->SetLeftMargin(0.19); m_pad2->SetRightMargin(0.05);
410    
411     m_rp1_top->SetTopMargin(0.065); m_rp1_top->SetBottomMargin(0.0); m_rp1_top->SetLeftMargin(0.19); m_rp1_top->SetRightMargin(0.05);
412     m_rp2_top->SetTopMargin(0.065); m_rp2_top->SetBottomMargin(0.0); m_rp2_top->SetLeftMargin(0.19); m_rp2_top->SetRightMargin(0.05);
413     m_rp1->SetTopMargin(0.0); m_rp1->SetBottomMargin(0.35); m_rp1->SetLeftMargin(0.19); m_rp1->SetRightMargin(0.05);
414     m_rp2->SetTopMargin(0.0); m_rp2->SetBottomMargin(0.35); m_rp2->SetLeftMargin(0.19); m_rp2->SetRightMargin(0.05);
415 rkogler 1.1
416     if (debug){
417 rkogler 1.5 m_rp1_top->SetFillColor(kYellow);
418     m_rp2_top->SetFillColor(kOrange);
419 rkogler 1.1 if (bPlotRatio){
420     m_rp1->SetFillColor(kGray);
421     m_rp2->SetFillColor(kGray);
422     }
423     }
424    
425 rkogler 1.5 m_pad1->Draw();
426 rkogler 1.1 m_pad2->Draw();
427 rkogler 1.5
428     m_rp1_top->Draw();
429     m_rp2_top->Draw();
430 rkogler 1.1
431     if (bPlotRatio){
432     m_rp1->Draw();
433     m_rp2->Draw();
434     }
435    
436     return;
437    
438     }
439    
440 rkogler 1.10 void SPlotter::OpenPostscript(TString dir, TString hname)
441 rkogler 1.1 {
442     // create a new ps file with the directory in the name
443 rkogler 1.10 // optional: for EPS files add the name of the histogram
444 rkogler 1.1
445     TString filename(m_ps_name);
446     filename.ReplaceAll(".ps","");
447     filename.Append("_");
448     filename.Append(dir);
449     filename.Append(".ps");
450    
451 rkogler 1.10 if (bSingleEPS){
452     filename.ReplaceAll(".ps","");
453     filename.Append("_");
454     filename.Append(hname);
455     filename.Append(".eps");
456    
457     } else {
458    
459     TString text(dir);
460     text.Prepend("Plotting all histograms in directory ");
461     cout << "\n+-------------------------- SFrame Plotter ---------------------------+" << endl;
462     cout << "| " << setw(60)<< text << " |" << endl;
463     cout << "+---------------------------------------------------------------------+" << endl;
464     m_page = 0;
465     }
466 rkogler 1.1
467     m_ps = NULL;
468 rkogler 1.10 if (bSingleEPS){
469     m_ps = new TPostScript(filename, 113); // eps output
470 rkogler 1.1 } else {
471 rkogler 1.10 if (bPortrait){
472     m_ps = new TPostScript(filename, 111); // ps output
473     m_ps->Range(20.0, 30.0);
474     } else {
475     m_ps = new TPostScript(filename, 112); // ps output
476     m_ps->Range(27.0, 18.0);
477     }
478 rkogler 1.1 }
479    
480     }
481    
482     void SPlotter::ClosePostscript()
483     {
484 rkogler 1.10 // close the ps file and set page number to 0
485 rkogler 1.1 if (m_ps){
486     m_ps->Close();
487     delete m_ps;
488     m_ps = NULL;
489     }
490     m_page = 0;
491     }
492    
493     void SPlotter::ProcessAndPlot(std::vector<TObjArray*> histarr)
494     {
495     // loop over all arrays in the input array and plot them
496    
497     if (histarr.size()<1){
498     cerr << "SPlotter::ProcessAndPlot: No arrays of histograms given. Abort." << endl;
499     exit(EXIT_FAILURE);
500     }
501    
502     if (histarr[0]->GetEntries()<1){
503     cerr << "SPlotter::ProcessAndPlot: No histograms given. Abort." << endl;
504     exit(EXIT_FAILURE);
505     }
506    
507     if (bPlotRatio && histarr.size()==1){
508     cerr << "SPlotter::ProcessAndPlot: Only one process given, can not plot "
509     << " ratio. Steering correct?" << endl;
510     exit(EXIT_FAILURE);
511     }
512    
513     SetupGlobalStyle();
514    
515     TString psname = m_ps_name;
516     TString current_dir = "";
517    
518     // loop over all histograms and plot them!
519     int iplot = 1;
520     bool bleg = true;
521     for (int i=0; i<histarr[0]->GetEntries(); ++i){
522    
523     // get the histograms for the different processes
524     vector<SHist*> hists = GetPlottableHists(histarr, i);
525    
526     // no plottable hists found at position i
527     if (debug) cout << "Number of plottable hists at index " << i << " = " << hists.size() << endl;
528     if (hists.size()==0) continue;
529    
530 rkogler 1.5 if (bShapeNorm) ShapeNormalise(hists);
531    
532 rkogler 1.1 int ipad = GetCurrentPad(iplot);
533 rkogler 1.10
534 rkogler 1.1 if (debug) cout << "Plotting histograms " << hists[0]->GetName()
535     << " iplot = " << iplot << " ipad = " << ipad << endl;
536 rkogler 1.10
537     // new directory? create new ps file for ps-book!
538     if (!bSingleEPS){
539     TString dir = hists[0]->GetDir();
540     if (dir.CompareTo(current_dir)!=0){
541     if (iplot!=1) DrawPageNum();
542     Cleanup();
543     SetupCanvas();
544     OpenPostscript(dir);
545     current_dir = dir;
546     iplot = 1;
547     bleg = true;
548     }
549    
550     // new page every second plot
551     if (iplot%2==1){
552     if (debug) cout << "Creating new page with number " << m_page << endl;
553     DrawPageNum();
554     if (need_update) m_can->Update();
555     m_ps->NewPage();
556     ++m_page;
557     }
558 rkogler 1.1
559 rkogler 1.10 // new file for each plot in single EPS mode
560     } else {
561     TString dir = hists[0]->GetDir();
562     TString hname = hists[0]->GetName();
563     Cleanup();
564     SetupCanvasForEPS();
565     if (debug) cout << "Creating new eps file with name " << dir << "_" << hname << endl;
566     OpenPostscript(dir, hname);
567     current_dir = dir;
568     iplot = 1;
569     bleg = true;
570 rkogler 1.1 }
571    
572     // cosmetics
573     DoCosmetics(hists);
574    
575 rkogler 1.5 // ---------- do what we set out to do: plot! ----------------
576    
577     if (hists[0]->IsYieldPlot()){ // special treatment for lumi yield plot
578    
579     PlotLumiYield(hists[0], ipad);
580    
581     } else { // usual plots
582    
583     PlotHists(hists, ipad);
584     // draw a legend
585     if (bleg){
586     DrawLegend(GetHistsAtIndex(histarr, i));
587     if (!bDrawLegend) bleg = false;
588     }
589     // draw lumi information
590     if (bDrawLumi) DrawLumi();
591     // draw the ratio
592     if (bPlotRatio) PlotRatios(hists, ipad);
593    
594 rkogler 1.1 }
595    
596     ++iplot;
597     }
598    
599     // done!
600     DrawPageNum();
601     if (need_update) m_can->Update();
602     Cleanup();
603    
604     }
605    
606 rkogler 1.5 void SPlotter::PlotLumiYield(SHist* hist, int ipad)
607     {
608     // plot the lumi yield histogram
609    
610     if (ipad==1) m_pad1->cd();
611     if (ipad==2) m_pad2->cd();
612    
613     hist->Draw();
614 rkogler 1.7
615 rkogler 1.11 // calculate the average
616 rkogler 1.7 TH1* h = hist->GetHist();
617 rkogler 1.11 double sum=0;
618     int bins=0;
619     for (int i=1; i<h->GetNbinsX()+1; ++i){
620     if (h->GetBinContent(i)>0){
621     sum += h->GetBinContent(i);
622     bins++;
623     }
624     }
625     double av = sum / bins;
626    
627     // calculate average with outlier-rejection (4sigma)
628     sum=0;
629     bins=0;
630     for (int i=1; i<h->GetNbinsX()+1; ++i){
631     if (h->GetBinContent(i)>0){
632     double dev = TMath::Abs( (h->GetBinContent(i) - av)/h->GetBinError(i) );
633     if (dev<4){
634     sum += h->GetBinContent(i);
635     bins++;
636     } else {
637     cout << "Lumi yield: outlier in bin " << i << " with content " << h->GetBinContent(i) << " average = " << av << endl;
638     }
639     }
640     }
641     av = sum / bins;
642    
643     // calculate error on mean and chi2
644     double dev = 0;
645     double chi2 = 0;
646     for (int i=1; i<h->GetNbinsX()+1; ++i){
647     if (h->GetBinContent(i)>0){
648     double pull = (h->GetBinContent(i) - av)/h->GetBinError(i);
649     if (TMath::Abs(pull)<4){
650     dev += TMath::Power(h->GetBinContent(i)-av, 2);
651     chi2 += pull*pull;
652     }
653     }
654     }
655     double err = TMath::Sqrt(dev/bins);
656    
657     // highlight points with deviations of more than 3, 4 and 5 sigma
658     double xr = h->GetXaxis()->GetXmax() - h->GetXaxis()->GetXmin();
659     double wi = gPad->GetAbsWNDC() * (1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
660     double he = gPad->GetAbsHNDC() * (1 - gPad->GetTopMargin() - gPad->GetBottomMargin());
661     double ar = wi/he;
662     double fudge = 1.;
663     if (bSingleEPS) fudge = 1.2;
664     double r1 = 0.02*xr*fudge;
665     double yr = h->GetMaximum()-h->GetMinimum();
666     double r2 = 0.016*yr*ar*fudge;
667     for (int i=1; i<h->GetNbinsX()+1; ++i){
668     if (h->GetBinContent(i)>0){
669     double pull = (h->GetBinContent(i) - av)/h->GetBinError(i);
670     if (TMath::Abs(pull)>5){
671     TEllipse* circ = new TEllipse(h->GetXaxis()->GetBinCenter(i), h->GetBinContent(i), r1, r2);
672     circ->SetFillColor(kWhite);
673     circ->SetLineColor(kRed);
674     circ->Draw();
675     } else if (TMath::Abs(pull)>4){
676     TEllipse* circ = new TEllipse(h->GetXaxis()->GetBinCenter(i), h->GetBinContent(i), r1, r2);
677     circ->SetFillColor(kWhite);
678     circ->SetLineColor(kOrange);
679     circ->Draw();
680     } else if (TMath::Abs(pull)>3){
681     TEllipse* circ = new TEllipse(h->GetXaxis()->GetBinCenter(i), h->GetBinContent(i), r1, r2);
682     circ->SetFillColor(kWhite);
683     circ->SetLineColor(kSpring);
684     circ->Draw();
685     }
686     }
687     }
688    
689     // draw the average
690 rkogler 1.7 TF1* f = new TF1("average", "[0]", h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
691     f->SetLineColor(kAzure+1);
692     f->SetLineWidth(1);
693 rkogler 1.11 f->SetParameter(0, av);
694     f->Draw("same");
695 rkogler 1.7
696    
697     TF1* fup = new TF1("up", "[0]", h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
698     TF1* fdown = new TF1("down", "[0]", h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
699 rkogler 1.11 fup->SetParameter(0, av+err);
700     fdown->SetParameter(0, av-err);
701 rkogler 1.7 fup->SetLineColor(kAzure+1);
702     fdown->SetLineColor(kAzure+1);
703     fup->SetLineWidth(1);
704     fdown->SetLineWidth(1);
705     fup->SetLineStyle(kDashed);
706     fdown->SetLineStyle(kDashed);
707     fup->Draw("same");
708     fdown->Draw("same");
709    
710     TLatex* text = new TLatex();
711     text->SetTextFont(42);
712     text->SetNDC();
713     text->SetTextColor(kBlack);
714     text->SetTextSize(0.05);
715 rkogler 1.11 if (bSingleEPS) text->SetTextSize(0.04);
716 rkogler 1.7 text->SetTextAlign(11);
717     TString info = TString::Format("#chi^{2} / ndf");
718 rkogler 1.11 text->DrawLatex(0.5, 0.30, info.Data());
719     info = TString::Format("%3.1f / %d", chi2, bins-1);
720     text->DrawLatex(0.65, 0.30, info.Data());
721 rkogler 1.7 info = TString::Format("average");
722 rkogler 1.11 text->DrawLatex(0.5, 0.23, info.Data());
723     info = TString::Format("%4.1f #pm %4.1f", av, err);
724     text->DrawLatex(0.65, 0.23, info.Data());
725    
726     hist->Draw("same");
727 rkogler 1.7
728 rkogler 1.5 return;
729    
730     }
731    
732    
733 dagonzal 1.4 void SPlotter::PlotHists(vector<SHist*> hists, int ipad)
734 rkogler 1.3 {
735 dagonzal 1.4 // plot all histograms in the array
736 rkogler 1.3
737 rkogler 1.5 if (ipad==1){
738     if (bPlotRatio) m_rp1_top->cd();
739     else m_pad1->cd();
740     }
741     if (ipad==2){
742     if (bPlotRatio) m_rp2_top->cd();
743     else m_pad2->cd();
744     }
745 rkogler 1.3
746 rkogler 1.1 bool isok = SetMinMax(hists);
747     if (isok) SetLogAxes(hists);
748    
749     // first get some basic histograms
750     SHist* sstack = SelStack(hists);
751     SHist* sdata = SelData(hists);
752    
753     // first, draw data if it exists
754     int ndrawn = 0;
755     if (sdata){
756     sdata->Draw();
757     ++ndrawn;
758     }
759    
760 rkogler 1.7 if (debug){
761     if (sdata){
762     cout << "\nHist name = " << sdata->GetName() << " process = " << sdata->GetProcessName() << endl;
763     cout << "hists, entries = " << hists.size() << endl;
764     cout << "Data entries = " << sdata->GetHist()->Integral() << endl;
765     }
766     if (sstack){
767     double stack_entries = 0;
768     TObjArray* arr = sstack->GetStack()->GetStack();
769     TH1* h = (TH1*)arr->At(arr->GetEntries()-1);
770     stack_entries = h->Integral();
771     cout << "Stack entries = " << stack_entries << endl;
772     TList* hists = sstack->GetStack()->GetHists();
773     // calculate individual area
774     for (int i=0; i<hists->GetSize(); ++i){
775     TH1* h = (TH1*) hists->At(i);
776     int iend = h->GetNbinsX();
777     double area = h->Integral(1,iend);
778     cout << " entries of histogram " << i << " in stack = " << area << endl;
779     }
780     }
781     }
782    
783 rkogler 1.1 // first round
784     int nh = hists.size();
785    
786     for (int i=0; i<nh; ++i){
787     SHist* sh = hists[i];
788     if (sh->IsStack()) continue;
789     if (sh==sdata) continue;
790     if (ndrawn==0) sh->Draw();
791     else sh->Draw("same");
792     ++ndrawn;
793     }
794    
795     // now draw the stack
796     if (sstack){
797     if (ndrawn==0){
798     sstack->Draw();
799     need_update = false;
800     } else {
801     sstack->Draw("same");
802     }
803     }
804    
805     // second round
806     for (int i=0; i<nh; ++i){
807     SHist* sh = hists[i];
808     if (sh->IsStack()) continue;
809     if (sh==sdata) continue;
810     sh->Draw("same");
811     }
812    
813 rkogler 1.7 // draw normalisation error if it is given
814     if (sstack){
815     DrawNormError(sstack);
816     }
817    
818 rkogler 1.1 // draw data on top
819     if (sdata) sdata->Draw("same");
820    
821     gPad->RedrawAxis();
822    
823     }
824    
825 rkogler 1.7 void SPlotter::DrawNormError(SHist* stack)
826     {
827     // plot an error band corresponding to the overall
828     // normalisation error
829     TH1* h = (TH1*) stack->GetStack()->GetStack()->At( stack->GetStack()->GetStack()->GetEntries()-1 );
830     TH1* e = (TH1*) h->Clone();
831     for (Int_t i=1; i<e->GetNbinsX()+1; ++i){
832 rkogler 1.8 Double_t sys = 0;
833 rkogler 1.9 if (m_syserr>0) sys = m_syserr*e->GetBinContent(i);
834 rkogler 1.7 Double_t stat = e->GetBinError(i);
835 rkogler 1.12 Double_t norm_err = CalcNormErrorForBin(stack, i);
836     Double_t err = TMath::Sqrt(norm_err*norm_err + sys*sys + stat*stat);
837 rkogler 1.7 e->SetBinError(i, err);
838     }
839     static Int_t LightGray = TColor::GetColor( "#aaaaaa" );
840     //e->SetFillColor(kGray+2);
841     e->SetFillColor(LightGray);
842     e->SetLineWidth(1);
843     e->SetFillStyle(3245);
844     e->Draw("E2 same");
845    
846     }
847    
848 rkogler 1.12 double SPlotter::CalcNormErrorForBin(SHist* stack, int ibin)
849     {
850     // calculate the normalisation uncertainty of a single bin in the stack
851     // due to normalisation uncertainty on different processes
852    
853     double err = 0;
854     for (int i=0; i<stack->GetStack()->GetStack()->GetEntries(); ++i){
855     TH1* h = (TH1*) stack->GetStack()->GetHists()->At(i);
856     err += h->GetBinContent(ibin)*stack->GetUnc(i);
857     }
858     return err;
859     }
860    
861 rkogler 1.1 void SPlotter::PlotRatios(vector<SHist*> hists, int ipad)
862     {
863     // plot all histograms in the array
864    
865     if (ipad==1) m_rp1->cd();
866     if (ipad==2) m_rp2->cd();
867    
868     // calculate ratios
869     vector<SHist*> ratios = CalcRatios(hists);
870    
871     gPad->SetLogx(0);
872     gPad->SetLogy(0);
873    
874     int ndrawn = 0;
875     int nh = ratios.size();
876     for (int i=0; i<nh; ++i){
877     SHist* rh = ratios[i];
878     TString name = rh->GetName();
879     if (name.Contains("_lx")) gPad->SetLogx(1);
880     if (ndrawn==0) rh->Draw();
881     else rh->Draw("same");
882     ++ndrawn;
883     }
884    
885     gPad->RedrawAxis();
886    
887     }
888    
889     vector<SHist*> SPlotter::CalcRatios(vector<SHist*> hists)
890     {
891     // build ratios from the array 'hists'
892     // by default it is checked if a data histogram exists,
893     // which is then divided by the stack
894     // steerable: which histograms should be calculated for the ratio
895    
896     // first get the basic histograms
897     SHist* sstack = SelStack(hists);
898     SHist* sdata = SelData(hists);
899    
900     vector<SHist*> ratios;
901    
902     // TODO: ratio if neither stack nor data exist
903     if (!sstack || !sdata){
904     return ratios;
905     }
906    
907     SHist* rd = (SHist*) sdata->Duplicate();
908     TH1D* rdhist = (TH1D*) rd->GetHist();
909    
910     // get the denominator: the last element in the stack is the sum of all
911     TObjArray* arr = sstack->GetStack()->GetStack();
912     TH1D* denom = (TH1D*) arr->At(arr->GetEntries()-1);
913    
914     rdhist->Divide(denom);
915 rkogler 1.7 // set the error to display only the error on the data
916     for (Int_t ibin=1;ibin<denom->GetNbinsX()+1; ++ibin){
917     Double_t val = sdata->GetHist()->GetBinContent(ibin);
918     Double_t err = sdata->GetHist()->GetBinError(ibin);
919     Double_t rel_err = err / val;
920     rdhist->SetBinError(ibin, rel_err * rdhist->GetBinContent(ibin) );
921     }
922 rkogler 1.1 rdhist->GetYaxis()->SetTitle(rd->GetProcessName() + " / MC");
923 rkogler 1.10 if (bSingleEPS){
924     SingleEPSRatioCosmetics(rdhist);
925     } else {
926     RatioCosmetics(rdhist);
927     }
928 rkogler 1.1
929 rkogler 1.7 // one histogram for the MC statistical error and one for the total error
930 rkogler 1.1 SHist* mcerr = new SHist(rdhist);
931     mcerr->GetHist()->SetName("MCstat");
932     mcerr->SetProcessName("MCstat");
933     TH1D* MCstat = (TH1D*)mcerr->GetHist();
934    
935 rkogler 1.7 SHist* mctot = new SHist(rdhist);
936     mctot->GetHist()->SetName("MCtot");
937     mctot->SetProcessName("MCtot");
938     TH1D* MCtot = (TH1D*)mctot->GetHist();
939    
940 rkogler 1.1 for (Int_t ibin=1;ibin<denom->GetNbinsX()+1; ++ibin){
941     Double_t val = denom->GetBinContent(ibin);
942     Double_t err = denom->GetBinError(ibin);
943     MCstat->SetBinContent(ibin, 1.0);
944     MCstat->SetBinError(ibin, err/val);
945 rkogler 1.7
946 rkogler 1.8 Double_t sys = 0;
947     if (m_syserr>0) sys = m_syserr;
948 rkogler 1.12 Double_t norm_err = CalcNormErrorForBin(sstack, ibin)/val;
949     Double_t tot = TMath::Sqrt(norm_err*norm_err + sys*sys + err/val*err/val);
950 rkogler 1.7 MCtot->SetBinContent(ibin, 1.0);
951     MCtot->SetBinError(ibin, tot);
952 rkogler 1.1 }
953 rkogler 1.7
954 rkogler 1.9 //static Int_t VLightGray = TColor::GetColor( "#eeeeee" );
955 rkogler 1.7 static Int_t MLightGray = TColor::GetColor( "#dddddd" );
956 rkogler 1.9 static Int_t LightGray = TColor::GetColor( "#aaaaaa" );
957 rkogler 1.7 //static Int_t Gray = TColor::GetColor( "#888888" );
958    
959 rkogler 1.1 MCstat->SetMarkerStyle(0);
960     MCstat->SetMarkerSize(0);
961 rkogler 1.9 MCstat->SetLineColor(LightGray);
962     MCstat->SetFillColor(LightGray);
963 rkogler 1.1
964 rkogler 1.7 MCtot->SetMarkerStyle(0);
965     MCtot->SetMarkerSize(0);
966 rkogler 1.9 MCtot->SetLineColor(MLightGray);
967     MCtot->SetFillColor(MLightGray);
968 rkogler 1.7
969     ratios.push_back(mctot);
970 rkogler 1.1 ratios.push_back(mcerr);
971     ratios.push_back(rd);
972    
973     return ratios;
974    
975     }
976    
977     void SPlotter::DrawLegend(vector<SHist*> hists)
978     {
979     // draw a legend
980    
981     int narr = hists.size();
982     float yfrac = 0.06;
983     if (!bPlotRatio) yfrac = 0.05;
984 rkogler 1.7
985     float top = 0.89;
986 rkogler 1.5 if (!bPlotRatio && bDrawLumi) top = 0.86;
987 rkogler 1.10 if (bSingleEPS){
988     top = 0.92;
989     if (bPlotRatio) top = 0.88;
990     if (bDrawLumi) top = 0.84;
991     }
992 rkogler 1.1 float ysize = yfrac*narr;
993 rkogler 1.5 float xleft = 0.7;
994 rkogler 1.10 if (bSingleEPS) xleft = 0.6;
995 rkogler 1.1 float xright = 0.92;
996     if (!bPortrait){
997     top = 0.99;
998     ysize = 0.07*narr;
999     xleft = 0.72;
1000     xright = 0.96;
1001     }
1002    
1003     TLegend *leg = new TLegend(xleft,top-ysize,xright,top, NULL,"brNDC");
1004     leg->SetFillColor(0);
1005     leg->SetLineColor(1);
1006     leg->SetBorderSize(0);
1007     leg->SetTextFont(42);
1008     leg->SetFillStyle(0);
1009 rkogler 1.10 if (bSingleEPS) leg->SetTextSize(0.045);
1010 rkogler 1.1
1011     for (Int_t i=0; i<narr; ++i){
1012     SHist* sh = hists[i];
1013     if (sh->IsStack()) continue;
1014    
1015     TString legname = TString::Format("leg_entry_%i",i);
1016     TString legtitle = sh->GetLegName();
1017     TLegendEntry* entry = NULL;
1018     int marker = sh->GetHist()->GetMarkerStyle();
1019     int lstyle = sh->GetHist()->GetLineStyle();
1020    
1021     if (marker>0){
1022     entry = leg->AddEntry(legname, legtitle, "lp");
1023     entry->SetLineWidth(1);
1024     entry->SetLineColor(sh->GetHist()->GetLineColor());
1025     entry->SetMarkerColor(sh->GetHist()->GetLineColor());
1026     entry->SetMarkerStyle(marker);
1027     entry->SetMarkerSize(1.0);
1028 rkogler 1.10 if (bSingleEPS) entry->SetMarkerSize(0.8);
1029 rkogler 1.1 } else {
1030    
1031     if (sh->IsUsedInStack()){
1032     entry = leg->AddEntry(legname, legtitle, "f");
1033     entry->SetLineWidth(1);
1034     entry->SetLineColor(sh->GetHist()->GetLineColor());
1035     entry->SetFillColor(sh->GetHist()->GetLineColor());
1036     entry->SetFillStyle(1001);
1037    
1038     } else {
1039     entry = leg->AddEntry(legname, legtitle, "l");
1040     entry->SetLineColor(sh->GetHist()->GetLineColor());
1041     entry->SetMarkerStyle(0);
1042     entry->SetMarkerSize(0);
1043     entry->SetMarkerColor(sh->GetHist()->GetLineColor());
1044     entry->SetLineWidth(2);
1045     entry->SetLineStyle(lstyle);
1046    
1047     }
1048     entry->SetTextAlign(12);
1049     //entry->SetTextColor(fSampleColors.At(i));
1050     }
1051     }
1052     leg->Draw();
1053    
1054     }
1055    
1056    
1057     void SPlotter::DrawLumi()
1058     {
1059 rkogler 1.5 TString infotext = TString::Format("CMS Preliminary, %3.1f fb^{-1} at #sqrt{s} = 8 TeV", m_lumi);
1060 rkogler 1.1 TLatex *text1 = new TLatex(3.5, 24, infotext);
1061     text1->SetNDC();
1062     text1->SetTextAlign(13);
1063     text1->SetX(0.22);
1064     text1->SetTextFont(42);
1065 rkogler 1.5 if (bPlotRatio){
1066     text1->SetTextSize(0.06);
1067 rkogler 1.7 text1->SetY(0.89);
1068 rkogler 1.5 } else {
1069 rkogler 1.7 text1->SetTextSize(0.045);
1070 rkogler 1.5 text1->SetY(0.92);
1071     }
1072 rkogler 1.1 text1->Draw();
1073    
1074     }
1075    
1076     void SPlotter::DoCosmetics(vector<SHist*> hists)
1077     {
1078    
1079     // loop over all histograms and make them pretty
1080     int nh = hists.size();
1081     for (int i=0; i<nh; ++i){
1082     SHist* sh = hists[i];
1083     if (sh->IsStack()) continue;
1084     GeneralCosmetics(sh->GetHist());
1085     if (bPortrait) PortraitCosmetics(sh->GetHist());
1086     if (!bPortrait) LandscapeCosmetics(sh->GetHist());
1087 rkogler 1.10 if (bSingleEPS) SingleEPSCosmetics(sh->GetHist());
1088 rkogler 1.5 if (sh->IsYieldPlot()) YieldCosmetics(sh->GetHist());
1089 rkogler 1.1 }
1090    
1091     }
1092    
1093     SHist* SPlotter::SelStack(vector<SHist*> hists)
1094     {
1095     // select the stack histogram from the array
1096     int narr = hists.size();
1097     SHist* h = NULL;
1098     for (int i=0; i<narr; ++i){
1099     if (hists[i]->IsStack()){
1100     h=hists[i];
1101     break;
1102     }
1103     }
1104     return h;
1105     }
1106    
1107     SHist* SPlotter::SelData(vector<SHist*> hists)
1108     {
1109     // select the data histogram from the array
1110     int narr = hists.size();
1111     SHist* h = NULL;
1112     TString process;
1113     for (int i=0; i<narr; ++i){
1114     process = hists[i]->GetProcessName();
1115     if (process.Contains("data", TString::kIgnoreCase)){
1116     h = hists[i];
1117     break;
1118     }
1119     }
1120     return h;
1121     }
1122    
1123     bool SPlotter::SetMinMax(vector<SHist*> hists)
1124     {
1125     // set minimum and maximum of all histograms
1126     int narr = hists.size();
1127     TString name = hists[0]->GetName();
1128     double max = 0;
1129     double min = FLT_MAX;
1130     for (int i=0; i<narr; ++i){
1131     if (max<hists[i]->GetMaximum()) max = hists[i]->GetMaximum();
1132 rkogler 1.7 if (min>hists[i]->GetMinimum(1e-6)) min = hists[i]->GetMinimum(1e-6);
1133 mmeyer 1.6 double imin = hists[i]->GetMinimum(1e-10);
1134     if (min>imin){
1135     if (imin>1e-10){
1136     min = imin;
1137     }
1138     }
1139 rkogler 1.1 }
1140    
1141     bool isok = true;
1142     if (max<1e-6){
1143     isok = false;
1144     return isok;
1145     }
1146    
1147     bool islog = false;
1148     double uscale = 1.2;
1149     if (name.Contains("_lxy") || name.Contains("_ly")){
1150     islog = true;
1151     uscale = 12.;
1152     }
1153    
1154     for (int i=0; i<narr; ++i){
1155     SHist* h = hists[i];
1156     if (h->IsStack()){
1157 mmeyer 1.6 if (!islog){
1158     h->GetStack()->SetMinimum(0.001);
1159     } else {
1160     if (min>1e-10){
1161     if (min<0.1){
1162     h->GetStack()->SetMinimum(0.04);
1163     } else {
1164     h->GetStack()->SetMinimum(min);
1165     }
1166     }
1167     }
1168 rkogler 1.1 h->GetStack()->SetMaximum(uscale*max);
1169     } else {
1170 mmeyer 1.6 if (!islog){
1171     h->GetHist()->SetMinimum(0.001);
1172     } else {
1173     if (min>1e-10){
1174     if (min<0.1){
1175     h->GetHist()->SetMinimum(0.04);
1176     } else {
1177     h->GetHist()->SetMinimum(min);
1178     }
1179     }
1180     }
1181 rkogler 1.1 h->GetHist()->SetMaximum(uscale*max);
1182     }
1183     }
1184    
1185     return isok;
1186     }
1187    
1188     void SPlotter::SetLogAxes(vector<SHist*> hists)
1189     {
1190     // set log axes
1191     TString name = hists[0]->GetName();
1192     gPad->SetLogx(0);
1193     gPad->SetLogy(0);
1194     if (name.Contains("_lxy")){
1195     gPad->SetLogx(1);
1196     gPad->SetLogy(1);
1197     } else if (name.Contains("_lx")){
1198     gPad->SetLogx(1);
1199     } else if (name.Contains("_ly")){
1200     gPad->SetLogy(1);
1201     } else {
1202     // do nothing, all fine
1203     }
1204     return;
1205     }
1206    
1207     int SPlotter::GetCurrentPad(int np)
1208     {
1209     // get the current pad, depending on the number of
1210     // already processed plots
1211     int ipad = 1;
1212     int rest = np%2;
1213     if (rest==0) ipad=2;
1214     return ipad;
1215     }
1216    
1217     vector<SHist*> SPlotter::GetHistsAtIndex(std::vector<TObjArray*> histarr, int index)
1218     {
1219     // fill an array with histograms at position index.
1220    
1221     vector<SHist*> hists;
1222     int narr = histarr.size();
1223     for (int i=0; i<narr; ++i){
1224     SHist* hist = (SHist*)histarr[i]->At(index);
1225     hists.push_back(hist);
1226     }
1227    
1228     return hists;
1229    
1230     }
1231    
1232     vector<SHist*> SPlotter::GetPlottableHists(std::vector<TObjArray*> histarr, int index)
1233     {
1234     // fill an array with plottable histograms at position index.
1235     // if the first histogram in the array should be plotted (DoPlot flag),
1236     // then take at first position in the array
1237     // otherwise look for the stack and plot it first
1238     // only then all other histograms are added
1239    
1240     if (debug) cout << "\nSPlotter: Collecting plottable hists for index " << index << endl;
1241     vector<SHist*> hists;
1242     bool gotstack = false;
1243     SHist* hist = (SHist*)histarr[0]->At(index);
1244    
1245     // check if the histogram is a 2D or 3D histogram,
1246     // plotting not supported yet, to come
1247     if (hist->GetHist()->InheritsFrom(TH2::Class())){
1248     if (debug) cout << "Hist inherits from TH2, return without adding any to the array " << endl;
1249     return hists;
1250     }
1251    
1252 rkogler 1.5 TString name = hist->GetName();
1253     TString process = hist->GetProcessName();
1254     if (process.Contains("data",TString::kIgnoreCase)
1255     && name.Contains("_perlumibin", TString::kIgnoreCase)){
1256     hist->SetIsYieldPlot(true);
1257     hists.push_back(hist);
1258     return hists;
1259     }
1260    
1261 rkogler 1.1 if (hist->DoDraw()){ // take first hist
1262     hists.push_back(hist);
1263     gotstack = false;
1264     if (debug) cout << "Adding hist " << hist->GetHist()->GetName()
1265     << " from process " << hist->GetProcessName()
1266     << " and directory " << hist->GetDir() << " to array." << endl;
1267     } else { // try if stack exists
1268     TObjArray* stacks = GetStacks(histarr);
1269     if (stacks){
1270     hist = (SHist*)stacks->At(index);
1271     hists.push_back(hist);
1272     gotstack = true;
1273     if (debug) cout << "Adding stack " << hist->GetStack()->GetName()
1274     << " from process " << hist->GetProcessName()
1275     << " and directory " << hist->GetDir() << " to array." << endl;
1276     }
1277     }
1278    
1279     // loop over the rest and add them to the array
1280     int narr = histarr.size();
1281     for (int i=1; i<narr; ++i){
1282    
1283     SHist* hist = (SHist*)histarr[i]->At(index);
1284    
1285     if (hist->DoDraw()){ // take it if it should be drawn
1286    
1287     if (hist->IsStack()){
1288     if (!gotstack){ // take the stack only if not already added
1289     hists.push_back(hist);
1290     if (debug) cout << "Adding stack " << hist->GetStack()->GetName()
1291     << " from process " << hist->GetProcessName()
1292     << " and directory " << hist->GetDir() << " to array." << endl;
1293     }
1294     } else { // take the histogram if it's not the stack hist
1295     hists.push_back(hist);
1296     if (debug) cout << "Adding hist " << hist->GetHist()->GetName()
1297     << " from process " << hist->GetProcessName()
1298     << " and directory " << hist->GetDir() << " to array." << endl;
1299     }
1300     }
1301     }
1302    
1303     if (debug) cout << "SPlotter: Done with collecting plottable hists for index "
1304     << index << ", got " << hists.size() << " histograms" << endl;
1305    
1306     return hists;
1307    
1308     }
1309    
1310     void SPlotter::DrawPageNum()
1311     {
1312    
1313     m_can->cd();
1314     TPaveText* text;
1315     TString s;
1316     s.Form("%i",m_page);
1317     if (bPortrait){
1318     text = new TPaveText(0.93, 0.00, 0.97, 0.03, "NDC");
1319     } else {
1320     text = new TPaveText(0.03,0.00, 0.06, 0.03, "NDC");
1321     }
1322     text->SetBorderSize(0);
1323     text->SetFillColor(0);
1324     text->AddText(s.Data());
1325     text->Draw("same");
1326    
1327     }
1328    
1329     void SPlotter::GeneralCosmetics(TH1* hist)
1330     {
1331     // set Y-axis title
1332 rkogler 1.7 hist->GetYaxis()->SetTitle("Events");
1333 rkogler 1.1
1334     // set X-axis title
1335     hist->GetXaxis()->SetTitle(hist->GetTitle());
1336    
1337     hist->SetTitle("");
1338    
1339     if (bShapeNorm) {
1340     hist->GetYaxis()->SetTitle("#DeltaN/N");
1341     }
1342    
1343     hist->GetXaxis()->SetTitleFont(42);
1344     hist->GetXaxis()->SetLabelFont(42);
1345     hist->GetYaxis()->SetTitleFont(42);
1346     hist->GetYaxis()->SetLabelFont(42);
1347    
1348     }
1349    
1350     void SPlotter::PortraitCosmetics(TH1* hist)
1351     {
1352    
1353     // top histogram of the ratio plot
1354     if (bPlotRatio){
1355    
1356     // x-axis
1357     hist->GetXaxis()->SetTickLength(0.05);
1358    
1359     // y-axis
1360     hist->GetYaxis()->SetTitleSize(0.07);
1361     hist->GetYaxis()->SetLabelSize(0.062);
1362     hist->GetYaxis()->SetLabelOffset(0.01);
1363     hist->GetYaxis()->SetTitleOffset(0.8);
1364     hist->GetYaxis()->SetTickLength(0.02);
1365    
1366     // only this histogram
1367     } else {
1368    
1369     hist->GetXaxis()->SetLabelSize(0.05);
1370     hist->GetXaxis()->SetLabelOffset(0.008);
1371     hist->GetXaxis()->SetTickLength(0.03);
1372     hist->GetXaxis()->SetTitleSize(0.05);
1373     hist->GetXaxis()->SetTitleOffset(1.2);
1374    
1375     hist->GetYaxis()->SetTitleOffset(1.2);
1376     hist->GetYaxis()->SetTitleSize(0.06);
1377     hist->GetYaxis()->SetLabelSize(0.045);
1378     hist->GetYaxis()->SetTickLength(0.02);
1379     hist->GetYaxis()->SetLabelOffset(0.011);
1380    
1381     }
1382    
1383     }
1384    
1385 rkogler 1.10 void SPlotter::SingleEPSCosmetics(TH1* hist)
1386     {
1387    
1388     // top histogram of the ratio plot
1389     if (bPlotRatio){
1390    
1391     // x-axis
1392     hist->GetXaxis()->SetTickLength(0.05);
1393    
1394     // y-axis
1395     hist->GetYaxis()->SetTitleSize(0.07);
1396     hist->GetYaxis()->SetLabelSize(0.062);
1397     hist->GetYaxis()->SetLabelOffset(0.01);
1398     hist->GetYaxis()->SetTitleOffset(1.15);
1399     hist->GetYaxis()->SetTickLength(0.02);
1400    
1401     // only this histogram
1402     } else {
1403    
1404     hist->GetXaxis()->SetLabelSize(0.05);
1405     hist->GetXaxis()->SetLabelOffset(0.008);
1406     hist->GetXaxis()->SetTickLength(0.03);
1407     hist->GetXaxis()->SetTitleSize(0.05);
1408     hist->GetXaxis()->SetTitleOffset(1.2);
1409    
1410     hist->GetYaxis()->SetTitleOffset(1.8);
1411     hist->GetYaxis()->SetTitleSize(0.05);
1412     hist->GetYaxis()->SetLabelSize(0.045);
1413     hist->GetYaxis()->SetTickLength(0.02);
1414     hist->GetYaxis()->SetLabelOffset(0.011);
1415    
1416     }
1417    
1418     }
1419    
1420     void SPlotter::SingleEPSRatioCosmetics(TH1* hist)
1421     {
1422    
1423     //hist->GetYaxis()->SetRangeUser(0.3, 1.7);
1424     hist->GetYaxis()->SetRangeUser(0.05, 1.95);
1425     hist->SetMarkerSize(0.7);
1426    
1427     // cosmetics for portrait mode
1428     if (bPortrait){
1429     hist->SetTitle("");
1430    
1431     // x-axis
1432     hist->GetXaxis()->SetLabelSize(0.12);
1433     hist->GetXaxis()->SetTickLength(0.08);
1434     hist->GetXaxis()->SetTitleSize(0.12);
1435     hist->GetXaxis()->SetTitleOffset(1.25);
1436    
1437     // y-axis
1438     hist->GetYaxis()->CenterTitle();
1439     hist->GetYaxis()->SetTitleSize(0.12);
1440     hist->GetYaxis()->SetTitleOffset(0.66);
1441     hist->GetYaxis()->SetLabelSize(0.11);
1442     //hist->GetYaxis()->SetNdivisions(210);
1443     hist->GetYaxis()->SetNdivisions(505);
1444     hist->GetYaxis()->SetTickLength(0.02);
1445     hist->GetYaxis()->SetLabelOffset(0.011);
1446    
1447     // cosmetics for landscape mode
1448     } else {
1449    
1450     hist->SetTitle("");
1451     hist->SetTitleOffset(1.1, "X");
1452     hist->SetTitleOffset(0.5, "Y");
1453     hist->SetLabelOffset(0.02, "X");
1454     hist->SetLabelOffset(0.01, "Y");
1455    
1456     hist->GetXaxis()->SetLabelSize(0.14);
1457     hist->GetXaxis()->SetTickLength(0.07);
1458     hist->GetXaxis()->SetTitleSize(0.15);
1459    
1460     hist->GetYaxis()->CenterTitle();
1461     hist->GetYaxis()->SetTitleSize(0.11);
1462     hist->GetYaxis()->SetLabelSize(0.12);
1463     hist->GetYaxis()->SetNdivisions(505);
1464     hist->GetYaxis()->SetTickLength(0.03);
1465    
1466     }
1467    
1468     }
1469    
1470 mmeyer 1.6
1471 rkogler 1.5 void SPlotter::YieldCosmetics(TH1* hist)
1472     {
1473     // cosmetics for the lumi yield histogram
1474     hist->GetXaxis()->SetLabelSize(0.05);
1475     hist->GetXaxis()->SetLabelOffset(0.008);
1476     hist->GetXaxis()->SetTickLength(0.03);
1477     hist->GetXaxis()->SetTitleSize(0.05);
1478     hist->GetXaxis()->SetTitleOffset(1.2);
1479    
1480     hist->GetYaxis()->SetTitleOffset(1.2);
1481     hist->GetYaxis()->SetTitleSize(0.06);
1482     hist->GetYaxis()->SetLabelSize(0.045);
1483     hist->GetYaxis()->SetTickLength(0.02);
1484     hist->GetYaxis()->SetLabelOffset(0.011);
1485    
1486 rkogler 1.11 if (bSingleEPS){
1487     hist->GetYaxis()->SetTitleOffset(1.8);
1488     hist->GetYaxis()->SetTitleSize(0.055);
1489     hist->GetYaxis()->SetLabelSize(0.05);
1490     hist->GetYaxis()->SetTickLength(0.02);
1491     hist->GetYaxis()->SetLabelOffset(0.011);
1492     }
1493    
1494 rkogler 1.7 hist->GetXaxis()->SetTitle("integrated luminosity [fb^{-1}]");
1495     double dlum = hist->GetXaxis()->GetBinWidth(1);
1496     TString xtit = TString::Format("events per %3.1f fb^{-1}", dlum);
1497     hist->GetYaxis()->SetTitle(xtit);
1498 rkogler 1.5 }
1499    
1500 mmeyer 1.6
1501    
1502 rkogler 1.1 void SPlotter::LandscapeCosmetics(TH1* hist)
1503     {
1504    
1505    
1506    
1507     }
1508    
1509     void SPlotter::RatioCosmetics(TH1* hist)
1510     {
1511    
1512 mmeyer 1.6 //hist->GetYaxis()->SetRangeUser(0.3, 1.7);
1513     hist->GetYaxis()->SetRangeUser(0.05, 1.95);
1514 rkogler 1.1 hist->SetMarkerSize(0.7);
1515    
1516     // cosmetics for portrait mode
1517     if (bPortrait){
1518     hist->SetTitle("");
1519    
1520     // x-axis
1521     hist->GetXaxis()->SetLabelSize(0.12);
1522     hist->GetXaxis()->SetTickLength(0.08);
1523     hist->GetXaxis()->SetTitleSize(0.12);
1524     hist->GetXaxis()->SetTitleOffset(1.25);
1525    
1526     // y-axis
1527     hist->GetYaxis()->CenterTitle();
1528     hist->GetYaxis()->SetTitleSize(0.12);
1529     hist->GetYaxis()->SetTitleOffset(0.46);
1530     hist->GetYaxis()->SetLabelSize(0.11);
1531 mmeyer 1.6 //hist->GetYaxis()->SetNdivisions(210);
1532     hist->GetYaxis()->SetNdivisions(505);
1533 rkogler 1.1 hist->GetYaxis()->SetTickLength(0.02);
1534     hist->GetYaxis()->SetLabelOffset(0.011);
1535    
1536     // cosmetics for landscape mode
1537     } else {
1538    
1539     hist->SetTitle("");
1540     hist->SetTitleOffset(1.1, "X");
1541     hist->SetTitleOffset(0.5, "Y");
1542     hist->SetLabelOffset(0.02, "X");
1543     hist->SetLabelOffset(0.01, "Y");
1544    
1545     hist->GetXaxis()->SetLabelSize(0.14);
1546     hist->GetXaxis()->SetTickLength(0.07);
1547     hist->GetXaxis()->SetTitleSize(0.15);
1548    
1549     hist->GetYaxis()->CenterTitle();
1550     hist->GetYaxis()->SetTitleSize(0.11);
1551     hist->GetYaxis()->SetLabelSize(0.12);
1552     hist->GetYaxis()->SetNdivisions(505);
1553     hist->GetYaxis()->SetTickLength(0.03);
1554    
1555     }
1556    
1557 rkogler 1.5 }
1558 rkogler 1.1
1559 rkogler 1.5 void SPlotter::ShapeNormalise(std::vector<SHist*> hists)
1560     {
1561     for (unsigned int i=0; i<hists.size(); ++i){
1562     hists[i]->NormaliseToArea();
1563     }
1564     }
1565 rkogler 1.1