17 FullLLH = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"FullLLH"],
false, __FILE__, __LINE__ );
21 Ntoys = Get<int>(
fitMan->
raw()[
"Predictive"][
"Ntoy"], __FILE__, __LINE__);
38 auto DoNotThrowLegacyCov = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"Predictive"][
"DoNotThrowLegacyCov"], {}, __FILE__, __LINE__);
40 for (
size_t i = 0; i < DoNotThrowLegacyCov.size(); ++i) {
69 for (
size_t iPDF = 0; iPDF <
samples.size(); iPDF++)
93 for (
size_t iPDF = 0; iPDF <
samples.size(); iPDF++) {
94 for (
int SampleIndex = 0; SampleIndex <
samples[iPDF]->GetNsamples(); ++SampleIndex) {
122 MACH3LOG_INFO(
"You've chosen to run Prior Predictive Distribution");
124 auto PosteriorFileName = Get<std::string>(
fitMan->
raw()[
"Predictive"][
"PosteriorFile"], __FILE__, __LINE__);
130 auto AllowDifferentConfigs = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"AllowDifferentConfigs"],
false, __FILE__, __LINE__);
138 if(AllowDifferentConfigs){
139 MACH3LOG_WARN(
"Yaml configs used for your ParameterHandler for chain you want sample from ({}) and one currently initialised are different", PosteriorFileName);
141 MACH3LOG_ERROR(
"Yaml configs used for your ParameterHandler for chain you want sample from ({}) and one currently initialised are different", PosteriorFileName);
148 MACH3LOG_ERROR(
"Found {} ParmaterHandler inheriting from ParameterHandlerGeneric, I can accept at most 1", counter);
157 auto ThrowParamGroupOnly = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"Predictive"][
"ThrowParamGroupOnly"], {}, __FILE__, __LINE__);
159 auto ParameterOnlyToVaryString = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"Predictive"][
"ThrowSinlgeParams"], {}, __FILE__, __LINE__);
161 if (!ThrowParamGroupOnly.empty() && !ParameterOnlyToVaryString.empty()) {
162 MACH3LOG_ERROR(
"Can't use ThrowParamGroupOnly and ThrowSinlgeParams at the same time");
166 if (!ParameterOnlyToVaryString.empty()) {
167 MACH3LOG_INFO(
"I will throw only: {}", fmt::join(ParameterOnlyToVaryString,
", "));
168 std::vector<int> ParameterVary(ParameterOnlyToVaryString.size());
170 for (
size_t i = 0; i < ParameterOnlyToVaryString.size(); ++i) {
173 MACH3LOG_ERROR(
"Can't proceed if param {} is missing", ParameterOnlyToVaryString[i]);
179 MACH3LOG_INFO(
"I have following parameter groups: {}", fmt::join(UniqueParamGroup,
", "));
180 if (ThrowParamGroupOnly.empty()) {
183 std::unordered_set<std::string> throwOnlySet(ThrowParamGroupOnly.begin(), ThrowParamGroupOnly.end());
186 for (
const auto& group : UniqueParamGroup) {
187 if (throwOnlySet.find(group) == throwOnlySet.end()) {
192 MACH3LOG_INFO(
"I will vary: {}", fmt::join(ThrowParamGroupOnly,
", "));
203 auto PosteriorFileName = Get<std::string>(
fitMan->
raw()[
"Predictive"][
"PosteriorFile"], __FILE__, __LINE__);
205 int originalErrorWarning = gErrorIgnoreLevel;
206 gErrorIgnoreLevel = kFatal;
207 TFile* file =
TFile::Open(PosteriorFileName.c_str(),
"READ");
209 gErrorIgnoreLevel = originalErrorWarning;
210 TDirectory* ToyDir =
nullptr;
211 if (!file || file->IsZombie()) {
215 if ((ToyDir = file->GetDirectory(
"Toys"))) {
216 MACH3LOG_INFO(
"Found toys in Posterior file will attempt toy reading");
225 TTree* PenaltyTree =
static_cast<TTree*
>(file->Get(
"ToySummary"));
233 Ntoys =
static_cast<int>(PenaltyTree->GetEntries());
234 int ConfigNtoys = Get<int>(
fitMan->
raw()[
"Predictive"][
"Ntoy"], __FILE__, __LINE__);;
235 if (
Ntoys != ConfigNtoys) {
236 MACH3LOG_WARN(
"Found different number of toys in saved file than asked to run!");
245 double Penalty = 0, Weight = 1;
246 PenaltyTree->SetBranchAddress(
"Penalty", &Penalty);
247 PenaltyTree->SetBranchAddress(
"Weight", &Weight);
248 PenaltyTree->SetBranchAddress(
"NModelParams", &
NModelParams);
250 for (
int i = 0; i <
Ntoys; ++i) {
251 PenaltyTree->GetEntry(i);
264 TH1* DataHist1D =
static_cast<TH1*
>(ToyDir->Get((
SampleInfo[sample].Name +
"_data").c_str()));
267 TH1* MCHist1D =
static_cast<TH1*
>(ToyDir->Get((
SampleInfo[sample].Name +
"_mc").c_str()));
270 TH1* W2Hist1D =
static_cast<TH1*
>(ToyDir->Get((
SampleInfo[sample].Name +
"_w2").c_str()));
275 for (
int iToy = 0; iToy <
Ntoys; ++iToy)
280 TH1* MCHist1D =
static_cast<TH1*
>(ToyDir->Get((
SampleInfo[sample].Name +
"_mc_" + std::to_string(iToy)).c_str()));
281 TH1* W2Hist1D =
static_cast<TH1*
>(ToyDir->Get((
SampleInfo[sample].Name +
"_w2_" + std::to_string(iToy)).c_str()));
296 TDirectory * ogdir = gDirectory;
298 std::vector<std::string> FancyNames;
299 std::string Name = std::string(
"Config_") + Systematics->
GetName();
300 auto PosteriorFileName = Get<std::string>(
fitMan->
raw()[
"Predictive"][
"PosteriorFile"], __FILE__, __LINE__);
302 TFile* file =
TFile::Open(PosteriorFileName.c_str(),
"READ");
303 TDirectory* CovarianceFolder = file->GetDirectory(
"CovarianceFolder");
305 TMacro* FoundMacro =
static_cast<TMacro*
>(CovarianceFolder->Get(Name.c_str()));
306 if(FoundMacro ==
nullptr) {
309 if(ogdir){ ogdir->cd(); }
316 int params = int(Settings[
"Systematics"].size());
317 FancyNames.resize(params);
319 for (
auto const ¶m : Settings[
"Systematics"]) {
320 FancyNames[iPar] = Get<std::string>(param[
"Systematic"][
"Names"][
"FancyName"], __FILE__ , __LINE__);
325 if(ogdir){ ogdir->cd(); }
339 auto PosteriorFileName = Get<std::string>(
fitMan->
raw()[
"Predictive"][
"PosteriorFile"], __FILE__, __LINE__);
344 double Penalty = 0, Weight = 1;
347 TTree *ToyTree =
new TTree(
"ToySummary",
"ToySummary");
348 ToyTree->Branch(
"Penalty", &Penalty,
"Penalty/D");
349 ToyTree->Branch(
"Weight", &Weight,
"Weight/D");
350 ToyTree->Branch(
"Draw", &Draw,
"Draw/I");
351 ToyTree->Branch(
"NModelParams", &
NModelParams,
"NModelParams/I");
355 std::vector<const double*> ParampPointers(
NModelParams);
356 int ParamCounter = 0;
357 for (
size_t iSys = 0; iSys <
systematics.size(); iSys++)
359 for (
int iPar = 0; iPar <
systematics[iSys]->GetNumParams(); iPar++)
361 ParampPointers[ParamCounter] =
systematics[iSys]->RetPointer(iPar);
362 std::string Name =
systematics[iSys]->GetParFancyName(iPar);
364 while (Name.find(
"-") != std::string::npos) {
365 Name.replace(Name.find(
"-"), 1, std::string(
"_"));
367 ToyTree->Branch(Name.c_str(), &ParamValues[ParamCounter], (Name +
"/D").c_str());
371 TDirectory* ToyDirectory =
outputFile->mkdir(
"Toys");
373 int SampleCounter = 0;
374 for (
size_t iPDF = 0; iPDF <
samples.size(); iPDF++)
377 for (
int SampleIndex = 0; SampleIndex < MaCh3Sample->GetNsamples(); ++SampleIndex)
380 TH1* DataHist = MaCh3Sample->
GetDataHist(SampleIndex);
381 Data_Hist[SampleCounter] =
M3::Clone(DataHist, MaCh3Sample->GetSampleTitle(SampleIndex) +
"_data");
382 Data_Hist[SampleCounter]->Write((MaCh3Sample->GetSampleTitle(SampleIndex) +
"_data").c_str());
384 TH1* MCHist = MaCh3Sample->GetMCHist(SampleIndex);
385 MC_Nom_Hist[SampleCounter] =
M3::Clone(MCHist, MaCh3Sample->GetSampleTitle(SampleIndex) +
"_mc");
386 MC_Nom_Hist[SampleCounter]->Write((MaCh3Sample->GetSampleTitle(SampleIndex) +
"_mc").c_str());
388 TH1* W2Hist = MaCh3Sample->GetW2Hist(SampleIndex);
389 W2_Nom_Hist[SampleCounter] =
M3::Clone(W2Hist, MaCh3Sample->GetSampleTitle(SampleIndex) +
"_w2");
390 W2_Nom_Hist[SampleCounter]->Write((MaCh3Sample->GetSampleTitle(SampleIndex) +
"_w2").c_str());
396 std::vector<std::vector<double>> branch_vals(
systematics.size());
397 std::vector<std::vector<std::string>> branch_name(
systematics.size());
399 TChain* PosteriorFile =
nullptr;
400 unsigned int burn_in = 0;
401 unsigned int maxNsteps = 0;
402 unsigned int Step = 0;
405 PosteriorFile =
new TChain(
"posteriors");
406 PosteriorFile->Add(PosteriorFileName.c_str());
408 PosteriorFile->SetBranchAddress(
"step", &Step);
409 if (PosteriorFile->GetBranch(
"Weight")) {
410 PosteriorFile->SetBranchStatus(
"Weight",
true);
411 PosteriorFile->SetBranchAddress(
"Weight", &Weight);
419 systematics[s]->MatchMaCh3OutputBranches(PosteriorFile, branch_vals[s], branch_name[s], fancy_names);
423 burn_in = Get<unsigned int>(
fitMan->
raw()[
"Predictive"][
"BurnInSteps"], __FILE__, __LINE__);
426 maxNsteps =
static_cast<unsigned int>(PosteriorFile->GetMaximum(
"step"));
427 if(burn_in >= maxNsteps)
429 MACH3LOG_ERROR(
"You are running on a chain shorter than burn in cut");
430 MACH3LOG_ERROR(
"Maximal value of nSteps: {}, burn in cut {}", maxNsteps, burn_in);
437 TStopwatch TempClock;
439 for(
int i = 0; i <
Ntoys; i++)
453 while(Step < burn_in){
454 entry =
random->Integer(
static_cast<unsigned int>(PosteriorFile->GetEntries()));
455 PosteriorFile->GetEntry(entry);
484 for (
size_t iPDF = 0; iPDF <
samples.size(); iPDF++) {
489 for (
size_t iPDF = 0; iPDF <
samples.size(); iPDF++)
492 for (
int SampleIndex = 0; SampleIndex < MaCh3Sample->GetNsamples(); ++SampleIndex)
494 TH1* MCHist = MaCh3Sample->
GetMCHist(SampleIndex);
495 MC_Hist_Toy[SampleCounter][i] =
M3::Clone(MCHist, MaCh3Sample->GetSampleTitle(SampleIndex) +
"_mc_" + std::to_string(i));
498 TH1* W2Hist = MaCh3Sample->GetW2Hist(SampleIndex);
499 W2_Hist_Toy[SampleCounter][i] =
M3::Clone(W2Hist, MaCh3Sample->GetSampleTitle(SampleIndex) +
"_w2_" + std::to_string(i));
506 for (
size_t iPar = 0; iPar < ParamValues.size(); iPar++) {
507 ParamValues[iPar] = *ParampPointers[iPar];
514 if(PosteriorFile)
delete PosteriorFile;
515 ToyDirectory->Close();
522 MACH3LOG_INFO(
"{} took {:.2f}s to finish for {} toys", __func__, TempClock.RealTime(),
Ntoys);
527 const std::vector<std::vector<std::unique_ptr<TH1>>>& Toys,
528 const std::vector<TDirectory*>& SampleDirectories,
529 const std::string suffix) {
537 SampleDirectories[sample]->cd();
539 const int nDims =
SampleInfo[sample].Dimenstion;
540 MaxValue[sample].assign(nDims, 0);
541 Projections[sample].resize(
Ntoys);
542 for (
int toy = 0; toy <
Ntoys; ++toy) {
546 }
else if (nDims == 2) {
547 Projections[sample][toy].resize(nDims);
548 TH2* h2 =
dynamic_cast<TH2*
>(Toys[sample][toy].get());
553 auto px = h2->ProjectionX();
554 px->SetDirectory(
nullptr);
555 Projections[sample][toy][0] =
M3::Clone(px);
557 auto py = h2->ProjectionY();
558 py->SetDirectory(
nullptr);
559 Projections[sample][toy][1] =
M3::Clone(py);
564 MACH3LOG_ERROR(
"Asking for {} with N Dimension = {}. This is not implemented", __func__, nDims);
572 #pragma omp parallel for collapse(2)
575 for (
int toy = 0; toy <
Ntoys; ++toy) {
576 const int nDims = Toys[sample][0]->GetDimension();
577 for (
int dim = 0; dim < nDims; dim++) {
580 max_val = Toys[sample][toy]->GetMaximum();
582 else if (nDims == 2) {
584 max_val = Projections[sample][toy][0]->GetMaximum();
586 max_val = Projections[sample][toy][1]->GetMaximum();
589 MACH3LOG_ERROR(
"Asking for {} with N Dimension = {}. This is not implemented", __func__, nDims);
592 MaxValue[sample][dim] = std::max(MaxValue[sample][dim], max_val);
601 const int nDims =
SampleInfo[sample].Dimenstion;
602 Spectra[sample].resize(nDims);
603 for (
int dim = 0; dim < nDims; dim++) {
605 TH1D* refHist =
nullptr;
607 refHist =
static_cast<TH1D*
>(Toys[sample][0].get());
609 else if (nDims == 2) {
611 refHist =
static_cast<TH1D*
>(Projections[sample][0][0].get());
613 refHist =
static_cast<TH1D*
>(Projections[sample][0][1].get());
617 MACH3LOG_ERROR(
"Asking for {} with N Dimension = {}. This is not implemented", __func__, nDims);
622 MACH3LOG_ERROR(
"Failed to cast to {} dimensions in {}!", nDims, __func__);
626 const int n_bins_x = refHist->GetNbinsX();
627 std::vector<double> x_bin_edges(n_bins_x + 1);
628 for (
int b = 0; b <= n_bins_x; ++b) {
629 x_bin_edges[b] = refHist->GetXaxis()->GetBinLowEdge(b + 1);
632 x_bin_edges[n_bins_x] = refHist->GetXaxis()->GetBinUpEdge(n_bins_x);
634 constexpr
int n_bins_y = 400;
635 constexpr
double y_min = 0.0;
636 const double y_max = MaxValue[sample][dim] * 1.05;
639 Spectra[sample][dim] = std::make_unique<TH2D>(
640 (
SampleInfo[sample].Name +
"_" + suffix +
"_dim" + std::to_string(dim)).c_str(),
641 (
SampleInfo[sample].Name +
"_" + suffix +
"_dim" + std::to_string(dim)).c_str(),
642 n_bins_x, x_bin_edges.data(),
643 n_bins_y, y_min, y_max
646 Spectra[sample][dim]->GetXaxis()->SetTitle(refHist->GetXaxis()->GetTitle());
647 Spectra[sample][dim]->GetYaxis()->SetTitle(
"Events");
649 Spectra[sample][dim]->SetDirectory(
nullptr);
650 Spectra[sample][dim]->Sumw2(
true);
656 #pragma omp parallel for
659 const int nDims =
SampleInfo[sample].Dimenstion;
660 for (
int dim = 0; dim < nDims; dim++) {
661 for (
int toy = 0; toy <
Ntoys; ++toy) {
663 FastViolinFill(Spectra[sample][dim].get(),
static_cast<TH1D*
>(Toys[sample][toy].get()));
665 else if (nDims == 2) {
666 FastViolinFill(Spectra[sample][dim].get(),
static_cast<TH1D*
>(Projections[sample][toy][dim].get()));
669 MACH3LOG_ERROR(
"Asking for {} with N Dimension = {}. This is not implemented", __func__, nDims);
678 SampleDirectories[sample]->cd();
679 for (
long unsigned int dim = 0; dim < Spectra[sample].size(); dim++) {
680 Spectra[sample][dim]->Write();
690 const std::vector<TDirectory*>& Directory,
691 const std::string& suffix,
692 const bool DebugHistograms) {
698 Directory[sample]->cd();
699 const int nDims =
SampleInfo[sample].Dimenstion;
700 const std::string Sample_Name =
SampleInfo[sample].Name;
702 int nbinsx = Toys[sample][0]->GetNbinsX();
703 const double* xbins = Toys[sample][0]->GetXaxis()->GetXbins()->GetArray();
704 auto PredictiveHist = std::make_unique<TH1D>(
705 (Sample_Name +
"_" + suffix +
"_PostPred").c_str(),
706 (Sample_Name +
"_" + suffix +
"_PostPred").c_str(),
709 PredictiveHist->GetXaxis()->SetTitle(Toys[sample][0]->GetXaxis()->GetTitle());
710 PredictiveHist->GetYaxis()->SetTitle(
"Events");
711 PredictiveHist->SetDirectory(
nullptr);
713 for (
int i = 1; i <= nbinsx; ++i) {
714 std::string ProjName = fmt::format(
"{} {} Bin: {}",
719 auto PosteriorHist = std::make_unique<TH1D>(ProjName.c_str(), ProjName.c_str(), 100, 1, -1);
720 PosteriorHist->SetDirectory(
nullptr);
721 PosteriorHist->GetXaxis()->SetTitle(
"Events");
723 for (
size_t iToy = 0; iToy < Toys[sample].size(); ++iToy) {
724 double content = Toys[sample][iToy]->GetBinContent(i);
728 if (DebugHistograms) PosteriorHist->Write();
730 PredictiveHist->SetBinContent(i, PosteriorHist->GetMean());
731 PredictiveHist->SetBinError(i, PosteriorHist->GetRMS());
733 PredictiveHist->Write();
734 PostPred_mc[sample] = std::move(PredictiveHist);
736 else if (nDims == 2) {
737 int nbinsx = Toys[sample][0]->GetNbinsX();
738 int nbinsy = Toys[sample][0]->GetNbinsY();
739 const double* xbins = Toys[sample][0]->GetXaxis()->GetXbins()->GetArray();
740 const double* ybins = Toys[sample][0]->GetYaxis()->GetXbins()->GetArray();
743 auto PredictiveHist = std::make_unique<TH2D>(
744 (Sample_Name +
"_" + suffix +
"_PostPred").c_str(),
745 (Sample_Name +
"_" + suffix +
"_PostPred").c_str(),
749 PredictiveHist->GetXaxis()->SetTitle(Toys[sample][0]->GetXaxis()->GetTitle());
750 PredictiveHist->GetYaxis()->SetTitle(Toys[sample][0]->GetYaxis()->GetTitle());
751 PredictiveHist->SetDirectory(
nullptr);
753 for (
int iy = 1; iy <= nbinsy; ++iy) {
754 for (
int ix = 1; ix <= nbinsx; ++ix) {
756 const int MaCh3Bin =
SampleInfo[sample].Binning->GetBinSafe(
SampleInfo[sample].LocalId, {ix-1, iy-1});
757 std::string ProjName = fmt::format(
"{} {} Bin: {}",
762 auto PosteriorHist = std::make_unique<TH1D>(ProjName.c_str(), ProjName.c_str(), 100, 1, -1);
763 PosteriorHist->SetDirectory(
nullptr);
764 PosteriorHist->GetXaxis()->SetTitle(
"Events");
765 int bin = Toys[sample][0]->GetBin(ix, iy);
766 for (
size_t iToy = 0; iToy < Toys[sample].size(); ++iToy) {
767 double content = Toys[sample][iToy]->GetBinContent(bin);
771 if (DebugHistograms) PosteriorHist->Write();
773 PredictiveHist->SetBinContent(ix, iy, PosteriorHist->GetMean());
774 PredictiveHist->SetBinError(ix, iy, PosteriorHist->GetRMS());
777 PredictiveHist->Write();
778 PostPred_mc[sample] = std::move(PredictiveHist);
781 MACH3LOG_ERROR(
"Asking for {} with N Dimension = {}. This is not implemented", __func__, nDims);
793 TStopwatch TempClock;
796 auto DebugHistograms = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"DebugHistograms"],
false, __FILE__, __LINE__);
798 TDirectory* PredictiveDir =
outputFile->mkdir(
"Predictive");
799 std::vector<TDirectory*> SampleDirectories;
804 SampleDirectories[sample] = PredictiveDir->mkdir(
SampleInfo[sample].Name.c_str());
816 SampleDirectories[sample]->Close();
817 delete SampleDirectories[sample];
822 PredictiveDir->Close();
823 delete PredictiveDir;
828 MACH3LOG_INFO(
"{} took {:.2f}s to finish for {} toys", __func__, TempClock.RealTime(),
Ntoys);
833 const std::unique_ptr<TH1>& MCHist,
834 const std::unique_ptr<TH1>& W2Hist,
838 for (
int i = 1; i <= DatHist->GetXaxis()->GetNbins(); ++i)
840 const double data = DatHist->GetBinContent(i);
841 const double mc = MCHist->GetBinContent(i);
842 const double w2 = W2Hist->GetBinContent(i);
851 const std::vector<TDirectory*>& SampleDir) {
855 std::vector<std::vector<double>> chi2_dat_vec(
Ntoys);
856 std::vector<std::vector<double>> chi2_mc_vec(
Ntoys);
857 std::vector<std::vector<double>> chi2_pred_vec(
Ntoys);
859 for(
int iToy = 0; iToy <
Ntoys; iToy++) {
870 const int nDims =
SampleInfo[iSample].Dimenstion;
873 auto PredFluctHist =
M3::Clone(PostPred_mc[iSample].get());
878 else if (nDims == 2) {
883 MACH3LOG_ERROR(
"Asking for {} with N Dimension = {}. This is not implemented", __func__, nDims);
892 chi2_dat_vec[iToy].back() += chi2_dat_vec[iToy][iSample];
893 chi2_mc_vec[iToy].back() += chi2_mc_vec[iToy][iSample];
894 chi2_pred_vec[iToy].back() += chi2_pred_vec[iToy][iSample];
898 MakeChi2Plots(chi2_mc_vec,
"-2LLH (Draw Fluc, Draw)", chi2_dat_vec,
"-2LLH (Data, Draw)", SampleDir,
"_drawfluc_draw");
899 MakeChi2Plots(chi2_pred_vec,
"-2LLH (Pred Fluc, Draw)", chi2_dat_vec,
"-2LLH (Data, Draw)", SampleDir,
"_predfluc_draw");
904 const std::string& Chi2_x_title,
905 const std::vector<std::vector<double>>& Chi2_y,
906 const std::string& Chi2_y_title,
907 const std::vector<TDirectory*>& SampleDir,
908 const std::string Title) {
911 SampleDir[iSample]->cd();
914 std::vector<double> chi2_y_sample(
Ntoys);
915 std::vector<double> chi2_x_per_sample(
Ntoys);
917 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
918 chi2_y_sample[iToy] = Chi2_y[iToy][iSample];
919 chi2_x_per_sample[iToy] = Chi2_x[iToy][iSample];
922 const double min_val = std::min(*std::min_element(chi2_y_sample.begin(), chi2_y_sample.end()),
923 *std::min_element(chi2_x_per_sample.begin(), chi2_x_per_sample.end()));
924 const double max_val = std::max(*std::max_element(chi2_y_sample.begin(), chi2_y_sample.end()),
925 *std::max_element(chi2_x_per_sample.begin(), chi2_x_per_sample.end()));
927 auto chi2_hist = std::make_unique<TH2D>((
SampleInfo[iSample].Name+ Title).c_str(),
929 100, min_val, max_val, 100, min_val, max_val);
930 chi2_hist->SetDirectory(
nullptr);
931 chi2_hist->GetXaxis()->SetTitle(Chi2_x_title.c_str());
932 chi2_hist->GetYaxis()->SetTitle(Chi2_y_title.c_str());
934 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
935 chi2_hist->Fill(chi2_x_per_sample[iToy], chi2_y_sample[iToy]);
947 bool StudyBeta = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"StudyBetaParameters"],
true, __FILE__, __LINE__ );
948 if (StudyBeta ==
false)
return;
951 TDirectory* BetaDir = PredictiveDir->mkdir(
"BetaParameters");
957 DirBeta[sample] = BetaDir->mkdir(
SampleInfo[sample].Name.c_str());
964 for (
int iBin = 0; iBin <
SampleInfo[iSample].Binning->GetNBins(
SampleInfo[iSample].LocalId); iBin++ ) {
965 std::string title = fmt::format(
"#beta param, {} Bin: {}",
970 BetaHist[iSample][iBin] = std::make_unique<TH1D>(title.c_str(), title.c_str(), 100, 1, -1);
971 BetaHist[iSample][iBin]->SetDirectory(
nullptr);
972 BetaHist[iSample][iBin]->GetXaxis()->SetTitle(
"beta parameter");
978 #pragma omp parallel for
981 const int nDims =
SampleInfo[iSample].Dimenstion;
983 int nbinsx =
Data_Hist[iSample]->GetNbinsX();
984 for (
int iBinX = 0; iBinX < nbinsx; ++iBinX) {
985 const int RootBin = iBinX+1;
986 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
988 const double Data =
Data_Hist[iSample]->GetBinContent(RootBin);
989 const double MC =
MC_Hist_Toy[iSample][iToy]->GetBinContent(RootBin);
990 const double w2 =
W2_Hist_Toy[iSample][iToy]->GetBinContent(RootBin);
991 const auto likelihood =
SampleInfo[iSample].SamHandler->GetTestStatistic();
997 }
else if (nDims == 2) {
998 const int nX =
Data_Hist[iSample]->GetNbinsX();
999 const int nY =
Data_Hist[iSample]->GetNbinsY();
1000 for (
int y = 0; y < nY; ++y) {
1001 for (
int x = 0; x < nX; ++x) {
1002 const int RootBin =
Data_Hist[iSample]->GetBin(x+1, y+1);
1003 const int MaCh3Bin =
SampleInfo[iSample].Binning->GetBinSafe(
SampleInfo[iSample].LocalId, {x, y});
1005 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
1006 const double Data =
Data_Hist[iSample]->GetBinContent(RootBin);
1007 const double MC =
MC_Hist_Toy[iSample][iToy]->GetBinContent(RootBin);
1008 const double w2 =
W2_Hist_Toy[iSample][iToy]->GetBinContent(RootBin);
1009 const auto likelihood =
SampleInfo[iSample].SamHandler->GetTestStatistic();
1012 BetaHist[iSample][MaCh3Bin]->Fill(BetaParam,
ReweightWeight[iToy]);
1017 MACH3LOG_ERROR(
"Asking for {} with N Dimension = {}. This is not implemented", __func__, nDims);
1024 for (
int iBin = 0; iBin <
SampleInfo[iSample].Binning->GetNBins(
SampleInfo[iSample].LocalId); iBin++ ) {
1025 DirBeta[iSample]->cd();
1026 BetaHist[iSample][iBin]->Write();
1028 DirBeta[iSample]->Close();
1029 delete DirBeta[iSample];
1034 PredictiveDir->cd();
void MakeFluctuatedHistogramAlternative(TH1D *FluctHist, TH1D *PolyHist, TRandom3 *rand)
Make Poisson fluctuation of TH1D hist using slow method which is only for cross-check.
void FastViolinFill(TH2D *violin, TH1D *hist_1d)
KS: Fill Violin histogram with entry from a toy.
double GetBetaParameter(const double data, const double mc, const double w2, const TestStatistic TestStat)
KS: Calculate Beta parameter which will be different based on specified test statistic.
void Get2DBayesianpValue(TH2D *Histogram)
Calculates the 2D Bayesian p-value and generates a visualization.
YAML::Node TMacroToYAML(const TMacro ¯o)
KS: Convert a ROOT TMacro object to a YAML node.
bool compareYAMLNodes(const YAML::Node &node1, const YAML::Node &node2, bool Mute=false)
Compare if yaml nodes are identical.
bool CheckNodeExists(const YAML::Node &node, Args... args)
KS: Wrapper function to call the recursive helper.
Base class for implementing fitting algorithms.
std::string GetName() const
Get name of class.
std::unique_ptr< TRandom3 > random
Random number.
std::vector< SampleHandlerBase * > samples
Sample holder.
TFile * outputFile
Output.
std::string AlgorithmName
Name of fitting algorithm that is being used.
Manager * fitMan
The manager for configuration handling.
std::vector< ParameterHandlerBase * > systematics
Systematic holder.
Class responsible for processing MCMC chains, performing diagnostics, generating plots,...
void Initialise()
Scan chain, what parameters we have and load information from covariance matrices.
YAML::Node GetCovConfig(const int i) const
Get Yaml config obtained from a Chain.
Custom exception class used throughout MaCh3.
The manager class is responsible for managing configurations and settings.
YAML::Node const & raw() const
Return config.
Base class responsible for handling of systematic error parameters. Capable of using PCA or using ada...
int GetNumParams() const
Get total number of parameters.
void SetParProp(const int i, const double val)
Set proposed parameter value.
int GetParIndex(const std::string &name) const
Get index based on name.
std::string GetName() const
Get name of covariance.
double GetParInit(const int i) const
Get prior parameter value.
YAML::Node GetConfig() const
Getter to return a copy of the YAML node.
Class responsible for handling of systematic error parameters with different types defined in the con...
void SetGroupOnlyParameters(const std::string &Group, const std::vector< double > &Pars={})
KS Function to set to prior parameters of a given group or values from vector.
std::vector< std::string > GetUniqueParameterGroups()
KS: Get names of all unique parameter groups.
void SetParamters()
This set some params to prior value this way you can evaluate errors from subset of errors.
std::vector< double > PenaltyTerm
Penalty term values for each toy by default 0.
virtual ~PredictiveThrower()
Destructor.
std::vector< std::vector< std::unique_ptr< TH2D > > > ProduceSpectra(const std::vector< std::vector< std::unique_ptr< TH1 >>> &Toys, const std::vector< TDirectory * > &Director, const std::string suffix)
Produce Violin style spectra.
bool FullLLH
KS: Use Full LLH or only sample contribution based on discussion with Asher we almost always only wan...
void RunPredictiveAnalysis()
Main routine responsible for producing posterior predictive distributions and $p$-value.
bool LoadToys()
Load existing toys.
void PosteriorPredictivepValue(const std::vector< std::unique_ptr< TH1 >> &PostPred_mc, const std::vector< TDirectory * > &SampleDir)
Calculate Posterior Predictive $p$-value.
std::vector< std::unique_ptr< TH1 > > MakePredictive(const std::vector< std::vector< std::unique_ptr< TH1 >>> &Toys, const std::vector< TDirectory * > &Director, const std::string &suffix, const bool DebugHistograms)
Produce posterior predictive distribution.
std::vector< std::string > GetStoredFancyName(ParameterHandlerBase *Systematics) const
Get Fancy parameters stored in mcmc chains for passed ParameterHandler.
std::vector< std::unique_ptr< TH1 > > W2_Nom_Hist
Vector of W2 histograms.
std::unordered_set< int > ParameterOnlyToVary
KS: Index of parameters that will be varied.
std::vector< std::vector< std::unique_ptr< TH1 > > > W2_Hist_Toy
double GetLLH(const std::unique_ptr< TH1 > &DatHist, const std::unique_ptr< TH1 > &MCHist, const std::unique_ptr< TH1 > &W2Hist, const SampleHandlerBase *SampleHandler)
Helper functions to calculate likelihoods using TH1.
bool Is_PriorPredictive
Whether it is Prior or Posterior predictive.
std::vector< std::string > ParameterGroupsNotVaried
KS: Names of parameter groups that will not be varied.
int NModelParams
KS: Count total number of model parameters which can be used for stuff like BIC.
int Ntoys
Number of toys we are generating analysing.
void SetupToyGeneration()
Setup useful variables etc before stating toy generation.
void MakeChi2Plots(const std::vector< std::vector< double >> &Chi2_x, const std::string &Chi2_x_title, const std::vector< std::vector< double >> &Chi2_y, const std::string &Chi2_y_title, const std::vector< TDirectory * > &SampleDir, const std::string Title)
Produce Chi2 plot for a single sample based on which $p$-value is calculated.
void SetupSampleInformation()
Setup sample information.
std::vector< std::unique_ptr< TH1 > > MC_Nom_Hist
Vector of MC histograms.
int TotalNumberOfSamples
Number of toys we are generating analysing.
void ProduceToys()
Produce toys by throwing from MCMC.
void StudyBetaParameters(TDirectory *PredictiveDir)
Evaluate prior/post predictive distribution for beta parameters (used for evaluating impact MC statis...
std::vector< std::unique_ptr< TH1 > > Data_Hist
Vector of Data histograms.
ParameterHandlerGeneric * ModelSystematic
Pointer to El Generico.
std::vector< double > ReweightWeight
Reweighting factors applied for each toy, by default 1.
PredictiveThrower(Manager *const fitMan)
Constructor.
std::vector< std::vector< std::unique_ptr< TH1 > > > MC_Hist_Toy
Class responsible for handling implementation of samples used in analysis, reweighting and returning ...
double GetTestStatLLH(const double data, const double mc, const double w2) const
Calculate test statistic for a single bin. Calculation depends on setting of fTestStatistic....
Class responsible for handling implementation of samples used in analysis, reweighting and returning ...
TH1 * GetDataHist(const int Sample) override
Get Data histogram.
TH1 * GetMCHist(const int Sample) override
Get MC histogram.
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.
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.
constexpr static const int _BAD_INT_
Default value used for int initialisation.
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.
KS: Store info about MC sample.