ra4_macros  bede988c286599a3a84b77a4d788ac0a971e89f9
make_card.cxx
Go to the documentation of this file.
1 #include "make_card.hpp"
2 
3 #include <cstdlib>
4 
5 #include <fstream>
6 #include <sstream>
7 #include <iostream>
8 #include <iomanip>
9 #include <vector>
10 #include <string>
11 
12 #include <unistd.h>
13 #include <getopt.h>
14 
15 #include "TMath.h"
16 #include "TError.h"
17 #include "TSystem.h"
18 
19 #include "gamma_params.hpp"
20 #include "small_tree_quick.hpp"
21 #include "timer.hpp"
22 #include "utilities.hpp"
23 #include "utilities_macros.hpp"
24 
25 namespace{
26  //Options that can all be set with command line args
27  int method = 0;
28  std::string ntuple_date = "2015_06_05";
29  double lumi = 10.;
30  double mc_multiplier = 1.;
31  bool no_mc_kappa = false;
32  bool no_systematics = false;
33 
34  std::string mgluino = "1500";
35  std::string mlsp = "100";
36 
37  double inject_signal = 0.;
38 
39  bool do_tk_veto = false;
40 
41  double mt_min = 0.;
42  double mt_div = 140.;
43  double mj_min = 0.;
44  double mj_div = 400.;
45  int njets_min = 7;
46  int njets_div = 9;
47  double met_min = 200.;
48  double met_div = 400.;
49  double ht_min = 500.;
50  int nb_min = 2;
51  int nb_div = 3;
52 
53  bool verbose = false;
54 
55  //Track whether option was set in command line for logging purposes
56  bool set_method = false;
57  bool set_ntuple_date = false;
58  bool set_lumi = false;
59  bool set_mc_multiplier = false;
60 
61  bool set_masses = false;
62  bool set_inject_signal = false;
63 
64  bool set_mt = false;
65  bool set_mj = false;
66  bool set_njets = false;
67  bool set_met = false;
68  bool set_ht = false;
69  bool set_nb = false;
70 }
71 
72 using namespace std;
73 
74 int main(int argc, char *argv[]){
75  gErrorIgnoreLevel=6000;
76  GetOptions(argc, argv);
77 
78  string folder="archive/"+ntuple_date+"/skim/";
79 
80  small_tree_quick ttbar(folder+"*TTJets*");
81  small_tree_quick pos(folder+"*TTWJets*");
82  pos.Add(folder+"*TTZJets*");
83  pos.Add(folder+"*QCD_Pt*");
84  pos.Add(folder+"*WJetsToLNu_HT*");
85  pos.Add(folder+"*ZJetsToLNu_HT*");
86  pos.Add(folder+"*DYJets*");
87  pos.Add(folder+"*H_HToBB*");
88  small_tree_quick neg(folder+"*_T*s-channel*");
89  neg.Add(folder+"*_T*tW-channel*");
90  neg.Add(folder+"*_T*t-channel*");
91  small_tree_quick sig(folder+"*T1tttt*"+mgluino+"*"+mlsp+"*");
92 
93  vector<GammaParams> ttbar_gp, pos_gp, neg_gp, sig_gp;
94  GetCounts(ttbar, ttbar_gp);
95  GetCounts(pos, pos_gp);
96  GetCounts(neg, neg_gp);
97  GetCounts(sig, sig_gp);
98 
99  //Force possibly negative component to be positive and ignore uncertainty, then lump together with "pos"
100  vector<GammaParams> other_gp(pos_gp.size());
101  for(size_t bin = 0; bin < other_gp.size(); ++bin){
102  other_gp.at(bin).SetYieldAndUncertainty(pos_gp.at(bin).Yield()+max(0.,neg_gp.at(bin).Yield()),
103  pos_gp.at(bin).Uncertainty());
104  }
105 
106  vector<string> bkg_names;
107  vector<vector<GammaParams> > bkg_gps;
108  bkg_gps.push_back(ttbar_gp); bkg_names.push_back("ttbar");
109  bkg_gps.push_back(other_gp); bkg_names.push_back("other");
110 
111  vector<GammaParams> mc_gp;
112  GetMCTotals(mc_gp, bkg_gps);
113 
114  vector<double> data_counts;
115  MockUpData(data_counts, sig_gp, bkg_gps);
116 
117  WriteFile(bkg_gps, bkg_names, sig_gp, mc_gp, data_counts);
118 
119  if(verbose){
120  PrintDebug(sig_gp, "signal");
121  for(size_t ibkg = 0; ibkg < bkg_gps.size(); ++ibkg){
122  PrintDebug(bkg_gps.at(ibkg), bkg_names.at(ibkg));
123  }
124  PrintDebug(pos_gp,"pos");
125  PrintDebug(neg_gp,"neg");
126  }
127 }
128 
129 void GetOptions(int argc, char *argv[]){
130  bool set_gluino = false, set_lsp = false, set_mj_div = false;
131  while(true){
132  static struct option long_options[] = {
133  {"method", required_argument, 0, 'm'},
134  {"ntuple_date", required_argument, 0, 'd'},
135  {"lumi", required_argument, 0, 'l'},
136  {"mc_multiplier", required_argument, 0, 0},
137  {"no_mc_kappa", no_argument, 0, 0},
138  {"no_systematics", no_argument, 0, 0},
139  {"inject_signal", required_argument, 0, 's'},
140  {"mgluino", required_argument, 0, 0},
141  {"mlsp", required_argument, 0, 0},
142  {"tk_veto", no_argument, 0, 't'},
143  {"mt_min", required_argument, 0, 0},
144  {"mt_div", required_argument, 0, 0},
145  {"mj_min", required_argument, 0, 0},
146  {"mj_div", required_argument, 0, 0},
147  {"njets_min", required_argument, 0, 0},
148  {"njets_div", required_argument, 0, 0},
149  {"met_min", required_argument, 0, 0},
150  {"met_div", required_argument, 0, 0},
151  {"ht_min", required_argument, 0, 0},
152  {"nb_min", required_argument, 0, 0},
153  {"verbose", no_argument, 0, 'v'},
154  {0, 0, 0, 0}
155  };
156 
157  char opt = -1;
158  int option_index;
159  opt = getopt_long(argc, argv, "m:d:l:s:tv", long_options, &option_index);
160  if( opt == -1) break;
161 
162  string optname;
163  switch(opt){
164  case 'm':
165  method = atoi(optarg);
166  set_method = true;
167  break;
168  case 'd':
169  ntuple_date = optarg;
170  set_ntuple_date = true;
171  break;
172  case 'l':
173  lumi = atof(optarg);
174  set_lumi = true;
175  break;
176  case 's':
177  inject_signal = atof(optarg);
178  set_inject_signal = true;
179  break;
180  case 't':
181  do_tk_veto = true;
182  break;
183  case 'v':
184  verbose = true;
185  break;
186  case 0:
187  optname = long_options[option_index].name;
188  if(optname == "mc_multiplier"){
189  mc_multiplier = atof(optarg);
190  set_mc_multiplier = true;
191  }else if(optname == "no_mc_kappa"){
192  no_mc_kappa = true;
193  }else if(optname == "no_systematics"){
194  no_systematics = true;
195  }else if(optname == "mgluino"){
196  mgluino = optarg;
197  set_gluino = true;
198  set_masses = true;
199  }else if(optname == "mlsp"){
200  mlsp = optarg;
201  set_lsp = true;
202  set_masses = true;
203  }else if(optname == "mt_min"){
204  mt_min = atof(optarg);
205  set_mt = true;
206  }else if(optname == "mt_div"){
207  mt_div = atof(optarg);
208  set_mt = true;
209  }else if(optname == "mj_min"){
210  mj_min = atof(optarg);
211  set_mj = true;
212  }else if(optname == "mj_div"){
213  mj_div = atof(optarg);
214  set_mj = true;
215  set_mj_div = true;
216  }else if(optname == "njets_min"){
217  njets_min = atoi(optarg);
218  set_njets = true;
219  }else if(optname == "njets_div"){
220  njets_div = atoi(optarg);
221  set_njets = true;
222  }else if(optname == "met_min"){
223  met_min = atof(optarg);
224  set_met = true;
225  }else if(optname == "met_div"){
226  met_div = atof(optarg);
227  set_met = true;
228  }else if(optname == "nb_min"){
229  nb_min = atoi(optarg);
230  set_nb = true;
231  }else if(optname == "nb_div"){
232  nb_div = atoi(optarg);
233  set_nb = true;
234  }else if(optname == "ht_min"){
235  ht_min = atof(optarg);
236  set_ht = true;
237  }else{
238  printf("Bad option! Found option name %s\n", optname.c_str());
239  }
240  break;
241  default:
242  printf("Bad option! getopt_long returned character code 0%o\n", opt);
243  break;
244  }
245  }
246 
247  //Fix masses if only one is set
248  if(set_gluino && !set_lsp){
249  if(mgluino == "1500"){
250  mlsp = "100";
251  }else if(mgluino == "1200"){
252  mlsp = "800";
253  }
254  }else if(set_lsp && !set_gluino){
255  if(mlsp == "100"){
256  mgluino = "1500";
257  }else if(mlsp == "800"){
258  mgluino = "1200";
259  }
260  }
261 
262  //Adjust mj_div if using method 1 and not manually overridden
263  if(method == 1 && !set_mj_div) mj_div = 600.;
264 }
265 
266 void GetCounts(small_tree_quick &tree, vector<GammaParams> &gp){
267  size_t nbins = 0;
268  switch(method){
269  case 0: nbins = 8; break;
270  case 1: nbins = 16; break;
271  case 2: nbins = 12; break;
272  case 3: nbins = 18; break;
273  default: break;
274  }
275 
276  vector<double> counts(nbins, 0.);
277  vector<double> squares(nbins, 0.);
278 
279  double sumw = 0., sumw2 = 0.;
280  int num_entries = tree.GetEntries();
281  Timer timer(num_entries, 1.);
282  timer.Start();
283  for(int entry = 0; entry < num_entries; ++entry){
284  tree.GetEntry(entry);
285  timer.Iterate();
286 
287  double weight = lumi*tree.weight();
288 
289  if(tree.nbm()<nb_min
290  || tree.njets()<njets_min
291  || (tree.nmus()+tree.nels())!=1
292  || tree.met()<=met_min
293  || (do_tk_veto && tree.ntks_chg_mini()>0)
294  || tree.ht()<=ht_min){
295  continue;
296  }
297  size_t bin = LookUpBin(tree);
298 
299  counts.at(bin) += weight;
300  squares.at(bin) += weight*weight;
301 
302  sumw += weight;
303  sumw2 += weight*weight;
304  }
305  sumw2 /= mc_multiplier;
306 
307  gp.resize(counts.size());
308  for(size_t bin = 0; bin < counts.size(); ++bin){
309  double raw, weight;
310  squares.at(bin) /= mc_multiplier;
311  CountsToGammas(counts.at(bin), squares.at(bin),
312  sumw, sumw2,
313  raw, weight);
314  gp.at(bin).SetNEffectiveAndWeight(raw, weight);
315  }
316 }
317 
318 void CountsToGammas(double sumw, double sumw2,
319  double sumw_backup, double sumw2_backup,
320  double &nraw, double &weight){
321  if(sumw2 == 0.){
322  //Never filled
323  nraw = 0.;
324  weight = sumw2_backup/sumw_backup;
325  }else if(sumw <= 0.){
326  //Negative estimate
327  nraw = 0;
328  weight = sqrt(sumw2+sumw*sumw);
329  }else{
330  //Normal case
331  nraw = sumw*sumw/sumw2;
332  weight = sumw2/sumw;
333  }
334 }
335 
337  unsigned code = 0;
338  code += (tree.mt() > mt_div) << 4;
339  code += (tree.mj() > mj_div) << 3;
340  code += (tree.met() > met_div) << 2;
341  code += (tree.njets() >= njets_div) << 1;
342  code += (tree.nbm() >= nb_div) << 0;
343  switch(method){
344  case 0:
345  switch(code){
346  case 0x00:
347  case 0x01:
348  case 0x02:
349  case 0x03:
350  case 0x04:
351  case 0x05:
352  case 0x06:
353  case 0x07: return 0;
354  case 0x08:
355  case 0x09: return 1;
356  case 0x0A:
357  case 0x0B: return 2;
358  case 0x0C:
359  case 0x0D: return 1;
360  case 0x0E:
361  case 0x0F: return 2;
362  case 0x10:
363  case 0x11:
364  case 0x12:
365  case 0x13:
366  case 0x14:
367  case 0x15:
368  case 0x16:
369  case 0x17: return 3;
370  case 0x18:
371  case 0x19: return 4;
372  case 0x1A:
373  case 0x1B: return 5;
374  case 0x1C:
375  case 0x1D: return 6;
376  case 0x1E:
377  case 0x1F: return 7;
378  default: return -1;
379  }
380  case 1:
381  switch(code){
382  case 0x00:
383  case 0x01: return 0;
384  case 0x02:
385  case 0x03: return 1;
386  case 0x04:
387  case 0x05: return 2;
388  case 0x06:
389  case 0x07: return 3;
390  case 0x08:
391  case 0x09: return 4;
392  case 0x0A:
393  case 0x0B: return 5;
394  case 0x0C:
395  case 0x0D: return 6;
396  case 0x0E:
397  case 0x0F: return 7;
398  case 0x10:
399  case 0x11: return 8;
400  case 0x12:
401  case 0x13: return 9;
402  case 0x14:
403  case 0x15: return 10;
404  case 0x16:
405  case 0x17: return 11;
406  case 0x18:
407  case 0x19: return 12;
408  case 0x1A:
409  case 0x1B: return 13;
410  case 0x1C:
411  case 0x1D: return 14;
412  case 0x1E:
413  case 0x1F: return 15;
414  default: return -1;
415  }
416  case 2:
417  switch(code){
418  case 0x00:
419  case 0x01:
420  case 0x02:
421  case 0x03: return 0;
422  case 0x04:
423  case 0x05:
424  case 0x06:
425  case 0x07: return 1;
426  case 0x08:
427  case 0x09: return 2;
428  case 0x0A:
429  case 0x0B: return 3;
430  case 0x0C:
431  case 0x0D: return 4;
432  case 0x0E:
433  case 0x0F: return 5;
434  case 0x10:
435  case 0x11:
436  case 0x12:
437  case 0x13: return 6;
438  case 0x14:
439  case 0x15:
440  case 0x16:
441  case 0x17: return 7;
442  case 0x18:
443  case 0x19: return 8;
444  case 0x1A:
445  case 0x1B: return 9;
446  case 0x1C:
447  case 0x1D: return 10;
448  case 0x1E:
449  case 0x1F: return 11;
450  default: return -1;
451  }
452  case 3:
453  switch(code){
454  case 0x00: return 0;
455  case 0x01: return 1;
456  case 0x02: return 0;
457  case 0x03: return 1;
458  case 0x04:
459  case 0x05:
460  case 0x06:
461  case 0x07: return 2;
462  case 0x08: return 3;
463  case 0x09: return 4;
464  case 0x0A: return 5;
465  case 0x0B: return 6;
466  case 0x0C:
467  case 0x0D: return 7;
468  case 0x0E:
469  case 0x0F: return 8;
470  case 0x10: return 9;
471  case 0x11: return 10;
472  case 0x12: return 9;
473  case 0x13: return 10;
474  case 0x14:
475  case 0x15:
476  case 0x16:
477  case 0x17: return 11;
478  case 0x18: return 12;
479  case 0x19: return 13;
480  case 0x1A: return 14;
481  case 0x1B: return 15;
482  case 0x1C:
483  case 0x1D: return 16;
484  case 0x1E:
485  case 0x1F: return 17;
486  default: return -1;
487  }
488  default: return -1;
489  }
490  return -1;
491 }
492 
493 void GetMCTotals(vector<GammaParams> &mc_gp,
494  const vector<vector<GammaParams> > &bkg_gps){
495  if(bkg_gps.size() == 0){
496  mc_gp.clear();
497  return;
498  }
499 
500  mc_gp = vector<GammaParams>(bkg_gps.at(0).size());
501  for(size_t sample = 0; sample < bkg_gps.size(); ++sample){
502  for(size_t bin = 0; bin < bkg_gps.at(sample).size(); ++bin){
503  mc_gp.at(bin) += bkg_gps.at(sample).at(bin);
504  }
505  }
506 }
507 
508 void MockUpData(vector<double> &data,
509  const vector<GammaParams> &sig_gp,
510  const vector<vector<GammaParams> > &bkg_gps){
511  data.resize(sig_gp.size());
512  for(size_t bin = 0; bin < data.size(); ++bin){
513  data.at(bin) = inject_signal*sig_gp.at(bin).Yield();
514  for(size_t sample = 0; sample < bkg_gps.size(); ++sample){
515  data.at(bin) += bkg_gps.at(sample).at(bin).Yield();
516  }
517  }
518 }
519 
520 void GetBinMapping(size_t &nr1, vector<size_t> &r1_map,
521  size_t &nr2, vector<size_t> &r2_map,
522  size_t &nr3, vector<size_t> &r3_map,
523  size_t &nr4, vector<size_t> &r4_map){
524  nr1 = 0; nr2 = 0; nr3 = 0; nr4 = 0;
525  r1_map.clear(); r2_map.clear(); r3_map.clear(); r4_map.clear();
526  switch(method){
527  case 0:
528  nr1 = 1; nr2 = 2; nr3 = 1; nr4 = 4;
529  r1_map.push_back(0); r2_map.push_back(0); r3_map.push_back(0); r4_map.push_back(0);
530  r1_map.push_back(0); r2_map.push_back(1); r3_map.push_back(0); r4_map.push_back(1);
531  r1_map.push_back(0); r2_map.push_back(0); r3_map.push_back(0); r4_map.push_back(2);
532  r1_map.push_back(0); r2_map.push_back(1); r3_map.push_back(0); r4_map.push_back(3);
533  break;
534  case 1:
535  nr1 = 4; nr2 = 4; nr3 = 4; nr4 = 4;
536  r1_map.push_back(0); r2_map.push_back(0); r3_map.push_back(0); r4_map.push_back(0);
537  r1_map.push_back(1); r2_map.push_back(1); r3_map.push_back(1); r4_map.push_back(1);
538  r1_map.push_back(2); r2_map.push_back(2); r3_map.push_back(2); r4_map.push_back(2);
539  r1_map.push_back(3); r2_map.push_back(3); r3_map.push_back(3); r4_map.push_back(3);
540  break;
541  case 2:
542  nr1 = 2; nr2 = 4; nr3 = 2; nr4 = 4;
543  r1_map.push_back(0); r2_map.push_back(0); r3_map.push_back(0); r4_map.push_back(0);
544  r1_map.push_back(0); r2_map.push_back(1); r3_map.push_back(0); r4_map.push_back(1);
545  r1_map.push_back(1); r2_map.push_back(2); r3_map.push_back(1); r4_map.push_back(2);
546  r1_map.push_back(1); r2_map.push_back(3); r3_map.push_back(1); r4_map.push_back(3);
547  break;
548  case 3:
549  nr1 = 3; nr2 = 6; nr3 = 3; nr4 = 6;
550  r1_map.push_back(0); r2_map.push_back(0); r3_map.push_back(0); r4_map.push_back(0);
551  r1_map.push_back(1); r2_map.push_back(1); r3_map.push_back(1); r4_map.push_back(1);
552  r1_map.push_back(0); r2_map.push_back(2); r3_map.push_back(0); r4_map.push_back(2);
553  r1_map.push_back(1); r2_map.push_back(3); r3_map.push_back(1); r4_map.push_back(3);
554  r1_map.push_back(2); r2_map.push_back(4); r3_map.push_back(2); r4_map.push_back(4);
555  r1_map.push_back(2); r2_map.push_back(5); r3_map.push_back(2); r4_map.push_back(5);
556  break;
557  default:
558  break;
559  }
560 }
561 
562 double sqr(double x){
563  return x*x;
564 }
565 
566 void WriteFile(const vector<vector<GammaParams> > &bkg_gps,
567  const vector<string> &bkg_names,
568  const vector<GammaParams> &sig_gp,
569  const vector<GammaParams> &mc_gp,
570  const vector<double> &data_counts){
571  size_t nr1, nr2, nr3, nr4;
572  vector<size_t> r1_map, r2_map, r3_map, r4_map;
573  GetBinMapping(nr1, r1_map, nr2, r2_map, nr3, r3_map, nr4, r4_map);
574 
575  ostringstream file_name;
576  file_name << "txt/data_card";
577  if(set_ntuple_date) file_name << '_' << ntuple_date;
578  if(set_method) file_name << "_method_" << method;
579  if(set_mc_multiplier) file_name << "_mc_multiplier_" << NoDecimal(mc_multiplier);
580  if(no_mc_kappa) file_name << "_no_mc_kappa";
581  if(no_systematics) file_name << "_no_systematics";
582  if(set_masses) file_name << "_T1tttt_" << mgluino << '_' << mlsp;
583  if(set_lumi) file_name << "_lumi_" << lumi;
584  if(set_inject_signal) file_name << "_inject_" << NoDecimal(inject_signal);
585  if(do_tk_veto) file_name << "_tk_veto";
586  if(set_ht) file_name << "_ht_" << ht_min;
587  if(set_mt) file_name << "_mt_" << mt_min << '_' << mt_div;
588  if(set_mj) file_name << "_mj_" << mj_min << '_' << mj_div;
589  if(set_njets) file_name << "_njets_" << njets_min << '_' << njets_div;
590  if(set_met) file_name << "_met_" << met_min << '_' << met_div;
591  if(set_nb) file_name << "_nb_" << nb_min << '_' << nb_div;
592  file_name << ".txt" << flush;
593 
594  ofstream file(file_name.str().c_str());
595  file << "imax " << nr4 << " number of channels\n";
596  file << "jmax " << bkg_gps.size() << " number of backgrounds\n";
597  file << "kmax * number of nuisance parameters\n";
598  file << "------------\n";
599  file << "bin ";
600  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
601  file << ' ' << setw(12) << (ir4+1);
602  }
603  file << '\n';
604  file << "observation";
605  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
606  file << ' ' << setw(12) << data_counts.at(ir4+nr1+nr2+nr3);
607  }
608  file << '\n';
609  file << "------------\n";
610  file << "bin ";
611  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
612  for(size_t i = 0; i < 3; ++i){
613  file << ' ' << setw(12) << (ir4+1);
614  }
615  }
616  file << '\n';
617  file << "process ";
618  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
619  file << ' ' << setw(12) << "sig";
620  for(size_t isam = 0; isam < bkg_names.size(); ++isam){
621  file << ' ' << setw(12) << bkg_names.at(isam);
622  }
623  }
624  file << '\n';
625  file << "process ";
626  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
627  file << " 0";
628  for(size_t isam = 0; isam < bkg_names.size(); ++isam){
629  file << ' ' << setw(12) << (isam+1);
630  }
631  }
632  file << '\n';
633  file << "rate ";
634  vector<double> sig_pred(0);
635  vector<vector<double> > bkg_preds(bkg_gps.size());
636  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
637  size_t ir1 = r1_map.at(ir4);
638  size_t ir2 = r2_map.at(ir4)+nr1;
639  size_t ir3 = r3_map.at(ir4)+nr1+nr2;
640  size_t iir4 = r4_map.at(ir4)+nr1+nr2+nr3;
641  sig_pred.push_back(sig_gp.at(iir4).Yield());
642  file << ' ' << setw(12) << sig_pred.back();
643  for(size_t isam = 0; isam < bkg_gps.size(); ++isam){
644  bkg_preds.at(isam).push_back(GetPred(data_counts, mc_gp, bkg_gps.at(isam), ir1, ir2, ir3, iir4));
645  file << ' ' << setw(12) << bkg_preds.at(isam).back();
646  }
647  }
648  file << '\n';
649  file << "------------\n";
650 
651  //Print control region uncertainty from data
652  GammaToLogN13(file, r1_map, nr1, nr2, nr4, data_counts, bkg_gps.size());
653  GammaToLogN2(file, r2_map, nr1, nr2, nr4, data_counts, bkg_gps.size());
654 
655  vector<double> mc_counts(mc_gp.size());
656  for(size_t i = 0; i < mc_gp.size(); ++i){
657  mc_counts.at(i) = mc_gp.at(i).NEffective();
658  }
659  if(!no_mc_kappa){
660  GammaToLogN13(file, r1_map, nr1, nr2, nr4, bkg_gps);
661  GammaToLogN2(file, r2_map, nr1, nr2, nr4, bkg_gps);
662  }
663 
664  PrintGamma(file, r4_map, "sgnl_r4", 4, nr1, nr2, nr3, nr4, sig_gp, sig_pred, 0, bkg_gps.size());
665  for(size_t isam = 0; isam < bkg_preds.size(); ++isam){
666  PrintGamma(file, r4_map, bkg_names.at(isam)+"_r4",4, nr1, nr2, nr3, nr4, bkg_gps.at(isam), bkg_preds.at(isam), isam+1, bkg_gps.size());
667  }
668 
669  if(!no_systematics){
670  PrintSystematics(file, bkg_gps.size());
671  }
672 
673  file << "#kappa ";
674  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
675  size_t ir1 = r1_map.at(ir4);
676  size_t ir2 = r2_map.at(ir4)+nr1;
677  size_t ir3 = r3_map.at(ir4)+nr1+nr2;
678  size_t iir4 = r4_map.at(ir4)+nr1+nr2+nr3;
679 
680  double kappa = mc_gp.at(ir1).Yield();
681  kappa /= mc_gp.at(ir2).Yield();
682  kappa /= mc_gp.at(ir3).Yield();
683  kappa *= mc_gp.at(iir4).Yield();
684 
685  file << ' ' << setw(12) << '-';
686  for(size_t isam = 0; isam < bkg_gps.size(); ++isam){
687  file << ' ' << setw(12) << kappa;
688  }
689  }
690 
691  file << endl;
692  file.close();
693 
694  cout << endl << "Created data card at " << file_name.str() << endl << endl;
695 }
696 
697 void GetGammaParameters(int &raw_out, double &weight_out,
698  double raw_in, double weight_in, double pred_in){
699  raw_out = TMath::Nint(raw_in);
700  if(raw_out>0){
701  weight_out = pred_in/raw_out;
702  }else{
703  weight_out = weight_in;
704  }
705 }
706 
707 double GetPred(const vector<double> &data,
708  const vector<GammaParams> &mc_gp,
709  const vector<GammaParams> &proc_gp,
710  size_t ir1,
711  size_t ir2,
712  size_t ir3,
713  size_t ir4){
714  //Full data prediction for bin
715  double pred = data.at(ir2)*data.at(ir3)/data.at(ir1);
716 
717  //Fraction belonging to this process
718  pred *= (proc_gp.at(ir4).Yield())/mc_gp.at(ir4).Yield();
719 
720  //MC kappa correction
721  if(!no_mc_kappa){
722  pred *= mc_gp.at(ir1).Yield();
723  pred /= mc_gp.at(ir2).Yield();
724  pred /= mc_gp.at(ir3).Yield();
725  pred *= mc_gp.at(ir4).Yield();
726  }else{
727  if(method==0){
728  //Deal with MET spectrum from MC due to incomplete binning in R2
729  size_t id1 = 0, id2 = 0;
730  switch(ir4){
731  case 4:
732  case 6: id1 = 4; id2 = 6; break;
733  case 5:
734  case 7: id1 = 5; id2 = 7; break;
735  default: break;
736  }
737  pred *= proc_gp.at(ir4).Yield();
738  pred /= proc_gp.at(id1).Yield()+proc_gp.at(id2).Yield();
739  }
740  }
741 
742  return max(0.,pred);
743 }
744 
745 void PrintGamma(ofstream &file, const vector<size_t> map,
746  const string &name, size_t iregion,
747  size_t nr1, size_t nr2, size_t nr3, size_t nr4,
748  const vector<GammaParams> &gps,
749  const vector<double> &preds,
750  size_t iproc, size_t nbkgs){
751  size_t nri = -1; size_t offset = 0;
752  switch(iregion){
753  case 1: nri = nr1; offset = 0; break;
754  case 2: nri = nr2; offset = nr1; break;
755  case 3: nri = nr3; offset = nr1+nr2; break;
756  case 4: nri = nr4; offset = nr1+nr2+nr3; break;
757  default: break;
758  }
759  for(size_t iri = 0; iri < nri; ++iri){
760  int gmn_raw;
761  double gmn_wght;
762  GetGammaParameters(gmn_raw, gmn_wght, gps.at(iri+offset).NEffective(), gps.at(iri+offset).Weight(), preds.at(iri));
763  file << Expand(name+'_'+ToString(iri+1),12) << " gmN " << setw(12) << gmn_raw;
764  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
765  if(map.at(ir4) == iri){
766  for(size_t i = 0; i < (nbkgs+1); ++i){
767  if(i == iproc){
768  file << ' ' << setw(12) << gmn_wght;
769  }else{
770  file << ' ' << setw(12) << '-';
771  }
772  }
773  }else{
774  for(size_t isam = 0; isam < (nbkgs+1); ++isam){
775  file << ' ' << setw(12) << '-';
776  }
777  }
778  }
779  file << '\n';
780  }
781 }
782 
783 string NoDecimal(double x){
784  ostringstream oss;
785  oss.precision(2);
786  oss << fixed << x;
787  string s = oss.str();
788  size_t l = s.find('.');
789  while(l<s.size()){
790  s.at(l)='_';
791  l = s.find('.');
792  }
793  return s;
794 }
795 
796 void PrintSystematics(ofstream &file, size_t nbkgs){
797  double lf = 1./sqrt(lumi/10.);
798  double mf = 1./sqrt(mc_multiplier);
799  switch(method){
800  case 0:
801  case 1:
802  file << "n_isr lnN ";
803  RepLogN(file, 4, nbkgs);
804  RepLogN(file, 4, nbkgs);
805  RepLogN(file, 9, nbkgs);
806  RepLogN(file, 14, nbkgs);
807  file << endl;
808  file << "isr_pt lnN ";
809  RepLogN(file, 4, nbkgs);
810  RepLogN(file, 5, nbkgs);
811  RepLogN(file, 59, nbkgs);
812  RepLogN(file, 19, nbkgs);
813  file << endl;
814  file << "top_pt lnN ";
815  RepLogN(file, 1, nbkgs);
816  RepLogN(file, 1, nbkgs);
817  RepLogN(file, 8, nbkgs);
818  RepLogN(file, 0, nbkgs);
819  file << endl;
820  file << "high_mt lnN ";
821  RepLogN(file, 7, nbkgs);
822  RepLogN(file, 16, nbkgs);
823  RepLogN(file, 2, nbkgs);
824  RepLogN(file, 23, nbkgs);
825  file << endl;
826  file << "dilep_data lnN ";
827  RepAsymLogN(file, 58.4*lf, 30.8*lf, nbkgs);
828  RepAsymLogN(file, 94.0*lf, 72.2*lf, nbkgs);
829  RepAsymLogN(file, 58.4*lf, 30.8*lf, nbkgs);
830  RepAsymLogN(file, 94.0*lf, 72.2*lf, nbkgs);
831  file << endl;
832  file << "dilep_mc lnN ";
833  RepAsymLogN(file, 16.2*mf, 16.7*mf, nbkgs);
834  RepAsymLogN(file, 30.3*mf, 31.8*mf, nbkgs);
835  RepAsymLogN(file, 16.2*mf, 16.7*mf, nbkgs);
836  RepAsymLogN(file, 30.3*mf, 31.8*mf, nbkgs);
837  file << endl;
838  break;
839  case 2:
840  file << "n_isr lnN ";
841  RepLogN(file, 2, nbkgs);
842  RepLogN(file, 6, nbkgs);
843  RepLogN(file, 4, nbkgs);
844  RepLogN(file, 19, nbkgs);
845  file << endl;
846  file << "isr_pt lnN ";
847  RepLogN(file, 4, nbkgs);
848  RepLogN(file, 1, nbkgs);
849  RepLogN(file, 25, nbkgs);
850  RepLogN(file, 42, nbkgs);
851  file << endl;
852  file << "top_pt lnN ";
853  RepLogN(file, 1, nbkgs);
854  RepLogN(file, 2, nbkgs);
855  RepLogN(file, 10, nbkgs);
856  RepLogN(file, 23, nbkgs);
857  file << endl;
858  file << "high_mt lnN ";
859  RepLogN(file, 9, nbkgs);
860  RepLogN(file, 17, nbkgs);
861  RepLogN(file, 18, nbkgs);
862  RepLogN(file, 20, nbkgs);
863  file << endl;
864  file << "dilep_data lnN ";
865  RepAsymLogN(file, 15.5*lf, 16.3*lf, nbkgs);
866  RepAsymLogN(file, 37.6*lf, 28.0*lf, nbkgs);
867  RepAsymLogN(file, 15.5*lf, 16.3*lf, nbkgs);
868  RepAsymLogN(file, 37.6*lf, 28.0*lf, nbkgs);
869  file << endl;
870  file << "dilep_mc lnN ";
871  RepAsymLogN(file, 8.2*mf, 8.5*mf, nbkgs);
872  RepAsymLogN(file, 15.2*mf, 15.6*mf, nbkgs);
873  RepAsymLogN(file, 8.2*mf, 8.5*mf, nbkgs);
874  RepAsymLogN(file, 15.2*mf, 15.6*mf, nbkgs);
875  file << endl;
876  break;
877  case 3:
878  file << "n_isr lnN ";
879  RepLogN(file, 2, nbkgs);
880  RepLogN(file, 2, nbkgs);
881  RepLogN(file, 6, nbkgs);
882  RepLogN(file, 6, nbkgs);
883  RepLogN(file, 4, nbkgs);
884  RepLogN(file, 19, nbkgs);
885  file << endl;
886  file << "isr_pt lnN ";
887  RepLogN(file, 4, nbkgs);
888  RepLogN(file, 4, nbkgs);
889  RepLogN(file, 1, nbkgs);
890  RepLogN(file, 1, nbkgs);
891  RepLogN(file, 25, nbkgs);
892  RepLogN(file, 42, nbkgs);
893  file << endl;
894  file << "top_pt lnN ";
895  RepLogN(file, 1, nbkgs);
896  RepLogN(file, 1, nbkgs);
897  RepLogN(file, 2, nbkgs);
898  RepLogN(file, 2, nbkgs);
899  RepLogN(file, 10, nbkgs);
900  RepLogN(file, 23, nbkgs);
901  file << endl;
902  file << "high_mt lnN ";
903  RepLogN(file, 9, nbkgs);
904  RepLogN(file, 9, nbkgs);
905  RepLogN(file, 17, nbkgs);
906  RepLogN(file, 17, nbkgs);
907  RepLogN(file, 18, nbkgs);
908  RepLogN(file, 20, nbkgs);
909  file << endl;
910  file << "dilep_data lnN ";
911  RepAsymLogN(file, 15.5*lf, 16.3*lf, nbkgs);
912  RepAsymLogN(file, 15.5*lf, 16.3*lf, nbkgs);
913  RepAsymLogN(file, 37.6*lf, 28.0*lf, nbkgs);
914  RepAsymLogN(file, 37.6*lf, 28.0*lf, nbkgs);
915  RepAsymLogN(file, 15.5*lf, 16.3*lf, nbkgs);
916  RepAsymLogN(file, 37.6*lf, 28.0*lf, nbkgs);
917  file << endl;
918  file << "dilep_mc lnN ";
919  RepAsymLogN(file, 8.2*mf, 8.5*mf, nbkgs);
920  RepAsymLogN(file, 8.2*mf, 8.5*mf, nbkgs);
921  RepAsymLogN(file, 15.2*mf, 15.6*mf, nbkgs);
922  RepAsymLogN(file, 15.2*mf, 15.6*mf, nbkgs);
923  RepAsymLogN(file, 8.2*mf, 8.5*mf, nbkgs);
924  RepAsymLogN(file, 15.2*mf, 15.6*mf, nbkgs);
925  file << endl;
926  break;
927  default:
928  break;
929  }
930 }
931 
932 void RepLogN(ofstream &file, double val, size_t nbkgs){
933  file << ' ' << setw(12) << '-';
934  for(size_t ibkg = 0; ibkg < nbkgs; ++ibkg){
935  file << ' ' << setw(12) << (1.+val/100.);
936  }
937 }
938 
939 void RepAsymLogN(ofstream &file, double minus, double plus, size_t nbkgs){
940  file << ' ' << setw(12) << '-';
941  for(size_t ibkg = 0; ibkg < nbkgs; ++ibkg){
942  file << ' ' << setw(12) << (ToString(1./(1.+minus/100.))+'/'+ToString(1.+plus/100.));
943  }
944 }
945 
946 string Expand(string in, size_t size){
947  while(in.size() < size){
948  in += ' ';
949  }
950  return in;
951 }
952 
953 void GammaToLogN13(ofstream &file, const vector<size_t> &map,
954  size_t nr1, size_t nr2, size_t nr4,
955  const vector<double> &counts, size_t nbkgs){
956  for(size_t icr = 0; icr < nr1; ++icr){
957  file << Expand(string("data_31_")+ToString(icr+1),12) << " lnN ";
958  vector<vector<float> > entries(2,vector<float>(1)), weights(2,vector<float>(1,1.));
959  vector<float> powers(2);
960  entries.at(0).at(0) = counts.at(icr);
961  powers.at(0) = -1.;
962  entries.at(1).at(0) = counts.at(icr+nr1+nr2);
963  powers.at(1) = 1.;
964 
965  float minus, plus;
966 
967  double center = calcKappa(entries, weights, powers, minus, plus, false, verbose);
968  minus = 1./(1.+minus/center);
969  plus = 1.+plus/center;
970  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
971  if(map.at(ir4) == icr){
972  file << " -";
973  for(size_t ibkg = 0; ibkg < nbkgs; ++ibkg){
974  file << ' ' << minus << '/' << plus;
975  }
976  }else{
977  for(size_t ibkg = 0; ibkg < (nbkgs+1); ++ibkg){
978  file << ' ' << setw(12) << '-';
979  }
980  }
981  }
982  file << '\n';
983  }
984 }
985 
986 void GammaToLogN2(ofstream &file, const vector<size_t> &map,
987  size_t nr1, size_t nr2, size_t nr4,
988  const vector<double> &counts, size_t nbkgs){
989  for(size_t icr = 0; icr < nr2; ++icr){
990  file << Expand(string("data_r2_")+ToString(icr+1),12) << " lnN ";
991  vector<vector<float> > entries(1,vector<float>(1)), weights(1,vector<float>(1,1.));
992  entries.at(0).at(0) = counts.at(icr+nr1);
993  vector<float> powers(1,1.);
994 
995  float minus, plus;
996 
997  double center = calcKappa(entries, weights, powers, minus, plus, false, verbose);
998  minus = 1./(1.+minus/center);
999  plus = 1.+plus/center;
1000  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
1001  if(map.at(ir4) == icr){
1002  file << " -";
1003  for(size_t ibkg = 0; ibkg < nbkgs; ++ibkg){
1004  file << ' ' << minus << '/' << plus;
1005  }
1006  }else{
1007  for(size_t ibkg = 0; ibkg < (nbkgs+1); ++ibkg){
1008  file << ' ' << setw(12) << '-';
1009  }
1010  }
1011  }
1012  file << '\n';
1013  }
1014 }
1015 
1016 void GammaToLogN13(ofstream &file, const vector<size_t> &map,
1017  size_t nr1, size_t nr2, size_t nr4,
1018  const vector<vector<GammaParams> > &gps){
1019  for(size_t icr = 0; icr < nr1; ++icr){
1020  file << Expand(string("mc_13_")+ToString(icr+1),12) << " lnN ";
1021  vector<vector<float> > entries(2,vector<float>(gps.size())), weights(2,vector<float>(gps.size()));
1022  for(size_t isample = 0; isample < gps.size(); ++isample){
1023  entries.at(0).at(isample) = gps.at(isample).at(icr).NEffective();
1024  entries.at(1).at(isample) = gps.at(isample).at(icr+nr1+nr2).NEffective();
1025  weights.at(0).at(isample) = gps.at(isample).at(icr).Weight();
1026  weights.at(1).at(isample) = gps.at(isample).at(icr+nr1+nr2).Weight();
1027  }
1028  vector<float> powers(2);
1029  powers.at(0) = 1.;
1030  powers.at(1) = -1.;
1031 
1032  float minus, plus;
1033 
1034  double center = calcKappa(entries, weights, powers, minus, plus, false, verbose);
1035  minus = 1./(1.+minus/center);
1036  plus = 1.+plus/center;
1037  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
1038  if(map.at(ir4) == icr){
1039  file << " -";
1040  for(size_t ibkg = 0; ibkg < gps.size(); ++ibkg){
1041  file << ' ' << minus << '/' << plus;
1042  }
1043  }else{
1044  for(size_t ibkg = 0; ibkg < (gps.size()+1); ++ibkg){
1045  file << ' ' << setw(12) << '-';
1046  }
1047  }
1048  }
1049  file << '\n';
1050  }
1051 }
1052 
1053 void GammaToLogN2(ofstream &file, const vector<size_t> &map,
1054  size_t nr1, size_t nr2, size_t nr4,
1055  const vector<vector<GammaParams> > &gps){
1056  for(size_t icr = 0; icr < nr2; ++icr){
1057  file << Expand(string("mc_r2_")+ToString(icr+1),12) << " lnN ";
1058  vector<vector<float> > entries(1,vector<float>(gps.size())), weights(1,vector<float>(gps.size()));
1059  for(size_t isample = 0; isample < gps.size(); ++isample){
1060  entries.at(0).at(isample) = gps.at(isample).at(icr+nr1).NEffective();
1061  weights.at(0).at(isample) = gps.at(isample).at(icr+nr1).Weight();
1062  }
1063  vector<float> powers(1,-1.);
1064 
1065  float minus, plus;
1066 
1067  double center = calcKappa(entries, weights, powers, minus, plus, false, verbose);
1068  minus = 1./(1.+minus/center);
1069  plus = 1.+plus/center;
1070  for(size_t ir4 = 0; ir4 < nr4; ++ir4){
1071  if(map.at(ir4) == icr){
1072  file << " -";
1073  for(size_t ibkg = 0; ibkg < gps.size(); ++ibkg){
1074  file << ' ' << minus << '/' << plus;
1075  }
1076  }else{
1077  for(size_t ibkg = 0; ibkg < (gps.size()+1); ++ibkg){
1078  file << ' ' << setw(12) << '-';
1079  }
1080  }
1081  }
1082  file << '\n';
1083  }
1084 }
1085 
1086 void PrintDebug(const vector<GammaParams> &gps, const string &name){
1087  cout
1088  << ' ' << setw(16) << "Process"
1089  << ' ' << setw(16) << "Bin"
1090  << ' ' << setw(16) << "Yield"
1091  << ' ' << setw(16) << "Uncertainty"
1092  << ' ' << setw(16) << "N. Effective"
1093  << ' ' << setw(16) << "Weight"
1094  << endl;
1095  for(size_t ibin = 0; ibin < gps.size(); ++ibin){
1096  printf(" %16s", name.c_str());
1097  printf(" %16d", static_cast<int>(ibin+1));
1098  printf(" %16.2f", gps.at(ibin).Yield());
1099  printf(" %16.2f", gps.at(ibin).Uncertainty());
1100  printf(" %16.2f", gps.at(ibin).NEffective());
1101  printf(" %16.6f", gps.at(ibin).Weight());
1102  printf("\n");
1103  fflush(0);
1104  }
1105 }
void GammaToLogN2(ofstream &file, const vector< size_t > &map, size_t nr1, size_t nr2, size_t nr4, const vector< double > &counts, size_t nbkgs)
Definition: make_card.cxx:986
void GammaToLogN13(ofstream &file, const vector< size_t > &map, size_t nr1, size_t nr2, size_t nr4, const vector< double > &counts, size_t nbkgs)
Definition: make_card.cxx:953
void PrintDebug(const vector< GammaParams > &gps, const string &name)
Definition: make_card.cxx:1086
void WriteFile(const vector< vector< GammaParams > > &bkg_gps, const vector< string > &bkg_names, const vector< GammaParams > &sig_gp, const vector< GammaParams > &mc_gp, const vector< double > &data_counts)
Definition: make_card.cxx:566
Definition: timer.hpp:6
std::string ToString(const T &x)
Definition: make_card.hpp:71
void GetOptions(int argc, char *argv[])
Definition: make_card.cxx:129
int const & nbm() const
Definition: small_tree.cpp:550
float const & weight() const
Definition: small_tree.cpp:506
void GetBinMapping(size_t &nr1, vector< size_t > &r1_map, size_t &nr2, vector< size_t > &r2_map, size_t &nr3, vector< size_t > &r3_map, size_t &nr4, vector< size_t > &r4_map)
Definition: make_card.cxx:520
int const & nmus() const
Definition: small_tree.cpp:605
void PrintGamma(ofstream &file, const vector< size_t > map, const string &name, size_t iregion, size_t nr1, size_t nr2, size_t nr3, size_t nr4, const vector< GammaParams > &gps, const vector< double > &preds, size_t iproc, size_t nbkgs)
Definition: make_card.cxx:745
STL namespace.
void CountsToGammas(double sumw, double sumw2, double sumw_backup, double sumw2_backup, double &nraw, double &weight)
Definition: make_card.cxx:318
string NoDecimal(double x)
Definition: make_card.cxx:783
int main(int argc, char *argv[])
Definition: make_card.cxx:74
int const & nels() const
Definition: small_tree.cpp:572
void GetMCTotals(vector< GammaParams > &mc_gp, const vector< vector< GammaParams > > &bkg_gps)
Definition: make_card.cxx:493
float const & met() const
Definition: small_tree.cpp:462
string Expand(string in, size_t size)
Definition: make_card.cxx:946
virtual float const & mj() const
tuple kappa
Definition: parse_card.py:264
void RepAsymLogN(ofstream &file, double minus, double plus, size_t nbkgs)
Definition: make_card.cxx:939
void RepLogN(ofstream &file, double val, size_t nbkgs)
Definition: make_card.cxx:932
void GetGammaParameters(int &raw_out, double &weight_out, double raw_in, double weight_in, double pred_in)
Definition: make_card.cxx:697
void GetCounts(small_tree_quick &tree, vector< GammaParams > &gp)
Definition: make_card.cxx:266
tuple pred
Definition: parse_card.py:266
double GetPred(const vector< double > &data, const vector< GammaParams > &mc_gp, const vector< GammaParams > &proc_gp, size_t ir1, size_t ir2, size_t ir3, size_t ir4)
Definition: make_card.cxx:707
float const & mt() const
Definition: small_tree.cpp:484
double sqr(double x)
Definition: make_card.cxx:562
size_t LookUpBin(small_tree_quick &tree)
Definition: make_card.cxx:336
int const & njets() const
Definition: small_tree.cpp:583
virtual void GetEntry(const long entry)
tuple file
Definition: parse_card.py:238
long GetEntries() const
Definition: small_tree.cpp:400
void MockUpData(vector< double > &data, const vector< GammaParams > &sig_gp, const vector< vector< GammaParams > > &bkg_gps)
Definition: make_card.cxx:508
void Iterate()
Definition: timer.cpp:28
virtual int const & ntks_chg_mini() const
void Start()
Definition: timer.cpp:22
tuple data
Definition: parse_card.py:260
int Add(const std::string &filename)
Definition: small_tree.cpp:381
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, bool do_plot=false, int nrep=100000)
float const & ht() const
Definition: small_tree.cpp:451
void PrintSystematics(ofstream &file, size_t nbkgs)
Definition: make_card.cxx:796