7 std::string JeffreysScale =
"";
9 if(BayesFactor < 0) JeffreysScale =
"Negative";
10 else if( 5 > BayesFactor) JeffreysScale =
"Barely worth mentioning";
11 else if( 10 > BayesFactor) JeffreysScale =
"Substantial";
12 else if( 15 > BayesFactor) JeffreysScale =
"Strong";
13 else if( 20 > BayesFactor) JeffreysScale =
"Very strong";
14 else JeffreysScale =
"Decisive";
22 std::string DunneKaboth =
"";
25 if(2.125 > BayesFactor) DunneKaboth =
"< 1 #sigma";
26 else if( 20.74 > BayesFactor) DunneKaboth =
"> 1 #sigma";
27 else if( 369.4 > BayesFactor) DunneKaboth =
"> 2 #sigma";
28 else if( 15800 > BayesFactor) DunneKaboth =
"> 3 #sigma";
29 else if( 1745000 > BayesFactor) DunneKaboth =
"> 4 #sigma";
30 else DunneKaboth =
"> 5 #sigma";
39 switch (std::abs(sigma))
42 width = 0.682689492137;
45 width = 0.954499736104;
48 width = 0.997300203937;
51 width = 0.999936657516;
54 width = 0.999999426697;
57 width = 0.999999998027;
68double GetBIC(
const double llh,
const int data,
const int nPars){
72 MACH3LOG_ERROR(
"You haven't passed number of model parameters as it is still zero");
75 const double BIC = double(nPars * logl(data) + llh);
83 const double Nominator = (N1+N2);
84 const double Denominator = (N1*N2);
85 const double N_e = Nominator/Denominator;
91 const std::vector<double>& PValVec,
92 const double Threshold) {
95 if(SampleNameVec.size() != PValVec.size())
100 const size_t NumberOfStatisticalTests = SampleNameVec.size();
102 const double StatisticalSignificanceDown = Threshold / double(NumberOfStatisticalTests);
103 const double StatisticalSignificanceUp = 1 - StatisticalSignificanceDown;
104 MACH3LOG_INFO(
"Bonferroni-corrected statistical significance level: {:.2f}", StatisticalSignificanceDown);
107 for(
unsigned int i = 0; i < SampleNameVec.size(); i++)
109 if( (PValVec[i] < 0.5 && PValVec[i] < StatisticalSignificanceDown) ) {
110 MACH3LOG_INFO(
"Sample {} indicates disagreement between the model predictions and the data", SampleNameVec[i]);
111 MACH3LOG_INFO(
"Bonferroni-corrected statistical significance level: {:.2f} p-value: {:.2f}", StatisticalSignificanceDown, PValVec[i]);
113 }
else if( (PValVec[i] > 0.5 && PValVec[i] > StatisticalSignificanceUp) ) {
114 MACH3LOG_INFO(
"Sample {} indicates disagreement between the model predictions and the data", SampleNameVec[i]);
115 MACH3LOG_INFO(
"Bonferroni-corrected statistical significance level: {:.2f} p-value: {:.2f}", StatisticalSignificanceUp, PValVec[i]);
120 MACH3LOG_INFO(
"Every sample passed Bonferroni-corrected statistical significance level test");
122 MACH3LOG_WARN(
"{} samples didn't pass Bonferroni-corrected statistical significance level test", Counter);
130 double ADstat = std::fabs(CumulativeData - CumulativeMC)/ std::sqrt(CumulativeJoint*(1 - CumulativeJoint));
132 if( std::isinf(ADstat) || std::isnan(ADstat))
return 0;
139 int NumberOfRuns = 0;
140 int PreviousGroup = -999;
143 for (
unsigned int i = 0; i < GroupClasifier.size(); i++)
145 if(GroupClasifier[i] != PreviousGroup)
147 PreviousGroup = GroupClasifier[i];
160 const double k = mc*mc / w2;
162 Beta = (data + k) / (mc + k);
167 const double fractional = std::sqrt(w2)/mc;
169 const double temp = mc*fractional*fractional-1;
171 const double temp2 = temp*temp + 4*data*fractional*fractional;
173 MACH3LOG_ERROR(
"Negative square root in Barlow Beeston coefficient calculation!");
177 Beta = (-1*temp+std::sqrt(temp2))/2.;
184double GetSubOptimality(
const std::vector<double>& EigenValues,
const int TotalTarameters) {
186 double sum_eigenvalues_squared_inv = 0.0;
187 double sum_eigenvalues_inv = 0.0;
188 for (
unsigned int j = 0; j < EigenValues.size(); j++)
192 sum_eigenvalues_squared_inv += std::pow(EigenValues[j], -2);
193 sum_eigenvalues_inv += 1.0 / EigenValues[j];
195 const double SubOptimality = TotalTarameters * sum_eigenvalues_squared_inv / std::pow(sum_eigenvalues_inv, 2);
196 return SubOptimality;
203 Mean = hist->GetMean();
204 Error = hist->GetRMS();
210 const double meanval = hist->GetMean();
211 const double err = hist->GetRMS();
212 const double peakval = hist->GetBinCenter(hist->GetMaximumBin());
215 gauss->SetRange(meanval - 1.5*err , meanval + 1.5*err);
217 gauss->SetParameters(hist->GetMaximum()*err*std::sqrt(2*3.14), peakval, err);
220 hist->Fit(gauss->GetName(),
"Rq");
223 Mean = gauss->GetParameter(1);
224 Error = gauss->GetParameter(2);
228void GetHPD(TH1D*
const hist,
double&
Mean,
double& Error,
double& Error_p,
double& Error_m,
const double coverage) {
231 const int MaxBin = hist->GetMaximumBin();
233 const double peakval = hist->GetBinCenter(MaxBin);
236 const long double Integral = hist->Integral();
238 const long double LowIntegral = hist->Integral(1, MaxBin-1) + hist->GetBinContent(MaxBin)/2.0;
239 const long double HighIntegral = hist->Integral(MaxBin+1, hist->GetNbinsX()) + hist->GetBinContent(MaxBin)/2.0;
243 long double sum = hist->GetBinContent(MaxBin)/2.0;
246 int CurrBin = MaxBin;
247 while (sum/HighIntegral < coverage && CurrBin < hist->GetNbinsX()) {
249 sum += hist->GetBinContent(CurrBin);
251 const double sigma_p = std::fabs(hist->GetBinCenter(MaxBin)-hist->GetXaxis()->GetBinUpEdge(CurrBin));
254 sum = hist->GetBinContent(MaxBin)/2.0;
259 while (sum/LowIntegral < coverage && CurrBin > 1) {
261 sum += hist->GetBinContent(CurrBin);
263 const double sigma_m = std::fabs(hist->GetBinCenter(CurrBin)-hist->GetBinLowEdge(MaxBin));
267 sum = hist->GetBinContent(MaxBin);
269 int HighBin = MaxBin;
270 long double LowCon = 0.0;
271 long double HighCon = 0.0;
273 while (sum/Integral < coverage && (LowBin > 0 || HighBin < hist->GetNbinsX()+1))
281 LowCon = hist->GetBinContent(LowBin);
283 if(HighBin < hist->GetNbinsX())
286 HighCon = hist->GetBinContent(HighBin);
290 if ((sum+LowCon+HighCon)/Integral > coverage && LowCon > HighCon) {
294 }
else if ((sum+LowCon+HighCon)/Integral > coverage && HighCon >= LowCon) {
298 sum += LowCon + HighCon;
302 double sigma_hpd = 0.0;
303 if (LowCon > HighCon) {
304 sigma_hpd = std::fabs(hist->GetBinLowEdge(LowBin)-hist->GetBinCenter(MaxBin));
306 sigma_hpd = std::fabs(hist->GetXaxis()->GetBinUpEdge(HighBin)-hist->GetBinCenter(MaxBin));
316void GetCredibleInterval(
const std::unique_ptr<TH1D>& hist, std::unique_ptr<TH1D>& hpost_copy,
const double coverage) {
320 MACH3LOG_ERROR(
"Specified Credible Interval is greater that 1 and equal to {} Should be between 0 and 1", coverage);
324 hpost_copy->Reset(
"");
325 hpost_copy->Fill(0.0, 0.0);
328 std::vector<double> hist_copy(hist->GetXaxis()->GetNbins()+1);
329 std::vector<bool> hist_copy_fill(hist->GetXaxis()->GetNbins()+1);
330 for (
int i = 0; i <= hist->GetXaxis()->GetNbins(); ++i)
332 hist_copy[i] = hist->GetBinContent(i);
333 hist_copy_fill[i] =
false;
337 const long double Integral = hist->Integral();
340 while ((sum / Integral) < coverage)
343 int max_entry_bin = 0;
344 double max_entries = 0.;
345 for (
int i = 0; i <= hist->GetXaxis()->GetNbins(); ++i)
347 if (hist_copy[i] > max_entries)
349 max_entries = hist_copy[i];
354 hist_copy[max_entry_bin] = -1.;
355 hist_copy_fill[max_entry_bin] =
true;
360 for(
int i = 0; i <= hist->GetXaxis()->GetNbins(); ++i)
362 if(hist_copy_fill[i]) hpost_copy->SetBinContent(i, hist->GetBinContent(i));
367void GetCredibleIntervalSig(
const std::unique_ptr<TH1D>& hist, std::unique_ptr<TH1D>& hpost_copy,
const bool CredibleInSigmas,
const double coverage) {
370 if(CredibleInSigmas) {
372 const double CredReg =
GetSigmaValue(
int(std::round(coverage)));
384 MACH3LOG_ERROR(
"Specified Credible Region is greater than 1 and equal to {:.2f} Should be between 0 and 1 {}", coverage);
389 std::vector<std::vector<double>> hist_copy(hist2D->GetXaxis()->GetNbins()+1,
390 std::vector<double>(hist2D->GetYaxis()->GetNbins()+1));
391 for (
int i = 0; i <= hist2D->GetXaxis()->GetNbins(); ++i) {
392 for (
int j = 0; j <= hist2D->GetYaxis()->GetNbins(); ++j) {
393 hist_copy[i][j] = hist2D->GetBinContent(i, j);
398 const long double Integral = hist2D->Integral();
403 while ((sum / Integral) < coverage)
406 int max_entry_bin_x = 0;
407 int max_entry_bin_y = 0;
408 double max_entries = 0.;
409 for (
int i = 0; i <= hist2D->GetXaxis()->GetNbins(); ++i)
411 for (
int j = 0; j <= hist2D->GetYaxis()->GetNbins(); ++j)
413 if (hist_copy[i][j] > max_entries)
415 max_entries = hist_copy[i][j];
422 hist_copy[max_entry_bin_x][max_entry_bin_y] = -1.;
425 Contour[0] = max_entries;
427 hist2D->SetContour(1, Contour);
433 if(CredibleInSigmas) {
435 const double CredReg =
GetSigmaValue(
int(std::round(coverage)));
445 if(Hist->Integral() == 0)
return 0.0;
447 constexpr double quartiles_x[3] = {0.25, 0.5, 0.75};
450 Hist->GetQuantiles(3, quartiles, quartiles_x);
452 return quartiles[2] - quartiles[0];
458 double klDivergence = 0.0;
461 for (
int i = 1; i < DataPoly->GetNumberOfBins()+1; ++i)
463 if (DataPoly->GetBinContent(i) > 0 && PolyMC->GetBinContent(i) > 0) {
464 klDivergence += DataPoly->GetBinContent(i) / DataIntegral *
465 std::log((DataPoly->GetBinContent(i) / DataIntegral) / ( PolyMC->GetBinContent(i) / MCIntegral));
473 double testStatistic = 0;
474 for(
size_t i = 0; i < pvalues.size(); i++)
476 const double pval = std::max(0.00001, pvalues[i]);
477 testStatistic += -2.0 * std::log(pval);
480 int degreesOfFreedom = int(2 * pvalues.size());
481 double pValue = TMath::Prob(testStatistic, degreesOfFreedom);
490 std::string TempFilePath =
"Thinned_" + FilePath;
491 int ret = system((
"cp " + FilePath +
" " + TempFilePath).c_str());
493 MACH3LOG_WARN(
"Error: system call to copy file failed with code {}", ret);
496 TFile *inFile =
M3::Open(TempFilePath,
"RECREATE", __FILE__, __LINE__);
497 TTree *inTree = inFile->Get<TTree>(
"posteriors");
506 TTree *outTree = inTree->CloneTree(0);
509 Long64_t nEntries = inTree->GetEntries();
510 double retainedPercentage = (double(nEntries) / ThinningCut) /
double(nEntries) * 100;
511 MACH3LOG_INFO(
"Thinning will retain {:.2f}% of chains", retainedPercentage);
512 for (Long64_t i = 0; i < nEntries; i++) {
513 if (i % (nEntries/10) == 0) {
516 if (i % ThinningCut == 0) {
521 inFile->WriteTObject(outTree,
"posteriors",
"kOverwrite");
525 MACH3LOG_INFO(
"Thinned TTree saved and overwrote original in: {}", TempFilePath);
529double GetZScore(
const double value,
const double mean,
const double stddev) {
531 return (value - mean) / stddev;
537 return 0.5 * std::erfc(-zScore / std::sqrt(2));
545 int MaxBin = hpost->GetMaximumBin();
548 const double Integral = hpost->Integral();
551 int HighBin = MaxBin;
552 double sum = hpost->GetBinContent(MaxBin);;
554 double HighCon = 0.0;
555 while (sum/Integral < 0.6827 && (LowBin > 0 || HighBin < hpost->GetNbinsX()+1) )
563 LowCon = hpost->GetBinContent(LowBin);
565 if(HighBin < hpost->GetNbinsX())
568 HighCon = hpost->GetBinContent(HighBin);
572 if ((sum+LowCon+HighCon)/Integral > 0.6827 && LowCon > HighCon) {
576 }
else if ((sum+LowCon+HighCon)/Integral > 0.6827 && HighCon >= LowCon) {
580 sum += LowCon + HighCon;
584 double Mode_Error = 0.0;
585 if (LowCon > HighCon) {
586 Mode_Error = std::fabs(hpost->GetBinCenter(LowBin)-hpost->GetBinCenter(MaxBin));
588 Mode_Error = std::fabs(hpost->GetBinCenter(HighBin)-hpost->GetBinCenter(MaxBin));
598 const double TotalIntegral = Histogram->Integral();
602 for (
int i = 0; i < Histogram->GetXaxis()->GetNbins(); ++i) {
603 const double xvalue = Histogram->GetXaxis()->GetBinCenter(i+1);
604 for (
int j = 0; j < Histogram->GetYaxis()->GetNbins(); ++j) {
605 const double yvalue = Histogram->GetYaxis()->GetBinCenter(j+1);
607 if (xvalue >= yvalue) {
608 Above += Histogram->GetBinContent(i+1, j+1);
612 const double pvalue = Above/TotalIntegral;
613 std::stringstream ss;
614 ss << int(Above) <<
"/" << int(TotalIntegral) <<
"=" << pvalue;
615 Histogram->SetTitle((std::string(Histogram->GetTitle())+
"_"+ss.str()).c_str());
618 double minimum = Histogram->GetXaxis()->GetBinLowEdge(1);
619 if (Histogram->GetYaxis()->GetBinLowEdge(1) > minimum) {
620 minimum = Histogram->GetYaxis()->GetBinLowEdge(1);
622 double maximum = Histogram->GetXaxis()->GetBinLowEdge(Histogram->GetXaxis()->GetNbins());
623 if (Histogram->GetYaxis()->GetBinLowEdge(Histogram->GetYaxis()->GetNbins()) < maximum) {
624 maximum = Histogram->GetYaxis()->GetBinLowEdge(Histogram->GetYaxis()->GetNbins());
626 maximum += Histogram->GetYaxis()->GetBinWidth(Histogram->GetYaxis()->GetNbins());
628 else maximum += Histogram->GetXaxis()->GetBinWidth(Histogram->GetXaxis()->GetNbins());
629 auto TempLine = std::make_unique<TLine>(minimum, minimum, maximum, maximum);
630 TempLine->SetLineColor(kRed);
631 TempLine->SetLineWidth(2);
633 std::string Title = Histogram->GetName();
635 auto TempCanvas = std::make_unique<TCanvas>(Title.c_str(), Title.c_str(), 1024, 1024);
636 TempCanvas->SetGridx();
637 TempCanvas->SetGridy();
639 gStyle->SetPalette(81);
640 Histogram->SetMinimum(-0.01);
641 Histogram->Draw(
"colz");
642 TempLine->Draw(
"same");
double NoOverflowIntegral(TH2Poly *poly)
WP: Helper function for calculating binned Integral of TH2Poly i.e not including overflow.
TestStatistic
Make an enum of the test statistic that we're using.
@ kDembinskiAbdelmotteleb
Based on .
double GetSigmaValue(const int sigma)
KS: Convert sigma from normal distribution into percentage.
double ComputeKLDivergence(TH2Poly *DataPoly, TH2Poly *PolyMC)
Compute the Kullback-Leibler divergence between two TH2Poly histograms.
double GetSubOptimality(const std::vector< double > &EigenValues, const int TotalTarameters)
Based on .
double GetBIC(const double llh, const int data, const int nPars)
Get the Bayesian Information Criterion (BIC) or Schwarz information criterion (also SIC,...
double GetPValueFromZScore(const double zScore)
Compute the P-value from a given Z-score.
void Get2DBayesianpValue(TH2D *Histogram)
Calculates the 2D Bayesian p-value and generates a visualization.
double GetZScore(const double value, const double mean, const double stddev)
Compute the Z-score for a given value.
void GetGaussian(TH1D *&hist, TF1 *gauss, double &Mean, double &Error)
CW: Fit Gaussian to posterior.
void GetCredibleRegion(std::unique_ptr< TH2D > &hist2D, const double coverage)
KS: Set 2D contour within some coverage.
double GetModeError(TH1D *hpost)
Get the mode error from a TH1D.
double GetAndersonDarlingTestStat(const double CumulativeData, const double CumulativeMC, const double CumulativeJoint)
void GetCredibleIntervalSig(const std::unique_ptr< TH1D > &hist, std::unique_ptr< TH1D > &hpost_copy, const bool CredibleInSigmas, const double coverage)
KS: Get 1D histogram within credible interval, hpost_copy has to have the same binning,...
double FisherCombinedPValue(const std::vector< double > &pvalues)
KS: Combine p-values using Fisher's method.
double GetIQR(TH1D *Hist)
Interquartile Range (IQR)
void ThinningMCMC(const std::string &FilePath, const int ThinningCut)
Thin MCMC Chain, to save space and maintain low autocorrelations.
std::string GetJeffreysScale(const double BayesFactor)
KS: Following H. Jeffreys .
double GetNeffective(const int N1, const int N2)
KS: See 14.3.10 in Numerical Recipes in C .
void GetHPD(TH1D *const hist, double &Mean, double &Error, double &Error_p, double &Error_m, const double coverage)
Get Highest Posterior Density (HPD)
void GetCredibleRegionSig(std::unique_ptr< TH2D > &hist2D, const bool CredibleInSigmas, const double coverage)
KS: Set 2D contour within some coverage.
void GetArithmetic(TH1D *const hist, double &Mean, double &Error)
CW: Get Arithmetic mean from posterior.
void GetCredibleInterval(const std::unique_ptr< TH1D > &hist, std::unique_ptr< TH1D > &hpost_copy, const double coverage)
KS: Get 1D histogram within credible interval, hpost_copy has to have the same binning,...
void CheckBonferoniCorrectedpValue(const std::vector< std::string > &SampleNameVec, const std::vector< double > &PValVec, const double Threshold)
KS: For more see https://www.t2k.org/docs/technotes/429/TN429_v8#page=63.
std::string GetDunneKaboth(const double BayesFactor)
KS: Based on Table 1 in https://www.t2k.org/docs/technotes/435.
int GetNumberOfRuns(const std::vector< int > &GroupClasifier)
KS: https://esjeevanand.uccollege.edu.in/wp-content/uploads/sites/114/2020/08/NON-PARAMTERIC-TEST-6....
double GetBetaParameter(const double data, const double mc, const double w2, TestStatistic TestStat)
KS: Calculate Beta parameter which will be different based on specified test statistic.
Utility functions for statistical interpretations in MaCh3.
Custom exception class for MaCh3 errors.
TFile * Open(const std::string &Name, const std::string &Type, const std::string &File, const int Line)
Opens a ROOT file with the given name and mode.
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.