7 #include "TStopwatch.h"
9 #include "TGraphAsymmErrors.h"
13 #pragma GCC diagnostic ignored "-Wuseless-cast"
22 random = std::make_unique<TRandom3>(Get<int>(
fitMan->
raw()[
"General"][
"Seed"], __FILE__, __LINE__));
29 clock = std::make_unique<TStopwatch>();
30 stepClock = std::make_unique<TStopwatch>();
33 debug = GetFromManager<bool>(
fitMan->
raw()[
"General"][
"Debug"],
false, __FILE__ , __LINE__);
36 auto outfile = Get<std::string>(
fitMan->
raw()[
"General"][
"OutputFile"], __FILE__ , __LINE__);
39 auto_save = Get<int>(
fitMan->
raw()[
"General"][
"MCMC"][
"AutoSave"], __FILE__ , __LINE__);
45 outTree =
new TTree(
"posteriors",
"Posterior_Distributions");
61 if (debug) debugFile.open((outfile+
".log").c_str());
65 fTestLikelihood = GetFromManager<bool>(
fitMan->
raw()[
"General"][
"Fitter"][
"FitTestLikelihood"],
false, __FILE__ , __LINE__);
86 TDirectory* MaCh3Version =
outputFile->mkdir(
"MaCh3Engine");
89 if (std::getenv(
"MaCh3_ROOT") ==
nullptr) {
95 if (std::getenv(
"MACH3") ==
nullptr) {
100 std::string header_path = std::string(std::getenv(
"MACH3"));
101 header_path +=
"/version.h";
102 FILE* file = fopen(header_path.c_str(),
"r");
105 header_path = std::string(std::getenv(
"MaCh3_ROOT"));
106 header_path +=
"/version.h";
112 TMacro versionHeader(
"version_header",
"version_header");
113 versionHeader.ReadFile(header_path.c_str());
114 versionHeader.Write();
122 Engine.Write(
GetName().c_str());
124 MaCh3Version->Write();
136 for(
unsigned int i = 0; i <
systematics.size(); ++i)
139 for(
unsigned int i = 0; i <
samples.size(); ++i) {
141 for(
int iSam = 0; iSam <
samples[i]->GetNSamples(); ++iSam) {
142 MACH3LOG_INFO(
" {}: Sample title: {}, with {} osc channels",iSam ,
samples[i]->GetSampleTitle(iSam),
samples[i]->GetNOscChannels(iSam));
167 bool SaveProposal = GetFromManager<bool>(
fitMan->
raw()[
"General"][
"SaveProposal"],
false, __FILE__ , __LINE__);
169 if(SaveProposal)
MACH3LOG_INFO(
"Will save in the chain proposal parameters and LogL");
172 cov->SetBranches(*
outTree, SaveProposal);
186 for (
size_t i = 0; i <
samples.size(); ++i) {
187 std::stringstream oss, oss2;
188 oss <<
"LogL_sample_" << i;
189 oss2 << oss.str() <<
"/D";
194 std::stringstream oss, oss2;
195 oss <<
"LogL_systematic_" <<
systematics[i]->GetName();
196 oss2 << oss.str() <<
"/D";
208 MACH3LOG_INFO(
"-------------------- Starting MCMC --------------------");
211 debugFile <<
"----- Starting MCMC -----" << std::endl;
226 for (
size_t i = 0; i <
samples.size(); ++i) {
227 samples[i]->CleanMemoryBeforeFit();
239 int originalErrorLevel = gErrorIgnoreLevel;
240 gErrorIgnoreLevel = kFatal;
250 debugFile <<
"\n\n" <<
step <<
" steps took " <<
clock->RealTime() <<
" seconds to complete. (" <<
clock->RealTime() /
step <<
"s / step).\n" <<
accCount<<
" steps were accepted." << std::endl;
258 gErrorIgnoreLevel = originalErrorLevel;
266 for (
const auto &s :
samples) {
267 for (
int iExisting = 0; iExisting < s->GetNSamples(); ++iExisting) {
268 for (
int iNew = 0; iNew < sample->
GetNSamples(); ++iNew) {
269 if (s->GetSampleTitle(iExisting) == sample->
GetSampleTitle(iNew)) {
271 "Duplicate sample title '{}' in handler {} detected: "
273 sample->
GetName(), s->GetName());
280 for (
const auto &s :
samples) {
281 if (s->GetName() == sample->
GetName()) {
305 for (
int iPar = 0; iPar <
systematics[s]->GetNumParams(); ++iPar)
310 MACH3LOG_ERROR(
"ParameterHandler {} has param '{}' which already exists in in {}, with name {}",
316 MACH3LOG_ERROR(
"ParameterHandler {} has param '{}' which already exists in {}, with name {}",
334 CorrMatrix->Write((cov->
GetName() + std::string(
"_Corr")).c_str());
352 TFile *infile =
M3::Open(FitName,
"READ", __FILE__, __LINE__);
353 TTree *posts = infile->Get<TTree>(
"posteriors");
355 posts->SetBranchAddress(
"LogL",&log_val);
359 TDirectory* CovarianceFolder = infile->Get<TDirectory>(
"CovarianceFolder");
361 std::string ConfigName =
"Config_" +
systematics[s]->GetName();
362 TMacro *ConfigCov = CovarianceFolder->Get<TMacro>(ConfigName.c_str());
364 if (ConfigCov !=
nullptr) {
368 YAML::Node ConfigCurrent =
systematics[s]->GetConfig();
372 MACH3LOG_ERROR(
"Yaml configs in previous chain (from path {}) and current one are different", FitName);
378 CovarianceFolder->Close();
379 delete CovarianceFolder;
381 std::vector<double> branch_vals;
382 std::vector<std::string> branch_name;
383 systematics[s]->MatchMaCh3OutputBranches(posts, branch_vals, branch_name);
384 posts->GetEntry(posts->GetEntries()-1);
393 for (
int i = 0; i <
systematics[s]->GetNumParams(); ++i) {
394 posts->SetBranchAddress(
systematics[s]->GetParName(i).c_str(),
nullptr);
409 if (
fitMan ==
nullptr)
return;
412 if (GetFromManager<bool>(
fitMan->
raw()[
"General"][
"ProcessMCMC"],
false, __FILE__ , __LINE__)){
418 TVectorD *Central =
nullptr;
419 TVectorD *Errors =
nullptr;
420 TVectorD *Central_Gauss =
nullptr;
421 TVectorD *Errors_Gauss =
nullptr;
422 TVectorD *Peaks =
nullptr;
425 Processor.
GetPostfit(Central, Errors, Central_Gauss, Errors_Gauss, Peaks);
429 TMatrixDSym *Covariance =
nullptr;
430 TMatrixDSym *Correlation =
nullptr;
440 MACH3LOG_INFO(
"Opening output again to update with means..");
441 outputFile =
new TFile(Get<std::string>(
fitMan->
raw()[
"General"][
"OutputFile"], __FILE__, __LINE__).c_str(),
"UPDATE");
443 Central->Write(
"PDF_Means");
444 Errors->Write(
"PDF_Errors");
445 Central_Gauss->Write(
"Gauss_Means");
446 Errors_Gauss->Write(
"Errors_Gauss");
447 Covariance->Write(
"Covariance");
448 Correlation->Write(
"Correlation");
460 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs)
462 TStopwatch clockRace;
464 for(
int Lap = 0; Lap < NLaps; ++Lap) {
468 MACH3LOG_INFO(
"It took {:.4f} s to reweights {} times sample: {}", clockRace.RealTime(), NLaps,
samples[ivs]->GetName());
469 MACH3LOG_INFO(
"On average {:.6f}", clockRace.RealTime()/NLaps);
472 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs)
474 TStopwatch clockRace;
476 for(
int Lap = 0; Lap < NLaps; ++Lap) {
480 MACH3LOG_INFO(
"It took {:.4f} s to calculate GetLikelihood {} times sample: {}", clockRace.RealTime(), NLaps,
samples[ivs]->GetName());
481 MACH3LOG_INFO(
"On average {:.6f}", clockRace.RealTime()/NLaps);
484 std::vector<std::vector<double>> StepsValuesBefore(
systematics.size());
486 StepsValuesBefore[s] =
systematics[s]->GetProposed();
489 TStopwatch clockRace;
491 for(
int Lap = 0; Lap < NLaps; ++Lap) {
495 MACH3LOG_INFO(
"It took {:.4f} s to propose step {} times cov: {}", clockRace.RealTime(), NLaps,
systematics[s]->GetName());
496 MACH3LOG_INFO(
"On average {:.6f}", clockRace.RealTime()/NLaps);
499 systematics[s]->SetParameters(StepsValuesBefore[s]);
503 TStopwatch clockRace;
505 for(
int Lap = 0; Lap < NLaps; ++Lap) {
509 MACH3LOG_INFO(
"It took {:.4f} s to calculate get likelihood {} times cov: {}", clockRace.RealTime(), NLaps,
systematics[s]->GetName());
510 MACH3LOG_INFO(
"On average {:.6f}", clockRace.RealTime()/NLaps);
518 bool isScanRanges =
false;
520 if(
fitMan->
raw()[
"LLHScan"][
"ScanRanges"]){
521 YAML::Node scanRangesList =
fitMan->
raw()[
"LLHScan"][
"ScanRanges"];
522 for (
auto it = scanRangesList.begin(); it != scanRangesList.end(); ++it) {
523 std::string itname = it->first.as<std::string>();
524 std::vector<double> itrange = it->second.as<std::vector<double>>();
526 scanRanges[itname] = itrange;
530 MACH3LOG_INFO(
"There are no user-defined parameter ranges, so I'll use default param bounds for LLH Scans");
544 double& lower,
double& upper,
const int n_points,
const std::string& suffix)
const {
547 std::map<std::string, std::vector<double>> scanRanges;
550 double nSigma = GetFromManager<int>(
fitMan->
raw()[
"LLHScan"][
"LLHScanSigma"], 1., __FILE__, __LINE__);
551 bool IsPCA = cov->
IsPCA();
555 if (IsPCA) name +=
"_PCA";
564 if (std::abs(CentralValue - prior) > 1e-10) {
565 MACH3LOG_INFO(
"For {} scanning around value {} rather than prior {}", name, CentralValue, prior);
588 auto it = scanRanges.find(name);
589 if (it != scanRanges.end() && it->second.size() == 2) {
590 lower = it->second[0];
591 upper = it->second[1];
592 MACH3LOG_INFO(
"Found matching param name for setting specified range for {}", name);
593 MACH3LOG_INFO(
"Range for {} = [{:.2f}, {:.2f}]", name, lower, upper);
601 MACH3LOG_INFO(
"Scanning {} {} with {} steps, from [{:.2f} , {:.2f}], CV = {:.2f}", suffix, name, n_points, lower, upper, CentralValue);
608 std::vector<double> binEdges(n_points + 1);
610 double logLower = std::log10(lowerlimit);
611 double logUpper = std::log10(upperlimit);
613 for (
int j = 0; j <= n_points; ++j) {
614 binEdges[j] = std::pow(10.0, logLower + (logUpper - logLower) *
double(j) /
double(n_points));
630 bool PlotLLHScanBySample = GetFromManager<bool>(
fitMan->
raw()[
"LLHScan"][
"LLHScanBySample"],
false, __FILE__ , __LINE__);
631 auto SkipVector = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"LLHScan"][
"LLHScanSkipVector"], {}, __FILE__ , __LINE__);
633 bool LLHLogarithmic = GetFromManager<bool>(
fitMan->
raw()[
"LLHScan"][
"LLHLogarithmic"],
false, __FILE__ , __LINE__);
637 std::vector<TDirectory *> Cov_LLH(
systematics.size());
638 for(
unsigned int ivc = 0; ivc <
systematics.size(); ++ivc )
640 std::string NameTemp =
systematics[ivc]->GetName();
641 NameTemp = NameTemp.substr(0, NameTemp.find(
"_cov")) +
"_LLH";
642 Cov_LLH[ivc] =
outputFile->mkdir(NameTemp.c_str());
645 std::vector<TDirectory *> SampleClass_LLH(
samples.size());
646 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
648 std::string NameTemp =
samples[ivs]->GetName();
649 SampleClass_LLH[ivs] =
outputFile->mkdir(NameTemp.c_str());
652 TDirectory *Sample_LLH =
outputFile->mkdir(
"Sample_LLH");
653 TDirectory *Total_LLH =
outputFile->mkdir(
"Total_LLH");
655 std::vector<TDirectory *>SampleSplit_LLH;
656 if(PlotLLHScanBySample)
659 int SampleIterator = 0;
660 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
662 for(
int is = 0; is <
samples[ivs]->GetNSamples(); ++is )
664 SampleSplit_LLH[SampleIterator] =
outputFile->mkdir((
samples[ivs]->GetSampleTitle(is)+
"_LLH").c_str());
670 const int n_points = GetFromManager<int>(
fitMan->
raw()[
"LLHScan"][
"LLHScanPoints"], 100, __FILE__ , __LINE__);
673 const int countwidth = int(
double(n_points)/
double(5));
680 int npars = cov->GetNumParams();
681 bool IsPCA = cov->IsPCA();
682 if (IsPCA) npars = cov->GetNParameters();
683 for (
int i = 0; i < npars; ++i)
686 std::string name = cov->GetParFancyName(i);
687 if (IsPCA) name +=
"_PCA";
691 double CentralValue, lower, upper;
694 std::unique_ptr<TH1D> hScan;
698 if (lower < 0.0 || upper < 0.0) {
699 MACH3LOG_WARN(
"Cannot perform logarithmic scan for {} "" with range [{}, {}], falling back to linear scan",name, lower, upper);
700 hScan = std::make_unique<TH1D>((name +
"_full").c_str(), (name +
"_full").c_str(), n_points, lower, upper);
703 hScan = std::make_unique<TH1D>((name +
"_full").c_str(), (name +
"_full").c_str(), n_points, binEdges.data());
708 hScan = std::make_unique<TH1D>((name +
"_full").c_str(), (name +
"_full").c_str(), n_points, lower, upper);
711 hScan->SetTitle((std::string(
"2LLH_full, ") + name +
";" + name +
"; -2(ln L_{sample} + ln L_{xsec+flux} + ln L_{det})").c_str());
712 hScan->SetDirectory(
nullptr);
714 auto hScanSam = std::make_unique<TH1D>((name +
"_sam").c_str(), (name +
"_sam").c_str(), n_points, lower, upper);
715 hScanSam->SetTitle((std::string(
"2LLH_sam, ") + name +
";" + name +
"; -2(ln L_{sample})").c_str());
716 hScanSam->SetDirectory(
nullptr);
718 std::vector<std::unique_ptr<TH1D>> hScanSample(
samples.size());
719 std::vector<double> nSamLLH(
samples.size(), 0.0);
720 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
722 std::string NameTemp =
samples[ivs]->GetName();
723 hScanSample[ivs] = std::make_unique<TH1D>((name+
"_"+NameTemp).c_str(), (name+
"_" + NameTemp).c_str(), n_points, lower, upper);
724 hScanSample[ivs]->SetDirectory(
nullptr);
725 hScanSample[ivs]->SetTitle((
"2LLH_" + NameTemp +
", " + name +
";" + name +
"; -2(ln L_{" + NameTemp +
"})").c_str());
728 std::vector<std::unique_ptr<TH1D>> hScanCov(
systematics.size());
729 std::vector<double> nCovLLH(
systematics.size(), 0.0);
730 for(
unsigned int ivc = 0; ivc <
systematics.size(); ++ivc )
732 std::string NameTemp =
systematics[ivc]->GetName();
733 NameTemp = NameTemp.substr(0, NameTemp.find(
"_cov"));
734 hScanCov[ivc] = std::make_unique<TH1D>((name +
"_" + NameTemp).c_str(), (name +
"_" + NameTemp).c_str(), n_points, lower, upper);
735 hScanCov[ivc]->SetDirectory(
nullptr);
736 hScanCov[ivc]->SetTitle((
"2LLH_" + NameTemp +
", " + name +
";" + name +
"; -2(ln L_{" + NameTemp +
"})").c_str());
739 std::vector<std::unique_ptr<TH1D>> hScanSamSplit;
740 std::vector<double> sampleSplitllh;
741 if(PlotLLHScanBySample)
743 int SampleIterator = 0;
746 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
748 for(
int is = 0; is <
samples[ivs]->GetNSamples(); ++is )
750 auto histName = name +
samples[ivs]->GetSampleTitle(is);
751 auto histTitle = std::string(
"2LLH_sam, ") + name +
";" + name +
"; -2(ln L_{sample})";
752 hScanSamSplit[SampleIterator] = std::make_unique<TH1D>(histName.c_str(), histTitle.c_str(), n_points, lower, upper);
753 hScanSamSplit[SampleIterator]->SetDirectory(
nullptr);
761 for (
int j = 0; j < n_points; ++j)
763 if (j % countwidth == 0)
768 cov->GetPCAHandler()->SetParPropPCA(i, hScan->GetBinCenter(j+1));
771 cov->SetParProp(i, hScan->GetBinCenter(j+1));
775 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs ){
779 double totalllh = 0.;
782 double samplellh = 0.;
784 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs ) {
785 nSamLLH[ivs] =
samples[ivs]->GetLikelihood();
786 samplellh += nSamLLH[ivs];
789 for(
unsigned int ivc = 0; ivc <
systematics.size(); ++ivc ) {
791 totalllh += nCovLLH[ivc];
794 totalllh += samplellh;
796 if(PlotLLHScanBySample)
798 int SampleIterator = 0;
799 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
801 for(
int is = 0; is <
samples[ivs]->GetNSamples(); ++is)
803 sampleSplitllh[SampleIterator] =
samples[ivs]->GetSampleLikelihood(is);
809 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs ) {
810 hScanSample[ivs]->SetBinContent(j+1, 2*nSamLLH[ivs]);
812 for(
unsigned int ivc = 0; ivc <
systematics.size(); ++ivc ) {
813 hScanCov[ivc]->SetBinContent(j+1, 2*nCovLLH[ivc]);
816 hScanSam->SetBinContent(j+1, 2*samplellh);
817 hScan->SetBinContent(j+1, 2*totalllh);
819 if(PlotLLHScanBySample)
821 int SampleIterator = 0;
822 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
824 for(
int is = 0; is <
samples[ivs]->GetNSamples(); ++is)
826 hScanSamSplit[SampleIterator]->SetBinContent(j+1, 2*sampleSplitllh[SampleIterator]);
832 for(
unsigned int ivc = 0; ivc <
systematics.size(); ++ivc )
835 hScanCov[ivc]->Write();
838 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
840 SampleClass_LLH[ivs]->cd();
841 hScanSample[ivs]->Write();
848 if(PlotLLHScanBySample)
850 int SampleIterator = 0;
851 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
853 for(
int is = 0; is <
samples[ivs]->GetNSamples(); ++is)
855 SampleSplit_LLH[SampleIterator]->cd();
856 hScanSamSplit[SampleIterator]->Write();
864 cov->GetPCAHandler()->SetParPropPCA(i, CentralValue);
866 cov->SetParProp(i, CentralValue);
871 for(
unsigned int ivc = 0; ivc <
systematics.size(); ++ivc )
873 Cov_LLH[ivc]->Write();
877 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
879 SampleClass_LLH[ivs]->Write();
880 delete SampleClass_LLH[ivs];
889 if(PlotLLHScanBySample)
891 int SampleIterator = 0;
892 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
894 for(
int is = 0; is <
samples[ivs]->GetNSamples(); ++is )
896 SampleSplit_LLH[SampleIterator]->Write();
897 delete SampleSplit_LLH[SampleIterator];
908 TFile* outputFileLLH =
nullptr;
909 bool ownsfile =
false;
910 if(outputFileName !=
""){
911 outputFileLLH =
M3::Open(outputFileName,
"READ", __FILE__, __LINE__);
916 TDirectory *Sample_LLH = outputFileLLH->Get<TDirectory>(
"Sample_LLH");
919 if(!Sample_LLH || Sample_LLH->IsZombie())
921 MACH3LOG_WARN(
"Couldn't find Sample_LLH, it looks like LLH scan wasn't run, will do this now");
923 Sample_LLH = outputFileLLH->Get<TDirectory>(
"Sample_LLH");
928 const int npars = cov->GetNumParams();
929 std::vector<double> StepScale(npars);
930 for (
int i = 0; i < npars; ++i)
932 std::string name = cov->GetParFancyName(i);
933 StepScale[i] = cov->GetIndivStepScale(i);
934 TH1D* LLHScan = Sample_LLH->Get<TH1D>((name+
"_sam").c_str());
935 if(LLHScan ==
nullptr)
937 MACH3LOG_WARN(
"Couldn't find LLH scan, for {}, skipping", name);
940 const double LLH_val = std::max(LLHScan->GetBinContent(1), LLHScan->GetBinContent(LLHScan->GetNbinsX()));
942 if(LLH_val < 0.001)
continue;
947 const double Var = 1.;
948 const double approxSigma = std::abs(Var)/std::sqrt(LLH_val);
949 const double GlobalScale = cov->GetGlobalStepScale();
951 const double TargetStep = approxSigma * 2.38 / std::sqrt(npars);
953 const double NewStepScale = TargetStep / GlobalScale;
955 StepScale[i] = NewStepScale;
957 MACH3LOG_DEBUG(
"Target Step Size (before accounting for global step size): {}", TargetStep);
960 cov->SetIndivStepScale(StepScale);
961 cov->SaveUpdatedMatrixConfig();
963 if(ownsfile && outputFileLLH !=
nullptr)
delete outputFileLLH;
975 TDirectory *Sample_2DLLH =
outputFile->mkdir(
"Sample_2DLLH");
976 auto SkipVector = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"LLHScan"][
"LLHScanSkipVector"], {}, __FILE__ , __LINE__);;
979 bool LLHLogarithmic = GetFromManager<bool>(
fitMan->
raw()[
"LLHScan"][
"LLHLogarithmic"],
false, __FILE__ , __LINE__);
982 const int n_points = GetFromManager<int>(
fitMan->
raw()[
"LLHScan"][
"2DLLHScanPoints"], 20, __FILE__ , __LINE__);
984 const int countwidth = int(
double(n_points)/
double(5));
991 int npars = cov->GetNumParams();
992 bool IsPCA = cov->IsPCA();
993 if (IsPCA) npars = cov->GetNParameters();
995 for (
int i = 0; i < npars; ++i)
997 std::string name_x = cov->GetParFancyName(i);
998 if (IsPCA) name_x +=
"_PCA";
1000 double central_x, lower_x, upper_x;
1002 std::vector<double> binEdges_x;
1006 if (lower_x < 0.0 || upper_x < 0.0){
1007 MACH3LOG_WARN(
"Cannot perform logarithmic scan for {} "" with range [{}, {}], falling back to linear scan", name_x, lower_x, upper_x);
1015 for (
int j = 0; j < i; ++j)
1017 std::string name_y = cov->GetParFancyName(j);
1018 if (IsPCA) name_y +=
"_PCA";
1022 std::unique_ptr<TH2D> hScanSam;
1024 double central_y, lower_y, upper_y;
1028 if (lower_x < 0.0 || upper_x < 0.0 || lower_y < 0.0 || upper_y < 0.0 ) {
1029 MACH3LOG_WARN(
"Cannot perform logarithmic scan for {} and {} "" with range [{}, {}], [{}, {}], falling back to linear scan", name_x, lower_x, upper_x, name_y, lower_y, upper_y);
1030 hScanSam = std::make_unique<TH2D>((name_x +
"_" + name_y +
"_sam").c_str(), (name_x +
"_" + name_y +
"_sam").c_str(), n_points, lower_x, upper_x, n_points, lower_y, upper_y);
1031 hScanSam->SetDirectory(
nullptr);
1032 hScanSam->GetXaxis()->SetTitle(name_x.c_str());
1033 hScanSam->GetYaxis()->SetTitle(name_y.c_str());
1034 hScanSam->GetZaxis()->SetTitle(
"2LLH_sam");
1037 hScanSam = std::make_unique<TH2D>((name_x +
"_" + name_y +
"_sam").c_str(), (name_x +
"_" + name_y +
"_sam").c_str(), n_points, binEdges_x.data(), n_points, binEdges_y.data());
1042 hScanSam = std::make_unique<TH2D>((name_x +
"_" + name_y +
"_sam").c_str(), (name_x +
"_" + name_y +
"_sam").c_str(), n_points, lower_x, upper_x, n_points, lower_y, upper_y);
1043 hScanSam->SetDirectory(
nullptr);
1044 hScanSam->GetXaxis()->SetTitle(name_x.c_str());
1045 hScanSam->GetYaxis()->SetTitle(name_y.c_str());
1046 hScanSam->GetZaxis()->SetTitle(
"2LLH_sam");
1050 for (
int x = 0; x < n_points; ++x)
1052 if (x % countwidth == 0)
1055 for (
int y = 0; y < n_points; ++y)
1059 cov->GetPCAHandler()->SetParPropPCA(i, hScanSam->GetXaxis()->GetBinCenter(x+1));
1060 cov->GetPCAHandler()->SetParPropPCA(j, hScanSam->GetYaxis()->GetBinCenter(y+1));
1063 cov->SetParProp(i, hScanSam->GetXaxis()->GetBinCenter(x+1));
1064 cov->SetParProp(j, hScanSam->GetYaxis()->GetBinCenter(y+1));
1067 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs) {
1072 double samplellh = 0;
1073 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs) {
1074 samplellh +=
samples[ivs]->GetLikelihood();
1076 hScanSam->SetBinContent(x+1, y+1, 2*samplellh);
1084 cov->GetPCAHandler()->SetParPropPCA(i, central_x);
1085 cov->GetPCAHandler()->SetParPropPCA(j, central_y);
1087 cov->SetParProp(i, central_x);
1088 cov->SetParProp(j, central_y);
1093 Sample_2DLLH->Write();
1094 delete Sample_2DLLH;
1107 bool PlotLLHScanBySample = GetFromManager<bool>(
fitMan->
raw()[
"LLHScan"][
"LLHScanBySample"],
false, __FILE__ , __LINE__);
1108 auto ParamsOfInterest = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"LLHScan"][
"LLHParameters"], {}, __FILE__, __LINE__);
1110 if(ParamsOfInterest.empty()) {
1111 MACH3LOG_WARN(
"There were no LLH parameters of interest specified to run the LLHMap! LLHMap will not run at all ...");
1117 std::vector<std::tuple<std::string, ParameterHandlerBase*, int>> ParamsCovIDs;
1118 for(
auto& p : ParamsOfInterest) {
1121 for(
int c = 0; c < cov->GetNumParams(); ++c) {
1122 if(cov->GetParName(c) == p || cov->GetParFancyName(c) == p) {
1124 for(
auto& pc : ParamsCovIDs) {
1125 if(std::get<1>(pc) == cov && std::get<2>(pc) == c)
1127 MACH3LOG_WARN(
"Parameter {} as {}({}) listed multiple times for LLHMap, omitting and using only once!", p, cov->GetName(), c);
1134 ParamsCovIDs.push_back(std::make_tuple(p, cov, c));
1144 MACH3LOG_INFO(
"Parameter {} found in {} at an index {}.", p, std::get<1>(ParamsCovIDs.back())->GetName(), std::get<2>(ParamsCovIDs.back()));
1146 MACH3LOG_WARN(
"Parameter {} not found in any of the systematic covariance objects. Will not scan over this one!", p);
1150 std::map<std::string, std::pair<int, std::pair<double, double>>> ParamsRanges;
1152 MACH3LOG_INFO(
"======================================================================================");
1153 MACH3LOG_INFO(
"Performing a general multi-dimensional LogL map scan over following parameters ranges:");
1154 MACH3LOG_INFO(
"======================================================================================");
1155 unsigned long TotalPoints = 1;
1157 double nSigma = GetFromManager<int>(
fitMan->
raw()[
"LLHScan"][
"LLHScanSigma"], 1., __FILE__, __LINE__);
1162 for(
auto& p : ParamsCovIDs) {
1164 std::string name = std::get<0>(p);
1165 int i = std::get<2>(p);
1168 ParamsRanges[name].first = GetFromManager<int>(
fitMan->
raw()[
"LLHScan"][
"LLHScanPoints"], 20, __FILE__, __LINE__);
1170 ParamsRanges[name].first = GetFromManager<int>(
fitMan->
raw()[
"LLHScan"][
"ScanPoints"][name], ParamsRanges[name].first, __FILE__, __LINE__);
1175 bool IsPCA = cov->
IsPCA();
1183 if (std::abs(CentralValue - prior) > 1e-10) {
1184 MACH3LOG_INFO(
"For {} scanning around value {} rather than prior {}", name, CentralValue, prior);
1202 ParamsRanges[name].second = {lower,upper};
1205 ParamsRanges[name].second = GetFromManager<std::pair<double,double>>(
fitMan->
raw()[
"LLHScan"][
"ScanRanges"][name], ParamsRanges[name].second, __FILE__, __LINE__);
1207 MACH3LOG_INFO(
"{} from {:.4f} (lower bin edge) to {:.4f} (upper bin edge) with a {:.5f} step ({} points total)",
1208 name, ParamsRanges[name].second.first, ParamsRanges[name].second.second,
1209 (ParamsRanges[name].second.second - ParamsRanges[name].second.first)/(ParamsRanges[name].first),
1210 ParamsRanges[name].first);
1212 TotalPoints *= ParamsRanges[name].first;
1216 MACH3LOG_INFO(
"In total, looping over {} points, from {} parameters. Estimates for run time:", TotalPoints, ParamsCovIDs.size());
1217 MACH3LOG_INFO(
" 1 s per point = {} hours",
double(TotalPoints)/3600.);
1218 MACH3LOG_INFO(
" 0.1 s per point = {} hours",
double(TotalPoints)/36000.);
1219 MACH3LOG_INFO(
"0.01 s per point = {} hours",
double(TotalPoints)/360000.);
1220 MACH3LOG_INFO(
"==================================================================================");
1222 const int countwidth = int(
double(TotalPoints)/
double(20));
1225 auto LLHMap =
new TTree(
"llhmap",
"LLH Map");
1228 for(
unsigned int ivc = 0; ivc <
systematics.size(); ++ivc )
1230 std::string NameTemp =
systematics[ivc]->GetName();
1231 NameTemp = NameTemp.substr(0, NameTemp.find(
"_cov")) +
"_LLH";
1232 LLHMap->Branch(NameTemp.c_str(), &CovLogL[ivc]);
1235 std::vector<double> SampleClassLogL(
samples.size());
1236 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
1238 std::string NameTemp =
samples[ivs]->GetName()+
"_LLH";
1239 LLHMap->Branch(NameTemp.c_str(), &SampleClassLogL[ivs]);
1242 double SampleLogL, TotalLogL;
1243 LLHMap->Branch(
"Sample_LLH", &SampleLogL);
1244 LLHMap->Branch(
"Total_LLH", &TotalLogL);
1246 std::vector<double>SampleSplitLogL;
1247 if(PlotLLHScanBySample)
1250 int SampleIterator = 0;
1251 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
1253 for(
int is = 0; is <
samples[ivs]->GetNSamples(); ++is )
1255 std::string NameTemp =
samples[ivs]->GetSampleTitle(is)+
"_LLH";
1256 LLHMap->Branch(NameTemp.c_str(), &SampleSplitLogL[SampleIterator]);
1262 std::vector<double> ParamsValues(ParamsCovIDs.size());
1263 for(
unsigned int i=0; i < ParamsCovIDs.size(); ++i)
1264 LLHMap->Branch(std::get<0>(ParamsCovIDs[i]).c_str(), &ParamsValues[i]);
1268 std::vector<unsigned long> idx(ParamsCovIDs.size(), 0);
1271 for(
unsigned long sp = 0; sp < TotalPoints; ++sp)
1274 for(
unsigned int n = 0; n < ParamsCovIDs.size(); ++n)
1277 std::string name = std::get<0>(ParamsCovIDs[n]);
1278 int points = ParamsRanges[name].first;
1279 double low = ParamsRanges[name].second.first;
1280 double high = ParamsRanges[name].second.second;
1283 unsigned long dev = 1;
1284 for(
unsigned int m = 0; m <= n; ++m)
1285 dev *= ParamsRanges[std::get<0>(ParamsCovIDs[m])].first;
1289 idx[n] = idx[n] / ( dev / points );
1292 ParamsValues[n] = low + (2 * double(idx[n]) + 1) * (high-low) / (2 * double(points));
1297 int i = std::get<2>(ParamsCovIDs[n]);
1309 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs)
1312 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs)
1314 SampleClassLogL[ivs] = 2.*
samples[ivs]->GetLikelihood();
1315 SampleLogL += SampleClassLogL[ivs];
1317 TotalLogL += SampleLogL;
1320 for(
unsigned int ivc = 0; ivc <
systematics.size(); ++ivc )
1322 CovLogL[ivc] = 2.*
systematics[ivc]->GetLikelihood();
1323 TotalLogL += CovLogL[ivc];
1326 if(PlotLLHScanBySample)
1328 int SampleIterator = 0;
1329 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
1331 for(
int is = 0; is <
samples[ivs]->GetNSamples(); ++is)
1333 SampleSplitLogL[SampleIterator] = 2.*
samples[ivs]->GetSampleLikelihood(is);
1341 if (sp % countwidth == 0)
1353 if(!
fitMan->
raw()[
"SigmaVar"][
"CustomRange"])
return;
1355 auto Config =
fitMan->
raw()[
"SigmaVar"][
"CustomRange"];
1357 const auto sigmaStr = std::to_string(
static_cast<int>(std::round(sigma)));
1359 if (Config[ParName] && Config[ParName][sigmaStr]) {
1360 ParamShiftValue = Config[ParName][sigmaStr].as<
double>();
1361 MACH3LOG_INFO(
" ::: setting custom range from config ::: {} -> {}", ParName, ParamShiftValue);
1370 hist->SetTitle(baseName.c_str());
1372 TString className = hist->ClassName();
1375 if (className.Contains(
"TH1")) {
1376 hist->GetYaxis()->SetTitle(
"Events");
1377 }
else if (className.Contains(
"TH2")) {
1378 hist->GetZaxis()->SetTitle(
"Events");
1380 hist->Write(baseName.c_str());
1386 const std::string& suffix,
1388 const bool by_channel,
1389 const std::vector<TDirectory*>& SampleDir) {
1392 for (
int iSample = 0; iSample < sample->
GetNSamples(); ++iSample) {
1393 SampleDir[iSample]->cd();
1395 for(
int iDim1 = 0; iDim1 < sample->
GetNDim(iSample); iDim1++) {
1396 std::string ProjectionName = sample->
GetKinVarName(iSample, iDim1);
1397 std::string ProjectionSuffix =
"_1DProj" + std::to_string(iDim1);
1401 for (
int iMode = 0; iMode < modes->
GetNModes(); ++iMode) {
1408 for (
int iChan = 0; iChan < sample->
GetNOscChannels(iSample); ++iChan) {
1414 if (by_mode && by_channel) {
1415 for (
int iMode = 0; iMode < modes->
GetNModes(); ++iMode) {
1416 for (
int iChan = 0; iChan < sample->
GetNOscChannels(iSample); ++iChan) {
1423 if (!by_mode && !by_channel) {
1424 auto hist = sample->
Get1DVarHist(iSample, ProjectionName);
1427 for (
int iDim2 = iDim1 + 1; iDim2 < sample->
GetNDim(iSample); ++iDim2) {
1429 std::string XVarName = sample->
GetKinVarName(iSample, iDim1);
1430 std::string YVarName = sample->
GetKinVarName(iSample, iDim2);
1433 auto hist2D = sample->
Get2DVarHist(iSample, XVarName, YVarName);
1436 std::string suffix2D =
"_2DProj_" + std::to_string(iDim1) +
"_vs_" + std::to_string(iDim2) + suffix;
1450 bool plot_by_mode = GetFromManager<bool>(
fitMan->
raw()[
"SigmaVar"][
"PlotByMode"],
false, __FILE__ , __LINE__);
1451 bool plot_by_channel = GetFromManager<bool>(
fitMan->
raw()[
"SigmaVar"][
"PlotByChannel"],
false, __FILE__ , __LINE__);
1452 auto SkipVector = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"SigmaVar"][
"SkipVector"], {}, __FILE__ , __LINE__);
1454 if (plot_by_mode)
MACH3LOG_INFO(
"Plotting by sample and mode");
1455 if (plot_by_channel)
MACH3LOG_INFO(
"Plotting by sample and channel");
1456 if (!plot_by_mode && !plot_by_channel)
MACH3LOG_INFO(
"Plotting by sample only");
1457 if (plot_by_mode && plot_by_channel)
MACH3LOG_INFO(
"Plotting by sample, mode and channel");
1459 auto SigmaArray = GetFromManager<std::vector<double>>(
fitMan->
raw()[
"SigmaVar"][
"SigmaArray"], {-3, -1, 0, 1, 3}, __FILE__ , __LINE__);
1460 if (std::find(SigmaArray.begin(), SigmaArray.end(), 0.0) == SigmaArray.end()) {
1461 MACH3LOG_ERROR(
":: SigmaArray does not contain 0! Current contents: {} ::", fmt::join(SigmaArray,
", "));
1465 TDirectory* SigmaDir =
outputFile->mkdir(
"SigmaVar");
1470 for(
int i = 0; i <
systematics[s]->GetNumParams(); i++)
1472 std::string ParName =
systematics[s]->GetParFancyName(i);
1478 TDirectory* ParamDir = SigmaDir->mkdir(ParName.c_str());
1481 const double ParamCentralValue =
systematics[s]->GetParProp(i);
1482 const double Prior =
systematics[s]->GetParPreFit(i);
1483 const double ParamLower =
systematics[s]->GetLowerBound(i);
1484 const double ParamUpper =
systematics[s]->GetUpperBound(i);
1486 if (std::abs(ParamCentralValue - Prior) > 1e-10) {
1487 MACH3LOG_INFO(
"For {} scanning around value {} rather than prior {}", ParName, ParamCentralValue, Prior);
1490 for(
unsigned int iSample = 0; iSample <
samples.size(); ++iSample)
1492 auto* MaCh3Sample =
samples[iSample];
1493 std::vector<TDirectory*> SampleDir(MaCh3Sample->GetNSamples());
1494 for (
int SampleIndex = 0; SampleIndex < MaCh3Sample->GetNSamples(); ++SampleIndex) {
1495 SampleDir[SampleIndex] = ParamDir->mkdir(MaCh3Sample->GetSampleTitle(SampleIndex).c_str());
1498 for (
size_t j = 0; j < SigmaArray.size(); ++j) {
1499 double sigma = SigmaArray[j];
1501 double ParamShiftValue = ParamCentralValue + sigma * std::sqrt((*
systematics[s]->GetCovMatrix())(i,i));
1502 ParamShiftValue = std::max(std::min(ParamShiftValue, ParamUpper), ParamLower);
1507 MACH3LOG_INFO(
" - set to {:<5.2f} ({:<2} sigma shift)", ParamShiftValue, sigma);
1510 std::ostringstream valStream;
1511 valStream << std::fixed << std::setprecision(2) << ParamShiftValue;
1512 std::string valueStr = valStream.str();
1514 std::ostringstream sigmaStream;
1515 sigmaStream << std::fixed << std::setprecision(2) << std::abs(sigma);
1516 std::string sigmaStr = sigmaStream.str();
1520 suffix =
"_" + ParName +
"_nom_val_" + valueStr;
1522 std::string sign = (sigma > 0) ?
"p" :
"n";
1523 suffix =
"_" + ParName +
"_sig_" + sign + sigmaStr +
"_val_" + valueStr;
1527 MaCh3Sample->Reweight();
1531 for (
int subSampleIndex = 0; subSampleIndex < MaCh3Sample->GetNSamples(); ++subSampleIndex) {
1532 SampleDir[subSampleIndex]->Close();
1533 delete SampleDir[subSampleIndex];
1539 MACH3LOG_INFO(
" - set back to CV {:<5.2f}", ParamCentralValue);
#define _MaCh3_Safe_Include_Start_
KS: Avoiding warning checking for headers.
#define _MaCh3_Safe_Include_End_
void WriteHistogramsByMode(SampleHandlerInterface *sample, const std::string &suffix, const bool by_mode, const bool by_channel, const std::vector< TDirectory * > &SampleDir)
Generic histogram writer - should make main code more palatable.
void WriteHistograms(TH1 *hist, const std::string &baseName)
Helper to write histograms.
#define MACH3LOG_CRITICAL
TMacro YAMLtoTMacro(const YAML::Node &yaml_node, const std::string &name)
Convert a YAML node to a ROOT TMacro object.
YAML::Node TMacroToYAML(const TMacro ¯o)
KS: Convert a ROOT TMacro object to a YAML node.
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.
void RunLLHScan()
Perform a 1D likelihood scan.
FitterBase(Manager *const fitMan)
Constructor.
void AddSystObj(ParameterHandlerBase *cov)
This function adds a Covariance object to the analysis framework. The Covariance object will be utili...
std::string GetName() const
Get name of class.
std::unique_ptr< TRandom3 > random
Random number.
double logLProp
proposed likelihood
bool CheckSkipParameter(const std::vector< std::string > &SkipVector, const std::string &ParamName) const
KS: Check whether we want to skip parameter using skip vector.
void ProcessMCMC()
Process MCMC output.
int accCount
counts accepted steps
bool OutputPrepared
Checks if output prepared not repeat some operations.
void SaveOutput()
Save output and close files.
TFile * outputFile
Output.
void SaveSettings()
Save the settings that the MCMC was run with.
unsigned int step
current state
void PrepareOutput()
Prepare the output file.
bool SettingsSaved
Checks if setting saved not repeat some operations.
double accProb
current acceptance prob
virtual void StartFromPreviousFit(const std::string &FitName)
Allow to start from previous fit/chain.
bool FileSaved
Checks if file saved not repeat some operations.
std::string AlgorithmName
Name of fitting algorithm that is being used.
std::vector< double > sample_llh
store the llh breakdowns
void RunSigmaVar()
Perform a 1D/2D sigma var for all samples.
std::vector< SampleHandlerInterface * > samples
Sample holder.
void GetParameterScanRange(const ParameterHandlerBase *cov, const int i, double &CentralValue, double &lower, double &upper, const int n_points, const std::string &suffix="") const
Helper function to get parameter scan range, central value.
double stepTime
Time of single step.
std::unique_ptr< TStopwatch > clock
tells global time how long fit took
Manager * fitMan
The manager for configuration handling.
unsigned int stepStart
step start, by default 0 if we start from previous chain then it will be different
bool GetScanRange(std::map< std::string, std::vector< double >> &scanRanges) const
YSP: Set up a mapping to store parameters with user-specified ranges, suggested by D....
std::unique_ptr< TStopwatch > stepClock
tells how long single step/fit iteration took
TDirectory * CovFolder
Output cov folder.
void CustomRange(const std::string &ParName, const double sigma, double &ParamShiftValue) const
For comparison with other fitting frameworks (like P-Theta) we usually have to apply different parame...
TDirectory * SampleFolder
Output sample folder.
void DragRace(const int NLaps=100)
Calculates the required time for each sample or covariance object in a drag race simulation....
void Run2DLLHScan()
Perform a 2D likelihood scan.
unsigned int TotalNSamples
Total number of samples used, single SampleHandler can store more than one analysis sample!
double logLCurr
current likelihood
void RunLLHMap()
Perform a general multi-dimensional likelihood scan.
std::vector< double > syst_llh
systematic llh breakdowns
int auto_save
auto save every N steps
bool fTestLikelihood
Necessary for some fitting algorithms like PSO.
void GetStepScaleBasedOnLLHScan(const std::string &filename="")
LLH scan is good first estimate of step scale.
virtual ~FitterBase()
Destructor for the FitterBase class.
TTree * outTree
Output tree with posteriors.
void SanitiseInputs()
Remove obsolete memory and make other checks before fit starts.
void AddSampleHandler(SampleHandlerInterface *sample)
This function adds a sample PDF object to the analysis framework. The sample PDF object will be utili...
std::vector< double > CalculateBinEdges(double lowerlimit, double upperlimit, int n_points) const
std::vector< ParameterHandlerBase * > systematics
Systematic holder.
Class responsible for processing MCMC chains, performing diagnostics, generating plots,...
const std::vector< TString > & GetBranchNames() const
Get the vector of branch names from root file.
void Initialise()
Scan chain, what parameters we have and load information from covariance matrices.
void GetPostfit(TVectorD *&Central, TVectorD *&Errors, TVectorD *&Central_Gauss, TVectorD *&Errors_Gauss, TVectorD *&Peaks)
Get the post-fit results (arithmetic and Gaussian)
void DrawCovariance()
Draw the post-fit covariances.
void DrawPostfit()
Draw the post-fit comparisons.
void GetCovariance(TMatrixDSym *&Cov, TMatrixDSym *&Corr)
Get the post-fit covariances and correlations.
Custom exception class used throughout MaCh3.
KS: Class describing MaCh3 modes used in the analysis, it is being initialised from config.
int GetNModes() const
KS: Get number of modes, keep in mind actual number is +1 greater due to unknown category.
std::string GetMaCh3ModeName(const int Index) const
KS: Get normal name of mode, if mode not known you will get UNKNOWN_BAD.
The manager class is responsible for managing configurations and settings.
YAML::Node const & raw() const
Return config.
void SaveSettings(TFile *const OutputFile) const
Add manager useful information's to TFile, in most cases to Fitter.
double GetParPropPCA(const int i) const
Get current parameter value using PCA.
void SetParPropPCA(const int i, const double value)
Set proposed value for parameter in PCA base.
double GetPreFitValuePCA(const int i) const
Get current parameter value using PCA.
const TVectorD GetEigenValues() const
Get eigen values for all parameters, if you want for decomposed only parameters use GetEigenValuesMas...
Base class for handling systematic uncertainty parameters.
int GetNumParams() const
Get total number of parameters.
TH2D * GetCorrelationMatrix() const
KS: Convert covariance matrix to correlation matrix and return TH2D which can be used for fancy plott...
std::string GetParName(const int i) const
Get name of parameter.
void SetParProp(const int i, const double val)
Set proposed parameter value.
double GetUpperBound(const int i) const
Get upper parameter bound in which it is physically valid.
TMatrixDSym * GetCovMatrix() const
Return covariance matrix.
std::string GetParFancyName(const int i) const
Get fancy name of the Parameter.
PCAHandler * GetPCAHandler() const
Get pointer for PCAHandler.
double GetLowerBound(const int i) const
Get lower parameter bound in which it is physically valid.
bool IsPCA() const
is PCA, can use to query e.g. LLH scans
std::string GetName() const
Get name of covariance.
double GetParPreFit(const int i) const
Get prior parameter value.
M3::float_t GetParProp(const int i) const
Get proposed parameter value.
double GetDiagonalError(const int i) const
Get diagonal error for ith parameter.
YAML::Node GetConfig() const
Getter to return a copy of the YAML node.
Class responsible for handling implementation of samples used in analysis, reweighting and returning ...
virtual std::unique_ptr< TH1 > Get1DVarHistByModeAndChannel(const int iSample, const std::string &ProjectionVar_Str, const int kModeToFill=-1, const int kChannelToFill=-1, const int WeightStyle=0)=0
Build a 1D histogram for a given variable, optionally filtered by mode and channel.
virtual std::string GetName() const =0
Get name for Sample Handler.
virtual std::unique_ptr< TH1 > Get1DVarHist(const int iSample, const std::string &ProjectionVar, const std::vector< KinematicCut > &EventSelectionVec={}, int WeightStyle=0, const std::vector< KinematicCut > &SubEventSelectionVec={})=0
Return 1D projection of MC into given 1D variable (doesn't have to be variable used in the fit)
virtual std::string GetFlavourName(const int iSample, const int iChannel) const =0
Get the flavour name for a given sample and oscillation channel.
virtual void SaveAdditionalInfo([[maybe_unused]] TDirectory *Dir)
Store additional info in a chain.
MaCh3Modes * GetMaCh3Modes() const
Return pointer to MaCh3 modes.
virtual int GetNOscChannels(const int iSample) const =0
Get number of oscillation channels for a single sample.
virtual M3::int_t GetNSamples()
returns total number of samples
virtual std::string GetSampleTitle(const int iSample) const =0
Get fancy title for specified samples.
virtual std::string GetKinVarName(const int iSample, const int Dimension) const =0
Return Kinematic Variable name for specified sample and dimension for example "Reconstructed_Neutrino...
virtual std::unique_ptr< TH2 > Get2DVarHist(const int iSample, const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &EventSelectionVec={}, const int WeightStyle=0, const std::vector< KinematicCut > &SubEventSelectionVec={})=0
Build a 2D projection of MC events into specified variables.
virtual int GetNDim(const int Sample) const =0
DB Get what dimensionality binning for given sample has.
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.
constexpr static const double _LARGE_LOGL_
Large Likelihood is used it parameter go out of physical boundary, this indicates in MCMC that such s...
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.
int GetNThreads()
number of threads which we need for example for TRandom3
bool CaseInsensitiveMatchAny(std::string Text, const std::vector< std::string > &Patterns)
Matches a string against a simple wildcard Pattern using regex. Is not case sensitive.