7 #include "Math/QuantFuncMathCore.h"
13 std::string JeffreysScale =
"";
15 if(BayesFactor < 0) JeffreysScale =
"Negative";
16 else if( 5 > BayesFactor) JeffreysScale =
"Barely worth mentioning";
17 else if( 10 > BayesFactor) JeffreysScale =
"Substantial";
18 else if( 15 > BayesFactor) JeffreysScale =
"Strong";
19 else if( 20 > BayesFactor) JeffreysScale =
"Very strong";
20 else JeffreysScale =
"Decisive";
28 std::string DunneKaboth =
"";
31 if(2.125 > BayesFactor) DunneKaboth =
"< 1 #sigma";
32 else if( 20.74 > BayesFactor) DunneKaboth =
"> 1 #sigma";
33 else if( 369.4 > BayesFactor) DunneKaboth =
"> 2 #sigma";
34 else if( 15800 > BayesFactor) DunneKaboth =
"> 3 #sigma";
35 else if( 1745000 > BayesFactor) DunneKaboth =
"> 4 #sigma";
36 else DunneKaboth =
"> 5 #sigma";
45 switch (std::abs(sigma))
48 width = 0.682689492137;
51 width = 0.954499736104;
54 width = 0.997300203937;
57 width = 0.999936657516;
60 width = 0.999999426697;
63 width = 0.999999998027;
74 double GetBIC(
const double llh,
const int data,
const int nPars){
78 MACH3LOG_ERROR(
"You haven't passed number of model parameters as it is still zero");
81 const double BIC = double(nPars * logl(data) + llh);
89 const double Nominator = (N1+N2);
90 const double Denominator = (N1*N2);
91 const double N_e = Nominator/Denominator;
97 const std::vector<double>& PValVec,
98 const double Threshold) {
101 if(SampleNameVec.size() != PValVec.size())
106 const size_t NumberOfStatisticalTests = SampleNameVec.size();
108 const double StatisticalSignificanceDown = Threshold / double(NumberOfStatisticalTests);
109 const double StatisticalSignificanceUp = 1 - StatisticalSignificanceDown;
110 MACH3LOG_INFO(
"Bonferroni-corrected statistical significance level: {:.2f}", StatisticalSignificanceDown);
113 for(
unsigned int i = 0; i < SampleNameVec.size(); i++)
115 if( (PValVec[i] < 0.5 && PValVec[i] < StatisticalSignificanceDown) ) {
116 MACH3LOG_INFO(
"Sample {} indicates disagreement between the model predictions and the data", SampleNameVec[i]);
117 MACH3LOG_INFO(
"Bonferroni-corrected statistical significance level: {:.2f} p-value: {:.2f}", StatisticalSignificanceDown, PValVec[i]);
119 }
else if( (PValVec[i] > 0.5 && PValVec[i] > StatisticalSignificanceUp) ) {
120 MACH3LOG_INFO(
"Sample {} indicates disagreement between the model predictions and the data", SampleNameVec[i]);
121 MACH3LOG_INFO(
"Bonferroni-corrected statistical significance level: {:.2f} p-value: {:.2f}", StatisticalSignificanceUp, PValVec[i]);
126 MACH3LOG_INFO(
"Every sample passed Bonferroni-corrected statistical significance level test");
128 MACH3LOG_WARN(
"{} samples didn't pass Bonferroni-corrected statistical significance level test", Counter);
136 double ADstat = std::fabs(CumulativeData - CumulativeMC)/ std::sqrt(CumulativeJoint*(1 - CumulativeJoint));
138 if( std::isinf(ADstat) || std::isnan(ADstat))
return 0;
145 int NumberOfRuns = 0;
146 int PreviousGroup = -999;
149 for (
unsigned int i = 0; i < GroupClasifier.size(); i++)
151 if(GroupClasifier[i] != PreviousGroup)
153 PreviousGroup = GroupClasifier[i];
166 const double k = mc*mc / w2;
168 Beta = (data + k) / (mc + k);
173 const double fractional = std::sqrt(w2)/mc;
175 const double temp = mc*fractional*fractional-1;
177 const double temp2 = temp*temp + 4*data*fractional*fractional;
179 MACH3LOG_ERROR(
"Negative square root in Barlow Beeston coefficient calculation!");
183 Beta = (-1*temp+std::sqrt(temp2))/2.;
190 double GetSubOptimality(
const std::vector<double>& EigenValues,
const int TotalTarameters) {
192 double sum_eigenvalues_squared_inv = 0.0;
193 double sum_eigenvalues_inv = 0.0;
194 for (
unsigned int j = 0; j < EigenValues.size(); j++)
198 sum_eigenvalues_squared_inv += std::pow(EigenValues[j], -2);
199 sum_eigenvalues_inv += 1.0 / EigenValues[j];
201 const double SubOptimality = TotalTarameters * sum_eigenvalues_squared_inv / std::pow(sum_eigenvalues_inv, 2);
202 return SubOptimality;
209 Mean = hist->GetMean();
210 Error = hist->GetRMS();
217 int originalErrorLevel = gErrorIgnoreLevel;
218 gErrorIgnoreLevel = kFatal;
220 const double meanval = hist->GetMean();
221 const double err = hist->GetRMS();
222 const double peakval = hist->GetBinCenter(hist->GetMaximumBin());
225 gauss->SetRange(meanval - 1.5*err , meanval + 1.5*err);
227 gauss->SetParameters(hist->GetMaximum()*err*std::sqrt(2*3.14), peakval, err);
230 hist->Fit(gauss->GetName(),
"Rq");
233 Mean = gauss->GetParameter(1);
234 Error = gauss->GetParameter(2);
237 gErrorIgnoreLevel = originalErrorLevel;
241 void GetHPD(TH1D*
const hist,
double&
Mean,
double& Error,
double& Error_p,
double& Error_m,
const double coverage) {
244 const int MaxBin = hist->GetMaximumBin();
246 const double peakval = hist->GetBinCenter(MaxBin);
249 const long double Integral = hist->Integral();
251 const long double LowIntegral = hist->Integral(1, MaxBin-1) + hist->GetBinContent(MaxBin)/2.0;
252 const long double HighIntegral = hist->Integral(MaxBin+1, hist->GetNbinsX()) + hist->GetBinContent(MaxBin)/2.0;
256 long double sum = hist->GetBinContent(MaxBin)/2.0;
259 int CurrBin = MaxBin;
260 while (sum/HighIntegral < coverage && CurrBin < hist->GetNbinsX()) {
262 sum += hist->GetBinContent(CurrBin);
264 const double sigma_p = std::fabs(hist->GetBinCenter(MaxBin)-hist->GetXaxis()->GetBinUpEdge(CurrBin));
267 sum = hist->GetBinContent(MaxBin)/2.0;
272 while (sum/LowIntegral < coverage && CurrBin > 1) {
274 sum += hist->GetBinContent(CurrBin);
276 const double sigma_m = std::fabs(hist->GetBinCenter(CurrBin)-hist->GetBinLowEdge(MaxBin));
280 sum = hist->GetBinContent(MaxBin);
282 int HighBin = MaxBin;
283 long double LowCon = 0.0;
284 long double HighCon = 0.0;
286 while (sum/Integral < coverage && (LowBin > 0 || HighBin < hist->GetNbinsX()+1))
294 LowCon = hist->GetBinContent(LowBin);
296 if(HighBin < hist->GetNbinsX())
299 HighCon = hist->GetBinContent(HighBin);
303 if ((sum+LowCon+HighCon)/Integral > coverage && LowCon > HighCon) {
307 }
else if ((sum+LowCon+HighCon)/Integral > coverage && HighCon >= LowCon) {
311 sum += LowCon + HighCon;
315 double sigma_hpd = 0.0;
316 if (LowCon > HighCon) {
317 sigma_hpd = std::fabs(hist->GetBinLowEdge(LowBin)-hist->GetBinCenter(MaxBin));
319 sigma_hpd = std::fabs(hist->GetXaxis()->GetBinUpEdge(HighBin)-hist->GetBinCenter(MaxBin));
329 void GetCredibleInterval(
const std::unique_ptr<TH1D>& hist, std::unique_ptr<TH1D>& hpost_copy,
const double coverage) {
333 MACH3LOG_ERROR(
"Specified Credible Interval is greater that 1 and equal to {} Should be between 0 and 1", coverage);
337 hpost_copy->Reset(
"");
338 hpost_copy->Fill(0.0, 0.0);
341 std::vector<double> hist_copy(hist->GetXaxis()->GetNbins()+1);
342 std::vector<bool> hist_copy_fill(hist->GetXaxis()->GetNbins()+1);
343 for (
int i = 0; i <= hist->GetXaxis()->GetNbins(); ++i)
345 hist_copy[i] = hist->GetBinContent(i);
346 hist_copy_fill[i] =
false;
350 const long double Integral = hist->Integral();
353 while ((sum / Integral) < coverage)
356 int max_entry_bin = 0;
357 double max_entries = 0.;
358 for (
int i = 0; i <= hist->GetXaxis()->GetNbins(); ++i)
360 if (hist_copy[i] > max_entries)
362 max_entries = hist_copy[i];
367 hist_copy[max_entry_bin] = -1.;
368 hist_copy_fill[max_entry_bin] =
true;
373 for(
int i = 0; i <= hist->GetXaxis()->GetNbins(); ++i)
375 if(hist_copy_fill[i]) hpost_copy->SetBinContent(i, hist->GetBinContent(i));
380 void GetCredibleIntervalSig(
const std::unique_ptr<TH1D>& hist, std::unique_ptr<TH1D>& hpost_copy,
const bool CredibleInSigmas,
const double coverage) {
383 if(CredibleInSigmas) {
385 const double CredReg =
GetSigmaValue(
int(std::round(coverage)));
397 MACH3LOG_ERROR(
"Specified Credible Region is greater than 1 and equal to {:.2f} Should be between 0 and 1", coverage);
402 std::vector<std::vector<double>> hist_copy(hist2D->GetXaxis()->GetNbins()+1,
403 std::vector<double>(hist2D->GetYaxis()->GetNbins()+1));
404 for (
int i = 0; i <= hist2D->GetXaxis()->GetNbins(); ++i) {
405 for (
int j = 0; j <= hist2D->GetYaxis()->GetNbins(); ++j) {
406 hist_copy[i][j] = hist2D->GetBinContent(i, j);
411 const long double Integral = hist2D->Integral();
416 while ((sum / Integral) < coverage)
419 int max_entry_bin_x = 0;
420 int max_entry_bin_y = 0;
421 double max_entries = 0.;
422 for (
int i = 0; i <= hist2D->GetXaxis()->GetNbins(); ++i)
424 for (
int j = 0; j <= hist2D->GetYaxis()->GetNbins(); ++j)
426 if (hist_copy[i][j] > max_entries)
428 max_entries = hist_copy[i][j];
435 hist_copy[max_entry_bin_x][max_entry_bin_y] = -1.;
438 Contour[0] = max_entries;
440 hist2D->SetContour(1, Contour);
446 if(CredibleInSigmas) {
448 const double CredReg =
GetSigmaValue(
int(std::round(coverage)));
458 if(Hist->Integral() == 0)
return 0.0;
460 constexpr
double quartiles_x[3] = {0.25, 0.5, 0.75};
463 Hist->GetQuantiles(3, quartiles, quartiles_x);
465 return quartiles[2] - quartiles[0];
470 const std::vector<double>& MC) {
472 double klDivergence = 0.0;
473 double DataIntegral = std::accumulate(Data.begin(), Data.end(), 0.0);
474 double MCIntegral = std::accumulate(MC.begin(), MC.end(), 0.0);
475 for (
size_t i = 0; i < Data.size(); ++i)
477 if (Data[i] > 0 && MC[i] > 0) {
478 klDivergence += Data[i] / DataIntegral *
479 std::log((Data[i] / DataIntegral) / ( MC[i] / MCIntegral));
488 int nBins = DataPoly->GetNumberOfBins();
489 std::vector<double> Data(nBins);
490 std::vector<double> MC(nBins);
492 for (
int i = 0; i < nBins; ++i) {
493 Data[i] = DataPoly->GetBinContent(i+1);
494 MC[i] = PolyMC->GetBinContent(i+1);
503 double testStatistic = 0;
504 for(
size_t i = 0; i < pvalues.size(); i++)
506 const double pval = std::max(0.00001, pvalues[i]);
507 testStatistic += -2.0 * std::log(pval);
510 int degreesOfFreedom = int(2 * pvalues.size());
511 double pValue = TMath::Prob(testStatistic, degreesOfFreedom);
517 void ThinningMCMC(
const std::string& FilePath,
const int ThinningCut) {
519 std::string FilePathNowRoot = FilePath;
520 if (FilePath.size() >= 5 && FilePath.substr(FilePath.size() - 5) ==
".root") {
521 FilePathNowRoot = FilePath.substr(0, FilePath.size() - 5);
523 std::string TempFilePath = FilePathNowRoot +
"_thinned.root";
524 int ret = system((
"cp " + FilePath +
" " + TempFilePath).c_str());
526 MACH3LOG_WARN(
"System call to copy file failed with code {}", ret);
529 TFile *inFile =
M3::Open(TempFilePath,
"RECREATE", __FILE__, __LINE__);
530 TTree *inTree = inFile->Get<TTree>(
"posteriors");
539 TTree *outTree = inTree->CloneTree(0);
542 Long64_t nEntries = inTree->GetEntries();
543 double retainedPercentage = (double(nEntries) / ThinningCut) /
double(nEntries) * 100;
544 MACH3LOG_INFO(
"Thinning will retain {:.2f}% of chains", retainedPercentage);
545 for (Long64_t i = 0; i < nEntries; i++) {
546 if (i % (nEntries/10) == 0) {
549 if (i % ThinningCut == 0) {
554 inFile->WriteTObject(outTree,
"posteriors",
"kOverwrite");
558 MACH3LOG_INFO(
"Thinned TTree saved and overwrote original in: {}", TempFilePath);
562 double GetZScore(
const double value,
const double mean,
const double stddev) {
564 return (value - mean) / stddev;
570 return 0.5 * std::erfc(-zScore / std::sqrt(2));
578 int MaxBin = hpost->GetMaximumBin();
581 const double Integral = hpost->Integral();
584 int HighBin = MaxBin;
585 double sum = hpost->GetBinContent(MaxBin);;
587 double HighCon = 0.0;
588 while (sum/Integral < 0.6827 && (LowBin > 0 || HighBin < hpost->GetNbinsX()+1) )
596 LowCon = hpost->GetBinContent(LowBin);
598 if(HighBin < hpost->GetNbinsX())
601 HighCon = hpost->GetBinContent(HighBin);
605 if ((sum+LowCon+HighCon)/Integral > 0.6827 && LowCon > HighCon) {
609 }
else if ((sum+LowCon+HighCon)/Integral > 0.6827 && HighCon >= LowCon) {
613 sum += LowCon + HighCon;
617 double Mode_Error = 0.0;
618 if (LowCon > HighCon) {
619 Mode_Error = std::fabs(hpost->GetBinCenter(LowBin)-hpost->GetBinCenter(MaxBin));
621 Mode_Error = std::fabs(hpost->GetBinCenter(HighBin)-hpost->GetBinCenter(MaxBin));
631 const double TotalIntegral = Histogram->Integral();
635 for (
int i = 0; i < Histogram->GetXaxis()->GetNbins(); ++i) {
636 const double xvalue = Histogram->GetXaxis()->GetBinCenter(i+1);
637 for (
int j = 0; j < Histogram->GetYaxis()->GetNbins(); ++j) {
638 const double yvalue = Histogram->GetYaxis()->GetBinCenter(j+1);
640 if (xvalue >= yvalue) {
641 Above += Histogram->GetBinContent(i+1, j+1);
645 const double pvalue = Above/TotalIntegral;
646 std::stringstream ss;
647 ss << int(Above) <<
"/" << int(TotalIntegral) <<
"=" << pvalue;
648 Histogram->SetTitle((std::string(Histogram->GetTitle())+
"_"+ss.str()).c_str());
651 double minimum = Histogram->GetXaxis()->GetBinLowEdge(1);
652 if (Histogram->GetYaxis()->GetBinLowEdge(1) > minimum) {
653 minimum = Histogram->GetYaxis()->GetBinLowEdge(1);
655 double maximum = Histogram->GetXaxis()->GetBinLowEdge(Histogram->GetXaxis()->GetNbins());
656 if (Histogram->GetYaxis()->GetBinLowEdge(Histogram->GetYaxis()->GetNbins()) < maximum) {
657 maximum = Histogram->GetYaxis()->GetBinLowEdge(Histogram->GetYaxis()->GetNbins());
659 maximum += Histogram->GetYaxis()->GetBinWidth(Histogram->GetYaxis()->GetNbins());
661 else maximum += Histogram->GetXaxis()->GetBinWidth(Histogram->GetXaxis()->GetNbins());
662 auto TempLine = std::make_unique<TLine>(minimum, minimum, maximum, maximum);
663 TempLine->SetLineColor(kRed);
664 TempLine->SetLineWidth(2);
666 std::string Title = Histogram->GetName();
668 auto TempCanvas = std::make_unique<TCanvas>(Title.c_str(), Title.c_str(), 1024, 1024);
669 TempCanvas->SetGridx();
670 TempCanvas->SetGridy();
672 gStyle->SetPalette(81);
673 Histogram->SetMinimum(-0.01);
674 Histogram->Draw(
"colz");
675 TempLine->Draw(
"same");
684 auto delta_chi2 =
M3::Clone(posterior_probability_hist);
685 delta_chi2->GetYaxis()->SetTitle(
"#Delta#chi^{2}");
687 int max_bin = delta_chi2->GetMaximumBin();
688 double max_content = delta_chi2->GetBinContent(max_bin);
689 if (max_content == 0) {
690 MACH3LOG_ERROR(
"Histogram {}, has larges bin with 0", delta_chi2->GetTitle());
691 MACH3LOG_ERROR(
"This suggest you skewed binning for posterior probability or something else");
696 for(
int iBin = 1; iBin < delta_chi2->GetNbinsX()+1; iBin++) {
697 double bin_content = delta_chi2->GetBinContent(iBin);
698 if(bin_content == 0) bin_content = 1.0 ;
700 double chi2_likelihood = -2*std::log(bin_content/max_content);
701 delta_chi2->SetBinContent(iBin, chi2_likelihood);
702 NewMaximum = std::max(NewMaximum, chi2_likelihood);
704 delta_chi2->SetMaximum(NewMaximum*1.1);
711 for (
int j = 0; j <= RatioHist->GetNbinsX(); ++j)
713 if(DataHist->GetBinContent(j) > 0)
715 double dx = Hist1->GetBinError(j) / DataHist->GetBinContent(j);
716 RatioHist->SetBinError(j, dx);
723 std::unique_ptr<TGraphAsymmErrors>
PoissonGraph(
const TH1D* hist,
double cl) {
725 auto graph = std::make_unique<TGraphAsymmErrors>();
727 const double alpha = 1.0 - cl;
728 const double half = alpha / 2.0;
730 for (
int i = 1; i <= hist->GetNbinsX(); i++)
732 double N = hist->GetBinContent(i);
733 double x = hist->GetBinCenter(i);
734 double ex = hist->GetBinWidth(i) / 2.0;
740 low = N - ROOT::Math::gamma_quantile(half, N, 1.0);
741 high = ROOT::Math::gamma_quantile_c(half, N + 1, 1.0) - N;
744 high = ROOT::Math::gamma_quantile_c(half, 1, 1.0);
747 int p = graph->GetN();
748 graph->SetPoint(p, x, N);
749 graph->SetPointError(p, ex, ex, low, high);
758 auto graph = std::make_unique<TGraphAsymmErrors>();
760 const double alpha = 1.0 - cl;
761 const double half = alpha / 2.0;
763 for (
int i = 1; i <= hist->GetNbinsX(); i++) {
764 double N = hist->GetBinContent(i);
765 double x = hist->GetBinCenter(i);
766 double ex = hist->GetBinWidth(i) / 2.0;
767 double binWidth = hist->GetBinWidth(i);
773 low = N - ROOT::Math::gamma_quantile(half, N, 1.0);
774 high = ROOT::Math::gamma_quantile_c(half, N + 1, 1.0) - N;
777 high = ROOT::Math::gamma_quantile_c(half, 1, 1.0);
781 double scaleFactor = scale / binWidth;
782 double y = N * scaleFactor;
783 double low_scaled = low * scaleFactor;
784 double high_scaled = high * scaleFactor;
786 int p = graph->GetN();
787 graph->SetPoint(p, x, y);
788 graph->SetPointError(p, ex, ex, low_scaled, high_scaled);
#define _MaCh3_Safe_Include_Start_
KS: Avoiding warning checking for headers.
#define _MaCh3_Safe_Include_End_
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.
std::unique_ptr< TGraphAsymmErrors > PoissonGraph(const TH1D *hist, double cl)
Create a TGraphAsymmErrors from a histogram using exact Poisson confidence intervals instead of symme...
double GetBetaParameter(const double data, const double mc, const double w2, const TestStatistic TestStat)
KS: Calculate Beta parameter which will be different based on specified test statistic.
double ComputeKLDivergence(const std::vector< double > &Data, const std::vector< double > &MC)
Compute the Kullback-Leibler divergence between two TH2Poly histograms.
std::unique_ptr< TGraphAsymmErrors > PoissonGraphScaled(const TH1D *hist, double scale, double cl)
Create a TGraphAsymmErrors from a histogram using exact Poisson confidence intervals instead of symme...
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.
void PassErrorToRatioPlot(TH1D *RatioHist, TH1D *Hist1, TH1D *DataHist)
Propagate numerator uncertainties to a ratio histogram.
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.
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)
Convert a Bayes factor into an approximate particle-physics significance level using the Dunne–Kaboth...
int GetNumberOfRuns(const std::vector< int > &GroupClasifier)
KS: https://esjeevanand.uccollege.edu.in/wp-content/uploads/sites/114/2020/08/NON-PARAMTERIC-TEST-6....
_MaCh3_Safe_Include_Start_ _MaCh3_Safe_Include_End_ std::string GetJeffreysScale(const double BayesFactor)
KS: Following H. Jeffreys .
std::unique_ptr< TH1D > GetDeltaChi2(TH1D *posterior_probability_hist)
Convert a posterior probability histogram into a distribution. Using the likelihood-ratio definition...
Utility functions for statistical interpretations in MaCh3.
Custom exception class used throughout MaCh3.
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.
std::unique_ptr< ObjectType > Clone(const ObjectType *obj, const std::string &name="")
KS: Creates a copy of a ROOT-like object and wraps it in a smart pointer.
constexpr static const double _BAD_DOUBLE_
Default value used for double initialisation.
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.