ra4_draw  4bd0201e3d922d42bd545d4b045ed44db33454a4
table_preds.cxx
Go to the documentation of this file.
1 
5 #include <fstream>
6 #include <iostream>
7 #include <vector>
8 #include <ctime>
9 #include <iomanip> // setw
10 #include <chrono>
11 
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <getopt.h>
15 
16 #include "TError.h" // Controls error level reporting
17 #include "RooStats/NumberCountingUtils.h"
18 #include "TCanvas.h"
19 #include "TGraphAsymmErrors.h"
20 #include "TH1D.h"
21 #include "TLine.h"
22 #include "TLatex.h"
23 #include "TLegend.h"
24 
25 #include "core/utilities.hpp"
26 #include "core/baby.hpp"
27 #include "core/process.hpp"
28 #include "core/named_func.hpp"
29 #include "core/plot_maker.hpp"
30 #include "core/palette.hpp"
31 #include "core/table.hpp"
32 #include "core/abcd_method.hpp"
33 #include "core/styles.hpp"
34 #include "core/plot_opt.hpp"
35 
36 using namespace std;
37 
38 namespace{
39  bool only_mc = true;
40  bool only_kappa = false;
41  bool split_bkg = true;
42  bool only_dilepton = false;
43  bool do_leptons = false;
44  bool do_signal = true;
45  bool unblind = true;
46  bool debug = false;
47  bool do_ht = false;
48  TString skim = "standard";
49  TString json = "2p6";
50  TString only_method = "";
51  TString mc_lumi = "40";
52  float lumi;
53 }
54 
55 TString printTable(abcd_method &abcd, vector<vector<GammaParams> > &allyields,
56  vector<vector<vector<float> > > &kappas, vector<vector<vector<float> > > &preds,
57  vector<shared_ptr<Process> > &proc_sigs);
58 void plotKappa(abcd_method &abcd, vector<vector<vector<float> > > &kappas);
59 void findPreds(abcd_method &abcd, vector<vector<GammaParams> > &allyields,
60  vector<vector<vector<float> > > &kappas, vector<vector<vector<float> > > &preds);
61 void printDebug(abcd_method &abcd, vector<vector<GammaParams> > &allyields, TString baseline,
62  vector<vector<vector<float> > > &kappas, vector<vector<vector<float> > > &preds);
63 TString Zbi(double Nobs, double Nbkg, double Eup_bkg, double Edown_bkg);
64 
65 void GetOptions(int argc, char *argv[]);
66 
68 const NamedFunc st("st", [](const Baby &b) -> NamedFunc::ScalarType{
69  float stvar = b.ht();
70  for (const auto &pt: *(b.leps_pt())) stvar += pt;
71  return stvar;
72  });
73 
74 int main(int argc, char *argv[]){
75  gErrorIgnoreLevel=6000; // Turns off ROOT errors due to missing branches
76  GetOptions(argc, argv);
77 
78  chrono::high_resolution_clock::time_point begTime;
79  begTime = chrono::high_resolution_clock::now();
80 
83  string bfolder("");
84  string hostname = execute("echo $HOSTNAME");
85  if(Contains(hostname, "cms") || Contains(hostname, "compute-"))
86  bfolder = "/net/cms2"; // In laptops, you can't create a /net folder
87 
88  string ntupletag="";
89 
91  string foldermc(bfolder+"/cms2r0/babymaker/babies/2016_08_10/mc/merged_higmc_higtight/");
92  string foldersig(bfolder+"/cms2r0/babymaker/babies/2016_08_10/TChiHH/merged_higmc_higtight/");
93  string folderdata(bfolder+"/cms2r0/babymaker/babies/2016_08_10/data/merged_database_stdnj5/");
94 
95  Palette colors("txt/colors.txt", "default");
96 
97  // Cuts in baseline speed up the yield finding
98  string baseline_s = "hig_drmax<2.2&&ntks==0&&njets>=4&&njets<=5&&!low_dphi&&nvleps==0";
99  NamedFunc baseline=baseline_s;
100 
102  auto proc_bkg = Process::MakeShared<Baby_full>("All_bkg", Process::Type::background, colors("tt_1l"),
103  {foldermc+"*_TTJets_Tune*"+ntupletag+"*.root"},
104  baseline && "stitch && pass");
105 
106  vector<string> sigMasses({"225", "300", "400", "700"});
107  vector<shared_ptr<Process> > proc_sigs;
108  for(size_t ind=0; ind<sigMasses.size(); ind++)
109  proc_sigs.push_back(Process::MakeShared<Baby_full>("TChiHH("+sigMasses[ind]+")", Process::Type::signal, 2,
110  {foldersig+"*mGluino-"+sigMasses[ind]+"_*"+ntupletag+"*.root"}, baseline && "stitch"));
111 
112  auto proc_ttbar = Process::MakeShared<Baby_full>("ttbar", Process::Type::background, colors("tt_1l"),
113  {foldermc+"*_TTJets*"+ntupletag+"*.root"},
114  baseline && "stitch && pass");
115  auto proc_singlet = Process::MakeShared<Baby_full>("singlet", Process::Type::background, colors("tt_2l"),
116  {foldermc+"*_ST_*"+ntupletag+"*.root"},
117  baseline && "stitch && pass");
118 
119  // Filling all other processes
120  vector<string> vnames_other({"_WJetsToLNu", "_TTW", "_TTZ", "DYJetsToLL",
121  "_ZJet", "_ttHJetTobb", "_TTGJets", "_TTTT",
122  "_WH_HToBB", "_ZH_HToBB", "_WWTo", "_WZ", "_ZZ_", "QCD_HT*0_Tune", "QCD_HT*Inf_Tune"});
123  set<string> names_other;
124  for(auto name : vnames_other)
125  names_other.insert(name = foldermc + "*" + name + "*" + ntupletag + "*.root");
126  auto proc_other = Process::MakeShared<Baby_full>("Other", Process::Type::background, colors("other"),
127  names_other, baseline && "stitch && pass");
128 
129  //string trigs = "(trig[4]||trig[8]||trig[13]||trig[33])";
130  string trigs = "trig_ra4";
131  if(skim.Contains("2015")) trigs = "(trig[4]||trig[8]||trig[28]||trig[14])";
132 
133  // Setting luminosity
134  string jsonCuts = "nonblind";
135  if(skim.Contains("2015")) lumi = 2.3;
136  else if(json=="0p815"){
137  lumi = 0.815;
138  jsonCuts = "nonblind";
139  } else if(json=="2p6"){
140  lumi = 2.6;
141  jsonCuts = "json2p6";
142  } else if(json=="1p7"){
143  lumi = 1.7;
144  jsonCuts = "json4p0&&!json2p6";
145  } else if(json=="4p3"){
146  lumi = 4.3;
147  jsonCuts = "json4p0";
148  } else if(json=="7p65"){
149  lumi = 7.65;
150  jsonCuts = "json7p65";
151  } else if(json=="12p9"){
152  lumi = 12.9;
153  jsonCuts = "json12p9";
154  }
155  if(mc_lumi!="") lumi = mc_lumi.Atof();
156 
157 
158  if(only_method.Contains("old")) trigs = "(trig[4]||trig[8])";
159  if(!skim.Contains("2015")) trigs += " && "+jsonCuts;
160 
161  auto proc_data = Process::MakeShared<Baby_full>("Data", Process::Type::data, kBlack,
162  {folderdata+"*"+ntupletag+"*.root"},baseline && trigs && "pass");
163 
164  vector<shared_ptr<Process> > all_procs = {proc_ttbar, proc_singlet, proc_other};
165  //vector<shared_ptr<Process> > all_procs = {proc_bkg};
166  if (do_signal){
167  for(size_t ind=0; ind<proc_sigs.size(); ind++)
168  all_procs.push_back(proc_sigs[ind]);
169  }
170  if(!only_mc) all_procs.push_back(proc_data);
171 
174  // baseline defined above
175 
177  TString c_lowmet = "met>100 && met<=200";
178  TString c_midmet = "met>200 && met<=300";
179  TString c_higmet = "met>300";
180 
182  TString c_2b="nbt==2&&nbm==2";
183  TString c_3b="nbt>=2&&nbm==3&&nbl==3";
184  TString c_4b="nbt>=2&&nbm>=3&&nbl>=4";
185 
187  TString c_sr="hig_am>100&&hig_am<140&&hig_dm<40";
188  TString c_cr="!("+c_sr+")";
189 
191  vector<TString> abcdcuts_std = {c_cr + " && 2bcuts",
192  c_cr + " && nj_1l",
193  c_sr + " && 2bcuts",
194  c_sr + " && nj_1l"};
195 
196 
199  vector<abcd_method> abcds;
200  vector<TString> abcdcuts, metcuts, bincuts;
201  PlotMaker pm;
202 
204  vector<TString> methods = {"TTML", "MMMM"};
205 
206  if(only_method!="") methods = vector<TString>({only_method});
207 
208  for(size_t iabcd=0; iabcd<methods.size(); iabcd++) {
209  TString method = methods[iabcd];
210  TString basecuts = "", caption = "";
211 
212  if(method.Contains("TTML")){
213  c_2b="nbt==2&&nbm==2";
214  c_3b="nbt>=2&&nbm==3&&nbl==3";
215  c_4b="nbt>=2&&nbm>=3&&nbl>=4";
216  caption = "TTML method: 2 tight b-tags, 1 medium, 1 loose";
217  } // TTML
218  if(method.Contains("MMMM")){
219  c_2b="nbm==2";
220  c_3b="nbm==3";
221  c_4b="nbm>=4";
222  caption = "MMMM method: all medium b-tags";
223  } // MMMM
224 
226  abcdcuts = abcdcuts_std;
227  for(size_t ind=0; ind<abcdcuts.size(); ind++)
228  abcdcuts[ind].ReplaceAll("2bcuts", c_2b);
229  metcuts = vector<TString>{c_midmet, c_higmet};
230  bincuts = vector<TString>{c_3b, c_4b};
231 
232 
234  abcds.push_back(abcd_method(method, metcuts, bincuts, abcdcuts, caption, basecuts));
235  if(method.Contains("noint")) abcds.back().setIntNbNj(false);
236 
237  vector<TableRow> table_cuts;
238  for(size_t icut=0; icut < abcds.back().allcuts.size(); icut++)
239  table_cuts.push_back(TableRow(abcds.back().allcuts[icut].Data(), abcds.back().allcuts[icut].Data()));
240 
241  TString tname = "preds"; tname += iabcd;
242  pm.Push<Table>(tname.Data(), table_cuts, all_procs, true, false);
243  } // Loop over ABCD methods
244 
247 
248  bool single_thread = false;
249  if(single_thread) pm.multithreaded_ = false;
250  pm.min_print_ = true;
251  pm.MakePlots(lumi);
252 
255  vector<TString> tablenames;
256  for(size_t imethod=0; imethod<abcds.size(); imethod++) {
257  Table * yield_table = static_cast<Table*>(pm.Figures()[imethod].get());
258  // allyields: [0] data, [1] bkg, [2] T1tttt(NC), [3] T1tttt(C)
259  // if split_bkg [2/4] Other, [3/5] tt1l, [4/6] tt2l
260  vector<vector<GammaParams> > allyields;
261  if(!only_mc) allyields.push_back(yield_table->DataYield());
262  else allyields.push_back(yield_table->BackgroundYield(lumi));
263  allyields.push_back(yield_table->BackgroundYield(lumi));
264  if(do_signal){
265  for(size_t ind=0; ind<proc_sigs.size(); ind++)
266  allyields.push_back(yield_table->Yield(proc_sigs[ind].get(), lumi));
267  }
268  if(split_bkg){
269  allyields.push_back(yield_table->Yield(proc_other.get(), lumi));
270  allyields.push_back(yield_table->Yield(proc_singlet.get(), lumi));
271  allyields.push_back(yield_table->Yield(proc_ttbar.get(), lumi));
272  }
273 
275  vector<vector<vector<float> > > kappas, preds;
276  findPreds(abcds[imethod], allyields, kappas, preds);
277 
279  if(!only_kappa) {
280  TString fullname = printTable(abcds[imethod], allyields, kappas, preds, proc_sigs);
281  tablenames.push_back(fullname);
282  }
283 
285  plotKappa(abcds[imethod], kappas);
286 
288  if(debug) printDebug(abcds[imethod], allyields, TString(baseline.Name()), kappas, preds);
289 
290  } // Loop over ABCD methods
291 
292  if(!only_kappa){
294  cout<<endl<<"===== Tables to be moved to the AN/PAS/paper:"<<endl;
295  for(size_t ind=0; ind<tablenames.size(); ind++){
296  TString name=tablenames[ind]; name.ReplaceAll("fulltable","table");
297  cout<<" mv "<<name<<" ${tables_folder}"<<endl;
298  }
299  cout<<endl<<"===== Tables that can be compiled"<<endl;
300  for(size_t ind=0; ind<tablenames.size(); ind++)
301  cout<<" pdflatex "<<tablenames[ind]<<" > /dev/null"<<endl;
302  cout<<endl;
303  }
304 
305  double seconds = (chrono::duration<double>(chrono::high_resolution_clock::now() - begTime)).count();
306  TString hhmmss = HoursMinSec(seconds);
307  cout<<endl<<"Finding "<<abcds.size()<<" tables took "<<round(seconds)<<" seconds ("<<hhmmss<<")"<<endl<<endl;
308 } // main
309 
314 
316 // allyields: [0] data, [1] bkg, [2] T1tttt(NC), [3] T1tttt(C)
317 // if split_bkg: [2/4] Other, [3/5] tt1l, [4/6] tt2l
318 TString printTable(abcd_method &abcd, vector<vector<GammaParams> > &allyields,
319  vector<vector<vector<float> > > &kappas, vector<vector<vector<float> > > &preds,
320  vector<shared_ptr<Process> > &proc_sigs){
321  cout<<endl<<"Printing table (significance estimation can take a bit)"<<endl;
322 
324  int digits = 2;
325  TString ump = " & ", blind_s = "$\\spadesuit$";
326 
327  size_t Nsig = proc_sigs.size(); // Number of signal points (for now it cannot be changed)
328  bool do_zbi = true;
329  if(!unblind) do_zbi = false;
330  size_t Ncol = 3; // The only colums always printed are the bin names, kappa, and MC bkg.
331  if(split_bkg) Ncol += 3;
332  if(do_signal) Ncol += Nsig;
333  if(only_mc) {
334  if(do_zbi && do_signal) Ncol += Nsig;
335  } else {
336  Ncol += 3;
337  if(do_zbi) Ncol++;
338  }
339 
341  int digits_lumi = 1;
342  if(lumi < 1) digits_lumi = 3;
343  if(lumi >= 15) digits_lumi = 0;
344  TString lumi_s = RoundNumber(lumi, digits_lumi);
345  TString outname = "tables/table_pred_lumi"+lumi_s; outname.ReplaceAll(".","p");
346  if(skim.Contains("2015")) outname += "_2015";
347  if(unblind) outname += "_unblind";
348  else outname += "_blind";
349  outname += "_"+abcd.method+".tex";
350  ofstream out(outname);
351 
353  if(abcd.method.Contains("signal") && Ncol>7) out << "\\resizebox{\\textwidth}{!}{\n";
354  out << "\\begin{tabular}[tbp!]{ l ";
355  if(split_bkg) out << "|ccc";
356  out << "|cc";
357  if(!only_mc) {
358  out << "|ccc";
359  if(do_zbi) out<<"c";
360  } else {
361  if(do_signal)
362  for(size_t ind=0; ind<Nsig; ind++)
363  out<<"|c"<<(do_zbi?"c":"");
364  }
365  out<<"}\\hline\\hline\n";
366  out<<"${\\cal L}="<<lumi_s<<"$ fb$^{-1}$ ";
367  if(split_bkg) out << " & Other & Single $t$ & $t\\bar{t}$ ";
368  out << "& $\\kappa$ & MC bkg.";
369  if(!only_mc) out << " & Pred.& Obs. & Obs./MC "<<(do_zbi?"& Signi.":"");
370  else if(do_signal)
371  for(size_t ind=0; ind<Nsig; ind++) {
372  TString signame = proc_sigs[ind]->name_.c_str();
373  if(do_zbi) out << "& \\multicolumn{2}{c"<<(ind<Nsig-1?"|":"")<<"}{" << signame <<"}";
374  else out << "& " << signame;
375  }
376  out << " \\\\ \\hline\\hline\n";
377 
378  vector<TString> binNames({"SBD, 2b", "SBD, xb", "HIG, 2b", "HIG, xb"});
381  for(size_t iplane=0; iplane < abcd.planecuts.size(); iplane++) {
382  out<<endl<< "\\multicolumn{"<<Ncol<<"}{c}{$"<<CodeToLatex(abcd.planecuts[iplane].Data())<<"$} \\\\ \\hline\n";
383  for(size_t iabcd=0; iabcd < abcd.abcdcuts.size(); iabcd++){
384  for(size_t ibin=0; ibin < abcd.bincuts[iplane].size(); ibin++){
385  size_t index = abcd.indexBin(iplane, ibin, iabcd);
386  if(abcd.int_nbnj && iabcd%2==0 && ibin>0) continue;
387  if(iabcd==3 && ibin==0) out << "\\hline" << endl;
389  TString binName = binNames[iabcd];
390  if(ibin==0) binName.ReplaceAll("xb", "3b");
391  else binName.ReplaceAll("xb", "4b");
392  out << binName;
393  // if(iabcd%2==0 && abcd.int_nbnj)
394  // out << "All "<<(abcd.bincuts[iplane][ibin].Contains("nbm")?"\\nb, ":"")<<"\\njets" ;
395  // else {
396  // if(abcd.method.Contains("2lonly") && iabcd>=2) out<<"$"<<CodeToLatex(abcd.lowerNjets(abcd.bincuts[iplane][ibin]))<<"$";
397  // else if(abcd.method.Contains("2lveto") && iabcd>=2){
398  // if(abcd.bincuts[iplane][ibin].Contains("6")) out<<"Low \\njets";
399  // else out<<"High \\njets";
400  // } else out<<"$"<<CodeToLatex(abcd.bincuts[iplane][ibin])<<"$";
401  // }
403  if(split_bkg){
404  size_t offset = (do_signal?Nsig:0);
405  out << ump <<RoundNumber(allyields[offset+2][index].Yield(), digits)
406  << ump <<RoundNumber(allyields[offset+3][index].Yield(), digits)
407  << ump <<RoundNumber(allyields[offset+4][index].Yield(), digits);
408  }
410  out<<ump;
411  if(iabcd==3) out << "$" << RoundNumber(kappas[iplane][ibin][0], digits)
412  << "^{+" << RoundNumber(kappas[iplane][ibin][1], digits)
413  << "}_{-" << RoundNumber(kappas[iplane][ibin][2], digits) <<"}$ ";
415  out << ump << RoundNumber(allyields[1][index].Yield(), digits);
416  if(!only_mc){
417  out << ump;
419  if(iabcd==3) out << "$" << RoundNumber(preds[iplane][ibin][0], digits)
420  << "^{+" << RoundNumber(preds[iplane][ibin][1], digits)
421  << "}_{-" << RoundNumber(preds[iplane][ibin][2], digits) <<"}$ ";
423  if(!unblind && iabcd==3) out << ump << blind_s<< ump << blind_s;
424  else {
425  out << ump << RoundNumber(allyields[0][index].Yield(), 0);
426  TString ratio_s = "-";
427  double Nobs = allyields[0][index].Yield(), Nmc = allyields[1][index].Yield();
428  double Eobs = sqrt(Nobs), Emc = allyields[1][index].Uncertainty();
429  if(Nobs==0) Eobs=1;
430  if(Emc>0){
431  double ratio = Nobs/Nmc;
432  double Eratio = sqrt(pow(Eobs/Nmc,2) + pow(Nobs*Emc/Nmc/Nmc,2));
433  ratio_s = "$"+RoundNumber(ratio, 2)+"\\pm"+RoundNumber(Eratio,2)+"$";
434  }
435  out << ump << ratio_s;
436  }
438  if(do_zbi && iabcd==3) out << ump << Zbi(allyields[0][index].Yield(), preds[iplane][ibin][0],
439  preds[iplane][ibin][1], preds[iplane][ibin][2]);
441  if(do_signal)
442  for(size_t ind=0; ind<Nsig; ind++)
443  out<<ump<<RoundNumber(allyields[2+ind][index].Yield(), digits);
444  } else {// if not only_mc
445  if(do_signal){
446  for(size_t ind=0; ind<Nsig; ind++) {
447  out<<ump<<RoundNumber(allyields[2+ind][index].Yield(), digits);
448  if(do_zbi){
449  out << ump;
450  if(iabcd==3)
451  out<<Zbi(allyields[0][index].Yield()+allyields[2+ind][index].Yield(),preds[iplane][ibin][0],
452  preds[iplane][ibin][1], preds[iplane][ibin][2]);
453  } // if do_zbi
454  } // Loop over signals
455  } // if do_signal
456  } //if only_mc
457 
458  out << "\\\\ \n";
459  } // Loop over bin cuts
460  } // Loop over ABCD cuts
461  out << "\\hline\\hline\n";
462  } // Loop over plane cuts
464 
466  out<< "\\end{tabular}"<<endl;
467  if(abcd.method.Contains("signal") && Ncol>7) out << "}\n"; // For resizebox
468  out.close();
469 
471  TString fullname = outname; fullname.ReplaceAll("table_","fulltable_");
472  ofstream full(fullname);
473  ifstream header("txt/header.tex");
474  full<<header.rdbuf();
475  header.close();
476  if(!abcd.method.Contains("signal")) full << "\\usepackage[landscape]{geometry}\n\n";
477  full << "\\begin{document}\n\n";
478  full << "\\begin{table}\n\\centering\n";
479  full << "\\caption{" << abcd.caption <<".}\\vspace{0.1in}\n\\label{tab:"<<abcd.method<<"}\n";
480  ifstream outtab(outname);
481  full << outtab.rdbuf();
482  outtab.close();
483  full << "\\end{table}\n\n";
484  full << "\\end{document}\n";
485  full.close();
486 
487  return fullname;
488 } // printTable
489 
491 TString Zbi(double Nobs, double Nbkg, double Eup_bkg, double Edown_bkg){
492  TString zbi_s;
493  if(false){ // Old, bad Zbi
494  double Nsig = Nobs-Nbkg;
495  double zbi = RooStats::NumberCountingUtils::BinomialExpZ(Nsig, Nbkg, Eup_bkg/Nbkg);
496  if(Nbkg==0) zbi = RooStats::NumberCountingUtils::BinomialWithTauExpZ(Nsig, Nbkg, 1/Eup_bkg);
497  if(zbi<0) zbi=0;
498  zbi_s = RoundNumber(zbi,1);
499  if(zbi_s!="-") zbi_s = "$"+zbi_s+"\\sigma$";
500  if(Nsig<=0 || Eup_bkg<=0) zbi_s = "-";
501  } else zbi_s = "$"+RoundNumber(Significance(Nobs, Nbkg, Eup_bkg, Edown_bkg),1)+"\\sigma$";
502  //cout<<"Zbi for Nobs "<<Nobs<<", Nbkg "<<Nbkg<<", Ebkg "<<Eup_bkg<<" is "<<zbi_s<<endl;
503  return zbi_s;
504 }
505 
507 void plotKappa(abcd_method &abcd, vector<vector<vector<float> > > &kappas){
508 
509  bool label_up = false;
510 
512  PlotOpt opts("txt/plot_styles.txt", "Kappa");
513  if(label_up) opts.BottomMargin(0.11);
514  setPlotStyle(opts);
515 
516  struct kmarker{
517  TString cut;
518  int color;
519  int style;
520  vector<float> kappa;
521  };
523  vector<vector<vector<kmarker> > > k_ordered;
524  vector<kmarker> ind_bcuts; // nb cuts actually used in the plot
525  vector<float> zz; // Zero length vector for the kmarker constructor
526  vector<kmarker> bcuts({{"nbm==1",4,20,zz}, {"nbm==2",2,21,zz}, {"nbm>=3",kGreen+3,22,zz}, {"nbm>=2",kMagenta+2,23,zz}});
527 
528  int nbins = 0; // Total number of njets bins (used in the base histo)
529  for(size_t iplane=0; iplane < kappas.size(); iplane++) {
530  k_ordered.push_back(vector<vector<kmarker> >());
531  for(size_t ibin=0; ibin < kappas[iplane].size(); ibin++){
532  TString bincut = abcd.bincuts[iplane][ibin];
533  bincut.ReplaceAll(" ","");
534  bincut.ReplaceAll("mm_","");
535  int index;
536  do{
537  index = bincut.First('[');
538  bincut.Remove(index, bincut.First(']')-index+1);
539  }while(index>=0);
540  bool found=false;
541  for(size_t ib=0; ib<bcuts.size(); ib++){
542  if(bincut.Contains(bcuts[ib].cut)){
544  bool cutfound=false;
545  for(size_t indb=0; indb<ind_bcuts.size(); indb++)
546  if(ind_bcuts[indb].color == bcuts[ib].color) cutfound = true;
547  if(!cutfound) ind_bcuts.push_back(bcuts[ib]);
548 
550  bincut.ReplaceAll(bcuts[ib].cut+"&&","");
551  for(size_t ik=0; ik<k_ordered[iplane].size(); ik++){
553  if(bincut==k_ordered[iplane][ik][0].cut){
554  k_ordered[iplane][ik].push_back({bincut, bcuts[ib].color, bcuts[ib].style, kappas[iplane][ibin]});
555  found = true;
556  break;
557  } // if same njets cut
558  } // Loop over existing ordered kappas
560  if(!found) {
561  k_ordered[iplane].push_back(vector<kmarker>({{bincut, bcuts[ib].color, bcuts[ib].style, kappas[iplane][ibin]}}));
562  found = true;
563  nbins++;
564  }
565  } // if bincut.Contains(bcuts[ib].cut)
566  } // Loop over nb cuts
567 
569  if(!found) {
570  k_ordered[iplane].push_back(vector<kmarker>({{bincut, bcuts[0].color, bcuts[0].style, kappas[iplane][ibin]}}));
571  nbins++;
572  if(ind_bcuts.size()==0) ind_bcuts.push_back(bcuts[0]);
573  }
574  } // Loop over bin cuts
575  } // Loop over plane cuts
576 
578  TCanvas can("can","");
579  can.SetFillStyle(4000);
580  TLine line; line.SetLineWidth(2); line.SetLineStyle(2);
581  TLatex label; label.SetTextSize(0.05); label.SetTextFont(42); label.SetTextAlign(23);
582  if(k_ordered.size()>3) label.SetTextSize(0.04);
583 
584 
585  float minx = 0.5, maxx = nbins+0.5, miny = 0, maxy = 2.4;
586  if(label_up) maxy = 2.6;
587  TH1D histo("histo", "", nbins, minx, maxx);
588  histo.SetMinimum(miny);
589  histo.SetMaximum(maxy);
590  histo.GetYaxis()->CenterTitle(true);
591  histo.GetXaxis()->SetLabelOffset(0.008);
592  histo.SetYTitle("#kappa");
593  histo.Draw();
594 
596  int bin = 0;
597  vector<vector<double> > vx(ind_bcuts.size()), vexh(ind_bcuts.size()), vexl(ind_bcuts.size());
598  vector<vector<double> > vy(ind_bcuts.size()), veyh(ind_bcuts.size()), veyl(ind_bcuts.size());
599  for(size_t iplane=0; iplane < k_ordered.size(); iplane++) {
600  for(size_t ibin=0; ibin < k_ordered[iplane].size(); ibin++){
601  bin++;
602  histo.GetXaxis()->SetBinLabel(bin, CodeToRootTex(k_ordered[iplane][ibin][0].cut.Data()).c_str());
603  // xval is the x position of the first marker in the group
604  double xval = bin, nbs = k_ordered[iplane][ibin].size(), minxb = 0.15, binw = 0;
605  // If there is more than one point in the group, it starts minxb to the left of the center of the bin
606  // binw is the distance between points in the njets group
607  if(nbs>1) {
608  xval -= minxb;
609  binw = 2*minxb/(nbs-1);
610  }
611  for(size_t ib=0; ib<k_ordered[iplane][ibin].size(); ib++){
613  for(size_t indb=0; indb<ind_bcuts.size(); indb++){
614  if(ind_bcuts[indb].color == k_ordered[iplane][ibin][ib].color){
615  vx[indb].push_back(xval);
616  xval += binw;
617  vexl[indb].push_back(0);
618  vexh[indb].push_back(0);
619  vy[indb].push_back(k_ordered[iplane][ibin][ib].kappa[0]);
620  veyl[indb].push_back(k_ordered[iplane][ibin][ib].kappa[1]);
621  veyh[indb].push_back(k_ordered[iplane][ibin][ib].kappa[2]);
622  }
623  } // Loop over nb cuts in ordered TGraphs
624  } // Loop over nb cuts in kappa plot
625  } // Loop over bin cuts
626 
627  // Drawing line separating MET planes
628  line.SetLineStyle(2); line.SetLineWidth(2);
629  if (iplane<k_ordered.size()-1) line.DrawLine(bin+0.5, miny, bin+0.5, maxy);
630  // Drawing MET labels
631  if(label_up) label.DrawLatex((2*bin-k_ordered[iplane].size()+1.)/2., maxy-0.1, CodeToRootTex(abcd.planecuts[iplane].Data()).c_str());
632  else label.DrawLatex((2*bin-k_ordered[iplane].size()+1.)/2., -0.26, CodeToRootTex(abcd.planecuts[iplane].Data()).c_str());
633  } // Loop over plane cuts
634 
636  double legX(opts.LeftMargin()+0.026), legY(1-opts.TopMargin()-0.04), legSingle = 0.05;
637  if(label_up) legY = 0.8;
638  double legW = 0.22, legH = legSingle*(ind_bcuts.size()+1)/2;
639  if(ind_bcuts.size()>3) legH = legSingle*((ind_bcuts.size()+1)/2);
640  TLegend leg(legX, legY-legH, legX+legW, legY);
641  leg.SetTextSize(opts.LegendEntryHeight()); leg.SetFillColor(0);
642  leg.SetFillStyle(0); leg.SetBorderSize(0);
643  leg.SetTextFont(42);
644  leg.SetNColumns(2);
645  TGraphAsymmErrors graph[20]; // There's problems with vectors of TGraphs, so using an array
646  for(size_t indb=0; indb<ind_bcuts.size(); indb++){
647  graph[indb] = TGraphAsymmErrors(vx[indb].size(), &(vx[indb][0]), &(vy[indb][0]),
648  &(vexl[indb][0]), &(vexh[indb][0]), &(veyl[indb][0]), &(veyh[indb][0]));
649  graph[indb].SetMarkerStyle(ind_bcuts[indb].style); graph[indb].SetMarkerSize(1.1);
650  graph[indb].SetMarkerColor(ind_bcuts[indb].color);
651  graph[indb].SetLineColor(ind_bcuts[indb].color); graph[indb].SetLineWidth(2);
652  graph[indb].Draw("p0 same");
653  leg.AddEntry(&graph[indb], CodeToRootTex(ind_bcuts[indb].cut.Data()).c_str(), "p");
654  } // Loop over TGraphs
655  if(ind_bcuts.size()>1) leg.Draw();
656 
658  TLatex cmslabel;
659  cmslabel.SetTextSize(0.06);
660  cmslabel.SetNDC(kTRUE);
661  cmslabel.SetTextAlign(11);
662  cmslabel.DrawLatex(opts.LeftMargin()+0.005, 1-opts.TopMargin()+0.015,"#font[62]{CMS} #scale[0.8]{#font[52]{Simulation}}");
663  cmslabel.SetTextAlign(31);
664  cmslabel.DrawLatex(1-opts.RightMargin()-0.005, 1-opts.TopMargin()+0.015,"#font[42]{13 TeV}");
665 
666  line.SetLineStyle(3); line.SetLineWidth(1);
667  line.DrawLine(minx, 1, maxx, 1);
668 
669  TString fname="plots/kappa_" + abcd.method;
670  fname += ".pdf";
671  can.SaveAs(fname);
672  cout<<endl<<" open "<<fname<<endl;
673 
674 }
675 
677 // allyields: [0] data, [1] bkg, [2] T1tttt(NC), [3] T1tttt(C)
678 void findPreds(abcd_method &abcd, vector<vector<GammaParams> > &allyields,
679  vector<vector<vector<float> > > &kappas, vector<vector<vector<float> > > &preds){
680  // Powers for kappa: ({R1, R2, D3, R4})
681  vector<float> pow_kappa({ 1, -1, -1, 1});
682  // Powers for TotBkg pred:({R1, R2, D3, R1, R2, D3, D4})
683  vector<float> pow_totpred( {-1, 1, 1, 1, -1, -1, 1});
684 
685  float val(1.), valup(1.), valdown(1.);
686 
687  for(size_t iplane=0; iplane < abcd.planecuts.size(); iplane++) {
688  kappas.push_back(vector<vector<float> >());
689  preds.push_back(vector<vector<float> >());
690  for(size_t ibin=0; ibin < abcd.bincuts[iplane].size(); ibin++){
691  vector<vector<float> > entries;
692  vector<vector<float> > weights;
694  for(size_t iabcd=0; iabcd < 3; iabcd++){
695  size_t index = abcd.indexBin(iplane, ibin, iabcd);
696  entries.push_back(vector<float>());
697  weights.push_back(vector<float>());
698  entries.back().push_back(allyields[0][index].Yield());
699  weights.back().push_back(1.);
700  } // Loop over ABCD cuts
701 
702  vector<vector<float> > kentries;
703  vector<vector<float> > kweights;
705  for(size_t iabcd=0; iabcd < 4; iabcd++){
706  size_t index = abcd.indexBin(iplane, ibin, iabcd);
707  // Yields for predictions
708  entries.push_back(vector<float>());
709  weights.push_back(vector<float>());
710  entries.back().push_back(allyields[1][index].NEffective());
711  weights.back().push_back(allyields[1][index].Weight());
712  // Yields for kappas
713  kentries.push_back(vector<float>());
714  kweights.push_back(vector<float>());
715  kentries.back().push_back(allyields[1][index].NEffective());
716  kweights.back().push_back(allyields[1][index].Weight());
717  } // Loop over ABCD cuts
718 
719  // Throwing toys to find predictions and uncertainties
720  val = calcKappa(entries, weights, pow_totpred, valdown, valup);
721  if(valdown<0) valdown = 0;
722  preds[iplane].push_back(vector<float>({val, valup, valdown}));
723  // Throwing toys to find kappas and uncertainties
724  val = calcKappa(kentries, kweights, pow_kappa, valdown, valup);
725  if(valdown<0) valdown = 0;
726  kappas[iplane].push_back(vector<float>({val, valup, valdown}));
727  } // Loop over bin cuts
728  } // Loop over plane cuts
729 
730 } // findPreds
731 
732 // allyields: [0] data, [1] bkg, [2] T1tttt(NC), [3] T1tttt(C)
733 void printDebug(abcd_method &abcd, vector<vector<GammaParams> > &allyields, TString baseline,
734  vector<vector<vector<float> > > &kappas, vector<vector<vector<float> > > &preds){
735 
736  int digits = 3;
737  cout<<endl<<endl<<"=================== Printing cuts for method "<<abcd.method<<" ==================="<<endl;
738  cout<<"-- Baseline cuts: "<<baseline<<endl;
739  for(size_t iplane=0; iplane < abcd.planecuts.size(); iplane++) {
740  cout<<endl<<" **** Plane "<<abcd.planecuts[iplane]<<" ***"<<endl;
741  for(size_t ibin=0; ibin < abcd.bincuts[iplane].size(); ibin++){
742  for(size_t iabcd=0; iabcd < abcd.abcdcuts.size(); iabcd++){
743  size_t index = abcd.indexBin(iplane, ibin, iabcd);
744  cout<<"MC: "<<setw(8)<<RoundNumber(allyields[1][index].Yield(),digits)
745  <<" Data: "<<setw(4)<<RoundNumber(allyields[0][index].Yield(), 0)
746  <<" - "<< abcd.allcuts[index]<<endl;
747  } // Loop over ABCD cuts
748  cout<<"Kappa = "<<RoundNumber(kappas[iplane][ibin][0],digits)<<"+"<<RoundNumber(kappas[iplane][ibin][1],digits)
749  <<"-"<<RoundNumber(kappas[iplane][ibin][2],digits)<<", Prediction = "
750  <<RoundNumber(preds[iplane][ibin][0],digits)<<"+"<<RoundNumber(preds[iplane][ibin][1],digits)
751  <<"-"<<RoundNumber(preds[iplane][ibin][2],digits)<<endl;
752  cout<<endl;
753  } // Loop over bin cuts
754  } // Loop over plane cuts
755 
756 } // printDebug
757 
758 void GetOptions(int argc, char *argv[]){
759  while(true){
760  static struct option long_options[] = {
761  {"method", required_argument, 0, 'm'}, // Method to run on (if you just want one)
762  {"lumi", required_argument, 0, 'l'}, // Luminosity to normalize MC with (no data)
763  {"skim", required_argument, 0, 's'}, // Which skim to use: standard, 2015 data
764  {"json", required_argument, 0, 'j'}, // Which JSON to use: 0p815, 2p6, 4p0, 7p65, 12p9
765  {"split_bkg", no_argument, 0, 'b'}, // Prints Other, tt1l, tt2l contributions
766  {"no_signal", no_argument, 0, 'n'}, // Does not print signal columns
767  {"do_leptons", no_argument, 0, 'p'}, // Does tables for e/mu/emu as well
768  {"unblind", no_argument, 0, 'u'}, // Unblinds R4/D4
769  {"only_mc", no_argument, 0, 'o'}, // Uses MC as data for the predictions
770  {"only_kappa", no_argument, 0, 'k'}, // Only plots kappa (no table)
771  {"debug", no_argument, 0, 'd'}, // Debug: prints yields and cuts used
772  {"only_dilepton", no_argument, 0, '2'}, // Makes tables only for dilepton tests
773  {"ht", no_argument, 0, 0}, // Cuts on ht>500 instead of st>500
774  {0, 0, 0, 0}
775  };
776 
777  char opt = -1;
778  int option_index;
779  opt = getopt_long(argc, argv, "m:s:j:udbnl:p2ok", long_options, &option_index);
780  if(opt == -1) break;
781 
782  string optname;
783  switch(opt){
784  case 'm':
785  only_method = optarg;
786  break;
787  case 'l':
788  mc_lumi = optarg;
789  only_mc = true;
790  break;
791  case 'k':
792  only_kappa = true;
793  only_mc = true;
794  break;
795  case 's':
796  skim = optarg;
797  break;
798  case 'j':
799  json = optarg;
800  break;
801  case 'b':
802  split_bkg = false;
803  break;
804  case 'o':
805  only_mc = true;
806  break;
807  case '2':
808  only_dilepton = true;
809  break;
810  case 'p':
811  do_leptons = true;
812  break;
813  case 'n':
814  do_signal = false;
815  break;
816  case 'u':
817  unblind = true;
818  break;
819  case 'd':
820  debug = true;
821  break;
822  case 0:
823  optname = long_options[option_index].name;
824  if(optname == "ht"){
825  do_ht = true;
826  }else{
827  printf("Bad option! Found option name %s\n", optname.c_str());
828  exit(1);
829  }
830  break;
831  default:
832  printf("Bad option! getopt_long returned character code 0%o\n", opt);
833  break;
834  }
835  }
836 }
PlotOpt & TopMargin(double top)
Definition: plot_opt.cpp:260
void setPlotStyle(PlotOpt opts)
Definition: styles.cpp:7
PlotOpt & LeftMargin(double left)
Definition: plot_opt.cpp:233
int main(int argc, char *argv[])
Definition: table_preds.cxx:74
void findPreds(abcd_method &abcd, vector< vector< GammaParams > > &allyields, vector< vector< vector< float > > > &kappas, vector< vector< vector< float > > > &preds)
std::vector< GammaParams > Yield(const Process *process, double luminosity) const
Definition: table.cpp:158
TString HoursMinSec(float fseconds)
Definition: utilities.cpp:337
std::vector< float > *const & leps_pt() const
Get leps_pt for current event and cache it.
Definition: baby.cpp:4493
double Significance(double Nobs, double Nbkg, double Eup_bkg, double Edown_bkg=-1.)
Definition: utilities.cpp:426
const std::string & Name() const
Get the string representation of this function.
Definition: named_func.cpp:376
Abstract base class for access to ntuple variables.
Definition: baby.hpp:16
const std::vector< std::unique_ptr< Figure > > & Figures() const
Definition: plot_maker.cpp:63
void ReplaceAll(std::string &str, const std::string &orig, const std::string &rep)
Definition: utilities.cpp:52
TString caption
Definition: abcd_method.hpp:18
STL namespace.
size_t indexBin(size_t iplane, size_t ibin, size_t iabcd)
Definition: abcd_method.cpp:73
Combines a callable function taking a Baby and returning a scalar or vector with its string represent...
Definition: named_func.hpp:13
bool Contains(const std::string &str, const std::string &pat)
Definition: utilities.cpp:44
TString Zbi(double Nobs, double Nbkg, double Eup_bkg, double Edown_bkg)
TString printTable(abcd_method &abcd, vector< vector< GammaParams > > &allyields, vector< vector< vector< float > > > &kappas, vector< vector< vector< float > > > &preds, vector< shared_ptr< Process > > &proc_sigs)
bool multithreaded_
Definition: plot_maker.hpp:43
std::string execute(const std::string &cmd)
Definition: utilities.cpp:65
double ScalarType
Definition: named_func.hpp:15
std::vector< std::vector< TString > > bincuts
Definition: abcd_method.hpp:17
std::vector< TString > allcuts
Definition: abcd_method.hpp:16
std::vector< TString > abcdcuts
Definition: abcd_method.hpp:16
double calcKappa(std::vector< std::vector< float > > &entries, std::vector< std::vector< float > > &weights, std::vector< float > &powers, float &mSigma, float &pSigma, bool do_data=false, bool verbose=false, double syst=-1., bool do_plot=false, int nrep=100000)
Definition: utilities.cpp:469
FigureType & Push(Args &&...args)
Definition: plot_maker.hpp:24
std::vector< GammaParams > BackgroundYield(double luminosity) const
Definition: table.cpp:175
std::string CodeToRootTex(std::string code)
Definition: utilities.cpp:116
std::string CodeToLatex(std::string code)
Definition: utilities.cpp:242
void plotKappa(abcd_method &abcd, vector< vector< vector< float > > > &kappas)
void printDebug(abcd_method &abcd, vector< vector< GammaParams > > &allyields, TString baseline, vector< vector< vector< float > > > &kappas, vector< vector< vector< float > > > &preds)
bool min_print_
Definition: plot_maker.hpp:44
TString RoundNumber(double num, int decimals, double denom=1.)
Definition: utilities.cpp:361
Organizes efficient production of plots with single loop over each process.
Definition: plot_maker.hpp:14
std::vector< TString > planecuts
Definition: abcd_method.hpp:16
TString method
Definition: abcd_method.hpp:15
PlotOpt & BottomMargin(double bottom)
Definition: plot_opt.cpp:251
std::vector< GammaParams > DataYield() const
Definition: table.cpp:188
Definition: table.hpp:15
const NamedFunc st("st", [](const Baby &b) -> NamedFunc::ScalarType{float stvar=b.ht();for(const auto &pt:*(b.leps_pt())) stvar+=pt;return stvar;})
PlotOpt & LegendEntryHeight(double height)
Definition: plot_opt.cpp:287
void MakePlots(double luminosity, const std::string &subdir="")
Prints all added plots with given luminosity.
Definition: plot_maker.cpp:54
float const & ht() const
Get ht for current event and cache it.
Definition: baby.cpp:3929
PlotOpt & RightMargin(double right)
Definition: plot_opt.cpp:242
void GetOptions(int argc, char *argv[])
Loads colors from a text configuration file.
Definition: palette.hpp:8