21 #include "RooStats/RooStatsUtils.h" 27 set<string>
Glob(
const string &pattern){
29 glob(pattern.c_str(), GLOB_TILDE,
nullptr, &glob_result);
31 for(
size_t i=0; i<glob_result.gl_pathc; ++i){
32 ret.emplace(realpath(glob_result.gl_pathv[i],
nullptr));
34 globfree(&glob_result);
39 vector<char> c(filename.cbegin(), filename.cend());
41 return string(basename(&c.at(0)));
44 bool Contains(
const string &str,
const string &pat){
45 return str.find(pat) != string::npos;
49 return str.find(pat) == 0;
52 void ReplaceAll(
string &str,
const string &orig,
const string &rep){
54 while ((loc = str.find(orig, loc)) != string::npos) {
55 str.replace(loc, orig.length(), rep);
66 FILE *pipe = popen(cmd.c_str(),
"r");
67 if(!pipe)
throw runtime_error(
"Could not open pipe.");
68 const size_t buffer_size = 128;
69 char buffer[buffer_size];
72 if(fgets(buffer, buffer_size, pipe) != NULL) result += buffer;
80 ReplaceAll(code,
"((leps_pt[0]>30&&leps_eta[0]<2.1&&leps_eta[0]>-2.1)||(leps_pt[1]>30&&leps_eta[1]<2.1&&leps_eta[1]>-2.1))",
"SLtrig");
81 ReplaceAll(code,
"(mumu_m*(mumu_m>0&&mumu_pt1>30)+elel_m*(elel_m>0&&elel_pt1>30))>80&&(mumu_m*(mumu_m>0&&mumu_pt1>30)+elel_m*(elel_m>0&&elel_pt1>30))<100",
"zmasswindow");
108 for(
size_t i = 0; i < code.size(); ++i){
109 if(isalnum(code.at(i)) || code.at(i) ==
'.' || code.at(i) ==
'_')
continue;
110 code = code.substr(0,i)+code.substr(i+1);
121 >>>>>>> b1f888b55e7125d5a772cc4a7067bd650781e35f
122 ReplaceAll(code,
"ht1l_stmin2l",
"1l: H_{T}>500, 2l: H_{T} + p_{T}^{l,min}");
123 ReplaceAll(code,
"ht1l_stmax2l",
"1l: H_{T}>500, 2l: H_{T} + p_{T}^{l,max}");
124 ReplaceAll(code,
"ht1l_stave2l",
"1l: H_{T}>500, 2l: H_{T} + p_{T}^{l,ave}");
128 ReplaceAll(code,
"met>150&&met<=200",
"150<met<=200");
130 ReplaceAll(code,
"met>100&&met<=150",
"100<met<=150");
131 ReplaceAll(code,
"met>150&&met<=200",
"150<met<=200");
132 ReplaceAll(code,
"met>200&&met<=300",
"200<met<=300");
133 >>>>>>> b1f888b55e7125d5a772cc4a7067bd650781e35f
134 ReplaceAll(code,
"met>200&&met<=350",
"200<met<=350");
135 ReplaceAll(code,
"met>350&&met<=500",
"350<met<=500");
136 ReplaceAll(code,
"njets>=5&&njets<=7",
"5<=njets<=7");
137 ReplaceAll(code,
"njets>=6&&njets<=8",
"6<=njets<=8");
138 ReplaceAll(code,
"nbm>=1&&nbm<=2",
"1<=nbm<=2");
141 ReplaceAll(code,
"el_tks_chg*lep_charge<0",
"OS");
142 ReplaceAll(code,
"mu_tks_chg*lep_charge<0",
"OS");
143 ReplaceAll(code,
"had_tks_chg*lep_charge<0",
"OS");
144 ReplaceAll(code,
"Sum$(abs(mc_id)==11)",
"N^{true}_{e}");
145 ReplaceAll(code,
"Sum$(abs(mc_id)==13)",
"N^{true}_{#mu}");
146 ReplaceAll(code,
"Sum$(genels_pt>0)",
"N^{true}_{e}");
147 ReplaceAll(code,
"Sum$(genmus_pt>0)",
"N^{true}_{#mu}");
148 ReplaceAll(code,
"Sum$(mus_sigid&&mus_miniso<0.2)",
"N_{#mu}^{10}");
149 ReplaceAll(code,
"Sum$(els_sigid&&els_miniso<0.1)",
"N_{e}^{10}");
150 ReplaceAll(code,
"nvmus==1&&nmus==1&&nvels==0",
"1 #mu");
151 ReplaceAll(code,
"nvmus10==0&&nvels10==0",
"0 leptons");
155 ReplaceAll(code,
"(nvmus+nvels)",
"N^{veto}_{lep}");
156 ReplaceAll(code,
"nvmus==2&&nmus>=1",
"N_{#mu}#geq1, N^{veto}_{#mu}=2");
157 ReplaceAll(code,
"nvels==2&&nels>=1",
"N_{e}#geq1, N^{veto}_{e}=2");
158 ReplaceAll(code,
"(nvmus>=2||nvels>=2)",
"N^{veto}_{lep} #geq 2");
159 ReplaceAll(code,
"(mumu_m*(mumu_m>0)+elel_m*(elel_m>0))>80&&(mumu_m*(mumu_m>0)+elel_m*(elel_m>0))<100",
167 ReplaceAll(code,
"(nels==0&&nmus==1)",
"N_{#mu}=1");
168 ReplaceAll(code,
"(nels==1&&nmus==0)",
"N_{#font[12]{e}}=1");
169 ReplaceAll(code,
"Max$(abs(els_eta)*(els_sigid&&els_miniso<0.1&&els_pt>20))<1.479",
"barrel #font[12]{e}");
170 ReplaceAll(code,
"Max$(abs(els_eta)*(els_sigid&&els_miniso<0.1&&els_pt>20))>1.479",
"endcap #font[12]{e}");
172 ReplaceAll(code,
"!low_dphi",
"high #Delta#phi");
173 ReplaceAll(code,
"hig_drmax",
"#DeltaR^{max}_{bb}");
181 ReplaceAll(code,
"ntruleps",
"N^{true}_{lep}");
187 ReplaceAll(code,
"abs(mc_id)==1000006",
"stop");
188 ReplaceAll(code,
"abs(mc_id)==1000022",
"LSP");
195 ReplaceAll(code,
"fjets_nconst",
"N_{const}^{fat jet}");
198 ReplaceAll(code,
"(fjets_pt*cosh(fjets_eta))",
"p_{fatjet}");
199 ReplaceAll(code,
"fjets_pt",
"p^{fatjet}_{T}");
203 ReplaceAll(code,
"mus_miniso_tr15",
"MiniIso");
204 ReplaceAll(code,
"els_miniso_tr15",
"MiniIso");
225 ReplaceAll(code,
"had_tks_mt",
"Track m_{T}");
228 ReplaceAll(code,
"had_tks_pt",
"Track p_{T}");
229 ReplaceAll(code,
"el_tks_miniso",
"Track miniso");
230 ReplaceAll(code,
"mu_tks_miniso",
"Track miniso");
231 ReplaceAll(code,
"had_tks_miniso",
"Track miniso");
232 ReplaceAll(code,
"el_tks_chg_miniso",
"Track charged miniso");
233 ReplaceAll(code,
"mu_tks_chg_miniso",
"Track charged miniso");
234 ReplaceAll(code,
"had_tks_chg_miniso",
"Track charged miniso");
235 ReplaceAll(code,
"jetsys_nob_pt",
"ISR p_{T}");
249 const string& tokens){
250 char* ipt(
new char[input.size()+1]);
251 memcpy(ipt, input.data(), input.size());
252 ipt[input.size()]=
static_cast<char>(0);
253 char* ptr(strtok(ipt, tokens.c_str()));
254 vector<string> output(0);
256 output.push_back(ptr);
257 ptr=strtok(NULL, tokens.c_str());
264 char *dir_name =
new char[prefix.size()];
265 if(dir_name ==
nullptr)
throw runtime_error(
"Could not allocate directory name");
266 strcpy(dir_name, prefix.c_str());
274 double entries = h.GetEntries();
275 int nbins = h.GetNbinsX();
276 double low = h.GetBinLowEdge(1);
277 double high = h.GetBinLowEdge(nbins+1);
278 double width = (high-low)/nbins;
279 for(
int bin = 1; bin <= nbins; ++bin){
280 double content = h.GetBinContent(bin);
281 double error = h.GetBinError(bin);
282 double this_width = h.GetBinWidth(bin);
283 double scale = width/this_width;
284 h.SetBinContent(bin, content*scale);
285 h.SetBinError(bin, error*scale);
287 h.SetEntries(entries);
290 void Normalize(TH1D &h,
double normalization,
bool norm_per_avg_width){
291 int nbins = h.GetNbinsX();
292 double low = h.GetBinLowEdge(1);
293 double high = h.GetBinLowEdge(nbins+1);
294 double width = (high-low)/nbins;
295 if(norm_per_avg_width) normalization *= width;
296 double integral = h.Integral(
"width");
297 h.Scale(normalization/integral);
302 h.SetBinContent(1, h.GetBinContent(0)+h.GetBinContent(1));
303 h.SetBinContent(0, 0.);
304 h.SetBinError(1, hypot(h.GetBinError(0), h.GetBinError(1)));
305 h.SetBinError(0, 0.);
307 int nbins = h.GetNbinsX();
309 h.SetBinContent(nbins, h.GetBinContent(nbins)+h.GetBinContent(nbins+1));
310 h.SetBinContent(nbins+1, 0.);
311 h.SetBinError(nbins, hypot(h.GetBinError(nbins), h.GetBinError(nbins+1)));
312 h.SetBinError(nbins+1, 0.);
317 int digits_left = max(floor(log10(x))+1., 0.);
318 int digits_right = max(n_digits-digits_left, 0);
320 double multiplier = pow(10., digits_right);
323 oss << setprecision(numeric_limits<double>::digits10) << round(x*multiplier)/multiplier << flush;
324 string out = oss.str();
325 if(out.substr(0,2) ==
"0."){
332 return string(h.GetTitle())
333 +
";"+h.GetXaxis()->GetTitle()
334 +
";"+h.GetYaxis()->GetTitle();
338 long seconds = round(fseconds);
339 int minutes((seconds/60)%60), hours(seconds/3600);
341 if(hours<10) hhmmss +=
"0";
342 hhmmss += hours; hhmmss +=
":";
343 if(minutes<10) hhmmss +=
"0";
344 hhmmss += minutes; hhmmss +=
":";
345 if((seconds%60)<10) hhmmss +=
"0";
346 hhmmss += seconds%60;
352 TString result(
""); result += num;
353 int posdot(result.First(
'.'));
354 if(posdot==-1) posdot = result.Length();
355 for(
int ind(posdot-3); ind > 0; ind -= 3)
356 result.Insert(ind,
",");
362 if(denom==0 || !isfinite(num) || !isfinite(denom))
return " - ";
363 double neg = 1;
if(num*denom<0) neg = -1;
364 num /= neg*denom; num += 0.5*pow(10.,-decimals);
365 if(abs(num) > 1e16)
return "-";
366 long num_int =
static_cast<long>(num);
367 long num_dec =
static_cast<long>((1+num-num_int)*pow(10.,decimals));
368 TString s_dec =
""; s_dec += num_dec; s_dec.Remove(0,1);
370 if(neg<0) result+=
"-";
373 result+=
"."; result+=s_dec;
376 TString afterdot = result;
377 afterdot.Remove(0,afterdot.First(
".")+1);
378 for(
int i=0; i<decimals-afterdot.Length(); i++)
380 if(result.Length()>15) cout<<
"num "<<num<<
", denom "<<denom<<
" ----> "<<result<<endl;
388 double u = rand.Uniform(1);
393 double d = a - 1.0 / 3.0;
394 double c = (1.0 / 3.0) / sqrt (d);
398 x = rand.Gaus(0, 1.0);
406 if (u < 1 - 0.0331 * x * x * x * x)
409 if (log (u) < 0.5 * x * x + d * (1 - v + log (v)))
416 double intGaus(
double mean,
double sigma,
double minX,
double maxX){
417 return (TMath::Erf((maxX-mean)/sigma/sqrt(2.))-TMath::Erf((minX-mean)/sigma/sqrt(2.)))/2.;
420 float deltaR(
float eta1,
float phi1,
float eta2,
float phi2){
421 return hypot(TVector2::Phi_mpi_pi(phi2-phi1), eta2-eta1);
426 double Significance(
double Nobs,
double Nbkg,
double Eup_bkg,
double Edown_bkg){
427 double precision = 0.03;
428 double Nmin = 1/pow(precision,2), Nmax = 5e7;
429 double Nbelow=0, Nabove=0, Nequal=0;
430 if(Edown_bkg<0) Edown_bkg = Eup_bkg;
432 cout<<
"Down uncertainty ("<<Edown_bkg<<
") has to be smaller than Nbkg ("<<Nbkg<<
")"<<endl;
438 while( (min(Nbelow,Nabove)+Nequal)<Nmin && (Nbelow+Nequal+Nabove)<Nmax){
441 valG = rand.Gaus(0,1);
442 if(mu==0) mu = fabs(valG)*Eup_bkg;
443 else if(valG>=0) mu *= exp(valG*log(1+Eup_bkg/Nbkg));
444 else if(Edown_bkg<0.8*Nbkg) mu *= exp(-valG*log(1-Edown_bkg/Nbkg));
445 else mu = max(0., mu + valG*Edown_bkg);
447 double valPois = rand.PoissonD(mu);
448 if(valPois>Nobs) Nabove++;
449 else if(valPois==Nobs) Nequal++;
453 if(Nabove+Nequal==0){
454 cout<<
"No toys above or at Nobs="<<Nobs<<
" for Nbkg "<<Nbkg<<
"+"<<Eup_bkg<<
"-"<<Edown_bkg<<
". Returning " 455 <<RooStats::PValueToSignificance(1/Nmax)<<endl;
456 return RooStats::PValueToSignificance(1/Nmax);
458 if(Nbelow+Nequal==0){
459 cout<<
"No toys below or at Nobs="<<Nobs<<
" for Nbkg "<<Nbkg<<
"+"<<Eup_bkg<<
"-"<<Edown_bkg<<
". Returning " 460 <<RooStats::PValueToSignificance(1-1/Nmax)<<endl;
461 return RooStats::PValueToSignificance(1-1/Nmax);
463 return RooStats::PValueToSignificance((Nabove+Nequal/2.)/(Nbelow+Nequal+Nabove));
469 double calcKappa(vector<vector<float> > &entries, vector<vector<float> > &weights,
470 vector<float> &powers,
float &mSigma,
float &pSigma,
bool do_data,
471 bool verbose,
double syst,
bool do_plot,
int nrep){
474 vector<float> fKappas;
475 double mean(0.),
bignum(1e10);
477 for(
int rep(0), irep(0); rep < nrep; rep++) {
478 fKappas.push_back(1.);
479 bool Denom_is0(
false);
480 for(
unsigned obs(0); obs < powers.size(); obs++) {
482 for(
unsigned sam(0); sam < entries[obs].size(); sam++) {
485 if(do_data) observed += entries[obs][sam]*weights[obs][sam];
486 else observed +=
gsl_ran_gamma(entries[obs][sam]+1,1,rand)*weights[obs][sam];
490 if(observed <= 0 && powers[obs] < 0) Denom_is0 =
true;
491 else fKappas[irep] *= pow(observed, powers[obs]);
495 double factor = exp(rand.Gaus(0,log(1+syst)));
496 fKappas[irep] *= factor;
498 if(Denom_is0 && fKappas[irep]==0) {
502 if(Denom_is0) fKappas[irep] =
bignum;
503 else mean += fKappas[irep];
507 int ntot(nrep-nbadk);
508 mean /=
static_cast<double>(ntot);
510 sort(fKappas.begin(), fKappas.end());
511 double gSigma =
intGaus(0,1,0,1);
512 int iMedian((nrep-nbadk+1)/2-1);
513 int imSigma(iMedian-static_cast<int>(gSigma*ntot)), ipSigma(iMedian+static_cast<int>(gSigma*ntot));
514 float median(fKappas[iMedian]);
515 mSigma = median-fKappas[imSigma]; pSigma = fKappas[ipSigma]-median;
520 for(
unsigned obs(0); obs < powers.size(); obs++) {
522 if(verbose) cout<<obs<<
": ";
523 for(
unsigned sam(0); sam < entries[obs].size(); sam++) {
524 if(verbose) cout<<
"Yield"<<sam<<
" "<<entries[obs][sam]*weights[obs][sam]
525 <<
", N"<<sam<<
" "<<entries[obs][sam]
526 <<
", avW"<<sam<<
" "<<weights[obs][sam]<<
". ";
527 stdyield += entries[obs][sam]*weights[obs][sam];
529 if(verbose) cout<<
" ==> Total yield "<<stdyield<<endl;
530 if(stdyield <= 0 && powers[obs] < 0) infStd =
true;
531 else stdval *= pow(stdyield, powers[obs]);
533 if(infStd) stdval = median;
536 for(
int rep(0); rep < ntot; rep++)
537 if(fKappas[rep]>stdval) {istd = rep;
break;}
538 imSigma = istd-
static_cast<int>(gSigma*ntot);
539 ipSigma = istd+
static_cast<int>(gSigma*ntot);
541 ipSigma += (-imSigma);
545 imSigma -= (ipSigma-ntot+1);
548 mSigma = stdval-fKappas[imSigma]; pSigma = fKappas[ipSigma]-stdval;
553 double minH(stdval-3*mSigma), maxH(stdval+3*pSigma);
554 if(minH < fKappas[0]) minH = fKappas[0];
555 if(maxH > fKappas[ntot-1]) maxH = fKappas[ntot-1];
556 TH1D histo(
"h",
"",nbins, minH, maxH);
557 for(
int rep(0); rep < ntot; rep++)
558 histo.Fill(fKappas[rep]);
561 histo.Scale(1/histo.Integral());
562 histo.SetMaximum(histo.GetMaximum()*1.2);
563 histo.SetLineWidth(3);
565 histo.SetXTitle(
"Expected value");
566 histo.SetYTitle(
"Probability");
568 if(do_plot) can.SaveAs(
"test.eps");
570 double mode(histo.GetBinLowEdge(histo.GetMaximumBin()));
571 if(verbose) cout<<
"Std kappa = "<<stdval<<
"+"<<pSigma<<
"-"<<mSigma<<
". Mean = "<<mean
572 <<
". Mode = "<<mode<<
". Median = "<<median<<endl;
double Significance(double Nobs, double Nbkg, double Eup_bkg, double Edown_bkg)
string MakeDir(string prefix)
void MergeOverflow(TH1D &h, bool merge_underflow, bool merge_overflow)
string CodeToLatex(string code)
TString RoundNumber(double num, int decimals, double denom)
string CodeToRootTex(string code)
void AdjustDensityForBinWidth(TH1D &h)
string FixedDigits(double x, int n_digits)
void Normalize(TH1D &h, double normalization, bool norm_per_avg_width)
void ReplaceAll(string &str, const string &orig, const string &rep)
double intGaus(double mean, double sigma, double minX, double maxX)
vector< string > Tokenize(const string &input, const string &tokens)
TString AddCommas(double num)
float deltaR(float eta1, float phi1, float eta2, float phi2)
double gsl_ran_gamma(const double a, const double b, TRandom3 &rand)
TString HoursMinSec(float fseconds)
string CodeToPlainText(string code)
set< string > Glob(const string &pattern)
bool StartsWith(const string &str, const string &pat)
double calcKappa(vector< vector< float > > &entries, vector< vector< float > > &weights, vector< float > &powers, float &mSigma, float &pSigma, bool do_data, bool verbose, double syst, bool do_plot, int nrep)
string CopyReplaceAll(string str, const string &orig, const string &rep)
string FullTitle(const TH1 &h)
string Basename(const string &filename)
bool Contains(const string &str, const string &pat)
string execute(const string &cmd)