ra4_stats  0341147a0dc35f80f4e12c6003afb76a38e2ed6e
extract_yields.cxx
Go to the documentation of this file.
1 #include "extract_yields.hpp"
2 
3 #include <cstdlib>
4 
5 #include <iostream>
6 #include <iomanip>
7 #include <sstream>
8 #include <fstream>
9 #include <algorithm>
10 #include <initializer_list>
11 #include <stdexcept>
12 
13 #include <getopt.h>
14 
15 #include "TFile.h"
16 #include "TLine.h"
17 #include "TCanvas.h"
18 #include "TPad.h"
19 #include "TLegend.h"
20 #include "TColor.h"
21 #include "TH2D.h"
22 #include "TStyle.h"
23 #include "TLatex.h"
24 
25 #include "RooArgList.h"
26 #include "RooArgSet.h"
27 #include "RooRealVar.h"
28 #include "RooAbsData.h"
29 #include "RooDataSet.h"
30 #include "RooProdPdf.h"
31 #include "RooNLLVar.h"
32 #include "RooMinuit.h"
33 
34 #include "utilities.hpp"
35 #include "styles.hpp"
36 
37 using namespace std;
38 
39 namespace{
40  string file_wspace("");
41  bool table_clean(false);
42  bool r4_only(false);
43  bool show_exp_sig(false);
44  bool do_global = false;
45 }
46 
47 int main(int argc, char *argv[]){
48  GetOptionsExtract(argc, argv);
49 
50  if(file_wspace == "") ERROR("You need to specify the file containing the workspace with option -f");
51 
52  styles style("RA4");
53  style.setDefaultStyle();
54 
56 
57  TFile in_file(file_wspace.c_str(), "read");
58  RooWorkspace *w = static_cast<RooWorkspace*>(in_file.Get("w"));
59  RooFitResult *fit_b = static_cast<RooFitResult*>(in_file.Get("fit_b"));
60  RooFitResult *fit_s = static_cast<RooFitResult*>(in_file.Get("fit_s"));
61 
62  if(fit_b != nullptr){
63  PrintDebug(*w, *fit_b, ChangeExtension(file_wspace, "_bkg_debug.tex"));
64  PrintTable(*w, *fit_b, ChangeExtension(file_wspace, "_bkg_table.tex"));
65  MakeYieldPlot(*w, *fit_b, ChangeExtension(file_wspace, "_bkg_plot.pdf"), false);
66  MakeYieldPlot(*w, *fit_b, ChangeExtension(file_wspace, "_bkg_plot_linear.pdf"), true);
67  if(!Contains(file_wspace, "nokappa")) MakeCorrectionPlot(*w, *fit_b, ChangeExtension(file_wspace, "_bkg_correction.pdf"));
68  MakeCovarianceMatrix(*w, *fit_b, ChangeExtension(file_wspace, "_bkg_covar.pdf"));
69  }
70  if(fit_s != nullptr){
71  PrintDebug(*w, *fit_s, ChangeExtension(file_wspace, "_sig_debug.tex"));
72  PrintTable(*w, *fit_s, ChangeExtension(file_wspace, "_sig_table.tex"));
73  MakeYieldPlot(*w, *fit_s, ChangeExtension(file_wspace, "_sig_plot.pdf"), false);
74  MakeYieldPlot(*w, *fit_s, ChangeExtension(file_wspace, "_sig_plot_linear.pdf"), true);
75  if(!Contains(file_wspace, "nokappa")) MakeCorrectionPlot(*w, *fit_s, ChangeExtension(file_wspace, "_sig_correction.pdf"));
76  MakeCovarianceMatrix(*w, *fit_b, ChangeExtension(file_wspace, "_sig_covar.pdf"));
77  }
78 }
79 
80 void RunFit(const string &path){
81  TFile in_file(path.c_str(), "read");
82  RooFitResult *fit_b = static_cast<RooFitResult*>(in_file.Get("fit_b"));
83  RooFitResult *fit_s = static_cast<RooFitResult*>(in_file.Get("fit_s"));
84  if(fit_b == nullptr || fit_s == nullptr){
85  execute("python/run_combine.py --full_fit --overwrite "+path);
86  }
87 }
88 
89 string GetSignalName(const RooWorkspace &w){
90  RooArgSet funcs = w.allFunctions();
91  TIter iter(funcs.createIterator());
92  int size = funcs.getSize();
93  RooAbsArg *arg = nullptr;
94  int i = 0;
95  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
96  ++i;
97  if(arg == nullptr) continue;
98  string name = arg->GetName();
99  if(name.substr(0,9) != "nsig_BLK_") continue;
100  TIter iter2(arg->getVariables()->createIterator());
101  int size2 = arg->getVariables()->getSize();
102  RooAbsArg *arg2 = nullptr;
103  int i2 = 0;
104  while((arg2 = static_cast<RooAbsArg*>(iter2())) && i2 < size2){
105  ++i2;
106  if(arg2 == nullptr) continue;
107  string name2 = arg2->GetName();
108  auto pos2 = name2.find("_PRC_");
109  if(pos2 != string::npos){
110  iter2.Reset();
111  iter.Reset();
112  return name2.substr(pos2+5);
113  }
114  }
115  iter2.Reset();
116  }
117  iter.Reset();
118  return "signal";
119 }
120 
121 string TexFriendly(const string &s){
122  string out;
123  for(size_t i = 0; i < s.size(); ++i){
124  if(s.at(i) == '_'){
125  out += "\\_";
126  }else{
127  out += s.at(i);
128  }
129  }
130  return out;
131 }
132 
133 void PrintDebug(RooWorkspace &w,
134  const RooFitResult &f,
135  const string &file_name){
136  SetVariables(w, f);
137 
138  vector<string> var_names = GetVarNames(w);
139  vector<string> func_names = GetFuncNames(w);
140 
141  ofstream out(file_name);
142  out << "\\documentclass{article}\n";
143  out << "\\usepackage{amsmath,graphicx,rotating,longtable}\n";
144  out << "\\thispagestyle{empty}\n";
145  out << "\\begin{document}\n";
146  out << "\\begin{longtable}{rr}\n";
147  out << "\\hline\\hline\n";
148  out << "Variable & Fit Value\\\\\n";
149  out << "\\hline\n";
150  out << fixed << setprecision(6);
151  for(const auto &var: var_names){
152  RooRealVar *varo = w.var(var.c_str());
153  if(varo == nullptr) continue;
154  if(!varo->isConstant()){
155  out << TexFriendly(var) << " & $" << varo->getVal() << "\\pm" << GetError(*varo, f) << "$\\\\\n";
156  }else{
157  out << TexFriendly(var) << " & $" << varo->getVal() << "$\\\\\n";
158  }
159  }
160  for(const auto &func: func_names){
161  RooAbsReal *funco = w.function(func.c_str());
162  if(funco == nullptr) continue;
163  if(!funco->isConstant()){
164  out << TexFriendly(func) << " & $" << funco->getVal() << "\\pm" << GetError(*funco, f) << "$\\\\\n";
165  }else{
166  out << TexFriendly(func) << " & $" << funco->getVal() << "$\\\\\n";
167  }
168  }
169 
170  out << "\\hline\\hline\n";
171  out << "\\end{longtable}\n";
172  out << "\\end{document}\n";
173  out << endl;
174  out.close();
175  cout<<"Saved "<<file_name.c_str()<<endl;
176 }
177 
178 void PrintTable(RooWorkspace &w,
179  const RooFitResult &f,
180  const string &file_name){
181  SetVariables(w, f);
182 
183  string sig_name = GetSignalName(w);
184  vector<string> prc_names = GetProcessNames(w);
185  vector<string> bin_names = GetPlainBinNames(w);
186 
187  bool dosig(Contains(file_name, "sig_table")), blind_all(Contains(file_name, "r4blinded"));
188  bool blind_2b(Contains(file_name, "1bunblinded"));
189  size_t digits(2), ncols(11);
190  if(!dosig) ncols = 9;
191  if(table_clean) {
192  --ncols;
193  digits = 1;
194  }
195 
196  ofstream out(file_name);
197  out << fixed << setprecision(digits);
198  out << "\\documentclass{article}\n";
199  out << "\\usepackage{amsmath,graphicx,rotating,longtable}\n";
200  out << "\\thispagestyle{empty}\n";
201  out << "\\begin{document}\n";
202  out << "\\begin{longtable}{rr}\n";
203  out << "\\centering\n";
204  out << "\\resizebox{\\textwidth}{!}{\n";
205  out << "\\begin{tabular}{l ";
206  for(size_t i = 0; i < ncols-1; ++i) out << "r";
207  out << "}\n";
208  out << "\\hline\\hline\n";
209  out << "Bin & ";
210  for(const auto &prc_name: prc_names){
211  out << prc_name << " & ";
212  }
213  out << "MC Bkg. "<<(dosig?"& Bkgnd. Pred. ":"")<<"& Signal "<<(dosig?"& Sig. Pred. ":"")
214  <<"& $\\kappa$ & Pred. & Obs.";
215  if(!table_clean) out << " & $\\lambda$";
216  out<<"\\\\\n";
217 
218  // out << "\\hline\n";
219  for(const auto &bin_name: bin_names){
220  if(Contains(bin_name, "r1")) {
221  out << "\\hline\\hline"<<endl;
222  if(Contains(bin_name, "lowmet")) out<<"\\multicolumn{"<<ncols<<"}{c}{$200<E_{T}^{miss}\\leq 350$} \\\\ \\hline"<<endl;
223  if(Contains(bin_name, "medmet")) out<<"\\multicolumn{"<<ncols<<"}{c}{$350<E_{T}^{miss}\\leq 500$} \\\\ \\hline"<<endl;
224  if(Contains(bin_name, "highmet")) out<<"\\multicolumn{"<<ncols<<"}{c}{$E_{T}^{miss}>500$} \\\\ \\hline"<<endl;
225  }
226  string bin_tex(TexFriendly(bin_name));
227  ReplaceAll(bin_tex, "lowmet\\_","");
228  ReplaceAll(bin_tex, "medmet\\_","");
229  ReplaceAll(bin_tex, "highmet\\_","");
230  ReplaceAll(bin_tex, "lownj\\_","$6 \\leq N_{jets}\\leq8$, ");
231  ReplaceAll(bin_tex, "highnj\\_","$N_{jets}\\geq9$, ");
232  ReplaceAll(bin_tex, "allnb","all $N_{jets}, N_b$");
233  ReplaceAll(bin_tex, "1b","$N_b=1$");
234  ReplaceAll(bin_tex, "2b","$N_b=2$");
235  ReplaceAll(bin_tex, "3b","$N_b\\geq3$");
236  for(int ind(1); ind<=4; ind++){
237  ReplaceAll(bin_tex, "r"+to_string(ind)+"\\_","R"+to_string(ind)+": ");
238  ReplaceAll(bin_tex, "r"+to_string(ind)+"c\\_","R"+to_string(ind)+": ");
239  ReplaceAll(bin_tex, "d"+to_string(ind)+"\\_","D"+to_string(ind)+": ");
240  }
241  out << bin_tex << " & ";
242  for(const auto &prc_name: prc_names){
243  out << GetMCYield(w, bin_name, prc_name) << " & ";
244  }
245  out << "$" << GetMCTotal(w, bin_name);
246  if(!table_clean) out << "\\pm" << GetMCTotalErr(w, f, bin_name);
247  out << "$ & ";
248 
249  if(dosig) out << "$" << GetBkgPred(w, bin_name) << "\\pm" << GetBkgPredErr(w, f, bin_name) << "$ & ";
250  out << GetMCYield(w, bin_name, sig_name) << " & ";
251  if(dosig) out << "$" << GetSigPred(w, bin_name) << "\\pm" << GetSigPredErr(w, f, bin_name) << "$ & ";
252  if(Contains(bin_name,"r4")){
253  double kappa = GetKappaSys(w, bin_name);
254  double kappa_nosys = GetKappaNoSys(w, bin_name);
255  double stat_err = GetKappaNoSysErr(w, f, bin_name)*kappa/kappa_nosys;
256  double full_err = GetKappaSysErr(w, f, bin_name);
257  double sys_err = 0.;
258  if(full_err >= stat_err){
259  double ratio = stat_err/full_err;
260  sys_err = full_err*sqrt(1.-ratio*ratio);
261  if(false) DBG(sys_err);
262  }else{
263  DBG("(systematic error)^2<0 for " << bin_name);
264  }
265  out << "$" << kappa << "\\pm" << full_err << "$ & ";
266  }else{
267  out << " & ";
268  }
269  if(Contains(bin_name,"r4") || do_global){
270  out << "$" << GetTotPred(w, bin_name) << "\\pm" << GetTotPredErr(w, f, bin_name) << "$ & ";
271  }else{
272  out << " & ";
273  }
274  if(Contains(bin_name,"4") && (blind_all || (!Contains(bin_name,"1b") && blind_2b))) out << "-- & ";
275  else out << setprecision(0) << GetObserved(w, bin_name);
276  out << setprecision(digits);
277  if(!table_clean) out << "& $" << GetLambda(w, bin_name) << "\\pm" << GetLambdaErr(w, f, bin_name) << "$";
278  out << "\\\\\n";
279  if(Contains(bin_name, "r3") || Contains(bin_name, "d3")) out << "\\hline"<<endl;
280  }
281  out << "\\hline\\hline\n";
282  out << "\\end{tabular}\n";
283  out << "}\n";
284  out << "\\end{longtable}\n";
285  out << "\\end{document}\n";
286  out << endl;
287  out.close();
288  cout<<"Saved "<<file_name.c_str()<<endl;
289 }
290 
291 double GetMCYield(const RooWorkspace &w,
292  const string &bin_name,
293  const string &prc_name){
294  RooArgSet funcs = w.allFunctions();
295  TIter iter(funcs.createIterator());
296  int size = funcs.getSize();
297  RooAbsArg *arg = nullptr;
298  int i = 0;
299  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
300  ++i;
301  if(arg == nullptr) continue;
302  string name = arg->GetName();
303  if(name.substr(0,8) != "ymc_BLK_") continue;
304  if(!(Contains(name, "_BIN_"+bin_name))) continue;
305  if(!(Contains(name, "_PRC_"+prc_name))) continue;
306  return static_cast<RooRealVar*>(arg)->getVal();
307  }
308  iter.Reset();
309  return -1.;
310 }
311 
312 double GetMCTotal(const RooWorkspace &w,
313  const string &bin_name){
314  RooArgSet funcs = w.allFunctions();
315  TIter iter(funcs.createIterator());
316  int size = funcs.getSize();
317  RooAbsArg *arg = nullptr;
318  int i = 0;
319  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
320  ++i;
321  if(arg == nullptr) continue;
322  string name = arg->GetName();
323  if(name.substr(0,8) != "ymc_BLK_") continue;
324  if(!(Contains(name, "_BIN_"+bin_name))) continue;
325  if(Contains(name, "_PRC_")) continue;
326  return static_cast<RooRealVar*>(arg)->getVal();
327  }
328  iter.Reset();
329  return -1.;
330 }
331 
332 double GetMCTotalErr(RooWorkspace &w,
333  const RooFitResult &f,
334  const string &bin_name){
335  RooArgSet funcs = w.allFunctions();
336  TIter iter(funcs.createIterator());
337  int size = funcs.getSize();
338  RooAbsArg *arg = nullptr;
339  int i = 0;
340  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
341  ++i;
342  if(arg == nullptr) continue;
343  string name = arg->GetName();
344  if(name.substr(0,8) != "ymc_BLK_") continue;
345  if(!(Contains(name, "_BIN_"+bin_name))) continue;
346  if(Contains(name, "_PRC_")) continue;
347  return GetError(*static_cast<RooAbsReal*>(arg), f);
348  }
349  iter.Reset();
350  return -1.;
351 }
352 
353 double GetBkgPred(const RooWorkspace &w,
354  const string &bin_name){
355  RooArgSet funcs = w.allFunctions();
356  TIter iter(funcs.createIterator());
357  int size = funcs.getSize();
358  RooAbsArg *arg = nullptr;
359  int i = 0;
360  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
361  ++i;
362  if(arg == nullptr) continue;
363  string name = arg->GetName();
364  if(name.substr(0,9) != "nbkg_BLK_") continue;
365  if(!(Contains(name, "_BIN_"+bin_name))) continue;
366  if(Contains(name, "_PRC_")) continue;
367  return static_cast<RooRealVar*>(arg)->getVal();
368  }
369  iter.Reset();
370  return -1.;
371 }
372 
373 double GetBkgPredErr(RooWorkspace &w,
374  const RooFitResult &f,
375  const string &bin_name){
376  RooArgSet funcs = w.allFunctions();
377  TIter iter(funcs.createIterator());
378  int size = funcs.getSize();
379  RooAbsArg *arg = nullptr;
380  int i = 0;
381  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
382  ++i;
383  if(arg == nullptr) continue;
384  string name = arg->GetName();
385  if(name.substr(0,9) != "nbkg_BLK_") continue;
386  if(!(Contains(name, "_BIN_"+bin_name))) continue;
387  if(Contains(name, "_PRC_")) continue;
388  return GetError(*static_cast<RooAbsReal*>(arg), f);
389  }
390  iter.Reset();
391  return -1.;
392 }
393 
394 double GetSigPred(const RooWorkspace &w,
395  const string &bin_name){
396  RooArgSet funcs = w.allFunctions();
397  TIter iter(funcs.createIterator());
398  int size = funcs.getSize();
399  RooAbsArg *arg = nullptr;
400  int i = 0;
401  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
402  ++i;
403  if(arg == nullptr) continue;
404  string name = arg->GetName();
405  if(name.substr(0,9) != "nsig_BLK_") continue;
406  if(!(Contains(name, "_BIN_"+bin_name))) continue;
407  if(Contains(name, "_PRC_")) continue;
408  return static_cast<RooRealVar*>(arg)->getVal();
409  }
410  iter.Reset();
411  return -1.;
412 }
413 
414 double GetSigPredErr(RooWorkspace &w,
415  const RooFitResult &f,
416  const string &bin_name){
417  RooArgSet funcs = w.allFunctions();
418  TIter iter(funcs.createIterator());
419  int size = funcs.getSize();
420  RooAbsArg *arg = nullptr;
421  int i = 0;
422  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
423  ++i;
424  if(arg == nullptr) continue;
425  string name = arg->GetName();
426  if(name.substr(0,9) != "nsig_BLK_") continue;
427  if(!(Contains(name, "_BIN_"+bin_name))) continue;
428  if(Contains(name, "_PRC_")) continue;
429  return GetError(*static_cast<RooAbsReal*>(arg), f);
430  }
431  iter.Reset();
432  return -1.;
433 }
434 
435 double GetTotPred(const RooWorkspace &w,
436  const string &bin_name){
437  RooArgSet funcs = w.allFunctions();
438  TIter iter(funcs.createIterator());
439  int size = funcs.getSize();
440  RooAbsArg *arg = nullptr;
441  int i = 0;
442  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
443  ++i;
444  if(arg == nullptr) continue;
445  string name = arg->GetName();
446  if(name.substr(0,9) != "nexp_BLK_") continue;
447  if(!(Contains(name, "_BIN_"+bin_name))) continue;
448  if(Contains(name, "_PRC_")) continue;
449  return static_cast<RooRealVar*>(arg)->getVal();
450  }
451  iter.Reset();
452  return -1.;
453 }
454 
455 double GetTotPredErr(RooWorkspace &w,
456  const RooFitResult &f,
457  const string &bin_name){
458  RooArgSet funcs = w.allFunctions();
459  TIter iter(funcs.createIterator());
460  int size = funcs.getSize();
461  RooAbsArg *arg = nullptr;
462  int i = 0;
463  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
464  ++i;
465  if(arg == nullptr) continue;
466  string name = arg->GetName();
467  if(name.substr(0,9) != "nexp_BLK_") continue;
468  if(!(Contains(name, "_BIN_"+bin_name))) continue;
469  if(Contains(name, "_PRC_")) continue;
470  return GetError(*static_cast<RooAbsReal*>(arg), f);
471  }
472  iter.Reset();
473  return -1.;
474 }
475 
476 double GetObserved(const RooWorkspace &w,
477  const string &bin_name){
478  RooAbsArg *arg = nullptr;
479  const RooArgSet &vars = w.allVars();
480  TIterator *iter_ptr = vars.createIterator();
481  while(iter_ptr != nullptr && *(*iter_ptr) != nullptr){
482  arg = static_cast<RooAbsArg*>((*iter_ptr)());
483  if(arg == nullptr) continue;
484  string name = arg->GetName();
485  if(name.substr(0,9) != "nobs_BLK_") continue;
486  if(!(Contains(name, "_BIN_"+bin_name))) continue;
487  if(Contains(name, "_PRC_")) continue;
488  return static_cast<RooRealVar*>(arg)->getVal();
489  }
490  return -1.;
491 }
492 
493 double GetKappaNoSys(const RooWorkspace &w,
494  const string &bin_name){
495  RooArgSet funcs = w.allFunctions();
496  TIter iter(funcs.createIterator());
497  int size = funcs.getSize();
498  RooAbsArg *arg = nullptr;
499  int i = 0;
500  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
501  ++i;
502  if(arg == nullptr) continue;
503  string name = arg->GetName();
504  if(name.substr(0,15) != "nosyskappa_BLK_") continue;
505  if(!(Contains(name, "_BIN_"+bin_name))) continue;
506  if(Contains(name, "_PRC_")) continue;
507  return static_cast<RooRealVar*>(arg)->getVal();
508  }
509  iter.Reset();
510  return -1.;
511 }
512 
513 double GetKappaNoSysErr(RooWorkspace &w,
514  const RooFitResult &f,
515  const string &bin_name){
516  RooArgSet funcs = w.allFunctions();
517  TIter iter(funcs.createIterator());
518  int size = funcs.getSize();
519  RooAbsArg *arg = nullptr;
520  int i = 0;
521  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
522  ++i;
523  if(arg == nullptr) continue;
524  string name = arg->GetName();
525  if(name.substr(0,15) != "nosyskappa_BLK_") continue;
526  if(!(Contains(name, "_BIN_"+bin_name))) continue;
527  if(Contains(name, "_PRC_")) continue;
528  return GetError(*static_cast<RooAbsReal*>(arg), f);
529  }
530  iter.Reset();
531  return -1.;
532 }
533 
534 double GetKappaSys(const RooWorkspace &w,
535  const string &bin_name){
536  RooArgSet funcs = w.allFunctions();
537  TIter iter(funcs.createIterator());
538  int size = funcs.getSize();
539  RooAbsArg *arg = nullptr;
540  int i = 0;
541  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
542  ++i;
543  if(arg == nullptr) continue;
544  string name = arg->GetName();
545  if(name.substr(0,13) != "syskappa_BLK_") continue;
546  if(!(Contains(name, "_BIN_"+bin_name))) continue;
547  if(Contains(name, "_PRC_")) continue;
548  return static_cast<RooRealVar*>(arg)->getVal();
549  }
550  iter.Reset();
551  return -1.;
552 }
553 
554 double GetKappaSysErr(RooWorkspace &w,
555  const RooFitResult &f,
556  const string &bin_name){
557  RooArgSet funcs = w.allFunctions();
558  TIter iter(funcs.createIterator());
559  int size = funcs.getSize();
560  RooAbsArg *arg = nullptr;
561  int i = 0;
562  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
563  ++i;
564  if(arg == nullptr) continue;
565  string name = arg->GetName();
566  if(name.substr(0,13) != "syskappa_BLK_") continue;
567  if(!(Contains(name, "_BIN_"+bin_name))) continue;
568  if(Contains(name, "_PRC_")) continue;
569  return GetError(*static_cast<RooAbsReal*>(arg), f);
570  }
571  iter.Reset();
572  return -1.;
573 }
574 
575 double GetLambda(const RooWorkspace &w,
576  const string &bin_name){
577  RooArgSet funcs = w.allFunctions();
578  TIter iter(funcs.createIterator());
579  int size = funcs.getSize();
580  RooAbsArg *arg = nullptr;
581  int i = 0;
582  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
583  ++i;
584  if(arg == nullptr) continue;
585  string name = arg->GetName();
586  if(name.substr(0,12) != "kappamc_BLK_") continue;
587  if(!(Contains(name, "_BIN_"+bin_name))) continue;
588  if(Contains(name, "_PRC_")) continue;
589  return static_cast<RooRealVar*>(arg)->getVal();
590  }
591  iter.Reset();
592  return -1.;
593 }
594 
595 double GetLambdaErr(RooWorkspace &w,
596  const RooFitResult &f,
597  const string &bin_name){
598  RooArgSet funcs = w.allFunctions();
599  TIter iter(funcs.createIterator());
600  int size = funcs.getSize();
601  RooAbsArg *arg = nullptr;
602  int i = 0;
603  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
604  ++i;
605  if(arg == nullptr) continue;
606  string name = arg->GetName();
607  if(name.substr(0,12) != "kappamc_BLK_") continue;
608  if(!(Contains(name, "_BIN_"+bin_name))) continue;
609  if(Contains(name, "_PRC_")) continue;
610  return GetError(*static_cast<RooAbsReal*>(arg), f);
611  }
612  iter.Reset();
613  return -1.;
614 }
615 
616 RooRealVar * SetVariables(RooWorkspace &w,
617  const RooFitResult &f){
618  bool set_r = false;
619  RooArgList pars = f.floatParsFinal();
620  for(int ipar = 0; ipar < pars.getSize(); ++ipar){
621  RooRealVar *fit_var = static_cast<RooRealVar*>(pars.at(ipar));
622  if(fit_var == nullptr) continue;
623  RooRealVar *w_var = w.var(fit_var->GetName());
624  if(w_var == nullptr) continue;
625  w_var->removeRange();
626  w_var->setVal(fit_var->getVal());
627  w_var->setError(fit_var->getError());
628  if(fit_var->GetName() == string("r")) set_r = true;
629  }
630  vector<string> var_names = GetVarNames(w);
631  vector<string> func_names = GetFuncNames(w);
632  for(const auto &var: var_names){
633  RooRealVar *varo = w.var(var.c_str());
634  if(varo == nullptr) continue;
635  if(!varo->isConstant()){
636  varo->removeRange();
637  }
638  }
639 
640  RooRealVar *r_var = static_cast<RooRealVar*>(w.var("r"));
641  if(r_var != nullptr){
642  if(!set_r){
643  r_var->setVal(0);
644  r_var->setConstant(true);
645  }else{
646  r_var->setConstant(false);
647  }
648  }
649  return r_var;
650 }
651 
652 void MakeYieldPlot(RooWorkspace &w,
653  const RooFitResult &f,
654  const string &file_name,
655  bool linear){
656  RooRealVar *r_var = SetVariables(w, f);
657 
658  vector<string> bin_names = GetBinNames(w, r4_only);
659  vector<string> prc_names = GetProcessNames(w);
660 
661  vector<vector<double> > component_yields = GetComponentYields(w, bin_names, prc_names);
662 
663  vector<TH1D> histos = MakeBackgroundHistos(component_yields, bin_names, prc_names);
664  TH1D signal = MakeTotalHisto(w, f, bin_names);
665  TH1D exp_signal = MakeExpSignal(w, bin_names) + signal;
666  exp_signal.SetLineColor(kRed+1);
667  exp_signal.SetFillColor(0);
668  exp_signal.SetFillStyle(0);
669  TGraphErrors band = MakeErrorBand(signal);
670  TH1D obs = MakeObserved(w, bin_names);
671 
672  SetBounds(obs, signal, histos);
673 
674  TCanvas c("can","");
675  c.cd();
676  TPad bot_pad("bot_pad", "bot_pad", 0., 0., 1., 0.4);
677  bot_pad.SetFillColor(0); bot_pad.SetFillStyle(4000);
678  bot_pad.SetMargin(0.1, 0., 0.5, 0.);
679  bot_pad.Draw();
680  c.cd();
681  TPad mid_pad("mid_pad", "mid_pad", 0., 0.4, 1., 0.85);
682  mid_pad.SetFillColor(0); mid_pad.SetFillStyle(4000);
683  mid_pad.SetMargin(0.1, 0., 0.0, 0.);
684  if(!linear) mid_pad.SetLogy();
685  mid_pad.Draw();
686  c.cd();
687  TPad top_pad("top_pad", "top_pad", 0., 0.85, 1., 1.0);
688  top_pad.SetFillColor(0); top_pad.SetFillStyle(4000);
689  top_pad.SetMargin(0.1, 0., 0.0, 0.);
690  top_pad.Draw();
691 
692  double font_size = 0.1;
693  double offset = 0.5;
694 
695  mid_pad.cd();
696  signal.SetTitleSize(font_size, "Y");
697  signal.SetTitleOffset(offset, "Y");
698  signal.SetFillColor(kRed+1);
699  signal.SetFillStyle(1001);
700  signal.SetLineColor(2);
701  signal.SetLineStyle(1);
702  signal.SetLineWidth(0);
703  if(linear) signal.SetMinimum(0.);
704  else signal.SetMinimum(0.03);
705  signal.Draw("hist");
706  for(auto h = histos.rbegin(); h!= histos.rend(); ++h){
707  if(linear) h->SetMinimum(0.);
708  else h->SetMinimum(0.03);
709  h->Draw("same");
710  }
711 
712  double marker_size(1.4);
713  obs.SetMarkerStyle(20); obs.SetMarkerSize(marker_size);
714  band.Draw("02 same");
715  if(linear) obs.SetMinimum(0.);
716  else obs.SetMinimum(0.03);
717  obs.Draw("e0 x0 p0 same");
718  if(linear) signal.SetMinimum(0.);
719  else signal.SetMinimum(0.03);
720  signal.Draw("same axis");
721  if(linear) exp_signal.SetMinimum(0.);
722  else exp_signal.SetMinimum(0.03);
723  if(Contains(file_name, "bkg")) exp_signal.Draw("hist same");
724 
725  top_pad.cd();
726  TLegend l(0.1, 0., 1., 1.);
727  l.SetNColumns(3);
728  l.SetFillColor(0); l.SetFillStyle(4000);
729  l.SetBorderSize(0);
730  l.AddEntry(&obs, "Observed", "lep");
731  if(r_var->isConstant()){
732  l.AddEntry(&exp_signal, "Expected Signal", "l");
733  }else{
734  l.AddEntry(&signal, "Fitted Signal", "f");
735  }
736  ostringstream oss;
737  oss << setprecision(6) << fixed;
738  oss << "r=";
739  if(r_var == nullptr){
740  oss << "???";
741  }else if(r_var->isConstant()){
742  oss << r_var->getVal() << " (fixed)";
743  }else{
744  oss << r_var->getVal() << "#pm" << GetError(*r_var, f);
745  }
746  oss << flush;
747  l.AddEntry(&obs, oss.str().c_str(), "");
748  for(auto h = histos.crbegin(); h != histos.crend(); ++h){
749  l.AddEntry(&(*h), h->GetName(), "f");
750  }
751  l.Draw("same");
752 
753  bot_pad.cd();
754  TLine line; line.SetLineStyle(2);
755  TGraphErrors obs_rat = MakeRatio(obs, signal);
756  TGraphErrors pred_rat = MakeRatio(signal, signal);
757  TH1D dumb = obs;
758  obs_rat.SetMarkerStyle(20); obs_rat.SetMarkerSize(marker_size);
759  obs_rat.SetMarkerColor(1);
760  dumb.SetLineColor(0);
761  dumb.SetLineWidth(0);
762  dumb.SetFillColor(0);
763  dumb.SetFillStyle(4000);
764  dumb.SetMinimum(0.);
765  dumb.SetMaximum(2.8);
766  dumb.SetTitle(";;Obs/Pred ");
767  dumb.GetXaxis()->LabelsOption("V");
768  dumb.SetTitleSize(font_size, "Y");
769  dumb.SetTitleOffset(offset, "Y");
770  dumb.Draw();
771  pred_rat.SetFillColor(kGray);
772  pred_rat.SetFillStyle(3001);
773  pred_rat.Draw("02 same");
774  obs_rat.Draw("ep0 same");
775  line.DrawLine(0.5, 1, 0.5+dumb.GetNbinsX(), 1);
776  c.Print(file_name.c_str());
777 }
778 
779 vector<string> GetVarNames(const RooWorkspace &w){
780  vector<string> names;
781  TIter iter(w.allVars().createIterator());
782  int size = w.allVars().getSize();
783  TObject *obj = nullptr;
784  int i = 0;
785  while((obj = iter()) && i < size){
786  ++i;
787  if(obj == nullptr) continue;
788  string name = obj->GetName();
789  Append(names, name);
790  }
791  iter.Reset();
792  sort(names.begin(), names.end());
793  return names;
794 }
795 
796 vector<string> GetFuncNames(const RooWorkspace &w){
797  vector<string> names;
798  RooArgSet funcs = w.allFunctions();
799  TIter iter(funcs.createIterator());
800  int size = funcs.getSize();
801  TObject *obj = nullptr;
802  int i = 0;
803  while((obj = iter()) && i < size){
804  ++i;
805  if(obj == nullptr) continue;
806  string name = obj->GetName();
807  Append(names, name);
808  }
809  iter.Reset();
810  //sort(names.begin(), names.end());
811  return names;
812 }
813 
814 void ManuallyAddBins(const RooWorkspace &w, vector<string> &names){
815  RooArgSet funcs = w.allFunctions();
816  vector<string> blocks = {"lowmet", "medmet", "highmet"};
817  vector<string> regions = {"r1", "r2", "r3", "r4"};
818  vector<string> njets = {"", "lownj", "highnj"};
819  vector<string> nbs = {"allnb", "1b", "2b", "3b"};
820  for(const auto &block: blocks){
821  for(const auto &region: regions){
822  for(const auto &nj: njets){
823  for(const auto &nb: nbs){
824  string name = "nexp_BLK_"+block+"_BIN_"+region+"_"+block+"_"+(nj==""?string(""):nj+"_")+nb;
825  if(funcs.find(name.c_str())) names.push_back(name);
826  }
827  }
828  }
829  }
830 }
831 
832 vector<string> GetBinNames(const RooWorkspace &w, bool r4_only_local){
833  vector<string> func_names = GetFuncNames(w);
834  vector<string> names;
835  for(const auto &name: func_names){
836  if(name.substr(0,9) != "nexp_BLK_") continue;
837  if(!Contains(name, "r4") && r4_only_local) continue;
838  string bin_name = name.substr(5);
839  Append(names, bin_name);
840  }
841  //reverse(names.begin(), names.end());
842  return names;
843 }
844 
845 vector<string> GetPlainBinNames(const RooWorkspace &w){
846  vector<string> func_names = GetFuncNames(w);
847  vector<string> names;
848  for(const auto &name: func_names){
849  if(name.substr(0,9) != "nexp_BLK_") continue;
850  auto bpos = name.find("_BIN_");
851  auto ppos = name.find("_PRC_");
852  if(bpos == string::npos) continue;
853  string bin_name = name.substr(bpos+5, ppos-bpos-5);
854  Append(names, bin_name);
855  }
856  //reverse(names.begin(), names.end());
857  return names;
858 }
859 
860 vector<string> GetProcessNames(const RooWorkspace &w){
861  vector<string> names;
862  RooArgSet funcs = w.allFunctions();
863  TIter iter(funcs.createIterator());
864  int size = funcs.getSize();
865  RooAbsArg *arg = nullptr;
866  int i = 0;
867  while((arg = static_cast<RooAbsArg*>(iter())) && i < size){
868  ++i;
869  if(arg == nullptr) continue;
870  string name = arg->GetName();
871  if(name.substr(0,9) != "frac_BIN_") continue;
872  auto prc_pos = name.find("_PRC_");
873  if(prc_pos == string::npos) continue;
874  string bin_name = name.substr(prc_pos+5);
875  if(find(names.cbegin(), names.cend(), bin_name) != names.cend()) continue;
876  Append(names, bin_name);
877  }
878  iter.Reset();
879  return names;
880 }
881 
882 vector<vector<double> > GetComponentYields(const RooWorkspace &w,
883  const vector<string> &bin_names,
884  const vector<string> &prc_names){
885  vector<vector<double> > yields(bin_names.size());
886  for(auto &bin: yields){
887  bin = vector<double>(prc_names.size(), 0.);
888  }
889  for(size_t ibin = 0; ibin < yields.size(); ++ibin){
890  const string &bin_name = bin_names.at(ibin);
891  auto blk_pos = bin_name.find("_BIN_");
892  if(blk_pos == string::npos) continue;
893  string plain_name = bin_name.substr(blk_pos+5);
894  for(size_t iprc = 0; iprc < yields.at(ibin).size(); ++iprc){
895  const string &prc_name = prc_names.at(iprc);
896  RooRealVar *nbkg_arg = static_cast<RooRealVar*>(w.function(("nbkg_"+bin_name).c_str()));
897  if(nbkg_arg == nullptr) continue;
898  RooRealVar *frac_arg = static_cast<RooRealVar*>(w.function(("frac_BIN_"+plain_name+"_PRC_"+prc_name).c_str()));
899  if(frac_arg == nullptr) continue;
900  yields.at(ibin).at(iprc) = nbkg_arg->getVal() * frac_arg->getVal();
901  }
902  }
903  return yields;
904 }
905 
906 vector<TH1D> MakeBackgroundHistos(const vector<vector<double> > &yields,
907  const vector<string> &bin_names,
908  const vector<string> &prc_names){
909  if(yields.size() == 0){
910  return vector<TH1D>();
911  }
912  vector<TH1D> histos(yields.at(0).size(),
913  TH1D("", ";;Yield ", yields.size(), 0.5, yields.size()+0.5));
914  for(size_t ibin = 0; ibin < yields.size(); ++ibin){
915  for(size_t iprc = 0; iprc < yields.at(ibin).size(); ++iprc){
916  histos.at(iprc).SetBinContent(ibin+1, yields.at(ibin).at(iprc));
917  }
918  }
919  for(auto &h: histos) h.SetMinimum(0.03);
920 
921  for(size_t iprc = 0; iprc < histos.size(); ++iprc){
922  TH1D &h = histos.at(iprc);
923  h.SetName(prc_names.at(iprc).c_str());
924  Int_t color = iprc==0 ? TColor::GetColor(9,186,1) :
925  (iprc==1 ? TColor::GetColor(153,220,255) : static_cast<Int_t>(iprc+3));
926  h.SetFillColor(color);
927  h.SetLineColor(color);
928  h.SetLineWidth(0);
929  for(size_t ibin = 0; ibin < bin_names.size(); ++ibin){
930  const string &name = bin_names.at(ibin);
931  auto pos = name.find("_BIN_");
932  if(pos == string::npos) continue;
933  pos = name.find("4");
934  if(pos != string::npos && Contains(file_wspace, "nor4")) continue;
935  string label = name.substr(pos+5);
936  h.GetXaxis()->SetBinLabel(ibin+1, label.c_str());
937  }
938  }
939  sort(histos.begin(), histos.end(),
940  [](const TH1D &a, const TH1D &b) -> bool{return a.Integral() < b.Integral();});
941 
942  for(size_t iprc = histos.size()-1; iprc < histos.size(); --iprc){
943  TH1D &h = histos.at(iprc);
944  for(size_t isum = iprc-1; isum < histos.size(); --isum){
945  h.Add(&histos.at(isum));
946  }
947  }
948 
949  return histos;
950 }
951 
952 TH1D MakeExpSignal(RooWorkspace &w,
953  const vector<string> &bin_names){
954  TH1D h("", ";;Yield ", bin_names.size(), 0.5, bin_names.size()+0.5);
955  h.SetFillColor(0);
956  h.SetFillStyle(0);
957  h.SetLineColor(kRed+1);
958  h.SetLineStyle(2);
959  h.SetMinimum(0.03);
960 
961  for(size_t ibin = 0; ibin < bin_names.size(); ++ibin){
962  h.SetBinError(ibin+1, 0.);
963  string name = bin_names.at(ibin);
964  auto pos = name.find("_BIN_");
965  name = name.substr(pos+5);
966  h.GetXaxis()->SetBinLabel(ibin+1, name.c_str());
967  if(pos != string::npos){
968  h.SetBinContent(ibin+1, GetMCYield(w, name, "signal"));
969  }else{
970  h.SetBinContent(ibin+1, -1.);
971  }
972  }
973 
974  return h;
975 }
976 
977 TH1D MakeTotalHisto(RooWorkspace &w,
978  const RooFitResult &f,
979  const vector<string> &bin_names){
980  TH1D h("signal", ";;Yield ", bin_names.size(), 0.5, bin_names.size()+0.5);
981  h.SetFillColor(kRed+1);
982  h.SetLineColor(kRed+1);
983  h.SetLineWidth(0);
984  h.SetMinimum(0.03);
985 
986  for(size_t ibin = 0; ibin < bin_names.size(); ++ibin){
987  const string &name = bin_names.at(ibin);
988  auto pos = name.find("_BIN_");
989  if(pos == string::npos) continue;
990  string label = name.substr(pos+5);
991  h.GetXaxis()->SetBinLabel(ibin+1, label.c_str());
992  RooRealVar *var = static_cast<RooRealVar*>(w.function(("nexp_"+name).c_str()));
993  if(var == nullptr) continue;
994  h.SetBinContent(ibin+1, var->getVal());
995  h.SetBinError(ibin+1, GetError(*var, f));
996  }
997 
998  return h;
999 }
1000 
1001 TH1D MakeObserved(const RooWorkspace &w,
1002  const vector<string> &bin_names){
1003  TH1D h("observed", ";;Yield ", bin_names.size(), 0.5, bin_names.size()+0.5);
1004  h.SetBinErrorOption(TH1::kPoisson);
1005  h.SetLineColor(1);
1006  h.SetFillColor(0);
1007  h.SetFillStyle(4000);
1008  h.SetMinimum(0.03);
1009 
1010  for(size_t ibin = 0; ibin < bin_names.size(); ++ibin){
1011  const string &name = bin_names.at(ibin);
1012  auto pos = name.find("_BIN_");
1013  if(pos == string::npos) continue;
1014  string label = name.substr(pos+5);
1015  h.GetXaxis()->SetBinLabel(ibin+1, label.c_str());
1016  RooRealVar *var = static_cast<RooRealVar*>(w.var(("nobs_"+name).c_str()));
1017  if(var == nullptr) continue;
1018  h.SetBinContent(ibin+1, var->getVal());
1019  }
1020 
1021  return h;
1022 }
1023 
1024 void SetBounds(TH1D &a,
1025  TH1D &b,
1026  std::vector<TH1D> &cs){
1027  double factor = 0.02;
1028 
1029  double hmax = GetMaximum(a, b, cs);
1030  double hmin = GetMinimum(a, b, cs);
1031  double lmax = log(hmax);
1032  double lmin = log(hmin);
1033  double log_diff = lmax-lmin;
1034  lmin -= factor*log_diff;
1035  lmax += factor*log_diff;
1036  hmin = exp(lmin);
1037  hmax = exp(lmax);
1038  if(!Contains(file_wspace, "nor4")){
1039  a.SetMinimum(hmin);
1040  a.SetMaximum(hmax);
1041  b.SetMinimum(hmin);
1042  b.SetMaximum(hmax);
1043  for(auto &c: cs){
1044  c.SetMinimum(hmin);
1045  c.SetMaximum(hmax);
1046  }
1047  } else {
1048  a.SetMaximum(hmax+1.1*sqrt(hmax));
1049  b.SetMaximum(hmax+1.1*sqrt(hmax));
1050  a.SetMinimum(0);
1051  b.SetMinimum(0);
1052  }
1053 }
1054 
1055 double GetMaximum(const TH1D &a,
1056  const TH1D &b,
1057  const vector<TH1D> &cs){
1058  double the_max = GetMaximum(a);
1059  double this_max = GetMaximum(b);
1060  if(this_max > the_max) the_max = this_max;
1061  for(const auto &c: cs){
1062  this_max = GetMaximum(c);
1063  if(this_max > the_max) the_max = this_max;
1064  }
1065  return the_max;
1066 }
1067 
1068 double GetMinimum(const TH1D &a,
1069  const TH1D &b,
1070  const vector<TH1D> &cs){
1071  double the_min = GetMinimum(a, 0.1);
1072  double this_min = GetMinimum(b, 0.1);
1073  if(this_min < the_min) the_min = this_min;
1074  for(const auto &c: cs){
1075  this_min = GetMinimum(c, 0.1);
1076  if(this_min < the_min) the_min = this_min;
1077  }
1078  return the_min;
1079 }
1080 
1081 double GetMaximum(const TH1D &h, double y){
1082  double the_max = -numeric_limits<double>::max();
1083  for(int bin = 1; bin <= h.GetNbinsX(); ++bin){
1084  double content = h.GetBinContent(bin);
1085  if(content > the_max){
1086  if(content < y){
1087  the_max = content;
1088  }else{
1089  the_max = y;
1090  }
1091  }
1092  }
1093  return the_max;
1094 }
1095 
1096 double GetMinimum(const TH1D &h, double y){
1097  double the_min = numeric_limits<double>::max();
1098  for(int bin = 1; bin <= h.GetNbinsX(); ++bin){
1099  double content = h.GetBinContent(bin);
1100  if(content < the_min){
1101  if(content > y){
1102  the_min = content;
1103  }else{
1104  the_min = y;
1105  }
1106  }
1107  }
1108  return the_min;
1109 }
1110 
1111 TGraphErrors MakeErrorBand(const TH1D &h){
1112  TGraphErrors g(h.GetNbinsX());
1113  for(int bin = 1; bin <= h.GetNbinsX(); ++bin){
1114  g.SetPoint(bin, h.GetBinCenter(bin), h.GetBinContent(bin));
1115  g.SetPointError(bin, 0.5, h.GetBinError(bin));
1116  }
1117  g.SetFillColor(kGray);
1118  g.SetFillStyle(3001);
1119  return g;
1120 }
1121 
1122 TGraphErrors MakeRatio(const TH1D &num, const TH1D &den){
1123  TGraphErrors g(num.GetNbinsX());
1124  double xerror(0.5);
1125  if(&num != &den) xerror = 0;
1126  for(int bin = 1; bin <= num.GetNbinsX(); ++bin){
1127  double x = num.GetBinCenter(bin);
1128  double nc = num.GetBinContent(bin);
1129  double dc = den.GetBinContent(bin);
1130  double ne = num.GetBinError(bin);
1131  double big_num = 0.5*numeric_limits<float>::max();
1132  if(dc != 0.){
1133  g.SetPoint(bin, x, nc/dc);
1134  g.SetPointError(bin, xerror, ne/dc);
1135  }else if(nc == 0.){
1136  g.SetPoint(bin, x, 1.);
1137  g.SetPointError(bin, xerror, big_num);
1138  }else{
1139  g.SetPoint(bin, x, nc > 0. ? big_num : -big_num);
1140  g.SetPointError(bin, xerror, big_num);
1141  }
1142  }
1143  return g;
1144 }
1145 
1146 string StripPath(const string &full_path){
1147  auto pos = full_path.rfind("/");
1148  if(pos != string::npos){
1149  return full_path.substr(pos+1);
1150  }else{
1151  return full_path;
1152  }
1153 }
1154 
1155 void MakeCorrectionPlot(RooWorkspace &w,
1156  const RooFitResult &f,
1157  const string &file_name){
1158  SetVariables(w, f);
1159 
1160  vector<string> bin_names = GetBinNames(w);
1161  vector<string> prc_names = GetProcessNames(w);
1162 
1163  TCanvas c("can","");
1164  c.cd();
1165 
1166  TH1D h("", ";;#lambda", bin_names.size(), 0.5, bin_names.size()+0.5);
1167  for(size_t ibin = 0; ibin < bin_names.size(); ++ibin){
1168  string bin = bin_names.at(ibin);
1169  auto pos = bin.find("_BIN_");
1170  string plain_bin = bin.substr(pos+5);
1171  h.GetXaxis()->SetBinLabel(ibin+1, plain_bin.c_str());
1172  h.SetBinContent(ibin+1, static_cast<RooRealVar*>(w.function(("kappamc_"+bin).c_str()))->getVal());
1173  h.SetBinError(ibin+1, GetError(*w.function(("kappamc_"+bin).c_str()), f));
1174  }
1175  h.GetXaxis()->LabelsOption("V");
1176  h.Draw();
1177  c.SetMargin(0.1, 0.05, 1./3., 0.05);
1178  c.Print(file_name.c_str());
1179 }
1180 
1181 void MakeCovarianceMatrix(RooWorkspace &w,
1182  const RooFitResult &f,
1183  string covar_file_name){
1184  SetVariables(w, f);
1185  const RooArgList &fpf = f.floatParsFinal();
1186 
1187  vector<RooAbsReal*> yields;
1188  RooArgSet funcs = w.allFunctions();
1189  TIter iter(funcs.createIterator());
1190  int size = funcs.getSize();
1191  RooAbsReal *arg = nullptr;
1192  int i = 0;
1193  while((arg = static_cast<RooAbsReal*>(iter())) && i < size){
1194  ++i;
1195  if(arg == nullptr) continue;
1196  string name = arg->GetName();
1197  if(name.substr(0,9) != "nbkg_BLK_") continue;
1198  if(!Contains(name, "_BIN_")) continue;
1199  if(Contains(name, "_PRC_")) continue;
1200  if(r4_only && !Contains(name, "r4_")) continue;
1201  yields.push_back(arg);
1202  }
1203 
1204  vector<vector<double> > errors(fpf.getSize(), vector<double>(yields.size(), 0.));
1205  for(Int_t iparam = 0; iparam<fpf.getSize(); ++iparam){
1206  RooRealVar &rrv = static_cast<RooRealVar&>(*w.var(fpf.at(iparam)->GetName()));
1207 
1208  double cenVal = rrv.getVal();
1209  double minVal = rrv.getMin();
1210  double maxVal = rrv.getMax();
1211  double downVal = cenVal-fabs(rrv.getErrorLo());
1212  double upVal = cenVal+fabs(rrv.getErrorHi());
1213  if(upVal-downVal >= maxVal-minVal){
1214  //Error bars bigger than variable range
1215  downVal = minVal;
1216  upVal = maxVal;
1217  }else if(downVal < minVal){
1218  upVal += minVal - downVal;
1219  downVal = minVal;
1220  }else if(upVal > maxVal){
1221  downVal -= upVal - maxVal;
1222  upVal = maxVal;
1223  }
1224 
1225  rrv.setVal(upVal);
1226  for(size_t iyield = 0; iyield<yields.size(); ++iyield){
1227  errors.at(iparam).at(iyield) = 0.5*yields.at(iyield)->getVal();
1228  }
1229  rrv.setVal(downVal);
1230  for(size_t iyield = 0; iyield<yields.size(); ++iyield){
1231  errors.at(iparam).at(iyield) -= 0.5*yields.at(iyield)->getVal();
1232  }
1233  rrv.setVal(cenVal);
1234  }
1235 
1236  vector<vector<double> > right(fpf.getSize(), vector<double>(yields.size(), 0.));
1237  for(Int_t iparam = 0; iparam<fpf.getSize(); ++iparam){
1238  for(size_t iyield = 0; iyield<yields.size(); ++iyield){
1239  right.at(iparam).at(iyield) = 0.;
1240  for(Int_t entry = 0; entry<fpf.getSize(); ++entry){
1241  right.at(iparam).at(iyield) += f.correlation(fpf.at(iparam)->GetName(),fpf.at(entry)->GetName())
1242  * errors.at(entry).at(iyield);
1243  }
1244  }
1245  }
1246 
1247  vector<vector<double> > covar(yields.size(), vector<double>(yields.size(), 0.));
1248  for(size_t irow = 0; irow < yields.size(); ++irow){
1249  for(size_t icol = 0.; icol < yields.size(); ++icol){
1250  covar.at(irow).at(icol) = 0.;
1251  for(Int_t ientry = 0.; ientry < fpf.getSize(); ++ientry){
1252  covar.at(irow).at(icol) += errors.at(ientry).at(irow) * right.at(ientry).at(icol);
1253  }
1254  }
1255  }
1256 
1257  TH2D h_covar("", "",
1258  covar.size(), -0.5, covar.size()-0.5,
1259  covar.size(), -0.5, covar.size()-0.5);
1260  TH2D h_corr("", "",
1261  covar.size(), -0.5, covar.size()-0.5,
1262  covar.size(), -0.5, covar.size()-0.5);
1263  h_covar.SetLabelSize(0.015, "xy");
1264  h_covar.SetMarkerSize(12.5/covar.size());
1265  h_covar.SetTickLength(0., "xy");
1266  h_corr.SetLabelSize(0.015, "xy");
1267  h_corr.SetMarkerSize(12.5/covar.size());
1268  h_corr.SetTickLength(0., "xy");
1269  for(size_t x = 0; x < yields.size(); ++x){
1270  string name = yields.at(x)->GetName();
1271  auto pos = name.find("_BIN_");
1272  name = name.substr(pos+5);
1273  name = PrettyBinName(name);
1274  h_covar.GetXaxis()->SetBinLabel(x+1, name.c_str());
1275  h_covar.GetYaxis()->SetBinLabel(x+1, name.c_str());
1276  h_corr.GetXaxis()->SetBinLabel(x+1, name.c_str());
1277  h_corr.GetYaxis()->SetBinLabel(x+1, name.c_str());
1278  for(size_t y = 0; y < yields.size(); ++y){
1279  h_covar.SetBinContent(x+1,y+1,covar.at(x).at(y));
1280  h_corr.SetBinContent(x+1,y+1,covar.at(x).at(y)/sqrt(covar.at(x).at(x)*covar.at(y).at(y)));
1281  }
1282  }
1283  h_corr.SetMinimum(-1.);
1284  h_corr.SetMaximum(1.);
1285 
1286  const unsigned num = 3;
1287  const int bands = 255;
1288  int colors[bands];
1289  double stops[num] = {0.0, 0.5, 1.0};
1290  double red[num] = {0.0, 1.0, 1.0};
1291  double green[num] = {0.0, 1.0, 0.0};
1292  double blue[num] = {1.0, 1.0, 0.0};
1293  int fi = TColor::CreateGradientColorTable(num, stops, red, green, blue, bands);
1294  for(int ib = 0; ib < bands; ++ib){
1295  colors[ib] = fi+ib;
1296  }
1297  gStyle->SetNumberContours(bands);
1298  gStyle->SetPalette(bands, colors);
1299 
1300  TCanvas c("can", "", 1024, 1024);
1301  c.SetMargin(0.2, 0.05, 0.2, 0.05);
1302  gStyle->SetPaintTextFormat("6.1f");
1303  h_covar.LabelsOption("v","x");
1304  h_corr.LabelsOption("v","x");
1305  h_covar.Draw("axis");
1306  h_corr.Draw("col same");
1307  h_covar.Draw("text same");
1308 
1309 
1310  TLatex ltitle(c.GetLeftMargin(), 1.-0.5*c.GetTopMargin(),
1311  "#font[62]{CMS}#scale[0.76]{#font[52]{ Preliminary}}");
1312  TLatex rtitle(1.-c.GetRightMargin(), 1.-0.5*c.GetTopMargin(),
1313  "#scale[0.8]{35.9 fb^{-1} (13 TeV)}");
1314  ltitle.SetNDC();
1315  rtitle.SetNDC();
1316  ltitle.SetTextAlign(12);
1317  rtitle.SetTextAlign(32);
1318 
1319  ltitle.Draw("same");
1320  rtitle.Draw("same");
1321  c.Print(covar_file_name.c_str());
1322 
1323  TString fitname = "Global";
1324  if(Contains(covar_file_name, "nor4")) {
1325  fitname = "Predictive";
1326  }
1327  TString pname = covar_file_name; pname.ReplaceAll(".pdf", ".root");
1328  TFile file(pname, "recreate");
1329  file.cd();
1330  h_covar.Write("CovarianceMatrix_"+fitname+"Fit");
1331  file.Close();
1332  cout<<"Saved correlation matrix in "<<pname<<endl<<endl;
1333 
1334  gStyle->SetPaintTextFormat("6.2f");
1335  c.SetLogz(false);
1336  h_corr.Draw("col");
1337  h_corr.Draw("text same");
1338  ReplaceAll(covar_file_name, "_covar.pdf", "_corr.pdf");
1339  ltitle.Draw("same");
1340  rtitle.Draw("same");
1341  c.Print(covar_file_name.c_str());
1342 
1343  pname = covar_file_name; pname.ReplaceAll(".pdf", ".root");
1344  TFile fileCorr(pname, "recreate");
1345  fileCorr.cd();
1346  h_corr.Write("CorrelationMatrix_"+fitname+"Fit");
1347  fileCorr.Close();
1348  cout<<"Saved correlation matrix in "<<pname<<endl<<endl;
1349 }
1350 
1351 double GetError(const RooAbsReal &var,
1352  const RooFitResult &f){
1353  // Clone self for internal use
1354  RooAbsReal* cloneFunc = static_cast<RooAbsReal*>(var.cloneTree());
1355  RooArgSet* errorParams = cloneFunc->getObservables(f.floatParsFinal());
1356  RooArgSet* nset = cloneFunc->getParameters(*errorParams);
1357 
1358  // Make list of parameter instances of cloneFunc in order of error matrix
1359  RooArgList paramList;
1360  const RooArgList& fpf = f.floatParsFinal();
1361  vector<int> fpf_idx;
1362  for (int i=0; i<fpf.getSize(); i++) {
1363  RooAbsArg* par = errorParams->find(fpf[i].GetName());
1364  if (par) {
1365  paramList.add(*par);
1366  fpf_idx.push_back(i);
1367  }
1368  }
1369 
1370  vector<double> errors(paramList.getSize());
1371  for (Int_t ivar=0; ivar<paramList.getSize(); ivar++) {
1372  RooRealVar& rrv = static_cast<RooRealVar&>(fpf[fpf_idx[ivar]]);
1373 
1374  double cenVal = rrv.getVal();
1375  double minVal = rrv.getMin();
1376  double maxVal = rrv.getMax();
1377  double downVal = cenVal-fabs(rrv.getErrorLo());
1378  double upVal = cenVal+fabs(rrv.getErrorHi());
1379  if(upVal-downVal >= maxVal-minVal){
1380  //Error bars bigger than variable range
1381  downVal = minVal;
1382  upVal = maxVal;
1383  }else if(downVal < minVal){
1384  upVal += minVal - downVal;
1385  downVal = minVal;
1386  }else if(upVal > maxVal){
1387  downVal -= upVal - maxVal;
1388  upVal = maxVal;
1389  }
1390 
1391  // Make Plus variation
1392  static_cast<RooRealVar*>(paramList.at(ivar))->setVal(upVal);
1393  double up = cloneFunc->getVal(nset);
1394 
1395  // Make Minus variation
1396  static_cast<RooRealVar*>(paramList.at(ivar))->setVal(downVal);
1397  double down = cloneFunc->getVal(nset);
1398 
1399  errors.at(ivar) = 0.5*(up-down);
1400 
1401  static_cast<RooRealVar*>(paramList.at(ivar))->setVal(cenVal);
1402  }
1403 
1404  vector<double> right(errors.size());
1405  for(size_t i = 0; i < right.size(); ++i){
1406  right.at(i) = 0.;
1407  for(size_t j = 0; j < errors.size(); ++j){
1408  right.at(i) += f.correlation(paramList.at(i)->GetName(),paramList.at(j)->GetName())*errors.at(j);
1409  }
1410  }
1411  double sum = 0.;
1412  for(size_t i = 0; i < right.size(); ++i){
1413  sum += errors.at(i)*right.at(i);
1414  }
1415 
1416  if(cloneFunc != nullptr){
1417  delete cloneFunc;
1418  cloneFunc = nullptr;
1419  }
1420  if(errorParams != nullptr){
1421  delete errorParams;
1422  errorParams = nullptr;
1423  }
1424  if(nset != nullptr){
1425  delete nset;
1426  nset = nullptr;
1427  }
1428 
1429  return sqrt(sum);
1430 }
1431 
1432 string PrettyBinName(string name){
1433  ReplaceAll(name, "r1_", "R1: ");
1434  ReplaceAll(name, "r2_", "R2: ");
1435  ReplaceAll(name, "r3_", "R3: ");
1436  ReplaceAll(name, "r4_", "R4: ");
1437  ReplaceAll(name, "lowmet", "200<p_{T}^{miss}#leq 350");
1438  ReplaceAll(name, "medmet", "350<p_{T}^{miss}#leq 500");
1439  ReplaceAll(name, "highmet", "p_{T}^{miss}>500");
1440  ReplaceAll(name, "_lownj", ", 6#leq N_{jets}#leq 8");
1441  ReplaceAll(name, "_highnj", ", N_{jets}#geq 9");
1442  ReplaceAll(name, "_1b", ", N_{b}=1");
1443  ReplaceAll(name, "_2b", ", N_{b}=2");
1444  ReplaceAll(name, "_3b", ", N_{b}#geq 3");
1445  ReplaceAll(name, "_allnb", "");
1446  return name;
1447 }
1448 
1449 void GetOptionsExtract(int argc, char *argv[]){
1450  while(true){
1451  static struct option long_options[] = {
1452  {"file_wspace", required_argument, 0, 'f'},
1453  {"table_clean", no_argument, 0, 'c'},
1454  {"r4_only", no_argument, 0, '4'},
1455  {"exp_sig", no_argument, 0, 's'},
1456  {"global", no_argument, 0, 'g'},
1457  {0, 0, 0, 0}
1458  };
1459 
1460  char opt = -1;
1461  int option_index;
1462  opt = getopt_long(argc, argv, "f:c4sg", long_options, &option_index);
1463  if( opt == -1) break;
1464 
1465  string optname;
1466  switch(opt){
1467  case 'f':
1468  file_wspace = optarg;
1469  break;
1470  case 'c':
1471  table_clean = true;
1472  break;
1473  case '4':
1474  r4_only = true;
1475  break;
1476  case 's':
1477  show_exp_sig = true;
1478  break;
1479  case 'g':
1480  do_global = true;
1481  break;
1482  case 0:
1483  optname = long_options[option_index].name;
1484  if(false){
1485  }else{
1486  printf("Bad option! Found option name %s\n", optname.c_str());
1487  }
1488  break;
1489  default:
1490  printf("Bad option! getopt_long returned character code 0%o\n", opt);
1491  break;
1492  }
1493  }
1494 }
void Append(T &collection, const typename T::value_type &value)
Definition: utilities.hpp:48
string TexFriendly(const string &s)
#define DBG(x)
Definition: utilities.hpp:16
void PrintDebug(RooWorkspace &w, const RooFitResult &f, const string &file_name)
void PrintTable(RooWorkspace &w, const RooFitResult &f, const string &file_name)
double GetBkgPredErr(RooWorkspace &w, const RooFitResult &f, const string &bin_name)
void MakeCovarianceMatrix(RooWorkspace &w, const RooFitResult &f, string covar_file_name)
vector< string > GetPlainBinNames(const RooWorkspace &w)
vector< string > GetProcessNames(const RooWorkspace &w)
void setDefaultStyle()
Definition: styles.cpp:36
double GetLambdaErr(RooWorkspace &w, const RooFitResult &f, const string &bin_name)
double GetKappaNoSys(const RooWorkspace &w, const string &bin_name)
double GetMCTotal(const RooWorkspace &w, const string &bin_name)
void ReplaceAll(std::string &str, const std::string &orig, const std::string &rep)
Definition: utilities.cpp:34
double GetSigPredErr(RooWorkspace &w, const RooFitResult &f, const string &bin_name)
STL namespace.
void SetBounds(TH1D &a, TH1D &b, std::vector< TH1D > &cs)
TH1D MakeObserved(const RooWorkspace &w, const vector< string > &bin_names)
void GetOptionsExtract(int argc, char *argv[])
bool Contains(const std::string &str, const std::string &pat)
Definition: utilities.cpp:26
double GetMCTotalErr(RooWorkspace &w, const RooFitResult &f, const string &bin_name)
double GetBkgPred(const RooWorkspace &w, const string &bin_name)
double GetKappaSys(const RooWorkspace &w, const string &bin_name)
double GetMaximum(const TH1D &a, const TH1D &b, const vector< TH1D > &cs)
vector< TH1D > MakeBackgroundHistos(const vector< vector< double > > &yields, const vector< string > &bin_names, const vector< string > &prc_names)
RooRealVar * SetVariables(RooWorkspace &w, const RooFitResult &f)
double GetSigPred(const RooWorkspace &w, const string &bin_name)
std::string execute(const std::string &cmd)
Definition: utilities.cpp:87
double GetObserved(const RooWorkspace &w, const string &bin_name)
double GetError(const RooAbsReal &var, const RooFitResult &f)
double GetMCYield(const RooWorkspace &w, const string &bin_name, const string &prc_name)
def GetColor(index)
TH1D MakeExpSignal(RooWorkspace &w, const vector< string > &bin_names)
std::string ChangeExtension(std::string path, const std::string &new_ext)
Definition: utilities.cpp:115
vector< string > GetBinNames(const RooWorkspace &w, bool r4_only_local)
void RunFit(const string &path)
vector< string > GetVarNames(const RooWorkspace &w)
#define ERROR(x)
Definition: utilities.hpp:15
string PrettyBinName(string name)
void MakeCorrectionPlot(RooWorkspace &w, const RooFitResult &f, const string &file_name)
def style(h, width, style, color)
double GetLambda(const RooWorkspace &w, const string &bin_name)
vector< string > GetFuncNames(const RooWorkspace &w)
TH1D MakeTotalHisto(RooWorkspace &w, const RooFitResult &f, const vector< string > &bin_names)
TGraphErrors MakeRatio(const TH1D &num, const TH1D &den)
TGraphErrors MakeErrorBand(const TH1D &h)
void MakeYieldPlot(RooWorkspace &w, const RooFitResult &f, const string &file_name, bool linear)
void ManuallyAddBins(const RooWorkspace &w, vector< string > &names)
string StripPath(const string &full_path)
vector< vector< double > > GetComponentYields(const RooWorkspace &w, const vector< string > &bin_names, const vector< string > &prc_names)
double GetKappaNoSysErr(RooWorkspace &w, const RooFitResult &f, const string &bin_name)
double GetTotPredErr(RooWorkspace &w, const RooFitResult &f, const string &bin_name)
double GetTotPred(const RooWorkspace &w, const string &bin_name)
string GetSignalName(const RooWorkspace &w)
int main(int argc, char *argv[])
double GetKappaSysErr(RooWorkspace &w, const RooFitResult &f, const string &bin_name)
double GetMinimum(const TH1D &a, const TH1D &b, const vector< TH1D > &cs)