HighLAND
DrawingToolsBase.cxx
1 #include "DrawingToolsBase.hxx"
2 #include "WeightTools.hxx"
3 #include "HEPConstants.hxx"
4 #include <TVirtualHistPainter.h>
5 #include <THistPainter.h>
6 #include "SetT2KStyle.H"
7 #include <TArrow.h>
8 #include <TColor.h>
9 #include <TLatex.h>
10 #include <TStyle.h>
11 #include <iomanip>
12 #include <iostream>
13 #include <fstream>
14 #include <cerrno>
15 
16 int auto_colors[NAUTOCOLORS] = { 1, 2 ,3 ,4 , 6 ,7, 8, 9, 31, 32};
17 int auto_markers[NAUTOCOLORS] = { 20, 21, 22, 23, 33, 34, 29, 24, 25, 26};
18 int auto_styles[NAUTOCOLORS] = {3004, 3005, 3006, 3007, 3013, 3001, 3352, 3325, 3357, 3375};
19 const int NMAXTOYS=1000;
20 
21 //********************************************************************
22 DrawingToolsBase::DrawingToolsBase(const std::string& file, Int_t T2KstyleIndex){
23 //********************************************************************
24 
25  _config_file ="";
26 
27  // Load the categories from the file, and any other information stored
28  // in the "config" tree.
29  if (file!=""){
30  ReadConfig(file);
31  }
32 
33  gStyle->SetStatFormat("6.6g"); // no scientifiic notation up to 10e6
34 
35  if (T2KstyleIndex==1) {
36  // OLD T2K style
37 
38  // use plain black on white colors
39  gStyle->SetFrameBorderMode(0);
40  gStyle->SetCanvasBorderMode(0);
41  gStyle->SetPadBorderMode(0);
42  gStyle->SetPadColor(0);
43  gStyle->SetCanvasColor(0);
44  gStyle->SetStatColor(0);
45  gStyle->SetLegendBorderSize(1);
46 
47  // set the paper & margin sizes
48  gStyle->SetPaperSize(20,26);
49  gStyle->SetPadTopMargin(0.05);
50  gStyle->SetPadRightMargin(0.05);
51  gStyle->SetPadBottomMargin(0.16);
52  gStyle->SetPadLeftMargin(0.13);
53 
54  // use large Times-Roman fonts
55  gStyle->SetTextFont(132);
56  gStyle->SetTextSize(0.08);
57  gStyle->SetLabelFont(132,"x");
58  gStyle->SetLabelFont(132,"y");
59  gStyle->SetLabelFont(132,"z");
60  gStyle->SetLabelSize(0.05,"x");
61  gStyle->SetTitleSize(0.06,"x");
62  gStyle->SetLabelSize(0.05,"y");
63  gStyle->SetTitleSize(0.06,"y");
64  gStyle->SetLabelSize(0.05,"z");
65  gStyle->SetTitleSize(0.06,"z");
66  gStyle->SetLabelFont(132,"t");
67  gStyle->SetTitleFont(132,"x");
68  gStyle->SetTitleFont(132,"y");
69  gStyle->SetTitleFont(132,"z");
70  gStyle->SetTitleFont(132,"t");
71  gStyle->SetStatFont(132);
72  gStyle->SetTitleFillColor(0);
73  gStyle->SetTitleX(0.25);
74  gStyle->SetTitleFontSize(0.08);
75  gStyle->SetTitleFont(132,"pad");
76 
77  // get rid of X error bars and y error bar caps
78  //gStyle->SetErrorX(0.001);
79 
80 
81  // put tick marks on top and RHS of plots
82  gStyle->SetPadTickX(1);
83  gStyle->SetPadTickY(1);
84 
85 
86  // Define a nicer color palette (red->blue)
87  // Uncomment these lines for a color palette (default is B&W)
88  gStyle->SetPalette(1,0); // use the nice red->blue palette
89  const Int_t NRGBs = 5;
90  const Int_t NCont = 255;
91 
92  Double_t stops[NRGBs] = { 0.00, 0.34, 0.61, 0.84, 1.00 };
93  Double_t red[NRGBs] = { 0.00, 0.00, 0.87, 1.00, 0.51 };
94  Double_t green[NRGBs] = { 0.00, 0.81, 1.00, 0.20, 0.00 };
95  Double_t blue[NRGBs] = { 0.51, 1.00, 0.12, 0.00, 0.00 };
96  TColor::CreateGradientColorTable(NRGBs, stops, red, green, blue, NCont);
97  gStyle->SetNumberContours(NCont);
98  }
99  else if (T2KstyleIndex>1) {
100  if (T2KstyleIndex>4){std::cout << "DrawingTools. Not existing style !!!!" << std::endl;}
101  // Official T2K style as described in http://www.t2k.org/comm/pubboard/style/index_html
102  TString localStyleName = "T2K";
103  // -- WhichStyle --
104  // 1 = presentation large fonts
105  // 2 = presentation small fonts
106  // 3 = publication/paper
107  Int_t localWhichStyle = T2KstyleIndex-1;
108 
109  TStyle* t2kstyle = SetT2KStyle(localWhichStyle, localStyleName);
110  gROOT->SetStyle(t2kstyle->GetName());
111  }
112 
113  // Set the height reserved for each entry in the legend (in NDC coordinates)
114  SetLegendEntryHeight(0.05);
115 
116  // The initial legend height should be 0, since it is increased when adding an entry
117  SetLegendSize(0.3,0);
118 
119  // Fix legend size for the small legend
120  SetSmallLegendSize(0.15,0.1);
121 
122  // By default legend on the top-right
123  SetLegendPos("tr");
124 
125  // default position for Stats box
126  _statPos[0] = 1 - gStyle->GetPadRightMargin();
127  _statPos[1] = 1.04 - gStyle->GetPadTopMargin();
128  SetStatPos(_statPos[0],_statPos[1]);
129 
130  // Only print integral by default
131  _stat_option = 1000000;
132 
133  // Default stack fill
134  _stack_fill_style = 3001;
135  _different_fill_styles = false;
136  _marker_style = 20;
137  _marker_size = 1.;
138  _cut_line_col = 2;
139  _cut_line_width = 3;
140 
141  // No title
142  _titleX="";
143  _titleY="";
144  _title="";
145 
146  _data_color = kBlack;
147  _allmc_color = kBlack;
148  _data_label = "Data";
149  _allmc_label = "MC all";
150  _allmcstat_label = "MC all (stat)";
151  _allmcsyst_label = "MC all (syst)";
152 
153  // The default range is 0 -> auto.
154  _minY = 0;
155  _maxY = 0;
156 
157  // Default to non-log plots.
158  _logY = false;
159  _logZ = false;
160 
161  // The default fill style.
162  _fill_style = 0;
163  _line_width = 1;
164  _line_color = 1;
165  _fill_color = 2;
166  _mcerror_color = 7;
167  _mcstaterror_color = 6;
168 
169  // The default maximum in the vertical axes is 0 (it means no max value);
170  _maxY = 0;
171 
172  // The default relative maximum in the vertical axes is 1.1 (10%)
173  _relativeMaxY = 1.1;
174 
175  // No superimposition
176  _same_level=0;
177  _unique = 0;
178 
179  // no legend
180  _drawleg=false;
181 
182  // Set the default method for computing efficiencies
184 
185  // switch on 2p2h type for reaction histos by default
186  _draw_2p2h = true;
187 
188  // define the auto colors when superimposing histograms
189  for (int i=0;i<NMAXAUTOCOLORS;i++) {
190  if (i<NAUTOCOLORS){
191  _auto_colors[i] = auto_colors[i];
192  _auto_markers[i] = auto_markers[i];
193  }
194  else{
195  _auto_colors[i] = _line_color;
196  _auto_markers[i] = _marker_style;
197  }
198  }
199 
200  _pdfcanvas = NULL;
201  _bodypad = NULL;
202  _headpad = NULL;
203 
205 }
206 
207 //********************************************************************
209 //********************************************************************
210 
211  for (unsigned int i=0;i<_saved_histos.size();i++)
212  delete _saved_histos[i];
213 
214  _saved_histos.clear();
215 
216 
217  for (unsigned int i=0;i<_saved_histos2D.size();i++)
218  delete _saved_histos2D[i];
219 
220  _saved_histos2D.clear();
221 
222 
223  for (unsigned int i=0;i<_saved_graphs.size();i++)
224  delete _saved_graphs[i];
225 
226  _saved_graphs.clear();
227 
228 
229  for (unsigned int i=0;i<_saved_histoStacks.size();i++)
230  delete _saved_histoStacks[i];
231 
232  _saved_histoStacks.clear();
233 
234  for (unsigned int i=0;i<_cut_lines.size();i++)
235  delete _cut_lines[i];
236 
237  _cut_lines.clear();
238 
239 
240  for (unsigned int i=0;i<_legends.size();i++)
241  delete _legends[i];
242 
243  _legends.clear();
244 
245 }
246 
247 //********************************************************************
248 void DrawingToolsBase::ReadConfig(const std::string& file) {
249 //********************************************************************
250 
251  _config_file = file;
252 
253  ReadCategories(file);
254  ReadSelections(file);
255  ReadDocStrings(file);
256  ReadCorrections(file);
257  ReadSystematics(file);
258  ReadConfigurations(file);
259  ReadOther(file);
260  ND::versioning().ReadVersions(file);
261 
262  _configTree_tools.Initialize(file);
263 
264 }
265 
266 //*********************************************************
267 void DrawingToolsBase::SetLegendParam(double a, double b, double c, double d){
268 //*********************************************************
269 
270  // a = x min (in percentage, from 0 to 1)
271  // b = y min
272  // c = x max
273  // d = y max
274 
275  _legendParam[0]=a;
276  _legendParam[1]=b;
277  _legendParam[2]=c;
278  _legendParam[3]=d;
279 }
280 
281 //*********************************************************
282 void DrawingToolsBase::SetLegendPos(double posX, double posY){
283 //*********************************************************
284 
285  _legendPosS = "";
286  if (posX != -999) _legendPos[0] = posX;
287  if (posY != -999) _legendPos[1] = posY;
288  SetLegendParam(_legendPos[0],_legendPos[1],_legendPos[0]+_legendSize[0], _legendPos[1]+_legendSize[1]);
289 }
290 
291 //*********************************************************
292 void DrawingToolsBase::SetLegendPos(std::string pos){
293 //*********************************************************
294 
295  if (pos.find("r") != std::string::npos)
296  SetLegendPos(1-gStyle->GetPadRightMargin()-_legendSize[0],_legendPos[1]);
297  else if (pos.find("l") != std::string::npos)
298  SetLegendPos(gStyle->GetPadLeftMargin() + 0.02,_legendPos[1]);
299  else if (pos.find("c") != std::string::npos)
300  SetLegendPos((1-gStyle->GetPadRightMargin()+gStyle->GetPadLeftMargin()-_legendSize[0])/2.,_legendPos[1]);
301 
302  if (pos.find("t") != std::string::npos)
303  SetLegendPos(_legendPos[0],(1-gStyle->GetPadTopMargin()-_legendSize[1]));
304  else if (pos.find("b") != std::string::npos)
305  SetLegendPos(_legendPos[0],gStyle->GetPadBottomMargin()+0.02);
306 
307  // a standard position has been set
308  _legendPosS = pos;
309 }
310 
311 //*********************************************************
312 void DrawingToolsBase::SetLegendSize(double w, double h){
313 //*********************************************************
314 
315  if (w != -999) _legendSize[0] = w;
316  if (h != -999) _legendSize[1] = h;
317 
318  if (_legendPosS!="")
319  SetLegendPos(_legendPosS);
320  else
321  SetLegendParam(_legendPos[0],_legendPos[1],_legendPos[0]+_legendSize[0], _legendPos[1]+_legendSize[1]);
322 }
323 
324 //*********************************************************
325 void DrawingToolsBase::SetStatPos(double x, double y){
326 //*********************************************************
327  if (x != -999) _statPos[0]=x;
328  if (y != -999) _statPos[1]=y;
329  gStyle->SetStatX(_statPos[0]);
330  gStyle->SetStatY(_statPos[1]);
331 }
332 
333 //*********************************************************
334 void DrawingToolsBase::SetEffDivideParams(const std::string& params) {
335 //*********************************************************
336  if(params.find_first_not_of(" ") == std::string::npos){
337  std::cout << " DrawingToolsBase::SetEffDivideParams() no options provided --> setting default " << std::endl;
339  return;
340  }
341  _eff_params = params;
342 }
343 
344 //*********************************************************
346 //*********************************************************
347  // default params for efficiency calculation (TGraphAsymmErrors::Divide)
348  // we want the efficiency estimation to be by default equal passed/total and work for events/histograms with weights as well
349  // so use bayesian intervals with beta params (prior): alpha = 1, beta = 1, this gives a flat prior
350  // confidence level is set to one sigma
351  _eff_params = "cl=0.683 b(1,1) mode";
352 }
353 
354 //*********************************************************
355 TH1* DrawingToolsBase::Draw(TTree* tree, const std::string& var, int nx, double xmin, double xmax, const std::string& categ,
356  const std::string& cut, const std::string& root_opt, const std::string& opt, double norm, bool scale_errors){
357 //*********************************************************
358 
359  // Draw 1D histogram for a given set of cuts and uniform binning
360  double xbins[NMAXBINS];
361  return Draw(tree, var, nx, GetVariableBins(nx,xmin,xmax,xbins), categ, cut, root_opt, opt, norm, scale_errors);
362 }
363 
364 //*********************************************************
365 TH1* DrawingToolsBase::Draw(TTree* tree, const std::string& var, int nx, double* xbins, const std::string& categ,
366  const std::string& cut, const std::string& root_opt, const std::string& opt, double norm, bool scale_errors){
367 //*********************************************************
368 
369  // Draw 1D histogram for a given set of cuts and variable binning
370  int ny=0;
371  double* ybins=NULL;
372  return Draw(tree,var,nx,xbins,ny,ybins,categ,cut, root_opt, opt,norm,scale_errors);
373 }
374 
375 //*********************************************************
376 TH1* DrawingToolsBase::Draw(TTree* tree, const std::string& var, int nx, double xmin, double xmax, int ny, double ymin, double ymax,
377  const std::string& categ, const std::string& cut, const std::string& root_opt, const std::string& opt, double norm,bool scale_errors){
378 //*********************************************************
379 
380  // Draw 2D histogram for a given set of cuts and uniform binning
381  double xbins[NMAXBINS];
382  double ybins[NMAXBINS];
383  return Draw(tree, var, nx, GetVariableBins(nx,xmin,xmax,xbins), ny, GetVariableBins(ny,ymin,ymax,ybins), categ, cut, root_opt, opt, norm, scale_errors);
384 }
385 
386 //*********************************************************
387 void DrawingToolsBase::Draw(TTree* tree, const std::string& var, int nx, double xmin, double xmax, int ny, double ymin, double ymax,
388  const std::string& idVar, std::vector<int> idSel, std::vector<std::string> idName, std::vector<int> idColor,
389  const std::string& cut, const std::string& root_opt, const std::string& opt, double norm, bool scale_errors){
390 //*********************************************************
391  double xbins[NMAXBINS];
392  double ybins[NMAXBINS];
393  Draw(tree, var, nx, GetVariableBins(nx,xmin,xmax,xbins), ny, GetVariableBins(ny,ymin,ymax,ybins), idVar,idSel,idName,idColor,cut,root_opt,opt,norm,scale_errors);
394 }
395 
396 //*********************************************************
397 void DrawingToolsBase::Project(HistoStack* hs1, HistoStack* hs2, TTree* tree1, TTree* tree2, const std::string& var, int nx, double* xbins, int ny, double* ybins, const std::string& categ,
398  const std::string& cut, const std::string& root_opt, const std::string& opt, double norm2, bool scale_errors){
399 //*********************************************************
400 
401  ProjectNew(hs1,hs2,tree1,tree2,var,nx,xbins,ny,ybins,categ,cut,cut,root_opt,opt,norm2,scale_errors);
402 }
403 
404 //*********************************************************
405 void DrawingToolsBase::ProjectNew(HistoStack* hs1, HistoStack* hs2, TTree* tree1, TTree* tree2, const std::string& var, int nx, double* xbins, int ny, double* ybins, const std::string& categ,
406  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt, double norm2, bool scale_errors){
407 //*********************************************************
408 
409  double norm1=1;
410 
411  std::string uopt = drawUtils::ToUpper(opt);
412 
413  // Project both trees (first sample with no systematics)
414  // Project(hs1, "sample1", tree1,var,nx,xbins,ny,ybins,"all",cut1,root_opt,opt+" NOSYS NOAREA",norm1,scale_errors);
415  Project(hs1, "sample1", tree1,var,nx,xbins,ny,ybins,"all",cut1,root_opt,opt+" NOAREA",norm1,scale_errors);
416  Project(hs2, "sample2", tree2,var,nx,xbins,ny,ybins,categ,cut2,root_opt,opt+" NOAREA",norm2,scale_errors);
417 
418  if(drawUtils::CheckOption(uopt,"AREA")){
419  hs1->NormalizeByArea(uopt);
420  hs2->NormalizeByArea(uopt,hs1->GetTotal1D()->GetSumOfWeights());
421  }
422 }
423 
424 //*********************************************************
425 void DrawingToolsBase::Project(HistoStack* hs, const std::string& sample_name, TTree* tree, const std::string& var, int nx, double* xbins, int ny, double* ybins, const std::string& categ,
426  const std::string& cut, const std::string& root_opt, const std::string& opt, double norm, bool scale_errors){
427 //*********************************************************
428 
429  // Project 1D (ny=0) or 2D histogram for a given set of cuts and variable binning
430 
431  // Read the categories from the config tree
432  ReadCategories(_config_file);
433 
434  // Check that the category exists and dump category info
435  // (don't dump for each Experiment class samples)
436  if (! drawUtils::CheckInternalOption(opt,"EXP"))
437  if ( ! HasCategory(categ)) return;
438 
439  std::string uopt = drawUtils::ToUpper(opt);
440  std::string uroot_opt = drawUtils::ToUpper(root_opt);
441 
442  //-------- Project the total ------------------------------------------
443  if (ny==0){
444  TH1_h* hsyst = NULL;
445  TH1_h* hall = GetHisto(hs, tree, GetUniqueName(sample_name+"_all"),var,nx,xbins,cut,root_opt,uopt,hsyst,norm,scale_errors);
446  hs->AddTotal(hall,hsyst);
447  _saved_histos.pop_back();
448  delete hall;
449  }
450  else{
451  TH2_h* hall = GetHisto(tree, GetUniqueName(sample_name+"_all"),var,nx,xbins,ny,ybins,cut, root_opt, uopt,norm,scale_errors);
453  hs->AddTotal(hall);
454  _saved_histos.pop_back();
455  delete hall;
456  }
457 
458  //-------- Project the track categories -----------------------
459 
460  if (categ!="all"){
461 
462  std::string categ2 = categ;
463  std::string categ_withoutPur = categ;
464 
465  // Print purities when requested, and create categories with % on the name
466  if (drawUtils::CheckOption(uopt,"PUR")) {
467 
468  // if Experiment class, categories might already be "_withPurities"
469  if (drawUtils::CheckInternalOption(uopt,"EXP")) {
470  size_t pos = categ.find("_withPurities");
471  if (pos != std::string::npos) categ_withoutPur = categ.substr(0,pos);
472  else categ_withoutPur = categ;
473 
474  // otherwise create them
475  } else {
476  std::string cut_range = AddRangeCut(var,nx,xbins,ny,ybins,cut,uopt);
477  PrintPurities(tree, categ, cut_range);
478  categ2 += "_withPurities";
479  }
480 
481  } // end if PUR
482 
483  std::vector<TrackTypeDefinition>::iterator it;
484  int i=0;
485  for (it=cat().GetCategoryTypes(categ2).begin();it!=cat().GetCategoryTypes(categ2).end();it++, i++){
486  std::string type = it->_name;
487  std::string code = drawUtils::GetString(it->_code);
488  int color = it->_color;
489 
490  if(!_draw_2p2h && type=="2p2h") continue; // Ignore 2P2H when requested
491 
492  std::string cut2 = categ_withoutPur + "==" + code;
493 
494  if (cut!="") cut2 = cut + " && " + cut2;
495 
496  if (ny==0){
497  TH1_h* ht1 = GetHisto(hs, tree,GetUniqueName(sample_name+"_"+type),var,nx,xbins,cut2, root_opt,uopt+" CAT",norm,scale_errors);
498  if( drawUtils::CheckOption(uopt,"IGNOREEMPTY") && ht1->Integral() == 0.) continue; // Ignore empty categories in the legend
499  if(!drawUtils::CheckOption(uopt,"SHOWSAND") && ht1->Integral() == 0. && type.find(NAMESAND) !=std::string::npos) continue; // Ignore sand mu when requested
500  if(!drawUtils::CheckOption(uopt,"SHOWNOTRUTH") && ht1->Integral() == 0. && type.find(NAMENOTRUTH)!=std::string::npos) continue; // Ignore no truth when requested
501 
502  //drawUtils::NormalizeVariableBinning(ht1,2,uopt);
503  if (hs->GetCurrentSystGroup()=="default")
504  hs->Add(ht1,color,_line_width,color,GetFillStyle(i),type.c_str());
505  _saved_histos.pop_back();
506  delete ht1;
507  }
508  else{
509  TH2_h* ht2 = GetHisto(tree,GetUniqueName(sample_name+"_"+type),var,nx,xbins,ny,ybins,cut2,root_opt,uopt+" CAT",norm,scale_errors);
511  if (uroot_opt.find("BOX") != std::string::npos)
512  hs->Add(ht2,0,color,type.c_str());
513  else
514  hs->Add(ht2,color,color,type.c_str());
515  _saved_histos.pop_back();
516  delete ht2;
517  }
518  }
519  }
520 
521  if(drawUtils::CheckOption(uopt,"AREA"))
522  hs->NormalizeByArea(uopt);
523 }
524 
525 //*********************************************************
526 TH1* DrawingToolsBase::Draw(TTree* tree, const std::string& var, int nx, double* xbins, int ny, double* ybins, const std::string& categ,
527  const std::string& cut, const std::string& root_opt, const std::string& opt, double norm2, bool scale_errors){
528 //*********************************************************
529 
530  std::string uopt = drawUtils::ToUpper(opt);
531 
532  // Check that all user options are valid
533  if (!drawUtils::ContainValidOptions(uopt)) return NULL;
534 
535 
536  // Create the empty HistoStack
537  HistoStack* hs = new HistoStack(_title,_titleX,_titleY);
538  _saved_histoStacks.push_back(hs);
539 
540  // std::string slevel = GetSameLevel(root_opt);
541 
542  // Project the trees
543  Project(hs, "", tree,var,nx,xbins,ny,ybins,categ,cut,root_opt,opt,norm2,scale_errors);
544 
545  //Draw the HistoStack
546  DrawHistoStack(hs,categ,root_opt, uopt);
547 
548  if (ny==0)
549  return hs->GetTotal1D();
550  else
551  return hs->GetTotal2D();
552 
553 }
554 
555 //*********************************************************
556 void DrawingToolsBase::Project(HistoStack* hs, TTree* tree, const std::string& var, int nx, double* xbins, int ny, double* ybins,
557  const std::string& idVar, std::vector<int> idSel, std::vector<std::string> idName, std::vector<int> idColor,
558  const std::string& cut, const std::string& root_opt, const std::string& opt, double norm, bool scale_errors) {
559 //*********************************************************
560  //-------- Draw the total ------------------------------------------
561  // std::string slevel = GetSameLevel(root_opt);
562  std::string uopt = drawUtils::ToUpper(opt);
563  std::string uroot_opt = drawUtils::ToUpper(root_opt);
564 
565  if (ny == 0) {
566  TH1_h* hall = GetHisto(tree, "all", var, nx, xbins, cut, root_opt, uopt, norm, scale_errors);
568  hs->SetTotal(hall);
569  } else {
570  TH2_h* hall = GetHisto(tree, "all", var, nx, xbins, ny, ybins, cut, root_opt, uopt, norm, scale_errors);
571  hs->SetTotal(hall);
572  }
573 
574  //-------- Draw the track categories -----------------------
575  for (unsigned int i = 0; i < idSel.size(); i++) {
576  std::string type = idName[i];
577  std::stringstream ss;
578  ss << idSel[i];
579  int color = idColor[i];
580 
581  if(!_draw_2p2h && type=="2p2h") continue; // Ignore 2P2H when requested
582 
583  std::string cut2 = idVar + "==" + ss.str();
584  if (cut != "")
585  cut2 = cut + " && " + cut2;
586 
587  if (ny == 0) {
588  TH1_h* ht1 = GetHisto(tree, type, var, nx, xbins, cut2, root_opt, uopt + " CAT", norm, scale_errors);
589  if( drawUtils::CheckOption(uopt,"IGNOREEMPTY") && ht1->Integral() == 0.) continue; // Ignore empty categories in the legend
590  if(!drawUtils::CheckOption(uopt,"SHOWSAND") && ht1->Integral() == 0. && type==NAMESAND ) continue; // Ignore sand mu when requested
591  if(!drawUtils::CheckOption(uopt,"SHOWNOTRUTH") && ht1->Integral() == 0. && type==NAMENOTRUTH ) continue; // Ignore no truth when requested
592 
593  ht1->SetFillStyle(GetFillStyle(i));
595  hs->Add(ht1, color, _line_width, color, GetFillStyle(i), type);
596  if (_drawleg && !drawUtils::CheckOption(uopt,"NOLEG"))
597  drawUtils::AddLegendEntry(_legends.back(), ht1, type, "f");
598  } else {
599  TH2_h* ht2 = GetHisto(tree, type, var, nx, xbins, ny, ybins, cut2, root_opt, uopt + " CAT", norm, scale_errors);
601  if (uroot_opt.find("BOX") != std::string::npos)
602  hs->Add(ht2, 0, color);
603  else
604  hs->Add(ht2, color, color);
605  if (_drawleg && !drawUtils::CheckOption(uopt,"NOLEG"))
606  drawUtils::AddLegendEntry(_legends.back(), ht2, type, "f");
607  }
608  }
609 }
610 
611 //*********************************************************
612 void DrawingToolsBase::Draw(TTree* tree, const std::string& var, int nx, double* xbins, int ny, double* ybins,
613  const std::string& idVar, std::vector<int> idSel, std::vector<std::string> idName, std::vector<int> idColor,
614  const std::string& cut, const std::string& root_opt, const std::string& opt, double norm2, bool scale_errors){
615 //*********************************************************
616 
617  // Draw 1D (ny=0) or 2D histogram for a given set of cuts and variable binning
618 
619  // std::string slevel = GetSameLevel(root_opt);
620  std::string uopt = drawUtils::ToUpper(opt);
621 
622  // Check that all user options are valid
623  if (!drawUtils::ContainValidOptions(uopt)) return;
624 
625 
626  std::string uroot_opt = drawUtils::ToUpper(root_opt);
627 
628  // Create the legend
629  if (!drawUtils::CheckOption(uopt,"NOLEG"))
630  CreateLegend();
631 
632  HistoStack* hs = new HistoStack(_title,_titleX,_titleY);
633  _saved_histoStacks.push_back(hs);
634 
635  Project(hs, tree, var, nx, xbins, ny, ybins, idVar, idSel, idName, idColor, cut, root_opt, opt, norm2, scale_errors);
636 
637  //Draw the HistoStack
638  DrawHistoStack(hs,"",root_opt, uopt,"",2);
639 
640  // Draw the legend
641  if (!drawUtils::CheckOption(uopt,"NOLEG"))
642  _legends.back()->Draw();
643 
644  if (!drawUtils::CheckOption(uopt,"NODRAW"))
645  gPad->Update();
646 }
647 
648 
649 //*********************************************************
650 void DrawingToolsBase::Draw(TTree* tree_mc, TTree* tree_data, const std::string& var, int nx, double* xbins, int ny, double* ybins,
651  const std::string& idVar, std::vector<int> idSel, std::vector<std::string> idName, std::vector<int> idColor,
652  const std::string& cut, const std::string& root_opt, const std::string& opt, double norm, bool scale_errors){
653 //*********************************************************
654 
655  // Draw 1D (ny=0) or 2D histogram for a given set of cuts and variable binning
656 
657  // std::string slevel = GetSameLevel(root_opt);
658  std::string uopt = drawUtils::ToUpper(opt);
659  std::string uroot_opt = drawUtils::ToUpper(root_opt);
660 
661  TVirtualPad* curPad = gPad;
662 
663  // Check that all user options are valid
664  if (!drawUtils::ContainValidOptions(uopt)) return;
665 
666  if(ny==0 && drawUtils::CheckOption(uopt,"RATIO")){
667  curPad->cd();
668  gPad->SetLogy(0);
669  gPad->SetBottomMargin(0);
670  if(!_MainPad) _MainPad = new TPad("MainPad","MainPad",
671  curPad->GetAbsXlowNDC(),
672  curPad->GetAbsYlowNDC()+(curPad->GetAbsHNDC()*0.3),
673  curPad->GetAbsXlowNDC()+curPad->GetAbsWNDC(),
674  curPad->GetAbsYlowNDC()+curPad->GetAbsHNDC());
675  _MainPad->SetLogy(_logY);
676  _MainPad->SetBottomMargin(0);
677  gStyle->SetOptStat(_stat_option);
678 
679  _MainPad->Draw();
680  _MainPad->cd();
681  }
682 
683 
684  // Normalize to a given area
685  double norm_data = 1.;
686  if(drawUtils::CheckOption(uopt,"AREA")) {
687  double entries_mc = GetEntries(tree_mc,cut,var,opt);
688  double entries_data = GetEntries(tree_data,cut,var,opt);
689 
690  double area = entries_data;
691  if (drawUtils::CheckOption(uopt,"AREA100")) area = 100.;
692  else if(drawUtils::CheckOption(uopt,"AREA1")) area = 1.;
693 
694  if(entries_mc > 0.) norm = area/entries_mc; // norm for MC
695  if(entries_data > 0.) norm_data = area/entries_data; // norm for data
696  scale_errors = true;
697  }
698 
699  // Create the legend
700  if (!drawUtils::CheckOption(uopt,"NOLEG"))
701  CreateLegend();
702 
703  //
704  //data
705  //
706 
707  TH1_h* hdata = GetHisto(tree_data,"data",var,nx,xbins,cut, root_opt, uopt,norm_data,scale_errors);
709 
710  std::string leg = "data";
711 
712  if (_drawleg && drawUtils::CheckOption(uopt,"NOLEG"))
713  drawUtils::AddLegendEntry(_legends.back(), hdata, leg,"LE1P");
714 
715 
716  //
717  // mc
718  //
719 
720  HistoStack* hs = new HistoStack(_title,_titleX,_titleY);
721  _saved_histoStacks.push_back(hs);
722 
723 
724 
725  //-------- Draw the total ------------------------------------------
726 
727  if (ny==0){
728 
729  TH1_h* hall = GetHisto(tree_mc, "mcall",var,nx,xbins,cut, root_opt, uopt,norm,scale_errors);
731 
732  hs->SetTotal(hall);
733  }
734  else{
735  TH2_h* hall = GetHisto(tree_mc,"mcall",var,nx,xbins,ny,ybins,cut, root_opt, uopt,norm,scale_errors);
736  hs->SetTotal(hall);
737  }
738 
739  //-------- Draw the track categories -----------------------
740  for (unsigned int i = 0; i < idSel.size();i++ ) {
741  std::string type = idName[i];
742  std::stringstream ss;
743  ss << idSel[i];
744  int color = idColor[i];
745 
746  if(!_draw_2p2h && type=="2p2h") continue; // Ignore 2P2H when requested
747 
748  std::string cut2 = idVar+"=="+ss.str();
749  if (cut!="") cut2 = cut+" && "+cut2;
750 
751  if (ny==0){
752 
753  TH1_h* ht1 = GetHisto(tree_mc,type,var,nx,xbins,cut2, root_opt,uopt+" CAT",norm,scale_errors);
754  if( drawUtils::CheckOption(uopt,"IGNOREEMPTY") && ht1->Integral() == 0.) continue; // Ignore empty categories in the legend
755  if(!drawUtils::CheckOption(uopt,"SHOWSAND") && ht1->Integral() == 0. && type==NAMESAND ) continue; // Ignore sand mu when requested
756  if(!drawUtils::CheckOption(uopt,"SHOWNOTRUTH") && ht1->Integral() == 0. && type==NAMENOTRUTH) continue; // Ignore no truth when requested
757 
758  ht1->SetFillStyle(GetFillStyle(i));
760 
761  hs->Add(ht1,color,1,color,GetFillStyle(i),type);
762 
763  if (_drawleg && !drawUtils::CheckOption(uopt,"NOLEG")) {
764  drawUtils::AddLegendEntry(_legends.back(), ht1, type, "f");
765  }
766 
767  }
768  else{
769  TH2_h* ht2 = GetHisto(tree_mc,type,var,nx,xbins,ny,ybins,cut2,root_opt,uopt+" CAT",norm,scale_errors);
771 
772  if (uroot_opt.find("BOX") != std::string::npos)
773  hs->Add(ht2,0,color);
774  else
775  hs->Add(ht2,color,color);
776  if (_drawleg && !drawUtils::CheckOption(uopt,"NOLEG"))
777  drawUtils::AddLegendEntry(_legends.back(), ht2, type, "f");
778  }
779  }
780 
781  //Draw the HistoStack
782 
783  if(ny==0 && ( hdata->GetMaximum() + sqrt(hdata->GetBinError(hdata->GetMaximumBin()))) > hs->GetTotal1D()->GetMaximum()) { // draw "higher" histogram firstly
784  DrawHisto(hdata, 1, 1, 0, 0, root_opt+"error", "ST NOSTAT ISDATA", "", 2);
785  DrawHistoStack(hs,"",root_opt+" same", uopt,"",2);
786  DrawHisto(hdata, 1, 1, 0, 0, root_opt+" same error", "ST NOSTAT ISDATA", "", 2);
787  }
788  else {
789  DrawHistoStack(hs,"",root_opt, uopt,"",2);
790  DrawHisto(hdata, 1, 1, 0, 0, root_opt+" same error", "ST NOSTAT ISDATA", "", 2);
791  }
792 
793  // Draw the legend
794  if (!drawUtils::CheckOption(uopt,"NOLEG"))
795  _legends.back()->Draw();
796 
797  if (drawUtils::CheckOption(uopt,"NODRAW"))
798  gPad->Update();
799 
800  if(ny == 0 && drawUtils::CheckOption(uopt,"RATIO")){
801  curPad->cd();
802  if(!_RatioPad) _RatioPad = new TPad("RatioPad","RatioPad",
803  curPad->GetAbsXlowNDC(),
804  curPad->GetAbsYlowNDC(),
805  curPad->GetAbsXlowNDC()+curPad->GetAbsWNDC(),
806  curPad->GetAbsYlowNDC()+(curPad->GetAbsHNDC()*0.3));
807  _RatioPad->Draw();
808  _RatioPad->cd();
809  TH1F* ratio = (TH1F*)hdata->Clone();
810  ratio->Divide(hs->GetTotal1D());
811 
812  ratio->SetStats(0);
813  ratio->GetYaxis()->SetNdivisions(010, true);
814  ratio->GetXaxis()->SetLabelSize(ratio->GetXaxis()->GetLabelSize()/0.3);
815  ratio->GetYaxis()->SetLabelSize(ratio->GetYaxis()->GetLabelSize()/0.3);
816  ratio->GetYaxis()->SetTitle("Ratio");
817  ratio->GetXaxis()->SetTitleSize(ratio->GetXaxis()->GetTitleSize()/0.3);
818  ratio->GetYaxis()->SetTitleSize(ratio->GetYaxis()->GetTitleSize()/0.3);
819  DrawHisto(ratio, _line_color, _line_width, 0, 0, root_opt+" same error", "ST NOSTAT ISDATA DONTADDLEGENTRY", "", 2);
820  ratio->SetMaximum(_relativeMaxY*ratio->GetBinContent(ratio->GetMaximumBin()));
821  ratio->SetMinimum( ratio->GetBinContent(ratio->GetMinimumBin())/_relativeMaxY);
822  _RatioPad->SetLogy(0);
823  _RatioPad->SetTopMargin(0);
824  _RatioPad->SetBottomMargin(0.3);
825  _RatioPad->SetGridx();
826  _RatioPad->SetGridy();
827  _RatioPad->Update();
828  curPad->cd();
829 
830  }
831 
832  gStyle->SetOptStat(_stat_option);
833 
834  if(_RatioPad){_RatioPad->Update();_RatioPad->Draw();}
835  if(_MainPad) {_MainPad ->Update();_MainPad ->Draw();}
836  gPad->Update();
837  gPad->Draw();
838 
839 }
840 
841 
842 //*********************************************************
843 void DrawingToolsBase::Draw(TTree* tree_mc, TTree* tree_data, const std::string& var, int nx, double xmin, double xmax, int ny, double ymin, double ymax,
844  const std::string& idVar, std::vector<int> idSel, std::vector<std::string> idName, std::vector<int> idColor,
845  const std::string& cut, const std::string& root_opt, const std::string& opt, double norm, bool scale_errors){
846 //*********************************************************
847 
848  double xbins[NMAXBINS];
849  double ybins[NMAXBINS];
850 
851  Draw(tree_mc, tree_data, var, nx, GetVariableBins(nx,xmin,xmax,xbins), ny, GetVariableBins(ny,ymin,ymax,ybins), idVar,idSel,idName,idColor,cut,root_opt,opt,norm,scale_errors);
852 }
853 
854 //*********************************************************
855 double DrawingToolsBase::GetEff(TTree* tree, const std::string& var, double xmin, double xmax,
856  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt) {
857 //*********************************************************
858  double errhigh = 0.;
859  double errlow = 0.;
860  return GetEff(tree, var, xmin, xmax, errlow, errhigh, cut1, cut2, root_opt, opt);
861 }
862 
863 //*********************************************************
864 double DrawingToolsBase::GetEff(TTree* tree, const std::string& var, double xmin, double xmax, double& errlow, double& errhigh,
865  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt) {
866 //*********************************************************
867 
868  errlow = 0;
869  errhigh = 0;
870  // std::string slevel = GetSameLevel(root_opt);
871  int nbins = 1;
872  double xbins[2] = {xmin, xmax};
873 
874  // Histogram for cut1+cut2 (numerator)
875  TH1_h* h1 = GetHisto(tree, "eff1",var,nbins,xbins,(cut1+" && "+cut2), root_opt, opt,1);
876  h1->Sumw2();
877  // Histogram for cut2 (denominator)
878  TH1_h* h2 = GetHisto(tree, "eff2",var,nbins,xbins,cut2, root_opt, opt,1);
879  h2->Sumw2();
880 
881  // compute the efficiency
882  TGraphAsymmErrors* eff = new TGraphAsymmErrors(h1);
883  _saved_graphs.push_back(eff);
884  eff->Divide(h1, h2, _eff_params.c_str()); //the options are explicitely provided by SetEffDivideParams(const std::string&), root_opt not used to avoid possible confusions
885 
886  if (eff->GetN() != 1) {
887  std::cout << "Error computing efficiency" << std::endl;
888  return 0;
889  }
890 
891  errlow = eff->GetEYlow()[0];
892  errhigh = eff->GetEYhigh()[0];
893 
894  return eff->GetY()[0];
895 }
896 
897 
898 //*********************************************************
899 void DrawingToolsBase::DrawEff(TTree* tree, const std::string& var, int nx, double xmin, double xmax,
900  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt, const std::string& leg){
901 //*********************************************************
902 
903  // Draw 1D efficiency, meaning the ratio of two histograms in which the numerator (cut1+cut2) is a subset of the denominator (cut2).
904  double xbins[NMAXBINS];
905  DrawEff(tree, var, nx, GetVariableBins(nx,xmin,xmax,xbins), cut1, cut2, root_opt, opt, leg);
906 }
907 
908 //*********************************************************
909 void DrawingToolsBase::DrawEff(TTree* tree, const std::string& var, int nx, double* xbins,
910  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt, const std::string& leg){
911 //*********************************************************
912 
913  // Draw 1D efficiency, meaning the Divide ratio of two histograms in which the numerator (cut1+cut2) is a subset of the denominator (cut2).
914  std::string uopt = drawUtils::ToUpper(opt);
915  std::string uroot_opt = drawUtils::ToUpper(root_opt);
916 
917  // Check that all user options are valid
918  if (!drawUtils::ContainValidOptions(uopt)) return;
919 
920  // Create empty HistoStacks
921  HistoStack* hs1 = new HistoStack(_title,_titleX,_titleY);
922  HistoStack* hs2 = new HistoStack(_title,_titleX,_titleY);
923  _saved_histoStacks.push_back(hs1);
924  _saved_histoStacks.push_back(hs2);
925 
926  // std::string slevel = GetSameLevel(root_opt);
927 
928  // Project both trees
929  Int_t ny=0;
930  double *ybins = NULL;
931  ProjectNew(hs1, hs2, tree,tree,var,nx,xbins,ny,ybins,"all",(cut1+" && "+cut2),cut2,root_opt,opt,1.,true);
932 
933  // Histogram for numerator
934  TH1_h* h1 = hs1->GetTotalStat1D();
935  TH1_h* h2 = hs2->GetTotalStat1D();
936  if (!h1) h1 = hs1->GetTotal1D();
937  if (!h2) h2 = hs2->GetTotal1D();
938 
939  h1->Sumw2();
940  h2->Sumw2();
941 
942  // compute the efficiency
943  TGraphAsymmErrors* eff = new TGraphAsymmErrors(h1);
944  _saved_graphs.push_back(eff);
945  eff->Divide(h1, h2, _eff_params.c_str()); //the options are explicitely provided by SetEffDivideParams(const std::string&), root_opt not used to avoid possible confusions
946 
947  // Put the errors into the ratio
948  FillGraphErrors(hs1, hs2, eff, uopt);
949 
950  // Draw the efficiency graph
951  DrawGraph(eff,nx,xbins,uroot_opt,uopt,leg);
952 }
953 
954 
955 //*********************************************************
956 void DrawingToolsBase::DrawDoubleEff(TTree* tree1, TTree* tree2, const std::string& var, int nx, double xmin, double xmax,
957  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt, const std::string& leg){
958 //*********************************************************
959 
960  double xbins[NMAXBINS];
961  DrawDoubleEff(tree1, tree2, var, nx, GetVariableBins(nx,xmin,xmax,xbins), cut1, cut2, root_opt, opt, leg);
962 }
963 
964 //*********************************************************
965 void DrawingToolsBase::DrawDoubleEff(TTree* tree1, TTree* tree2, const std::string& var, int nx, double* xbins,
966  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt, const std::string& leg){
967 //*********************************************************
968 
969  // Draw 1D efficiency, meaning the Divide ratio of two histograms in which the numerator (cut1+cut2) is a subset of the denominator (cut2).
970  std::string uopt = drawUtils::ToUpper(opt);
971  std::string uroot_opt = drawUtils::ToUpper(root_opt);
972 
973  // Check that all user options are valid
974  if (!drawUtils::ContainValidOptions(uopt)) return;
975 
976  // Create empty HistoStacks
977  HistoStack* hs1_num = new HistoStack(_title,_titleX,_titleY);
978  HistoStack* hs1_den = new HistoStack(_title,_titleX,_titleY);
979  HistoStack* hs2_num = new HistoStack(_title,_titleX,_titleY);
980  HistoStack* hs2_den = new HistoStack(_title,_titleX,_titleY);
981  _saved_histoStacks.push_back(hs1_num);
982  _saved_histoStacks.push_back(hs1_den);
983  _saved_histoStacks.push_back(hs2_num);
984  _saved_histoStacks.push_back(hs2_den);
985 
986  // std::string slevel = GetSameLevel(root_opt);
987 
988  // Project both trees
989  Int_t ny=0;
990  double *ybins = NULL;
991  ProjectNew(hs1_num, hs1_den, tree1,tree1,var,nx,xbins,ny,ybins,"all",(cut1+" && "+cut2),cut2,root_opt,opt,1.,true);
992  ProjectNew(hs2_num, hs2_den, tree2,tree2,var,nx,xbins,ny,ybins,"all",(cut1+" && "+cut2),cut2,root_opt,opt,1.,true);
993 
994  // Histogram for numerator
995  TH1_h* h1n = hs1_num->GetTotalStat1D();
996  TH1_h* h1d = hs1_den->GetTotalStat1D();
997 
998  // Histogram for denominator
999  TH1_h* h2n = hs2_num->GetTotalStat1D();
1000  TH1_h* h2d = hs2_den->GetTotalStat1D();
1001 
1002  if (!h1n) h1n = hs1_num->GetTotal1D();
1003  if (!h1d) h1d = hs1_den->GetTotal1D();
1004  if (!h2n) h2n = hs2_num->GetTotal1D();
1005  if (!h2d) h2d = hs2_den->GetTotal1D();
1006 
1007 
1008  h1d->Sumw2();
1009  h1n->Sumw2();
1010  h2d->Sumw2();
1011  h2n->Sumw2();
1012 
1013  // compute the efficiency for first sample
1014  TGraphAsymmErrors* eff1 = new TGraphAsymmErrors(h1d);
1015  _saved_graphs.push_back(eff1);
1016  eff1->Divide(h1n, h1d, _eff_params.c_str()); //the options are explicitely provided by SetEffDivideParams(const std::string&), root_opt not used to avoid possible confusions
1017 
1018  // compute the efficiency for second sample
1019  TGraphAsymmErrors* eff2 = new TGraphAsymmErrors(h2d);
1020  _saved_graphs.push_back(eff2);
1021  eff2->Divide(h2n, h2d, _eff_params.c_str()); //the options are explicitely provided by SetEffDivideParams(const std::string&), root_opt not used to avoid possible confusions
1022 
1023  // Put the errors into the efficiency of the first sample
1024  FillGraphErrors(hs1_num, hs1_den, eff1, uopt);
1025 
1026  // Put the errors into the efficiency of the second sample
1027  FillGraphErrors(hs2_num, hs2_den, eff2, uopt);
1028 
1029  // compute the efficiency for second sample
1030  TGraphAsymmErrors* ratio = new TGraphAsymmErrors(h2d);
1031  _saved_graphs.push_back(ratio);
1032 
1033  for (int i=0;i<nx;i++){
1034  double x1,y1,x2,y2;
1035  eff1->GetPoint(i,x1,y1);
1036  eff2->GetPoint(i,x2,y2);
1037  double e1 = eff1->GetErrorY(i);
1038  double e2l = eff2->GetErrorYlow(i);
1039  double e2h = eff2->GetErrorYhigh(i);
1040  double exl = eff2->GetErrorXlow(i);
1041  double exh = eff2->GetErrorXhigh(i);
1042 
1043  double r = y1/y2;
1044  double erl = sqrt(e1*e1/(y2*y2)+pow(y1/(y2*y2)*e2l,2));
1045  double erh = sqrt(e1*e1/(y2*y2)+pow(y1/(y2*y2)*e2h,2));
1046 
1047  ratio->SetPoint(i,x1,r);
1048  ratio->SetPointError(i,exl,exh,erl,erh);
1049  }
1050 
1051  // Draw the graph
1052  DrawGraph(ratio,nx,xbins,uroot_opt,uopt,leg,1.3);
1053 }
1054 
1055 //*********************************************************
1056 void DrawingToolsBase::DrawGraph(TGraphAsymmErrors* graph, int nbins, double* xbins,
1057  const std::string& uroot_opt, const std::string& uopt, const std::string& leg, double ymax){
1058 //*********************************************************
1059 
1060  std::string slevel = GetSameLevel(uroot_opt);
1061  if (slevel=="0" && leg!="")
1062  CreateLegend();
1063 
1064  // Dump te graph
1065  if (drawUtils::CheckOption(uopt,"DUMP"))
1066  DumpGraph(graph,nbins,uopt);
1067 
1068  // Don't draw
1069  if (drawUtils::CheckOption(uopt,"NODRAW")) return;
1070 
1071  // Histogram attributes
1072  graph->GetXaxis()->SetRangeUser(xbins[0],xbins[nbins]);
1073  graph->GetYaxis()->SetRangeUser(0,ymax);
1074  graph->GetYaxis()->SetNdivisions(520);
1075 
1076  graph->SetTitle(_title.c_str());
1077  graph->SetLineColor(_auto_colors[_same_level]);
1078  graph->SetMarkerColor(_auto_colors[_same_level]);
1079  graph->SetMarkerStyle(_auto_markers[_same_level]);
1080 
1081  // No stats box
1082  gStyle->SetOptStat(0);
1083 
1084  // Draw the efficiency histogram
1085  if (uroot_opt.find("SAME")!=std::string::npos)
1086  graph->Draw(("P"+uroot_opt).c_str());
1087  else
1088  graph->Draw(("AP"+uroot_opt).c_str());
1089 
1090  gPad->Update();
1091  graph->GetXaxis()->SetTitle(_titleX.c_str());
1092  graph->GetYaxis()->SetTitle(_titleY.c_str());
1093 
1094  // Add an entry to the legend if requested
1095  if (!drawUtils::CheckOption(uopt,"NOLEG") && leg!=""){
1096  drawUtils::AddLegendEntry(_legends.back(), graph, leg ,"LE1P");
1097  _legends.back()->Draw();
1098  }
1099 
1100  gPad->Update();
1101 }
1102 
1103 //*********************************************************
1104 void DrawingToolsBase::DumpGraph(TGraphAsymmErrors* graph, int nbins, const std::string& uopt){
1105 //*********************************************************
1106 
1107  (void)uopt;
1108 
1109  std::cout << "---------- Dumping graph -----------" << std::endl;
1110 
1111  for (int i=0;i<nbins;i++){
1112  double x,y;
1113  graph->GetPoint(i,x,y);
1114  double el = graph->GetErrorYlow(i);
1115  double eh = graph->GetErrorYhigh(i);
1116 
1117  std::cout << i << ": x = " << x << ", y = " << y << " +- " << eh << " " << el << std::endl;
1118  }
1119 }
1120 
1121 //*********************************************************
1122 void DrawingToolsBase::DumpHisto(TH1* histo, const std::string& uopt){
1123 //*********************************************************
1124 
1125  (void)uopt;
1126 
1127  std::cout << "---------- Dumping histo -----------" << std::endl;
1128 
1129  for (int i=0;i<histo->GetNbinsX();i++){
1130  double x = histo->GetBinCenter(i+1);
1131  double y = histo->GetBinContent(i+1);
1132  double e = histo->GetBinError(i+1);
1133 
1134  std::cout << i << ": x = " << x << ", y = " << y << " +- " << e << std::endl;
1135  }
1136 }
1137 
1138 
1139 //*********************************************************
1140 void DrawingToolsBase::DumpHistoInfo(TH1* histo, const std::string& uopt){
1141 //*********************************************************
1142 
1143  (void)uopt;
1144 
1145  std::cout << " --------------------------------------------------------" << std::endl;
1146  std::cout << " Statistics" << std::endl;
1147  std::cout << " entries = " << histo->GetEntries() << " (not weighted; under/overflow included) " << std::endl;
1148  std::cout << " integral = " << histo->Integral() << std::endl;
1149  std::cout << " underflow = " << histo->GetBinContent(0) << std::endl;
1150  std::cout << " overflow = " << histo->GetBinContent(histo->GetNbinsX()+1) << std::endl;
1151  std::cout << " --------------------------------------------------------" << std::endl;
1152  std::cout << std::endl;
1153 }
1154 
1155 //*********************************************************
1156 void DrawingToolsBase::DrawSignificance(TTree* tree, const std::string& var, int nx, double xmin, double xmax, const std::string& cut1, const std::string& cut2,
1157  double norm, double rel_syst, const std::string& root_opt, const std::string& opt, const std::string& leg){
1158 //*********************************************************
1159 
1160  // Draw 1D significance, defined as the number of signal events (bkg subtracted) divided by its error
1161  // In this case cut2 defines the selected events, while cut1+cut2 is a sunset (the true signal events)
1162  double xbins[NMAXBINS];
1163  DrawSignificance(tree,var, nx, GetVariableBins(nx,xmin,xmax,xbins), cut1, cut2, norm, rel_syst, root_opt, opt, leg);
1164 }
1165 
1166 //*********************************************************
1167 void DrawingToolsBase::DrawSignificance(TTree* tree, const std::string& var, int nbins, double* xbins, const std::string& cut1, const std::string& cut2,
1168  double norm, double rel_syst, const std::string& root_opt, const std::string& opt, const std::string& leg){
1169 //*********************************************************
1170 
1171  // Draw 1D significance, defined as the number of signal events (bkg subtracted) divided by its error
1172  // In this case cut2 defines the selected events, while cut1+cut2 is a sunset (the true signal events)
1173 
1174  std::string slevel = GetSameLevel(root_opt);
1175  std::string uopt = drawUtils::ToUpper(opt);
1176 
1177  // Check that all user options are valid
1178  if (!drawUtils::ContainValidOptions(uopt)) return;
1179 
1180  if (slevel=="0" && leg!="")
1181  CreateLegend();
1182 
1183  // Histogram for cut1+cut2 (numerator)
1184  TH1_h* h1 = GetHisto(tree, "sig1",var,nbins,xbins,(cut1+" && "+cut2), root_opt, uopt,norm);
1185  // Histogram for cut2 (denominator)
1186  TH1_h* h2 = GetHisto(tree, "sig2",var,nbins,xbins,cut2, root_opt, uopt,norm);
1187 
1188  // create a histo to store the significance
1189  TH1_h* sig = new TH1_h(*h1);
1190  sig->SetName(GetUniqueName("sig").c_str());
1191  _saved_histos.push_back(sig);
1192 
1193  // compute the significance
1194  for (int ibin=0;ibin<sig->GetXaxis()->GetNbins();ibin++){
1195  double total = h2->GetBinContent(ibin+1);
1196  double s=0;
1197  if (total>0){
1198  double pur = h1->GetBinContent(ibin+1)/total;
1199  s = pur/(sqrt(1/(total*norm) + pow(rel_syst*(1-pur),2)));
1200  }
1201  sig->SetBinContent(ibin+1,s);
1202  sig->SetBinError(ibin+1,0);
1203  }
1204 
1205  // Histogram attributes
1206  sig->GetXaxis()->SetTitle(_titleX.c_str());
1207  sig->GetYaxis()->SetTitle("significance");
1208  sig->SetTitle(leg.c_str());
1209 
1210  // Draw the histo
1211  DrawHisto(sig, _auto_colors[_same_level], _line_width, 1, _fill_style, root_opt, uopt+ " NOSTAT","LE1P");
1212 
1213  // Draw the legend
1214  if (!drawUtils::CheckOption(uopt,"NOLEG")&& leg!="")
1215  _legends.back()->Draw();
1216 
1217  if (!drawUtils::CheckOption(uopt,"NODRAW"))
1218  gPad->Update();
1219 }
1220 
1221 //*********************************************************
1222 void DrawingToolsBase::DrawRatio(TTree* tree, const std::string& var, int nx, double xmin, double xmax,
1223  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt, const std::string& leg){
1224 //*********************************************************
1225 
1226  // Ratio between two histograms with independent cuts
1227  double xbins[NMAXBINS];
1228  DrawRatio(tree, var, nx, GetVariableBins(nx,xmin,xmax,xbins), cut1, cut2, root_opt, opt, leg);
1229 }
1230 
1231 //*********************************************************
1232 void DrawingToolsBase::DrawRatio(TTree* tree, const std::string& var, int nx, double* xbins,
1233  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt, const std::string& leg){
1234 //*********************************************************
1235 
1236  // Ratio between two histograms with independent cuts
1237  DrawRatioTwoCuts(tree, tree, var, nx, xbins, cut1, cut2, root_opt, opt, leg, 1.);
1238 }
1239 
1240 //**************************************************
1241 void DrawingToolsBase::Draw(TTree* tree1, TTree* tree2, const std::string& var, int nx, double xmin, double xmax,
1242  const std::string& categ, const std::string& cut, const std::string& root_opt, const std::string& opt, double norm, bool scale_errors){
1243 //**************************************************
1244 
1245  // 1D comparison between two data samples with different normalisation. Uniform binning
1246  double xbins[NMAXBINS];
1247  Draw(tree1,tree2,var,nx,GetVariableBins(nx,xmin,xmax,xbins),categ,cut,root_opt,opt,norm,scale_errors);
1248 }
1249 
1250 //**************************************************
1251 void DrawingToolsBase::Draw(TTree* tree1, TTree* tree2, const std::string& var, int nx, double* xbins,
1252  const std::string& categ, const std::string& cut, const std::string& root_opt, const std::string& opt, double norm, bool scale_errors){
1253 //**************************************************
1254 
1255  // 1D comparison between two data samples with different normalisation. Variable binning
1256  int ny=0;
1257  double *ybins=NULL;
1258  Draw(tree1,tree2,var,nx,xbins,ny,ybins,categ,cut,root_opt,opt,norm,scale_errors);
1259 }
1260 
1261 //**************************************************
1262 void DrawingToolsBase::Draw(TTree* tree1, TTree* tree2, const std::string& var, int nx, double xmin, double xmax, int ny, double ymin, double ymax,
1263  const std::string& categ, const std::string& cut, const std::string& root_opt, const std::string& opt, double norm, bool scale_errors){
1264 //**************************************************
1265 
1266  // 2D comparison between two data samples with different normalisation. Uniform binning
1267  double xbins[NMAXBINS];
1268  double ybins[NMAXBINS];
1269  Draw(tree1,tree2,var,nx,GetVariableBins(nx,xmin,xmax,xbins),ny,GetVariableBins(ny,ymin,ymax,ybins),categ,cut,root_opt,opt,norm,scale_errors);
1270 }
1271 
1272 //**************************************************
1273 void DrawingToolsBase::Draw(TTree* tree1, TTree* tree2, const std::string& var, int nx, double* xbins, int ny, double* ybins,
1274  const std::string& categ, const std::string& cut, const std::string& root_opt, const std::string& opt, double norm2, bool scale_errors){
1275 //**************************************************
1276 
1277  // Draw 1D (ny=0) or 2D comparison between two data samples with different normalisation. Variable binning
1278  if (!HasCategory(categ)) return;
1279 
1280  std::string uopt = drawUtils::ToUpper(opt);
1281 
1282  // Check that all user options are valid
1283  if (!drawUtils::ContainValidOptions(uopt)) return;
1284 
1285 
1286  // Create empty HistoStacks
1287  HistoStack* hs1 = new HistoStack(_title,_titleX,_titleY);
1288  HistoStack* hs2 = new HistoStack(_title,_titleX,_titleY);
1289  _saved_histoStacks.push_back(hs1);
1290  _saved_histoStacks.push_back(hs2);
1291 
1292  // std::string slevel = GetSameLevel(root_opt);
1293 
1294  // Project both trees
1295  Project(hs1, hs2, tree1,tree2,var,nx,xbins,ny,ybins,categ,cut,root_opt,opt,norm2,scale_errors);
1296 
1297  // Draw the HistoStacks
1298  DrawHistoStacks(hs1,hs2,categ,root_opt,opt,norm2);
1299 }
1300 
1301 //**************************************************
1302 void DrawingToolsBase::DrawRatioTwoCuts(TTree* tree1, TTree* tree2, const std::string& var, int nx, double* xbins, int ny, double* ybins,
1303  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt, const std::string& leg, double norm, bool scale_errors){
1304 //**************************************************
1305 
1306  std::string uopt = drawUtils::ToUpper(opt);
1307 
1308  // Check that all user options are valid
1309  if (!drawUtils::ContainValidOptions(uopt)) return;
1310 
1311 
1312  // Create empty HistoStacks
1313  HistoStack* hs1 = new HistoStack(_title,_titleX,_titleY);
1314  HistoStack* hs2 = new HistoStack(_title,_titleX,_titleY);
1315  _saved_histoStacks.push_back(hs1);
1316  _saved_histoStacks.push_back(hs2);
1317 
1318  // Project both trees
1319  ProjectNew(hs1, hs2, tree1,tree2,var,nx,xbins,ny,ybins,"all",cut1,cut2,root_opt,opt,norm,scale_errors);
1320 
1321  // Draw the HistoStacks
1322  DrawRatioHistoStacks(hs1,hs2,root_opt,opt,norm,leg);
1323 }
1324 
1325 
1326 //**************************************************
1327 void DrawingToolsBase::DrawRatioHistoStacks(HistoStack* hs1, HistoStack* hs2,
1328  const std::string& root_opt, const std::string& opt, double norm, const std::string& leg){
1329 //**************************************************
1330 
1331  (void)norm; // norm not currently used
1332 
1333  std::string uopt = drawUtils::ToUpper(opt);
1334 
1335  // Is a 2D histo ?
1336  bool is2D = false;
1337  if (hs1){
1338  if (hs1->Is2D()) is2D=true;
1339  }
1340  else if (hs2){
1341  if (hs2->Is2D()) is2D=true;
1342  }
1343  // options for 2D histos
1344  std::string box = "";
1345  std::string error = "e";
1346  if (is2D){
1347  box =" box";
1348  error = "";
1349  }
1350  // std::string smallleg = " SMALLLEG";
1351  if (!hs2) uopt=uopt+" NOLEG";
1352 
1353  std::string slevel = GetSameLevel(root_opt);
1354 
1355  if (slevel=="0" && leg!="")
1356  CreateLegend(uopt);
1357 
1358  // Don't create the legend below
1359  uopt = uopt+ " NOCREATELEG";
1360 
1361  TH1_h* ratio = GetRatioHisto(hs1,hs2,uopt);
1362 
1363  if (ratio)
1364  DrawRatio(ratio,root_opt+box+error,uopt,leg);
1365 }
1366 
1367 
1368 //**************************************************
1369 void DrawingToolsBase::DrawRatio(TTree* tree1, TTree* tree2, const std::string& var, int nx, double xmin, double xmax,
1370  const std::string& cut, const std::string& root_opt, const std::string& opt, const std::string& leg, double norm){
1371 //**************************************************
1372 
1373  // 1D ratio between two data samples with different normalisation and same cut. Uniform binning
1374  double xbins[NMAXBINS];
1375  DrawRatioTwoCuts(tree1,tree2,var,nx,GetVariableBins(nx,xmin,xmax,xbins),cut,cut,root_opt,opt,leg,norm);
1376 }
1377 
1378 //**************************************************
1379 void DrawingToolsBase::DrawRatio(TTree* tree1, TTree* tree2, const std::string& var, int nx, double* xbins,
1380  const std::string& cut, const std::string& root_opt, const std::string& opt, const std::string& leg, double norm){
1381 //**************************************************
1382 
1383  // 1D ratio between two data samples with different normalisation and same cut. Variable binning
1384  DrawRatioTwoCuts(tree1,tree2,var,nx,xbins,cut,cut,root_opt,opt,leg,norm);
1385 }
1386 
1387 //**************************************************
1388 void DrawingToolsBase::DrawRatioTwoCuts(TTree* tree1, TTree* tree2, const std::string& var, int nx, double xmin, double xmax,
1389  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt, const std::string& leg, double norm){
1390 //**************************************************
1391 
1392  // 1D ratio between two data samples with different normalisation. Uniform binning
1393  double xbins[NMAXBINS];
1394  DrawRatioTwoCuts(tree1,tree2,var,nx,GetVariableBins(nx,xmin,xmax,xbins),cut1,cut2,root_opt,opt,leg,norm);
1395 }
1396 
1397 //**************************************************
1398 void DrawingToolsBase::DrawRatioTwoCuts(TTree* tree1, TTree* tree2, const std::string& var, int nx, double* xbins,
1399  const std::string& cut1, const std::string& cut2, const std::string& root_opt, const std::string& opt, const std::string& leg, double norm){
1400 //**************************************************
1401 
1402  int ny=0;
1403  double* ybins=NULL;
1404  DrawRatioTwoCuts(tree1,tree2,var,nx,xbins,ny,ybins,cut1,cut2,root_opt,opt,leg,norm);
1405 }
1406 
1407 //**************************************************
1408 void DrawingToolsBase::DrawRatio(TH1_h* ratio, const std::string& root_opt, const std::string& uopt, const std::string& leg){
1409 //**************************************************
1410 
1411  std::string slevel = GetSameLevel(root_opt);
1412  if (slevel=="0" && leg!="")
1413  CreateLegend();
1414 
1415  // Draw the histogram
1416  DrawHisto(ratio, _auto_colors[_same_level], _line_width, 1, _fill_style, root_opt, uopt+" NOSTAT NOVARBIN","LE1P",0);
1417 
1418  // Draw the legend
1419  if (_drawleg && !drawUtils::CheckOption(uopt,"NOLEG") && leg!="")
1420  _legends.back()->Draw();
1421 
1422  if (!drawUtils::CheckOption(uopt,"NODRAW"))
1423  gPad->Update();
1424 }
1425 
1426 //**************************************************
1427 void DrawingToolsBase::DrawEventsVSCut(TTree* tree, const std::string& cut_norm, int first_cut, int last_cut,
1428  const std::string& root_opt, const std::string& opt, const std::string& leg){
1429 //**************************************************
1430 
1431  DrawEventsVSCut(tree,0,cut_norm,first_cut,last_cut,root_opt,opt,leg);
1432 }
1433 
1434 //**************************************************
1435 void DrawingToolsBase::DrawEventsVSCut(TTree* tree, int ibranch, const std::string& cut_norm, int first_cut, int last_cut,
1436  const std::string& root_opt, const std::string& opt, const std::string& leg){
1437 //**************************************************
1438 
1439  // if selection exists
1440  if (sel().GetSelection(ibranch,true)) {
1441  int isel = ibranch;
1442  std::cout << "Drawing for selection " << isel << ", branch 0" << std::endl;
1443  return DrawEventsVSCut(tree,isel,0,cut_norm,first_cut,last_cut,root_opt,opt,leg);
1444  }
1445 
1446  DrawEventsVSCut(tree,0,ibranch,cut_norm,first_cut,last_cut,root_opt,opt,leg);
1447 }
1448 
1449 
1450 //**************************************************
1451 void DrawingToolsBase::DrawEventsVSCut(TTree* tree, int isel, int ibranch, const std::string& cut_norm, int first_cut, int last_cut,
1452  const std::string& root_opt, const std::string& opt, const std::string& leg){
1453 //**************************************************
1454 
1455  // Read the steps from the config tree
1456  // ReadSteps(_config_file);
1457 
1458  // Check if selection exists
1459  if (!sel().GetSelection(isel,true)) return;
1460 
1461  std::string slevel = GetSameLevel(root_opt);
1462  std::string uopt = drawUtils::ToUpper(opt);
1463 
1464  // Check that all user options are valid
1465  if (!drawUtils::ContainValidOptions(uopt)) return;
1466 
1467  if (slevel=="0" && leg!="")
1468  CreateLegend();
1469 
1470  if (strcmp(tree->GetName(), "truth") && !drawUtils::CheckOption(uopt,"DRAWALLCUTS")) first_cut = _minAccumLevelToSave-1;
1471  TH1_h* hall = GetEventsVSCut(tree,"events",cut_norm, isel, ibranch,first_cut, last_cut,root_opt,uopt);
1472 
1473  Int_t cut_offset = 0;
1474  // First bin corresponds to no cut
1475  if (first_cut ==-1){
1476  hall->GetXaxis()->SetBinLabel(1, "NO CUT");
1477  cut_offset = 1;
1478  }
1479 
1480  std::vector<StepBase*> cuts = sel().GetSelection(isel)->GetCutsInBranch(ibranch);
1481  // Start from second bin since first corresponds to no cut
1482  for (int i=cut_offset;i<hall->GetNbinsX();i++ ){
1483  int icut = first_cut+i;
1484  hall->GetXaxis()->SetBinLabel(i+1, cuts[icut]->Title().c_str());
1485  }
1486 
1487  // No error in X
1488  gStyle->SetErrorX(0.0001);
1489 
1490  hall->SetTitle(_title.c_str());
1491  hall->SetMarkerStyle(21);
1492 
1493  DrawHisto(hall, _auto_colors[_same_level], _line_width, _auto_colors[_same_level], _fill_style, "pl e"+root_opt, uopt+" NOSTAT NOLEG");
1494 
1495  hall->GetXaxis()->SetTitle("");
1496  hall->GetYaxis()->SetTitle("# events");
1497 
1498  // Add an entry to the legend if requested
1499  if (!drawUtils::CheckOption(uopt,"NOLEG") && leg!=""){
1500  drawUtils::AddLegendEntry(_legends.back(), hall, leg, "LE1P");
1501  _legends.back()->Draw();
1502  }
1503 
1504  if (!drawUtils::CheckOption(uopt,"NODRAW"))
1505  gPad->Update();
1506 
1507  // reset error in X
1508  gStyle->SetErrorX();
1509 }
1510 
1511 //**************************************************
1512 void DrawingToolsBase::DrawRatioVSCut(TTree* tree1, TTree* tree2, const std::string& precut, int first_cut, int last_cut,
1513  const std::string& root_opt, const std::string& opt, const std::string& leg, double norm){
1514 //**************************************************
1515 
1516  DrawRatioVSCut(tree1,tree2,0, precut,first_cut,last_cut,root_opt,opt,leg,norm);
1517 }
1518 
1519 //**************************************************
1520 void DrawingToolsBase::DrawRatioVSCut(TTree* tree1, TTree* tree2, int ibranch, const std::string& precut, int first_cut, int last_cut,
1521  const std::string& root_opt, const std::string& opt, const std::string& leg, double norm){
1522 //**************************************************
1523 
1524  // if selection exists
1525  if (sel().GetSelection(ibranch,true)) {
1526  int isel = ibranch;
1527  std::cout << "Drawing for selection " << isel << ", branch 0" << std::endl;
1528  return DrawRatioVSCut(tree1,tree2,isel,0,precut,first_cut,last_cut,root_opt,opt,leg,norm);
1529  }
1530 
1531  DrawRatioVSCut(tree1,tree2,0,ibranch,precut,first_cut,last_cut,root_opt,opt,leg,norm);
1532 }
1533 
1534 //**************************************************
1535 void DrawingToolsBase::DrawRatioVSCut(TTree* tree1, TTree* tree2, int isel, int branch, const std::string& precut, int first_cut, int last_cut,
1536  const std::string& root_opt, const std::string& opt, const std::string& leg, double norm){
1537 //**************************************************
1538 
1539  // Check if selection exists
1540  if (!sel().GetSelection(isel,true)) return;
1541 
1542  std::string slevel = GetSameLevel(root_opt);
1543  std::string uopt = drawUtils::ToUpper(opt);
1544 
1545  // Check that all user options are valid
1546  if (!drawUtils::ContainValidOptions(uopt)) return;
1547 
1548  if (slevel=="0" && leg!="")
1549  CreateLegend();
1550 
1551  Int_t first_cut2=-1;
1552  // Histogram for cut1+cut2 (numerator)
1553  TH1_h* h1 = GetEventsVSCut(tree1,"num",precut,isel,branch,first_cut2, last_cut,root_opt,uopt);
1554 
1555  first_cut2=-1;
1556  // Histogram for cut2 (denominator)
1557  TH1_h* h2 = GetEventsVSCut(tree2,"den",precut,isel,branch,first_cut2, last_cut,root_opt,uopt);
1558 
1559  // scale the histo if requested
1560  ScaleHisto(h2,norm);
1561 
1562  DrawRatioVSCut(h1,h2,isel,branch,first_cut,root_opt,uopt,leg);
1563 }
1564 
1565 
1566 //**************************************************
1567 void DrawingToolsBase::DrawPurVSCut(TTree* tree, const std::string& signal, const std::string& precut, int first_cut, int last_cut,
1568  const std::string& root_opt, const std::string& opt, const std::string& leg){
1569 //**************************************************
1570 
1571  DrawPurVSCut(tree,0,signal,precut,first_cut,last_cut,root_opt,opt,leg);
1572 }
1573 
1574 //**************************************************
1575 void DrawingToolsBase::DrawPurVSCut(TTree* tree, int ibranch, const std::string& signal, const std::string& precut, int first_cut, int last_cut,
1576  const std::string& root_opt, const std::string& opt, const std::string& leg){
1577 //**************************************************
1578 
1579  // if selection exists
1580  if (sel().GetSelection(ibranch,true)) {
1581  int isel = ibranch;
1582  std::cout << "Drawing for selection " << isel << ", branch 0" << std::endl;
1583  return DrawPurVSCut(tree,isel,0,signal,precut,first_cut,last_cut,root_opt,opt,leg);
1584  }
1585 
1586  DrawPurVSCut(tree,0,ibranch,signal,precut,first_cut,last_cut,root_opt,opt,leg);
1587 }
1588 
1589 
1590 //**************************************************
1591 void DrawingToolsBase::DrawPurVSCut(TTree* tree, int isel, int branch, const std::string& signal, const std::string& precut, int first_cut, int last_cut,
1592  const std::string& root_opt, const std::string& opt, const std::string& leg){
1593 //**************************************************
1594 
1595  // Check if selection exists
1596  if (!sel().GetSelection(isel,true)) return;
1597 
1598  std::string slevel = GetSameLevel(root_opt);
1599  std::string uopt = drawUtils::ToUpper(opt);
1600 
1601  // Check that all user options are valid
1602  if (!drawUtils::ContainValidOptions(uopt)) return;
1603 
1604  if (slevel=="0" && leg!="")
1605  CreateLegend();
1606 
1607  std::string numer = "";
1608  if (signal == "") {
1609  numer = precut;
1610  } else if (precut == "") {
1611  numer = signal;
1612  } else {
1613  numer = signal+"&&"+precut;
1614  }
1615 
1616  Int_t first_cut2 =-1;
1617  // Histogram for cut1+cut2 (numerator)
1618  TH1_h* h1 = GetEventsVSCut(tree,"pur1",numer,isel,branch,first_cut2, last_cut,root_opt,uopt);
1619 
1620  first_cut2 =-1;
1621  // Histogram for cut2 (denominator)
1622  TH1_h* h2 = GetEventsVSCut(tree,"pur2",precut,isel,branch,first_cut2, last_cut,root_opt,uopt);
1623 
1624  std::cout << "----- Purity values -----------" << std::endl;
1625 
1626  if (!drawUtils::CheckOption(uopt,"DRAWALLCUTS")) first_cut = _minAccumLevelToSave-1;
1627  DrawRatioVSCut(h1,h2,isel,branch,first_cut,root_opt,uopt+" EFF",leg);
1628 }
1629 
1630 //**************************************************
1631 void DrawingToolsBase::DrawEffVSCut(TTree* tree, const std::string& signal, const std::string& precut, int first_cut, int last_cut,
1632  const std::string& root_opt, const std::string& opt, const std::string& leg){
1633 //**************************************************
1634 
1635  DrawEffVSCut(tree,0,signal,precut,first_cut,last_cut,root_opt,opt,leg);
1636 }
1637 
1638 //**************************************************
1639 void DrawingToolsBase::DrawEffVSCut(TTree* tree, int ibranch, const std::string& signal, const std::string& precut, int first_cut, int last_cut,
1640  const std::string& root_opt, const std::string& opt, const std::string& leg){
1641 //**************************************************
1642 
1643  // if selection exists
1644  if (sel().GetSelection(ibranch,true)) {
1645  int isel = ibranch;
1646  std::cout << "Drawing for selection " << isel << ", branch 0" << std::endl;
1647  return DrawEffVSCut(tree,isel,0,signal,precut,first_cut,last_cut,root_opt,opt,leg);
1648  }
1649 
1650  DrawEffVSCut(tree,0,ibranch,signal,precut,first_cut,last_cut,root_opt,opt,leg);
1651 }
1652 
1653 
1654 //**************************************************
1655 void DrawingToolsBase::DrawEffVSCut(TTree* tree, int isel, int branch, const std::string& signal, const std::string& precut, int first_cut, int last_cut,
1656  const std::string& root_opt, const std::string& opt, const std::string& leg){
1657 //**************************************************
1658 
1659  // Check if selection exists
1660  if (!sel().GetSelection(isel,true)) return;
1661 
1662  std::string slevel = GetSameLevel(root_opt);
1663  std::string uopt = drawUtils::ToUpper(opt);
1664 
1665  // Check that all user options are valid
1666  if (!drawUtils::ContainValidOptions(uopt)) return;
1667 
1668  if (slevel=="0" && leg!="")
1669  CreateLegend();
1670 
1671  std::string numer = "";
1672  if (signal == "") {
1673  numer = precut;
1674  } else if (precut == "") {
1675  numer = signal;
1676  } else {
1677  numer = signal+"&&"+precut;
1678  }
1679 
1680  Int_t first_cut2 = -1;
1681  // Histogram for cut1+cut2 (numerator)
1682  TH1_h* h1 = GetEventsVSCut(tree,"eff1",numer,isel,branch,first_cut2, last_cut,root_opt,uopt);
1683 
1684  // Histogram for cut2 (denominator)
1685  int nx = h1->GetNbinsX();
1686  double xmin = h1->GetXaxis()->GetXmin();
1687  double xmax = h1->GetXaxis()->GetXmax();
1688  double xbins[NMAXBINS];
1689  TH1_h* h2 = new TH1_h(GetUniqueName("eff2").c_str(),"eff2",nx,GetVariableBins(nx,xmin,xmax,xbins));
1690  _saved_histos.push_back(h2);
1691 
1692  for (int i=0; i<h2->GetNbinsX();i++){
1693  h2->SetBinContent(i+1,h1->GetBinContent(1));
1694  h2->SetBinError( i+1,h1->GetBinError(1));
1695  }
1696 
1697  std::cout << "----- Efficiency values -----------" << std::endl;
1698  DrawRatioVSCut(h1,h2,isel,branch,first_cut,root_opt,uopt+" EFF",leg);
1699 }
1700 
1701 //**************************************************
1702 void DrawingToolsBase::DrawRatioVSCut(TH1_h* h1, TH1_h* h2, int isel, int branch, int first_cut,
1703  const std::string& root_opt, const std::string& opt, const std::string& leg){
1704 //**************************************************
1705 
1706  // TODO: The entire method must be simplified using DrawHisto and DrawGraph
1707 
1708  // Read the steps from the config tree
1709  // ReadSteps(_config_file);
1710 
1711  // Check if selection exists
1712  if (!sel().GetSelection(isel,true)) return;
1713 
1714  std::string uopt = drawUtils::ToUpper(opt);
1715  std::string uroot_opt = drawUtils::ToUpper(root_opt);
1716 
1717  // Check that all user options are valid
1718  if (!drawUtils::ContainValidOptions(uopt)) return;
1719 
1720  TH1_h* hratio = new TH1_h(GetUniqueName("ratio").c_str(),"",h1->GetNbinsX(),h1->GetXaxis()->GetXmin(),h1->GetXaxis()->GetXmax());
1721  _saved_histos.push_back(hratio);
1722 
1723  hratio->Divide(h1,h2);
1724 
1725  Int_t cut_offset = 1;
1726  // First bin corresponds to no cut
1727  hratio->GetXaxis()->SetBinLabel(1, "NO CUT");
1728 
1729  std::vector<StepBase*> cuts = sel().GetSelection(isel)->GetCutsInBranch(branch);
1730  // Start from second bin since first corresponds to no cut
1731  for (int i=cut_offset;i<hratio->GetNbinsX();i++ ){
1732  int icut = i-cut_offset;
1733  hratio->GetXaxis()->SetBinLabel(i+1, cuts[icut]->Title().c_str());
1734  }
1735 
1736  // No stats box
1737  gStyle->SetOptStat(0);
1738 
1739  // Histogram attributes
1740  hratio->SetTitle(_title.c_str());
1741  hratio->GetXaxis()->SetTitle("");
1742  hratio->GetYaxis()->SetTitle(_titleY.c_str());
1743  hratio->GetYaxis()->SetNdivisions(520);
1744 
1745  // Efficiency ratio
1746  if (drawUtils::CheckInternalOption(uopt,"EFF")){
1747 
1748  hratio->GetYaxis()->SetRangeUser(0,1.1);
1749 
1750  // Set the proper range depending on the first_cut
1751  hratio->GetXaxis()->SetRange(first_cut+cut_offset+1,hratio->GetNbinsX());
1752 
1753  if (uroot_opt.find("SAME")!=std::string::npos)
1754  hratio->Draw("PHIST same");
1755  else
1756  hratio->Draw("PHIST");
1757 
1758  // compute the efficiency
1759  // TGraphAsymmErrors* eff = new TGraphAsymmErrors(h1);
1760  TGraphAsymmErrors* eff = new TGraphAsymmErrors(h1->GetNbinsX());
1761  eff->SetName(GetUniqueName("eff").c_str());
1762  _saved_graphs.push_back(eff);
1763  eff->Divide(h1, h2, (_eff_params + " v").c_str()); //the options are explicitely provided by SetEffDivideParams(const std::string&), root_opt not used to avoid possible confusions
1764 
1765  eff->SetLineColor(_auto_colors[_same_level]);
1766  eff->SetMarkerColor(_auto_colors[_same_level]);
1767  eff->SetMarkerStyle(21);
1768 
1769  // eff->GetXaxis()->SetRange(first_cut+cut_offset+1,hratio->GetNbinsX());
1770  eff->GetXaxis()->SetLimits(first_cut+cut_offset+1,hratio->GetNbinsX());
1771 
1772  for (int i=0; i<h1->GetNbinsX();i++){
1773  eff->SetPointEXhigh(i,0);
1774  eff->SetPointEXlow(i,0);
1775  }
1776 
1777  // Draw the efficiency histogram (TODO: use DrawGraph)
1778  eff->Draw(("PL "+root_opt).c_str());
1779 
1780  // Add an entry to the legend if requested
1781  if (!drawUtils::CheckOption(uopt,"NOLEG") && leg!=""){
1782  drawUtils::AddLegendEntry(_legends.back(), eff, leg, "LE1P");
1783  }
1784  }
1785  // Normal ratio
1786  else{
1787  hratio->SetLineColor(_auto_colors[_same_level]);
1788  hratio->SetMarkerColor(_auto_colors[_same_level]);
1789  hratio->SetMarkerStyle(21);
1790 
1791  // Set the proper range depending on the first_cut
1792  hratio->GetXaxis()->SetRange(first_cut+cut_offset+1,hratio->GetNbinsX());
1793 
1794  // Draw the ratio histogram
1795  hratio->Draw(("PL "+uroot_opt).c_str());
1796 
1797  // Add an entry to the legend if requested
1798  if (!drawUtils::CheckOption(uopt,"NOLEG") && leg!=""){
1799  drawUtils::AddLegendEntry(_legends.back(), hratio, leg, "LE1P");
1800  }
1801 
1802  // Print numbers on the screen
1803  char out1[256];
1804  char out2[256];
1805  for (int i=0;i<hratio->GetNbinsX();i++ ){
1806  int icut = i-1;
1807  std::string cut_name="";
1808  if (icut==-1)
1809  cut_name = "NO CUT";
1810  else
1811  cut_name = cuts[icut]->Title();
1812  sprintf(out1,"%3s: %-25s %-10s", "#", "cut", "ratio");
1813  sprintf(out2,"%3d: %-25s %-10.2f", icut, cut_name.c_str(), hratio->GetBinContent(i+1));
1814  if (i==0) std::cout << out1 << std::endl;
1815  std::cout << out2 << std::endl;
1816  }
1817  }
1818 
1819  // Draw the legend if requestet
1820  if (!drawUtils::CheckOption(uopt,"NOLEG") && leg!="")
1821  _legends.back()->Draw();
1822 
1823  if (!drawUtils::CheckOption(uopt,"NODRAW"))
1824  gPad->Update();
1825 }
1826 
1827 //*********************************************************
1828 void DrawingToolsBase::DrawToys(TTree* tree, const std::string& cut, const std::string& root_opt, const std::string& opt, const std::string& leg){
1829 //*********************************************************
1830 
1831  // Draw the distribution of entries for all toy experiments
1832  // The rms of this distribution is the systematic error
1833 
1834  std::string uopt = drawUtils::ToUpper(opt);
1835 
1836 
1837  // Check that all user options are valid
1838  if (!drawUtils::ContainValidOptions(uopt)) return;
1839 
1840  int ntoys = drawUtils::GetNToys(tree);
1841 
1842  TH1_h h1("h1","h1",ntoys,0,ntoys);
1843  TH1_h hw("hw","hw",ntoys,0,ntoys);
1844 
1845  // Apply event weights
1846  std::string cutp = weightTools::ApplyWeights(tree,FormatCut(cut),(uopt+" NOTOYW").c_str());
1847 
1848  // Project with no toy experiment weights
1849  tree->Project("h1","toy_index",cutp.c_str());
1850 
1851  std::string cut2=cut;
1852  if (cut2=="") cut2="1==1";
1853 
1854  // Project the toy experiment PDF weights
1855  if (drawUtils::TreeHasVar(tree,"toy_weight"))
1856  tree->Project("hw","toy_index",("("+cutp+")*toy_weight").c_str());
1857  else
1858  hw = h1;
1859 
1860  // compute the average toy exp weight
1861  TH1_h hwa(hw);
1862  hwa.Divide(&hw,&h1);
1863 
1864  DrawToysBase(h1,hwa,root_opt,uopt,leg);
1865 }
1866 
1867 
1868 //*********************************************************
1869 void DrawingToolsBase::DrawToysRatio(TTree* tree1, TTree* tree2, const std::string& cut,
1870  const std::string& root_opt, const std::string& opt, const std::string& leg, double norm){
1871 //*********************************************************
1872 
1873  // Draw the distribution of ratios for all toy experiments
1874  // The rms of this distribution is the systematic error
1875  // Use same cut for both data samples
1876 
1877  DrawToysRatioTwoCuts(tree1,tree2,cut,cut,root_opt,opt,leg,norm);
1878 }
1879 
1880 //*********************************************************
1881 void DrawingToolsBase::DrawToysRatioTwoCuts(TTree* tree1, TTree* tree2, const std::string& cut1, const std::string& cut2,
1882  const std::string& root_opt, const std::string& opt, const std::string& leg, double norm){
1883 //*********************************************************
1884 
1885  // Draw the distribution of ratios for all toy experiments
1886  // The rms of this distribution is the systematic error
1887  // Use different cuts for both data samples
1888 
1889  int NTOYS1 = drawUtils::GetNToys(tree1);
1890  int NTOYS2 = drawUtils::GetNToys(tree2);
1891 
1892  // The number of toy experiments must be the same
1893  if (NTOYS1!=NTOYS2) return;
1894 
1895  std::string uopt = drawUtils::ToUpper(opt);
1896 
1897  // Check that all user options are valid
1898  if (!drawUtils::ContainValidOptions(uopt)) return;
1899 
1900 
1901  // Apply event weights
1902  std::string cut1p = weightTools::ApplyWeights(tree1,FormatCut(cut1),(uopt+" NOTOYW").c_str());
1903  std::string cut2p = weightTools::ApplyWeights(tree2,FormatCut(cut2),(uopt+" NOTOYW").c_str());
1904 
1905  // Project the first sample
1906  TH1_h h1("en1","en2",NTOYS1,0,NTOYS1);
1907  tree1->Project("en1","toy_index",cut1p.c_str());
1908 
1909  // Project the second sample
1910  TH1_h h2("en2","en2",NTOYS1,0,NTOYS1);
1911  tree2->Project("en2","toy_index",cut2p.c_str());
1912 
1913  // compute the ratio
1914  TH1_h ratio(h1);
1915  ratio.SetName("ratio");
1916  ScaleHisto(&h2,norm);
1917  ratio.Divide(&h1,&h2);
1918 
1919  // Project the weights for the first sample
1920  TH1_h hw1("hw1","hw1",NTOYS1,0,NTOYS1);
1921  if (drawUtils::TreeHasVar(tree1,"toy_weight"))
1922  tree1->Project("hw1","toy_index",("("+cut1p+")*toy_weight").c_str());
1923  else
1924  hw1 = h1;
1925 
1926  // Project the weights for the first sample
1927  TH1_h hw2("hw2","hw2",NTOYS1,0,NTOYS1);
1928  if (drawUtils::TreeHasVar(tree2,"toy_weight"))
1929  tree2->Project("hw2","toy_index",("("+cut2p+")*toy_weight").c_str());
1930  else
1931  hw2 = h2;
1932 
1933 
1934  // compute the average weights for sample 1
1935  TH1_h hwa1(hw1);
1936  hwa1.Divide(&hw1,&h1);
1937 
1938  // compute the average weights for sample 2
1939  TH1_h hwa2(hw2);
1940  hwa2.Divide(&hw2,&h2);
1941 
1942 
1943  DrawToysBase(ratio,hwa2,root_opt,uopt,leg);
1944 }
1945 
1946 //*********************************************************
1947 void DrawingToolsBase::DrawToysBase(TH1_h& result, TH1_h& weights, const std::string& root_opt, const std::string& opt, const std::string& leg){
1948 //*********************************************************
1949 
1950  // Draw the distribution of entries for all toy experiments
1951 
1952  std::string slevel = GetSameLevel(root_opt);
1953  std::string uopt = drawUtils::ToUpper(opt);
1954  if (slevel=="0" && leg!="")
1955  CreateLegend();
1956 
1957  // Stat option (entries, MEAN, RMS, and integral)
1958  int statTemp = _stat_option;
1959  SetOptStat(1001110);
1960  gStyle->SetOptStat(1001110);
1961 
1962  const int NTOYS = result.GetNbinsX();
1963 
1964  double nentries[NMAXTOYS];
1965  double avg_weight[NMAXTOYS];
1966  double sum_weights=0;
1967  double avg_nentries=0;
1968  double hmin = 1e10;
1969  double hmax = -1;
1970 
1971  // Get the entries
1972  for (int itoy=0;itoy<NTOYS;itoy++){
1973  nentries[itoy]=result.GetBinContent(itoy+1);
1974  // Get the average weight for each toy experiment
1975  if (nentries[itoy]>0)
1976  avg_weight[itoy] = weights.GetBinContent(itoy+1);
1977  else
1978  avg_weight[itoy] = 0;
1979  std::cout << "toy_index = "<< itoy << "\t --> #entries = " << nentries[itoy] << "\t w=" << avg_weight[itoy] << std::endl;
1980 
1981  if (nentries[itoy]>hmax) hmax = nentries[itoy];
1982  if (nentries[itoy]<hmin) hmin = nentries[itoy];
1983 
1984  // compute the total weight and average entries (justfor debugging)
1985  sum_weights += avg_weight[itoy];
1986  avg_nentries += nentries[itoy]*avg_weight[itoy];
1987  }
1988 
1989  std::cout << "avg[#entries] = sum[entries*avg_weight]/sum[avg_weight] = "<< avg_nentries/sum_weights
1990  << ", sum[avg_weights] = " << sum_weights
1991  << ", sum[entries*avg_weight] = " << avg_nentries << std::endl;
1992 
1993  // Create an histogram and fill the distribution
1994  TH1_h* hentries = new TH1_h(GetUniqueName("hentries").c_str(),leg.c_str(),1000,hmin-(hmax-hmin)/10.,hmax+(hmax-hmin)/10.);
1995  _saved_histos.push_back(hentries);
1996 
1997  double rms=0;
1998  double rms2=0;
1999  for (int itoy=0;itoy<NTOYS;itoy++){
2000  // hentries->Fill(nentries[itoy],avg_weight[itoy]);
2001  hentries->Fill(nentries[itoy],1./NTOYS);
2002 
2003  // this is just for debugging. rms should coincide with the rms given by root
2004  rms += pow(nentries[itoy]-avg_nentries/sum_weights,2)*avg_weight[itoy]/sum_weights;
2005 
2006  // this is the rms when the weights are not properly normilized to 1
2007  rms2 += pow(nentries[itoy]-avg_nentries,2)*avg_weight[itoy];
2008  }
2009 
2010  std::cout << "rms = "<< sqrt(rms) << ", rms' = " << sqrt(rms2) << std::endl;
2011 
2012  // Draw the entries histogram
2013  DrawHisto(hentries, _line_width, _line_color, _fill_style, root_opt, uopt, "LE1P");
2014 
2015  // Draw the legend
2016  if (!drawUtils::CheckOption(uopt,"NOLEG") && leg!="")
2017  _legends.back()->Draw();
2018 
2019  if (!drawUtils::CheckOption(uopt,"NODRAW"))
2020  gPad->Update();
2021 
2022  // go back to previous stat option
2023  SetOptStat(statTemp);
2024 }
2025 
2026 //**************************************************
2027 void DrawingToolsBase::DrawHisto(TH1* h, int lw, int fc, int fs, const std::string& root_opt, const std::string& opt,const std::string& leg_opt,int mode){
2028 //**************************************************
2029 
2030  std::string uopt = drawUtils::ToUpper(opt);
2031 
2032  // (_line_color != 1) allows SetLineColor with DrawRealtiveErrors
2033  if (drawUtils::CheckInternalOption(uopt,"NOAUTOCOLORS") || _line_color != 1){
2034  // Draw histogram without specific color
2035  DrawHisto(h,fc,lw,fc,fs, root_opt, opt,leg_opt,mode);
2036  }
2037  else{
2038  // Draw histogram without specific color. Use the auto colors
2039  DrawHisto(h,_auto_colors[_same_level],lw,fc,fs, root_opt, opt,leg_opt,mode);
2040  }
2041 }
2042 
2043 //**************************************************
2044 void DrawingToolsBase::DrawHisto(TH1* h, int lc, int lw, int fc, int fs, const std::string& root_opt, const std::string& opt,const std::string& leg_opt,int mode){
2045 //**************************************************
2046 
2047  (void)mode;
2048 
2049 
2050  // Basic function to draw 1D histo
2051  std::string uopt = drawUtils::ToUpper(opt);
2052  std::string uroot_opt = drawUtils::ToUpper(root_opt);
2053 
2054  // Dump the histogram
2055  if (drawUtils::CheckOption(uopt,"DUMP"))
2056  DumpHisto(h,uopt);
2057 
2058  // Don't draw
2059  if (drawUtils::CheckOption(uopt,"NODRAW")) return;
2060 
2061  if (drawUtils::CheckOption(uopt,"NOSTAT"))
2062  gStyle->SetOptStat(0);
2063  else
2064  gStyle->SetOptStat(_stat_option);
2065 
2066  h->SetLineColor(lc);
2067  h->SetMarkerColor(lc);
2068 
2069  // Use the marker in all cases
2070  if (fs == 0)// && drawUtils::CheckInternalOption(uopt,"ISDATA")) // check ISDATA in case of plotting mc,data with FillStyle 0
2071  h->SetMarkerStyle(_marker_style);
2072 
2073  h->SetMarkerSize(_marker_size);
2074 
2075  h->SetLineWidth(lw);
2076  h->SetFillColor(fc);
2077  h->SetFillStyle(fs);
2078 
2079  // get the title for the legend
2080  std::string title = h->GetTitle();
2081  std::string leg_opt_copy = leg_opt;
2082  if (_data_label != "" && drawUtils::CheckInternalOption(uopt,"ISDATA")) {
2083  title = _data_label;
2084  leg_opt_copy = "lpe";
2085  }
2086  else if (_allmcstat_label != "" && drawUtils::CheckInternalOption(uopt,"ALLMCSTATLEG")) {
2087  title = _allmcstat_label;
2088  leg_opt_copy = "f";
2089  }
2090  else if (_allmcsyst_label != "" && drawUtils::CheckInternalOption(uopt,"ALLMCSYSTLEG")) {
2091  title = _allmcsyst_label;
2092  leg_opt_copy = "f";
2093  }
2094  else if (_allmc_label != "" && drawUtils::CheckInternalOption(uopt,"ALLMCLEG")) {
2095  title = _allmc_label;
2096  leg_opt_copy = "f";
2097  }
2098 
2099  // Set axis labels and title
2100  h->GetXaxis()->SetTitle(_titleX.c_str());
2101  h->GetYaxis()->SetTitle(_titleY.c_str());
2102  h->SetTitle(_title.c_str());
2103 
2104  //---------- Put the right statistics box, with no variable binning normalization --------------
2105  TH1_h* hp = new TH1_h(*((TH1_h*)h));
2106  std::string name = hp->GetName();
2107  hp->SetName((name+"_new").c_str());
2108  _saved_histos.push_back(hp);
2109 
2110  // TODO: for some reason putting an option that does not exist (i.e. Z) does the trick: plots the axis with stat and title. This solves bug 1043
2111  // If no one complains keep it like this
2112  std::string root_opt_novarbin = "Z";
2113  root_opt_novarbin = root_opt_novarbin + GetSameRootOption(uroot_opt);
2114 
2115  // I don't know why these lines were here. It causes problems when ploting two DataSample's with "all" category, since it does not plot the h histogram empty
2116  // The comment above is probably obsolete. These lines are needed to ensure markers are not drawn in all cases when option HIST is used
2117  // (even with AREA1 and AREA100, see bug 1338)
2118  if (uroot_opt.find("HIST")!=std::string::npos)
2119  root_opt_novarbin = root_opt_novarbin + " HIST";
2120 
2121  h->Draw(root_opt_novarbin.c_str());
2122  //----------------------------------------------------------------------------------------------
2123 
2125 
2126  // Draw the final histogram with variable binning normalization but no statistics box
2127  // first remove SAME or SAMES from the root_opt, because if it appears twice we can have undesired effects
2128  // In addition we dont want the stat box again, so never use SAMES
2129  std::string uroot_opt2= GetNoSameRootOption(uroot_opt);
2130 
2131  hp->Draw((uroot_opt2+" same").c_str());
2132 
2133 
2134  // Note: TH1_h::GetBinErrorUp() was used in this function in stead of TH1_h::GetBinError(). That
2135  // function is not available on ROOT 5.30, which is the default for production 5. Thus this
2136  // function cannot be used here, as we need production 5 compatibility!
2137 
2138  double ymax = hp->GetBinContent(hp->GetMaximumBin())+hp->GetBinError(hp->GetMaximumBin());
2139  // Get the maximum y and set the y max of the histogram
2140  if (fabs(_maxY) > 1e-6 && _maxY > _minY)
2141  h->SetMaximum(_maxY);
2142  else
2143  h->SetMaximum(ymax*_relativeMaxY);
2144 
2145 
2146  // set the minimun Y
2147  if (!drawUtils::CheckOption(uopt,"NOMIN")|| _logY)
2148  h->SetMinimum(_minY);
2149 
2150 
2151  gPad->SetLogy(_logY);
2152 
2153  //Add entry to legend
2154  if (_drawleg && !drawUtils::CheckOption(uopt,"NOLEG") && !drawUtils::CheckInternalOption(uopt,"DONTADDLEGENTRY") && title!="")
2155  drawUtils::AddLegendEntry(_legends.back(), h, title, leg_opt_copy);
2156 
2157 }
2158 
2159 //**************************************************
2160 void DrawingToolsBase::DrawHistoStack(HistoStack* hs, const std::string& categ, const std::string& root_opt, const std::string& opt,const std::string& leg_opt,int mode){
2161 //**************************************************
2162 
2163  DrawHistoStack(hs,categ,root_opt,opt,_line_color, _line_width, _fill_color, _fill_style, leg_opt, mode);
2164 }
2165 
2166 //**************************************************
2167 void DrawingToolsBase::DrawHistoStack(HistoStack* hs, const std::string& categ, const std::string& root_opt, const std::string& opt, int lc, int lw, int fc, int fs, const std::string& leg_opt,int mode){
2168 //**************************************************
2169 
2170  if (!hs->GetTotal1D() && !hs->GetTotal2D()) return;
2171 
2172  // mode not currently used. This is for variable bin normalization. This normalization is done when Projecting the histogram and not at drawing level
2173  // mainly to avoid normalizing several times when plotting the same histo twice
2174  (void)mode;
2175  (void)leg_opt;
2176 
2177  std::string uopt = drawUtils::ToUpper(opt);
2178 
2179  // Dump the histogram
2180  if (drawUtils::CheckOption(uopt,"DUMP") && hs->GetTotal1D())
2181  DumpHisto(hs->GetTotal1D(),uopt);
2182 
2183  if (!drawUtils::CheckOption(uopt,"NOINFO") && hs->GetTotal1D()){
2184  DumpHistoInfo(hs->GetTotal1D(),uopt);
2185  }
2186 
2187 
2188  // Don't draw
2189  if (drawUtils::CheckOption(uopt,"NODRAW")) return;
2190 
2191  if (drawUtils::CheckOption(uopt,"NOSTAT"))
2192  gStyle->SetOptStat(0);
2193  else
2194  gStyle->SetOptStat(_stat_option);
2195 
2196  // Create the legend
2197  CreateLegend(uopt);
2198 
2199  if (categ=="all") {
2200  // this if is needed to draw the legend for data when categ is all
2201  if (!drawUtils::CheckInternalOption(uopt,"ISDATA") && !drawUtils::CheckInternalOption(uopt,"ALLMCLEG")) uopt=uopt+" NOLEG";
2202 
2203  if (hs->Is1D()){
2204  std::string same="";
2205 
2206  // Error bars for second sample (MC in general)
2207  std::string uopt2 = uopt;
2208  std::string error_opt = "";
2209  if (drawUtils::CheckInternalOption(uopt,"ISSECONDSAMPLE")){
2210  error_opt = GetErrorStyle(uopt);
2211  if (error_opt!=""){
2212  lc = fc = _mcerror_color;
2213  lw = _line_width;
2214  fs = 1001;
2215  uopt2 = uopt+" NOAUTOCOLORS";
2216  error_opt= " "+ error_opt;
2217  }
2218  else
2219  uopt2 = uopt+" NOERROR";
2220  }
2221 
2222  // Draw first the histo with all errors (stat+syst)
2223  if (!drawUtils::CheckOption(uopt2,"NOTOTERROR") || drawUtils::CheckInternalOption(uopt2,"ISDATA") || !hs->GetTotalSyst1D()){
2224  if (drawUtils::CheckInternalOption(uopt2,"NOERROR"))
2225  DrawHisto(hs->GetTotal1D(), lc, lw, fc, fs, root_opt+" HIST", uopt2, "f");
2226  else
2227  DrawHisto(hs->GetTotal1D(), lc, lw, fc, fs, root_opt+error_opt, uopt2, "f");
2228  same = " same";
2229  }
2230 
2231  // Draw superimposed the histo with only statistical or systematic errors
2232  if (!drawUtils::CheckInternalOption(uopt,"ISDATA")){
2233  if (hs->GetTotalStat1D() && !drawUtils::CheckOption(uopt,"NOSTERROR") && !drawUtils::CheckOption(uopt,"SYSTERROR"))
2234  DrawHisto(hs->GetTotalStat1D(), _mcstaterror_color, lw, _mcstaterror_color, fs, root_opt+same+error_opt, uopt2+" ALLMCSTATLEG", "f");
2235  else if (hs->GetTotalSyst1D() && drawUtils::CheckOption(uopt,"SYSTERROR"))
2236  DrawHisto(hs->GetTotalSyst1D(), _mcstaterror_color, lw, _mcstaterror_color, fs, root_opt+same+error_opt, uopt2+" ALLMCSYSTLEG", "f");
2237  }
2238  }
2239  else if (hs->Is2D())
2240  DrawHisto(hs->GetTotal2D(), lc, lw, fc, fs, root_opt, uopt);
2241 
2242  }
2243  else {
2244  // if categ != all
2245  hs->Draw(root_opt+" HIST",uopt);
2246  if(hs->Is1D() && drawUtils::CheckOption(uopt,"DRAWALLMC"))
2247  DrawHisto(hs->GetTotal1D(), lc, lw, fc, fs, root_opt+" same", uopt,"f");
2248  }
2249 
2250  // Create the legend. After || is needed to draw the legend for data when categ is all
2251  // if ((!drawUtils::CheckOption(uopt,"NOLEG") && categ!="all") || (drawUtils::CheckOption(uopt,"ISDATA") && categ=="all")) {
2252  if ((!drawUtils::CheckOption(uopt,"NOLEG"))){
2253  hs->FillLegend(_legends.back());
2254  _legends.back()->Draw();
2255  }
2256 
2257  // If stat box has "name", set it manually (instead of having the hs name). scantaTM
2258  int optstat = gStyle->GetOptStat();
2259  if (optstat % 2 != 0) {
2260  gPad->Update(); // needed, PaveStats might not exist yet
2261  TPaveStats *pavestat = (TPaveStats*)gPad->GetPrimitive("stats");
2262  pavestat->SetName("mystats"); // needed, unknown reasons
2263  TList *list = pavestat->GetListOfLines();
2264  list->RemoveFirst(); // remove the current title
2265  // create new title
2266  TLatex *name = new TLatex(0,0,_allmc_label.c_str());
2267  if (drawUtils::CheckInternalOption(uopt,"ISDATA")) {
2268  name = new TLatex(0,0,_data_label.c_str());
2269  name->SetTextColor(_data_color);
2270  } else {
2271  name = new TLatex(0,0,_allmc_label.c_str());
2272  name->SetTextColor(_allmc_color);
2273  }
2274  list->AddFirst(name);
2275 // list->Print();
2276  if (hs->Is1D()) hs->GetTotal1D()->SetStats(0); // to avoid the automatic redraw of stats
2277  else hs->GetTotal2D()->SetStats(0); // to avoid the automatic redraw of stats
2278  gPad->Draw(); // needed to update
2279  pavestat->Draw(); // needed when categ != all
2280  }
2281 
2282  // Set the appropriate maximum for 1D plots
2283  if (hs->Is1D()){
2284  double max = _maxY;
2285  double relmax=1.;
2286  if (fabs(_maxY) < 1e-6 || _maxY < _minY) {
2287  max = hs->GetMaximumWithError(opt);
2288  relmax=_relativeMaxY;
2289  if (categ!="all" && !drawUtils::CheckOption(uopt,"ETOT"))
2290  max = hs->GetMaximum(opt);
2291  }
2292 
2293  if (categ!="all") relmax/=1.05;
2294 
2295  hs->SetMaximum(max*relmax);
2296 
2297  // set the minimun Y
2298  if (!drawUtils::CheckOption(uopt,"NOMIN") || _logY)
2299  hs->SetMinimum(_minY);
2300 
2301  gPad->SetLogy(_logY);
2302  gPad->Update();
2303  gPad->Draw();
2304  }
2305 }
2306 
2307 //**************************************************
2308 void DrawingToolsBase::DrawHistoStacks(HistoStack* hs1p, HistoStack* hs2p,
2309  const std::string& categ, const std::string& root_opt, const std::string& opt, double norm){
2310 //**************************************************
2311 
2312  (void)norm; // norm not currently used
2313 
2314  // Draw 1D (ny=0) or 2D comparison between two data samples with different normalisation. Variable binning
2315 
2316  if (!HasCategory(categ)) return;
2317  std::string uopt = drawUtils::ToUpper(opt);
2318  std::string uroot_opt = drawUtils::ToUpper(root_opt);
2319 
2320  // Make sure the HistoStacks have been filled
2321  HistoStack* hs1 = NULL;
2322  HistoStack* hs2 = NULL;
2323  if (hs1p && (hs1p->GetTotal1D() || hs1p->GetTotal2D())) hs1=hs1p;
2324  if (hs2p && (hs2p->GetTotal1D() || hs2p->GetTotal2D())) hs2=hs2p;
2325 
2326  // Is a 2D histo ?
2327  bool is2D = false;
2328  if (hs1){
2329  if (hs1->Is2D()) is2D=true;
2330  }
2331  else if (hs2){
2332  if (hs2->Is2D()) is2D=true;
2333  }
2334  // options for 2D histos
2335  std::string box = "";
2336  std::string error1 = "";
2337  TVirtualPad* curPad = gPad;
2338 
2339  // Don't draw errors on first sample when option HIST is specified
2340  if (uroot_opt.find("HIST") == std::string::npos)
2341  error1=" e";
2342  else
2343  uopt= uopt+" NOERROR";
2344 
2345  if (is2D){
2346  box = " box";
2347  error1 = "";
2348  }
2349 
2350  std::string smallleg="";
2351  if (categ=="all") smallleg= " SMALLLEG";
2352  if (!hs2) uopt=uopt+" NOLEG";
2353 
2354  CreateLegend(uopt+smallleg);
2355 
2356  // Don't create the legend below
2357  uopt = uopt+ " NOCREATELEG";
2358 
2359  if(!is2D && drawUtils::CheckOption(uopt,"RATIO")){
2360  curPad->cd();
2361  gPad->SetLogy(0);
2362  gPad->SetBottomMargin(0);
2363  if(!_MainPad) _MainPad = new TPad("MainPad","MainPad",
2364  curPad->GetAbsXlowNDC(),
2365  curPad->GetAbsYlowNDC()+(curPad->GetAbsHNDC()*0.3),
2366  curPad->GetAbsXlowNDC()+curPad->GetAbsWNDC(),
2367  curPad->GetAbsYlowNDC()+curPad->GetAbsHNDC());
2368  _MainPad->SetLogy(_logY);
2369  _MainPad->SetBottomMargin(0);
2370  gStyle->SetOptStat(_stat_option);
2371 
2372  _MainPad->Draw();
2373  _MainPad->cd();
2374  }
2375 
2376  // 1. Add the data (first sample) entry to the legend, such that it goes first
2377  if (hs1 && hs2 && ! drawUtils::CheckOption(uopt,"NOLEG") && ! drawUtils::CheckOption(uopt,"NODATA"))
2378  drawUtils::AddLegendEntry(_legends.back(), hs1->GetTotal1D(), _data_label, "lpe");
2379 
2380  // 2. Draw the second sample (mc) with a specific category
2381 
2382  // must set the stat option before changing the legend position
2383  gStyle->SetOptStat(_stat_option);
2384 
2385  if (hs2 && ! drawUtils::CheckOption(uopt,"NOMC")) {
2386  if (hs1 && !is2D && ! drawUtils::CheckOption(uopt,"NODATA")){
2387  // Shift the position of the stat box to the left
2388  double w = gStyle->GetStatW();
2389  SetStatPos(_statPos[0]-w);
2390  // re-set the default stat position
2391  _statPos[0] = _statPos[0] + w;
2392 
2393  std::string uopt2 = uopt+" ALLMCLEG";
2394  // Don't show second sample stat when normalizing by area
2395  if (drawUtils::CheckOption(uopt,"AREA")) uopt2 = uopt2+" NOSTAT";
2396 
2397  // The root_opt is only for first sample
2398  DrawHistoStack(hs2,categ, GetSameRootOption(root_opt), uopt2+" ISSECONDSAMPLE");
2399  }
2400  else{
2401  // This is done for 2D histos and also when the NODATA option is specified. In this last case the second sample is treated similar to first
2402  SetStatPos(_statPos[0], _statPos[1]);
2403  DrawHistoStack(hs2,categ,root_opt+box,uopt+" ISSECONDSAMPLE");
2404  }
2405  }
2406  // 3. Draw first sample (data) on top and write the number of entries
2407  if (hs1 && ! drawUtils::CheckOption(uopt,"NODATA")) {
2408  SetStatPos(_statPos[0], _statPos[1]);
2409  std::string same="";
2410  if (hs2 && ! drawUtils::CheckOption(uopt,"NOMC")) same = " sames";
2411  DrawHistoStack(hs1, "all", root_opt+same+error1, uopt+" ISDATA DONTADDLEGENTRY",_line_color, _line_width, _fill_color, 0, "LE1P", 2);
2412  }
2413 
2414 
2415  // Don't draw
2416  if (drawUtils::CheckOption(uopt,"NODRAW")) return;
2417 
2418  // Set the appropriate maximum for 1D plots
2419  if (!is2D){
2420  bool draw1 = (hs1 && ! drawUtils::CheckOption(uopt,"NODATA"));
2421  bool draw2 = (hs2 && ! drawUtils::CheckOption(uopt,"NOMC"));
2422 
2423  double max = _maxY;
2424  double relmax=1.;
2425  if (fabs(_maxY) < 1e-6 || _maxY < _minY) {
2426  relmax=_relativeMaxY;
2427  double max2 = 0;
2428  if (draw2){
2429  if (drawUtils::CheckOption(uopt,"ETOT"))
2430  max2 = hs2->GetMaximumWithError(opt);
2431  else
2432  max2 = hs2->GetMaximum(opt);
2433  }
2434  if (draw1 && draw2) max = std::max(hs1->GetMaximumWithError(opt), max2);
2435  else if (draw1) max = hs1->GetMaximumWithError(opt);
2436  else if (draw2) max = max2;
2437  }
2438  if (categ!="all") relmax/=1.05;
2439 
2440  if (draw1) hs1->SetMaximum(max*relmax);
2441  if (draw2) hs2->SetMaximum(max*relmax);
2442 
2443  // set the minimun Y
2444  if (!drawUtils::CheckOption(uopt,"NOMIN") || _logY){
2445  if (draw1) hs1->SetMinimum(_minY);
2446  if (draw2) hs2->SetMinimum(_minY);
2447  }
2448  if(drawUtils::CheckOption(uopt,"RATIO")){
2449  //gPad->Update();
2450  curPad->cd();
2451  if(!_RatioPad) _RatioPad = new TPad("RatioPad","RatioPad",
2452  curPad->GetAbsXlowNDC(),
2453  curPad->GetAbsYlowNDC(),
2454  curPad->GetAbsXlowNDC()+curPad->GetAbsWNDC(),
2455  curPad->GetAbsYlowNDC()+(curPad->GetAbsHNDC()*0.3));
2456  _RatioPad->Draw();
2457  _RatioPad->cd();
2458  TH1F* ratio = (TH1F*)hs1->GetTotal1D()->Clone();
2459  ratio->Divide(hs2->GetTotal1D());
2460 
2461  ratio->SetStats(0);
2462  ratio->GetYaxis()->SetNdivisions(010, true);
2463  ratio->GetXaxis()->SetLabelSize(ratio->GetXaxis()->GetLabelSize()/0.3);
2464  ratio->GetYaxis()->SetLabelSize(ratio->GetYaxis()->GetLabelSize()/0.3);
2465  ratio->GetYaxis()->SetTitle("Ratio");
2466  ratio->GetXaxis()->SetTitleSize(ratio->GetXaxis()->GetTitleSize()/0.3);
2467  ratio->GetYaxis()->SetTitleSize(ratio->GetYaxis()->GetTitleSize()/0.3);
2468  DrawHisto(ratio, _line_color, _line_width, 0, 0, root_opt+" same error", "ST NOSTAT ISDATA DONTADDLEGENTRY", "", 2);
2469  ratio->SetMaximum(_relativeMaxY*ratio->GetBinContent(ratio->GetMaximumBin()));
2470  ratio->SetMinimum( ratio->GetBinContent(ratio->GetMinimumBin())/_relativeMaxY);
2471  _RatioPad->SetLogy(0);
2472  _RatioPad->SetTopMargin(0);
2473  _RatioPad->SetBottomMargin(0.3);
2474  _RatioPad->SetGridx();
2475  _RatioPad->SetGridy();
2476  _RatioPad->Update();
2477  curPad->cd();
2478  }
2479 
2480  gStyle->SetOptStat(_stat_option);
2481 
2482  if(_RatioPad){_RatioPad->Update();_RatioPad->Draw();}
2483  if(_MainPad) {_MainPad ->Update();_MainPad ->Draw();}
2484  gPad->Update();
2485  gPad->Draw();
2486  }
2487 
2488 }
2489 
2490 //**************************************************
2491 void DrawingToolsBase::DrawHisto(TH2* h, int lc, int lw, int fc, int fs, const std::string& root_opt, const std::string& opt,const std::string& leg_opt,int mode){
2492 //**************************************************
2493 
2494  // Basic function to draw 2D histo
2495 
2496  (void)mode; // mode not currently used
2497 
2498  std::string uopt = drawUtils::ToUpper(opt);
2499 
2500  if (drawUtils::CheckOption(uopt,"NOSTAT"))
2501  gStyle->SetOptStat(0);
2502  else
2503  gStyle->SetOptStat(_stat_option);
2504 
2505  h->SetLineColor(lc);
2506  h->SetMarkerColor(lc);
2507 
2508  // Use the marker in all cases
2509  if (fs == 0)// && drawUtils::CheckInternalOption(uopt,"ISDATA")) // check ISDATA in case of plotting mc,data with FillStyle 0
2510  h->SetMarkerStyle(_marker_style);
2511 
2512  h->SetMarkerSize(_marker_size);
2513 
2514  h->SetLineWidth(lw);
2515  h->SetFillColor(fc);
2516  h->SetFillStyle(fs);
2517 
2518  if (!drawUtils::CheckOption(uopt,"NOMIN"))
2519  h->SetMinimum(_minY);
2520 
2521  // Normalize the content to take into account variable binning
2522  // drawUtils::NormalizeVariableBinning(h,mode,uopt);
2523 
2524  // get the title for the legend
2525  std::string title = h->GetTitle();
2526 
2527  h->GetXaxis()->SetTitle(_titleX.c_str());
2528  h->GetYaxis()->SetTitle(_titleY.c_str());
2529 
2530  h->SetTitle(_title.c_str());
2531 
2532 
2533  if (drawUtils::CheckInternalOption(uopt,"PROF")){
2534  TProfile* prof;
2535  if (drawUtils::CheckOption(uopt,"PROFX")){
2536  prof = h->ProfileX();
2537  }
2538  else if (drawUtils::CheckOption(uopt,"PROFY")){
2539  prof = h->ProfileY();
2540  }
2541  else{
2542  std::cout << "wrong profile type !!!!" << std::endl;
2543  return;
2544  }
2545  _saved_histos.push_back(prof);
2546  DrawHisto(prof,lc,lw,fc,fs, root_opt, uopt+" NOMIN",leg_opt);
2547  }
2548  else
2549  h->Draw(root_opt.c_str());
2550 
2551  gPad->SetLogz(_logZ);
2552 
2553  //Add entry to legend
2554  if (_drawleg && !drawUtils::CheckOption(uopt,"NOLEG") && title!="")
2555  drawUtils::AddLegendEntry(_legends.back(), h, title, leg_opt);
2556 
2557 }
2558 
2559 //**************************************************
2560 void DrawingToolsBase::DrawHisto(TH3F* h, int lc, int lw, int fc, int fs, const std::string& root_opt){
2561 //**************************************************
2562 
2563  // Basic function to draw 3D histo
2564 
2565  gStyle->SetOptStat(_stat_option);
2566 
2567  h->SetTitle("");
2568 
2569  h->SetLineColor(lc);
2570  h->SetLineWidth(lw);
2571  h->SetFillColor(fc);
2572  h->SetFillStyle(fs);
2573 
2574  h->SetMarkerColor(lc);
2575 
2576  h->Draw(root_opt.c_str());
2577 
2578 }
2579 
2580 //**************************************************
2581 void DrawingToolsBase::ScaleHisto(TH1* h, double scale, bool scale_errors){
2582 //**************************************************
2583 
2584  // Scale an histogram
2585  // if scale_errors=true, errors are also scaled
2586  // This is needed to draw comparisons or ratios between two data samples with different statistics
2587 
2588  if (scale==0 || scale ==1) return;
2589 
2590  if (scale_errors)
2591  h->Sumw2();
2592  h->Scale(scale);
2593 }
2594 
2595 //*********************************************************
2596 double* DrawingToolsBase::GetVariableBins(int nx, double xmin, double xmax, double* xbins){
2597 //*********************************************************
2598 
2599  for (int i=0;i<nx+1;i++)
2600  xbins[i]= xmin+i*(xmax-xmin)/nx;
2601 
2602  return xbins;
2603 }
2604 
2605 //*********************************************************
2606 std::string DrawingToolsBase::GetSameLevel(const std::string& root_opt ){
2607 //*********************************************************
2608 
2609  std::string uroot_opt = drawUtils::ToUpper(root_opt);
2610  if (uroot_opt.find("SAME") == std::string::npos){
2611  _drawleg = false;
2612  _same_level=0;
2613  }
2614  else{
2615  _same_level++;
2616  }
2617 
2618  _same_level_tot++;
2619 
2620  std::stringstream slevel;
2621  slevel << _same_level;
2622 
2623  return slevel.str();
2624 }
2625 
2626 //*********************************************************
2628 //*********************************************************
2629 
2630  if (_different_fill_styles && i < NAUTOCOLORS) {
2631  return auto_styles[i];
2632  } else {
2633  return _stack_fill_style;
2634  }
2635 }
2636 
2637 //*********************************************************
2638 void DrawingToolsBase::CreateLegend(const std::string& uopt){
2639 //*********************************************************
2640 
2641 
2642  if (drawUtils::CheckInternalOption(uopt,"NOCREATELEG") || drawUtils::CheckOption(uopt,"NOLEG") ) return;
2643 
2644  // save the current legend size
2645  double sizex = _legendSize[0];
2646  double sizey = _legendSize[1];
2647 
2648  if (drawUtils::CheckInternalOption(uopt,"SMALLLEG") ) {
2649  // SetLegendSize(0.08,0.05);
2650  SetLegendSize(_legendSmallSize[0],_legendSmallSize[1]);
2651  }
2652 
2653 
2654  _legends.push_back(new TLegend(_legendParam[0],_legendParam[1],_legendParam[2],_legendParam[3]));
2655  _legends.back()->SetShadowColor(0);
2656  _legends.back()->SetFillColor(0);
2657  _drawleg = true;
2658 
2659  if (drawUtils::CheckOption(uopt,"PUR"))
2660  _legends.back()->SetTextAlign(32);
2661  else
2662  _legends.back()->SetTextAlign(12);
2663 
2664  SetLegendSize(sizex,sizey);
2665 }
2666 
2667 //*********************************************************
2668 std::string DrawingToolsBase::GetUniqueName(const std::string& name) {
2669 //*********************************************************
2670  std::stringstream unique;
2671  unique << _unique++;
2672  TString name2 = name;
2673  name2 = name2.ReplaceAll("(","_");
2674  name2 = name2.ReplaceAll(")","_");
2675  return std::string(name2.Data()) + "_" + unique.str();
2676 }
2677 
2678 //*********************************************************
2679 TH1_h* DrawingToolsBase::GetHisto(TTree* tree, const std::string& name, const std::string& var, int nx, double* xbins,
2680  const std::string& cut, const std::string& root_opt, const std::string& opt, double scale, bool scale_errors, int toy_ref){
2681 //*********************************************************
2682 
2683  HistoStack* hs = NULL;
2684  return GetHisto(hs,tree,name,var,nx,xbins,cut,root_opt,opt,scale,scale_errors,toy_ref);
2685 }
2686 
2687 //*********************************************************
2688 TH1_h* DrawingToolsBase::GetHisto(HistoStack* hs, TTree* tree, const std::string& name, const std::string& var, int nx, double* xbins,
2689  const std::string& cut, const std::string& root_opt, const std::string& opt, double scale, bool scale_errors, int toy_ref){
2690 //*********************************************************
2691 
2692  TH1_h* hsyst = NULL;
2693  return GetHisto(hs,tree,name,var,nx,xbins,cut,root_opt,opt,hsyst,scale,scale_errors,toy_ref);
2694 }
2695 
2696 //*********************************************************
2697 TH1_h* DrawingToolsBase::GetHisto(HistoStack* hs, TTree* tree, const std::string& name, const std::string& var, int nx, double* xbins,
2698  const std::string& cut, const std::string& root_opt, const std::string& opt, TH1_h*& hsyst, double scale, bool scale_errors, int toy_ref){
2699 //*********************************************************
2700 
2701  // tree: the input tree
2702  // name: name of the histogram
2703  // var: variable to be plotted
2704  // nx: number of bins
2705  // xbins: vector of variable bins
2706  // cut: cut to be applied when projecting the tree into the histo
2707  // opt: plotting option (the ones of root + several specific to these tools)
2708  // scale: scale factor for the histogram (useful when comparing different data samples)
2709  // scale_errors: specify whether errors have to be scaled as well
2710  // toy_ref: the reference toy index
2711 
2712 
2713  (void)root_opt; // root_opt not used here
2714 
2715  std::string uopt = drawUtils::ToUpper(opt);
2716  std::string name2 = GetUniqueName(name);
2717 
2718  std::string cut2=FormatCut(cut);
2719 
2720  // Don't show -999
2721  if (drawUtils::CheckOption(uopt,"NODEFAULT"))
2722  cut2 = cut2 + " && (" + var + "!=-999)";
2723 
2724  // Only plot the reference toy when it is indicated (toy_ref>-1)
2725  if (toy_ref>-1){
2726  std::stringstream stoy_ref;
2727  stoy_ref << toy_ref;
2728  cut2 = cut2 + " && toy_index=="+stoy_ref.str();
2729  }
2730 
2731  // Apply event weights
2732  std::string cutp = weightTools::ApplyWeights(tree,cut,(uopt+" NOTOYW").c_str());
2733  std::string cut2p = weightTools::ApplyWeights(tree,cut2,uopt);
2734 
2735  // Create an histo and project the tree (only statistical errors)
2736  TH1_h* hstat = new TH1_h(name2.c_str(),"all",nx,xbins);
2737  _saved_histos.push_back(hstat);
2738 
2739  // Deal with overflow and underflow
2740  std::string newvar = var;
2741  if (drawUtils::CheckOption(uopt,"OVER")) {
2742  std::stringstream s;
2743  s << "((" << newvar << "<" << xbins[nx] << ")*(" << newvar << "))+((" << newvar << ">=" << xbins[nx] << ")*(" << (xbins[nx]+xbins[nx-1])/2. << "))";
2744  newvar = s.str();
2745  }
2746  if (drawUtils::CheckOption(uopt,"UNDER")) {
2747  std::stringstream s;
2748  s << "((" << newvar << ">" << xbins[0] << ")*(" << newvar << "))+((" << newvar << "<=" << xbins[0] << ")*(" << (xbins[0]+xbins[1])/2. << "))";
2749  newvar = s.str();
2750  }
2751 
2752  tree->Project(name2.c_str(),newvar.c_str(),cut2p.c_str());
2753 
2754  // Put the appropriate errors into the histogram
2755  if (!drawUtils::CheckInternalOption(uopt,"CAT"))
2756  FillHistoErrors(NULL, hs, NULL, tree,name2,var,nx,xbins,cutp,cutp,uopt,1,hstat,hsyst);
2757 
2758  else if(drawUtils::CheckInternalOption(uopt,"MATRIX"))
2759  UpdateSystInfo(NULL, hs, NULL, tree, var, nx, xbins, cutp, cutp, uopt,1);
2760 
2761  // scale the histo if requested
2762  ScaleHisto(hstat,scale,scale_errors);
2763 
2764  return hstat;
2765 }
2766 
2767 //*********************************************************
2768 TH2_h* DrawingToolsBase::GetHisto(TTree* tree, const std::string& name, const std::string& var, int nx, double* xbins, int ny, double* ybins,
2769  const std::string& cut, const std::string& root_opt, const std::string& opt, double scale, bool scale_errors, int toy_ref){
2770 //*********************************************************
2771 
2772  // tree: the input tree
2773  // name: name of the histogram
2774  // var: variable to be plotted
2775  // nx: number of bins in x
2776  // xbins: vector of variable bins in x
2777  // nx: number of bins in y
2778  // xbins: vector of variable bins in y
2779  // cut: cut to be applied when projecting the tree into the histo
2780  // opt: plotting option (the ones of root + several specific to these tools)
2781  // scale: scale factor for the histogram (useful when comparing different data samples)
2782  // scale_errors: specify whether errors have to be scaled as well
2783  // toy_ref: the reference toy index
2784 
2785  (void)root_opt; // root_opt not used here
2786 
2787  std::string name2 = GetUniqueName(name);
2788  std::string uopt = drawUtils::ToUpper(opt);
2789 
2790  // Only plot the reference toy when it is indicated (toy_ref>-1)
2791  std::string cut2 = FormatCut(cut);
2792  if (toy_ref>-1){
2793  std::stringstream stoy_ref;
2794  stoy_ref << toy_ref;
2795  cut2 = (cut+" && toy_index=="+stoy_ref.str()).c_str();
2796  }
2797 
2798  // Apply event weights
2799  std::string cut2p = weightTools::ApplyWeights(tree,cut2,uopt);
2800 
2801  // Create an histo and project the tree (only statistical errors)
2802  TH2_h* hall = new TH2_h(name2.c_str(),"all",nx,xbins,ny,ybins);
2803  _saved_histos2D.push_back(hall);
2804  tree->Project(name2.c_str(),var.c_str(),cut2p.c_str());
2805 
2806  // Put the appropriate errors into the histogram
2807  // FillHistoErrors(tree,name2,var,nx,xbins,cut, opt,hall);
2808 
2809  // scale the histo if requested
2810  ScaleHisto(hall,scale,scale_errors);
2811 
2812 
2813  return hall;
2814 }
2815 
2816 //*********************************************************
2817 TH1_h* DrawingToolsBase::GetRatioHisto(HistoStack* hs1, HistoStack* hs2, const std::string& opt){
2818 //*********************************************************
2819 
2820  std::string uopt = drawUtils::ToUpper(opt);
2821 
2822  if (!hs1->GetTotal1D()){
2823  std::cout << "ERROR. numerator does not exist !!!" << std::endl;
2824  return NULL;
2825  }
2826 
2827  if (!hs2->GetTotal1D()){
2828  std::cout << "ERROR. denominator does not exist !!!" << std::endl;
2829  return NULL;
2830  }
2831 
2832 
2833  // Histogram for numerator
2834  TH1_h* h1 = hs1->GetTotal1D();
2835  TH1_h* h2 = hs2->GetTotal1D();
2836 
2837  h1->Sumw2();
2838  h1->Sumw2();
2839 
2840  // compute the ratio
2841  TH1_h* ratio = new TH1_h(*h1);
2842  std::string name2 = GetUniqueName("ratio");
2843  ratio->SetName(name2.c_str());
2844  _saved_histos.push_back(ratio);
2845  ratio->Divide(h1,h2);
2846 
2847  // Put the errors into the ratio
2848  FillHistoErrors(hs1, hs2, ratio, uopt);
2849 
2850  return ratio;
2851 }
2852 
2853 //*********************************************************
2854 TH1_h* DrawingToolsBase::GetRatioHisto(TTree* tree1, TTree* tree2, const std::string& name, const std::string& var, int nx, double* xbins,
2855  const std::string& cut1, const std::string& cut2,
2856  const std::string& root_opt, const std::string& opt, double norm, double scale, bool scale_errors, int toy_ref){
2857 //*********************************************************
2858 
2859  // tree1: the numerator input tree
2860  // tree2: the denominator input tree
2861  // name: name of the histogram
2862  // var: variable to be plotted
2863  // nx: number of bins
2864  // xbins: vector of variable bins
2865  // cut1: cut to be applied when projecting tree1 into the histo
2866  // cut2: cut to be applied when projecting tree2 into the histo
2867  // opt: plotting option (the ones of root + several specific to these tools)
2868  // norm: normalization factor for second tree
2869  // scale: scale factor for the histogram (useful when comparing different data samples)
2870  // scale_errors: specify whether errors have to be scaled as well
2871  // toy_ref: the reference toy index
2872 
2873  (void)root_opt; // root_opt not used here
2874  (void)scale; // Scaling not used
2875  (void)scale_errors; // Scaling not used
2876 
2877  std::string name2 = GetUniqueName(name);
2878  std::string uopt = drawUtils::ToUpper(opt);
2879 
2880  std::string cut1p = FormatCut(cut1);
2881  std::string cut2p = FormatCut(cut2);
2882 
2883  // Don't show -999
2884  if (drawUtils::CheckOption(uopt,"NODEFAULT")){
2885  cut1p = cut1p + " && (" + var + "!=-999)";
2886  cut2p = cut2p + " && (" + var + "!=-999)";
2887  }
2888 
2889 
2890  // Only plot the reference toy when it is indicated (toy_ref>-1)
2891 
2892  if (toy_ref>-1){
2893  std::stringstream stoy_ref;
2894  stoy_ref << toy_ref;
2895  cut1p = (cut1p+" && toy_index=="+stoy_ref.str()).c_str();
2896  cut2p = (cut2p+" && toy_index=="+stoy_ref.str()).c_str();
2897  }
2898 
2899  // Apply event weights
2900  std::string cut1pp = weightTools::ApplyWeights(tree1,cut1p,uopt);
2901  std::string cut2pp = weightTools::ApplyWeights(tree2,cut2p,uopt);
2902 
2903  // Deal with overflow and underflow
2904  std::string newvar = var;
2905  if (drawUtils::CheckOption(uopt,"OVER")) {
2906  std::stringstream s;
2907  s << "((" << newvar << "<" << xbins[nx] << ")*(" << newvar << "))+((" << newvar << ">=" << xbins[nx] << ")*(" << (xbins[nx]+xbins[nx-1])/2. << "))";
2908  newvar = s.str();
2909  }
2910  if (drawUtils::CheckOption(uopt,"UNDER")) {
2911  std::stringstream s;
2912  s << "((" << newvar << ">" << xbins[0] << ")*(" << newvar << "))+((" << newvar << "<=" << xbins[0] << ")*(" << (xbins[0]+xbins[1])/2. << "))";
2913  newvar = s.str();
2914  }
2915 
2916  // Create an histo and project the tree (only statistical errors)
2917  // TH1_h ratio1(GetUniqueName("ratio1").c_str(),"ratio1",nx,xbins);
2918  TH1_h ratio1("ratio1","ratio1",nx,xbins);
2919  tree1->Project("ratio1",var.c_str(),cut1pp.c_str());
2920 
2921  // TH1_h ratio2(GetUniqueName("ratio2").c_str(),"ratio2",nx,xbins);
2922  TH1_h ratio2("ratio2","ratio2",nx,xbins);
2923  tree2->Project("ratio2",var.c_str(),cut2pp.c_str());
2924 
2925  // scale the denominator
2926  ScaleHisto(&ratio2,norm);
2927 
2928  ratio1.Sumw2();
2929  ratio2.Sumw2();
2930 
2931  // compute the ratio
2932  TH1_h* ratio = new TH1_h(ratio1);
2933  ratio->SetName(name2.c_str());
2934  _saved_histos.push_back(ratio);
2935 
2936  ratio->Divide(&ratio1,&ratio2);
2937 
2938  // Put the appropriate errors into the histogram
2939  TH1_h* hsyst;
2940  FillHistoErrors(NULL,NULL,tree1,tree2,name2,var,nx,xbins,cut1,cut2,uopt,norm,ratio,hsyst);
2941 
2942  return ratio;
2943 }
2944 
2945 
2946 //**************************************************
2947 void DrawingToolsBase::FillHistoErrors(HistoStack* hs1, HistoStack* hs2, TH1_h* histo, const std::string uopt){
2948 //**************************************************
2949 
2950  (void)hs1;
2951  (void)hs2;
2952  (void)histo;
2953  (void)uopt;
2954 
2955 }
2956 
2957 //**************************************************
2958 void DrawingToolsBase::FillGraphErrors(HistoStack* hs1, HistoStack* hs2, TGraphAsymmErrors* graph, const std::string uopt){
2959 //**************************************************
2960 
2961  (void)hs1;
2962  (void)hs2;
2963  (void)graph;
2964  (void)uopt;
2965 }
2966 
2967 //**************************************************
2968 void DrawingToolsBase::FillHistoErrors(HistoStack* hs1, HistoStack* hs2, TTree* tree1,TTree* tree2, const std::string& name, const std::string& var, int nx, double* xbins,
2969  const std::string& cut1, const std::string& cut2, const std::string& opt, double norm, TH1_h* hstat, TH1_h*& hsyst) {
2970 //**************************************************
2971  // TODO: This function isn't implemented. We just use all the variables to avoid warnings.
2972  (void)hs1;
2973  (void)hs2;
2974  (void)tree1;
2975  (void)tree2;
2976  (void)name;
2977  (void)var;
2978  (void)nx;
2979  (void)xbins;
2980  (void)cut1;
2981  (void)cut2;
2982  (void)norm;
2983  (void)opt;
2984  (void)hstat;
2985  (void)hsyst;
2986 }
2987 
2988 //**************************************************
2989 void DrawingToolsBase::UpdateSystInfo(HistoStack* hs1, HistoStack* hs2, TTree* tree1,TTree* tree2, const std::string& var, int nx, double* xbins,
2990  const std::string& cut1, const std::string& cut2, const std::string& opt, double norm) {
2991 //**************************************************
2992  // TODO: This function isn't implemented. We just use all the variables to avoid warnings.
2993  (void)hs1;
2994  (void)hs2;
2995  (void)tree1;
2996  (void)tree2;
2997  (void)var;
2998  (void)nx;
2999  (void)xbins;
3000  (void)cut1;
3001  (void)cut2;
3002  (void)norm;
3003  (void)opt;
3004 }
3005 
3006 
3007 
3008 
3009 //**************************************************
3010 TH1_h* DrawingToolsBase::GetEventsVSCut(TTree* tree, const std::string& name, const std::string& cut_norm, int isel, int ibranch, int& first_cut, int& last_cut,
3011  const std::string& root_opt, const std::string& opt){
3012 //**************************************************
3013 
3014  // Check if selection exists
3015  if (!sel().GetSelection(isel,true)) return NULL;
3016 
3017  (void)root_opt; // root_opt not used here
3018  std::string uopt = drawUtils::ToUpper(opt);
3019 
3020  // Read the steps from the config tree
3021  // ReadSteps(_config_file);
3022 
3023  if (last_cut>(int)(sel().GetSelection(isel)->GetNCuts(ibranch)-1) || last_cut == -1) last_cut=sel().GetSelection(isel)->GetNCuts(ibranch)-1;
3024  if (first_cut<-1 || first_cut>last_cut ) first_cut=-1;
3025 
3026  double xmin=first_cut-0.5;
3027  double xmax=last_cut+0.5;
3028  int nx = (int)(xmax-xmin);
3029  double xbins[NMAXBINS];
3030 
3031  // Create an histo and project the tree (only statistical errors)
3032  TH1_h* hall = new TH1_h(GetUniqueName(name).c_str(),"events",nx,GetVariableBins(nx,xmin,xmax,xbins));
3033  _saved_histos.push_back(hall);
3034 
3035  std::string cut0 = FormatCut(cut_norm);
3036 
3037  std::vector<StepBase*> cuts = sel().GetSelection(isel)->GetCutsInBranch(ibranch);
3038 
3039  std::cout << std::endl <<"-------- List of selected cuts for branch " << ibranch;
3040  std::cout << ": #cuts = " << cuts.size() << " -------" << std::endl;
3041 
3042  for (int i=0;i<nx;i++ ){
3043  int icut = first_cut+i;
3044 
3045  std::stringstream sbranch;
3046  sbranch << ibranch;
3047  std::stringstream ssel;
3048  ssel << isel;
3049  std::stringstream scut;
3050  scut << icut;
3051 
3052  Int_t accumLevelCut = std::max(icut,_minAccumLevelToSave-1);
3053  std::stringstream sAccumLevelCut;
3054  sAccumLevelCut << accumLevelCut;
3055 
3056  std::string cut;
3057  if (!strcmp(tree->GetName(), "truth")){
3058  if (sel().GetNEnabledSelections()>1)
3059  cut= cut0 + " && accum_level["+ssel.str()+"]["+sbranch.str()+"]>"+scut.str();
3060  else
3061  cut= cut0 + " && accum_level["+sbranch.str()+"]>"+scut.str();
3062  }
3063  else{
3064  if (sel().GetNEnabledSelections()>1)
3065  cut= cut0 + " && accum_level[]["+ssel.str()+"]["+sbranch.str()+"]>"+sAccumLevelCut.str();
3066  else
3067  cut= cut0 + " && accum_level[]["+sbranch.str()+"]>"+sAccumLevelCut.str();
3068  }
3069 
3070  // Apply event weights
3071  std::string cutp = weightTools::ApplyWeights(tree,cut,uopt);
3072 
3073  TH1_h htemp("temp","temp",1,0,1);
3074  tree->Project("temp","0.5",cutp.c_str());
3075 
3076  double ball = (double)htemp.Integral();
3077  hall->SetBinContent(i+1,ball);
3078 
3079  if (icut==-1)
3080  std::cout << ball << " events before any cut " << std::endl;
3081  else
3082  std::cout << ball << " events after cut " << icut << ": " << cuts[icut]->Title() << std::endl;
3083  }
3084 
3085  std::cout << "---------------------------------------------------------------" << std::endl << std::endl;
3086 
3087  return hall;
3088 
3089 }
3090 
3091 
3092 //*********************************************************
3093 TH1_h* DrawingToolsBase::AddErrorsInQuadrature(TH1_h* h1,TH1_h* h2, const std::string& slevel){
3094 //*********************************************************
3095 
3096  // Add the errors of histograms h1 and h2 in quadrature.
3097  // The contents are the ones of histogram h1
3098 
3099  TH1_h *h3 = new TH1_h(*h1);
3100  std::string name = "errors_quad_sum"+slevel;
3101  h3->SetName(name.c_str());
3102  _saved_histos.push_back(h3);
3103 
3104  // Set the sqrt of the diagonal as error
3105  for (int i=0;i<h1->GetNbinsX();i++){
3106  if (h1 && h2){
3107  // Require same number of bins
3108  if (h1->GetNbinsX() != h2->GetNbinsX()) return NULL;
3109 
3110  double err = sqrt(pow(h1->GetBinError(i+1),2)+pow(h2->GetBinError(i+1),2));
3111  h3->SetBinError(i+1,err);
3112  h3->SetBinContent(i+1,h1->GetBinContent(i+1));
3113  }
3114  else if (h1){
3115  h3->SetBinError(i+1,h1->GetBinError(i+1));
3116  h3->SetBinContent(i+1,h1->GetBinContent(i+1));
3117  }
3118  else if (h2){
3119  h3->SetBinError(i+1,h2->GetBinError(i+1));
3120  h3->SetBinContent(i+1,h2->GetBinContent(i+1));
3121  }
3122  }
3123 
3124  return h3;
3125 }
3126 
3127 //*********************************************************
3128 std::string DrawingToolsBase::FormatCut(const std::string& cut) {
3129 //*********************************************************
3130 
3131  // In the case the cut is empty
3132  std::string cut2=cut;
3133  if (cut2=="") cut2="1==1";
3134 
3135  // To avoid problems with || conditions
3136  cut2 ="("+cut2+")";
3137  return cut2;
3138 }
3139 
3140 //*********************************************************
3141 double DrawingToolsBase::GetEntries(TTree* tree, const std::string& cut){
3142 //*********************************************************
3143  TH1_h *ht = new TH1_h("temp"," ",10,0.,10.);
3144 
3145  std::string cut1 = FormatCut(cut);
3146 
3147  if (tree->FindLeaf("toy_ref"))
3148  cut1 = cut1 + "&& toy_index == toy_ref";
3149 
3150  // cut1 = "("+cut1+")"+w;
3151 
3152 
3153  cut1 = weightTools::ApplyWeights(tree,cut1,"");
3154 
3155  tree->Project("temp","1.",cut1.c_str());
3156 
3157  double TotalEntries = ht->GetSumOfWeights();
3158  delete ht;
3159 
3160  return TotalEntries;
3161 }
3162 
3163 //*********************************************************
3164 double DrawingToolsBase::GetEntries(TTree* tree, const std::string& cut, const std::string& var, const std::string& opt, int toy_ref){
3165 //*********************************************************
3166  // tree: the input tree
3167  // var: variable to be plotted
3168  // cut: cut to be applied when projecting the tree into the histo
3169  // opt: plotting option (the ones of root + several specific to these tools)
3170  // toy_ref: the reference toy index
3171 
3172  std::string uopt = drawUtils::ToUpper(opt);
3173 
3174  // Check that all user options are valid
3175  if (!drawUtils::ContainValidOptions(uopt)) return 0;
3176 
3177  // Only plot the reference toy when it is indicated (toy_ref>-1)
3178  std::string cut2 = FormatCut(cut);
3179 
3180  // Don't show -999
3181  if (drawUtils::CheckOption(uopt,"NODEFAULT")) {
3182  cut2 += "&&(" + var + "!=-999)";
3183  }
3184 
3185  if (toy_ref>-1){
3186  std::stringstream stoy_ref;
3187  stoy_ref << toy_ref;
3188  cut2 = (cut+" && toy_index=="+stoy_ref.str()).c_str();
3189  }
3190 
3191  // Apply event weights
3192  std::string cut2p = weightTools::ApplyWeights(tree,cut2,uopt);
3193 
3194  // Create an histo and project the tree (only statistical errors)
3195  double xbins[NMAXBINS];
3196  TH1_h* hall = new TH1_h("temp","all",10,GetVariableBins(10,-5.,5.,xbins));
3197  _saved_histos.push_back(hall);
3198 
3199  // Include all possible values of "var" ( newvar = var*var/(var*var+10), so it's always between 0 and 1 )
3200  std::string newvar = var;
3201  std::stringstream s;
3202  s << "((" << newvar << ")*(" << newvar << ")/((" << newvar << ")*(" << newvar << ")+10.))";
3203  newvar = s.str();
3204 
3205  tree->Project("temp",newvar.c_str(),cut2p.c_str());
3206 
3207  // Return sum of all weights
3208  double TotalEntries = hall->GetSumOfWeights();
3209  delete hall;
3210 
3211  return TotalEntries;
3212 }
3213 
3214 //*********************************************************
3215 void DrawingToolsBase::PrintPurities(TTree* tree, const std::string& categ, const std::string& cut, double events_ratio){
3216 //*********************************************************
3217 
3218  // Read the categories from the config tree
3219  ReadCategories(_config_file);
3220 
3221  if (!cat().HasCategory(categ) || categ =="all" ) {
3222  std::cout << " ------------------------------------------ " << std::endl;
3223  std::cout << " Invalid category " << categ << std::endl;
3224  std::cout << " ------------------------------------------ " << std::endl;
3225  return;
3226  }
3227 
3228  int i=0;
3229 
3230  TH1_h *ht = new TH1_h("temp"," ",10,0.,10.);
3231 
3232  std::string cut1 = FormatCut(cut);
3233  if (tree->FindLeaf("toy_ref"))
3234  cut1 = cut1 + " && toy_index == toy_ref";
3235 
3236  // std::string cut1w = "("+cut1+")"+w;
3237  std::string cut1w = weightTools::ApplyWeights(tree,cut,"");
3238 
3239  tree->Project("temp","1.",cut1w.c_str());
3240 
3241  double TotalEntries = ht->GetSumOfWeights();
3242  delete ht;
3243 
3244 
3245  std::cout << " --------------------------------------------------------" << std::endl;
3246  std::cout << " Purities: " << std::endl;
3247  std::cout << " Category: " << categ << std::endl;
3248  std::cout << " Cut: " << cut << std::endl;
3249  std::cout << " Events: " << std::setprecision(8) << TotalEntries << std::endl;
3250  std::cout << " --------------------------------------------------------" << std::endl;
3251 
3252  // define stuff to print % on the legend
3253  std::ostringstream percstr, str_tmp;
3254  const int ntypes = (const int)cat().GetCategoryTypes(categ).size();
3255  std::string* cattypes = new std::string[ntypes]; // to initialize with const dimension
3256  int* catcodes = new int[ntypes]; // to initialize with const dimension
3257  int* catcolors = new int[ntypes]; // to initialize with const dimension
3258  int itype=0;
3259 
3260  std::vector<TrackTypeDefinition>::iterator it;
3261  for (it=cat().GetCategoryTypes(categ).begin();it!=cat().GetCategoryTypes(categ).end();it++, i++){
3262  std::string type = it->_name;
3263  std::string code = drawUtils::GetString(it->_code);
3264 
3265  std::string cut2 = cut1+"&&"+categ+"=="+code;
3266 
3267  cut2 = weightTools::ApplyWeights(tree,cut2,"");
3268  // cut2 = "("+cut2+")"+w;
3269 
3270  TH1_h *ht1 = new TH1_h("temp1"," ",10,0.,10.);
3271 
3272  tree->Project("temp1","1.",cut2.c_str());
3273 
3274  double caseEntries = ht1->GetSumOfWeights();
3275  double frac = caseEntries/TotalEntries;
3276  double nev1 = caseEntries * events_ratio;
3277  delete ht1;
3278 
3279  std::cout << std::setprecision(8) << std::setw(25) << type << std::setw(12) << frac*100. << " % (" << nev1 << " events)" << std::endl;
3280 
3281  // create categ_temp to print % on the legend
3282  percstr.str(std::string()); // to clear it
3283  percstr << std::setprecision(2) << std::fixed << frac*100.; // round to 2 decimal
3284  str_tmp.str(std::string()); // to clear it
3285  str_tmp << it->_name << std::setw(8) << percstr.str() << " %"; // tab
3286  cattypes[itype] = str_tmp.str();
3287  catcodes[itype] = it->_code;
3288  catcolors[itype] = it->_color;
3289  itype++;
3290  }
3291 
3292  // create categories with % in the name
3293  bool multi = cat().GetCategory(categ).IsMultiType();
3294  bool noWarning = true, addNOTRUTH = false, addSAND = false;
3295  cat().AddCategory(categ+"_withPurities",itype,cattypes,catcodes,catcolors,multi,noWarning,addNOTRUTH,addSAND);
3296 
3297  std::cout << " --------------------------------------------------------" << std::endl;
3298  std::cout << std::endl;
3299 
3300  return;
3301 }
3302 
3303 //********************************************************************
3304 void DrawingToolsBase::ChangeCategory(const std::string& categ_name, int ntypes, std::string* names, int* codes, int* colors){
3305 //********************************************************************
3306 
3307  // Read the categories from the config tree
3308  ReadCategories(_config_file);
3309 
3310  bool multi = false;
3311  bool noWarning = false;
3312 
3313  // don't add automatic categories
3314  bool addNOTRUTH=false;
3315  bool addSAND=false;
3316 
3317 
3318  cat().AddCategory(categ_name, ntypes, names, codes, colors, multi, noWarning, addNOTRUTH, addSAND);
3319 }
3320 
3321 //********************************************************************
3322 bool DrawingToolsBase::HasCategory(const std::string& categ){
3323 //********************************************************************
3324 
3325  // Read the categories from the config tree
3326  ReadCategories(_config_file);
3327 
3328  if (categ!="all"){
3329  if (!cat().HasCategory(categ)){
3330  std::cout << "Category '" << categ << "' does not exist" << std::endl;
3331  return false;
3332  }
3333  // else DumpCategory(categ);
3334  }
3335  return true;
3336 }
3337 
3338 
3339 //*********************************************************
3340 void DrawingToolsBase::PrintEventNumbers(TTree* tree, const std::string& cut, const std::string& file, int toy_ref){
3341 //*********************************************************
3342 
3343  // tree: the input tree
3344  // cut: cut to be applied when projecting the tree into the histo
3345  // file: the reference toy index
3346  // toy_ref: the reference toy index
3347 
3348  if ( !( drawUtils::TreeHasVar(tree, "evt") && drawUtils::TreeHasVar(tree, "run") && drawUtils::TreeHasVar(tree, "subrun"))){
3349  std::cout << " Invalid tree. It is missing one or all of the following branches: evt, run, subrun " << std::endl;
3350  return;
3351  }
3352 
3353  // Only plot the reference toy when it is indicated (toy_ref>-1)
3354  std::string cut2 = FormatCut(cut);
3355  if (toy_ref>-1){
3356  std::stringstream stoy_ref;
3357  stoy_ref << toy_ref;
3358  cut2 = (cut+" && toy_index=="+stoy_ref.str()).c_str();
3359  }
3360 
3361  // Apply event weights
3362  std::string cutp = weightTools::ApplyWeights(tree,cut2,"");
3363 
3364  std::ofstream output;
3365  if (file!="")
3366  output.open (file.c_str());
3367 
3368  // Copy the entries we are interested into another tree
3369  char* tmpFilename= new char;
3370  strcpy(tmpFilename,"/tmp/XXXXXX");
3371  mktemp (tmpFilename);
3372  TFile *tmpFile = new TFile(tmpFilename, "RECREATE");
3373  TTree *tmpTree = tree->CopyTree(cutp.c_str());
3374  int run, subrun, evt;
3375  tmpTree->SetBranchAddress("run", &run);
3376  tmpTree->SetBranchAddress("subrun", &subrun);
3377  tmpTree->SetBranchAddress("evt", &evt);
3378  // Print out the event, run and subrun numbers
3379  Long64_t nentries = tmpTree->GetEntries();
3380  if (file=="")
3381  std::cout<<"# run,subrun,evt"<<std::endl;
3382  for (Long64_t i=0;i<nentries; i++) {
3383  tmpTree->GetEntry(i);
3384  if (file!="")
3385  output<<run<<","<<subrun<<","<<evt<<std::endl;
3386  else
3387  std::cout<<run<<","<<subrun<<","<<evt<<std::endl;
3388  }
3389  // Clean up
3390  output.close();
3391  tmpFile->Close();
3392  remove(tmpFilename);
3393 
3394 }
3395 
3396 //*********************************************************
3397 void DrawingToolsBase::DrawCutLineVertical(double xval, bool addarrow, std::string arrowopt, double arrowpos) {
3398 //*********************************************************
3399 
3400  double ymin = gPad->PadtoY(gPad->GetUymin());
3401  double ymax = gPad->PadtoY(gPad->GetUymax());
3402  DrawCutLine(xval, ymin, xval, ymax);
3403 
3404  if (addarrow) {
3405  std::string uarrowdir = drawUtils::ToUpper(arrowopt);
3406  double deltax = xval-gPad->PadtoX( gPad->XtoPad(xval)-(gPad->GetUxmax()-gPad->GetUxmin())/20.);
3407 
3408  if (uarrowdir.find("L") != std::string::npos) {
3409  deltax *= -1;
3410  }
3411 
3412  // It needs this to work in LogY scale
3413  double yarr = gPad->PadtoY((gPad->GetUymax()-gPad->GetUymin())*arrowpos+gPad->GetUymin());
3414  double xarrmax = xval + deltax;
3415  DrawCutArrow(xval, yarr, xarrmax, yarr);
3416  }
3417 }
3418 
3419 //*********************************************************
3420 void DrawingToolsBase::DrawCutLineHorizontal(double yval, bool addarrow, std::string arrowdir, double arrowpos) {
3421 //*********************************************************
3422  double xmin = gPad->PadtoX(gPad->GetUxmin());
3423  double xmax = gPad->PadtoX(gPad->GetUxmax());
3424  DrawCutLine(xmin, yval, xmax, yval);
3425 
3426  if (addarrow) {
3427  std::string uarrowdir = drawUtils::ToUpper(arrowdir);
3428  double deltay = yval-gPad->PadtoY( gPad->YtoPad(yval)-(gPad->GetUymax()-gPad->GetUymin())/20.);
3429 
3430  if (uarrowdir.find("D") != std::string::npos) {
3431  deltay *= -1;
3432  }
3433 
3434  // It needs this to work in LogX scale
3435  double xarr = gPad->PadtoX((gPad->GetUxmax()-gPad->GetUxmin())*arrowpos+gPad->GetUxmin());
3436  double yarrmax = yval + deltay;
3437  DrawCutArrow(xarr, yval, xarr, yarrmax);
3438  }
3439 }
3440 
3441 //*********************************************************
3442 void DrawingToolsBase::DrawCutLine(double xmin, double ymin, double xmax, double ymax) {
3443 //*********************************************************
3444  TLine* l = new TLine(xmin, ymin, xmax, ymax);
3445 
3446  l->SetLineColor(_cut_line_col);
3447  l->SetLineWidth(_cut_line_width);
3448  _cut_lines.push_back(l);
3449  l->Draw();
3450 
3451  if (_drawleg && _legends.size() > 0 && gPad->FindObject(_legends.back())) {
3452  _legends.back()->Draw();
3453  }
3454 }
3455 
3456 //*********************************************************
3457 void DrawingToolsBase::DrawCutArrow(double xmin, double ymin, double xmax, double ymax) {
3458 //*********************************************************
3459  TArrow* arr = new TArrow(xmin, ymin, xmax, ymax, 0.02, "|>");
3460  arr->SetLineColor(_cut_line_col);
3461  arr->SetFillColor(_cut_line_col);
3462  arr->SetLineWidth(_cut_line_width);
3463  _cut_lines.push_back(arr);
3464  arr->Draw();
3465 
3466  if (_drawleg && _legends.size() > 0 && gPad->FindObject(_legends.back())) {
3467  _legends.back()->Draw();
3468  }
3469 }
3470 
3471 //*********************************************************
3472 void DrawingToolsBase::DrawCutRegion(double xmin, double ymin, double xmax, double ymax, std::string opt) {
3473 //*********************************************************
3474  std::string uopt = drawUtils::ToUpper(opt);
3475 
3476  if (!drawUtils::CheckOption(uopt,"NOCHOP")) {
3477  xmin = std::max(xmin, gPad->PadtoX(gPad->GetUxmin()));
3478  xmax = std::min(xmax, gPad->PadtoY(gPad->GetUxmax()));
3479  ymin = std::max(ymin, gPad->PadtoX(gPad->GetUymin()));
3480  ymax = std::min(ymax, gPad->PadtoY(gPad->GetUymax()));
3481  }
3482 
3483  if (uopt.find("T")!=std::string::npos) {
3484  DrawCutLine(xmin, ymax, xmax, ymax);
3485  }
3486  if (uopt.find("B")!=std::string::npos) {
3487  DrawCutLine(xmin, ymin, xmax, ymin);
3488  }
3489  if (uopt.find("L")!=std::string::npos) {
3490  DrawCutLine(xmin, ymin, xmin, ymax);
3491  }
3492  if (uopt.find("R")!=std::string::npos) {
3493  DrawCutLine(xmax, ymin, xmax, ymax);
3494  }
3495 }
3496 
3497 //*********************************************************
3498 void DrawingToolsBase::SetMinY(double minY) {
3499 //*********************************************************
3500 
3501  if (minY<=0 && _logY) {
3502  std::cout << "Cannot set minimum <= 0 in logY scale! Call SetLogY(false) before calling SetMinY()!" << std::endl;
3503  return;
3504  }
3505  _minY = minY;
3506 }
3507 
3508 //*********************************************************
3509 void DrawingToolsBase::SetLogY(bool logY) {
3510 //*********************************************************
3511  if (logY) {
3512  if (_minY > 0) {
3513  _logY = logY;
3514  } else {
3515  std::cout << "Cannot set a log-scale if minimum is <= 0! Call SetMinY() before calling SetLogY()!" << std::endl;
3516  _logY = false;
3517  }
3518  } else {
3519  _logY = false;
3520  }
3521 }
3522 
3523 //*********************************************************
3524 void DrawingToolsBase::SetLogZ(bool logZ) {
3525 //*********************************************************
3526  _logZ = logZ;
3527 }
3528 
3529 //*********************************************************
3530 void DrawingToolsBase::SetAutoColors(int colors[],int ncolors){
3531 //*********************************************************
3532  for (Int_t i=0;i<NMAXAUTOCOLORS;i++){
3533  if (i<ncolors) _auto_colors[i]= colors[i];
3534  else _auto_colors[i]= _line_color;
3535  }
3536 }
3537 
3538 //*********************************************************
3539 void DrawingToolsBase::SetAutoMarkers(int markers[], int nmarkers){
3540 //*********************************************************
3541  for (Int_t i=0;i<NMAXAUTOCOLORS;i++){
3542  if (i<nmarkers) _auto_markers[i]= markers[i];
3543  else _auto_markers[i]= _marker_style;
3544  }
3545 }
3546 
3547 //*********************************************************
3548 void DrawingToolsBase::StartDocument(const std::string& title, bool pdf, bool web, const std::string& pdffile, const std::string& webpath) {
3549 //*********************************************************
3550  if (_pdfcanvas) {
3551  delete _pdfcanvas;
3552  }
3553  _pdfpath = "";
3554  _webpath = "";
3555  _webheader = "";
3556  _webbody = "";
3557 
3558  if (web) {
3559  _webpath = webpath;
3560  MakeDirectory(_webpath, 0755);
3561  _webheader += "<html><head><title>" + title + "</title></head><body>\n";
3562  _webheader += "<h2>" + title + "</h2>\n<ol>\n";
3563  _webbody += "</ol>\n";
3564  }
3565  if (pdf) {
3566  _pdfpath = pdffile;
3567 
3568  if (!gPad) {
3569  // User hadn't set up a canvas - create one for them.
3570  // We split it into 2 sections, so we can save useful info
3571  // in the small top "header" bit.
3572  _pdfcanvas = new TCanvas("pdfcanvas", "pdfcanvas", 800, 630);
3573  _headpad = new TPad("header", "header", 0, 0.95, 1, 1, 0);
3574  _headpad->SetNumber(1);
3575  _headpad->Draw();
3576  _bodypad = new TPad("body", "body", 0, 0, 1, 0.95, 0);
3577  _bodypad->SetNumber(2);
3578  _bodypad->Draw();
3579  _pdfcanvas->Draw();
3580  _bodypad->cd();
3581  }
3582 
3583  std::cout << _pdfpath << std::endl;
3584 
3585  gPad->Print((_pdfpath+"[").c_str());
3586  }
3587 }
3588 
3589 //*********************************************************
3590 void DrawingToolsBase::AddDocumentPage(const std::string& name) {
3591 //*********************************************************
3592  if (_webpath != "") {
3593  TString safename = name;
3594  safename = safename.ReplaceAll(" ", "_");
3595  gPad->SaveAs((_webpath + "/" + safename.Data() + ".png").c_str());
3596  _webheader += std::string("<li><a href=\"#") + safename.Data() + "\">" + name + "</a></li>\n";
3597  _webbody += std::string("<p><a name=\"") + safename.Data() + "\"></a>" + name + "</p>\n";
3598  _webbody += std::string("<p><img src=\"") + safename.Data() + ".png\" alt=\"" + name + "\"/></p>\n";
3599  }
3600 
3601  if (_pdfpath != "") {
3602  TVirtualPad* currpad = gPad;
3603 
3604  if (currpad && currpad == _bodypad) {
3605  _headpad->Clear();
3606  _headpad->cd();
3607  TLatex l;
3608  l.SetTextSize(0.5);
3609  l.SetTextAlign(22);
3610  l.DrawLatex(0.5, 0.5, name.c_str());
3611 
3612  _pdfcanvas->cd();
3613  _pdfcanvas->Draw();
3614  _pdfcanvas->Print(_pdfpath.c_str());
3615 
3616  currpad->cd();
3617  } else {
3618  currpad->Print(_pdfpath.c_str());
3619  }
3620  }
3621 }
3622 
3623 //*********************************************************
3625 //*********************************************************
3626  if (_webpath != "") {
3627  _webbody += "</body></html>\n";
3628  std::ofstream outfile;
3629  outfile.open((_webpath+"/index.html").c_str());
3630  outfile << _webheader << _webbody;
3631  outfile.close();
3632  }
3633  if (_pdfpath != "") {
3634  gPad->Print((_pdfpath+"]").c_str());
3635  }
3636 }
3637 
3638 //*********************************************************
3639 int DrawingToolsBase::MakeDirectory(const std::string& path, mode_t mode) {
3640 //*********************************************************
3641  size_t pre = 0, pos;
3642  std::string dir;
3643  std::string s = path;
3644  int mdret;
3645 
3646  if (s[s.size() - 1] != '/') {
3647  // force trailing / so we can handle everything in loop
3648  s += "/";
3649  }
3650 
3651  while ((pos = s.find_first_of("/", pre))) {
3652  dir = s.substr(0, pos++);
3653  pre = pos;
3654  if (dir.size() == 0)
3655  continue; // if leading / first time is 0 length
3656  if ((mdret = mkdir(dir.c_str(), mode)) && errno != EEXIST) {
3657  return mdret;
3658  }
3659  }
3660 
3661  return mdret;
3662 }
3663 
3664 //*********************************************************
3665 void DrawingToolsBase::SetOptStat(Option_t *stat) {
3666 //*********************************************************
3667 
3668  Int_t mode=0;
3669  TString opt = stat;
3670 
3671  if (opt.Contains("n")) mode+=1;
3672  if (opt.Contains("e")) mode+=10;
3673  if (opt.Contains("m")) mode+=100;
3674  if (opt.Contains("M")) mode+=200;
3675  if (opt.Contains("r")) mode+=1000;
3676  if (opt.Contains("R")) mode+=2000;
3677  if (opt.Contains("u")) mode+=10000;
3678  if (opt.Contains("o")) mode+=100000;
3679  if (opt.Contains("i")) mode+=1000000;
3680  if (opt.Contains("I")) mode+=2000000;
3681  if (opt.Contains("s")) mode+=10000000;
3682  if (opt.Contains("S")) mode+=20000000;
3683  if (opt.Contains("k")) mode+=100000000;
3684  if (opt.Contains("K")) mode+=200000000;
3685  if (mode == 1) mode = 1000000001;
3686 
3687  return SetOptStat(mode);
3688 }
3689 
3690 
3691 //*********************************************************
3692 std::string DrawingToolsBase::GetErrorStyle(const std::string& uopt) {
3693 //*********************************************************
3694 
3695  if (drawUtils::CheckOption(uopt,"E0")) return "e0";
3696  else if (drawUtils::CheckOption(uopt,"E1")) return "e1";
3697  else if (drawUtils::CheckOption(uopt,"E2")) return "e2";
3698  else if (drawUtils::CheckOption(uopt,"E3")) return "e3";
3699  else if (drawUtils::CheckOption(uopt,"E4")) return "e4";
3700  else if (drawUtils::CheckOption(uopt,"E5")) return "e5";
3701  else if (drawUtils::CheckOption(uopt,"E6")) return "e6";
3702  else return "";
3703 }
3704 
3705 //********************************************************************
3706 void DrawingToolsBase::DumpConfiguration(const std::string& name){
3707 //********************************************************************
3708 
3709  ConfigurationBase* con = conf().GetConfiguration(name);
3710  if (!con) return;
3711 
3712  con->Dump(syst());
3713 }
3714 
3715 //********************************************************************
3716 void DrawingToolsBase::DrawVariations(const std::string& name, Int_t ipar, int nx, double xmin, double xmax, const std::string& root_opt, const std::string& opt, const std::string& leg){
3717 //********************************************************************
3718 
3719  ConfigurationBase* con = conf().GetConfiguration(name);
3720  if (!con) return;
3721 
3722  std::string uopt = drawUtils::ToUpper(opt);
3723 
3724  // Check that all user options are valid
3725  if (!drawUtils::ContainValidOptions(uopt)) return;
3726 
3727  std::string slevel = GetSameLevel(root_opt);
3728  if (slevel=="0" && leg!="")
3729  CreateLegend();
3730 
3731  // Stat option (entries, MEAN, RMS, and integral)
3732  int statTemp = _stat_option;
3733  SetOptStat(1110);
3734  gStyle->SetOptStat(1110);
3735 
3736  TH1_h* hvar = new TH1_h(GetUniqueName("hvar").c_str(),leg.c_str(),nx,xmin,xmax);
3737  _saved_histos.push_back(hvar);
3738 
3739 
3740  // Get the variations
3741  for (Int_t itoy=0;itoy<con->GetNToys();itoy++){
3742  if (ipar==-1){
3743  for (UInt_t ipar2=0;ipar2<con->_toys[itoy].npar;ipar2++)
3744  hvar->Fill(con->_toys[itoy].variations[ipar2]);
3745  }
3746  else
3747  hvar->Fill(con->_toys[itoy].variations[ipar]);
3748  }
3749 
3750  hvar->SetTitle(_title.c_str());
3751 
3752  // Draw the entries histogram
3753  // DrawHisto(hvar, _line_width, _line_color, _fill_style, root_opt+" H", uopt+ "NOVARBIN", "LE1P");
3754  DrawHisto(hvar, _line_width, _line_color, _fill_style, root_opt, uopt, "LE1P");
3755 
3756  hvar->GetXaxis()->SetTitle("variation");
3757  hvar->GetYaxis()->SetTitle("# toys");
3758 
3759  // Draw the legend
3760  if (!drawUtils::CheckOption(uopt,"NOLEG") && leg!="")
3761  _legends.back()->Draw();
3762 
3763  if (!drawUtils::CheckOption(uopt,"NODRAW"))
3764  gPad->Update();
3765 
3766  // go back to previous stat option
3767  SetOptStat(statTemp);
3768 }
3769 
3770 //*********************************************************
3771 void DrawingToolsBase::DumpOriginalSoftwareVersion(const std::string& file, bool all) {
3772 //*********************************************************
3773 
3774  // Use the file used to create the DrawingTools if no file is specified
3775  std::string file2 = file;
3776  if (file=="") file2 = _config_file;
3777 
3778  // And read the new ones from the file
3779  TChain* chain = new TChain("header");
3780  chain->AddFile(file2.c_str());
3781 
3782  if (!drawUtils::TreeHasVar(chain,"SoftwareVersion")){
3783  delete chain;
3784  chain = new TChain("config");
3785  chain->AddFile(file2.c_str());
3786  if (!drawUtils::TreeHasVar(chain,"SoftwareVersion")) return;
3787  }
3788 
3789  char version[20];
3790  chain->SetBranchAddress("SoftwareVersion", version);
3791 
3792  Long64_t centry = chain->LoadTree(0);
3793  if (centry<0){
3794  std::cout << "failed in reading SoftwareVersion !!!" << std::endl;
3795  return;
3796  }
3797  Int_t nb = chain->GetEntry(0);
3798  if (nb==0){
3799  std::cout << "failed in reading SoftwareVersion !!!" << std::endl;
3800  return;
3801  }
3802 
3803  if (all){
3804  std::cout << "------ Software Version for original input files -------------------------------------" << std::endl;
3805  std::cout << "file: " << file << std::endl;
3806  std::cout << "version: " << version << std::endl;
3807  }
3808  else
3809  std::cout << "software version used to produce original input files: " << version << std::endl;
3810 }
3811 
3812 
3813 //*********************************************************
3814 void DrawingToolsBase::DumpSoftwareVersions(const std::string& file){
3815 //*********************************************************
3816 
3817  // Use the file used to create the DrawingTools if no file is specified
3818  std::string file2 = file;
3819  if (file=="") file2 = _config_file;
3820 
3821  if (file2!="") ND::versioning().ReadVersions(file2);
3822  ND::versioning().DumpVersions();
3823  DumpOriginalSoftwareVersion(file2, false);
3824 }
3825 
3826 //*********************************************************
3827 void DrawingToolsBase::DumpFileInfo(const std::string& file) {
3828 //*********************************************************
3829 
3830  // And read the new ones from the file
3831  TChain* chain = new TChain("config");
3832  chain->AddFile(file.c_str());
3833 
3834  char cmtpath[200]="unknown";
3835  char hostname[50]="unknown";
3836  char inputFile[200]="unknown";
3837  char OriginalFile[200]="unknown";
3838  if (drawUtils::TreeHasVar(chain,"CMTPATH")){
3839  chain->SetBranchAddress("CMTPATH", cmtpath);
3840  chain->SetBranchAddress("HOSTNAME", hostname);
3841  chain->SetBranchAddress("InputFile", inputFile);
3842  if (drawUtils::TreeHasVar(chain,"OriginalFile"))
3843  chain->SetBranchAddress("OriginalFile", OriginalFile);
3844 
3845 
3846  Long64_t centry = chain->LoadTree(0);
3847  if (centry<0){
3848  std::cout << "failed in reading config tree !!!" << std::endl;
3849  return;
3850  }
3851  Int_t nb = chain->GetEntry(0);
3852  if (nb==0){
3853  std::cout << "failed in reading config tree !!!" << std::endl;
3854  return;
3855  }
3856  }
3857 
3858  std::cout << "====================== FILE INFORMATION ===================================" << std::endl;
3859  std::cout << std::endl;
3860  std::cout << "CMTPATH: " << cmtpath << std::endl;
3861  std::cout << "HOSTNAME: " << hostname << std::endl;
3862  std::cout << "Input file: " << inputFile << std::endl;
3863  std::cout << "original file: " << OriginalFile << std::endl;
3864 
3865  DumpSoftwareVersions(file);
3866 
3867  // Not available in Flat and Mini trees
3868  if (drawUtils::TreeHasVar(chain,"NSEL")) DumpSelections(file);
3869  if (drawUtils::TreeHasVar(chain,"NCONF")) DumpConfigurations(file);
3870 
3871  DumpCorrections(file);
3872 
3873  std::cout << "===========================================================================" << std::endl;
3874 
3875 }
3876 
3877 
3878 //*********************************************************
3879 void DrawingToolsBase::ReadOther(const std::string& file) {
3880 //*********************************************************
3881 
3882  // And read the new ones from the file
3883  TChain chain("config");
3884  chain.AddFile(file.c_str());
3885  ReadOther(&chain);
3886 }
3887 
3888 //*********************************************************
3889 void DrawingToolsBase::ReadOther(TTree* config) {
3890 //*********************************************************
3891 
3892  _minAccumLevelToSave = 0;
3893  if (drawUtils::TreeHasVar(config,"MinAccumLevelToSave")){
3894  config->SetBranchAddress("MinAccumLevelToSave", &_minAccumLevelToSave);
3895 
3896  Long64_t centry = config->LoadTree(0);
3897  if (centry<0){
3898  std::cout << "failed in reading config tree !!!" << std::endl;
3899  return;
3900  }
3901  Int_t nb = config->GetEntry(0);
3902  if (nb==0){
3903  std::cout << "failed in reading config tree !!!" << std::endl;
3904  return;
3905  }
3906  }
3907 }
3908 
3909 //*********************************************************
3910 std::string DrawingToolsBase::AddRangeCut(const std::string& var, int nx, double* xbins, int ny, double* ybins, const std::string& cut, const std::string& uopt) {
3911 //*********************************************************
3912 
3913  (void)ny;
3914  (void)ybins;
3915 
3916  std::string cut2 = FormatCut(cut);
3917  std::stringstream scut;
3918 
3919  if (!drawUtils::CheckOption(uopt,"UNDER") || !drawUtils::CheckOption(uopt,"OVER")){
3920  scut << "(" << cut2;
3921 
3922  if (!drawUtils::CheckOption(uopt,"UNDER")){
3923  scut << " && " << var << ">=" << xbins[0];
3924  }
3925  if (!drawUtils::CheckOption(uopt,"OVER")){
3926  scut << " && " << var << "<" << xbins[nx];
3927  }
3928  scut << ")";
3929  }
3930  else{
3931  scut << cut2;
3932  }
3933 
3934  return scut.str();
3935 }
3936 
3937 //*********************************************************
3938 std::string DrawingToolsBase::GetSameRootOption(const std::string& root_opt) {
3939 //*********************************************************
3940 
3941  std::string uroot_opt = drawUtils::ToUpper(root_opt);
3942  if (uroot_opt.find("SAMES")!=std::string::npos)
3943  return " sames";
3944  else if (uroot_opt.find("SAME")!=std::string::npos)
3945  return " same";
3946  else return "";
3947 }
3948 
3949 //*********************************************************
3950 std::string DrawingToolsBase::GetNoSameRootOption(const std::string& root_opt) {
3951 //*********************************************************
3952 
3953  std::string uroot_opt = drawUtils::ToUpper(root_opt);
3954  bool found=true;
3955 
3956  while(found){
3957  if (uroot_opt.find("SAMES")!=std::string::npos){
3958  uroot_opt = uroot_opt.replace(uroot_opt.find("SAMES"), 5, std::string(""));
3959  found=true;
3960  }
3961  else if (uroot_opt.find("SAME")!=std::string::npos){
3962  uroot_opt = uroot_opt.replace(uroot_opt.find("SAME"), 4, std::string(""));
3963  found=true;
3964  }
3965  else found=false;
3966  }
3967 
3968  return uroot_opt;
3969 }
3970 
3971 //*********************************************************
3972 void DrawingToolsBase::ChangeLegendEntry(Int_t index, const std::string& new_label, const std::string& new_opt) {
3973 //*********************************************************
3974 
3975  TLegend* leg0 = GetLastLegend();
3976 
3977  std::vector<TLegendEntry*> entries;
3978 
3979  // Clear the output Legend
3980  while (leg0->GetNRows()>0){
3981  entries.push_back(new TLegendEntry(leg0->GetEntry()->GetObject(), leg0->GetEntry()->GetLabel(), leg0->GetEntry()->GetOption()));
3982  leg0->DeleteEntry();
3983  }
3984 
3985  // Put 0 height to the new legend
3986  if (drawUtils::legendEntryHeight>0)
3987  leg0->SetY1NDC(leg0->GetY2NDC());
3988 
3989  // Change the label/option of the entry with a given index
3990  for (UInt_t i=0;i<entries.size();i++){
3991  const char* label = entries[i]->GetLabel();
3992  const char* opt = entries[i]->GetOption();
3993  if ((Int_t)i==index && new_label!="") label = new_label.c_str();
3994  if ((Int_t)i==index && new_opt!="" ) opt = new_opt.c_str();
3995  drawUtils::AddLegendEntry(leg0, entries[i]->GetObject(),(std::string)label,(std::string)opt);
3996  delete entries[i];
3997  }
3998 
3999  entries.clear();
4000  leg0->Draw();
4001 }
4002 
4003 //*********************************************************
4005 //*********************************************************
4006 
4007  TLegend* leg0 = GetLastLegend();
4008 
4009  std::vector<TLegendEntry*> entries;
4010 
4011  // Clear the output Legend
4012  while (leg0->GetNRows()>0){
4013  entries.push_back(new TLegendEntry(leg0->GetEntry()->GetObject(), leg0->GetEntry()->GetLabel(), leg0->GetEntry()->GetOption()));
4014  leg0->DeleteEntry();
4015  }
4016 
4017  // Put 0 height to the new legend
4018  if (drawUtils::legendEntryHeight>0)
4019  leg0->SetY1NDC(leg0->GetY2NDC());
4020 
4021 
4022  // Change the label/option of the entry with a given index
4023  for (UInt_t i=0;i<entries.size();i++){
4024  if ((Int_t)i!=index)
4025  drawUtils::AddLegendEntry(leg0, entries[i]->GetObject(),entries[i]->GetLabel(),entries[i]->GetOption());
4026  delete entries[i];
4027  }
4028 
4029  entries.clear();
4030  leg0->Draw();
4031 }
4032 
4033 
4034 //*********************************************************
4035 std::string DrawingToolsBase::ConvertCutForTruthTree(const std::string cut, bool replace_selmu) {
4036 //*********************************************************
4037 
4038  std::string cut2 = cut;
4039 
4040  // replace accum_level[] with accum_level
4041  while (true) {
4042  size_t pos = cut2.find("accum_level[]");
4043  if (pos == std::string::npos) break;
4044  std::string pre = cut2.substr(0,pos);
4045  std::string post = cut2.substr(pos+strlen("accum_level[]"));
4046  cut2 = pre + "accum_level" + post;
4047  }
4048 
4049  if ( ! replace_selmu) return cut2;
4050 
4051  // replace selmu_ with truelepton_
4052  while (true) {
4053  size_t pos = cut2.find("selmu_");
4054  if (pos == std::string::npos) break;
4055  std::string pre = cut2.substr(0,pos);
4056  std::string post = cut2.substr(pos+strlen("selmu_"));
4057  cut2 = pre + "truelepton_" + post;
4058  }
4059 
4060  return cut2;
4061 }
4062 
4063 //********************************************************************
4064 int DrawingToolsBase::GetNDOF(const TH1* h1, const TH1* h2) {
4065 //********************************************************************
4066  int ndof=0;
4067  for (int i=1; i<=h1->GetXaxis()->GetNbins(); i++) {
4068  if (h1->GetBinContent(i)==0 && h2->GetBinContent(i)==0) continue;
4069  ndof++;
4070  }
4071  ndof--;
4072  return ndof;
4073 }
4074 
4075 //********************************************************************
4076  double DrawingToolsBase::GetChi2(const TH1* h1, const TH1* h2) {
4077  //********************************************************************
4078 
4079  if (h1->GetXaxis()->GetNbins() != h2->GetXaxis()->GetNbins())
4080  std::cout << "WARNING: the two histograms have different number of bins!" << std::endl;
4081 
4082  TH1* h1temp = (TH1*)h1->Clone();
4083  TH1* h2temp = (TH1*)h2->Clone();
4084 
4085  // Refill to avoid dealing with normalizing factors
4086  h1temp->Reset();
4087  h2temp->Reset();
4088  for (int i=1; i<=h1temp->GetXaxis()->GetNbins(); i++) {
4089  h1temp->SetBinContent(i,h1->GetBinContent(i));
4090  h2temp->SetBinContent(i,h2->GetBinContent(i));
4091  h1temp->SetBinError(i,h1->GetBinError(i));
4092  h2temp->SetBinError(i,h2->GetBinError(i));
4093  }
4094 
4095  double chi2=0;
4096  int ndof=0;
4097  for (int i=1; i<=h1temp->GetXaxis()->GetNbins(); i++) {
4098  if (h1temp->GetBinContent(i)==0 && h2temp->GetBinContent(i)==0) continue;
4099  ndof++;
4100  double diff = h1temp->GetBinContent(i) - h2temp->GetBinContent(i);
4101  double err1 = h1temp->GetBinError(i);
4102  double err2 = h2temp->GetBinError(i);
4103  double errsq = pow(err1,2) + pow(err2,2);
4104  if (errsq == 0 || errsq != errsq) {
4105  if (diff != 0)
4106  std::cout << "ERROR errsq = 0! \n";
4107  else {
4108  std::cout << "WARNING diff=0 and errsq= 0 (set to 1) \n";
4109  errsq=1;
4110  diff=1;
4111  }
4112  }
4113  chi2 += pow(diff,2) / errsq;
4114  }
4115  ndof--;
4116 /*
4117  double chi2test;
4118  int ndoftest;
4119  int igood;
4120  double pvalue = h2temp->Chi2TestX(h1temp,chi2test,ndoftest,igood,"WW");
4121 
4122  cout << "my chi2/ndof (pvalue) = " << chi2 << " / " << ndof
4123  << " (" << TMath::Prob(chi2,ndof) << ")" << endl;
4124  cout << "my Chi2TestX (pvalue) = " << chi2test << " / " << ndoftest
4125  << " (" << TMath::Prob(chi2test,ndoftest) << ")" << endl;
4126 */
4127  delete h1temp;
4128  delete h2temp;
4129 
4130  return chi2;
4131 }
4132 
4133 //********************************************************************
4134 void DrawingToolsBase::DumpSelections(const std::string& file){
4135 //********************************************************************
4136  if (file!="") sel().ReadSelections(file);
4137  sel().DumpSelections();
4138  if (_config_file!="") ReadSelections(_config_file);
4139 }
4140 
4141 //********************************************************************
4142 void DrawingToolsBase::DumpBranches(Int_t sel_index){
4143 //********************************************************************
4144  if (sel().GetSelection(sel_index)) sel().GetSelection(sel_index)->DumpBranches();
4145 }
4146 
4147 //********************************************************************
4148 void DrawingToolsBase::DumpBranches(const std::string& sel_name){
4149 //********************************************************************
4150  if (sel().GetSelection(sel_name)) sel().GetSelection(sel_name)->DumpBranches();
4151 }
4152 
4153 //********************************************************************
4155 //********************************************************************
4156  if (sel().GetNEnabledSelections()>1){
4157  if (sel().GetSelection(branch)) sel().GetSelection(branch)->DumpCuts();
4158  }
4159  else
4160  sel().GetSelection(0)->DumpCuts(branch);
4161 }
4162 
4163 //********************************************************************
4165 //********************************************************************
4166  if (sel().GetNEnabledSelections()>1){
4167  if (sel().GetSelection(branch,true)) sel().GetSelection(branch)->DumpSteps();
4168  }
4169  else
4170  sel().GetSelection(0)->DumpSteps(branch);
4171 }
4172 
4173 //********************************************************************
4174 void DrawingToolsBase::DumpCuts(const std::string& sel_name, int branch){
4175 //********************************************************************
4176  if (sel().GetSelection(sel_name)) sel().GetSelection(sel_name)->DumpCuts(branch);
4177 }
4178 
4179 //********************************************************************
4180 void DrawingToolsBase::DumpSteps(const std::string& sel_name,int branch){
4181 //********************************************************************
4182  if (sel().GetSelection(sel_name)) sel().GetSelection(sel_name)->DumpSteps(branch);
4183 }
4184 
4185 //********************************************************************
4186 void DrawingToolsBase::DumpCuts(Int_t sel_index, int branch){
4187 //********************************************************************
4188  if (sel().GetSelection(sel_index)) sel().GetSelection(sel_index)->DumpCuts(branch);
4189 }
4190 
4191 //********************************************************************
4192 void DrawingToolsBase::DumpSteps(Int_t sel_index,int branch){
4193 //********************************************************************
4194  if (sel().GetSelection(sel_index)) sel().GetSelection(sel_index)->DumpSteps(branch);
4195 }
4196 
4197 //********************************************************************
4198 void DrawingToolsBase::DumpPOT(TTree* tree){
4199 //********************************************************************
4200  header().ReadHeader(tree);
4201  header().DumpPOT();
4202 }
4203 
4204 //********************************************************************
4205 void DrawingToolsBase::DumpPOT(const std::string& file){
4206 //********************************************************************
4207  header().ReadHeader(file);
4208  header().DumpPOT();
4209 }
void Draw(int lc, int lw, int fc, int fs, const std::string &root_opt="", const std::string &opt="", const std::string &leg_opt="", int mode=0)
Definition: HistoStack.cxx:148
TH1_h * GetEventsVSCut(TTree *tree, const std::string &var, const std::string &cut_norm, int isel, int branch, int &first_cut, int &last_cut, const std::string &root_opt="", const std::string &opt="")
Get a TH1 containing the number of events passing the selection as a function of the cut...
void ChangeLegendEntry(Int_t index, const std::string &new_label="", const std::string &new_opt="")
Change the label or drawing style of a entry in the legend provided the entry number.
void DumpBranches() const
Dumps the list of branches.
void DumpCuts(Int_t branch=-1) const
Print out the index, name and title of each cut for a given branch (no argument for all branches) ...
int _unique
Counter for ensuring all histograms get a unique name.
void AddTotal(TH1_h *h1, TH1_h *hsyst=NULL)
Sets the total 1D histo if it does not exists or adds to the previous one when it exists...
Definition: HistoStack.cxx:328
void DumpSelections()
Print out the index, name and title of each selection for a given branch (no argument for all branche...
bool IsMultiType()
Is this a multi-type category ? (Can several types coexist?)
void AddCategory(const std::string &name, int ntypes, std::string *names, int *codes, int *colors, bool multi=false, bool noWarning=false, bool addNOTRUTH=true, bool addSAND=true)
void AddLegendEntry(TLegend *leg, TObject *ht, const std::string &type, const std::string &opt)
Add an entry to the Legend and resize it.
void DumpFileInfo(const std::string &file="")
---— Package versions ----------—
void PrintEventNumbers(TTree *tree, const std::string &cut, const std::string &file="", int toy_ref=-1)
Print the event number of a specific selection.
void DumpSteps(const std::string &branch="", bool onlycuts=false) const
Print out the index, name and title of each step for a given branch (no argument for all branches) ...
std::string GetSameLevel(const std::string &root_opt)
Get the superposition level.
TLegend * GetLastLegend()
Get the last legend that was drawn. Useful if you want to modify its appearance.
void AddDocumentPage(const std::string &name)
void BuildOptions()
Build the map of valid options with AddOption.
double GetEff(TTree *tree, const std::string &var, double xmin, double xmax, const std::string &cut1, const std::string &cut2, const std::string &root_opt="", const std::string &opt="")
void SetLegendSize(double w=-999, double h=-999)
Set legend/small legend size, width and height (if -999 keep same value)
void DumpSoftwareVersions(const std::string &file="")
—— Package versions -------——
void DrawPurVSCut(TTree *tree, const std::string &signal="", const std::string &precut="", int first_cut=-1, int last_cut=-1, const std::string &root_opt="", const std::string &opt="", const std::string &leg="")
Draw the selection purity as a function of the cut. Must use the default tree as input.
void ReadVersions(const std::string &file)
Read package names and versions use to produce this file.
void DrawCutArrow(double xmin, double ymin, double xmax, double ymax)
void NormalizeVariableBinning(TH1 *h, int mode, const std::string &opt, Double_t &minwidth)
Normalize bin contents by bin width. return the with of the bin with minimum width.
Int_t GetNToys() const
Get and sets the number of toys.
void ReadCorrections(const std::string &file)
Read the list of Corrections.
void SetLogY(bool logY=true)
Set the current histogram to be drawn with a logarithmic Y axis.
void FillLegend(TLegend *leg)
Fill the legend with info in the HistoStack.
Definition: HistoStack.cxx:306
void SetLegendEntryHeight(double h)
[DrawingToolsCommandLineOptions]
UInt_t GetNEnabledSelections()
Returns the number of enabled selections.
void DrawToysRatioTwoCuts(TTree *tree1, TTree *tree2, const std::string &cut1, const std::string &cut2, const std::string &root_opt="", const std::string &opt="", const std::string &leg="", double norm=1)
TH1 * Draw(TTree *tree, const std::string &var, int nbins, double *xbins, const std::string &categ="all", const std::string &cut="", const std::string &root_opt="", const std::string &opt="", double norm=1, bool scale_errors=true)
1D histos
TH1_h * GetTotalStat1D()
Return the total 1D histo with only stat errors.
Definition: HistoStack.hxx:70
std::string FormatCut(const std::string &cut)
Give the appropriate format to any cut.
std::string AddRangeCut(const std::string &var, int nx, double *xbins, int ny, double *ybins, const std::string &cut, const std::string &uopt)
Add cut on range shown on plot.
void ReadSelections(const std::string &file)
Read the list of Selections.
void DrawToysRatio(TTree *tree1, TTree *tree2, const std::string &cut="", const std::string &root_opt="", const std::string &opt="", const std::string &leg="", double norm=1)
double GetMaximum(const std::string &opt="")
Get the maximum for the HistoStack.
Definition: HistoStack.cxx:538
TH1_h * GetTotalSyst1D()
Return the total 1D histo with only systematic errors.
Definition: HistoStack.hxx:73
double GetChi2(const TH1 *h1, const TH1 *h2)
std::string GetErrorStyle(const std::string &opt)
Gets the root error style from the user option.
void SetMinimum(double min)
Set the minimum for the HistoStack.
Definition: HistoStack.cxx:581
void Reset()
reset all saved histograms
virtual void UpdateSystInfo(HistoStack *hs1, HistoStack *hs2, TTree *tree1, TTree *tree2, const std::string &var, int nx, double *xbins, const std::string &cut1, const std::string &cut2, const std::string &opt, double norm)
fill/update systematics information (fill appopriate histograms) for the stacks
void StartDocument(const std::string &title, bool pdf=true, bool web=false, const std::string &pdffile="plots.pdf", const std::string &webpath="plots")
double * GetVariableBins(int nx, double xmin, double xmax, double *)
Get a vector with variable binning.
void NormalizeByArea(const std::string &uopt, double area=1)
normalize all histos in the stack by area
Definition: HistoStack.cxx:499
void DrawEffVSCut(TTree *tree, const std::string &signal="", const std::string &precut="", int first_cut=-1, int last_cut=-1, const std::string &root_opt="", const std::string &opt="", const std::string &leg="")
Draw the selection efficiency as a function of the cut. Must use the truth tree as input...
TrackCategoryDefinition & GetCategory(const std::string &categ)
Get a specific category.
void SetMinY(double minY=0)
void SetAutoColors(int colors[], int ncolors)
Set the auto colors when superimposing histograms.
std::string GetSameRootOption(const std::string &root_opt)
extract the same or sames option from the full root option
void SetLogZ(bool logZ=true)
Set the current 2D histogram to be drawn with a logarithmic Z axis (works only for category "all")...
void DrawCutLine(double xmin, double ymin, double xmax, double ymax)
void SetMaximum(double max)
Set the maximum for the HistoStack.
Definition: HistoStack.cxx:571
void DrawCutLineHorizontal(double yval, bool addarrow=false, std::string arrowdir="u", double arrowpos=0.5)
bool TreeHasVar(TTree *tree, const std::string &var)
Check wether the tree has a given variable.
void DumpSteps(int branch=-1)
void ReadSelections(const std::string &file)
void ReadConfigurations(const std::string &file)
Read the list of Configurations.
std::vector< ToyVariationWrite > _toys
The variations for each of the toys.
void Add(TH1_h *h1, int lc, int lw, int fc, int fs, const std::string &leg)
Add a new 1D histogram to the stack, with fill colour "fc", line colour "lc".
Definition: HistoStack.cxx:431
std::string _eff_params
parameter to control options for TGraphAsymmErrors::Divide() method, the one used to get the efficien...
void CreateLegend(const std::string &uopt="")
create the legend
void PrintPurities(TTree *tree, const std::string &categ, const std::string &cut, double events_ratio=1)
void DrawDoubleEff(TTree *tree1, TTree *tree2, const std::string &var, int nx, double *xbins, const std::string &cut1, const std::string &cut2, const std::string &root_opt="", const std::string &opt="", const std::string &leg="")
ratio between two Efficiencies
void ChangeCategory(const std::string &categ_name, int ntypes, std::string *names, int *codes, int *colors)
[DrawingToolsBase_categ]
bool Is1D()
Tells whether this is a 1D histo.
Definition: HistoStack.hxx:39
std::string GetString(int code)
convert integer to string
void DumpBranches(Int_t sel_index=0)
Dump the list of branches in the selection provided selection index.
std::vector< StepBase * > GetCutsInBranch(const std::string &branch) const
Get all cuts in a given branch provided the branch alias.
void DumpConfiguration(const std::string &name)
Print out the Configuration.
std::vector< TrackTypeDefinition > & GetCategoryTypes(const std::string &categ)
Get the vector of track types in a given category.
int MakeDirectory(const std::string &path, mode_t mode)
Make a directory on the filesystem.
bool ContainValidOptions(const std::string &uopt)
Check if the input string contails only valid options.
void DrawSignificance(TTree *tree, const std::string &var, int nbins, double *xbins, const std::string &cut1, const std::string &cut2, double norm=1, double rel_syst=0, const std::string &root_opt="", const std::string &opt="", const std::string &leg="")
1D significance
std::string GetNoSameRootOption(const std::string &root_opt)
remove same and sames options from the root option
std::string GetUniqueName(const std::string &name)
void ReadOther(const std::string &file)
Read any other variables in the config tree.
void DumpConfigurations(const std::string &file="")
Print out the Configurations.
void ScaleHisto(TH1 *h, double scale, bool scale_errors=true)
Scale an histogram and its errors(when requested)
void SetLegendPos(double x=-999, double y=-999)
void SetAutoMarkers(int markers[], int nmarkers)
Set the auto Markers when superimposing histograms.
void DumpOriginalSoftwareVersion(const std::string &file="", bool all=true)
Dumps on the screen the software version of the original file (i.e. output of recon) ...
UInt_t GetNCuts(Int_t branch) const
Return the number of cuts in a given branch.
void ReadDocStrings(const std::string &file)
[DrawingToolsBase_vars]
void DrawGraph(TGraphAsymmErrors *eff, int nbins, double *xbins, const std::string &uroot_opt, const std::string &uopt, const std::string &leg, double ymax=1.05)
[DrawingToolsBase_eff_ratio]
void SetLegendParam(double a, double b, double c, double d)
Set position and size of the legend.
void ReadConfig(const std::string &file)
[DrawingToolsBase_POT]
void DumpSelections(const std::string &file="")
double GetMaximumWithError(const std::string &opt="")
Get the maximum for the HistoStack taking into account the upper error.
Definition: HistoStack.cxx:552
void DrawToysBase(TH1_h &result, TH1_h &entries, const std::string &root_opt="", const std::string &opt="", const std::string &leg="")
[DrawingToolsBaseDrawToyMethods]
double GetEntries(TTree *tree, const std::string &cut)
Get number (sum of weights) of events (i.e. bunches) passing "cut".
void DrawEventsVSCut(TTree *tree, const std::string &cut_norm="", int first_cut=-1, int last_cut=-1, const std::string &root_opt="", const std::string &opt="", const std::string &leg="")
void DumpPOT(TTree *tree)
void SetTotal(TH1_h *h1)
Definition: HistoStack.hxx:60
void DumpCuts(int branch=-1)
[DrawingToolsBase_DumpSelections]
TH2_h * GetTotal2D()
Return the total 2D histo.
Definition: HistoStack.hxx:76
void DumpHistoInfo(TH1 *histo, const std::string &uopt)
Dump integral, underflow and overflow.
void DumpVersions()
dump package names and versions
void DeleteLegendEntry(Int_t index)
Delete a given Legent entry provided its index.
std::string ToUpper(const std::string &str)
Definition: DrawingUtils.cxx:9
void DrawToys(TTree *tree, const std::string &cut="", const std::string &root_opt="", const std::string &opt="", const std::string &leg="")
void DrawRatioVSCut(TTree *tree1, TTree *tree2, const std::string &precut="", int first_cut=-1, int last_cut=-1, const std::string &root_opt="", const std::string &opt="", const std::string &leg="", double norm=1.)
Draw the ratio between two trees as a function of the cut.
void DumpCorrections(const std::string &file="")
Print out the Corrections.
bool CheckInternalOption(const std::string &uopt, const std::string &this_opt)
Check if specific option appears in option field (don&#39;t check if it exists: Added with AddOption) ...
void DrawCutRegion(double xmin, double ymin, double xmax, double ymax, std::string opt="tblr")
int GetNToys(TTree *tree)
get the number of weights in the tree
void SetDefaultEffDivideParams()
Setter of default params.
void SetOptStat(int opt)
Set the stat option (by int or string)
void ReadHeader(const std::string &file)
Read the "header" tree from the given file, but reset POT counting first.
Definition: Header.cxx:141
ConfigurationBase * GetConfiguration(Int_t index) const
return the configuration with a given index
SelectionBase * GetSelection(const std::string &name, bool print_error=true)
Return the selection that was registered with the given name. NULL if it does not exist...
TH1_h * GetTotal1D()
Return the total 1D histo.
Definition: HistoStack.hxx:67
void DrawRatio(TTree *tree, const std::string &var, int nbins, double *xbins, const std::string &cut1, const std::string &cut2, const std::string &root_opt="", const std::string &opt="", const std::string &leg="")
void ReadCategories(const std::string &file)
void DumpPOT()
Print the POT information.
Definition: Header.cxx:226
void DumpHisto(TH1 *histo, const std::string &uopt)
dump histo contents
bool HasCategory(const std::string &categ_name)
Check whether a category has been defined.
void DrawVariations(const std::string &name, Int_t ipar=-1, int nx=100, double xmin=-5, double xmax=5, const std::string &root_opt="", const std::string &opt="", const std::string &leg="")
Draw the variations for systematic parameter ipar.
bool Is2D()
Tells whether this is a 2D histo.
Definition: HistoStack.hxx:42
bool CheckOption(const std::string &uopt, const std::string &this_opt)
Check if specific option exists, and if so if it appears in option field.
void DrawCutLineVertical(double xval, bool addarrow=false, std::string arrowdir="l", double arrowpos=0.5)
[DrawingToolsCommandLineOptions]