6 #include "TVirtualFFT.h"
15 #pragma GCC diagnostic ignored "-Wfloat-conversion"
19 Chain(nullptr), StepCut(
""), MadePostfit(false) {
93 GPUProcessor = std::make_unique<MCMCProcessorGPU>();
119 for (
int i = 0; i <
nDraw; ++i)
125 for (
int i = 0; i <
nDraw; ++i)
127 for (
int j = 0; j <
nDraw; ++j)
153 void MCMCProcessor::GetPostfit(TVectorD *&Central_PDF, TVectorD *&Errors_PDF, TVectorD *&Central_G, TVectorD *&Errors_G, TVectorD *&Peak_Values) {
174 const int ParamTypeSize = int(
ParamType.size());
176 for (
int i = 0; i < ParamTypeSize; ++i) {
178 (*PDF_Central)(ParamNumber) = (*
Means)(i);
179 (*PDF_Errors)(ParamNumber) = (*
Errors)(i);
180 (*Peak_Values)(ParamNumber) = (*
Means_HPD)(i);
190 Cov =
static_cast<TMatrixDSym*
>(
Covariance->Clone());
191 Corr =
static_cast<TMatrixDSym*
>(
Correlation->Clone());
198 auto rand = std::make_unique<TRandom3>(0);
199 const int uniform = int(rand->Uniform(0, 10000));
201 Posterior = std::make_unique<TCanvas>((
"Posterior" + std::to_string(uniform)).c_str(), (
"Posterior" + std::to_string(uniform)).c_str(), 0, 0, 1024, 1024);
203 TCandle::SetScaledViolin(
false);
206 gStyle->SetOptStat(0);
207 gStyle->SetOptTitle(0);
217 gErrorIgnoreLevel = kWarning;
231 double Prior = 1.0, PriorError = 1.0;
237 (*Central_Value)(i) = Prior;
239 double Mean, Err, Err_p, Err_m;
245 (*Means_Gauss)(i) =
Mean;
246 (*Errors_Gauss)(i) = Err;
249 (*Means_HPD)(i) =
Mean;
250 (*Errors_HPD)(i) = Err;
251 (*Errors_HPD_Positive)(i) = Err_p;
252 (*Errors_HPD_Negative)(i) = Err_m;
256 (*Correlation)(i,i) = 1.0;
262 hpost[i]->SetLineWidth(2);
263 hpost[i]->SetLineColor(kBlue-1);
265 hpost[i]->SetTitle(Title);
266 hpost[i]->GetXaxis()->SetTitle(
hpost[i]->GetTitle());
269 auto Asimov = std::make_unique<TLine>(Prior,
hpost[i]->GetMinimum(), Prior,
hpost[i]->GetMaximum());
272 auto leg = std::make_unique<TLegend>(0.15, 0.6, 0.6, 0.95);
274 leg->AddEntry(
hpost[i], Form(
"#splitline{PDF}{#mu = %.2f, #sigma = %.2f}",
hpost[i]->GetMean(),
hpost[i]->GetRMS()),
"l");
275 leg->AddEntry(
Gauss.get(), Form(
"#splitline{Gauss}{#mu = %.2f, #sigma = %.2f}",
Gauss->GetParameter(1),
Gauss->GetParameter(2)),
"l");
277 if(
isFlat && !
PlotFlatPrior) leg->AddEntry(Asimov.get(), Form(
"#splitline{Prior}{x = %.2f}", Prior),
"l");
278 else leg->AddEntry(Asimov.get(), Form(
"#splitline{Prior}{x = %.2f , #sigma = %.2f}", Prior, PriorError),
"l");
287 MACH3LOG_WARN(
"Found fixed parameter: {} ({}), moving on", Title, i);
290 (*Means_HPD)(i) = Prior;
291 (*Errors_HPD)(i) = PriorError;
292 (*Errors_HPD_Positive)(i) = PriorError;
293 (*Errors_HPD_Negative)(i) = PriorError;
295 (*Means_Gauss)(i) = Prior;
296 (*Errors_Gauss)(i) = PriorError;
299 (*Errors)(i) = PriorError;
309 Asimov->Draw(
"same");
318 hpost[i]->SetName(Title);
319 hpost[i]->SetTitle(Title);
328 hpost[iParam]->GetXaxis()->GetXmin(),
329 hpost[iParam]->GetXaxis()->GetXmax()
348 int originalErrorLevel = gErrorIgnoreLevel;
349 gErrorIgnoreLevel = kFatal;
352 TDirectory *PostDir =
OutputFile->mkdir(
"Post");
353 TDirectory *PostHistDir =
OutputFile->mkdir(
"Post_1d_hists");
356 std::string CutPosterior1D =
"";
359 }
else CutPosterior1D =
StepCut;
364 CutPosterior1D =
"(" + CutPosterior1D +
")*(" + name +
")";
370 for (
int i = 0; i <
nDraw; ++i)
372 if (i % (
nDraw/5) == 0) {
377 double Prior = 1.0, PriorError = 1.0;
382 if (Edges.find(Title.Data()) != Edges.end()) {
383 mini = Edges.at(Title.Data()).first;
384 maxi = Edges.at(Title.Data()).second;
389 MACH3LOG_DEBUG(
"Initialising histogram for {} with binning {:.4f}, {:.4f}", Title, mini, maxi);
394 hpost[i]->SetMinimum(0);
395 hpost[i]->GetYaxis()->SetTitle(
"Steps");
396 hpost[i]->GetYaxis()->SetNoExponent(
false);
405 TTree *SettingsBranch =
new TTree(
"Settings",
"Settings");
414 SettingsBranch->Fill();
415 SettingsBranch->Write();
416 delete SettingsBranch;
418 TDirectory *Names =
OutputFile->mkdir(
"Names");
421 TObjString((*it)).Write();
428 Means->Write(
"PDF_Means");
429 Errors->Write(
"PDF_Error");
439 PostHistDir->Close();
443 MACH3LOG_INFO(
"{} took {:.2f}s to", __func__, clock.RealTime());
446 gErrorIgnoreLevel = originalErrorLevel;
458 prefit->GetXaxis()->SetTitle(
"");
462 std::string CutPosterior1D =
"";
470 std::unique_ptr<TH1D> paramPlot = std::make_unique<TH1D>(
"paramPlot",
"paramPlot",
nDraw, 0,
nDraw);
471 paramPlot->SetDirectory(
nullptr);
472 paramPlot->SetName(
"mach3params");
473 paramPlot->SetTitle(CutPosterior1D.c_str());
474 paramPlot->SetFillStyle(3001);
475 paramPlot->SetFillColor(kBlue-1);
476 paramPlot->SetMarkerColor(paramPlot->GetFillColor());
477 paramPlot->SetMarkerStyle(20);
478 paramPlot->SetLineColor(paramPlot->GetFillColor());
479 paramPlot->SetMarkerSize(prefit->GetMarkerSize());
480 paramPlot->GetXaxis()->SetTitle(
"");
483 std::unique_ptr<TH1D> paramPlot_Gauss =
M3::Clone(paramPlot.get());
484 paramPlot_Gauss->SetMarkerColor(kOrange-5);
485 paramPlot_Gauss->SetMarkerStyle(23);
486 paramPlot_Gauss->SetLineWidth(2);
487 paramPlot_Gauss->SetMarkerSize((prefit->GetMarkerSize())*0.75);
488 paramPlot_Gauss->SetFillColor(paramPlot_Gauss->GetMarkerColor());
489 paramPlot_Gauss->SetFillStyle(3244);
490 paramPlot_Gauss->SetLineColor(paramPlot_Gauss->GetMarkerColor());
491 paramPlot_Gauss->GetXaxis()->SetTitle(
"");
494 std::unique_ptr<TH1D> paramPlot_HPD =
M3::Clone(paramPlot.get());
495 paramPlot_HPD->SetMarkerColor(kBlack);
496 paramPlot_HPD->SetMarkerStyle(25);
497 paramPlot_HPD->SetLineWidth(2);
498 paramPlot_HPD->SetMarkerSize((prefit->GetMarkerSize())*0.5);
499 paramPlot_HPD->SetFillColor(0);
500 paramPlot_HPD->SetFillStyle(0);
501 paramPlot_HPD->SetLineColor(paramPlot_HPD->GetMarkerColor());
502 paramPlot_HPD->GetXaxis()->SetTitle(
"");
505 for (
int i = 0; i <
nDraw; ++i)
513 double CentralValueTemp = 0;
514 double Central, Central_gauss, Central_HPD;
515 double Err, Err_Gauss, Err_HPD;
521 if ( CentralValueTemp != 0)
523 Central = (*Means)(i) / CentralValueTemp;
524 Err = (*Errors)(i) / CentralValueTemp;
526 Central_gauss = (*Means_Gauss)(i) / CentralValueTemp;
527 Err_Gauss = (*Errors_Gauss)(i) / CentralValueTemp;
529 Central_HPD = (*Means_HPD)(i) / CentralValueTemp;
530 Err_HPD = (*Errors_HPD)(i) / CentralValueTemp;
533 Central = 1+(*Means)(i);
536 Central_gauss = 1+(*Means_Gauss)(i);
537 Err_Gauss = (*Errors_Gauss)(i);
539 Central_HPD = 1+(*Means_HPD)(i) ;
540 Err_HPD = (*Errors_HPD)(i);
546 Central = (*Means)(i);
549 Central_gauss = (*Means_Gauss)(i);
550 Err_Gauss = (*Errors_Gauss)(i);
552 Central_HPD = (*Means_HPD)(i) ;
553 Err_HPD = (*Errors_HPD)(i);
556 paramPlot->SetBinContent(i+1, Central);
557 paramPlot->SetBinError(i+1, Err);
559 paramPlot_Gauss->SetBinContent(i+1, Central_gauss);
560 paramPlot_Gauss->SetBinError(i+1, Err_Gauss);
562 paramPlot_HPD->SetBinContent(i+1, Central_HPD);
563 paramPlot_HPD->SetBinError(i+1, Err_HPD);
565 paramPlot->GetXaxis()->SetBinLabel(i+1, prefit->GetXaxis()->GetBinLabel(i+1));
566 paramPlot_Gauss->GetXaxis()->SetBinLabel(i+1, prefit->GetXaxis()->GetBinLabel(i+1));
567 paramPlot_HPD->GetXaxis()->SetBinLabel(i+1, prefit->GetXaxis()->GetBinLabel(i+1));
569 prefit->GetXaxis()->LabelsOption(
"v");
570 paramPlot->GetXaxis()->LabelsOption(
"v");\
571 paramPlot_Gauss->GetXaxis()->LabelsOption(
"v");
572 paramPlot_HPD->GetXaxis()->LabelsOption(
"v");
575 auto CompLeg = std::make_unique<TLegend>(0.33, 0.73, 0.76, 0.95);
576 CompLeg->AddEntry(prefit.get(),
"Prefit",
"fp");
577 CompLeg->AddEntry(paramPlot.get(),
"Postfit PDF",
"fp");
578 CompLeg->AddEntry(paramPlot_Gauss.get(),
"Postfit Gauss",
"fp");
579 CompLeg->AddEntry(paramPlot_HPD.get(),
"Postfit HPD",
"lfep");
580 CompLeg->SetFillColor(0);
581 CompLeg->SetFillStyle(0);
582 CompLeg->SetLineWidth(0);
583 CompLeg->SetLineStyle(0);
584 CompLeg->SetBorderSize(0);
592 prefit->Write(
"param_xsec_prefit");
593 paramPlot->Write(
"param_xsec");
594 paramPlot_Gauss->Write(
"param_xsec_gaus");
595 paramPlot_HPD->Write(
"param_xsec_HPD");
600 else prefit->GetYaxis()->SetTitle(
"Parameter Value");
601 prefit->GetYaxis()->SetRangeUser(-2.5, 2.5);
605 paramPlot->Draw(
"e2, same");
606 paramPlot_Gauss->Draw(
"e2, same");
607 paramPlot_HPD->Draw(
"e1, same");
608 CompLeg->Draw(
"same");
612 constexpr
int IntervalsSize = 20;
613 const int NIntervals =
nDraw/IntervalsSize;
615 for (
int i = 0; i < NIntervals+1; ++i)
617 int RangeMin = i*IntervalsSize;
618 int RangeMax =RangeMin + IntervalsSize;
619 if(i == NIntervals+1) {
620 RangeMin = i*IntervalsSize;
623 if(RangeMin >=
nDraw)
break;
625 double ymin = std::numeric_limits<double>::max();
626 double ymax = -std::numeric_limits<double>::max();
627 for (
int b = RangeMin; b <= RangeMax; ++b) {
630 double val = prefit->GetBinContent(b);
631 double err = prefit->GetBinError(b);
632 ymin = std::min(ymin, val - err);
633 ymax = std::max(ymax, val + err);
637 double val = paramPlot_HPD->GetBinContent(b);
638 double err = paramPlot_HPD->GetBinError(b);
639 ymin = std::min(ymin, val - err);
640 ymax = std::max(ymax, val + err);
644 double margin = 0.1 * (ymax - ymin);
645 prefit->GetYaxis()->SetRangeUser(ymin - margin, ymax + margin);
647 prefit->GetXaxis()->SetRangeUser(RangeMin, RangeMax);
648 paramPlot->GetXaxis()->SetRangeUser(RangeMin, RangeMax);
649 paramPlot_Gauss->GetXaxis()->SetRangeUser(RangeMin, RangeMax);
650 paramPlot_HPD->GetXaxis()->SetRangeUser(RangeMin, RangeMax);
654 paramPlot->Draw(
"e2, same");
655 paramPlot_Gauss->Draw(
"e2, same");
656 paramPlot_HPD->Draw(
"e1, same");
657 CompLeg->Draw(
"same");
665 int NDbinCounter = Start;
672 prefit->GetYaxis()->SetTitle((
"Variation for "+NDname).c_str());
673 prefit->GetYaxis()->SetRangeUser(0.6, 1.4);
674 prefit->GetXaxis()->SetRangeUser(Start, NDbinCounter);
676 paramPlot->GetYaxis()->SetTitle((
"Variation for "+NDname).c_str());
677 paramPlot->GetYaxis()->SetRangeUser(0.6, 1.4);
678 paramPlot->GetXaxis()->SetRangeUser(Start, NDbinCounter);
679 paramPlot->SetTitle(CutPosterior1D.c_str());
681 paramPlot_Gauss->GetYaxis()->SetTitle((
"Variation for "+NDname).c_str());
682 paramPlot_Gauss->GetYaxis()->SetRangeUser(0.6, 1.4);
683 paramPlot_Gauss->GetXaxis()->SetRangeUser(Start, NDbinCounter);
684 paramPlot_Gauss->SetTitle(CutPosterior1D.c_str());
686 paramPlot_HPD->GetYaxis()->SetTitle((
"Variation for "+NDname).c_str());
687 paramPlot_HPD->GetYaxis()->SetRangeUser(0.6, 1.4);
688 paramPlot_HPD->GetXaxis()->SetRangeUser(Start, NDbinCounter);
689 paramPlot_HPD->SetTitle(CutPosterior1D.c_str());
691 prefit->Write((
"param_"+NDname+
"_prefit").c_str());
692 paramPlot->Write((
"param_"+NDname).c_str());
693 paramPlot_Gauss->Write((
"param_"+NDname+
"_gaus").c_str());
694 paramPlot_HPD->Write((
"param_"+NDname+
"_HPD").c_str());
697 paramPlot->Draw(
"e2, same");
698 paramPlot_Gauss->Draw(
"e1, same");
699 paramPlot_HPD->Draw(
"e1, same");
700 CompLeg->Draw(
"same");
701 Posterior->Write((
"param_"+NDname+
"_canv").c_str());
714 const std::vector<Color_t>& CredibleIntervalsColours,
715 const bool CredibleInSigmas) {
720 const double LeftMargin =
Posterior->GetLeftMargin();
725 const int nCredible = int(CredibleIntervals.size());
726 std::vector<std::unique_ptr<TH1D>> hpost_copy(
nDraw);
727 std::vector<std::vector<std::unique_ptr<TH1D>>> hpost_cl(
nDraw);
730 for (
int i = 0; i <
nDraw; ++i)
732 hpost_copy[i] = M3::Clone<TH1D>(
hpost[i], Form(
"hpost_copy_%i", i));
733 hpost_cl[i].resize(nCredible);
734 for (
int j = 0; j < nCredible; ++j)
736 hpost_cl[i][j] = M3::Clone<TH1D>(
hpost[i], Form(
"hpost_copy_%i_CL_%f", i, CredibleIntervals[j]));
739 hpost_cl[i][j]->Reset(
"");
740 hpost_cl[i][j]->Fill(0.0, 0.0);
745 #pragma omp parallel for
747 for (
int i = 0; i <
nDraw; ++i)
750 hpost_copy[i]->Scale(1. / hpost_copy[i]->Integral());
751 for (
int j = 0; j < nCredible; ++j)
754 hpost_cl[i][j]->Scale(1. / hpost_cl[i][j]->Integral());
757 hpost_cl[i][j]->SetFillColor(CredibleIntervalsColours[j]);
758 hpost_cl[i][j]->SetLineWidth(1);
760 hpost_copy[i]->GetYaxis()->SetTitleOffset(1.8);
761 hpost_copy[i]->SetLineWidth(1);
762 hpost_copy[i]->SetMaximum(hpost_copy[i]->GetMaximum()*1.2);
763 hpost_copy[i]->SetLineWidth(2);
764 hpost_copy[i]->SetLineColor(kBlack);
765 hpost_copy[i]->GetYaxis()->SetTitle(
"Posterior Probability");
769 TDirectory *CredibleDir =
OutputFile->mkdir(
"Credible");
771 for (
int i = 0; i <
nDraw; ++i)
777 double Prior = 1.0, PriorError = 1.0;
780 auto Asimov = std::make_unique<TLine>(Prior, hpost_copy[i]->GetMinimum(), Prior, hpost_copy[i]->GetMaximum());
783 auto legend = std::make_unique<TLegend>(0.20, 0.7, 0.4, 0.92);
785 hpost_copy[i]->Draw(
"HIST");
787 for (
int j = 0; j < nCredible; ++j)
788 hpost_cl[i][j]->Draw(
"HIST SAME");
789 for (
int j = nCredible-1; j >= 0; --j)
792 legend->AddEntry(hpost_cl[i][j].get(), Form(
"%.0f#sigma Credible Interval", CredibleIntervals[j]),
"f");
794 legend->AddEntry(hpost_cl[i][j].get(), Form(
"%.0f%% Credible Interval", CredibleIntervals[j]*100),
"f");
796 legend->AddEntry(Asimov.get(), Form(
"#splitline{Prior}{x = %.2f , #sigma = %.2f}", Prior, PriorError),
"l");
797 legend->Draw(
"SAME");
798 Asimov->Draw(
"SAME");
809 CredibleDir->Close();
827 double maxi_y = -9999;
828 double mini_y = +9999;
829 for (
int i = 0; i <
nDraw; ++i)
832 mini_y = std::min(mini_y, range.first);
833 maxi_y = std::max(maxi_y, range.second);
836 const int vBins = (maxi_y-mini_y)*25;
837 hviolin = std::make_unique<TH2D>(
"hviolin",
"hviolin",
nDraw, 0,
nDraw, vBins, mini_y, maxi_y);
838 hviolin->SetDirectory(
nullptr);
840 constexpr
int PriorFactor = 4;
841 hviolin_prior = std::make_unique<TH2D>(
"hviolin_prior",
"hviolin_prior",
nDraw, 0,
nDraw, PriorFactor*vBins, PriorFactor*mini_y, PriorFactor*maxi_y);
844 auto rand = std::make_unique<TRandom3>(0);
845 std::vector<double> PriorVec(
nDraw);
846 std::vector<double> PriorErrorVec(
nDraw);
847 std::vector<bool> PriorFlatVec(
nDraw);
849 for (
int x = 0; x <
nDraw; ++x)
852 double Prior, PriorError;
856 hviolin->GetXaxis()->SetBinLabel(x+1, Title);
859 PriorErrorVec[x] = PriorError;
869 #pragma omp parallel for
871 for (
int x = 0; x <
nDraw; ++x)
890 const double Entry = rand->Gaus(PriorVec[x], PriorErrorVec[x]);
900 constexpr
int IntervalsSize = 10;
901 const int NIntervals =
nDraw/IntervalsSize;
903 hviolin->GetYaxis()->SetTitle(
"Parameter Value");
904 hviolin->GetXaxis()->SetTitle();
905 hviolin->GetXaxis()->LabelsOption(
"v");
922 hviolin->SetMarkerColor(kBlue);
923 hviolin->SetFillColorAlpha(kBlue, 0.35);
927 const double BottomMargin =
Posterior->GetBottomMargin();
931 hviolin->Write(
"param_violin");
934 hviolin->GetYaxis()->SetRangeUser(-1, +2);
936 for (
int i = 0; i < NIntervals+1; ++i)
938 int RangeMin = i*IntervalsSize;
939 int RangeMax = RangeMin + IntervalsSize;
940 if(i == NIntervals+1) {
941 RangeMin = i*IntervalsSize;
944 if(RangeMin >=
nDraw)
break;
946 hviolin->GetXaxis()->SetRangeUser(RangeMin, RangeMax);
951 hviolin->Draw(
"violinX(03100300) SAME");
955 Posterior->SetBottomMargin(BottomMargin);
964 bool HaveMadeDiagonal =
false;
968 for (
int i = 0; i <
nDraw; ++i) {
970 HaveMadeDiagonal =
false;
971 MACH3LOG_INFO(
"Have not run diagonal elements in covariance, will do so now by calling MakePostfit()");
974 HaveMadeDiagonal =
true;
978 if (HaveMadeDiagonal ==
false) {
982 TDirectory *PostHistDir =
OutputFile->mkdir(
"Post_2d_hists");
984 gStyle->SetPalette(55);
986 for (
int i = 0; i <
nDraw; ++i)
988 if (i % (
nDraw/5) == 0)
991 TString Title_i =
"";
992 double Prior_i, PriorError;
997 for (
int j = 0; j <= i; ++j) {
999 if (j == i)
continue;
1003 (*Covariance)(i,j) = 0.0;
1005 (*Correlation)(i,j) = 0.0;
1010 TString Title_j =
"";
1011 double Prior_j, PriorError_j;
1020 auto hpost_2D =
new TH2D(DrawMe, DrawMe,
1021 nBins,
hpost[i]->GetXaxis()->GetXmin(),
hpost[i]->GetXaxis()->GetXmax(),
1022 nBins,
hpost[j]->GetXaxis()->GetXmin(),
hpost[j]->GetXaxis()->GetXmax());
1023 hpost_2D->SetMinimum(0);
1024 hpost_2D->GetXaxis()->SetTitle(Title_i);
1025 hpost_2D->GetYaxis()->SetTitle(Title_j);
1026 hpost_2D->GetZaxis()->SetTitle(
"Steps");
1028 std::string SelectionStr =
StepCut;
1031 SelectionStr =
"(" +
StepCut +
")*(" + name +
")";
1035 Chain->Project(DrawMe, DrawMe, SelectionStr.c_str());
1039 (*Covariance)(i,j) = hpost_2D->GetCovariance();
1042 (*Correlation)(i,j) = hpost_2D->GetCorrelationFactor();
1053 hpost_2D->Draw(
"colz");
1054 Posterior->SetName(hpost_2D->GetName());
1055 Posterior->SetTitle(hpost_2D->GetTitle());
1067 PostHistDir->Close();
1085 MACH3LOG_ERROR(
"Even though it is used for MakeCovariance_MP and for DiagMCMC ");
1086 MACH3LOG_ERROR(
"it has different structure in both for cache hits, sorry ");
1099 for (
int i = 0; i <
nDraw; ++i)
1112 Chain->SetBranchStatus(
"*",
false);
1113 unsigned int stepBranch = 0;
1114 std::vector<double> ParValBranch(
nDraw);
1116 for (
int i = 0; i <
nDraw; ++i)
1121 Chain->SetBranchStatus(
"step",
true);
1122 Chain->SetBranchAddress(
"step", &stepBranch);
1124 std::vector<double> ReweightWeight(
ReweightNames.size(), 1.0);
1134 const Long64_t countwidth =
nEntries/10;
1138 for (Long64_t j = 0; j <
nEntries; ++j)
1140 if (j % countwidth == 0) {
1148 for (
int i = 0; i <
nDraw; ++i) {
1149 ParStep[i][j] = ParValBranch[i];
1153 for (
size_t i = 0; i < ReweightWeight.size(); ++i) {
1159 Chain->SetBranchStatus(
"*",
true);
1162 size_t nHistograms =
nDraw * (
nDraw + 1) / 2;
1164 MACH3LOG_INFO(
"Allocating {:.2f} MB for {} 2D Posteriors (each {}x{} bins)",
1167 for (
int i = 0; i <
nDraw; ++i)
1169 TString Title_i =
"";
1170 double Prior_i, PriorError_i;
1173 for (
int j = 0; j <= i; ++j)
1175 TString Title_j =
"";
1176 double Prior_j, PriorError_j;
1182 hpost2D[i][j] =
new TH2D((Title_i +
"_" + Title_j).Data(), (Title_i +
"_" + Title_j).Data(),
1183 nBins, range_x.first, range_x.second,
1184 nBins, range_y.first, range_y.second);
1186 hpost2D[i][j]->GetXaxis()->SetTitle(Title_i);
1187 hpost2D[i][j]->GetYaxis()->SetTitle(Title_j);
1188 hpost2D[i][j]->GetZaxis()->SetTitle(
"Steps");
1203 bool HaveMadeDiagonal =
false;
1206 for (
int i = 0; i <
nDraw; ++i) {
1208 HaveMadeDiagonal =
false;
1209 MACH3LOG_WARN(
"Have not run diagonal elements in covariance, will do so now by calling MakePostfit()");
1212 HaveMadeDiagonal =
true;
1218 TDirectory *PostHistDir =
nullptr;
1223 PostHistDir =
OutputFile->mkdir(
"Post_2d_hists");
1229 gStyle->SetPalette(55);
1232 #pragma omp parallel for
1234 for (
int i = 0; i <
nDraw; ++i)
1236 for (
int j = 0; j <= i; ++j)
1239 if (j == i)
continue;
1243 (*Covariance)(i,j) = 0.0;
1245 (*Correlation)(i,j) = 0.0;
1268 (*Correlation)(i,j) =
hpost2D[i][j]->GetCorrelationFactor();
1279 for (
int i = 0; i <
nDraw; ++i)
1281 for (
int j = 0; j <= i; ++j)
1284 if (j == i)
continue;
1302 PostHistDir->Close();
1316 const int DefaultUpperCut =
UpperCut;
1326 const int IntervalsSize =
nSteps/NIntervals;
1332 std::unique_ptr<TH1D> SubOptimality = std::make_unique<TH1D>(
"Suboptimality",
"Suboptimality", NIntervals, MinStep, MaxStep);
1333 SubOptimality->SetDirectory(
nullptr);
1334 SubOptimality->GetXaxis()->SetTitle(
"Step");
1335 SubOptimality->GetYaxis()->SetTitle(
"Suboptimality");
1336 SubOptimality->SetLineWidth(2);
1337 SubOptimality->SetLineColor(kBlue);
1339 for(
int i = 0; i < NIntervals; ++i)
1351 TVectorD eigen_values;
1352 eigen_values.ResizeTo(eigen.GetEigenValues());
1353 eigen_values = eigen.GetEigenValues();
1356 std::vector<double> EigenValues(eigen_values.GetNrows());
1357 for(
unsigned int j = 0; j < EigenValues.size(); j++)
1359 EigenValues[j] = eigen_values(j);
1362 SubOptimality->SetBinContent(i+1, SubOptimalityValue);
1365 MACH3LOG_INFO(
"Making Suboptimality took {:.2f}s to finish for {} steps", clock.RealTime(),
nEntries);
1371 SubOptimality->Draw(
"l");
1372 Posterior->SetName(SubOptimality->GetName());
1373 Posterior->SetTitle(SubOptimality->GetTitle());
1385 const double RightMargin =
Posterior->GetRightMargin();
1390 hCov->GetZaxis()->SetTitle(
"Covariance");
1391 hCov->SetDirectory(
nullptr);
1394 hCovSq->SetDirectory(
nullptr);
1395 hCovSq->GetZaxis()->SetTitle(
"Covariance");
1398 hCorr->SetDirectory(
nullptr);
1399 hCorr->GetZaxis()->SetTitle(
"Correlation");
1400 hCorr->SetMinimum(-1);
1401 hCorr->SetMaximum(1);
1402 hCov->GetXaxis()->SetLabelSize(0.015);
1403 hCov->GetYaxis()->SetLabelSize(0.015);
1404 hCovSq->GetXaxis()->SetLabelSize(0.015);
1405 hCovSq->GetYaxis()->SetLabelSize(0.015);
1406 hCorr->GetXaxis()->SetLabelSize(0.015);
1407 hCorr->GetYaxis()->SetLabelSize(0.015);
1410 for (
int i = 0; i <
nDraw; ++i)
1412 TString titlex =
"";
1416 hCov->GetXaxis()->SetBinLabel(i+1, titlex);
1417 hCovSq->GetXaxis()->SetBinLabel(i+1, titlex);
1418 hCorr->GetXaxis()->SetBinLabel(i+1, titlex);
1420 for (
int j = 0; j <
nDraw; ++j)
1423 const double cov = (*Covariance)(i,j);
1424 const double corr = (*Correlation)(i,j);
1426 hCov->SetBinContent(i+1, j+1, cov);
1427 hCovSq->SetBinContent(i+1, j+1, ((cov > 0) - (cov < 0))*std::sqrt(std::fabs(cov)));
1428 hCorr->SetBinContent(i+1, j+1, corr);
1430 TString titley =
"";
1431 double nom_j, err_j;
1434 hCov->GetYaxis()->SetBinLabel(j+1, titley);
1435 hCovSq->GetYaxis()->SetBinLabel(j+1, titley);
1436 hCorr->GetYaxis()->SetBinLabel(j+1, titley);
1441 gStyle->SetOptStat(0);
1444 constexpr
int NRGBs = 5;
1445 TColor::InitializeColors();
1446 Double_t stops[NRGBs] = { 0.00, 0.25, 0.50, 0.75, 1.00 };
1447 Double_t red[NRGBs] = { 0.00, 0.25, 1.00, 1.00, 0.50 };
1448 Double_t green[NRGBs] = { 0.00, 0.25, 1.00, 0.25, 0.00 };
1449 Double_t blue[NRGBs] = { 0.50, 1.00, 1.00, 0.25, 0.00 };
1450 TColor::CreateGradientColorTable(5, stops, red, green, blue, 255);
1451 gStyle->SetNumberContours(255);
1459 else hCov->Draw(
"colz");
1465 else hCorr->Draw(
"colz");
1468 hCov->Write(
"Covariance_plot");
1469 hCovSq->Write(
"Covariance_sq_plot");
1470 hCorr->Write(
"Correlation_plot");
1484 MACH3LOG_ERROR(
"Using Legacy Parameters i.e. not one from Parameter Handler Generic, this will not work");
1487 std::vector<double> MeanArray(
nDraw);
1488 std::vector<double> ErrorArray(
nDraw);
1489 std::vector<std::vector<double>> CorrelationMatrix(
nDraw, std::vector<double>(
nDraw, 0.0));
1491 TVectorD* means_vec;
1492 TVectorD* errors_vec;
1494 if (MeansMethod ==
"Arithmetic") {
1497 }
else if (MeansMethod ==
"Gaussian") {
1500 }
else if (MeansMethod ==
"HPD") {
1504 MACH3LOG_ERROR(
"Unknown means method: {}, should be either 'Arithmetic', 'Gaussian', or 'HPD'.", MeansMethod);
1509 for (
int i = 0; i <
nDraw; i++)
1511 MeanArray[i] = (*means_vec)(i);
1512 ErrorArray[i] = (*errors_vec)(i);
1513 for (
int j = 0; j <= i; j++)
1515 CorrelationMatrix[i][j] = (*Correlation)(i,j);
1516 if(i != j) CorrelationMatrix[j][i] = (*Correlation)(i,j);
1535 const double RightMargin =
Posterior->GetRightMargin();
1537 auto MatrixCopy =
M3::Clone(CorrMatrix.get());
1539 std::vector<std::string> GroupName;
1540 std::vector<int> GroupStart;
1541 std::vector<int> GroupEnd;
1544 for (
int iPar = 0; iPar <
nDraw; ++iPar)
1546 std::string GroupNameCurr;
1551 GroupNameCurr =
"Other";
1555 GroupName.push_back(GroupNameCurr);
1556 GroupStart.push_back(0);
1557 }
else if(GroupName.back() != GroupNameCurr ){
1558 GroupName.push_back(GroupNameCurr);
1559 GroupEnd.push_back(iPar);
1560 GroupStart.push_back(iPar);
1563 MatrixCopy->GetXaxis()->SetBinLabel(iPar+1,
"");
1564 MatrixCopy->GetYaxis()->SetBinLabel(iPar+1,
"");
1566 GroupEnd.push_back(
nDraw);
1568 for(
size_t iPar = 0; iPar < GroupName.size(); iPar++) {
1569 MACH3LOG_INFO(
"Group name {} from {} to {}", GroupName[iPar], GroupStart[iPar], GroupEnd[iPar]);
1573 MatrixCopy->Draw(
"colz");
1575 std::vector<std::unique_ptr<TLine>> groupLines;
1577 int nBinsX = MatrixCopy->GetNbinsX();
1578 int nBinsY = MatrixCopy->GetNbinsY();
1581 double xMin = MatrixCopy->GetXaxis()->GetBinLowEdge(1);
1582 double xMax = MatrixCopy->GetXaxis()->GetBinUpEdge(nBinsX);
1583 double yMin = MatrixCopy->GetYaxis()->GetBinLowEdge(1);
1584 double yMax = MatrixCopy->GetYaxis()->GetBinUpEdge(nBinsY);
1586 for (
size_t g = 1; g < GroupStart.size(); ++g) {
1587 const double posX = MatrixCopy->GetXaxis()->GetBinLowEdge(GroupStart[g] + 1);
1588 const double posY = MatrixCopy->GetYaxis()->GetBinLowEdge(GroupStart[g] + 1);
1591 auto vLine = std::make_unique<TLine>(posX, yMin, posX, yMax);
1592 vLine->SetLineColor(kBlack);
1593 vLine->SetLineWidth(2);
1595 groupLines.push_back(std::move(vLine));
1598 auto hLine = std::make_unique<TLine>(xMin, posY, xMax, posY);
1599 hLine->SetLineColor(kBlack);
1600 hLine->SetLineWidth(2);
1602 groupLines.push_back(std::move(hLine));
1605 std::vector<std::unique_ptr<TText>> groupLabels(GroupName.size() * 2);
1606 const double yOffsetBelow = 0.05 * (yMax - yMin);
1607 const double xOffsetRight = 0.02 * (xMax - xMin);
1609 for (
size_t g = 0; g < GroupName.size(); ++g) {
1610 const int startBin = GroupStart[g] + 1;
1611 const int endBin = GroupEnd[g];
1613 const double xStart = MatrixCopy->GetXaxis()->GetBinLowEdge(startBin);
1614 const double xEnd = MatrixCopy->GetXaxis()->GetBinUpEdge(endBin);
1615 const double xMid = 0.5 * (xStart + xEnd);
1617 const double yStart = MatrixCopy->GetYaxis()->GetBinLowEdge(startBin);
1618 const double yEnd = MatrixCopy->GetYaxis()->GetBinUpEdge(endBin);
1619 const double yMid = 0.5 * (yStart + yEnd);
1622 auto labelX = std::make_unique<TText>(xMid, yMin - yOffsetBelow, GroupName[g].c_str());
1623 labelX->SetTextAlign(23);
1624 labelX->SetTextSize(0.025);
1626 groupLabels.push_back(std::move(labelX));
1629 auto labelY = std::make_unique<TText>(xMin - xOffsetRight, yMid, GroupName[g].c_str());
1630 labelY->SetTextAlign(32);
1631 labelY->SetTextSize(0.025);
1633 groupLabels.push_back(std::move(labelY));
1646 const int OptTitle = gStyle->GetOptTitle();
1650 gStyle->SetOptTitle(1);
1652 constexpr
int Nhists = 3;
1654 constexpr
double Thresholds[Nhists+1] = {0, 0.25, 0.5, 1.0001};
1655 constexpr Color_t CorrColours[Nhists] = {kRed-10, kRed-6, kRed};
1658 std::vector<std::vector<double>> CorrOfInterest;
1659 CorrOfInterest.resize(
nDraw);
1660 std::vector<std::vector<std::string>> NameCorrOfInterest;
1661 NameCorrOfInterest.resize(
nDraw);
1663 std::vector<std::vector<std::unique_ptr<TH1D>>> Corr1DHist(
nDraw);
1665 for(
int i = 0; i <
nDraw; ++i)
1668 double Prior = 1.0, PriorError = 1.0;
1671 Corr1DHist[i].resize(Nhists);
1672 for(
int j = 0; j < Nhists; ++j)
1674 Corr1DHist[i][j] = std::make_unique<TH1D>(Form(
"Corr1DHist_%i_%i", i, j), Form(
"Corr1DHist_%i_%i", i, j),
nDraw, 0,
nDraw);
1675 Corr1DHist[i][j]->SetTitle(Form(
"%s",Title.Data()));
1676 Corr1DHist[i][j]->SetDirectory(
nullptr);
1677 Corr1DHist[i][j]->GetYaxis()->SetTitle(
"Correlation");
1678 Corr1DHist[i][j]->SetFillColor(CorrColours[j]);
1679 Corr1DHist[i][j]->SetLineColor(kBlack);
1681 for (
int k = 0; k <
nDraw; ++k)
1683 TString Title_y =
"";
1684 double Prior_y = 1.0;
1685 double PriorError_y = 1.0;
1687 Corr1DHist[i][j]->GetXaxis()->SetBinLabel(k+1, Title_y.Data());
1694 #pragma omp parallel for
1696 for(
int i = 0; i <
nDraw; ++i)
1698 for(
int j = 0; j <
nDraw; ++j)
1700 for(
int k = 0; k < Nhists; ++k)
1702 const double TempEntry = std::fabs((*
Correlation)(i,j));
1703 if(Thresholds[k+1] > TempEntry && TempEntry >= Thresholds[k])
1705 Corr1DHist[i][k]->SetBinContent(j+1, (*
Correlation)(i,j));
1711 NameCorrOfInterest[i].push_back(Corr1DHist[i][0]->GetXaxis()->GetBinLabel(j+1));
1716 TDirectory *CorrDir =
OutputFile->mkdir(
"Corr1D");
1719 for(
int i = 0; i <
nDraw; i++)
1723 Corr1DHist[i][0]->GetXaxis()->LabelsOption(
"v");
1724 Corr1DHist[i][0]->SetMaximum(+1.);
1725 Corr1DHist[i][0]->SetMinimum(-1.);
1726 Corr1DHist[i][0]->Draw();
1727 for(
int k = 1; k < Nhists; k++) {
1728 Corr1DHist[i][k]->Draw(
"SAME");
1731 auto leg = std::make_unique<TLegend>(0.3, 0.75, 0.6, 0.90);
1733 for(
int k = 0; k < Nhists; k++) {
1734 leg->AddEntry(Corr1DHist[i][k].get(), Form(
"%.2f > |Corr| >= %.2f", Thresholds[k+1], Thresholds[k]),
"f");
1738 Posterior->Write(Corr1DHist[i][0]->GetTitle());
1743 for(
int i = 0; i <
nDraw; i++)
1745 const int size = int(CorrOfInterest[i].size());
1747 if(size == 0)
continue;
1748 auto Corr1DHist_Reduced = std::make_unique<TH1D>(
"Corr1DHist_Reduced",
"Corr1DHist_Reduced", size, 0, size);
1749 Corr1DHist_Reduced->SetDirectory(
nullptr);
1750 Corr1DHist_Reduced->SetTitle(Corr1DHist[i][0]->GetTitle());
1751 Corr1DHist_Reduced->GetYaxis()->SetTitle(
"Correlation");
1752 Corr1DHist_Reduced->SetFillColor(kBlue);
1753 Corr1DHist_Reduced->SetLineColor(kBlue);
1755 for (
int j = 0; j < size; ++j)
1757 Corr1DHist_Reduced->GetXaxis()->SetBinLabel(j+1, NameCorrOfInterest[i][j].c_str());
1758 Corr1DHist_Reduced->SetBinContent(j+1, CorrOfInterest[i][j]);
1760 Corr1DHist_Reduced->GetXaxis()->LabelsOption(
"v");
1762 Corr1DHist_Reduced->SetMaximum(+1.);
1763 Corr1DHist_Reduced->SetMinimum(-1.);
1764 Corr1DHist_Reduced->Draw();
1766 Posterior->Write(Form(
"%s_Red", Corr1DHist_Reduced->GetTitle()));
1775 gStyle->SetOptTitle(OptTitle);
1783 if(GroupName ==
"")
return;
1785 TDirectory* Chi2Folder =
OutputFile->mkdir(
"DeltaChi2");
1788 for (
int iPar = 0; iPar <
nDraw; iPar++)
1790 std::string GroupNameCurr;
1795 GroupNameCurr =
"Other";
1798 if (GroupName !=
"All" && GroupNameCurr != GroupName)
continue;
1805 Chi2Folder->Close();
1813 const std::vector<Style_t>& CredibleRegionStyle,
1814 const std::vector<Color_t>& CredibleRegionColor,
1815 const bool CredibleInSigmas,
1816 const bool Draw2DPosterior,
1817 const bool DrawBestFit) {
1823 const int nCredible = int(CredibleRegions.size());
1825 std::vector<std::vector<std::unique_ptr<TH2D>>> hpost_2D_copy(
nDraw);
1826 std::vector<std::vector<std::vector<std::unique_ptr<TH2D>>>> hpost_2D_cl(
nDraw);
1828 for (
int i = 0; i <
nDraw; ++i)
1830 hpost_2D_copy[i].resize(
nDraw);
1831 hpost_2D_cl[i].resize(
nDraw);
1832 for (
int j = 0; j <= i; ++j)
1834 hpost_2D_copy[i][j] = M3::Clone<TH2D>(
hpost2D[i][j], Form(
"hpost_copy_%i_%i", i, j));
1835 hpost_2D_cl[i][j].resize(nCredible);
1836 for (
int k = 0; k < nCredible; ++k)
1838 hpost_2D_cl[i][j][k] = M3::Clone<TH2D>(
hpost2D[i][j], Form(
"hpost_copy_%i_%i_CL_%f", i, j, CredibleRegions[k]));
1844 #pragma omp parallel for
1847 for (
int i = 0; i <
nDraw; ++i)
1849 for (
int j = 0; j <= i; ++j)
1851 for (
int k = 0; k < nCredible; ++k)
1854 hpost_2D_cl[i][j][k]->SetLineColor(CredibleRegionColor[k]);
1855 hpost_2D_cl[i][j][k]->SetLineWidth(2);
1856 hpost_2D_cl[i][j][k]->SetLineStyle(CredibleRegionStyle[k]);
1861 gStyle->SetPalette(51);
1862 for (
int i = 0; i <
nDraw; ++i)
1864 for (
int j = 0; j <= i; ++j)
1867 if (j == i)
continue;
1870 auto legend = std::make_unique<TLegend>(0.20, 0.7, 0.4, 0.92);
1871 legend->SetTextColor(kRed);
1875 auto bestfitM = std::make_unique<TGraph>(1);
1876 const int MaxBin = hpost_2D_copy[i][j]->GetMaximumBin();
1878 hpost_2D_copy[i][j]->GetBinXYZ(MaxBin, Mbx, Mby, Mbz);
1879 const double Mx = hpost_2D_copy[i][j]->GetXaxis()->GetBinCenter(Mbx);
1880 const double My = hpost_2D_copy[i][j]->GetYaxis()->GetBinCenter(Mby);
1882 bestfitM->SetPoint(0, Mx, My);
1883 bestfitM->SetMarkerStyle(22);
1884 bestfitM->SetMarkerSize(1);
1885 bestfitM->SetMarkerColor(kMagenta);
1889 if(Draw2DPosterior){
1890 hpost_2D_copy[i][j]->Draw(
"COLZ");
1892 hpost_2D_copy[i][j]->Draw(
"AXIS");
1896 for (
int k = 0; k < nCredible; ++k)
1897 hpost_2D_cl[i][j][k]->Draw(
"CONT3 SAME");
1898 for (
int k = nCredible-1; k >= 0; --k)
1900 if(CredibleInSigmas)
1901 legend->AddEntry(hpost_2D_cl[i][j][k].get(), Form(
"%.0f#sigma Credible Interval", CredibleRegions[k]),
"l");
1903 legend->AddEntry(hpost_2D_cl[i][j][k].get(), Form(
"%.0f%% Credible Region", CredibleRegions[k]*100),
"l");
1905 legend->Draw(
"SAME");
1908 legend->AddEntry(bestfitM.get(),
"Best Fit",
"p");
1909 bestfitM->Draw(
"SAME.P");
1931 const std::vector<double>& CredibleIntervals,
1932 const std::vector<Color_t>& CredibleIntervalsColours,
1934 const std::vector<double>& CredibleRegions,
1935 const std::vector<Style_t>& CredibleRegionStyle,
1936 const std::vector<Color_t>& CredibleRegionColor,
1938 const bool CredibleInSigmas) {
1942 const int nParamPlot = int(ParNames.size());
1943 std::vector<int> ParamNumber;
1944 std::string ParamInfoNames =
"Making Triangle Plot for { ";
1945 for(
int j = 0; j < nParamPlot; ++j)
1947 ParamInfoNames += fmt::format(
"{} ", ParNames[j]);
1951 MACH3LOG_WARN(
"Couldn't find param {}. Will not plot Triangle plot", ParNames[j]);
1954 ParamNumber.push_back(ParamNo);
1956 ParamInfoNames +=
"}";
1967 auto FormatHistogram = [](
auto& hist) {
1968 hist->GetXaxis()->SetTitle(
"");
1969 hist->GetYaxis()->SetTitle(
"");
1972 hist->GetXaxis()->SetLabelSize(0.1);
1973 hist->GetYaxis()->SetLabelSize(0.1);
1975 hist->GetXaxis()->SetNdivisions(4);
1976 hist->GetYaxis()->SetNdivisions(4);
1984 std::sort(ParamNumber.begin(), ParamNumber.end(), std::greater<int>());
1988 for(
int j = 1; j < nParamPlot+1; j++) Npad += j;
1994 const int nCredibleIntervals = int(CredibleIntervals.size());
1995 const int nCredibleRegions = int(CredibleRegions.size());
1998 std::vector<TPad*> TrianglePad(Npad);
2000 std::vector<std::unique_ptr<TH1D>> hpost_copy(nParamPlot);
2001 std::vector<std::vector<std::unique_ptr<TH1D>>> hpost_cl(nParamPlot);
2002 std::vector<std::unique_ptr<TText>> TriangleText(nParamPlot * 2);
2003 std::vector<std::unique_ptr<TH2D>> hpost_2D_copy(Npad-nParamPlot);
2004 std::vector<std::vector<std::unique_ptr<TH2D>>> hpost_2D_cl(Npad-nParamPlot);
2005 gStyle->SetPalette(51);
2008 std::vector<double> X_Min(nParamPlot);
2009 std::vector<double> X_Max(nParamPlot);
2027 const double TPm[4] = {.07,.07,.05,.05};
2028 const double Pm[2] = {.2,.1};
2031 const double TPw = 1. - TPm[0] - TPm[2];
2032 const double a_x = ( Pm[0] * TPw ) / ( 1. * nParamPlot + Pm[0] * ( 1. - 1.*nParamPlot ) );
2033 const double b_x = ( TPw - a_x ) / ( 1. * nParamPlot );
2036 X_Max[0] = X_Min[0] + a_x + b_x;
2037 for(
int i = 1; i < nParamPlot; i++)
2039 X_Min[i] = X_Max[i-1];
2040 X_Max[i] = X_Min[i]+b_x;
2043 std::vector<double> Y_Min(nParamPlot);
2044 std::vector<double> Y_Max(nParamPlot);
2047 const double TPh = 1. - TPm[1] - TPm[3];
2048 const double a_y = ( Pm[1] * TPh ) / ( 1. * nParamPlot + Pm[1] * ( 1. - 1.*nParamPlot ) );
2049 const double b_y = ( TPh - a_y ) / ( 1. * nParamPlot );
2051 Y_Min[nParamPlot-1] = TPm[1];
2052 Y_Max[nParamPlot-1] = Y_Min[nParamPlot-1] + a_y + b_y;
2053 for(
int i = nParamPlot-2; i >= 0; i--)
2055 Y_Min[i] = Y_Max[i+1];
2056 Y_Max[i] = Y_Min[i]+b_y;
2060 int counterPad = 0, counterText = 0, counterPost = 0, counter2DPost = 0;
2062 for(
int y = 0; y < nParamPlot; y++)
2065 for(
int x = 0; x <= y; x++)
2069 TrianglePad[counterPad] =
new TPad(Form(
"TPad_%i", counterPad), Form(
"TPad_%i", counterPad), X_Min[x], Y_Min[y], X_Max[x], Y_Max[y]);
2071 TrianglePad[counterPad]->SetTopMargin(0);
2072 TrianglePad[counterPad]->SetRightMargin(0);
2074 TrianglePad[counterPad]->SetGrid();
2075 TrianglePad[counterPad]->SetFrameBorderMode(0);
2076 TrianglePad[counterPad]->SetBorderMode(0);
2077 TrianglePad[counterPad]->SetBorderSize(0);
2080 TrianglePad[counterPad]->SetBottomMargin(y == (nParamPlot - 1) ? Pm[1] : 0);
2082 TrianglePad[counterPad]->SetLeftMargin(x == 0 ? Pm[0] : 0);
2084 TrianglePad[counterPad]->Draw();
2085 TrianglePad[counterPad]->cd();
2090 hpost_copy[counterPost] = M3::Clone<TH1D>(
hpost[ParamNumber[x]], Form(
"hpost_copy_%i", ParamNumber[x]));
2091 hpost_cl[counterPost].resize(nCredibleIntervals);
2093 hpost_copy[counterPost]->Scale(1. / hpost_copy[counterPost]->Integral());
2094 for (
int j = 0; j < nCredibleIntervals; ++j)
2096 hpost_cl[counterPost][j] = M3::Clone<TH1D>(
hpost[ParamNumber[x]], Form(
"hpost_copy_%i_CL_%f", ParamNumber[x], CredibleIntervals[j]));
2098 hpost_cl[counterPost][j]->Reset(
"");
2099 hpost_cl[counterPost][j]->Fill(0.0, 0.0);
2102 hpost_cl[counterPost][j]->Scale(1. / hpost_cl[counterPost][j]->Integral());
2103 GetCredibleIntervalSig(hpost_copy[counterPost], hpost_cl[counterPost][j], CredibleInSigmas, CredibleIntervals[j]);
2105 hpost_cl[counterPost][j]->SetFillColor(CredibleIntervalsColours[j]);
2106 hpost_cl[counterPost][j]->SetLineWidth(1);
2109 hpost_copy[counterPost]->SetMaximum(hpost_copy[counterPost]->GetMaximum()*1.2);
2110 hpost_copy[counterPost]->SetLineWidth(2);
2111 hpost_copy[counterPost]->SetLineColor(kBlack);
2114 FormatHistogram(hpost_copy[counterPost]);
2119 hpost_copy[counterPost]->GetXaxis()->SetLabelFont(133);
2120 hpost_copy[counterPost]->GetXaxis()->SetLabelSize(.08*(a_y+b_y)*
Posterior->GetWh());
2122 hpost_copy[counterPost]->GetYaxis()->SetLabelFont(133);
2123 hpost_copy[counterPost]->GetYaxis()->SetLabelSize(.08*(a_y+b_y)*
Posterior->GetWh());
2125 hpost_copy[counterPost]->Draw(
"HIST");
2126 for (
int j = 0; j < nCredibleIntervals; ++j){
2127 hpost_cl[counterPost][j]->Draw(
"HIST SAME");
2134 hpost_2D_copy[counter2DPost] = M3::Clone<TH2D>(
hpost2D[ParamNumber[x]][ParamNumber[y]],
2135 Form(
"hpost_copy_%i_%i", ParamNumber[x], ParamNumber[y]));
2136 hpost_2D_cl[counter2DPost].resize(nCredibleRegions);
2138 for (
int k = 0; k < nCredibleRegions; ++k)
2140 hpost_2D_cl[counter2DPost][k] = M3::Clone<TH2D>(
hpost2D[ParamNumber[x]][ParamNumber[y]],
2141 Form(
"hpost_copy_%i_%i_CL_%f", ParamNumber[x], ParamNumber[y], CredibleRegions[k]));
2144 hpost_2D_cl[counter2DPost][k]->SetLineColor(CredibleRegionColor[k]);
2145 hpost_2D_cl[counter2DPost][k]->SetLineWidth(2);
2146 hpost_2D_cl[counter2DPost][k]->SetLineStyle(CredibleRegionStyle[k]);
2149 FormatHistogram(hpost_2D_copy[counter2DPost]);
2154 hpost_2D_copy[counter2DPost]->GetXaxis()->SetLabelFont(133);
2155 hpost_2D_copy[counter2DPost]->GetXaxis()->SetLabelSize(.08*(a_y+b_y)*
Posterior->GetWh());
2157 hpost_2D_copy[counter2DPost]->GetYaxis()->SetLabelFont(133);
2158 hpost_2D_copy[counter2DPost]->GetYaxis()->SetLabelSize(.08*(a_y+b_y)*
Posterior->GetWh());
2160 hpost_2D_copy[counter2DPost]->Draw(
"COL");
2162 for (
int k = 0; k < nCredibleRegions; ++k){
2163 hpost_2D_cl[counter2DPost][k]->Draw(
"CONT3 SAME");
2168 if(y == (nParamPlot-1))
2171 TriangleText[counterText] = std::make_unique<TText>(X_Min[x] + (X_Max[x]-X_Min[x]+(x == 0 ? a_x : .0))/2., .05,
hpost[ParamNumber[x]]->GetTitle());
2174 TriangleText[counterText]->SetTextAlign(22);
2175 TriangleText[counterText]->SetTextSize(.08*(a_y+b_y));
2176 TriangleText[counterText]->SetNDC(
true);
2177 TriangleText[counterText]->Draw();
2184 TriangleText[counterText] = std::make_unique<TText>(.05, Y_Min[y] + (Y_Max[y]-Y_Min[y]+(y == nParamPlot-1 ? a_y : .0))/2.,
hpost[ParamNumber[y]]->GetTitle());
2186 TriangleText[counterText]->SetTextAngle(90);
2189 TriangleText[counterText]->SetTextAlign(22);
2190 TriangleText[counterText]->SetTextSize(.08*(a_y+b_y));
2191 TriangleText[counterText]->SetNDC(
true);
2192 TriangleText[counterText]->Draw();
2201 auto legend = std::make_unique<TLegend>(0.60, 0.7, 0.9, 0.9);
2204 for (
int j = nCredibleIntervals-1; j >= 0; --j)
2206 if(CredibleInSigmas)
2207 legend->AddEntry(hpost_cl[0][j].get(), Form(
"%.0f#sigma Credible Interval", CredibleIntervals[j]),
"f");
2209 legend->AddEntry(hpost_cl[0][j].get(), Form(
"%.0f%% Credible Interval", CredibleRegions[j]*100),
"f");
2211 for (
int k = nCredibleRegions-1; k >= 0; --k)
2213 if(CredibleInSigmas)
2214 legend->AddEntry(hpost_2D_cl[0][k].get(), Form(
"%.0f#sigma Credible Region", CredibleRegions[k]),
"l");
2216 legend->AddEntry(hpost_2D_cl[0][k].get(), Form(
"%.0f%% Credible Region", CredibleRegions[k]*100),
"l");
2218 legend->Draw(
"SAME");
2231 for(
int i = 0; i < Npad; i++)
delete TrianglePad[i];
2247 Chain =
new TChain(
"posteriors",
"posteriors");
2256 TObjArray* brlis =
Chain->GetListOfBranches();
2268 Chain->SetBranchStatus(
"*",
false);
2275 TBranch* br =
static_cast<TBranch*
>(brlis->At(i));
2280 TString bname = br->GetName();
2283 bool rejected =
false;
2292 if(rejected)
continue;
2295 Chain->SetBranchStatus(bname.Data(),
true);
2297 if (bname.BeginsWith(
"ndd_"))
2303 else if (bname.BeginsWith(
"skd_joint_"))
2311 if (bname.BeginsWith(
"LogL_sample_")) {
2314 else if (bname.BeginsWith(
"LogL_systematic_")) {
2357 Gauss = std::make_unique<TF1>(
"Gauss",
"[0]/sqrt(2.0*3.14159)/[2]*TMath::Exp(-0.5*pow(x-[1],2)/[2]/[2])", -5, 5);
2358 Gauss->SetLineWidth(2);
2359 Gauss->SetLineColor(kOrange-5);
2376 #pragma omp parallel for
2378 for (
int i = 0; i <
nDraw; ++i)
2389 for (
int j = 0; j <
nDraw; ++j) {
2403 for(
unsigned int j = 0; j <
ParamType.size(); j++)
2421 auto PreFitPlot = std::make_unique<TH1D>(
"Prefit",
"Prefit",
nDraw, 0,
nDraw);
2422 PreFitPlot->SetDirectory(
nullptr);
2423 for (
int i = 0; i < PreFitPlot->GetNbinsX() + 1; ++i) {
2424 PreFitPlot->SetBinContent(i+1, 0);
2425 PreFitPlot->SetBinError(i+1, 0);
2430 double CentralValueTemp, Central, Error;
2433 for (
int i = 0; i <
nDraw; ++i)
2442 if ( CentralValueTemp != 0) {
2443 Central =
ParamCentral[ParamEnum][ParamNo] / CentralValueTemp;
2444 Error =
ParamErrors[ParamEnum][ParamNo]/CentralValueTemp;
2446 Central = CentralValueTemp + 1.0;
2452 Central = CentralValueTemp;
2459 PreFitPlot->SetBinContent(i+1, Central);
2460 PreFitPlot->SetBinError(i+1, Error);
2461 PreFitPlot->GetXaxis()->SetBinLabel(i+1,
ParamNames[ParamEnum][ParamNo]);
2463 PreFitPlot->SetDirectory(
nullptr);
2465 PreFitPlot->SetFillStyle(1001);
2466 PreFitPlot->SetFillColor(kRed-3);
2467 PreFitPlot->SetMarkerStyle(21);
2468 PreFitPlot->SetMarkerSize(2.4);
2469 PreFitPlot->SetMarkerColor(kWhite);
2470 PreFitPlot->SetLineColor(PreFitPlot->GetFillColor());
2471 PreFitPlot->GetXaxis()->LabelsOption(
"v");
2501 TDirectory* CovarianceFolder = TempFile->Get<TDirectory>(
"CovarianceFolder");
2504 TMacro *Config = TempFile->Get<TMacro>(
"MaCh3_Config");
2506 if (Config ==
nullptr) {
2515 bool InputNotFound =
false;
2517 CovPos[
kXSecPar] = GetFromManager<std::vector<std::string>>(Settings[
"General"][
"Systematics"][
"XsecCovFile"], {
"none"}, __FILE__ , __LINE__);
2521 InputNotFound =
true;
2525 if (XsecConfig ==
nullptr) {
2539 TMacro *
ReweightConfig = TempFile->Get<TMacro>(
"Reweight_Config");
2552 MACH3LOG_INFO(
"Enabling reweighting with configured weights.");
2558 CovarianceFolder->Close();
2559 delete CovarianceFolder;
2571 TMacro *Config = TempFile->Get<TMacro>(
"MaCh3_Config");
2573 if (Config ==
nullptr) {
2581 CovPos[
kNDPar].push_back(GetFromManager<std::string>(Settings[
"General"][
"Systematics"][
"NDCovFile"],
"none", __FILE__ , __LINE__));
2584 MACH3LOG_WARN(
"Couldn't find NDCov (legacy) branch in output");
2587 CovNamePos[
kNDPar] = GetFromManager<std::string>(Settings[
"General"][
"Systematics"][
"NDCovName"],
"none", __FILE__ , __LINE__);
2592 CovPos[
kFDDetPar].push_back(GetFromManager<std::string>(Settings[
"General"][
"Systematics"][
"FDCovFile"],
"none", __FILE__ , __LINE__));
2595 MACH3LOG_WARN(
"Couldn't find FDCov (legacy) branch in output");
2598 CovNamePos[
kFDDetPar] = GetFromManager<std::string>(Settings[
"General"][
"Systematics"][
"FDCovName"],
"none", __FILE__ , __LINE__);
2618 auto systematics = XSecFile[
"Systematics"];
2620 for (
auto it = systematics.begin(); it != systematics.end(); ++it, ++paramIndex )
2622 auto const ¶m = *it;
2624 std::string ParName = (param[
"Systematic"][
"Names"][
"FancyName"].as<std::string>());
2625 std::string Group = param[
"Systematic"][
"ParameterGroup"].as<std::string>();
2627 bool rejected =
false;
2632 MACH3LOG_DEBUG(
"Excluding param {}, from group {}", ParName, Group);
2641 MACH3LOG_DEBUG(
"Excluding param {}, from group {}", ParName, Group);
2646 if(rejected)
continue;
2649 ParamCentral[
kXSecPar].push_back(param[
"Systematic"][
"ParameterValues"][
"PreFitValue"].as<double>());
2651 ParamFlat[
kXSecPar].push_back(GetFromManager<bool>(param[
"Systematic"][
"FlatPrior"],
false, __FILE__ , __LINE__));
2661 BranchNames.push_back(
"param_" + std::to_string(paramIndex));
2666 MACH3LOG_WARN(
"Couldn't find branch '{}', if you are not planning to draw posteriors this might be fine",
BranchNames.back());
2679 TMatrixDSym *NDdetMatrix = NDdetFile->Get<TMatrixDSym>(
CovNamePos[
kNDPar].c_str());
2680 TVectorD *NDdetNominal = NDdetFile->Get<TVectorD>(
"det_weights");
2681 TDirectory *BinningDirectory = NDdetFile->Get<TDirectory>(
"Binning");
2683 for (
int i = 0; i < NDdetNominal->GetNrows(); ++i)
2693 TIter next(BinningDirectory->GetListOfKeys());
2694 TKey *key =
nullptr;
2696 while ((key =
static_cast<TKey*
>(next())))
2698 std::string name = std::string(key->GetName());
2699 TH2Poly* RefPoly = BinningDirectory->Get<TH2Poly>((name).c_str());
2700 int size = RefPoly->GetNumberOfBins();
2719 for (
int i = 0; i < FDdetMatrix->GetNrows(); ++i)
2753 std::stringstream TempStream;
2754 TempStream <<
"step > " << Cuts;
2764 const unsigned int maxNsteps =
Chain->GetMaximum(
"step");
2789 for (
int i = 0; i <
nDraw; ++i)
2792 double Prior = 1.0, PriorError = 1.0;
2809 #pragma omp parallel for
2811 for (
int i = 0; i <
nDraw; ++i)
2813 for (
int j = 0; j <= i; ++j)
2817 hpost2D[i][j]->Fill(0.0, 0.0, 0.0);
2837 TDirectory *PolarDir =
OutputFile->mkdir(
"PolarDir");
2840 for(
unsigned int k = 0; k < ParNames.size(); ++k)
2846 MACH3LOG_WARN(
"Couldn't find param {}. Will not calculate Polar Plot", ParNames[k]);
2851 double Prior = 1.0, PriorError = 1.0;
2854 std::vector<double> x_val(
nBins);
2855 std::vector<double> y_val(
nBins);
2857 constexpr
double xmin = 0;
2858 constexpr
double xmax = 2*TMath::Pi();
2860 double Integral =
hpost[ParamNo]->Integral();
2861 for (Int_t ipt = 0; ipt <
nBins; ipt++)
2863 x_val[ipt] = ipt*(xmax-xmin)/
nBins+xmin;
2864 y_val[ipt] =
hpost[ParamNo]->GetBinContent(ipt+1)/Integral;
2867 auto PolarGraph = std::make_unique<TGraphPolar>(
nBins, x_val.data(), y_val.data());
2868 PolarGraph->SetLineWidth(2);
2869 PolarGraph->SetFillStyle(3001);
2870 PolarGraph->SetLineColor(kRed);
2871 PolarGraph->SetFillColor(kRed);
2872 PolarGraph->Draw(
"AFL");
2874 auto Text = std::make_unique<TText>(0.6, 0.1, Title);
2875 Text->SetTextSize(0.04);
2894 const std::vector<std::vector<double>>& Model1Bounds,
2895 const std::vector<std::vector<double>>& Model2Bounds,
2896 const std::vector<std::vector<std::string>>& ModelNames){
2901 if((ParNames.size() != Model1Bounds.size()) || (Model2Bounds.size() != Model1Bounds.size()) || (Model2Bounds.size() != ModelNames.size()))
2906 for(
unsigned int k = 0; k < ParNames.size(); ++k)
2912 MACH3LOG_WARN(
"Couldn't find param {}. Will not calculate Bayes Factor", ParNames[k]);
2916 const double M1_min = Model1Bounds[k][0];
2917 const double M2_min = Model2Bounds[k][0];
2918 const double M1_max = Model1Bounds[k][1];
2919 const double M2_max = Model2Bounds[k][1];
2921 long double IntegralMode1 =
hpost[ParamNo]->Integral(
hpost[ParamNo]->FindFixBin(M1_min),
hpost[ParamNo]->FindFixBin(M1_max));
2922 long double IntegralMode2 =
hpost[ParamNo]->Integral(
hpost[ParamNo]->FindFixBin(M2_min),
hpost[ParamNo]->FindFixBin(M2_max));
2924 double BayesFactor = 0.;
2925 std::string Name =
"";
2928 if(IntegralMode1 >= IntegralMode2)
2930 BayesFactor = IntegralMode1/IntegralMode2;
2931 Name =
"\\mathfrak{B}(" + ModelNames[k][0]+
"/" + ModelNames[k][1] +
") = " + std::to_string(BayesFactor);
2935 BayesFactor = IntegralMode2/IntegralMode1;
2936 Name =
"\\mathfrak{B}(" + ModelNames[k][1]+
"/" + ModelNames[k][0] +
") = " + std::to_string(BayesFactor);
2942 MACH3LOG_INFO(
"Following Jeffreys Scale = {}", JeffreysScale);
2943 MACH3LOG_INFO(
"Following Dunne-Kaboth Scale = {}", DunneKabothScale);
2951 const std::vector<double>& EvaluationPoint,
2952 const std::vector<std::vector<double>>& Bounds){
2954 if((ParNames.size() != EvaluationPoint.size()) || (Bounds.size() != EvaluationPoint.size()))
2963 TDirectory *SavageDickeyDir =
OutputFile->mkdir(
"SavageDickey");
2964 SavageDickeyDir->cd();
2966 for(
unsigned int k = 0; k < ParNames.size(); ++k)
2972 MACH3LOG_WARN(
"Couldn't find param {}. Will not calculate SavageDickey", ParNames[k]);
2977 double Prior = 1.0, PriorError = 1.0;
2981 auto PosteriorHist = M3::Clone<TH1D>(
hpost[ParamNo], std::string(Title));
2984 std::unique_ptr<TH1D> PriorHist;
2988 int NBins = PosteriorHist->GetNbinsX();
2989 if(Bounds[k][0] > Bounds[k][1])
2994 PriorHist = std::make_unique<TH1D>(
"PriorHist", Title, NBins, Bounds[k][0], Bounds[k][1]);
2995 PriorHist->SetDirectory(
nullptr);
2996 double FlatProb = ( Bounds[k][1] - Bounds[k][0]) / NBins;
2997 for (
int g = 0; g < NBins + 1; ++g)
2999 PriorHist->SetBinContent(g+1, FlatProb);
3004 PriorHist = M3::Clone<TH1D>(PosteriorHist.get(),
"Prior");
3005 PriorHist->Reset(
"");
3006 PriorHist->Fill(0.0, 0.0);
3008 auto rand = std::make_unique<TRandom3>(0);
3010 for(
int g = 0; g < 1000000; ++g)
3012 PriorHist->Fill(rand->Gaus(Prior, PriorError));
3015 SavageDickeyPlot(PriorHist, PosteriorHist, std::string(Title), EvaluationPoint[k]);
3018 SavageDickeyDir->Close();
3019 delete SavageDickeyDir;
3027 std::unique_ptr<TH1D>& PosteriorHist,
3028 const std::string& Title,
3029 const double EvaluationPoint)
const {
3032 PriorHist->Scale(1./PriorHist->Integral(),
"width");
3033 PosteriorHist->Scale(1./PosteriorHist->Integral(),
"width");
3035 PriorHist->SetLineColor(kRed);
3036 PriorHist->SetMarkerColor(kRed);
3037 PriorHist->SetFillColorAlpha(kRed, 0.35);
3038 PriorHist->SetFillStyle(1001);
3039 PriorHist->GetXaxis()->SetTitle(Title.c_str());
3040 PriorHist->GetYaxis()->SetTitle(
"Posterior Probability");
3041 PriorHist->SetMaximum(PosteriorHist->GetMaximum()*1.5);
3042 PriorHist->GetYaxis()->SetLabelOffset(999);
3043 PriorHist->GetYaxis()->SetLabelSize(0);
3044 PriorHist->SetLineWidth(2);
3045 PriorHist->SetLineStyle(kSolid);
3047 PosteriorHist->SetLineColor(kBlue);
3048 PosteriorHist->SetMarkerColor(kBlue);
3049 PosteriorHist->SetFillColorAlpha(kBlue, 0.35);
3050 PosteriorHist->SetFillStyle(1001);
3052 PriorHist->Draw(
"hist");
3053 PosteriorHist->Draw(
"hist same");
3055 double ProbPrior = PriorHist->GetBinContent(PriorHist->FindBin(EvaluationPoint));
3057 if(ProbPrior < 0) ProbPrior = 0.00001;
3058 double ProbPosterior = PosteriorHist->GetBinContent(PosteriorHist->FindBin(EvaluationPoint));
3059 double SavageDickey = ProbPosterior/ProbPrior;
3063 auto PostPoint = std::make_unique<TGraph>(1);
3064 PostPoint->SetPoint(0, EvaluationPoint, ProbPosterior);
3065 PostPoint->SetMarkerStyle(20);
3066 PostPoint->SetMarkerSize(1);
3067 PostPoint->Draw(
"P same");
3069 auto PriorPoint = std::make_unique<TGraph>(1);
3070 PriorPoint->SetPoint(0, EvaluationPoint, ProbPrior);
3071 PriorPoint->SetMarkerStyle(20);
3072 PriorPoint->SetMarkerSize(1);
3073 PriorPoint->Draw(
"P same");
3075 auto legend = std::make_unique<TLegend>(0.12, 0.6, 0.6, 0.97);
3077 legend->AddEntry(PriorHist.get(),
"Prior",
"l");
3078 legend->AddEntry(PosteriorHist.get(),
"Posterior",
"l");
3079 legend->AddEntry(PostPoint.get(), Form(
"SavageDickey = %.2f, (%s)", SavageDickey, DunneKabothScale.c_str()),
"");
3080 legend->Draw(
"same");
3089 const std::vector<double>& Error,
3090 const bool& SaveBranch)
const {
3094 if( (Names.size() != Error.size()))
3096 MACH3LOG_ERROR(
"Size of passed vectors doesn't match in {}", __func__);
3099 std::vector<int> Param;
3102 for(
unsigned int k = 0; k < Names.size(); ++k)
3108 MACH3LOG_WARN(
"Couldn't find param {}. Can't Smear", Names[k]);
3113 double Prior = 1.0, PriorError = 1.0;
3116 Param.push_back(ParamNo);
3118 std::string InputFile =
MCMCFile+
".root";
3119 std::string OutputFilename =
MCMCFile +
"_smeared.root";
3122 int ret = system((
"cp " + InputFile +
" " + OutputFilename).c_str());
3124 MACH3LOG_WARN(
"Error: system call to copy file failed with code {}", ret);
3126 TFile *OutputChain =
M3::Open(OutputFilename,
"UPDATE", __FILE__, __LINE__);
3128 TTree *post = OutputChain->Get<TTree>(
"posteriors");
3129 TTree *treeNew = post->CloneTree(0);
3131 std::vector<double> NewParameter(Names.size());
3132 for(
size_t i = 0; i < Param.size(); i++) {
3133 post->SetBranchAddress(
BranchNames[Param[i]], &NewParameter[i]);
3136 std::vector<double> Unsmeared_Parameter;
3138 Unsmeared_Parameter.resize(Param.size());
3139 for(
size_t i = 0; i < Param.size(); i++) {
3140 treeNew->Branch((
BranchNames[Param[i]] +
"_unsmeared"), &Unsmeared_Parameter[i]);
3144 auto rand = std::make_unique<TRandom3>(0);
3145 Long64_t AllEntries = post->GetEntries();
3146 for (Long64_t i = 0; i < AllEntries; ++i) {
3151 for(
size_t iPar = 0; iPar < Param.size(); iPar++) {
3152 Unsmeared_Parameter[iPar] = NewParameter[iPar];
3156 for(
size_t iPar = 0; iPar < Param.size(); iPar++) {
3157 NewParameter[iPar] = NewParameter[iPar] + rand->Gaus(0, Error[iPar]);
3164 treeNew->Write(
"posteriors", TObject::kOverwrite);
3167 YAML::Node yaml_node;
3168 yaml_node[
"Smearing"].SetStyle(YAML::EmitterStyle::Block);
3170 for (
size_t k = 0; k < Names.size(); ++k) {
3172 entry.SetStyle(YAML::EmitterStyle::Flow);
3174 entry.push_back(Error[k]);
3175 entry.push_back(
"Gauss");
3177 yaml_node[
"Smearing"][Names[k]] = entry;
3179 TMacro ConfigSave =
YAMLtoTMacro(yaml_node,
"Smearing_Config");
3182 OutputChain->Close();
3189 const std::vector<int>& NIntervals) {
3194 for(
unsigned int k = 0; k < Names.size(); ++k)
3200 MACH3LOG_WARN(
"Couldn't find param {}. Can't reweight Prior", Names[k]);
3204 const int IntervalsSize =
nSteps/NIntervals[k];
3206 std::string filename = Names[k] +
".gif";
3207 std::ifstream f(filename);
3210 int ret = system(fmt::format(
"rm {}", filename).c_str());
3212 MACH3LOG_WARN(
"Error: system call to delete {} failed with code {}", filename, ret);
3217 for(
int i = NIntervals[k]-1; i >= 0; --i)
3222 hpost[ParamNo]->GetXaxis()->GetXmin(),
hpost[ParamNo]->GetXaxis()->GetXmax());
3223 EvePlot->SetMinimum(0);
3224 EvePlot->GetYaxis()->SetTitle(
"PDF");
3225 EvePlot->GetYaxis()->SetNoExponent(
false);
3228 std::string CutPosterior1D =
"step > " + std::to_string(i*IntervalsSize+IntervalsSize);
3238 CutPosterior1D =
"(" + CutPosterior1D +
")*(" + name +
")";
3242 std::string TextTitle =
"Steps = 0 - "+std::to_string(Counter*IntervalsSize+IntervalsSize);
3246 EvePlot->SetLineWidth(2);
3247 EvePlot->SetLineColor(kBlue-1);
3248 EvePlot->SetTitle(Names[k].c_str());
3249 EvePlot->GetXaxis()->SetTitle(EvePlot->GetTitle());
3250 EvePlot->GetYaxis()->SetLabelOffset(1000);
3253 EvePlot->Scale(1. / EvePlot->Integral());
3254 EvePlot->Draw(
"HIST");
3256 TText text(0.3, 0.8, TextTitle.c_str());
3257 text.SetTextFont (43);
3258 text.SetTextSize (40);
3262 if(i == 0)
Posterior->Print((Names[k] +
".gif++20").c_str());
3263 else Posterior->Print((Names[k] +
".gif+20").c_str());
3302 std::unordered_set<unsigned int> s(StepNumber, StepNumber + size);
3303 return s.size() == size;
3314 MACH3LOG_ERROR(
"Even though it is used for MakeCovariance_MP and for DiagMCMC");
3315 MACH3LOG_ERROR(
"it has different structure in both for cache hits, sorry ");
3320 MACH3LOG_ERROR(
"please use SetnBatches to set other value fore example 20");
3326 for (
int j = 0; j <
nDraw; ++j) {
3328 for (
int i = 0; i <
nEntries; ++i) {
3337 for (
int i = 0; i <
nEntries; ++i) {
3344 for (
size_t j = 0; j <
SystName_v.size(); ++j) {
3356 Chain->SetBranchStatus(
"*",
false);
3359 const int countwidth =
nEntries/10;
3366 for (
int i = 0; i <
nBatches; ++i) {
3369 for (
int j = 0; j <
nDraw; ++j) {
3373 std::vector<double> ParStepBranch(
nDraw);
3374 std::vector<double> SampleValuesBranch(
SampleName_v.size());
3375 std::vector<double> SystValuesBranch(
SystName_v.size());
3376 unsigned int StepNumberBranch = 0;
3377 double AccProbValuesBranch = 0;
3379 for (
int j = 0; j <
nDraw; ++j) {
3389 for (
size_t j = 0; j <
SystName_v.size(); ++j) {
3394 Chain->SetBranchStatus(
"step",
true);
3395 Chain->SetBranchAddress(
"step", &StepNumberBranch);
3397 Chain->SetBranchStatus(
"accProb",
true);
3398 Chain->SetBranchAddress(
"accProb", &AccProbValuesBranch);
3402 for (
int i = 0; i <
nEntries; ++i) {
3406 if (i % countwidth == 0)
3410 for (
int j = 0; j <
nDraw; ++j) {
3411 ParStep[j][i] = ParStepBranch[j];
3418 for (
size_t j = 0; j <
SystName_v.size(); ++j) {
3427 int BatchNumber = -1;
3429 for (
int j = 0; j <
nBatches; ++j) {
3430 if (i < (j+1)*BatchLength) {
3436 for (
int j = 0; j <
nDraw; ++j) {
3444 MACH3LOG_INFO(
"Took {:.2f}s to finish caching statistic for Diag MCMC with {} steps", clock.RealTime(),
nEntries);
3447 MACH3LOG_ERROR(
"Found steps with duplicate StepNumber, this indicate merged chain has been passed to DiagMCMC");
3448 MACH3LOG_ERROR(
"Code hasn't been optimised to work with merged chains, results may be unintended");
3453 #pragma omp parallel for
3455 for (
int i = 0; i <
nDraw; ++i) {
3456 for (
int j = 0; j <
nBatches; ++j) {
3474 std::vector<std::unique_ptr<TH1D>> TraceParamPlots(
nDraw);
3475 std::vector<std::unique_ptr<TH1D>> TraceSamplePlots(
SampleName_v.size());
3476 std::vector<std::unique_ptr<TH1D>> TraceSystsPlots(
SystName_v.size());
3479 for (
int j = 0; j <
nDraw; ++j) {
3481 double Prior = 1.0, PriorError = 1.0;
3484 std::string HistName = Form(
"%s_%s_Trace", Title.Data(),
BranchNames[j].Data());
3485 TraceParamPlots[j] = std::make_unique<TH1D>(HistName.c_str(), HistName.c_str(),
nEntries, 0,
nEntries);
3486 TraceParamPlots[j]->SetDirectory(
nullptr);
3487 TraceParamPlots[j]->GetXaxis()->SetTitle(
"Step");
3488 TraceParamPlots[j]->GetYaxis()->SetTitle(
"Parameter Variation");
3493 TraceSamplePlots[j] = std::make_unique<TH1D>(HistName.c_str(), HistName.c_str(),
nEntries, 0,
nEntries);
3494 TraceSamplePlots[j]->SetDirectory(
nullptr);
3495 TraceSamplePlots[j]->GetXaxis()->SetTitle(
"Step");
3496 TraceSamplePlots[j]->GetYaxis()->SetTitle(
"Sample -logL");
3499 for (
size_t j = 0; j <
SystName_v.size(); ++j) {
3501 TraceSystsPlots[j] = std::make_unique<TH1D>(HistName.c_str(), HistName.c_str(),
nEntries, 0,
nEntries);
3502 TraceSystsPlots[j]->SetDirectory(
nullptr);
3503 TraceSystsPlots[j]->GetXaxis()->SetTitle(
"Step");
3504 TraceSystsPlots[j]->GetYaxis()->SetTitle(
"Systematic -logL");
3511 #pragma omp parallel for
3513 for (
int i = 0; i <
nEntries; ++i) {
3515 for (
int j = 0; j <
nDraw; ++j) {
3516 TraceParamPlots[j]->SetBinContent(i,
ParStep[j][i]);
3519 TraceSamplePlots[j]->SetBinContent(i,
SampleValues[i][j]);
3521 for (
size_t j = 0; j <
SystName_v.size(); ++j) {
3522 TraceSystsPlots[j]->SetBinContent(i,
SystValues[i][j]);
3527 TDirectory *TraceDir =
OutputFile->mkdir(
"Trace");
3529 for (
int j = 0; j <
nDraw; ++j) {
3531 auto Fitter = std::make_unique<TF1>(
"Fitter",
"[0]",
nEntries/2,
nEntries);
3532 Fitter->SetLineColor(kRed);
3533 TraceParamPlots[j]->Fit(
"Fitter",
"Rq");
3534 TraceParamPlots[j]->Write();
3537 TDirectory *LLDir =
OutputFile->mkdir(
"LogL");
3540 TraceSamplePlots[j]->Write();
3545 for (
size_t j = 0; j <
SystName_v.size(); ++j) {
3546 TraceSystsPlots[j]->Write();
3561 std::vector <double> ParamSums(
nDraw,0);
3564 #pragma omp parallel for
3566 for (
int j = 0; j <
nDraw; ++j) {
3567 for (
int i = 0; i <
nEntries; ++i) {
3568 ParamSums[j] +=
ParStep[j][i];
3573 #pragma omp parallel for
3575 for (
int i = 0; i <
nDraw; ++i) {
3591 MACH3LOG_INFO(
"Making auto-correlations for nLags = {}", nLags);
3595 TDirectory* AutoCorrDir =
OutputFile->mkdir(
"Auto_corr");
3596 std::vector<std::unique_ptr<TH1D>> LagKPlots(
nDraw);
3597 std::vector<std::vector<double>> LagL(
nDraw);
3600 std::vector<double> ACFFT(
nEntries, 0.0);
3601 std::vector<double> ParVals(
nEntries, 0.0);
3602 std::vector<double> ParValsFFTR(
nEntries, 0.0);
3603 std::vector<double> ParValsFFTI(
nEntries, 0.0);
3604 std::vector<double> ParValsFFTSquare(
nEntries, 0.0);
3605 std::vector<double> ParValsComplex(
nEntries, 0.0);
3610 TVirtualFFT* fftf = TVirtualFFT::FFT(1, &
nEntries,
"C2CFORWARD");
3611 TVirtualFFT* fftb = TVirtualFFT::FFT(1, &
nEntries,
"C2CBACKWARD");
3614 for (
int j = 0; j <
nDraw; ++j) {
3616 LagL[j].resize(nLags);
3617 for (
int i = 0; i <
nEntries; ++i) {
3618 ParVals[i] =
ParStep[j][i]-ParamSums[j];
3619 ParValsComplex[i] = 0.;
3623 fftf->SetPointsComplex(ParVals.data(), ParValsComplex.data());
3625 fftf->GetPointsComplex(ParValsFFTR.data(), ParValsFFTI.data());
3628 for (
int i = 0; i <
nEntries; ++i) {
3629 ParValsFFTSquare[i] = ParValsFFTR[i]*ParValsFFTR[i] + ParValsFFTI[i]*ParValsFFTI[i];
3633 fftb->SetPointsComplex(ParValsFFTSquare.data(), ParValsComplex.data());
3635 fftb->GetPointsComplex(ACFFT.data(), ParValsComplex.data());
3638 double normAC = ACFFT[0];
3639 for (
int i = 0; i <
nEntries; ++i) {
3645 double Prior = 1.0, PriorError = 1.0;
3647 std::string HistName = Form(
"%s_%s_Lag", Title.Data(),
BranchNames[j].Data());
3650 LagKPlots[j] = std::make_unique<TH1D>(HistName.c_str(), HistName.c_str(), nLags, 0.0, nLags);
3651 LagKPlots[j]->SetDirectory(
nullptr);
3652 LagKPlots[j]->GetXaxis()->SetTitle(
"Lag");
3653 LagKPlots[j]->GetYaxis()->SetTitle(
"Auto-correlation function");
3656 for (
int k = 0; k < nLags; ++k) {
3657 LagL[j][k] = ACFFT[k];
3658 LagKPlots[j]->SetBinContent(k, ACFFT[k]);
3663 LagKPlots[j]->Write();
3669 AutoCorrDir->Close();
3675 MACH3LOG_INFO(
"Making auto-correlations took {:.2f}s", clock.RealTime());
3687 MACH3LOG_INFO(
"Making auto-correlations for nLags = {}", nLags);
3690 std::vector<std::vector<double>> DenomSum(
nDraw);
3691 std::vector<std::vector<double>> NumeratorSum(
nDraw);
3692 std::vector<std::vector<double>> LagL(
nDraw);
3694 for (
int j = 0; j <
nDraw; ++j) {
3695 DenomSum[j].resize(nLags);
3696 NumeratorSum[j].resize(nLags);
3697 LagL[j].resize(nLags);
3699 std::vector<std::unique_ptr<TH1D>> LagKPlots(
nDraw);
3701 for (
int j = 0; j <
nDraw; ++j)
3704 for (
int k = 0; k < nLags; ++k) {
3705 NumeratorSum[j][k] = 0.0;
3706 DenomSum[j][k] = 0.0;
3712 double Prior = 1.0, PriorError = 1.0;
3715 std::string HistName = Form(
"%s_%s_Lag", Title.Data(),
BranchNames[j].Data());
3716 LagKPlots[j] = std::make_unique<TH1D>(HistName.c_str(), HistName.c_str(), nLags, 0.0, nLags);
3717 LagKPlots[j]->SetDirectory(
nullptr);
3718 LagKPlots[j]->GetXaxis()->SetTitle(
"Lag");
3719 LagKPlots[j]->GetYaxis()->SetTitle(
"Auto-correlation function");
3727 #pragma omp parallel for collapse(2)
3729 for (
int j = 0; j <
nDraw; ++j) {
3730 for (
int k = 0; k < nLags; ++k) {
3732 for (
int i = 0; i <
nEntries; ++i) {
3733 const double Diff =
ParStep[j][i]-ParamSums[j];
3737 const double LagTerm =
ParStep[j][i+k]-ParamSums[j];
3738 const double Product = Diff*LagTerm;
3739 NumeratorSum[j][k] += Product;
3742 const double Denom = Diff*Diff;
3743 DenomSum[j][k] += Denom;
3750 float* ParStep_cpu =
nullptr;
3751 float* NumeratorSum_cpu =
nullptr;
3752 float* ParamSums_cpu =
nullptr;
3753 float* DenomSum_cpu =
nullptr;
3756 PrepareGPU_AutoCorr(nLags, ParamSums, ParStep_cpu, NumeratorSum_cpu, ParamSums_cpu, DenomSum_cpu);
3759 GPUProcessor->RunGPU_AutoCorr(NumeratorSum_cpu,
3763 #pragma omp parallel for collapse(2)
3766 for (
int j = 0; j <
nDraw; ++j)
3768 for (
int k = 0; k < nLags; ++k)
3770 const int temp_index = j*nLags+k;
3771 NumeratorSum[j][k] = NumeratorSum_cpu[temp_index];
3772 DenomSum[j][k] = DenomSum_cpu[temp_index];
3776 if(NumeratorSum_cpu)
delete[] NumeratorSum_cpu;
3777 if(DenomSum_cpu)
delete[] DenomSum_cpu;
3778 if(ParStep_cpu)
delete[] ParStep_cpu;
3779 if(ParamSums_cpu)
delete[] ParamSums_cpu;
3782 GPUProcessor->CleanupGPU_AutoCorr();
3788 TDirectory *AutoCorrDir =
OutputFile->mkdir(
"Auto_corr");
3790 for (
int j = 0; j <
nDraw; ++j) {
3791 for (
int k = 0; k < nLags; ++k) {
3792 LagL[j][k] = NumeratorSum[j][k]/DenomSum[j][k];
3793 LagKPlots[j]->SetBinContent(k, NumeratorSum[j][k]/DenomSum[j][k]);
3796 LagKPlots[j]->Write();
3802 AutoCorrDir->Close();
3808 MACH3LOG_INFO(
"Making auto-correlations took {:.2f}s", clock.RealTime());
3814 void MCMCProcessor::PrepareGPU_AutoCorr(
const int nLags,
const std::vector<double>& ParamSums,
float*& ParStep_cpu,
3815 float*& NumeratorSum_cpu,
float*& ParamSums_cpu,
float*& DenomSum_cpu) {
3819 NumeratorSum_cpu =
new float[
nDraw*nLags];
3820 DenomSum_cpu =
new float[
nDraw*nLags];
3821 ParamSums_cpu =
new float[
nDraw];
3825 #pragma omp parallel
3830 #pragma omp for nowait
3832 for (
int i = 0; i <
nDraw; ++i)
3835 ParamSums_cpu[i] = ParamSums[i];
3839 #pragma omp for collapse(2) nowait
3841 for (
int j = 0; j <
nDraw; ++j)
3843 for (
int k = 0; k < nLags; ++k)
3845 const int temp = j*nLags+k;
3846 NumeratorSum_cpu[temp] = 0.0;
3847 DenomSum_cpu[temp] = 0.0;
3852 #pragma omp for collapse(2)
3854 for (
int j = 0; j <
nDraw; ++j)
3859 ParStep_cpu[temp] =
ParStep[j][i];
3868 GPUProcessor->InitGPU_AutoCorr(
nEntries,
3874 GPUProcessor->CopyToGPU_AutoCorr(ParStep_cpu,
3888 if(LagL.size() == 0)
3895 TVectorD* SamplingEfficiency =
new TVectorD(
nDraw);
3896 std::vector<double> TempDenominator(
nDraw);
3898 constexpr
int Nhists = 5;
3899 constexpr
double Thresholds[Nhists + 1] = {1, 0.02, 0.005, 0.001, 0.0001, 0.0};
3900 constexpr Color_t ESSColours[Nhists] = {kGreen, kGreen + 2, kYellow, kOrange, kRed};
3903 std::vector<std::unique_ptr<TH1D>> EffectiveSampleSizeHist(Nhists);
3904 for(
int i = 0; i < Nhists; ++i)
3906 EffectiveSampleSizeHist[i] =
3907 std::make_unique<TH1D>(Form(
"EffectiveSampleSizeHist_%i", i), Form(
"EffectiveSampleSizeHist_%i", i),
nDraw, 0,
nDraw);
3908 EffectiveSampleSizeHist[i]->SetDirectory(
nullptr);
3909 EffectiveSampleSizeHist[i]->GetYaxis()->SetTitle(
"N_{eff}/N");
3910 EffectiveSampleSizeHist[i]->SetFillColor(ESSColours[i]);
3911 EffectiveSampleSizeHist[i]->SetLineColor(ESSColours[i]);
3912 EffectiveSampleSizeHist[i]->Sumw2();
3913 for (
int j = 0; j <
nDraw; ++j)
3916 double Prior = 1.0, PriorError = 1.0;
3918 EffectiveSampleSizeHist[i]->GetXaxis()->SetBinLabel(j+1, Title.Data());
3923 #pragma omp parallel for
3926 for (
int j = 0; j <
nDraw; ++j)
3930 TempDenominator[j] = 0.;
3932 for (
int k = 0; k < nLags; ++k)
3934 TempDenominator[j] += LagL[j][k];
3936 TempDenominator[j] = 1+2*TempDenominator[j];
3937 (*EffectiveSampleSize)(j) =
double(
nEntries)/TempDenominator[j];
3939 (*SamplingEfficiency)(j) = 100 * 1/TempDenominator[j];
3941 for(
int i = 0; i < Nhists; ++i)
3943 EffectiveSampleSizeHist[i]->SetBinContent(j+1, 0);
3944 EffectiveSampleSizeHist[i]->SetBinError(j+1, 0);
3947 if(Thresholds[i] >= TempEntry && TempEntry > Thresholds[i+1])
3950 EffectiveSampleSizeHist[i]->SetBinContent(j+1, TempEntry);
3959 SamplingEfficiency->Write(
"SamplingEfficiency");
3961 EffectiveSampleSizeHist[0]->SetTitle(
"Effective Sample Size");
3962 EffectiveSampleSizeHist[0]->Draw();
3963 for(
int i = 1; i < Nhists; ++i)
3965 EffectiveSampleSizeHist[i]->Draw(
"SAME");
3968 auto leg = std::make_unique<TLegend>(0.2, 0.7, 0.6, 0.95);
3970 for(
int i = 0; i < Nhists; ++i)
3972 leg->AddEntry(EffectiveSampleSizeHist[i].get(), Form(
"%.4f >= N_{eff}/N > %.4f", Thresholds[i], Thresholds[i+1]),
"f");
3973 } leg->Draw(
"SAME");
3975 Posterior->Write(
"EffectiveSampleSizeCanvas");
3979 delete SamplingEfficiency;
3989 std::vector<std::unique_ptr<TH1D>> BatchedParamPlots(
nDraw);
3990 for (
int j = 0; j <
nDraw; ++j) {
3992 double Prior = 1.0, PriorError = 1.0;
3996 std::string HistName = Form(
"%s_%s_batch", Title.Data(),
BranchNames[j].Data());
3997 BatchedParamPlots[j] = std::make_unique<TH1D>(HistName.c_str(), HistName.c_str(),
nBatches, 0,
nBatches);
3998 BatchedParamPlots[j]->SetDirectory(
nullptr);
4002 #pragma omp parallel for
4004 for (
int j = 0; j <
nDraw; ++j) {
4005 for (
int i = 0; i <
nBatches; ++i) {
4009 std::stringstream ss;
4010 ss << BatchRangeLow <<
" - " << BatchRangeHigh;
4011 BatchedParamPlots[j]->GetXaxis()->SetBinLabel(i+1, ss.str().c_str());
4015 TDirectory *BatchDir =
OutputFile->mkdir(
"Batched_means");
4017 for (
int j = 0; j <
nDraw; ++j) {
4018 auto Fitter = std::make_unique<TF1>(
"Fitter",
"[0]", 0,
nBatches);
4019 Fitter->SetLineColor(kRed);
4020 BatchedParamPlots[j]->Fit(
"Fitter",
"Rq");
4021 BatchedParamPlots[j]->Write();
4028 for (
int i = 0; i <
nBatches; ++i) {
4045 MACH3LOG_ERROR(
"BatchedAverages haven't been initialises or have been deleted something is wrong");
4051 TVectorD* BatchedVariance =
new TVectorD(
nDraw);
4053 TVectorD* C_Test_Statistics =
new TVectorD(
nDraw);
4055 std::vector<double> OverallBatchMean(
nDraw);
4056 std::vector<double> C_Rho_Nominator(
nDraw);
4057 std::vector<double> C_Rho_Denominator(
nDraw);
4058 std::vector<double> C_Nominator(
nDraw);
4059 std::vector<double> C_Denominator(
nDraw);
4063 #pragma omp parallel
4070 for (
int j = 0; j <
nDraw; ++j)
4072 OverallBatchMean[j] = 0.0;
4073 C_Rho_Nominator[j] = 0.0;
4074 C_Rho_Denominator[j] = 0.0;
4075 C_Nominator[j] = 0.0;
4076 C_Denominator[j] = 0.0;
4078 (*BatchedVariance)(j) = 0.0;
4079 (*C_Test_Statistics)(j) = 0.0;
4088 #pragma omp for nowait
4091 for (
int j = 0; j <
nDraw; ++j)
4097 (*BatchedVariance)(j) = (BatchLength/(
nBatches-1))* (*BatchedVariance)(j);
4102 #pragma omp for nowait
4104 for (
int j = 0; j <
nDraw; ++j)
4112 C_Denominator[j] = 2*C_Denominator[j];
4119 for (
int j = 0; j <
nDraw; ++j)
4121 for (
int i = 0; i <
nBatches-1; ++i)
4136 for (
int j = 0; j <
nDraw; ++j)
4138 (*C_Test_Statistics)(j) = std::sqrt((
nBatches*
nBatches - 1)/(
nBatches-2)) * ( C_Rho_Nominator[j]/C_Rho_Denominator[j] + C_Nominator[j]/ C_Denominator[j]);
4146 BatchedVariance->Write(
"BatchedMeansVariance");
4147 C_Test_Statistics->Write(
"C_Test_Statistics");
4150 delete BatchedVariance;
4151 delete C_Test_Statistics;
4162 const double TopMargin =
Posterior->GetTopMargin();
4163 const int OptTitle = gStyle->GetOptTitle();
4166 gStyle->SetOptTitle(1);
4171 const int N_Coeffs = std::min(10000,
nEntries);
4172 const int start = -(N_Coeffs/2-1);
4173 const int end = N_Coeffs/2-1;
4174 const int v_size = end - start;
4180 std::vector<std::vector<float>> k_j(nPrams, std::vector<float>(v_size, 0.0));
4181 std::vector<std::vector<float>> P_j(nPrams, std::vector<float>(v_size, 0.0));
4184 if (_N % 2 != 0) _N -= 1;
4187 const double two_pi_over_N = 2 * TMath::Pi() /
static_cast<double>(_N);
4191 #pragma omp parallel for collapse(2)
4194 for (
int j = 0; j < nPrams; ++j)
4196 for (
int jj = start; jj < end; ++jj)
4198 std::complex<M3::float_t> a_j = 0.0;
4199 const double two_pi_over_N_jj = two_pi_over_N * jj;
4200 for (
int n = 0; n < _N; ++n)
4203 std::complex<M3::float_t> exp_temp(0, two_pi_over_N_jj * n);
4204 a_j +=
ParStep[j][n] * std::exp(exp_temp);
4206 a_j /= std::sqrt(
float(_N));
4207 const int _c = jj - start;
4209 k_j[j][_c] = two_pi_over_N_jj;
4211 P_j[j][_c] = std::norm(a_j);
4215 TDirectory *PowerDir =
OutputFile->mkdir(
"PowerSpectrum");
4218 TVectorD* PowerSpectrumStepSize =
new TVectorD(nPrams);
4219 for (
int j = 0; j < nPrams; ++j)
4221 auto plot = std::make_unique<TGraph>(v_size, k_j[j].data(), P_j[j].data());
4224 double Prior = 1.0, PriorError = 1.0;
4227 std::string name = Form(
"Power Spectrum of %s;k;P(k)", Title.Data());
4229 plot->SetTitle(name.c_str());
4230 name = Form(
"%s_power_spectrum", Title.Data());
4231 plot->SetName(name.c_str());
4232 plot->SetMarkerStyle(7);
4235 auto func = std::make_unique<TF1>(
"power_template",
"[0]*( ([1] / x)^[2] / (([1] / x)^[2] +1) )", 0.0, 1.0);
4237 func->SetParameter(0, 10.0);
4239 func->SetParameter(1, 0.1);
4241 func->SetParameter(2, 2.0);
4244 func->SetParLimits(0, 0.0, 100.0);
4245 func->SetParLimits(1, 0.001, 1.0);
4246 func->SetParLimits(2, 0.0, 5.0);
4248 plot->Fit(
"power_template",
"Rq");
4257 (*PowerSpectrumStepSize)(j) = std::sqrt(func->GetParameter(0)/float(v_size*0.5));
4260 PowerSpectrumStepSize->Write(
"PowerSpectrumStepSize");
4261 delete PowerSpectrumStepSize;
4266 MACH3LOG_INFO(
"Making Power Spectrum took {:.2f}s", clock.RealTime());
4269 gStyle->SetOptTitle(OptTitle);
4280 std::vector<double> MeanUp(
nDraw, 0.0);
4281 std::vector<double> SpectralVarianceUp(
nDraw, 0.0);
4282 std::vector<int> DenomCounterUp(
nDraw, 0);
4283 const double Threshold = 0.5 *
nSteps;
4286 constexpr
double LowerThreshold = 0;
4287 constexpr
double UpperThreshold = 1.0;
4289 constexpr
int NChecks = 100;
4290 constexpr
double Division = (UpperThreshold - LowerThreshold)/NChecks;
4292 std::vector<std::unique_ptr<TH1D>> GewekePlots(
nDraw);
4293 for (
int j = 0; j <
nDraw; ++j)
4296 double Prior = 1.0, PriorError = 1.0;
4298 std::string HistName = Form(
"%s_%s_Geweke", Title.Data(),
BranchNames[j].Data());
4299 GewekePlots[j] = std::make_unique<TH1D>(HistName.c_str(), HistName.c_str(), NChecks, 0.0, 100 * UpperThreshold);
4300 GewekePlots[j]->SetDirectory(
nullptr);
4301 GewekePlots[j]->GetXaxis()->SetTitle(
"Burn-In (%)");
4302 GewekePlots[j]->GetYaxis()->SetTitle(
"Geweke T score");
4307 #pragma omp parallel
4314 for (
int j = 0; j <
nDraw; ++j)
4321 DenomCounterUp[j]++;
4324 MeanUp[j] = MeanUp[j]/DenomCounterUp[j];
4329 #pragma omp for collapse(2)
4331 for (
int j = 0; j <
nDraw; ++j)
4337 SpectralVarianceUp[j] += (
ParStep[j][i] - MeanUp[j])*(
ParStep[j][i] - MeanUp[j]);
4346 for (
int k = 1; k < NChecks+1; ++k)
4349 std::vector<double> MeanDown(
nDraw, 0.0);
4350 std::vector<double> SpectralVarianceDown(
nDraw, 0.0);
4351 std::vector<int> DenomCounterDown(
nDraw, 0);
4353 const unsigned int ThresholsCheck = Division*k*
nSteps;
4355 for (
int j = 0; j <
nDraw; ++j)
4362 DenomCounterDown[j]++;
4365 MeanDown[j] = MeanDown[j]/DenomCounterDown[j];
4368 for (
int j = 0; j <
nDraw; ++j)
4374 SpectralVarianceDown[j] += (
ParStep[j][i] - MeanDown[j])*(
ParStep[j][i] - MeanDown[j]);
4379 for (
int j = 0; j <
nDraw; ++j)
4381 double T_score = std::fabs((MeanDown[j] - MeanUp[j])/std::sqrt(SpectralVarianceDown[j]/DenomCounterDown[j] + SpectralVarianceUp[j]/DenomCounterUp[j]));
4382 GewekePlots[j]->SetBinContent(k, T_score);
4391 TDirectory *GewekeDir =
OutputFile->mkdir(
"Geweke");
4392 for (
int j = 0; j <
nDraw; ++j)
4395 GewekePlots[j]->Write();
4397 for (
int i = 0; i <
nDraw; ++i) {
4416 auto AcceptanceProbPlot = std::make_unique<TH1D>(
"AcceptanceProbability",
"Acceptance Probability",
nEntries, 0,
nEntries);
4417 AcceptanceProbPlot->SetDirectory(
nullptr);
4418 AcceptanceProbPlot->GetXaxis()->SetTitle(
"Step");
4419 AcceptanceProbPlot->GetYaxis()->SetTitle(
"Acceptance Probability");
4421 auto BatchedAcceptanceProblot = std::make_unique<TH1D>(
"AcceptanceProbability_Batch",
"AcceptanceProbability_Batch",
nBatches, 0,
nBatches);
4422 BatchedAcceptanceProblot->SetDirectory(
nullptr);
4423 BatchedAcceptanceProblot->GetYaxis()->SetTitle(
"Acceptance Probability");
4425 for (
int i = 0; i <
nBatches; ++i) {
4429 std::stringstream ss;
4430 ss << BatchRangeLow <<
" - " << BatchRangeHigh;
4431 BatchedAcceptanceProblot->GetXaxis()->SetBinLabel(i+1, ss.str().c_str());
4435 #pragma omp parallel for
4437 for (
int i = 0; i <
nEntries; ++i) {
4442 TDirectory *probDir =
OutputFile->mkdir(
"AccProb");
4445 AcceptanceProbPlot->Write();
4446 BatchedAcceptanceProblot->Write();
4459 if (CredibleIntervals.size() != CredibleIntervalsColours.size()) {
4460 MACH3LOG_ERROR(
"size of CredibleIntervals is not equal to size of CredibleIntervalsColours");
4463 if (CredibleIntervals.size() > 1) {
4464 for (
unsigned int i = 1; i < CredibleIntervals.size(); i++) {
4465 if (CredibleIntervals[i] > CredibleIntervals[i - 1]) {
4467 MACH3LOG_ERROR(
"{:.2f} {:.2f}", CredibleIntervals[i], CredibleIntervals[i - 1]);
4477 const std::vector<Style_t>& CredibleRegionStyle,
4478 const std::vector<Color_t>& CredibleRegionColor) {
4480 if ((CredibleRegions.size() != CredibleRegionStyle.size()) || (CredibleRegionStyle.size() != CredibleRegionColor.size())) {
4481 MACH3LOG_ERROR(
"size of CredibleRegions is not equal to size of CredibleRegionStyle or CredibleRegionColor");
4484 for (
unsigned int i = 1; i < CredibleRegions.size(); i++) {
4485 if (CredibleRegions[i] > CredibleRegions[i - 1]) {
4487 MACH3LOG_ERROR(
"{:.2f} {:.2f}", CredibleRegions[i], CredibleRegions[i - 1]);
4498 auto caseInsensitiveCompare = [](
const std::string& a,
const std::string& b) {
4499 return std::equal(a.begin(), a.end(), b.begin(), b.end(),
4500 [](
char c1,
char c2) { return std::tolower(c1) == std::tolower(c2); });
4504 if (caseInsensitiveCompare(groupName, name)) {
4515 std::unordered_map<std::string, int> paramCounts;
4516 std::vector<std::string> orderedKeys;
4519 if (paramCounts[param] == 0) {
4520 orderedKeys.push_back(param);
4522 paramCounts[param]++;
4525 MACH3LOG_INFO(
"************************************************");
4530 for (
const std::string& key : orderedKeys) {
4535 MACH3LOG_INFO(
"************************************************");
4541 return std::vector<double>{Canv->GetTopMargin(), Canv->GetBottomMargin(),
4542 Canv->GetLeftMargin(), Canv->GetRightMargin()};
4552 if (margins.size() != 4) {
4556 Canv->SetTopMargin(margins[0]);
4557 Canv->SetBottomMargin(margins[1]);
4558 Canv->SetLeftMargin(margins[2]);
4559 Canv->SetRightMargin(margins[3]);
4565 Line->SetLineColor(Colour);
4566 Line->SetLineWidth(Width);
4567 Line->SetLineStyle(
Style);
4573 Legend->SetTextSize(size);
4574 Legend->SetLineColor(0);
4575 Legend->SetLineStyle(0);
4576 Legend->SetFillColor(0);
4577 Legend->SetFillStyle(0);
4578 Legend->SetBorderSize(0);
#define _MaCh3_Safe_Include_Start_
KS: Avoiding warning checking for headers.
#define _MaCh3_Safe_Include_End_
int NDParametersStartingPos
void RemoveFitter(TH1D *hist, const std::string &name)
KS: Remove fitted TF1 from hist to make comparison easier.
bool AllUnique(unsigned int *StepNumber, size_t size)
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
constexpr ELineStyle Style[NVars]
double * EffectiveSampleSize
bool isFlat(TSpline3_red *&spl)
CW: Helper function used in the constructor, tests to see if the spline is flat.
double GetSubOptimality(const std::vector< double > &EigenValues, const int TotalTarameters)
Based on .
void GetGaussian(TH1D *&hist, TF1 *gauss, double &Mean, double &Error)
CW: Fit Gaussian to posterior.
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,...
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.
std::string GetDunneKaboth(const double BayesFactor)
Convert a Bayes factor into an approximate particle-physics significance level using the Dunne–Kaboth...
_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...
TMacro YAMLtoTMacro(const YAML::Node &yaml_node, const std::string &name)
Convert a YAML node to a ROOT TMacro object.
YAML::Node TMacroToYAML(const TMacro ¯o)
KS: Convert a ROOT TMacro object to a YAML node.
void ScanParameterOrder()
Scan order of params from a different groups.
int nBatches
Number of batches for Batched Mean.
void CheckStepCut() const
Check if step cut isn't larger than highest values of step in a chain.
void GewekeDiagnostic()
Geweke Diagnostic based on the methods described by Fang (2014) and Karlsbakk (2011)....
TMatrixDSym * Correlation
Posterior Correlation Matrix.
void MakeViolin()
Make and Draw Violin.
void GetNthParameter(const int param, double &Prior, double &PriorError, TString &Title) const
Get properties of parameter by passing it number.
void Reset2DPosteriors()
Reset 2D posteriors, in case we would like to calculate in again with different BurnInCut.
void PrintInfo() const
Print info like how many params have been loaded etc.
void MakeCredibleIntervals(const std::vector< double > &CredibleIntervals={0.99, 0.90, 0.68 }, const std::vector< Color_t > &CredibleIntervalsColours={kCyan+4, kCyan-2, kCyan-10}, const bool CredibleInSigmas=false)
Make and Draw Credible intervals.
void ReadModelFile()
Read the xsec file and get the input central values and errors.
std::vector< double > GetMargins(const std::unique_ptr< TCanvas > &Canv) const
Get TCanvas margins, to be able to reset them if particular function need different margins.
M3::float_t ** ParStep
Array holding values for all parameters.
std::unique_ptr< TF1 > Gauss
Gaussian fitter.
void Initialise()
Scan chain, what parameters we have and load information from covariance matrices.
MCMCProcessor(const std::string &InputFile)
Constructs an MCMCProcessor object with the specified input file and options.
double Post2DPlotThreshold
KS: Set Threshold when to plot 2D posterior as by default we get a LOT of plots.
void AcceptanceProbabilities()
Acceptance Probability.
std::vector< std::string > ReweightNames
Name of branch used for chain reweighting.
double ** SampleValues
Holds the sample values.
void BatchedAnalysis()
Get the batched means variance estimation and variable indicating if number of batches is sensible .
void AutoCorrelation()
KS: Calculate autocorrelations supports both OpenMP and CUDA :)
TVectorD * Means_HPD
Vector with mean values using Highest Posterior Density.
std::vector< TString > SampleName_v
Vector of each systematic.
void GetBayesFactor(const std::vector< std::string > &ParName, const std::vector< std::vector< double >> &Model1Bounds, const std::vector< std::vector< double >> &Model2Bounds, const std::vector< std::vector< std::string >> &ModelNames)
Calculate Bayes factor for vector of params, and model boundaries.
double * WeightValue
Stores value of weight for each step.
std::vector< std::vector< double > > ParamCentral
Parameters central values which we are going to analyse.
std::vector< std::vector< double > > ParamErrors
Uncertainty on a single parameter.
void MakeTrianglePlot(const std::vector< std::string > &ParNames, const std::vector< double > &CredibleIntervals={0.99, 0.90, 0.68 }, const std::vector< Color_t > &CredibleIntervalsColours={kCyan+4, kCyan-2, kCyan-10}, const std::vector< double > &CredibleRegions={0.99, 0.90, 0.68}, const std::vector< Style_t > &CredibleRegionStyle={kDashed, kSolid, kDotted}, const std::vector< Color_t > &CredibleRegionColor={kGreen-3, kGreen-10, kGreen}, const bool CredibleInSigmas=false)
Make fancy triangle plot for selected parameters.
std::string OutputName
Name of output files.
std::unique_ptr< TH2D > hviolin_prior
Holds prior violin plot for all dials,.
bool GetParamFlat(const int iParam) const
Get whether param has flat prior or not.
std::vector< int > nParam
Number of parameters per type.
int GetGroup(const std::string &name) const
Number of params from a given group, for example flux.
void DrawPosterior(const int i, TDirectory *PostDir, TDirectory *PostHistDir)
Perform plot of 1d marginalised posterior with HPD etc.
std::vector< std::string > CovNamePos
Covariance matrix name position.
double DrawRange
Drawrange for SetMaximum.
std::vector< std::vector< bool > > ParamFlat
Whether Param has flat prior or not.
std::vector< YAML::Node > CovConfig
Covariance matrix config.
double ** SystValues
Holds the systs values.
virtual ~MCMCProcessor()
Destroys the MCMCProcessor object.
TVectorD * Errors
Vector with errors values using RMS.
double * AccProbBatchedAverages
Holds all accProb in batches.
void MakePostfit(const std::map< std::string, std::pair< double, double >> &Edges={})
Make 1D projection for each parameter and prepare structure.
bool useFFTAutoCorrelation
MJR: Use FFT-based autocorrelation algorithm (save time & resources)?
int GetParamIndexFromName(const std::string &Name) const
Get parameter number based on name.
void MakeCredibleRegions(const std::vector< double > &CredibleRegions={0.99, 0.90, 0.68}, const std::vector< Style_t > &CredibleRegionStyle={kDashed, kSolid, kDotted}, const std::vector< Color_t > &CredibleRegionColor={kGreen-3, kGreen-10, kGreen}, const bool CredibleInSigmas=false, const bool Draw2DPosterior=true, const bool DrawBestFit=true)
Make and Draw Credible Regions.
std::string StepCut
BurnIn Cuts.
void GetPostfit_Ind(TVectorD *&Central, TVectorD *&Errors, TVectorD *&Peaks, ParameterEnum kParam)
Or the individual post-fits.
void DrawCorrelations1D()
Draw 1D correlations which might be more helpful than looking at huge 2D Corr matrix.
void GetPostfit(TVectorD *&Central, TVectorD *&Errors, TVectorD *&Central_Gauss, TVectorD *&Errors_Gauss, TVectorD *&Peaks)
Get the post-fit results (arithmetic and Gaussian)
TVectorD * Means_Gauss
Vector with mean values using Gaussian fit.
unsigned int * StepNumber
Step number for step, important if chains were merged.
int AutoCorrLag
LagL used in AutoCorrelation.
std::unique_ptr< TCanvas > Posterior
Fancy canvas used for our beautiful plots.
TFile * OutputFile
The output file.
void ReadNDFile()
Read the ND cov file and get the input central values and errors.
void ProduceChi2(const std::string &GroupName) const
Convert posterior likelihood to Delta Chi2 used for comparison with frequentists fitter.
bool ApplySmoothing
Apply smoothing for 2D histos using root algorithm.
unsigned int UpperCut
KS: Used only for SubOptimality.
TChain * Chain
Main chain storing all steps etc.
std::string MCMCFile
Name of MCMC file.
bool ReweightPosterior
Whether to apply reweighting weight or not.
void SetLegendStyle(TLegend *Legend, const double size) const
Configures the style of a TLegend object.
std::vector< std::string > ExcludedNames
std::unique_ptr< TH1D > MakePrefit()
Prepare prefit histogram for parameter overlay plot.
std::vector< TH1D * > hpost
Holds 1D Posterior Distributions.
TVectorD * Errors_HPD_Negative
Vector with negative error (left hand side) values using Highest Posterior Density.
std::vector< std::vector< std::string > > CovPos
Covariance matrix file name position.
void DrawCorrelationsGroup(const std::unique_ptr< TH2D > &CorrMatrix) const
Produces correlation matrix but instead of giving name for each param it only give name for param gro...
void DiagMCMC()
KS: Perform MCMC diagnostic including Autocorrelation, Trace etc.
std::vector< std::string > ExcludedGroups
std::string Posterior1DCut
Cut used when making 1D Posterior distribution.
double * AccProbValues
Holds all accProb.
void FindInputFilesLegacy()
std::vector< double > GetParameterSums()
Computes the average of each parameter across all MCMC entries. Useful for autocorrelation.
void DrawCovariance()
Draw the post-fit covariances.
void SetMargins(std::unique_ptr< TCanvas > &Canv, const std::vector< double > &margins)
Set TCanvas margins to specified values.
void ParamTraces()
CW: Draw trace plots of the parameters i.e. parameter vs step.
void PrepareDiagMCMC()
CW: Prepare branches etc. for DiagMCMC.
std::unique_ptr< TH2D > hviolin
Holds violin plot for all dials.
int nDraw
Number of all parameters used in the analysis.
std::string OutputSuffix
Output file suffix useful when running over same file with different settings.
void SetupOutput()
Prepare all objects used for output.
void MakeOutputFile()
prepare output root file and canvas to which we will save EVERYTHING
bool plotBinValue
If true it will print value on each bin of covariance matrix.
TVectorD * Errors_Gauss
Vector with error values using Gaussian fit.
void CheckCredibleIntervalsOrder(const std::vector< double > &CredibleIntervals, const std::vector< Color_t > &CredibleIntervalsColours) const
Checks the order and size consistency of the CredibleIntervals and CredibleIntervalsColours vectors.
void CalculateESS(const int nLags, const std::vector< std::vector< double >> &LagL)
KS: calc Effective Sample Size.
std::vector< ParameterEnum > ParamType
Make an enum for which class this parameter belongs to so we don't have to keep string comparing.
std::vector< std::string > NDSamplesNames
virtual void LoadAdditionalInfo()
allow loading additional info for example used for oscillation parameters
TVectorD * Central_Value
Vector with central value for each parameter.
std::vector< std::string > ExcludedTypes
int nSteps
KS: For merged chains number of entries will be different from nSteps.
void CheckCredibleRegionsOrder(const std::vector< double > &CredibleRegions, const std::vector< Style_t > &CredibleRegionStyle, const std::vector< Color_t > &CredibleRegionColor)
Checks the order and size consistency of the CredibleRegions, CredibleRegionStyle,...
std::vector< int > NDSamplesBins
void MakeCovariance_MP(const bool Mute=false)
Calculate covariance by making 2D projection of each combination of parameters using multithreading.
double ** BatchedAverages
Values of batched average for every param and batch.
void DrawPostfit()
Draw the post-fit comparisons.
TString CanvasName
Name of canvas which help to save to the sample pdf.
std::vector< std::string > ParameterGroup
TVectorD * Errors_HPD
Vector with error values using Highest Posterior Density.
void AutoCorrelation_FFT()
MJR: Autocorrelation function using FFT algorithm for extra speed.
void SetTLineStyle(TLine *Line, const Color_t Colour, const Width_t Width, const ELineStyle Style) const
Configures a TLine object with the specified style parameters.
void ReadInputCovLegacy()
void GetPolarPlot(const std::vector< std::string > &ParNames)
Make funny polar plot.
std::vector< std::vector< TH2D * > > hpost2D
Holds 2D Posterior Distributions.
void ParameterEvolution(const std::vector< std::string > &Names, const std::vector< int > &NIntervals)
Make .gif of parameter evolution.
void GetCovariance(TMatrixDSym *&Cov, TMatrixDSym *&Corr)
Get the post-fit covariances and correlations.
TVectorD * Means
Vector with mean values using Arithmetic Mean.
std::vector< TString > SystName_v
Vector of each sample PDF object.
void CacheSteps()
KS:By caching each step we use multithreading.
std::vector< TString > BranchNames
std::vector< bool > ParamVaried
Is the ith parameter varied.
bool PlotFlatPrior
Whether we plot flat prior or not, we usually provide error even for flat prior params.
bool FancyPlotNames
Whether we want fancy plot names or not.
void SetStepCut(const std::string &Cuts)
Set the step cutting by string.
bool printToPDF
Will plot all plot to PDF not only to root file.
void GetSavageDickey(const std::vector< std::string > &ParName, const std::vector< double > &EvaluationPoint, const std::vector< std::vector< double >> &Bounds)
Calculate Bayes factor for point like hypothesis using SavageDickey.
std::pair< double, double > GetHistRange(const int iParam) const
Get Min/Max ranges for single parameter.
std::vector< std::vector< TString > > ParamNames
Name of parameters which we are going to analyse.
bool doDiagMCMC
Doing MCMC Diagnostic.
void ReadFDFile()
Read the FD cov file and get the input central values and errors.
void FindInputFiles()
Read the output MCMC file and find what inputs were used.
bool CacheMCMC
MCMC Chain has been cached.
std::vector< int > ParamTypeStartPos
bool MadePostfit
Sanity check if Postfit is already done to not make several times.
void PowerSpectrumAnalysis()
RC: Perform spectral analysis of MCMC .
void ScanInput()
Scan Input etc.
void BatchedMeans()
CW: Batched means, literally read from an array and chuck into TH1D.
int nEntries
KS: For merged chains number of entries will be different from nSteps.
void SavageDickeyPlot(std::unique_ptr< TH1D > &PriorHist, std::unique_ptr< TH1D > &PosteriorHist, const std::string &Title, const double EvaluationPoint) const
Produce Savage Dickey plot.
int nBranches
Number of branches in a TTree.
TVectorD * Errors_HPD_Positive
Vector with positive error (right hand side) values using Highest Posterior Density.
TMatrixDSym * Covariance
Posterior Covariance Matrix.
void MakeSubOptimality(const int NIntervals=10)
Make and Draw SubOptimality .
void MakeCovarianceYAML(const std::string &OutputYAMLFile, const std::string &MeansMethod) const
Make YAML file from post-fit covariance.
bool plotRelativeToPrior
Whether we plot relative to prior or nominal, in most cases is prior.
void MakeCovariance()
Calculate covariance by making 2D projection of each combination of parameters.
unsigned int BurnInCut
Value of burn in cut.
void SmearChain(const std::vector< std::string > &Names, const std::vector< double > &Error, const bool &SaveBranch) const
Smear chain contours.
void ReadInputCov()
CW: Read the input Covariance matrix entries. Get stuff like parameter input errors,...
Custom exception class used throughout MaCh3.
void EstimateDataTransferRate(TChain *chain, const Long64_t entry)
KS: Check what CPU you are using.
void PrintConfig(const YAML::Node &node)
KS: Print Yaml config using logger.
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.
void MaCh3Welcome()
KS: Prints welcome message with MaCh3 logo.
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.
bool CaseInsentiveMatch(std::string Text, std::string Pattern)
Matches a string against a simple wildcard Pattern using regex. Is not case sensitive.
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 MakeCorrelationMatrix(YAML::Node &root, const std::vector< double > &Values, const std::vector< double > &Errors, const std::vector< std::vector< double >> &Correlation, const std::string &OutYAMLName, const std::vector< std::string > &FancyNames={})
KS: Replace correlation matrix and tune values in YAML covariance matrix.
constexpr static const int _BAD_INT_
Default value used for int initialisation.
void AddPath(std::string &FilePath)
Prepends the MACH3 environment path to FilePath if it is not already present.
TMacro * GetConfigMacroFromChain(TDirectory *CovarianceFolder)
KS: We store configuration macros inside the chain. In the past, multiple configs were stored,...
Structure to hold reweight configuration.