15 m_parser = std::make_unique<MaCh3ArgumentParser>(
"process",
"1.0", argparse::default_arguments::help);
16 m_parser->add_description(
"Main executable responsible for different types of MCMC processing like drawing posteriors, triangle plots etc.");
18 ProcessMCMC The main application for analysing the ND280 chain.\n\
19 It prints posterior distributions after the burn-in cut and allows comparison of two or three different chains.\n\
20 Several options can be configured directly in the app, such as selection, burn-in cut, and whether to plot xsec+flux or only flux.\n\
22 Additional functionality includes:\n\
23 Produce a covariance matrix with multithreading (RAM intensive due to caching)\n\
25 Credible intervals and regions\n\
26 Calculation of Bayes factors with significance based on the Jeffreys scale\n\
28 Study of covariance matrix stability\n""");
30 .help(
"plot correlation - Same as PlotCorr option in config.")
32 m_parser->add_argument(
"--MakeCredibleIntervals")
33 .help(
"Same as MakeCredibleIntervals option in config.")
35 m_parser->add_argument(
"--CalcBayesFactor")
36 .help(
"Same as CalcBayesFactor option in config.")
38 m_parser->add_argument(
"--CalcSavageDickey")
39 .help(
"Same as CalcSavageDickey option in config.")
41 m_parser->add_argument(
"--CalcBipolarPlot")
42 .help(
"Same as CalcBipolarPlot option in config.")
44 m_parser->add_argument(
"--CalcParameterEvolution")
45 .help(
"Same as CalcParameterEvolution option in config.")
52 .help(
"MCMC chain root files and titles.\n"
53 "single chain mode: MCMC_CHAIN1\n"
54 "two chain mode : MCMC_CHAIN1 TITLE1 MCMC_CHAIN2 TITLE2\n"
55 "three chain mode : MCMC_CHAIN1 TITLE1 MCMC_CHAIN2 TITLE2 MCMC_CHAIN3 TITLE3")
56 .metavar(
"MCMC_CHAIN1 [TITLE1 MCMC_CHAIN2 TITLE2 [MCMC_CHAIN3 TITLE3]]")
67 auto mcmc_chain_args =
m_parser->get<std::vector<std::string>>(
"mcmc-chain");
69 int nargs =
static_cast<int>(mcmc_chain_args.size());
70 if (nargs != 1 && nargs !=4 && nargs != 6)
80 MACH3LOG_ERROR(
"The 'ProcessMCMC' node is not defined in the YAML configuration.");
84 if (mcmc_chain_args.size() == 1)
87 std::string filename = mcmc_chain_args[0];
91 else if (mcmc_chain_args.size() > 1)
93 for (std::size_t i = 0; i < mcmc_chain_args.size(); i += 2) {
131 std::map<std::string, std::pair<double, double>> CustomBinning;
132 if (Settings[
"CustomBinEdges"]) {
133 const YAML::Node& edges = Settings[
"CustomBinEdges"];
135 for (
const auto& node : edges) {
136 std::string key = node.first.as<std::string>();
137 auto values = node.second.as<std::vector<double>>();
139 if (values.size() == 2) {
140 CustomBinning[key] = std::make_pair(values[0], values[1]);
141 MACH3LOG_DEBUG(
"Adding custom binning {} with {:.4f}, {:.4f}", key, values[0], values[1]);
148 return CustomBinning;
162 auto Processor = std::make_unique<OscProcessor>(inputFile);
165 YAML::Node Settings = card_yaml[
"ProcessMCMC"];
167 const bool PlotCorr =
m_parser->get<
bool>(
"--corr") || GetFromManager<bool>(Settings[
"PlotCorr"],
false, __FILE__, __LINE__);
169 Processor->SetExcludedTypes(
GetFromManager<std::vector<std::string>>(Settings[
"ExcludedTypes"], {}, __FILE__, __LINE__));
170 Processor->SetExcludedNames(
GetFromManager<std::vector<std::string>>(Settings[
"ExcludedNames"], {}, __FILE__, __LINE__));
171 Processor->SetExcludedGroups(
GetFromManager<std::vector<std::string>>(Settings[
"ExcludedGroups"], {}, __FILE__, __LINE__));
174 Processor->SetPosterior1DCut(GetFromManager<std::string>(Settings[
"Posterior1DCut"],
"", __FILE__, __LINE__));
176 if(PlotCorr) Processor->SetOutputSuffix(
"_drawCorr");
178 Processor->SetPlotRelativeToPrior(GetFromManager<bool>(Settings[
"PlotRelativeToPrior"],
false, __FILE__, __LINE__));
179 Processor->SetPrintToPDF(GetFromManager<bool>(Settings[
"PrintToPDF"],
true, __FILE__, __LINE__));
182 Processor->SetPlotErrorForFlatPrior(GetFromManager<bool>(Settings[
"PlotErrorForFlatPrior"],
true, __FILE__, __LINE__));
183 Processor->SetFancyNames(GetFromManager<bool>(Settings[
"FancyNames"],
true, __FILE__, __LINE__));
184 Processor->SetPlotBinValue(GetFromManager<bool>(Settings[
"PlotBinValue"],
false, __FILE__, __LINE__));
186 Processor->SetPost2DPlotThreshold(GetFromManager<double>(Settings[
"Post2DPlotThreshold"], 0.2, __FILE__, __LINE__));
188 Processor->SetReweightNames(
GetFromManager<std::vector<std::string>>(Settings[
"WeightNames"], {
"Weight"}, __FILE__, __LINE__));
190 Processor->Initialise();
192 if(Settings[
"BurnInSteps"]) {
193 Processor->SetStepCut(Settings[
"BurnInSteps"].as<int>());
196 Processor->SetStepCut(
static_cast<int>(Processor->GetnSteps()/5));
198 if(Settings[
"MaxEntries"]) {
199 Processor->SetEntries(Get<int>(Settings[
"MaxEntries"], __FILE__, __LINE__));
201 if(Settings[
"NBins"]) {
202 Processor->SetNBins(Get<int>(Settings[
"NBins"], __FILE__, __LINE__));
204 if(Settings[
"Thinning"])
206 if(Settings[
"Thinning"][0].as<bool>()){
207 Processor->ThinMCMC(Settings[
"Thinning"][1].as<int>());
212 Processor->DrawPostfit();
214 if(
m_parser->get<
bool>(
"--MakeCredibleIntervals") || GetFromManager<bool>(Settings[
"MakeCredibleIntervals"],
true, __FILE__, __LINE__)) {
215 Processor->MakeCredibleIntervals(
GetFromManager<std::vector<double>>(Settings[
"CredibleIntervals"], {0.99, 0.90, 0.68}, __FILE__, __LINE__),
216 GetFromManager<std::vector<short int>>(Settings[
"CredibleIntervalsColours"], {436, 430, 422}, __FILE__, __LINE__),
217 GetFromManager<bool>(Settings[
"CredibleInSigmas"],
false, __FILE__, __LINE__));
219 if(
m_parser->get<
bool>(
"--CalcBayesFactor") || GetFromManager<bool>(Settings[
"CalcBayesFactor"],
true, __FILE__, __LINE__)) this->
CalcBayesFactor(Processor.get());
220 if(
m_parser->get<
bool>(
"--CalcSavageDickey") || GetFromManager<bool>(Settings[
"CalcSavageDickey"],
true, __FILE__, __LINE__)) this->
CalcSavageDickey(Processor.get());
221 if(
m_parser->get<
bool>(
"--CalcBipolarPlot") || GetFromManager<bool>(Settings[
"CalcBipolarPlot"],
false, __FILE__, __LINE__)) this->
CalcBipolarPlot(Processor.get());
222 if(
m_parser->get<
bool>(
"--CalcParameterEvolution") || GetFromManager<bool>(Settings[
"CalcParameterEvolution"],
false, __FILE__, __LINE__)) this->
CalcParameterEvolution(Processor.get());
226 Processor->SetSmoothing(GetFromManager<bool>(Settings[
"Smoothing"],
true, __FILE__, __LINE__));
229 Processor->CacheSteps();
231 if(GetFromManager<bool>(Settings[
"MakeViolin"],
true, __FILE__, __LINE__)) Processor->MakeViolin();
232 Processor->MakeCovariance_MP();
234 Processor->DrawCovariance();
235 if(GetFromManager<bool>(Settings[
"MakeCovarianceYAML"],
true, __FILE__, __LINE__)) Processor->MakeCovarianceYAML(GetFromManager<std::string>(Settings[
"CovarianceYAMLOutName"],
"UpdatedCorrelationMatrix.yaml", __FILE__, __LINE__), GetFromManager<std::string>(Settings[
"CovarianceYAMLMeansMethod"],
"HPD", __FILE__, __LINE__));
237 auto const &MakeSubOptimality = Settings[
"MakeSubOptimality"];
238 if(MakeSubOptimality[0].as<bool>()) Processor->MakeSubOptimality(MakeSubOptimality[1].as<int>());
240 if(GetFromManager<bool>(Settings[
"MakeCredibleRegions"],
false, __FILE__, __LINE__)) {
241 Processor->MakeCredibleRegions(
GetFromManager<std::vector<double>>(Settings[
"CredibleRegions"], {0.99, 0.90, 0.68}, __FILE__, __LINE__),
242 GetFromManager<std::vector<short int>>(Settings[
"CredibleRegionStyle"], {2, 1, 3}, __FILE__, __LINE__),
243 GetFromManager<std::vector<short int>>(Settings[
"CredibleRegionColor"], {413, 406, 416}, __FILE__, __LINE__),
244 GetFromManager<bool>(Settings[
"CredibleInSigmas"],
false, __FILE__, __LINE__),
245 GetFromManager<bool>(Settings[
"Draw2DPosterior"],
true, __FILE__, __LINE__),
246 GetFromManager<bool>(Settings[
"DrawBestFit"],
true, __FILE__, __LINE__));
248 if(GetFromManager<bool>(Settings[
"GetTrianglePlot"],
true, __FILE__, __LINE__)) this->
GetTrianglePlot(Processor.get());
251 if(GetFromManager<bool>(Settings[
"DiagnoseCovarianceMatrix"],
false, __FILE__, __LINE__)) this->
DiagnoseCovarianceMatrix(Processor.get(), inputFile);
253 Processor->ProduceChi2(GetFromManager<std::string>(Settings[
"Chi2Group"],
"Osc", __FILE__, __LINE__));
254 if(GetFromManager<bool>(Settings[
"JarlskogAnalysis"],
true, __FILE__, __LINE__)) Processor->PerformJarlskogAnalysis();
255 if(GetFromManager<bool>(Settings[
"ProducePMNSElements"],
true, __FILE__, __LINE__)) Processor->ProducePMNSElements();
256 if(GetFromManager<bool>(Settings[
"ProduceUnitarityTriangles"],
true, __FILE__, __LINE__)) Processor->ProduceUnitarityTriangles();
257 if(GetFromManager<bool>(Settings[
"MakePiePlot"],
true, __FILE__, __LINE__)) Processor->MakePiePlot();
268 YAML::Node Settings = card_yaml[
"ProcessMCMC"];
270 constexpr Color_t PosteriorColor[] = {kBlue-1, kRed, kGreen+2};
273 std::vector<std::unique_ptr<MCMCProcessor>> Processor(
nFiles);
275 if(!Settings[
"BurnInSteps"]) {
279 for (
int ik = 0; ik <
nFiles; ik++)
283 Processor[ik] = std::make_unique<MCMCProcessor>(
FileNames[ik]);
284 Processor[ik]->SetOutputSuffix((
"_" + std::to_string(ik)).c_str());
286 Processor[ik]->SetExcludedTypes(
GetFromManager<std::vector<std::string>>(Settings[
"ExcludedTypes"], {}, __FILE__, __LINE__));
287 Processor[ik]->SetExcludedNames(
GetFromManager<std::vector<std::string>>(Settings[
"ExcludedNames"], {}, __FILE__, __LINE__));
288 Processor[ik]->SetExcludedGroups(
GetFromManager<std::vector<std::string>>(Settings[
"ExcludedGroups"], {}, __FILE__, __LINE__));
291 Processor[ik]->SetPosterior1DCut(GetFromManager<std::string>(Settings[
"Posterior1DCut"],
"", __FILE__, __LINE__));
293 Processor[ik]->SetPlotRelativeToPrior(GetFromManager<bool>(Settings[
"PlotRelativeToPrior"],
false, __FILE__, __LINE__));
294 Processor[ik]->SetFancyNames(GetFromManager<bool>(Settings[
"FancyNames"],
true, __FILE__, __LINE__));
297 Processor[ik]->SetReweightNames(
GetFromManager<std::vector<std::string>>(Settings[
"WeightNames"], {
"Weight"}, __FILE__, __LINE__));
298 Processor[ik]->Initialise();
300 if(Settings[
"BurnInSteps"]) {
301 Processor[ik]->SetStepCut(Settings[
"BurnInSteps"].as<int>());
303 Processor[ik]->SetStepCut(
static_cast<int>(Processor[ik]->GetnSteps()/5));
306 if(Settings[
"MaxEntries"]) {
307 Processor[ik]->SetEntries(Get<int>(Settings[
"MaxEntries"], __FILE__, __LINE__));
309 if(Settings[
"NBins"]) {
310 Processor[ik]->SetNBins(Get<int>(Settings[
"NBins"], __FILE__, __LINE__));
315 Processor[0]->DrawPostfit();
317 std::map<std::string, std::pair<double, double>> ParamEdges;
318 for(
int i = 0; i < Processor[0]->GetNParams(); ++i) {
320 TH1D* hist = Processor[0]->GetHpost(i);
327 std::string paramName = hist->GetTitle();
330 TAxis* axis = hist->GetXaxis();
331 double xmin = axis->GetXmin();
332 double xmax = axis->GetXmax();
334 MACH3LOG_DEBUG(
"Adding bin edges for {} equal to {:.4f}, {:.4f}",paramName, xmin, xmax);
336 ParamEdges[paramName] = std::make_pair(xmin, xmax);
340 for (
int ik = 1; ik <
nFiles; ik++)
343 Processor[ik]->MakePostfit(ParamEdges);
344 Processor[ik]->DrawPostfit();
348 auto Posterior = std::make_unique<TCanvas>(
"PosteriorMulti",
"PosteriorMulti", 0, 0, 1024, 1024);
349 gStyle->SetOptStat(0);
350 gStyle->SetOptTitle(0);
351 Posterior->SetGrid();
352 Posterior->SetBottomMargin(0.1f);
353 Posterior->SetTopMargin(0.05f);
354 Posterior->SetRightMargin(0.03f);
355 Posterior->SetLeftMargin(0.15f);
359 size_t pos =
FileNames[0].rfind(
".root");
360 std::string base = (pos == std::string::npos) ?
FileNames[0] :
FileNames[0].substr(0, pos);
361 TString canvasname = base;
365 for (
int ik = 1; ik <
nFiles; ik++) {
368 pos = base.rfind(
".root");
369 if (pos != std::string::npos) base = base.substr(0, pos);
370 canvasname +=
"_" + TString(base);
373 canvasname = canvasname +
".pdf[";
375 Posterior->Print(canvasname);
377 canvasname.ReplaceAll(
"[",
"");
379 for(
int i = 0; i < Processor[0]->GetNParams(); ++i)
382 std::vector<std::unique_ptr<TH1D>> hpost(
nFiles);
383 std::vector<std::unique_ptr<TLine>> hpd(
nFiles);
384 hpost[0] =
M3::Clone(Processor[0]->GetHpost(i));
385 hpost[0]->GetYaxis()->SetTitle(
"Posterior Density");
387 for (
int ik = 1 ; ik <
nFiles; ik++)
390 const int Index = Processor[ik]->GetParamIndexFromName(hpost[0]->GetTitle());
396 hpost[ik] =
M3::Clone(Processor[ik]->GetHpost(Index));
400 if(hpost[0]->GetMaximum() == hpost[0]->Integral()*1.5 || Skip) {
403 for (
int ik = 0; ik <
nFiles; ik++)
408 hpost[ik]->SetLineColor(PosteriorColor[ik]);
410 hpost[ik]->SetLineWidth(2);
413 hpost[ik]->Scale(1./hpost[ik]->Integral());
417 double PriorError = 1.0;
419 Processor[0]->GetNthParameter(i, Prior, PriorError, Title);
422 auto Asimov = std::make_unique<TLine>(Prior, hpost[0]->GetMinimum(), Prior, hpost[0]->GetMaximum());
423 Asimov->SetLineColor(kRed-3);
424 Asimov->SetLineWidth(2);
425 Asimov->SetLineStyle(kDashed);
428 auto leg = std::make_unique<TLegend>(0.20, 0.7, 0.6, 0.97);
429 leg->SetTextSize(0.03f);
430 leg->SetFillColor(0);
431 leg->SetFillStyle(0);
432 leg->SetLineColor(0);
433 leg->SetLineStyle(0);
434 TString asimovLeg = Form(
"#splitline{Prior}{x = %.2f , #sigma = %.2f}", Prior, PriorError);
435 leg->AddEntry(Asimov.get(), asimovLeg,
"l");
437 for (
int ik = 0; ik <
nFiles; ik++)
439 TString rebinLeg = Form(
"#splitline{%s}{#mu = %.2f, #sigma = %.2f}",
TitleNames[ik].c_str(), hpost[ik]->GetMean(), hpost[ik]->GetRMS());
440 leg->AddEntry(hpost[ik].get(), rebinLeg,
"l");
442 hpd[ik] = std::make_unique<TLine>(hpost[ik]->GetBinCenter(hpost[ik]->GetMaximumBin()), hpost[ik]->GetMinimum(),
443 hpost[ik]->GetBinCenter(hpost[ik]->GetMaximumBin()), hpost[ik]->GetMaximum());
444 hpd[ik]->SetLineColor(hpost[ik]->GetLineColor());
445 hpd[ik]->SetLineWidth(2);
446 hpd[ik]->SetLineStyle(kSolid);
451 for (
int ik = 0; ik <
nFiles; ik++) maximum = std::max(maximum, hpost[ik]->GetMaximum());
452 for (
int ik = 0; ik <
nFiles; ik++) hpost[ik]->SetMaximum(1.3*maximum);
454 hpost[0]->Draw(
"hist");
455 for (
int ik = 1; ik <
nFiles; ik++) hpost[ik]->Draw(
"hist same");
456 Asimov->Draw(
"same");
457 for (
int ik = 0; ik <
nFiles; ik++) hpd[ik]->Draw(
"same");
460 Posterior->Print(canvasname);
468 if(GetFromManager<bool>(Settings[
"PerformKStest"],
true, __FILE__, __LINE__)) this->
KolmogorovSmirnovTest(Processor, Posterior, canvasname);
473 Posterior->Print(canvasname);
486 YAML::Node Settings = card_yaml[
"ProcessMCMC"];
488 std::vector<std::string> ParNames;
489 std::vector<std::vector<double>> Model1Bounds;
490 std::vector<std::vector<double>> Model2Bounds;
491 std::vector<std::vector<std::string>> ModelNames;
492 for (
const auto& dg : Settings[
"BayesFactor"])
494 ParNames.push_back(dg[0].as<std::string>());
495 ModelNames.push_back(dg[1].as<std::vector<std::string>>());
496 Model1Bounds.push_back(dg[2].as<std::vector<double>>());
497 Model2Bounds.push_back(dg[3].as<std::vector<double>>());
500 Processor->
GetBayesFactor(ParNames, Model1Bounds, Model2Bounds, ModelNames);
513 YAML::Node Settings = card_yaml[
"ProcessMCMC"];
515 std::vector<std::string> ParNames;
516 std::vector<double> EvaluationPoint;
517 std::vector<std::vector<double>> Bounds;
519 for (
const auto& d : Settings[
"SavageDickey"])
521 ParNames.push_back(d[0].as<std::string>());
522 EvaluationPoint.push_back(d[1].as<double>());
523 Bounds.push_back(d[2].as<std::vector<double>>());
538 YAML::Node Settings = card_yaml[
"ProcessMCMC"];
540 std::vector<std::string> ParNames;
541 std::vector<int> Intervals;
542 for (
const auto& d : Settings[
"ParameterEvolution"])
544 ParNames.push_back(d[0].as<std::string>());
545 Intervals.push_back(d[1].as<int>());
560 YAML::Node Settings = card_yaml[
"ProcessMCMC"];
562 std::vector<std::string> ParNames;
563 for (
const auto& d : Settings[
"BipolarPlot"])
565 ParNames.push_back(d[0].as<std::string>());
579 YAML::Node Settings = card_yaml[
"ProcessMCMC"];
581 for (
const auto& dg : Settings[
"TrianglePlot"])
583 std::string ParName = dg[0].as<std::string>();
585 std::vector<std::string> NameVec = dg[1].as<std::vector<std::string>>();
587 GetFromManager<std::vector<double>>(Settings[
"CredibleIntervals"], {0.99, 0.90, 0.68}, __FILE__, __LINE__),
588 GetFromManager<std::vector<short int>>(Settings[
"CredibleIntervalsColours"], {436, 430, 422}, __FILE__, __LINE__),
589 GetFromManager<std::vector<double>>(Settings[
"CredibleRegions"], {0.99, 0.90, 0.68}, __FILE__, __LINE__),
590 GetFromManager<std::vector<short int>>(Settings[
"CredibleRegionStyle"], {2, 1, 3}, __FILE__, __LINE__),
591 GetFromManager<std::vector<short int>>(Settings[
"CredibleRegionColor"], {413, 406, 416}, __FILE__, __LINE__),
592 GetFromManager<bool>(Settings[
"CredibleInSigmas"],
false, __FILE__, __LINE__));
609 auto Canvas = std::make_unique<TCanvas>(
"Canvas",
"Canvas", 0, 0, 1024, 1024);
611 gStyle->SetOptStat(0);
612 gStyle->SetOptTitle(0);
615 Canvas->SetBottomMargin(0.1f);
616 Canvas->SetTopMargin(0.05f);
617 Canvas->SetRightMargin(0.15f);
618 Canvas->SetLeftMargin(0.10f);
621 const int NRGBs = 10;
622 TColor::InitializeColors();
623 Double_t stops[NRGBs] = { 0.00, 0.10, 0.25, 0.35, 0.50, 0.60, 0.65, 0.75, 0.90, 1.00 };
624 Double_t red[NRGBs] = { 0.50, 1.00, 1.00, 0.25, 0.00, 0.10, 0.50, 1.00, 0.75, 0.55 };
625 Double_t green[NRGBs] = { 0.00, 0.25, 1.00, 0.25, 0.00, 0.60, 0.90, 1.00, 0.75, 0.75 };
626 Double_t blue[NRGBs] = { 0.00, 0.25, 1.00, 1.00, 0.50, 0.60, 0.90, 1.00, 0.05, 0.05 };
627 TColor::CreateGradientColorTable(NRGBs, stops, red, green, blue, 255);
628 gStyle->SetNumberContours(255);
630 std::string OutName = inputFile;
631 OutName = OutName.substr(0, OutName.find(
".root"));
632 Canvas->Print(Form(
"Correlation_%s.pdf[", OutName.c_str()),
"pdf");
633 Canvas->Print(Form(
"Covariance_%s.pdf[", OutName.c_str()),
"pdf");
636 YAML::Node Settings = card_yaml[
"ProcessMCMC"];
638 const int entries = int(Processor->
GetnSteps());
639 const int NIntervals = GetFromManager<int>(Settings[
"NIntervals"], 5, __FILE__, __LINE__);
640 const int IntervalsSize = entries/NIntervals;
643 MACH3LOG_INFO(
"Diagnosing matrices with entries={}, NIntervals={} and IntervalsSize={}", entries, NIntervals, IntervalsSize);
645 TMatrixDSym *Covariance =
nullptr;
646 TMatrixDSym *Correlation =
nullptr;
648 TH2D *CovariancePreviousHist =
nullptr;
649 TH2D *CorrelationPreviousHist =
nullptr;
651 TH2D *CovarianceHist =
nullptr;
652 TH2D *CorrelationHist =
nullptr;
658 CovariancePreviousHist = this->
TMatrixIntoTH2D(Covariance,
"Covariance");
659 CorrelationPreviousHist = this->
TMatrixIntoTH2D(Correlation,
"Correlation");
662 Covariance =
nullptr;
664 Correlation =
nullptr;
667 for(
int k = 1; k < NIntervals; ++k)
669 BurnIn = k*IntervalsSize;
677 TH2D *CovarianceDiff =
static_cast<TH2D*
>(CovarianceHist->Clone(
"Covariance_Ratio"));
678 TH2D *CorrelationDiff =
static_cast<TH2D*
>(CorrelationHist->Clone(
"Correlation_Ratio"));
682 #pragma omp parallel for
684 for (
int j = 1; j < CovarianceDiff->GetXaxis()->GetNbins()+1; ++j)
686 for (
int i = 1; i < CovarianceDiff->GetYaxis()->GetNbins()+1; ++i)
688 if( std::fabs (CovarianceDiff->GetBinContent(j, i)) < 1.e-5 && std::fabs (CovariancePreviousHist->GetBinContent(j, i)) < 1.e-5)
693 if( std::fabs (CorrelationDiff->GetBinContent(j, i)) < 1.e-5 && std::fabs (CorrelationPreviousHist->GetBinContent(j, i)) < 1.e-5)
701 CovarianceDiff->Divide(CovariancePreviousHist);
702 CorrelationDiff->Divide(CorrelationPreviousHist);
705 for (
int j = 0; j < CovarianceDiff->GetXaxis()->GetNbins(); ++j)
709 double PriorError = 1.0;
713 CovarianceDiff->GetXaxis()->SetBinLabel(j+1, Title);
714 CovarianceDiff->GetYaxis()->SetBinLabel(j+1, Title);
715 CorrelationDiff->GetXaxis()->SetBinLabel(j+1, Title);
716 CorrelationDiff->GetYaxis()->SetBinLabel(j+1, Title);
718 CovarianceDiff->GetXaxis()->SetLabelSize(0.015f);
719 CovarianceDiff->GetYaxis()->SetLabelSize(0.015f);
720 CorrelationDiff->GetXaxis()->SetLabelSize(0.015f);
721 CorrelationDiff->GetYaxis()->SetLabelSize(0.015f);
723 std::stringstream ss;
728 ss << (k-1)*IntervalsSize;
729 std::string str = ss.str();
731 TString Title =
"Cov " + str;
732 CovarianceDiff->GetZaxis()->SetTitle( Title );
733 Title =
"Corr " + str;
734 CorrelationDiff->GetZaxis()->SetTitle(Title);
736 CovarianceDiff->SetMinimum(-2);
737 CovarianceDiff->SetMaximum(2);
738 CorrelationDiff->SetMinimum(-2);
739 CorrelationDiff->SetMaximum(2);
742 CovarianceDiff->Draw(
"colz");
743 Canvas->Print(Form(
"Covariance_%s.pdf", OutName.c_str()),
"pdf");
745 CorrelationDiff->Draw(
"colz");
746 Canvas->Print(Form(
"Correlation_%s.pdf", OutName.c_str()),
"pdf");
749 delete CovariancePreviousHist;
750 CovariancePreviousHist =
static_cast<TH2D*
>(CovarianceHist->Clone());
751 delete CorrelationPreviousHist;
752 CorrelationPreviousHist =
static_cast<TH2D*
>(CorrelationHist->Clone());
754 delete CovarianceHist;
755 CovarianceHist =
nullptr;
756 delete CorrelationHist;
757 CorrelationHist =
nullptr;
759 delete CovarianceDiff;
760 delete CorrelationDiff;
762 Covariance =
nullptr;
764 Correlation =
nullptr;
767 Canvas->Print(Form(
"Covariance_%s.pdf]", OutName.c_str()),
"pdf");
768 Canvas->Print(Form(
"Correlation_%s.pdf]", OutName.c_str()),
"pdf");
771 if(Covariance !=
nullptr)
delete Covariance;
772 if(Correlation !=
nullptr)
delete Correlation;
773 if(CovariancePreviousHist !=
nullptr)
delete CovariancePreviousHist;
774 if(CorrelationPreviousHist !=
nullptr)
delete CorrelationPreviousHist;
775 if(CovarianceHist !=
nullptr)
delete CovarianceHist;
776 if(CorrelationHist !=
nullptr)
delete CorrelationHist;
789 TH2D* hMatrix =
new TH2D(title.c_str(), title.c_str(), Matrix->GetNrows(), 0.0, Matrix->GetNrows(), Matrix->GetNcols(), 0.0, Matrix->GetNcols());
790 for(
int i = 0; i < Matrix->GetNrows(); i++)
792 for(
int j = 0; j < Matrix->GetNcols(); j++)
795 hMatrix->SetBinContent(i+1,j+1, (*Matrix)(i,j));
811 const std::unique_ptr<TCanvas>& Posterior,
812 const TString& canvasname)
814 constexpr Color_t CumulativeColor[] = {kBlue-1, kRed, kGreen+2};
815 constexpr Style_t CumulativeStyle[] = {kSolid, kDashed, kDotted};
817 for(
int i = 0; i < Processor[0]->GetNParams(); ++i)
820 std::vector<std::unique_ptr<TH1D>> hpost(
nFiles);
821 std::vector<std::unique_ptr<TH1D>> CumulativeDistribution(
nFiles);
825 double PriorError = 1.0;
827 Processor[0]->GetNthParameter(i, Prior, PriorError, Title);
829 for (
int ik = 0 ; ik <
nFiles; ik++)
832 if(ik == 0 ) Index = i;
836 Index = Processor[ik]->GetParamIndexFromName(hpost[0]->GetTitle());
843 hpost[ik] =
M3::Clone(Processor[ik]->GetHpost(Index));
844 CumulativeDistribution[ik] =
M3::Clone(Processor[ik]->GetHpost(Index));
845 CumulativeDistribution[ik]->Fill(0., 0.);
846 CumulativeDistribution[ik]->Reset();
847 CumulativeDistribution[ik]->SetMaximum(1.);
848 TString TempTitle = Title+
" Kolmogorov Smirnov";
849 CumulativeDistribution[ik]->SetTitle(TempTitle);
851 TempTitle = Title+
" Value";
852 CumulativeDistribution[ik]->GetXaxis()->SetTitle(TempTitle);
853 CumulativeDistribution[ik]->GetYaxis()->SetTitle(
"Cumulative Probability");
855 CumulativeDistribution[ik]->SetLineWidth(2);
856 CumulativeDistribution[ik]->SetLineColor(CumulativeColor[ik]);
857 CumulativeDistribution[ik]->SetLineStyle(CumulativeStyle[ik]);
861 if(hpost[0]->GetMaximum() == hpost[0]->Integral()*1.5 || Skip) {
865 for (
int ik = 0 ; ik <
nFiles; ik++)
867 const int NumberOfBins = hpost[ik]->GetXaxis()->GetNbins();
868 double Cumulative = 0;
869 const double Integral = hpost[ik]->Integral();
870 for (
int j = 1; j < NumberOfBins+1; ++j)
872 Cumulative += hpost[ik]->GetBinContent(j)/Integral;
873 CumulativeDistribution[ik]->SetBinContent(j, Cumulative);
876 CumulativeDistribution[ik]->SetBinContent(NumberOfBins+1, 1.);
879 std::vector<int> TestStatBin(
nFiles, 0);
880 std::vector<double> TestStatD(
nFiles, -999);
881 std::vector<std::unique_ptr<TLine>> LineD(
nFiles);
883 for (
int ik = 1 ; ik <
nFiles; ik++)
885 const int NumberOfBins = CumulativeDistribution[0]->GetXaxis()->GetNbins();
886 for (
int j = 1; j < NumberOfBins+1; ++j)
888 const double BinValue = CumulativeDistribution[0]->GetBinCenter(j);
889 const int BinNumber = CumulativeDistribution[ik]->FindBin(BinValue);
891 double TempDstat = std::fabs(CumulativeDistribution[0]->GetBinContent(j) - CumulativeDistribution[ik]->GetBinContent(BinNumber));
892 if(TempDstat > TestStatD[ik])
894 TestStatD[ik] = TempDstat;
900 for (
int ik = 0 ; ik <
nFiles; ik++)
902 LineD[ik] = std::make_unique<TLine>(CumulativeDistribution[0]->GetBinCenter(TestStatBin[ik]), 0, CumulativeDistribution[0]->GetBinCenter(TestStatBin[ik]), CumulativeDistribution[0]->GetBinContent(TestStatBin[ik]));
903 LineD[ik]->SetLineColor(CumulativeColor[ik]);
904 LineD[ik]->SetLineWidth(2.0);
906 CumulativeDistribution[0]->Draw();
907 for (
int ik = 0 ; ik <
nFiles; ik++)
908 CumulativeDistribution[ik]->Draw(
"SAME");
910 auto leg = std::make_unique<TLegend>(0.15, 0.7, 0.5, 0.90);
911 leg->SetTextSize(0.04f);
912 for (
int ik = 0; ik <
nFiles; ik++)
913 leg->AddEntry(CumulativeDistribution[ik].get(),
TitleNames[ik].c_str(),
"l");
914 for (
int ik = 1; ik <
nFiles; ik++)
915 leg->AddEntry(LineD[ik].get(), Form(
"#Delta D = %.4f", TestStatD[ik]),
"l");
917 leg->SetLineColor(0);
918 leg->SetLineStyle(0);
919 leg->SetFillColor(0);
920 leg->SetFillStyle(0);
923 for (
int ik = 1; ik <
nFiles; ik++)
924 LineD[ik]->Draw(
"sam");
927 Posterior->Print(canvasname);
void RemoveFitter(TH1D *hist, const std::string &name)
KS: Remove fitted TF1 from hist to make comparison easier.
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
Module for processing MCMC chains and producing diagnostic plots.
Type GetFromManager(const YAML::Node &node, const Type defval, const std::string &File, const int Line)
Get content of config file if node is not found take default value specified.
bool CheckNodeExists(const YAML::Node &node, Args... args)
KS: Wrapper function to call the recursive helper.
#define M3OpenConfig(filename)
Macro to simplify calling LoadYaml with file and line info.
Extended ArgumentParser with MaCh3-specific functionality.
std::unique_ptr< MaCh3ArgumentParser > m_parser
Argument parser for this plugin.
virtual ~ProcessMCMCModule()
Destructor.
void CalcBipolarPlot(MCMCProcessor *Processor)
Create bipolar plots for parameter visualization.
std::vector< std::string > FileNames
List of MCMC chain file paths.
std::map< std::string, std::pair< double, double > > GetCustomBinning(const YAML::Node &Settings)
Parse custom binning edges from YAML configuration.
void CalcSavageDickey(MCMCProcessor *Processor)
Calculate Savage-Dickey ratios for Bayes factor estimation.
void CalcParameterEvolution(MCMCProcessor *Processor)
Calculate parameter evolution over MCMC steps.
void CalcBayesFactor(MCMCProcessor *Processor)
Calculate Bayes factors for hypothesis testing.
std::string config
Path to the configuration file.
void GetTrianglePlot(MCMCProcessor *Processor)
Generate triangle plots showing parameter correlations.
void DiagnoseCovarianceMatrix(MCMCProcessor *Processor, const std::string &inputFile)
Diagnose covariance matrix stability across burn-in cuts.
MaCh3ArgumentParser * get_parser() override
Get the argument parser for this module.
std::vector< std::string > TitleNames
List of titles for each chain.
TH2D * TMatrixIntoTH2D(TMatrixDSym *Matrix, const std::string &title)
Convert TMatrixDSym to TH2D histogram for plotting.
void ProcessMCMC(const std::string &inputFile)
Process a single MCMC chain.
void KolmogorovSmirnovTest(const std::vector< std::unique_ptr< MCMCProcessor >> &Processor, const std::unique_ptr< TCanvas > &Posterior, const TString &canvasname)
Perform Kolmogorov-Smirnov test between posterior distributions.
int Run() override
Execute the MCMC processing.
int nFiles
Number of MCMC files being processed.
void MultipleProcessMCMC()
Compare and process multiple MCMC chains.
Class responsible for processing MCMC chains, performing diagnostics, generating plots,...
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 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.
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.
void SetPrintToPDF(const bool PlotOrNot)
Whether to dump all plots into PDF.
Long64_t GetnSteps()
Get Number of Steps that Chain has, for merged chains will not be the same nEntries.
void GetPolarPlot(const std::vector< std::string > &ParNames)
Make funny polar plot.
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.
void SetStepCut(const std::string &Cuts)
Set the step cutting by string.
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.
Custom exception class used throughout MaCh3.
Main namespace for MaCh3 software.
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.
constexpr static const int _BAD_INT_
Default value used for int initialisation.