6 #pragma GCC diagnostic ignored "-Wfloat-conversion"
7 #pragma GCC diagnostic ignored "-Wuseless-cast"
21 else MACH3LOG_INFO(
"Using alternative method of statistical fluctuation, which is much slower");
25 FullLLH = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"FullLLH"],
false, __FILE__, __LINE__ );
29 Ntoys = Get<int>(
fitMan->
raw()[
"Predictive"][
"Ntoy"], __FILE__, __LINE__);
44 std::unordered_set<int>& ParameterOnlyToVary) {
47 auto DoNotThrowLegacyCov = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"Predictive"][
"DoNotThrowLegacyCov"], {}, __FILE__, __LINE__);
49 for (
size_t i = 0; i < DoNotThrowLegacyCov.size(); ++i) {
67 if (ParameterOnlyToVary.find(i) == ParameterOnlyToVary.end()) {
78 for (
size_t iPDF = 0; iPDF <
samples.size(); iPDF++) {
96 for (
size_t iPDF = 0; iPDF <
samples.size(); iPDF++) {
97 for (
int SampleIndex = 0; SampleIndex <
samples[iPDF]->GetNSamples(); ++SampleIndex) {
111 std::unordered_set<int>& ParameterOnlyToVary,
112 std::vector<const M3::float_t*>& BoundValuePointer,
113 std::vector<std::pair<double, double>>& ParamBounds) {
127 MACH3LOG_INFO(
"You've chosen to run Prior Predictive Distribution");
129 auto PosteriorFileName = Get<std::string>(
fitMan->
raw()[
"Predictive"][
"PosteriorFile"], __FILE__, __LINE__);
135 auto AllowDifferentConfigs = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"AllowDifferentConfigs"],
false, __FILE__, __LINE__);
143 if(AllowDifferentConfigs){
144 MACH3LOG_WARN(
"Yaml configs used for your ParameterHandler for chain you want sample from ({}) and one currently initialised are different", PosteriorFileName);
146 MACH3LOG_ERROR(
"Yaml configs used for your ParameterHandler for chain you want sample from ({}) and one currently initialised are different", PosteriorFileName);
153 MACH3LOG_ERROR(
"Found {} ParmaterHandler inheriting from ParameterHandlerGeneric, I can accept at most 1", counter);
162 auto ThrowParamGroupOnly = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"Predictive"][
"ThrowParamGroupOnly"], {}, __FILE__, __LINE__);
164 auto ParameterOnlyToVaryString = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"Predictive"][
"ThrowSinlgeParams"], {}, __FILE__, __LINE__);
166 if (!ThrowParamGroupOnly.empty() && !ParameterOnlyToVaryString.empty()) {
167 MACH3LOG_ERROR(
"Can't use ThrowParamGroupOnly and ThrowSinlgeParams at the same time");
171 if (!ParameterOnlyToVaryString.empty()) {
172 MACH3LOG_INFO(
"I will throw only: {}", fmt::join(ParameterOnlyToVaryString,
", "));
173 std::vector<int> ParameterVary(ParameterOnlyToVaryString.size());
175 for (
size_t i = 0; i < ParameterOnlyToVaryString.size(); ++i) {
178 MACH3LOG_ERROR(
"Can't proceed if param {} is missing", ParameterOnlyToVaryString[i]);
182 ParameterOnlyToVary = std::unordered_set<int>(ParameterVary.begin(), ParameterVary.end());
184 MACH3LOG_INFO(
"I have following parameter groups: {}", fmt::join(UniqueParamGroup,
", "));
185 if (ThrowParamGroupOnly.empty()) {
188 std::unordered_set<std::string> throwOnlySet(ThrowParamGroupOnly.begin(), ThrowParamGroupOnly.end());
189 ParameterGroupsNotVaried.clear();
191 for (
const auto& group : UniqueParamGroup) {
192 if (throwOnlySet.find(group) == throwOnlySet.end()) {
193 ParameterGroupsNotVaried.push_back(group);
197 MACH3LOG_INFO(
"I will vary: {}", fmt::join(ThrowParamGroupOnly,
", "));
198 MACH3LOG_INFO(
"Exclude: {}", fmt::join(ParameterGroupsNotVaried,
", "));
203 auto paramNode =
fitMan->
raw()[
"Predictive"][
"ParameterBounds"];
204 for (
const auto& p : paramNode) {
206 std::string name = p[0].as<std::string>();
209 double minVal = p[1][0].as<
double>();
210 double maxVal = p[1][1].as<
double>();
211 ParamBounds.emplace_back(minVal, maxVal);
214 for(
int iPar = 0; iPar <
systematics[s]->GetNParameters(); iPar++){
216 BoundValuePointer.push_back(
systematics[s]->RetPointer(iPar));
221 if(ParamBounds.size() != BoundValuePointer.size()){
225 MACH3LOG_INFO(
"Parameter: {} with : [{}, {}]", name, minVal, maxVal);
228 MACH3LOG_ERROR(
"Additional bounds not supported by prior predictive right now");
237 auto PosteriorFileName = Get<std::string>(
fitMan->
raw()[
"Predictive"][
"PosteriorFile"], __FILE__, __LINE__);
239 int originalErrorWarning = gErrorIgnoreLevel;
240 gErrorIgnoreLevel = kFatal;
241 TFile* file =
TFile::Open(PosteriorFileName.c_str(),
"READ");
243 gErrorIgnoreLevel = originalErrorWarning;
244 TDirectory* ToyDir =
nullptr;
245 if (!file || file->IsZombie()) {
249 if ((ToyDir = file->GetDirectory(
"Toys"))) {
250 MACH3LOG_INFO(
"Found toys in Posterior file will attempt toy reading");
259 TTree* PenaltyTree =
static_cast<TTree*
>(file->Get(
"ToySummary"));
267 Ntoys =
static_cast<int>(PenaltyTree->GetEntries());
268 int ConfigNtoys = Get<int>(
fitMan->
raw()[
"Predictive"][
"Ntoy"], __FILE__, __LINE__);;
269 if (
Ntoys != ConfigNtoys) {
270 MACH3LOG_WARN(
"Found different number of toys in saved file than asked to run!");
279 double Penalty = 0, Weight = 1;
280 PenaltyTree->SetBranchAddress(
"Penalty", &Penalty);
281 PenaltyTree->SetBranchAddress(
"Weight", &Weight);
282 PenaltyTree->SetBranchAddress(
"NModelParams", &
NModelParams);
284 for (
int i = 0; i <
Ntoys; ++i) {
285 PenaltyTree->GetEntry(i);
298 TH1* DataHist1D =
static_cast<TH1*
>(ToyDir->Get((
SampleInfo[sample].Name +
"_data").c_str()));
301 TH1* MCHist1D =
static_cast<TH1*
>(ToyDir->Get((
SampleInfo[sample].Name +
"_mc").c_str()));
304 TH1* W2Hist1D =
static_cast<TH1*
>(ToyDir->Get((
SampleInfo[sample].Name +
"_w2").c_str()));
309 for (
int iToy = 0; iToy <
Ntoys; ++iToy)
314 TH1* MCHist1D =
static_cast<TH1*
>(ToyDir->Get((
SampleInfo[sample].Name +
"_mc_" + std::to_string(iToy)).c_str()));
315 TH1* W2Hist1D =
static_cast<TH1*
>(ToyDir->Get((
SampleInfo[sample].Name +
"_w2_" + std::to_string(iToy)).c_str()));
330 TDirectory * ogdir = gDirectory;
332 std::vector<std::string> FancyNames;
333 std::string Name = std::string(
"Config_") + Systematics->
GetName();
334 auto PosteriorFileName = Get<std::string>(
fitMan->
raw()[
"Predictive"][
"PosteriorFile"], __FILE__, __LINE__);
336 TFile* file =
TFile::Open(PosteriorFileName.c_str(),
"READ");
337 TDirectory* CovarianceFolder = file->GetDirectory(
"CovarianceFolder");
339 TMacro* FoundMacro =
static_cast<TMacro*
>(CovarianceFolder->Get(Name.c_str()));
340 if(FoundMacro ==
nullptr) {
343 if(ogdir){ ogdir->cd(); }
350 int params = int(Settings[
"Systematics"].size());
351 FancyNames.resize(params);
353 for (
auto const ¶m : Settings[
"Systematics"]) {
354 FancyNames[iPar] = Get<std::string>(param[
"Systematic"][
"Names"][
"FancyName"], __FILE__ , __LINE__);
359 if(ogdir){ ogdir->cd(); }
366 TDirectory* Toy_1DDirectory,
367 TDirectory* Toy_2DDirectory,
370 int SampleCounter = 0;
371 for (
size_t iPDF = 0; iPDF <
samples.size(); iPDF++)
373 auto* SampleHandler =
samples[iPDF];
374 for (
int iSample = 0; iSample < SampleHandler->GetNSamples(); ++iSample)
378 auto SampleName = SampleHandler->GetSampleTitle(iSample);
379 const TH1* MCHist = SampleHandler->GetMCHist(iSample);
380 MC_Hist_Toy[SampleCounter][iToy] =
M3::Clone(MCHist, SampleName +
"_mc_" + std::to_string(iToy));
383 const TH1* W2Hist = SampleHandler->GetW2Hist(iSample);
384 W2_Hist_Toy[SampleCounter][iToy] =
M3::Clone(W2Hist, SampleName +
"_w2_" + std::to_string(iToy));
388 Toy_1DDirectory->cd();
389 for(
int iDim = 0; iDim < SampleHandler->GetNDim(iSample); iDim++) {
390 std::string ProjectionName = SampleHandler->GetKinVarName(iSample, iDim);
391 std::string ProjectionSuffix =
"_1DProj" + std::to_string(iDim) +
"_" + std::to_string(iToy);
393 auto hist = SampleHandler->Get1DVarHist(iSample, ProjectionName);
394 hist->SetTitle((SampleName + ProjectionSuffix).c_str());
395 hist->SetName((SampleName + ProjectionSuffix).c_str());
399 Toy_2DDirectory->cd();
401 for(
int iDim1 = 0; iDim1 < SampleHandler->GetNDim(iSample); iDim1++) {
402 for (
int iDim2 = iDim1 + 1; iDim2 < SampleHandler->GetNDim(iSample); ++iDim2) {
404 std::string XVarName = SampleHandler->GetKinVarName(iSample, iDim1);
405 std::string YVarName = SampleHandler->GetKinVarName(iSample, iDim2);
408 auto hist2D = SampleHandler->Get2DVarHist(iSample, XVarName, YVarName);
411 std::string suffix2D =
"_2DProj_" + std::to_string(iDim1) +
"_vs_" + std::to_string(iDim2) +
"_" + std::to_string(iToy);
412 hist2D->SetTitle((SampleName + suffix2D).c_str());
413 hist2D->SetName((SampleName + suffix2D).c_str());
426 int SampleCounter = 0;
427 for (
size_t iPDF = 0; iPDF <
samples.size(); iPDF++)
429 auto* SampleHandler =
samples[iPDF];
430 auto* modes = SampleHandler->GetMaCh3Modes();
431 for (
int iSample = 0; iSample < SampleHandler->GetNSamples(); ++iSample)
433 ByModeDirectory->cd();
435 auto SampleName = SampleHandler->GetSampleTitle(iSample);
436 for (
int iMode = 0; iMode < modes->GetNModes()+1; ++iMode) {
437 auto ModeName = modes->GetMaCh3ModeName(iMode);
438 for(
int iDim = 0; iDim < SampleHandler->GetNDim(iSample); iDim++) {
439 std::string ProjectionName = SampleHandler->GetKinVarName(iSample, iDim);
440 std::string PlotSuffix =
"_1DProj" + std::to_string(iDim) +
"_" + ModeName +
"_" + std::to_string(iToy);
442 auto hist = SampleHandler->Get1DVarHistByModeAndChannel(iSample, ProjectionName, iMode);
443 hist->SetTitle((SampleName + PlotSuffix).c_str());
444 hist->SetName((SampleName + PlotSuffix).c_str());
454 bool CheckBounds(
const std::vector<const M3::float_t*>& BoundValuePointer,
455 const std::vector<std::pair<double,double>>& ParamBounds) {
457 for (
size_t i = 0; i < BoundValuePointer.size(); ++i) {
458 const double val = *(BoundValuePointer[i]);
459 const double minVal = ParamBounds[i].first;
460 const double maxVal = ParamBounds[i].second;
462 if (val < minVal || val > maxVal)
476 std::vector<std::string> ParameterGroupsNotVaried;
478 std::unordered_set<int> ParameterOnlyToVary;
480 std::vector<const M3::float_t*> BoundValuePointer;
481 std::vector<std::pair<double, double>> ParamBounds;
485 BoundValuePointer, ParamBounds);
487 auto PosteriorFileName = Get<std::string>(
fitMan->
raw()[
"Predictive"][
"PosteriorFile"], __FILE__, __LINE__);
492 double Penalty = 0, Weight = 1;
495 TTree *ToyTree =
new TTree(
"ToySummary",
"ToySummary");
496 ToyTree->Branch(
"Penalty", &Penalty,
"Penalty/D");
497 ToyTree->Branch(
"Weight", &Weight,
"Weight/D");
498 ToyTree->Branch(
"Draw", &Draw,
"Draw/I");
499 ToyTree->Branch(
"NModelParams", &
NModelParams,
"NModelParams/I");
503 std::vector<const M3::float_t*> ParampPointers(
NModelParams);
504 int ParamCounter = 0;
505 for (
size_t iSys = 0; iSys <
systematics.size(); iSys++)
507 for (
int iPar = 0; iPar <
systematics[iSys]->GetNumParams(); iPar++)
509 ParampPointers[ParamCounter] =
systematics[iSys]->RetPointer(iPar);
510 std::string Name =
systematics[iSys]->GetParFancyName(iPar);
512 while (Name.find(
"-") != std::string::npos) {
513 Name.replace(Name.find(
"-"), 1, std::string(
"_"));
515 ToyTree->Branch(Name.c_str(), &ParamValues[ParamCounter], (Name +
"/D").c_str());
519 TDirectory* ToyDirectory =
outputFile->mkdir(
"Toys");
521 int SampleCounter = 0;
522 for (
size_t iPDF = 0; iPDF <
samples.size(); iPDF++)
524 auto* MaCh3Sample =
samples[iPDF];
525 for (
int SampleIndex = 0; SampleIndex < MaCh3Sample->GetNSamples(); ++SampleIndex)
528 const TH1* DataHist = MaCh3Sample->GetDataHist(SampleIndex);
529 Data_Hist[SampleCounter] =
M3::Clone(DataHist, MaCh3Sample->GetSampleTitle(SampleIndex) +
"_data");
530 Data_Hist[SampleCounter]->Write((MaCh3Sample->GetSampleTitle(SampleIndex) +
"_data").c_str());
532 const TH1* MCHist = MaCh3Sample->GetMCHist(SampleIndex);
533 MC_Nom_Hist[SampleCounter] =
M3::Clone(MCHist, MaCh3Sample->GetSampleTitle(SampleIndex) +
"_mc");
534 MC_Nom_Hist[SampleCounter]->Write((MaCh3Sample->GetSampleTitle(SampleIndex) +
"_mc").c_str());
536 const TH1* W2Hist = MaCh3Sample->GetW2Hist(SampleIndex);
537 W2_Nom_Hist[SampleCounter] =
M3::Clone(W2Hist, MaCh3Sample->GetSampleTitle(SampleIndex) +
"_w2");
538 W2_Nom_Hist[SampleCounter]->Write((MaCh3Sample->GetSampleTitle(SampleIndex) +
"_w2").c_str());
543 TDirectory* Toy_1DDirectory =
outputFile->mkdir(
"Toys_1DHistVar");
544 TDirectory* Toy_2DDirectory =
outputFile->mkdir(
"Toys_2DHistVar");
545 auto doByMode = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"ByMode"],
false, __FILE__, __LINE__);
546 TDirectory* ByModeDirectory =
nullptr;
547 if(doByMode) ByModeDirectory =
outputFile->mkdir(
"Toys_ByMode");
550 std::vector<std::vector<double>> branch_vals(
systematics.size());
551 std::vector<std::vector<std::string>> branch_name(
systematics.size());
553 TChain* PosteriorFile =
nullptr;
554 unsigned int burn_in = 0;
555 unsigned int maxNsteps = 0;
556 unsigned int Step = 0;
559 PosteriorFile =
new TChain(
"posteriors");
560 PosteriorFile->Add(PosteriorFileName.c_str());
562 PosteriorFile->SetBranchAddress(
"step", &Step);
563 if (PosteriorFile->GetBranch(
"Weight")) {
564 PosteriorFile->SetBranchStatus(
"Weight",
true);
565 PosteriorFile->SetBranchAddress(
"Weight", &Weight);
573 systematics[s]->MatchMaCh3OutputBranches(PosteriorFile, branch_vals[s], branch_name[s], fancy_names);
577 burn_in = Get<unsigned int>(
fitMan->
raw()[
"Predictive"][
"BurnInSteps"], __FILE__, __LINE__);
580 maxNsteps =
static_cast<unsigned int>(PosteriorFile->GetMaximum(
"step"));
581 if(burn_in >= maxNsteps)
583 MACH3LOG_ERROR(
"You are running on a chain shorter than burn in cut");
584 MACH3LOG_ERROR(
"Maximal value of nSteps: {}, burn in cut {}", maxNsteps, burn_in);
591 TStopwatch TempClock;
593 for(
int i = 0; i <
Ntoys; i++)
602 bool WithinBounds =
false;
607 while(Step < burn_in || !WithinBounds) {
608 entry =
random->Integer(
static_cast<unsigned int>(PosteriorFile->GetEntries()));
609 PosteriorFile->GetEntry(entry);
612 if(BoundValuePointer.size() > 0) {
617 WithinBounds =
CheckBounds(BoundValuePointer, ParamBounds);
633 SetParamters(ParameterGroupsNotVaried, ParameterOnlyToVary);
646 for (
size_t iPDF = 0; iPDF <
samples.size(); iPDF++) {
650 WriteToy(ToyDirectory, Toy_1DDirectory, Toy_2DDirectory, i);
654 for (
size_t iPar = 0; iPar < ParamValues.size(); iPar++) {
655 ParamValues[iPar] = *ParampPointers[iPar];
662 if(PosteriorFile)
delete PosteriorFile;
663 ToyDirectory->Close();
delete ToyDirectory;
664 Toy_1DDirectory->Close();
delete Toy_1DDirectory;
665 Toy_2DDirectory->Close();
delete Toy_2DDirectory;
667 ByModeDirectory->Close();
668 delete ByModeDirectory;
672 ToyTree->Write();
delete ToyTree;
674 MACH3LOG_INFO(
"{} took {:.2f}s to finish for {} toys", __func__, TempClock.RealTime(),
Ntoys);
682 TDirectory * ogdir = gDirectory;
683 auto PosteriorFileName = Get<std::string>(
fitMan->
raw()[
"Predictive"][
"PosteriorFile"], __FILE__, __LINE__);
685 int originalErrorWarning = gErrorIgnoreLevel;
686 gErrorIgnoreLevel = kFatal;
688 TFile* file =
TFile::Open(PosteriorFileName.c_str(),
"READ");
690 gErrorIgnoreLevel = originalErrorWarning;
691 TDirectory* ToyDir = file->GetDirectory(
"Toys_1DHistVar");
693 if(ToyDir ==
nullptr) {
694 ToyDir =
outputFile->GetDirectory(
"Toys_1DHistVar");
697 std::vector<std::vector<std::vector<std::unique_ptr<TH1D>>>> ProjectionToys(
TotalNumberOfSamples);
699 ProjectionToys[sample].resize(
Ntoys);
700 const int nDims =
SampleInfo[sample].Dimenstion;
701 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
702 ProjectionToys[sample][iToy].resize(nDims);
706 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
707 if (iToy % 100 == 0)
MACH3LOG_INFO(
" Loaded Projection toys {}", iToy);
709 const int nDims =
SampleInfo[sample].Dimenstion;
710 for(
int iDim = 0; iDim < nDims; iDim ++){
711 std::string ProjectionSuffix =
"_1DProj" + std::to_string(iDim) +
"_" + std::to_string(iToy);
712 TH1D* MCHist1D =
static_cast<TH1D*
>(ToyDir->Get((
SampleInfo[sample].Name + ProjectionSuffix).c_str()));
713 ProjectionToys[sample][iToy][iDim] =
M3::Clone(MCHist1D);
717 file->Close();
delete file;
718 if(ogdir){ ogdir->cd(); }
722 const int nDims =
SampleInfo[sample].Dimenstion;
726 SampleDirectories[sample]->cd();
728 std::string nameX =
"Data_" +
SampleInfo[sample].Name +
"_Dim0";
729 std::string nameY =
"Data_" +
SampleInfo[sample].Name +
"_Dim1";
731 if(std::string(hist->ClassName()) ==
"TH2Poly") {
732 TAxis* xax = ProjectionToys[sample][0][0]->GetXaxis();
733 TAxis* yax = ProjectionToys[sample][0][1]->GetXaxis();
735 std::vector<double> XBinning(xax->GetNbins()+1);
736 std::vector<double> YBinning(yax->GetNbins()+1);
738 for(
int i=0;i<=xax->GetNbins();++i)
739 XBinning[i] = xax->GetBinLowEdge(i+1);
741 for(
int i=0;i<=yax->GetNbins();++i)
742 YBinning[i] = yax->GetBinLowEdge(i+1);
744 TH1D* ProjectionX =
PolyProjectionX(
static_cast<TH2Poly*
>(hist), nameX.c_str(), XBinning,
false);
745 TH1D* ProjectionY =
PolyProjectionY(
static_cast<TH2Poly*
>(hist), nameY.c_str(), YBinning,
false);
747 ProjectionX->SetDirectory(
nullptr);
748 ProjectionY->SetDirectory(
nullptr);
750 ProjectionX->Write(nameX.c_str());
751 ProjectionY->Write(nameY.c_str());
756 TH1D* ProjectionX =
static_cast<TH2D*
>(hist)->ProjectionX(nameX.c_str());
757 TH1D* ProjectionY =
static_cast<TH2D*
>(hist)->ProjectionY(nameY.c_str());
759 ProjectionX->SetDirectory(
nullptr);
760 ProjectionY->SetDirectory(
nullptr);
762 ProjectionX->Write(nameX.c_str());
763 ProjectionY->Write(nameY.c_str());
776 TDirectory * ogdir = gDirectory;
777 auto PosteriorFileName = Get<std::string>(
fitMan->
raw()[
"Predictive"][
"PosteriorFile"], __FILE__, __LINE__);
779 int originalErrorWarning = gErrorIgnoreLevel;
780 gErrorIgnoreLevel = kFatal;
782 TFile* file =
TFile::Open(PosteriorFileName.c_str(),
"READ");
784 gErrorIgnoreLevel = originalErrorWarning;
785 TDirectory* ToyDir = file->GetDirectory(
"Toys_ByMode");
787 if(ToyDir ==
nullptr) {
788 ToyDir =
outputFile->GetDirectory(
"Toys_ByMode");
793 auto* mode =
SampleInfo[0].SamHandler->GetMaCh3Modes();
794 auto NModes = mode->GetNModes()+1;
796 std::vector<std::vector<std::vector<std::vector<std::unique_ptr<TH1D>>>>> ProjectionToys(NModes);
797 for(
int iMode = 0; iMode < NModes; iMode++) {
800 ProjectionToys[iMode][sample].resize(
Ntoys);
801 const int nDims =
SampleInfo[sample].Dimenstion;
802 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
803 ProjectionToys[iMode][sample][iToy].resize(nDims);
808 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
809 if (iToy % 100 == 0)
MACH3LOG_INFO(
" Loaded Projection toys {}", iToy);
810 for(
int iMode = 0; iMode < NModes; iMode++) {
811 auto ModeName = mode->GetMaCh3ModeName(iMode);
813 const int nDims =
SampleInfo[sample].Dimenstion;
814 for(
int iDim = 0; iDim < nDims; iDim ++) {
815 std::string ProjectionSuffix =
"_1DProj" + std::to_string(iDim) +
"_" + ModeName +
"_" + std::to_string(iToy);
816 TH1D* MCHist1D =
static_cast<TH1D*
>(ToyDir->Get((
SampleInfo[sample].Name + ProjectionSuffix).c_str()));
817 ProjectionToys[iMode][sample][iToy][iDim] =
M3::Clone(MCHist1D);
826 ModeDirectory[iSample] = SampleDirectories[iSample]->mkdir(
"ByMode");
829 for(
int iMode = 0; iMode < NModes; iMode++) {
830 auto ModeName = mode->GetMaCh3ModeName(iMode);
831 ProduceSpectra(ProjectionToys[iMode], ModeDirectory, ModeName,
false);
834 ModeDirectory[iSample]->Close();
835 delete ModeDirectory[iSample];
837 file->Close();
delete file;
838 if(ogdir){ ogdir->cd(); }
843 const std::vector<TDirectory*>& SampleDirectories,
844 const std::string suffix,
845 const bool DoSummary)
const {
851 const int nDims =
SampleInfo[sample].Dimenstion;
852 MaxValue[sample].assign(nDims, 0);
857 #pragma omp parallel for
860 for (
int toy = 0; toy <
Ntoys; ++toy) {
861 const int nDims =
SampleInfo[sample].Dimenstion;
862 for (
int dim = 0; dim < nDims; dim++) {
863 double max_val = Toys[sample][toy][dim]->GetMaximum();
864 MaxValue[sample][dim] = std::max(MaxValue[sample][dim], max_val);
873 const int nDims =
SampleInfo[sample].Dimenstion;
874 Spectra[sample].resize(nDims);
875 for (
int dim = 0; dim < nDims; dim++) {
877 TH1D* refHist = Toys[sample][0][dim].get();
879 const int n_bins_x = refHist->GetNbinsX();
880 std::vector<double> x_bin_edges(n_bins_x + 1);
881 for (
int b = 0; b < n_bins_x; ++b) {
882 x_bin_edges[b] = refHist->GetXaxis()->GetBinLowEdge(b + 1);
884 x_bin_edges[n_bins_x] = refHist->GetXaxis()->GetBinUpEdge(n_bins_x);
886 constexpr
int n_bins_y = 400;
887 constexpr
double y_min = 0.0;
888 const double y_max = MaxValue[sample][dim] * 1.05;
891 Spectra[sample][dim] = std::make_unique<TH2D>(
892 (
SampleInfo[sample].Name +
"_" + suffix +
"_dim" + std::to_string(dim)).c_str(),
893 (
SampleInfo[sample].Name +
"_" + suffix +
"_dim" + std::to_string(dim)).c_str(),
894 n_bins_x, x_bin_edges.data(),
895 n_bins_y, y_min, y_max
898 Spectra[sample][dim]->GetXaxis()->SetTitle(refHist->GetXaxis()->GetTitle());
899 Spectra[sample][dim]->GetYaxis()->SetTitle(
"Events");
901 Spectra[sample][dim]->SetDirectory(
nullptr);
902 Spectra[sample][dim]->Sumw2(
true);
908 #pragma omp parallel for collapse(2)
911 for (
int toy = 0; toy <
Ntoys; ++toy) {
912 const int nDims =
SampleInfo[sample].Dimenstion;
913 for (
int dim = 0; dim < nDims; dim++) {
914 FastViolinFill(Spectra[sample][dim].get(), Toys[sample][toy][dim].get());
921 SampleDirectories[sample]->cd();
922 const int nDims =
SampleInfo[sample].Dimenstion;
923 for (
long unsigned int dim = 0; dim < Spectra[sample].size(); dim++) {
924 Spectra[sample][dim]->Write();
926 if(nDims == 2 && DoSummary) {
927 const std::string name =
SampleInfo[sample].Name +
"_" + suffix+
"_PostPred_dim" + std::to_string(dim);
939 const std::vector<int>& bins)
const {
941 std::string BinName =
"";
943 const int b = bins[0];
944 const TAxis* ax = hist->GetXaxis();
945 const double low = ax->GetBinLowEdge(b);
946 const double up = ax->GetBinUpEdge(b);
948 BinName = fmt::format(
"Dim0 ({:g}, {:g})", low, up);
949 }
else if (Dim == 2) {
950 if(uniform ==
true) {
951 const int bx = bins[0];
952 const int by = bins[1];
953 const TAxis* ax = hist->GetXaxis();
954 const TAxis* ay = hist->GetYaxis();
955 BinName = fmt::format(
"Dim0 ({:g}, {:g}), ", ax->GetBinLowEdge(bx), ax->GetBinUpEdge(bx));
956 BinName += fmt::format(
"Dim1 ({:g}, {:g})", ay->GetBinLowEdge(by), ay->GetBinUpEdge(by));
958 TH2PolyBin* bin =
static_cast<TH2PolyBin*
>(
static_cast<TH2Poly*
>(hist)->GetBins()->At(bins[0]-1));
960 BinName += fmt::format(
"Dim{} ({:g}, {:g})", 0, bin->GetXMin(), bin->GetXMax());
961 BinName += fmt::format(
"Dim{} ({:g}, {:g})", 1, bin->GetYMin(), bin->GetYMax());
964 BinName = hist->GetXaxis()->GetBinLabel(bins[0]);
973 const std::string& suffix)
const {
975 std::vector<std::unique_ptr<TH1D>> PosteriorHistVec;
976 constexpr
int nBins = 100;
977 const std::string Sample_Name =
SampleInfo[SampleId].Name;
979 if(std::string(hist->ClassName()) ==
"TH2Poly") {
980 for (
int i = 1; i <= static_cast<TH2Poly*>(hist)->GetNumberOfBins(); ++i) {
981 std::string ProjName = fmt::format(
"{} {} Bin: {}",
986 auto PosteriorHist = std::make_unique<TH1D>(ProjName.c_str(), ProjName.c_str(), nBins, 1, -1);
987 PosteriorHist->SetDirectory(
nullptr);
988 PosteriorHist->GetXaxis()->SetTitle(
"Events");
989 PosteriorHistVec.push_back(std::move(PosteriorHist));
992 int nbinsx = hist->GetNbinsX();
993 int nbinsy = hist->GetNbinsY();
994 for (
int iy = 1; iy <= nbinsy; ++iy) {
995 for (
int ix = 1; ix <= nbinsx; ++ix) {
996 std::string ProjName = fmt::format(
"{} {} Bin: {}",
1001 auto PosteriorHist = std::make_unique<TH1D>(ProjName.c_str(), ProjName.c_str(), nBins, 1, -1);
1002 PosteriorHist->SetDirectory(
nullptr);
1003 PosteriorHist->GetXaxis()->SetTitle(
"Events");
1004 PosteriorHistVec.push_back(std::move(PosteriorHist));
1009 int nbinsx = hist->GetNbinsX();
1010 PosteriorHistVec.reserve(nbinsx);
1011 for (
int i = 1; i <= nbinsx; ++i) {
1012 std::string ProjName = fmt::format(
"{} {} Bin: {}",
1013 Sample_Name, suffix,
1017 auto PosteriorHist = std::make_unique<TH1D>(ProjName.c_str(), ProjName.c_str(), nBins, 1, -1);
1018 PosteriorHist->SetDirectory(
nullptr);
1019 PosteriorHist->GetXaxis()->SetTitle(
"Events");
1020 PosteriorHistVec.push_back(std::move(PosteriorHist));
1023 return PosteriorHistVec;
1028 const std::vector<TDirectory*>& Directory,
1029 const std::string& suffix,
1030 const bool DebugHistograms,
1031 const bool WriteHist) {
1037 const int nDims =
SampleInfo[sample].Dimenstion;
1038 const std::string Sample_Name =
SampleInfo[sample].Name;
1039 Posterior_hist[sample] =
PerBinHistogram(Toys[sample][0].get(), sample, nDims, suffix);
1040 auto PredictiveHist =
M3::Clone(Toys[sample][0].get());
1042 PredictiveHist->Reset();
1043 PredictiveHist->SetName((Sample_Name +
"_" + suffix +
"_PostPred").c_str());
1044 PredictiveHist->SetTitle((Sample_Name +
"_" + suffix +
"_PostPred").c_str());
1045 PredictiveHist->SetDirectory(
nullptr);
1046 PostPred[sample] = std::move(PredictiveHist);
1051 #pragma omp parallel for
1054 const int nDims =
SampleInfo[sample].Dimenstion;
1055 auto& hist = Toys[sample][0];
1056 for (
size_t iToy = 0; iToy < Toys[sample].size(); ++iToy) {
1058 if(std::string(hist->ClassName()) ==
"TH2Poly") {
1059 for (
int i = 1; i <= static_cast<TH2Poly*>(hist.get())->GetNumberOfBins(); ++i) {
1060 double content = Toys[sample][iToy]->GetBinContent(i);
1061 Posterior_hist[sample][i-1]->Fill(content,
ReweightWeight[iToy]);
1064 int nbinsx = hist->GetNbinsX();
1065 int nbinsy = hist->GetNbinsY();
1066 for (
int iy = 1; iy <= nbinsy; ++iy) {
1067 for (
int ix = 1; ix <= nbinsx; ++ix) {
1068 int Bin = (iy-1) * nbinsx + (ix-1);
1069 double content = Toys[sample][iToy]->GetBinContent(ix, iy);
1070 Posterior_hist[sample][Bin]->Fill(content,
ReweightWeight[iToy]);
1075 int nbinsx = hist->GetNbinsX();
1076 for (
int i = 1; i <= nbinsx; ++i) {
1077 double content = Toys[sample][iToy]->GetBinContent(i);
1078 Posterior_hist[sample][i-1]->Fill(content,
ReweightWeight[iToy]);
1086 const int nDims =
SampleInfo[sample].Dimenstion;
1087 auto& hist = Toys[sample][0];
1088 Directory[sample]->cd();
1090 if(std::string(hist->ClassName()) ==
"TH2Poly") {
1091 for (
int i = 1; i <= static_cast<TH2Poly*>(hist.get())->GetNumberOfBins(); ++i) {
1092 PostPred[sample]->SetBinContent(i, Posterior_hist[sample][i-1]->GetMean());
1094 PostPred[sample]->SetBinError(i, Posterior_hist[sample][i-1]->GetRMS());
1095 if (DebugHistograms) Posterior_hist[sample][i-1]->Write();
1098 int nbinsx = hist->GetNbinsX();
1099 int nbinsy = hist->GetNbinsY();
1100 for (
int iy = 1; iy <= nbinsy; ++iy) {
1101 for (
int ix = 1; ix <= nbinsx; ++ix) {
1102 int Bin = (iy-1) * nbinsx + (ix-1);
1103 if (DebugHistograms) Posterior_hist[sample][Bin]->Write();
1104 PostPred[sample]->SetBinContent(ix, iy, Posterior_hist[sample][Bin]->GetMean());
1105 PostPred[sample]->SetBinError(ix, iy, Posterior_hist[sample][Bin]->GetRMS());
1110 int nbinsx = hist->GetNbinsX();
1111 for (
int i = 1; i <= nbinsx; ++i) {
1112 PostPred[sample]->SetBinContent(i, Posterior_hist[sample][i-1]->GetMean());
1113 PostPred[sample]->SetBinError(i, Posterior_hist[sample][i-1]->GetRMS());
1114 if (DebugHistograms) Posterior_hist[sample][i-1]->Write();
1117 if(WriteHist) PostPred[sample]->Write();
1133 TStopwatch TempClock;
1136 auto DebugHistograms = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"DebugHistograms"],
false, __FILE__, __LINE__);
1137 auto doByMode = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"ByMode"],
false, __FILE__, __LINE__);
1139 TDirectory* PredictiveDir =
outputFile->mkdir(
"Predictive");
1140 std::vector<TDirectory*> SampleDirectories;
1145 SampleDirectories[sample] = PredictiveDir->mkdir(
SampleInfo[sample].Name.c_str());
1165 SampleDirectories[sample]->Close();
1166 delete SampleDirectories[sample];
1169 auto StudyBeta = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"StudyBetaParameters"],
true, __FILE__, __LINE__);
1170 auto StudyInfoCriterion = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"StudyInformationCriterion"],
true, __FILE__, __LINE__);
1171 auto StudyCorr = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"StudyCorrelations"],
true, __FILE__, __LINE__);
1180 PredictiveDir->Close();
1181 delete PredictiveDir;
1186 MACH3LOG_INFO(
"{} took {:.2f}s to finish for {} toys", __func__, TempClock.RealTime(),
Ntoys);
1207 if (
auto h1 =
dynamic_cast<const TH1D*
>(DatHist)) {
1209 static_cast<const TH1D*
>(MCHist),
1210 static_cast<const TH1D*
>(W2Hist),
1215 if (
auto h2 =
dynamic_cast<const TH2D*
>(DatHist)) {
1217 static_cast<const TH2D*
>(MCHist),
1218 static_cast<const TH2D*
>(W2Hist),
1223 if (
auto h2p =
dynamic_cast<const TH2Poly*
>(DatHist)) {
1225 static_cast<const TH2Poly*
>(MCHist),
1226 static_cast<const TH2Poly*
>(W2Hist),
1241 for (
int i = 1; i <= DatHist->GetXaxis()->GetNbins(); ++i)
1243 const double data = DatHist->GetBinContent(i);
1244 const double mc = MCHist->GetBinContent(i);
1245 const double w2 = W2Hist->GetBinContent(i);
1254 const TH2Poly* MCHist,
1255 const TH2Poly* W2Hist,
1259 for (
int i = 1; i <= DatHist->GetNumberOfBins(); ++i)
1261 const double data = DatHist->GetBinContent(i);
1262 const double mc = MCHist->GetBinContent(i);
1263 const double w2 = W2Hist->GetBinContent(i);
1278 const int nBinsX = DatHist->GetXaxis()->GetNbins();
1279 const int nBinsY = DatHist->GetYaxis()->GetNbins();
1281 for (
int i = 1; i <= nBinsX; ++i)
1283 for (
int j = 1; j <= nBinsY; ++j)
1285 const double data = DatHist->GetBinContent(i, j);
1286 const double mc = MCHist->GetBinContent(i, j);
1287 const double w2 = W2Hist->GetBinContent(i, j);
1302 auto applyFluctuation = [&](
auto* f,
auto* h) {
1310 if (Hist->InheritsFrom(TH2Poly::Class())) {
1311 applyFluctuation(
static_cast<TH2Poly*
>(FluctHist),
static_cast<TH2Poly*
>(Hist));
1313 else if (Hist->InheritsFrom(TH2D::Class())) {
1314 applyFluctuation(
static_cast<TH2D*
>(FluctHist),
static_cast<TH2D*
>(Hist));
1316 else if (Hist->InheritsFrom(TH1D::Class())) {
1317 applyFluctuation(
static_cast<TH1D*
>(FluctHist),
static_cast<TH1D*
>(Hist));
1327 const std::vector<TDirectory*>& SampleDir) {
1331 auto make_matrix = [&](
double init = 0.0) {
1332 return std::vector<std::vector<double>>(
1334 std::vector<double>(
Ntoys, init));
1336 auto chi2_dat = make_matrix();
1337 auto chi2_mc = make_matrix();
1338 auto chi2_pred = make_matrix();
1339 auto chi2_rate_dat = make_matrix();
1340 auto chi2_rate_mc = make_matrix();
1341 auto chi2_rate_pred = make_matrix();
1344 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
1356 auto SampleHandler =
SampleInfo[iSample].SamHandler;
1357 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
1360 auto PredFluctHist =
M3::Clone(PostPred_mc[iSample].get());
1373 chi2_rate_mc[iSample][iToy] =
CalcLLH(DrawFluctHist->Integral(),
MC_Hist_Toy[iSample][iToy]->Integral(),
W2_Hist_Toy[iSample][iToy]->Integral(), SampleHandler);
1374 chi2_rate_pred[iSample][iToy] =
CalcLLH(PredFluctHist->Integral(),
MC_Hist_Toy[iSample][iToy]->Integral(),
W2_Hist_Toy[iSample][iToy]->Integral(), SampleHandler);
1389 MakeChi2Plots(chi2_mc,
"-2LLH (Draw Fluc, Draw)", chi2_dat,
"-2LLH (Data, Draw)", SampleDir,
"_drawfluc_draw");
1390 MakeChi2Plots(chi2_pred,
"-2LLH (Pred Fluc, Draw)", chi2_dat,
"-2LLH (Data, Draw)", SampleDir,
"_predfluc_draw");
1393 MakeChi2Plots(chi2_rate_mc,
"-2LLH (Rate Draw Fluc, Draw)", chi2_rate_dat,
"-2LLH (Rate Data, Draw)", SampleDir,
"_rate_drawfluc_draw");
1394 MakeChi2Plots(chi2_rate_pred,
"-2LLH (Rate Pred Fluc, Draw)", chi2_rate_dat,
"-2LLH (Rate Data, Draw)", SampleDir,
"_rate_predfluc_draw");
1399 const std::vector<std::unique_ptr<TH1>>& PostPred_mc,
1400 const std::vector<std::unique_ptr<TH1>>& PostPred_w,
1401 const std::vector<TDirectory*>& SampleDir) {
1403 MACH3LOG_INFO(
"{:<55} {:<10} {:<10} {:<10}",
"Sample",
"DataInt",
"MCInt",
"-2LLH");
1404 MACH3LOG_INFO(
"{:-<55} {:-<10} {:-<10} {:-<10}",
"",
"",
"",
"");
1406 SampleDir[iSample]->cd();
1407 ExtractLLH(Data_histogram[iSample].get(), PostPred_mc[iSample].get(), PostPred_w[iSample].get(),
SampleInfo[iSample].SamHandler);
1408 PostPred_mc[iSample]->Write();
1415 const std::string& Chi2_x_title,
1416 const std::vector<std::vector<double>>& Chi2_y,
1417 const std::string& Chi2_y_title,
1418 const std::vector<TDirectory*>& SampleDir,
1419 const std::string Title) {
1422 SampleDir[iSample]->cd();
1425 std::vector<double> chi2_y_sample(
Ntoys);
1426 std::vector<double> chi2_x_per_sample(
Ntoys);
1428 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
1429 chi2_y_sample[iToy] = Chi2_y[iSample][iToy];
1430 chi2_x_per_sample[iToy] = Chi2_x[iSample][iToy];
1433 const double min_val = std::min(*std::min_element(chi2_y_sample.begin(), chi2_y_sample.end()),
1434 *std::min_element(chi2_x_per_sample.begin(), chi2_x_per_sample.end()));
1435 const double max_val = std::max(*std::max_element(chi2_y_sample.begin(), chi2_y_sample.end()),
1436 *std::max_element(chi2_x_per_sample.begin(), chi2_x_per_sample.end()));
1438 auto chi2_hist = std::make_unique<TH2D>((
SampleInfo[iSample].Name+ Title).c_str(),
1440 50, min_val, max_val, 50, min_val, max_val);
1441 chi2_hist->SetDirectory(
nullptr);
1442 chi2_hist->GetXaxis()->SetTitle(Chi2_x_title.c_str());
1443 chi2_hist->GetYaxis()->SetTitle(Chi2_y_title.c_str());
1445 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
1446 chi2_hist->Fill(chi2_x_per_sample[iToy], chi2_y_sample[iToy]);
1458 bool StudyBeta = GetFromManager<bool>(
fitMan->
raw()[
"Predictive"][
"StudyBetaParameters"],
true, __FILE__, __LINE__ );
1459 if (StudyBeta ==
false)
return;
1462 TDirectory* BetaDir = PredictiveDir->mkdir(
"BetaParameters");
1468 DirBeta[sample] = BetaDir->mkdir(
SampleInfo[sample].Name.c_str());
1473 const int nDims =
SampleInfo[iSample].Dimenstion;
1475 TH1* RefHist =
Data_Hist[iSample].get();
1476 BetaHist[iSample] =
PerBinHistogram(RefHist, iSample, nDims,
"Beta_Parameter");
1478 for (
size_t i = 0; i < BetaHist[iSample].size(); ++i) {
1479 BetaHist[iSample][i]->GetXaxis()->SetTitle(
"beta parameter");
1485 #pragma omp parallel for
1488 const int nDims =
SampleInfo[iSample].Dimenstion;
1489 const auto likelihood =
SampleInfo[iSample].SamHandler->GetTestStatistic();
1490 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
1492 if(std::string(
Data_Hist[iSample]->ClassName()) ==
"TH2Poly") {
1493 for (
int i = 1; i <= static_cast<TH2Poly*>(
Data_Hist[iSample].get())->GetNumberOfBins(); ++i) {
1494 const double Data =
Data_Hist[iSample]->GetBinContent(i);
1495 const double MC =
MC_Hist_Toy[iSample][iToy]->GetBinContent(i);
1496 const double w2 =
W2_Hist_Toy[iSample][iToy]->GetBinContent(i);
1502 const int nX =
Data_Hist[iSample]->GetNbinsX();
1503 const int nY =
Data_Hist[iSample]->GetNbinsY();
1504 for (
int iy = 1; iy <= nY; ++iy) {
1505 for (
int ix = 1; ix <= nX; ++ix) {
1506 const int FlatBin = (iy-1) * nX + (ix-1);
1508 const double Data =
Data_Hist[iSample]->GetBinContent(ix, iy);
1509 const double MC =
MC_Hist_Toy[iSample][iToy]->GetBinContent(ix, iy);
1510 const double w2 =
W2_Hist_Toy[iSample][iToy]->GetBinContent(ix, iy);
1513 BetaHist[iSample][FlatBin]->Fill(BetaParam,
ReweightWeight[iToy]);
1518 int nbinsx =
Data_Hist[iSample]->GetNbinsX();
1519 for (
int ix = 1; ix <= nbinsx; ++ix) {
1521 const double Data =
Data_Hist[iSample]->GetBinContent(ix);
1522 const double MC =
MC_Hist_Toy[iSample][iToy]->GetBinContent(ix);
1523 const double w2 =
W2_Hist_Toy[iSample][iToy]->GetBinContent(ix);
1534 for (
size_t iBin = 0; iBin < BetaHist[iSample].size(); iBin++) {
1535 DirBeta[iSample]->cd();
1536 BetaHist[iSample][iBin]->Write();
1538 DirBeta[iSample]->Close();
1539 delete DirBeta[iSample];
1544 PredictiveDir->cd();
1550 const std::vector<std::vector<std::unique_ptr<TH1>>>& Toys,
1551 const bool DebugHistograms)
const {
1556 TDirectory *CorrDir = PredictiveDir->mkdir(
"Correlations");
1562 #pragma omp parallel for
1566 for (
const auto& toyHist : Toys[i])
1568 const double val = toyHist->Integral();
1569 if (val < minVals[i]) minVals[i] = val;
1570 if (val > maxVals[i]) maxVals[i] = val;
1573 auto hSamCorr = std::make_unique<TH2D>(
"Sample Correlation",
"Sample Correlation",
TotalNumberOfSamples, 0,
1575 hSamCorr->SetDirectory(
nullptr);
1576 hSamCorr->GetZaxis()->SetTitle(
"Correlation");
1577 hSamCorr->SetMinimum(-1);
1578 hSamCorr->SetMaximum(1);
1579 hSamCorr->GetXaxis()->SetLabelSize(0.015);
1580 hSamCorr->GetYaxis()->SetLabelSize(0.015);
1583 hSamCorr->SetBinContent(i+1, i+1, 1.0);
1584 hSamCorr->GetXaxis()->SetBinLabel(i+1,
SampleInfo[i].Name.c_str());
1586 hSamCorr->GetYaxis()->SetBinLabel(j+1,
SampleInfo[j].Name.c_str());
1594 const double Min_i = minVals[i];
1595 const double Max_i = maxVals[i];
1598 const double Min_j = minVals[j];
1599 const double Max_j = maxVals[j];
1601 std::string name =
"SamCorr_" + std::to_string(i) +
"_" + std::to_string(j);
1602 SamCorr[i][j] = std::make_unique<TH2D>(name.c_str(), name.c_str(), 70, Min_i, Max_i, 70, Min_j, Max_j);
1603 SamCorr[i][j]->SetDirectory(
nullptr);
1604 SamCorr[i][j]->SetMinimum(0);
1605 SamCorr[i][j]->GetXaxis()->SetTitle(
SampleInfo[i].Name.c_str());
1606 SamCorr[i][j]->GetYaxis()->SetTitle(
SampleInfo[j].Name.c_str());
1607 SamCorr[i][j]->GetZaxis()->SetTitle(
"Events");
1613 #pragma omp parallel for
1617 for (
int j = 0; j <= i; ++j)
1620 if (j == i)
continue;
1622 for (
int iToy = 0; iToy <
Ntoys; ++iToy)
1624 SamCorr[i][j]->Fill(Toys[i][iToy]->Integral(), Toys[j][iToy]->Integral());
1626 SamCorr[i][j]->Smooth();
1629 const double corr = SamCorr[i][j]->GetCorrelationFactor();
1630 hSamCorr->SetBinContent(i+1, j+1, corr);
1631 hSamCorr->SetBinContent(j+1, i+1, corr);
1635 hSamCorr->Draw(
"colz");
1636 hSamCorr->Write(
"Sample_Corr");
1638 if(DebugHistograms) {
1640 for (
int j = 0; j <= i; ++j) {
1642 if (j == i)
continue;
1643 SamCorr[i][j]->Write();
1648 PredictiveDir->cd();
1655 const double llh =
CalcLLH(DatHist, MCHist, W2Hist, SampleHandler);
1656 std::stringstream ss;
1657 ss <<
"_2LLH=" << llh;
1658 MCHist->SetTitle((std::string(MCHist->GetTitle())+ss.str()).c_str());
1659 MACH3LOG_INFO(
"{:<55} {:<10.2f} {:<10.2f} {:<10.2f}", MCHist->GetName(), DatHist->Integral(), MCHist->Integral(), llh);
1667 int originalErrorWarning = gErrorIgnoreLevel;
1668 gErrorIgnoreLevel = kFatal;
1671 auto TempLine = std::make_unique<TLine>(DataRate, Histogram->GetMinimum(), DataRate, Histogram->GetMaximum());
1672 TempLine->SetLineColor(kRed);
1673 TempLine->SetLineWidth(2);
1675 auto Fitter = std::make_unique<TF1>(
"Fit",
"gaus", Histogram->GetBinLowEdge(1), Histogram->GetBinLowEdge(Histogram->GetNbinsX()+1));
1676 Histogram->Fit(Fitter.get(),
"RQ");
1677 Fitter->SetLineColor(kRed-5);
1680 for (
int z = 0; z < Histogram->GetNbinsX(); ++z) {
1681 const double xvalue = Histogram->GetBinCenter(z+1);
1682 if (xvalue >= DataRate) {
1683 Above += Histogram->GetBinContent(z+1);
1686 const double pvalue = Above/Histogram->Integral();
1687 TLegend Legend(0.4, 0.75, 0.98, 0.90);
1688 Legend.SetFillColor(0);
1689 Legend.SetFillStyle(0);
1690 Legend.SetLineWidth(0);
1691 Legend.SetLineColor(0);
1692 Legend.AddEntry(TempLine.get(), Form(
"Data, %.0f, p-value=%.2f", DataRate, pvalue),
"l");
1693 Legend.AddEntry(Histogram, Form(
"MC, #mu=%.1f#pm%.1f", Histogram->GetMean(), Histogram->GetRMS()),
"l");
1694 Legend.AddEntry(Fitter.get(), Form(
"Gauss, #mu=%.1f#pm%.1f", Fitter->GetParameter(1), Fitter->GetParameter(2)),
"l");
1695 std::string TempTitle = std::string(Histogram->GetName());
1696 TempTitle +=
"_canv";
1697 TCanvas TempCanvas(TempTitle.c_str(), TempTitle.c_str(), 1024, 1024);
1698 TempCanvas.SetGridx();
1699 TempCanvas.SetGridy();
1700 TempCanvas.SetRightMargin(0.03);
1701 TempCanvas.SetBottomMargin(0.08);
1702 TempCanvas.SetLeftMargin(0.10);
1703 TempCanvas.SetTopMargin(0.06);
1706 TempLine->Draw(
"same");
1707 Fitter->Draw(
"same");
1708 Legend.Draw(
"same");
1711 gErrorIgnoreLevel = originalErrorWarning;
1716 const std::vector<TDirectory*>& SampleDirectories)
const {
1720 std::string Title =
"EventHist: ";
1729 EventHist[iSample] = std::make_unique<TH1D>(Title.c_str(), Title.c_str(), 100, 1, -1);
1730 EventHist[iSample]->SetDirectory(
nullptr);
1731 EventHist[iSample]->GetXaxis()->SetTitle(
"Total event rate");
1732 EventHist[iSample]->GetYaxis()->SetTitle(
"Counts");
1733 EventHist[iSample]->SetLineWidth(2);
1738 #pragma omp parallel for
1741 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
1742 double Count = Toys[iSample][iToy]->Integral();
1743 EventHist[iSample]->Fill(Count);
1748 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
1749 double TotalCount = 0.0;
1751 TotalCount += Toys[iSample][iToy]->Integral();
1756 double DataRate = 0.0;
1759 #pragma omp parallel for reduction(+:DataRate)
1762 DataRates[i] =
Data_Hist[i]->Integral();
1763 DataRate += DataRates[i];
1768 SampleDirectories[SampleNum]->cd();
1777 const std::vector<std::unique_ptr<TH1>>& PostPred_mc,
1778 const std::vector<std::unique_ptr<TH1>>& PostPred_w) {
1807 const std::vector<std::unique_ptr<TH1>>& PostPred_w) {
1810 double DataRate = 0.0;
1811 double BinsRate = 0.0;
1812 double TotalLLH = 0.0;
1814 #pragma omp parallel for reduction(+:DataRate, BinsRate, TotalLLH)
1818 auto SampleHandler =
SampleInfo[i].SamHandler;
1820 DataRate += h->Integral();
1821 if (
auto h1 =
dynamic_cast<TH1D*
>(h)) {
1822 BinsRate += h1->GetNbinsX();
1823 }
else if (
auto h2 =
dynamic_cast<TH2D*
>(h)) {
1824 BinsRate += h2->GetNbinsX() * h2->GetNbinsY();
1825 }
else if (
auto h2poly =
dynamic_cast<TH2Poly*
>(h)) {
1826 BinsRate += h2poly->GetNumberOfBins();
1830 TotalLLH +=
CalcLLH(
Data_Hist[i].get(), PostPred_mc[i].get(), PostPred_w[i].get(), SampleHandler);
1835 MACH3LOG_INFO(
"Calculated Bayesian Information Criterion using global number of events: {:.2f}", EventRateBIC);
1836 MACH3LOG_INFO(
"Calculated Bayesian Information Criterion using global number of bins: {:.2f}", BinBasedBIC);
1837 MACH3LOG_INFO(
"Additional info: NModelParams: {}, DataRate: {:.2f}, BinsRate: {:.2f}",
NModelParams, DataRate, BinsRate);
1843 const std::vector<std::unique_ptr<TH1>>& PostPred_w) {
1847 double TotalLLH = 0.0;
1850 #pragma omp parallel for reduction(+:Dbar)
1854 auto SampleHandler =
SampleInfo[iSample].SamHandler;
1855 TotalLLH +=
CalcLLH(
Data_Hist[iSample].get(), PostPred_mc[iSample].get(), PostPred_w[iSample].get(), SampleHandler);
1856 double LLH_temp = 0.;
1857 for (
int iToy = 0; iToy <
Ntoys; ++iToy)
1863 Dbar = Dbar /
Ntoys;
1866 const double Dhat = TotalLLH;
1869 const double p_D = std::fabs(Dbar - Dhat);
1872 const double DIC_stat = Dhat + 2 * p_D;
1873 MACH3LOG_INFO(
"Effective number of parameters following DIC formalism is equal to: {:.2f}", p_D);
1882 double& mean_llh_squared,
1883 double& sum_exp_llh) {
1886 double LLH_temp = -neg_LLH_temp;
1888 mean_llh += LLH_temp;
1889 mean_llh_squared += LLH_temp * LLH_temp;
1890 sum_exp_llh += std::exp(LLH_temp);
1896 const unsigned int Ntoys,
double& lppd,
double& p_WAIC) {
1900 mean_llh_squared /=
Ntoys;
1901 sum_exp_llh /=
Ntoys;
1902 sum_exp_llh = std::log(sum_exp_llh);
1905 lppd += sum_exp_llh;
1908 p_WAIC += mean_llh_squared - (mean_llh * mean_llh);
1921 #pragma omp parallel for reduction(+:lppd, p_WAIC)
1924 auto SampleHandler =
SampleInfo[iSample].SamHandler;
1927 if (
auto h2poly =
dynamic_cast<TH2Poly*
>(hData)) {
1929 for (
int i = 1; i <= h2poly->GetNumberOfBins(); ++i) {
1930 const double data =
Data_Hist[iSample]->GetBinContent(i);
1931 double mean_llh = 0.;
1932 double sum_exp_llh = 0;
1933 double mean_llh_squared = 0.;
1935 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
1936 const double mc =
MC_Hist_Toy[iSample][iToy]->GetBinContent(i);
1937 const double w2 =
W2_Hist_Toy[iSample][iToy]->GetBinContent(i);
1939 double neg_LLH_temp = SampleHandler->GetTestStatLLH(data, mc, w2);
1944 }
else if (
auto h2 =
dynamic_cast<TH2D*
>(hData)) {
1946 for (
int ix = 1; ix <= h2->GetNbinsX(); ++ix) {
1947 for (
int iy = 1; iy <= h2->GetNbinsY(); ++iy) {
1948 const double data = hData->GetBinContent(ix, iy);
1949 double mean_llh = 0.;
1950 double mean_llh_squared = 0.;
1951 double sum_exp_llh = 0.;
1952 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
1953 const double mc =
MC_Hist_Toy[iSample][iToy]->GetBinContent(ix, iy);
1954 const double w2 =
W2_Hist_Toy[iSample][iToy]->GetBinContent(ix, iy);
1956 double neg_LLH_temp = SampleHandler->GetTestStatLLH(data, mc, w2);
1962 }
else if (
auto h1 =
dynamic_cast<TH1D*
>(hData)) {
1964 for (
int iBin = 1; iBin <= h1->GetNbinsX(); ++iBin) {
1965 const double data = hData->GetBinContent(iBin);
1966 double mean_llh = 0.;
1967 double mean_llh_squared = 0.;
1968 double sum_exp_llh = 0.;
1969 for (
int iToy = 0; iToy <
Ntoys; ++iToy) {
1970 const double mc =
MC_Hist_Toy[iSample][iToy]->GetBinContent(iBin);
1971 const double w2 =
W2_Hist_Toy[iSample][iToy]->GetBinContent(iBin);
1974 double neg_LLH_temp = SampleHandler->GetTestStatLLH(data, mc, w2);
1983 double WAIC = -2 * (lppd - p_WAIC);
1984 MACH3LOG_INFO(
"Effective number of parameters following WAIC formalism is equal to: {:.2f}", p_WAIC);
void MakeFluctuatedHistogramAlternative(TH1D *FluctHist, TH1D *PolyHist, TRandom3 *rand)
Make Poisson fluctuation of TH1D hist using slow method which is only for cross-check.
void MakeFluctuatedHistogramStandard(TH1D *FluctHist, TH1D *PolyHist, TRandom3 *rand)
Make Poisson fluctuation of TH1D hist using default fast method.
TH1D * PolyProjectionX(TObject *poly, const std::string &TempName, const std::vector< double > &xbins, const bool computeErrors)
WP: Poly Projectors.
void FastViolinFill(TH2D *violin, TH1D *hist_1d)
KS: Fill Violin histogram with entry from a toy.
TH1D * PolyProjectionY(TObject *poly, const std::string &TempName, const std::vector< double > &ybins, const bool computeErrors)
WP: Poly Projectors.
std::unique_ptr< TH1D > MakeSummaryFromSpectra(const TH2D *Spectra, const std::string &name)
Build a 1D posterior-predictive summary from a violin spectrum.
void AccumulateWAICToy(const double neg_LLH_temp, double &mean_llh, double &mean_llh_squared, double &sum_exp_llh)
bool CheckBounds(const std::vector< const M3::float_t * > &BoundValuePointer, const std::vector< std::pair< double, double >> &ParamBounds)
void AccumulateWAICBin(double &mean_llh, double &mean_llh_squared, double &sum_exp_llh, const unsigned int Ntoys, double &lppd, double &p_WAIC)
double GetBetaParameter(const double data, const double mc, const double w2, const TestStatistic TestStat)
KS: Calculate Beta parameter which will be different based on specified test statistic.
double GetBIC(const double llh, const int data, const int nPars)
Get the Bayesian Information Criterion (BIC) or Schwarz information criterion (also SIC,...
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.
TFile * outputFile
Output.
std::string AlgorithmName
Name of fitting algorithm that is being used.
std::vector< SampleHandlerInterface * > samples
Sample holder.
Manager * fitMan
The manager for configuration handling.
void SanitiseInputs()
Remove obsolete memory and make other checks before fit starts.
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...
std::vector< std::string > GetUniqueParameterGroups() const
KS: Get names of all unique parameter groups.
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< double > PenaltyTerm
Penalty term values for each toy by default 0.
virtual ~PredictiveThrower()
Destructor.
void ExtractLLH(TH1 *DatHist, TH1 *MCHist, TH1 *W2Hist, const SampleHandlerInterface *SampleHandler) const
Calculate the LLH for TH1, set the LLH to title of MCHist.
bool FullLLH
KS: Use Full LLH or only sample contribution based on discussion with Asher we almost always only wan...
void WriteToy(TDirectory *ToyDirectory, TDirectory *Toy_1DDirectory, TDirectory *Toy_2DDirectory, const int iToy)
Save histograms for a single MCMC Throw/Toy.
void StudyCorrelations(TDirectory *PredictiveDir, const std::vector< std::vector< std::unique_ptr< TH1 >>> &Toys, const bool DebugHistograms) const
Study Prior/Posterior correlations between samples etc.
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 Compares observed data to toy datasets generated from:
void WriteByModeToys(TDirectory *ByModeDirectory, const int iToy)
Save mode histograms for a single MCMC Throw/Toy.
void StudyBIC(const std::vector< std::unique_ptr< TH1 >> &PostPred_mc, const std::vector< std::unique_ptr< TH1 >> &PostPred_w)
Study Bayesian Information Criterion (BIC) The BIC is defined as:
void SetupToyGeneration(std::vector< std::string > &ParameterGroupsNotVaried, std::unordered_set< int > &ParameterOnlyToVary, std::vector< const M3::float_t * > &BoundValuePointer, std::vector< std::pair< double, double >> &ParamBounds)
Setup useful variables etc before stating toy generation.
std::string GetBinName(TH1 *hist, const bool uniform, const int Dim, const std::vector< int > &bins) const
Construct a human-readable label describing a specific analysis bin.
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::vector< std::vector< std::unique_ptr< TH1 > > > W2_Hist_Toy
bool Is_PriorPredictive
Whether it is Prior or Posterior predictive.
int NModelParams
KS: Count total number of model parameters which can be used for stuff like BIC.
void MakeCutEventRate(TH1D *Histogram, const double DataRate) const
Make the 1D Event Rate Hist.
void StudyInformationCriterion(M3::kInfCrit Criterion, const std::vector< std::unique_ptr< TH1 >> &PostPred_mc, const std::vector< std::unique_ptr< TH1 >> &PostPred_w)
Information Criterion.
int Ntoys
Number of toys we are generating analysing.
void StudyByMode1DProjections(const std::vector< TDirectory * > &SampleDirectories) const
Load 1D projections by mode and produce post pred for each.
void PredictiveLLH(const std::vector< std::unique_ptr< TH1 >> &Data_histogram, const std::vector< std::unique_ptr< TH1 >> &PostPred_mc, const std::vector< std::unique_ptr< TH1 >> &PostPred_w, const std::vector< TDirectory * > &SampleDir)
Calculate Posterior Predictive LLH.
void RateAnalysis(const std::vector< std::vector< std::unique_ptr< TH1 >>> &Toys, const std::vector< TDirectory * > &SampleDirectories) const
Produce distribution of number of events for each sample.
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 SetParamters(std::vector< std::string > &ParameterGroupsNotVaried, std::unordered_set< int > &ParameterOnlyToVary)
This set some params to prior value this way you can evaluate errors from subset of errors.
void StudyWAIC()
KS: Get the Watanabe-Akaike information criterion (WAIC)
void Study1DProjections(const std::vector< TDirectory * > &SampleDirectories) const
Load 1D projections and later produce violin plots for each.
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...
double CalcLLH(const double data, const double mc, const double w2, const SampleHandlerInterface *SampleHandler) const
Calculates the -2LLH (likelihood) for a single sample.
std::vector< std::unique_ptr< TH1 > > Data_Hist
Vector of Data histograms.
bool StandardFluctuation
KS: We have two methods for Poissonian fluctuation.
ParameterHandlerGeneric * ModelSystematic
Pointer to El Generico.
std::vector< double > ReweightWeight
Reweighting factors applied for each toy, by default 1.
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, const bool WriteHist)
Produce posterior predictive distribution.
PredictiveThrower(Manager *const fitMan)
Constructor.
void MakeFluctuatedHistogram(TH1 *FluctHist, TH1 *PolyHist)
Make Poisson fluctuation of TH1D hist.
std::vector< std::vector< std::unique_ptr< TH1 > > > MC_Hist_Toy
void StudyDIC(const std::vector< std::unique_ptr< TH1 >> &PostPred_mc, const std::vector< std::unique_ptr< TH1 >> &PostPred_w)
KS: Get the Deviance Information Criterion (DIC) The deviance is defined as:
double GetLLH(const TH1D *DatHist, const TH1D *MCHist, const TH1D *W2Hist, const SampleHandlerInterface *SampleHandler) const
Helper functions to calculate likelihoods using TH1D.
void ProduceSpectra(const std::vector< std::vector< std::vector< std::unique_ptr< TH1D >>>> &Toys, const std::vector< TDirectory * > &Director, const std::string suffix, const bool DoSummary=true) const
Produce Violin style spectra.
std::vector< std::unique_ptr< TH1D > > PerBinHistogram(TH1 *hist, const int SampleId, const int Dim, const std::string &suffix) const
Create per-bin posterior histograms for a given sample.
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....
int getValue(const std::string &Type)
CW: Get info like RAM.
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.
kInfCrit
KS: Different Information Criterion tests mostly based Gelman paper.
@ kWAIC
Watanabe-Akaike information criterion.
@ kInfCrits
This only enumerates.
@ kBIC
Bayesian Information Criterion.
@ kDIC
Deviance Information Criterion.
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.
KS: Store info about MC sample.