ra4_stats  0341147a0dc35f80f4e12c6003afb76a38e2ed6e
sig_inj.cxx
Go to the documentation of this file.
1 #include "sig_inj.hpp"
2 
3 #include <cmath>
4 
5 #include <fstream>
6 #include <iostream>
7 #include <iomanip>
8 #include <sstream>
9 #include <vector>
10 #include <algorithm>
11 #include <future>
12 #include <utility>
13 #include <mutex>
14 #include <limits>
15 #include <numeric>
16 #include <functional>
17 
18 #include <stdlib.h>
19 #include <getopt.h>
20 
21 #include "TFile.h"
22 #include "TGraphAsymmErrors.h"
23 #include "TH1D.h"
24 #include "TCanvas.h"
25 #include "TF1.h"
26 #include "TLine.h"
27 
28 #include "RooWorkspace.h"
29 #include "RooRealVar.h"
30 #include "RooArgList.h"
31 #include "RooFitResult.h"
32 
33 #include "utilities.hpp"
34 #include "styles.hpp"
35 #include "thread_pool.hpp"
36 
37 using namespace std;
38 
39 namespace{
40  int ntoys = 5;
41  vector<double> injections;
42  double lumi = 2.246;
43  bool do_asymmetric_error = false;
44  bool do_systematics = false;
45  bool draw_only = false;
46 
47  mutex global_mutex;
48 }
49 
50 int main(int argc, char *argv[]){
51  GetOptions(argc, argv);
52  styles style("RA4");
53  style.setDefaultStyle();
54 
55  ostringstream oss;
56  oss
57  << "toys_" << ntoys
58  << "_lumi_" << lumi
59  << (do_asymmetric_error ? "_asym_error" : "")
60  << (do_systematics ? "_with_syst" : "")
61  << flush;
62  string id_string = oss.str();
63 
64  ThreadPool thread_pool;
65  if(!draw_only){
66  cout << "Creating workspaces..." << endl;
67  vector<future<void> > injected(injections.size());
68  for(size_t i = 0; i < injections.size(); ++i){
69  injected.at(i) = thread_pool.Push(InjectSignal, id_string, injections.at(i), i);
70  }
71  for(size_t i = 0; i < injected.size(); ++i){
72  injected.at(i).get();
73  }
74  }
75 
76  vector<vector<double> > yvals_nc(injections.size(), vector<double>(ntoys, -9876543210.));
77  vector<vector<double> > yvals_c(injections.size(), vector<double>(ntoys, -9876543210.));
78  vector<vector<double> > pulls_nc(injections.size(), vector<double>(ntoys, -9876543210.));
79  vector<vector<double> > pulls_c(injections.size(), vector<double>(ntoys, -9876543210.));
80 
81  if(!draw_only){
82  cout << "Extracting signal strength from toys..." << endl;
83  vector<vector<future<pair<double,double> > > > toyed_nc(ntoys);
84  vector<vector<future<pair<double,double> > > > toyed_c(ntoys);
85  for(int toy = 0; toy < ntoys; ++toy){
86  vector<future<pair<double,double> > > (injections.size()).swap(toyed_nc.at(toy));
87  vector<future<pair<double,double> > > (injections.size()).swap(toyed_c.at(toy));
88  for(size_t i = 0; i < injections.size(); ++i){
89  toyed_nc.at(toy).at(i) = thread_pool.Push(ExtractSignal, id_string, i, toy, true);
90  toyed_c.at(toy).at(i) = thread_pool.Push(ExtractSignal, id_string, i, toy, false);
91  }
92  }
93  for(int toy = 0; toy < ntoys; ++toy){
94  for(size_t i = 0; i < injections.size(); ++i){
95  auto res_nc = toyed_nc.at(toy).at(i).get();
96  yvals_nc.at(i).at(toy) = res_nc.first;
97  pulls_nc.at(i).at(toy) = res_nc.second;
98  auto res_c = toyed_c.at(toy).at(i).get();
99  yvals_c.at(i).at(toy) = res_c.first;
100  pulls_c.at(i).at(toy) = res_c.second;
101  }
102  }
103  execute("rm -f *_sig_inj_*.root");
104  }
105 
106  cout << "Generating plots..." << endl;
107  for(size_t i = 0; i < injections.size(); ++i){
108  RemoveBadResults(yvals_nc.at(i), pulls_nc.at(i));
109  RemoveBadResults(yvals_c.at(i), pulls_c.at(i));
110  }
111 
112  vector<double> inj_nc = injections;
113  vector<double> inj_c = injections;
114 
115  MergeWithText(inj_nc, yvals_nc, pulls_nc, true);
116  MergeWithText(inj_c, yvals_c, pulls_c, false);
117 
118  MakePlot(inj_nc, yvals_nc, true, false);
119  MakePlot(inj_c, yvals_c, false, false);
120  MakePlot(inj_nc, pulls_nc, true, true);
121  MakePlot(inj_c, pulls_c, false, true);
122 }
123 
124 void InjectSignal(const string id_string, double inject, size_t index){
125  {
126  lock_guard<mutex> lock(global_mutex);
127  cout << "Starting to inject signal with strength " << inject << endl;
128  }
129  ostringstream oss;
130  oss << "./run/make_workspace.exe --method m1bk"
131  << (do_systematics ? "" : " --no_syst") << " --lumi " << lumi << " --use_r4 --toys " << ntoys
132  << " --sig_strength " << inject << " --identifier sig_inj_" << id_string << "_" << index
133  << " < /dev/null &> /dev/null" << flush;
134  {
135  lock_guard<mutex> lock(global_mutex);
136  cout << "Executing " << oss.str() << endl;
137  }
138  execute(oss.str());
139  {
140  lock_guard<mutex> lock(global_mutex);
141  cout << "Done injecting signal with strength " << inject << endl;
142  }
143 }
144 
145 pair<double, double> ExtractSignal(const string id_string, size_t index, size_t toy, bool is_nc){
146  {
147  lock_guard<mutex> lock(global_mutex);
148  cout << "Extracting signal given strength " << injections.at(index) << " in toy " << toy << endl;
149  }
150  ostringstream oss;
151  oss << "ls -rt m1bk*" << (is_nc ? "_nc_" : "_c_")
152  << "*sig_inj_" << id_string << "_" << index << ".root | tail -n 1" << flush;
153  string file_name = execute(oss.str());
154  while(file_name.back() == '\n' || file_name.back() == ' '){
155  file_name.pop_back();
156  }
157  oss.str("");
158  string workdir = MakeDir("sig_inj_");
159  {
160  lock_guard<mutex> lock(global_mutex);
161  oss << "export origdir=$(pwd); "
162  << "cd ~/cmssw/CMSSW_7_1_5/src; "
163  << "eval `scramv1 runtime -sh` &> /dev/null; "
164  << "cd $origdir; "
165  << "cp " << file_name << ' ' << workdir << "; "
166  << "cd " << workdir << "; "
167  << "combine -M MaxLikelihoodFit --skipBOnlyFit --dataset data_obs_" << toy << " --preFitValue " << max(injections.at(index),0.01) << ' ' << file_name << " &> /dev/null; "
168  << "cd $origdir; "
169  << flush;
170  cout << "Executing " << oss.str() << endl;
171  }
172  string output = execute(oss.str());
173  {
174  lock_guard<mutex> lock(global_mutex);
175  TFile r_file((workdir+"/mlfit.root").c_str(),"read");
176  if(!r_file.IsOpen()) return pair<double, double>(-1., -1.);
177  RooFitResult *f = static_cast<RooFitResult*>(r_file.Get("fit_s"));
178  if(f == nullptr) return pair<double, double>(-1., -1.);
179  RooArgList pars = f->floatParsFinal();
180  for(int ipar = 0; ipar < pars.getSize(); ++ipar){
181  RooRealVar *var = static_cast<RooRealVar*>(pars.at(ipar));
182  if(var == nullptr) continue;
183  if(var->GetName() != string("r")) continue;
184  double val = var->getVal();
185  double delta = val - injections.at(index);
186  double ehi, elo;
188  GetAsymError(*var, ehi, elo);
189  }else{
190  ehi = GetError(*var, *f);
191  elo = ehi;
192  }
193  double pull = 0.;
194  if(delta < 0.){
195  pull = -fabs(delta)/fabs(ehi);
196  }else{
197  pull = fabs(delta)/fabs(elo);
198  }
199  cout << "Extracted strength " << val << " + " << ehi << " - " << fabs(elo) << " given strength " << injections.at(index) << " in toy " << toy << ". pull=" << pull << endl;
200  r_file.Close();
201  execute("rm -rf "+workdir);
202  return pair<double, double>(val, pull);
203  }
204  execute("rm -rf "+workdir);
205  r_file.Close();
206  }
207  return pair<double, double>(-1., -1.);
208 }
209 
210 double GetAsymError(const RooRealVar& var, double &ehi, double &elo){
211  if(var.hasAsymError()){
212  ehi = var.getAsymErrorHi();
213  elo = var.getAsymErrorLo();
214  double aehi = fabs(ehi);
215  double aelo = fabs(elo);
216  double delta = aehi - aelo;
217  return aelo + 0.5*delta;
218  }else if(var.hasError()){
219  ehi = var.getError();
220  elo = ehi;
221  return ehi;
222  }else{
223  ehi = 0.;
224  elo = 0.;
225  return 0.;
226  }
227 }
228 
229 double GetError(const RooAbsReal &var,
230  const RooFitResult &f){
231  // Clone self for internal use
232  RooAbsReal* cloneFunc = static_cast<RooAbsReal*>(var.cloneTree());
233  RooArgSet* errorParams = cloneFunc->getObservables(f.floatParsFinal());
234  RooArgSet* nset = cloneFunc->getParameters(*errorParams);
235 
236  // Make list of parameter instances of cloneFunc in order of error matrix
237  RooArgList paramList;
238  const RooArgList& fpf = f.floatParsFinal();
239  vector<int> fpf_idx;
240  for (int i=0; i<fpf.getSize(); i++) {
241  RooAbsArg* par = errorParams->find(fpf[i].GetName());
242  if (par) {
243  paramList.add(*par);
244  fpf_idx.push_back(i);
245  }
246  }
247 
248  vector<double> errors(paramList.getSize());
249  for (Int_t ivar=0; ivar<paramList.getSize(); ivar++) {
250  RooRealVar& rrv = static_cast<RooRealVar&>(fpf[fpf_idx[ivar]]);
251 
252  double cenVal = rrv.getVal();
253  double errVal = rrv.getError();
254 
255  // Make Plus variation
256  static_cast<RooRealVar*>(paramList.at(ivar))->setVal(cenVal+0.5*errVal);
257  double up = cloneFunc->getVal(nset);
258 
259  // Make Minus variation
260  static_cast<RooRealVar*>(paramList.at(ivar))->setVal(cenVal-0.5*errVal);
261  double down = cloneFunc->getVal(nset);
262 
263  errors.at(ivar) = (up-down);
264 
265  static_cast<RooRealVar*>(paramList.at(ivar))->setVal(cenVal);
266  }
267 
268  vector<double> right(errors.size());
269  for(size_t i = 0; i < right.size(); ++i){
270  right.at(i) = 0.;
271  for(size_t j = 0; j < errors.size(); ++j){
272  right.at(i) += f.correlation(paramList.at(i)->GetName(),paramList.at(j)->GetName())*errors.at(j);
273  }
274  }
275  double sum = 0.;
276  for(size_t i = 0; i < right.size(); ++i){
277  sum += errors.at(i)*right.at(i);
278  }
279 
280  if(cloneFunc != nullptr){
281  delete cloneFunc;
282  cloneFunc = nullptr;
283  }
284  if(errorParams != nullptr){
285  delete errorParams;
286  errorParams = nullptr;
287  }
288  if(nset != nullptr){
289  delete nset;
290  nset = nullptr;
291  }
292 
293  return sqrt(sum);
294 }
295 
296 void GetStats(const vector<double> &vals, double &mean, double &median,
297  double &up, double &down,
298  double &up2, double &down2){
299  double tail = erfc(1./sqrt(2.))*0.5; //0.159 = (1-0.683)/2
300  double tail2 = erfc(sqrt(2.))*0.5; //0.023 = (1-0.954)/2
301  median = GetValue(vals, 0.5);
302  mean = vals.size() > 0 ? accumulate(vals.cbegin(), vals.cend(), 0.)/vals.size() : 0.;
303  double low = GetValue(vals, tail);
304  double high = GetValue(vals, 1.-tail);
305  double low2 = GetValue(vals, tail2);
306  double high2 = GetValue(vals, 1.-tail2);
307  up = max(high-median,0.);
308  down = max(median-low,0.);
309  up2 = max(high2-median,0.);
310  down2 = max(median-low2,0.);
311 }
312 
313 double GetValue(vector<double> vals, double fraction){
314  if(vals.size() == 0) return 0.;
315  if(vals.size() == 1) return vals.front();
316  sort(vals.begin(), vals.end());
317  double frac_index = fraction*vals.size()-0.5;
318  long lo_index = static_cast<long>(floor(frac_index));
319  long hi_index = static_cast<long>(ceil(frac_index));
320  if(lo_index < 0){
321  lo_index = 0;
322  hi_index = 1;
323  }
324  if(static_cast<size_t>(hi_index) >= vals.size()){
325  lo_index = vals.size() - 2;
326  hi_index = vals.size() - 1;
327  }
328  double lo_value = vals.at(lo_index);
329  double hi_value = vals.at(hi_index);
330  return lo_value+(hi_value-lo_value)*(frac_index - lo_index);
331 }
332 
333 double GetMode(const vector<double> &v, double frac){
334  if(v.size() == 0){
335  return 0.;
336  }else if( v.size() == 1){
337  return v.front();
338  }else{
339  vector<double> temp = GetSmallestRange(v, frac);
340  if(temp.size() == v.size()){
341  if(v.size() == 2){
342  return v.front()+0.5*(v.back()-v.front());
343  }else{
344  double fdiff = v.at(1)-v.at(0);
345  double bdiff = v.at(2)-v.at(1);
346  if(fdiff>bdiff){
347  return GetMode(vector<double>(v.cbegin()+1, v.cend()), frac);
348  }else{
349  return GetMode(vector<double>(v.cbegin(), v.cend()-1), frac);
350  }
351  }
352  }else{
353  return GetMode(temp, frac);
354  }
355  }
356 }
357 
358 vector<double> GetSmallestRange(const vector<double> &v, double frac){
359  if(v.size() <= 1){
360  return v;
361  }else{
362  if(frac < 0.) frac = 0.;
363  if(frac > 1.) frac = 1.;
364  size_t dist = ceil(frac*(v.size()-1));
365  if(dist == v.size()-1) return v;
366  size_t best_start = 0;
367  double best_sep = v.back() - v.front();
368  for(size_t i = 0; i < v.size()-dist; ++i){
369  double sep = v.at(i+dist)-v.at(i);
370  if(sep < best_sep){
371  best_start = i;
372  best_sep = sep;
373  }
374  }
375  return vector<double>(v.cbegin()+best_start, v.cbegin()+best_start+dist);
376  }
377 }
378 
379 void GetOptions(int argc, char *argv[]){
380  set<double> injection_set;
381  while(true){
382  static struct option long_options[] = {
383  {"toys", required_argument, 0, 't'},
384  {"inject", required_argument, 0, 'i'},
385  {"lumi", required_argument, 0, 'l'},
386  {"asym", no_argument, 0, 'a'},
387  {"syst", no_argument, 0, 's'},
388  {"draw", no_argument, 0, 'd'},
389  {0, 0, 0, 0}
390  };
391 
392  char opt = -1;
393  int option_index;
394  opt = getopt_long(argc, argv, "t:i:l:asd", long_options, &option_index);
395  if( opt == -1) break;
396 
397  string optname;
398  switch(opt){
399  case 't':
400  ntoys = atoi(optarg);
401  break;
402  case 'i':
403  injection_set.insert(atof(optarg));
404  break;
405  case 'l':
406  lumi = atof(optarg);
407  break;
408  case 'a':
409  do_asymmetric_error = true;
410  break;
411  case 's':
412  do_systematics = true;
413  break;
414  case 'd':
415  draw_only = true;
416  break;
417  default:
418  printf("Bad option! getopt_long returned character code 0%o\n", opt);
419  break;
420  }
421  }
422  if(injection_set.size() == 0){
423  injections.resize(2);
424  injections.at(0) = 0.;
425  injections.at(1) = 1.;
426  }else{
427  injections = vector<double>(injection_set.cbegin(), injection_set.cend());
428  }
429 }
430 
431 void MakePlot(const vector<double> &injections_list,
432  const vector<vector<double> > &yvals,
433  bool is_nc, bool is_pull){
434  vector<double> zeros(injections_list.size(), 0.);
435  vector<double> means(injections_list.size()), medians(injections_list.size());
436  vector<double> ups(injections_list.size()), downs(injections_list.size());
437  vector<double> ups2(injections_list.size()), downs2(injections_list.size());
438  vector<double> tops(injections_list.size()), bots(injections_list.size());
439  vector<double> tops2(injections_list.size()), bots2(injections_list.size());
440  for(size_t i = 0; i < injections_list.size(); ++i){
441  GetStats(yvals.at(i), means.at(i), medians.at(i),
442  ups.at(i), downs.at(i),
443  ups2.at(i), downs2.at(i));
444  tops.at(i) = medians.at(i) + ups.at(i);
445  bots.at(i) = medians.at(i) - downs.at(i);
446  tops2.at(i) = medians.at(i) + ups2.at(i);
447  bots2.at(i) = medians.at(i) - downs2.at(i);
448  }
449 
450  TGraphAsymmErrors g(injections_list.size(), &injections_list.at(0), &medians.at(0),
451  &zeros.at(0), &zeros.at(0),
452  &downs.at(0), &ups.at(0));
453  TGraphAsymmErrors g2(injections_list.size(), &injections_list.at(0), &medians.at(0),
454  &zeros.at(0), &zeros.at(0),
455  &downs2.at(0), &ups2.at(0));
456  TGraph gm(injections_list.size(), &injections_list.at(0), &means.at(0));
457  g.SetMarkerStyle(20);
458  g.SetMarkerSize(2);
459  g.SetMarkerColor(kRed+2);
460  g.SetLineStyle(1);
461  g.SetLineWidth(5);
462  g.SetLineColor(kRed+2);
463  g2.SetMarkerStyle(0);
464  g2.SetMarkerSize(0);
465  g2.SetMarkerColor(0);
466  g2.SetLineStyle(2);
467  g2.SetLineWidth(3);
468  g2.SetLineColor(kRed+2);
469  gm.SetMarkerStyle(20);
470  gm.SetMarkerSize(2);
471  gm.SetMarkerColor(kBlue);
472  double xmax = *max_element(injections_list.cbegin(), injections_list.cend());
473  double xright = 1.0625*xmax;
474  double ymax = *max_element(tops.cbegin(), tops.cend());
475  ostringstream oss;
476  oss << ";Injected " << (is_nc ? "NC" : "C") << " Signal Strength;";
477  if(is_pull){
478  oss << "Pull";
479  }else{
480  oss << "Extracted " << (is_nc ? "NC" : "C") << " Signal Strength";
481  }
482  oss << flush;
483  TH1D h("", oss.str().c_str(), 1, 0., xright);
484  if(is_pull){
485  h.SetMinimum(-3.);
486  h.SetMaximum(3.);
487  }else{
488  h.SetMinimum(0.);
489  h.SetMaximum(ymax);
490  }
491  h.Fill(0.5, 1.0);
492  TF1 f("", "x", 0., xright);
493  f.SetLineColor(kBlack);
494  f.SetLineWidth(1);
495  f.SetLineStyle(3);
496  TCanvas c;
497  h.Draw("axis");
498  if(!is_pull){
499  f.Draw("same");
500  }
501  g.Draw("p 0 same");
502  g2.Draw("p 0 same");
503  gm.Draw("p same");
504  TLine hline;
505  hline.SetLineColor(kBlack);
506  hline.SetLineWidth(1);
507  hline.SetLineStyle(3);
508  if(is_pull){
509  hline.DrawLine(0, -2., xright, -2.);
510  hline.DrawLine(0, -1., xright, -1.);
511  hline.DrawLine(0, 0., xright, 0.);
512  hline.DrawLine(0, 1., xright, 1.);
513  hline.DrawLine(0, 2., xright, 2.);
514  }
515  oss.str("");
516  oss
517  << "siginj"
518  << (is_nc ? "_nc" : "_c")
519  << "_toys_" << ntoys
520  << "_lumi_" << lumi
521  << (do_asymmetric_error ? "_asym_error" : "")
522  << (do_systematics ? "_with_syst" : "")
523  << ".pdf"
524  << flush;
525  string plot_name = oss.str();
526  if(is_pull){
527  ReplaceAll(plot_name, "siginj", "pull");
528  }
529  c.Print(plot_name.c_str());
530 
531  for(size_t i = 0; i < injections_list.size(); ++i){
532  Plot1D(injections_list.at(i), yvals.at(i),
533  means.at(i), medians.at(i),
534  ups.at(i), downs.at(i),
535  ups2.at(i), downs2.at(i),
536  is_nc, is_pull);
537  }
538 }
539 
540 void Plot1D(double inj, const vector<double> &vals,
541  double mean, double median,
542  double up, double down,
543  double up2, double down2,
544  bool is_nc, bool is_pull){
545  if(vals.size() == 0) return;
546  ostringstream oss;
547  oss
548  << (is_pull ? "pull" : "siginj")
549  << "_" << (is_nc ? "nc" : "c")
550  << "_lumi_" << lumi
551  << "_inj_" << inj
552  << ".pdf"
553  << flush;
554  string name = oss.str();
555  oss.str("");
556  oss << "Inj. " << (is_nc ? "NC" : "C") << " Sig.=" << inj << ", N_{toys}=" << vals.size() << ";";
557  if(is_pull){
558  oss << "Pull";
559  }else{
560  if(is_nc){
561  oss << "Extracted NC Signal Strength";
562  }else{
563  oss << "Extracted C Signal Strength";
564  }
565  }
566  oss << ";# of Toys" << flush;
567 
568  TH1D h("", oss.str().c_str(), floor(sqrt(vals.size())),
569  *min_element(vals.cbegin(), vals.cend())-0.001,
570  *max_element(vals.cbegin(), vals.cend())+0.001);
571  h.SetLineWidth(5);
572  h.SetLineColor(kBlack);
573  h.Sumw2();
574  for(const auto &val: vals){
575  h.Fill(val);
576  }
577  double hmax = 0.;
578  for(int bin = 1; bin <= h.GetNbinsX(); ++bin){
579  double content = h.GetBinContent(bin)+h.GetBinError(bin);
580  if(content > hmax) hmax = content;
581  }
582  h.SetMinimum(0.);
583  h.SetMaximum(hmax);
584  TLine ldown2(median-down2, 0., median-down2, hmax);
585  ldown2.SetLineColor(kRed+2);
586  ldown2.SetLineStyle(3);
587  ldown2.SetLineWidth(2);
588  TLine ldown(median-down, 0., median-down, hmax);
589  ldown.SetLineColor(kRed+2);
590  ldown.SetLineStyle(2);
591  ldown.SetLineWidth(4);
592  TLine lmedian(median, 0., median, hmax);
593  lmedian.SetLineColor(kRed+2);
594  lmedian.SetLineWidth(5);
595  TLine lmean(mean, 0., mean, hmax);
596  lmean.SetLineColor(kBlue);
597  lmean.SetLineWidth(5);
598  TLine lup(median+up, 0., median+up, hmax);
599  lup.SetLineColor(kRed+2);
600  lup.SetLineStyle(2);
601  lup.SetLineWidth(4);
602  TLine lup2(median+up2, 0., median+up2, hmax);
603  lup2.SetLineColor(kRed+2);
604  lup2.SetLineStyle(3);
605  lup2.SetLineWidth(2);
606  TCanvas c;
607  h.Draw("e1p");
608  ldown2.Draw("same");
609  ldown.Draw("same");
610  lmedian.Draw("same");
611  lmean.Draw("same");
612  lup.Draw("same");
613  lup2.Draw("same");
614  c.Print(name.c_str());
615 }
616 
617 void RemoveBadResults(vector<double> &vals, vector<double> &pulls){
618  if(vals.size() != pulls.size()) ERROR("Vals and pull must have same length");
619  vector<size_t> bad_indices;
620  for(size_t i = 0; i < vals.size(); ++i){
621  if(vals.at(i) < 0.
622  || fabs(pulls.at(i)) >= 1000.){
623  bad_indices.push_back(i);
624  }
625  }
626  sort(bad_indices.begin(), bad_indices.end(), greater<size_t>());
627  for(size_t ii = 0; ii < bad_indices.size(); ++ii){
628  size_t i = bad_indices.at(ii);
629  vals.erase(vals.begin()+i);
630  pulls.erase(pulls.begin()+i);
631  }
632 }
633 
634 void MergeWithText(vector<double> &injs,
635  vector<vector<double> > &yvals,
636  vector<vector<double> > &pulls,
637  bool is_nc){
638  ostringstream oss;
639  oss << "txt/siginj/lumi_" << lumi << "_" << (is_nc ? "nc" : "c") << ".txt" << flush;
640  string path = oss.str();
641 
642  string line;
643  ifstream infile(path);
644  while(getline(infile, line)){
645  istringstream iss(line);
646  double inj, y, pull;
647  iss >> inj >> y >> pull;
648  size_t i = GetIndex(injs, inj);
649  if(i == static_cast<size_t>(-1)){
650  injs.push_back(inj);
651  yvals.push_back(vector<double>());
652  pulls.push_back(vector<double>());
653  i = injs.size() - 1;
654  }
655  yvals.at(i).push_back(y);
656  pulls.at(i).push_back(pull);
657  }
658  SortByInjectionStrength(injs, yvals, pulls);
659 
660  ofstream outfile(path);
661  outfile.precision(std::numeric_limits<double>::max_digits10);
662  for(size_t iinj = 0; iinj < injs.size(); ++iinj){
663  for(size_t itoy = 0; itoy < yvals.at(iinj).size() || itoy < pulls.at(iinj).size(); ++itoy){
664  outfile
665  << setw(32) << injs.at(iinj)
666  << ' ' << setw(32) << (itoy < yvals.at(iinj).size() ? yvals.at(iinj).at(itoy) : -9876543210.)
667  << ' ' << setw(32) << (itoy < pulls.at(iinj).size() ? pulls.at(iinj).at(itoy) : -9876543210.)
668  << endl;
669  }
670  }
671  outfile.close();
672 }
673 
674 size_t GetIndex(const vector<double> &v, double x){
675  for(size_t i = 0; i < v.size(); ++i){
676  if(v.at(i) == x) return i;
677  }
678  return -1;
679 }
680 
681 void SortByInjectionStrength(vector<double> &inj,
682  vector<vector<double> > &yvals,
683  vector<vector<double> > &pulls){
684  vector<size_t> vi(inj.size());
685  for(size_t i = 0; i < vi.size(); ++i) vi.at(i) = i;
686  sort(vi.begin(), vi.end(), [&](size_t a, size_t b){return inj.at(a)<inj.at(b);});
687  auto inj_temp = inj;
688  auto yvals_temp = yvals;
689  auto pulls_temp = pulls;
690  for(size_t i = 0; i < vi.size(); ++i){
691  inj.at(i) = inj_temp.at(vi.at(i));
692  yvals.at(i) = yvals_temp.at(vi.at(i));
693  pulls.at(i) = pulls_temp.at(vi.at(i));
694  sort(yvals.at(i).begin(), yvals.at(i).end());
695  sort(pulls.at(i).begin(), pulls.at(i).end());
696  }
697 }
void GetStats(const vector< double > &vals, double &mean, double &median, double &up, double &down, double &up2, double &down2)
Definition: sig_inj.cxx:296
void setDefaultStyle()
Definition: styles.cpp:36
double GetError(const RooAbsReal &var, const RooFitResult &f)
Definition: sig_inj.cxx:229
void RemoveBadResults(vector< double > &vals, vector< double > &pulls)
Definition: sig_inj.cxx:617
void ReplaceAll(std::string &str, const std::string &orig, const std::string &rep)
Definition: utilities.cpp:34
double GetAsymError(const RooRealVar &var, double &ehi, double &elo)
Definition: sig_inj.cxx:210
STL namespace.
int main(int argc, char *argv[])
Definition: sig_inj.cxx:50
vector< double > GetSmallestRange(const vector< double > &v, double frac)
Definition: sig_inj.cxx:358
auto Push(FuncType &&func, ArgTypes &&...args) -> std::future< decltype(func(args...))>
Definition: thread_pool.hpp:66
void MakePlot(const vector< double > &injections_list, const vector< vector< double > > &yvals, bool is_nc, bool is_pull)
Definition: sig_inj.cxx:431
std::string execute(const std::string &cmd)
Definition: utilities.cpp:87
size_t GetIndex(const vector< double > &v, double x)
Definition: sig_inj.cxx:674
void SortByInjectionStrength(vector< double > &inj, vector< vector< double > > &yvals, vector< vector< double > > &pulls)
Definition: sig_inj.cxx:681
#define ERROR(x)
Definition: utilities.hpp:15
def style(h, width, style, color)
void GetOptions(int argc, char *argv[])
Definition: sig_inj.cxx:379
double GetValue(vector< double > vals, double fraction)
Definition: sig_inj.cxx:313
void InjectSignal(const string id_string, double inject, size_t index)
Definition: sig_inj.cxx:124
double GetMode(const vector< double > &v, double frac)
Definition: sig_inj.cxx:333
void MergeWithText(vector< double > &injs, vector< vector< double > > &yvals, vector< vector< double > > &pulls, bool is_nc)
Definition: sig_inj.cxx:634
pair< double, double > ExtractSignal(const string id_string, size_t index, size_t toy, bool is_nc)
Definition: sig_inj.cxx:145
void Plot1D(double inj, const vector< double > &vals, double mean, double median, double up, double down, double up2, double down2, bool is_nc, bool is_pull)
Definition: sig_inj.cxx:540
vector< double > injections
Definition: sig_inj.cxx:41
string workdir
Definition: change_r.py:13
std::string MakeDir(std::string prefix)
Definition: utilities.cpp:126