6 #include "TStopwatch.h"
8 #include "TGraphAsymmErrors.h"
12 #pragma GCC diagnostic ignored "-Wuseless-cast"
21 auto Seed = Get<int>(
fitMan->
raw()[
"General"][
"Seed"], __FILE__, __LINE__);
28 clock = std::make_unique<TStopwatch>();
29 stepClock = std::make_unique<TStopwatch>();
32 debug = GetFromManager<bool>(
fitMan->
raw()[
"General"][
"Debug"],
false, __FILE__ , __LINE__);
35 auto outfile = Get<std::string>(
fitMan->
raw()[
"General"][
"OutputFile"], __FILE__ , __LINE__);
38 auto_save = Get<int>(
fitMan->
raw()[
"General"][
"MCMC"][
"AutoSave"], __FILE__ , __LINE__);
44 outTree =
new TTree(
"posteriors",
"Posterior_Distributions");
60 if (debug) debugFile.open((outfile+
".log").c_str());
64 fTestLikelihood = GetFromManager<bool>(
fitMan->
raw()[
"General"][
"Fitter"][
"FitTestLikelihood"],
false, __FILE__ , __LINE__);
85 TDirectory* MaCh3Version =
outputFile->mkdir(
"MaCh3Engine");
88 if (std::getenv(
"MaCh3_ROOT") ==
nullptr) {
94 if (std::getenv(
"MACH3") ==
nullptr) {
99 std::string header_path = std::string(std::getenv(
"MACH3"));
100 header_path +=
"/version.h";
101 FILE* file = fopen(header_path.c_str(),
"r");
104 header_path = std::string(std::getenv(
"MaCh3_ROOT"));
105 header_path +=
"/version.h";
111 TMacro versionHeader(
"version_header",
"version_header");
112 versionHeader.ReadFile(header_path.c_str());
113 versionHeader.Write();
121 TNamed Engine(Name, Name);
122 Engine.Write(Name.c_str());
124 MaCh3Version->Write();
136 for(
unsigned int i = 0; i <
systematics.size(); ++i){
140 for(
unsigned int i = 0; i <
samples.size(); ++i) {
142 for(
int iSam = 0; iSam <
samples[i]->GetNSamples(); ++iSam) {
143 MACH3LOG_INFO(
" {}: Sample title: {}, with {} osc channels",iSam ,
samples[i]->GetSampleTitle(iSam),
samples[i]->GetNOscChannels(iSam));
168 bool SaveProposal = GetFromManager<bool>(
fitMan->
raw()[
"General"][
"SaveProposal"],
false, __FILE__ , __LINE__);
170 if(SaveProposal)
MACH3LOG_INFO(
"Will save in the chain proposal parameters and LogL");
173 cov->SetBranches(*
outTree, SaveProposal);
187 for (
size_t i = 0; i <
samples.size(); ++i) {
188 std::stringstream oss, oss2;
189 oss <<
"LogL_sample_" << i;
190 oss2 << oss.str() <<
"/D";
195 std::stringstream oss, oss2;
196 oss <<
"LogL_systematic_" <<
systematics[i]->GetName();
197 oss2 << oss.str() <<
"/D";
209 MACH3LOG_INFO(
"-------------------- Starting MCMC --------------------");
212 debugFile <<
"----- Starting MCMC -----" << std::endl;
227 for (
size_t i = 0; i <
samples.size(); ++i) {
228 samples[i]->CleanMemoryBeforeFit();
240 int originalErrorLevel = gErrorIgnoreLevel;
241 gErrorIgnoreLevel = kFatal;
251 debugFile <<
"\n\n" <<
step <<
" steps took " <<
clock->RealTime() <<
" seconds to complete. (" <<
clock->RealTime() /
step <<
"s / step).\n" <<
accCount<<
" steps were accepted." << std::endl;
259 gErrorIgnoreLevel = originalErrorLevel;
267 for (
const auto &s :
samples) {
268 for (
int iExisting = 0; iExisting < s->GetNSamples(); ++iExisting) {
269 for (
int iNew = 0; iNew < sample->
GetNSamples(); ++iNew) {
270 if (s->GetSampleTitle(iExisting) == sample->
GetSampleTitle(iNew)) {
272 "Duplicate sample title '{}' in handler {} detected: "
274 sample->
GetName(), s->GetName());
281 for (
const auto &s :
samples) {
282 if (s->GetName() == sample->
GetName()) {
306 for (
int iPar = 0; iPar <
systematics[s]->GetNumParams(); ++iPar)
311 MACH3LOG_ERROR(
"ParameterHandler {} has param '{}' which already exists in in {}, with name {}",
317 MACH3LOG_ERROR(
"ParameterHandler {} has param '{}' which already exists in {}, with name {}",
335 CorrMatrix->Write((cov->
GetName() + std::string(
"_Corr")).c_str());
353 TFile *infile =
M3::Open(FitName,
"READ", __FILE__, __LINE__);
354 TTree *posts = infile->Get<TTree>(
"posteriors");
356 posts->SetBranchAddress(
"LogL",&log_val);
360 TDirectory* CovarianceFolder = infile->Get<TDirectory>(
"CovarianceFolder");
362 std::string ConfigName =
"Config_" +
systematics[s]->GetName();
363 TMacro *ConfigCov = CovarianceFolder->Get<TMacro>(ConfigName.c_str());
365 if (ConfigCov !=
nullptr) {
369 YAML::Node ConfigCurrent =
systematics[s]->GetConfig();
373 MACH3LOG_ERROR(
"Yaml configs in previous chain (from path {}) and current one are different", FitName);
379 CovarianceFolder->Close();
380 delete CovarianceFolder;
382 std::vector<double> branch_vals;
383 std::vector<std::string> branch_name;
384 systematics[s]->MatchMaCh3OutputBranches(posts, branch_vals, branch_name);
385 posts->GetEntry(posts->GetEntries()-1);
394 for (
int i = 0; i <
systematics[s]->GetNumParams(); ++i) {
395 posts->SetBranchAddress(
systematics[s]->GetParName(i).c_str(),
nullptr);
410 if (
fitMan ==
nullptr)
return;
413 if (GetFromManager<bool>(
fitMan->
raw()[
"General"][
"ProcessMCMC"],
false, __FILE__ , __LINE__)){
419 TVectorD *Central =
nullptr;
420 TVectorD *Errors =
nullptr;
421 TVectorD *Central_Gauss =
nullptr;
422 TVectorD *Errors_Gauss =
nullptr;
423 TVectorD *Peaks =
nullptr;
426 Processor.
GetPostfit(Central, Errors, Central_Gauss, Errors_Gauss, Peaks);
430 TMatrixDSym *Covariance =
nullptr;
431 TMatrixDSym *Correlation =
nullptr;
441 MACH3LOG_INFO(
"Opening output again to update with means..");
442 outputFile =
new TFile(Get<std::string>(
fitMan->
raw()[
"General"][
"OutputFile"], __FILE__, __LINE__).c_str(),
"UPDATE");
444 Central->Write(
"PDF_Means");
445 Errors->Write(
"PDF_Errors");
446 Central_Gauss->Write(
"Gauss_Means");
447 Errors_Gauss->Write(
"Errors_Gauss");
448 Covariance->Write(
"Covariance");
449 Correlation->Write(
"Correlation");
461 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs)
463 TStopwatch clockRace;
465 for(
int Lap = 0; Lap < NLaps; ++Lap) {
469 MACH3LOG_INFO(
"It took {:.4f} s to reweights {} times sample: {}", clockRace.RealTime(), NLaps,
samples[ivs]->GetName());
470 MACH3LOG_INFO(
"On average {:.6f}", clockRace.RealTime()/NLaps);
473 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs)
475 TStopwatch clockRace;
477 for(
int Lap = 0; Lap < NLaps; ++Lap) {
481 MACH3LOG_INFO(
"It took {:.4f} s to calculate GetLikelihood {} times sample: {}", clockRace.RealTime(), NLaps,
samples[ivs]->GetName());
482 MACH3LOG_INFO(
"On average {:.6f}", clockRace.RealTime()/NLaps);
485 std::vector<std::vector<double>> StepsValuesBefore(
systematics.size());
487 StepsValuesBefore[s] =
systematics[s]->GetProposed();
490 TStopwatch clockRace;
492 for(
int Lap = 0; Lap < NLaps; ++Lap) {
496 MACH3LOG_INFO(
"It took {:.4f} s to propose step {} times cov: {}", clockRace.RealTime(), NLaps,
systematics[s]->GetName());
497 MACH3LOG_INFO(
"On average {:.6f}", clockRace.RealTime()/NLaps);
500 systematics[s]->SetParameters(StepsValuesBefore[s]);
504 TStopwatch clockRace;
506 for(
int Lap = 0; Lap < NLaps; ++Lap) {
510 MACH3LOG_INFO(
"It took {:.4f} s to calculate get likelihood {} times cov: {}", clockRace.RealTime(), NLaps,
systematics[s]->GetName());
511 MACH3LOG_INFO(
"On average {:.6f}", clockRace.RealTime()/NLaps);
519 bool isScanRanges =
false;
521 if(
fitMan->
raw()[
"LLHScan"][
"ScanRanges"]){
522 YAML::Node scanRangesList =
fitMan->
raw()[
"LLHScan"][
"ScanRanges"];
523 for (
auto it = scanRangesList.begin(); it != scanRangesList.end(); ++it) {
524 std::string itname = it->first.as<std::string>();
525 std::vector<double> itrange = it->second.as<std::vector<double>>();
527 scanRanges[itname] = itrange;
531 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 {:.4f} rather than prior {:.4f}", 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];
909 TFile* outputFileLLH =
nullptr;
910 bool ownsfile =
false;
912 if(outputFileName !=
""){
918 outputFileLLH =
M3::Open(outputFileName,
"READ", __FILE__, __LINE__);
927 auto ParamVector = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"LLHScan"][
"StepScaleParameters"], {}, __FILE__ , __LINE__);
929 std::string LLH_type =
"Sample_LLH";
930 const std::string llhType = GetFromManager<std::string>(
fitMan->
raw()[
"LLHScan"][
"LLHType"], {}, __FILE__ , __LINE__);
931 if(!llhType.empty()){
935 TDirectory *LLHScans =
nullptr;
936 if(outputFileLLH !=
nullptr)
937 LLHScans = outputFileLLH->Get<TDirectory>(LLH_type.c_str());
939 if(!LLHScans || LLHScans->IsZombie() || LLHScans ==
nullptr)
941 MACH3LOG_WARN(
"Couldn't find LLH directory, it looks like LLH scan wasn't run, will do this now");
944 LLHScans = outputFileLLH->Get<TDirectory>(LLH_type.c_str());
950 cov->PrintIndivStepScale();
951 const int npars = cov->GetNumParams();
954 std::vector<std::vector<std::string>> CorrParams(npars);
955 std::vector<double> StepScale(npars);
956 TMatrixDSym *cov_matrix = cov->GetCovMatrix();
958 for (
int i = 0; i < npars; ++i)
960 std::string name = cov->GetParFancyName(i);
963 std::map<std::string, double> parCorr;
964 for (
int j = 0; j < npars; ++j) {
965 double correlation = (*cov_matrix)(i, j) / std::sqrt((*cov_matrix)(i, i) * (*cov_matrix)(j, j));
966 std::string par_corr_name = cov->GetParFancyName(j);
967 parCorr[par_corr_name] = correlation;
970 for (
const auto& corrMap : parCorr){
971 std::string corr_var_name = corrMap.first;
972 if (!ParamVector.empty()){
973 if (std::find(ParamVector.begin(), ParamVector.end(), name) == ParamVector.end()) {
977 if (std::find(ParamVector.begin(), ParamVector.end(), corr_var_name) == ParamVector.end()) {
983 double corr = corrMap.second;
984 int index = cov->GetParIndex(corr_var_name);
985 if(index == i)
continue;
988 std::string parameter_group_i =
"";
989 std::string parameter_group_index =
"";
992 parameter_group_i = param_handler->GetParamGroup(i);
993 parameter_group_index = param_handler->GetParamGroup(index);
995 if(std::abs(corr) > 0.3 && parameter_group_i == parameter_group_index)
996 CorrParams[i].push_back(corr_var_name);
998 StepScale[i] = cov->GetIndivStepScale(i);
1000 if (!ParamVector.empty()){
1001 if (std::find(ParamVector.begin(), ParamVector.end(), name) == ParamVector.end()) {
1007 TH1D* LLHScan =
nullptr;
1008 if(LLH_type ==
"Total_LLH")
1009 LLHScan = LLHScans->Get<TH1D>((name+
"_full").c_str());
1011 LLHScan = LLHScans->Get<TH1D>((name+
"_sam").c_str());
1013 if(LLHScan ==
nullptr)
1015 MACH3LOG_WARN(
"Couldn't find LLH scan, for {}, skipping", name);
1018 const double LLH_val = std::max(LLHScan->GetBinContent(1), LLHScan->GetBinContent(LLHScan->GetNbinsX()));
1020 if(LLH_val < 0.001)
continue;
1025 const double Var = 1.;
1026 const double approxSigma = std::abs(Var)/std::sqrt(LLH_val);
1027 const double GlobalScale = cov->GetGlobalStepScale();
1029 const double TargetStep = approxSigma * 2.38 / std::sqrt(npars);
1031 const double NewStepScale = TargetStep / GlobalScale;
1033 StepScale[i] = NewStepScale;
1035 MACH3LOG_DEBUG(
"Target Step Size (before accounting for global step size): {}", TargetStep);
1038 std::vector<double> StepScaleCorr = StepScale;
1039 for (
int p = 0; p < npars; p++){
1041 if(CorrParams[p].size() != 0){
1042 double avg_step_scale = StepScale[p];
1043 for(
const auto& corrName : CorrParams[p]) {
1044 int index = cov->GetParIndex(corrName);
1045 avg_step_scale += StepScale[index];
1048 avg_step_scale /=
static_cast<double>(CorrParams[p].size()) + 1.0;
1049 StepScaleCorr[p] = avg_step_scale;
1050 MACH3LOG_INFO(
"Changed step scale of parameter {} from {} to {}",cov->GetParFancyName(p),StepScale[p],StepScaleCorr[p]);
1054 cov->SetIndivStepScale(StepScaleCorr);
1055 cov->SaveUpdatedMatrixConfig();
1057 if(ownsfile && outputFileLLH !=
nullptr)
delete outputFileLLH;
1068 TDirectory *Sample_2DLLH =
outputFile->mkdir(
"Sample_2DLLH");
1069 auto SkipVector = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"LLHScan"][
"LLHScanSkipVector"], {}, __FILE__ , __LINE__);;
1072 bool LLHLogarithmic = GetFromManager<bool>(
fitMan->
raw()[
"LLHScan"][
"LLHLogarithmic"],
false, __FILE__ , __LINE__);
1075 const int n_points = GetFromManager<int>(
fitMan->
raw()[
"LLHScan"][
"2DLLHScanPoints"], 20, __FILE__ , __LINE__);
1077 const int countwidth = int(
double(n_points)/
double(5));
1084 int npars = cov->GetNumParams();
1085 bool IsPCA = cov->IsPCA();
1086 if (IsPCA) npars = cov->GetNParameters();
1088 for (
int i = 0; i < npars; ++i)
1090 std::string name_x = cov->GetParFancyName(i);
1091 if (IsPCA) name_x +=
"_PCA";
1093 double central_x, lower_x, upper_x;
1095 std::vector<double> binEdges_x;
1099 if (lower_x < 0.0 || upper_x < 0.0){
1100 MACH3LOG_WARN(
"Cannot perform logarithmic scan for {} "" with range [{}, {}], falling back to linear scan", name_x, lower_x, upper_x);
1108 for (
int j = 0; j < i; ++j)
1110 std::string name_y = cov->GetParFancyName(j);
1111 if (IsPCA) name_y +=
"_PCA";
1115 std::unique_ptr<TH2D> hScanSam;
1117 double central_y, lower_y, upper_y;
1121 if (lower_x < 0.0 || upper_x < 0.0 || lower_y < 0.0 || upper_y < 0.0 ) {
1122 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);
1123 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);
1124 hScanSam->SetDirectory(
nullptr);
1125 hScanSam->GetXaxis()->SetTitle(name_x.c_str());
1126 hScanSam->GetYaxis()->SetTitle(name_y.c_str());
1127 hScanSam->GetZaxis()->SetTitle(
"2LLH_sam");
1130 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());
1135 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);
1136 hScanSam->SetDirectory(
nullptr);
1137 hScanSam->GetXaxis()->SetTitle(name_x.c_str());
1138 hScanSam->GetYaxis()->SetTitle(name_y.c_str());
1139 hScanSam->GetZaxis()->SetTitle(
"2LLH_sam");
1143 for (
int x = 0; x < n_points; ++x)
1145 if (x % countwidth == 0)
1148 for (
int y = 0; y < n_points; ++y)
1152 cov->GetPCAHandler()->SetParPropPCA(i, hScanSam->GetXaxis()->GetBinCenter(x+1));
1153 cov->GetPCAHandler()->SetParPropPCA(j, hScanSam->GetYaxis()->GetBinCenter(y+1));
1156 cov->SetParProp(i, hScanSam->GetXaxis()->GetBinCenter(x+1));
1157 cov->SetParProp(j, hScanSam->GetYaxis()->GetBinCenter(y+1));
1160 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs) {
1165 double samplellh = 0;
1166 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs) {
1167 samplellh +=
samples[ivs]->GetLikelihood();
1169 hScanSam->SetBinContent(x+1, y+1, 2*samplellh);
1177 cov->GetPCAHandler()->SetParPropPCA(i, central_x);
1178 cov->GetPCAHandler()->SetParPropPCA(j, central_y);
1180 cov->SetParProp(i, central_x);
1181 cov->SetParProp(j, central_y);
1186 Sample_2DLLH->Write();
1187 delete Sample_2DLLH;
1200 bool PlotLLHScanBySample = GetFromManager<bool>(
fitMan->
raw()[
"LLHScan"][
"LLHScanBySample"],
false, __FILE__ , __LINE__);
1201 auto ParamsOfInterest = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"LLHScan"][
"LLHParameters"], {}, __FILE__, __LINE__);
1203 if(ParamsOfInterest.empty()) {
1204 MACH3LOG_WARN(
"There were no LLH parameters of interest specified to run the LLHMap! LLHMap will not run at all ...");
1210 std::vector<std::tuple<std::string, ParameterHandlerBase*, int>> ParamsCovIDs;
1211 for(
auto& p : ParamsOfInterest) {
1214 for(
int c = 0; c < cov->GetNumParams(); ++c) {
1215 if(cov->GetParName(c) == p || cov->GetParFancyName(c) == p) {
1217 for(
auto& pc : ParamsCovIDs) {
1218 if(std::get<1>(pc) == cov && std::get<2>(pc) == c)
1220 MACH3LOG_WARN(
"Parameter {} as {}({}) listed multiple times for LLHMap, omitting and using only once!", p, cov->GetName(), c);
1227 ParamsCovIDs.push_back(std::make_tuple(p, cov, c));
1237 MACH3LOG_INFO(
"Parameter {} found in {} at an index {}.", p, std::get<1>(ParamsCovIDs.back())->GetName(), std::get<2>(ParamsCovIDs.back()));
1239 MACH3LOG_WARN(
"Parameter {} not found in any of the systematic covariance objects. Will not scan over this one!", p);
1243 std::map<std::string, std::pair<int, std::pair<double, double>>> ParamsRanges;
1245 MACH3LOG_INFO(
"======================================================================================");
1246 MACH3LOG_INFO(
"Performing a general multi-dimensional LogL map scan over following parameters ranges:");
1247 MACH3LOG_INFO(
"======================================================================================");
1248 unsigned long TotalPoints = 1;
1250 double nSigma = GetFromManager<int>(
fitMan->
raw()[
"LLHScan"][
"LLHScanSigma"], 1., __FILE__, __LINE__);
1255 for(
auto& p : ParamsCovIDs) {
1257 std::string name = std::get<0>(p);
1258 int i = std::get<2>(p);
1261 ParamsRanges[name].first = GetFromManager<int>(
fitMan->
raw()[
"LLHScan"][
"LLHScanPoints"], 20, __FILE__, __LINE__);
1263 ParamsRanges[name].first = GetFromManager<int>(
fitMan->
raw()[
"LLHScan"][
"ScanPoints"][name], ParamsRanges[name].first, __FILE__, __LINE__);
1268 bool IsPCA = cov->
IsPCA();
1276 if (std::abs(CentralValue - prior) > 1e-10) {
1277 MACH3LOG_INFO(
"For {} scanning around value {} rather than prior {}", name, CentralValue, prior);
1295 ParamsRanges[name].second = {lower,upper};
1298 ParamsRanges[name].second = GetFromManager<std::pair<double,double>>(
fitMan->
raw()[
"LLHScan"][
"ScanRanges"][name], ParamsRanges[name].second, __FILE__, __LINE__);
1300 MACH3LOG_INFO(
"{} from {:.4f} (lower bin edge) to {:.4f} (upper bin edge) with a {:.5f} step ({} points total)",
1301 name, ParamsRanges[name].second.first, ParamsRanges[name].second.second,
1302 (ParamsRanges[name].second.second - ParamsRanges[name].second.first)/(ParamsRanges[name].first),
1303 ParamsRanges[name].first);
1305 TotalPoints *= ParamsRanges[name].first;
1309 MACH3LOG_INFO(
"In total, looping over {} points, from {} parameters. Estimates for run time:", TotalPoints, ParamsCovIDs.size());
1310 MACH3LOG_INFO(
" 1 s per point = {:.4f} hours",
double(TotalPoints)/3600.);
1311 MACH3LOG_INFO(
" 0.1 s per point = {:.4f} hours",
double(TotalPoints)/36000.);
1312 MACH3LOG_INFO(
"0.01 s per point = {:.4f} hours",
double(TotalPoints)/360000.);
1313 MACH3LOG_INFO(
"==================================================================================");
1315 const int countwidth = int(
double(TotalPoints)/
double(20));
1318 auto LLHMap =
new TTree(
"llhmap",
"LLH Map");
1321 for(
unsigned int ivc = 0; ivc <
systematics.size(); ++ivc )
1323 std::string NameTemp =
systematics[ivc]->GetName();
1324 NameTemp = NameTemp.substr(0, NameTemp.find(
"_cov")) +
"_LLH";
1325 LLHMap->Branch(NameTemp.c_str(), &CovLogL[ivc]);
1328 std::vector<double> SampleClassLogL(
samples.size());
1329 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
1331 std::string NameTemp =
samples[ivs]->GetName()+
"_LLH";
1332 LLHMap->Branch(NameTemp.c_str(), &SampleClassLogL[ivs]);
1335 double SampleLogL, TotalLogL;
1336 LLHMap->Branch(
"Sample_LLH", &SampleLogL);
1337 LLHMap->Branch(
"Total_LLH", &TotalLogL);
1339 std::vector<double>SampleSplitLogL;
1340 if(PlotLLHScanBySample)
1343 int SampleIterator = 0;
1344 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
1346 for(
int is = 0; is <
samples[ivs]->GetNSamples(); ++is )
1348 std::string NameTemp =
samples[ivs]->GetSampleTitle(is)+
"_LLH";
1349 LLHMap->Branch(NameTemp.c_str(), &SampleSplitLogL[SampleIterator]);
1355 std::vector<double> ParamsValues(ParamsCovIDs.size());
1356 for(
unsigned int i=0; i < ParamsCovIDs.size(); ++i)
1357 LLHMap->Branch(std::get<0>(ParamsCovIDs[i]).c_str(), &ParamsValues[i]);
1361 std::vector<unsigned long> idx(ParamsCovIDs.size(), 0);
1364 for(
unsigned long sp = 0; sp < TotalPoints; ++sp)
1367 for(
unsigned int n = 0; n < ParamsCovIDs.size(); ++n)
1370 std::string name = std::get<0>(ParamsCovIDs[n]);
1371 int points = ParamsRanges[name].first;
1372 double low = ParamsRanges[name].second.first;
1373 double high = ParamsRanges[name].second.second;
1376 unsigned long dev = 1;
1377 for(
unsigned int m = 0; m <= n; ++m)
1378 dev *= ParamsRanges[std::get<0>(ParamsCovIDs[m])].first;
1382 idx[n] = idx[n] / ( dev / points );
1385 ParamsValues[n] = low + (2 * double(idx[n]) + 1) * (high-low) / (2 * double(points));
1390 int i = std::get<2>(ParamsCovIDs[n]);
1402 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs)
1405 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs)
1407 SampleClassLogL[ivs] = 2.*
samples[ivs]->GetLikelihood();
1408 SampleLogL += SampleClassLogL[ivs];
1410 TotalLogL += SampleLogL;
1413 for(
unsigned int ivc = 0; ivc <
systematics.size(); ++ivc )
1415 CovLogL[ivc] = 2.*
systematics[ivc]->GetLikelihood();
1416 TotalLogL += CovLogL[ivc];
1419 if(PlotLLHScanBySample)
1421 int SampleIterator = 0;
1422 for(
unsigned int ivs = 0; ivs <
samples.size(); ++ivs )
1424 for(
int is = 0; is <
samples[ivs]->GetNSamples(); ++is)
1426 SampleSplitLogL[SampleIterator] = 2.*
samples[ivs]->GetSampleLikelihood(is);
1434 if (sp % countwidth == 0)
1446 if(!
fitMan->
raw()[
"SigmaVar"][
"CustomRange"])
return;
1448 auto Config =
fitMan->
raw()[
"SigmaVar"][
"CustomRange"];
1450 const auto sigmaStr = std::to_string(
static_cast<int>(std::round(sigma)));
1452 if (Config[ParName] && Config[ParName][sigmaStr]) {
1453 ParamShiftValue = Config[ParName][sigmaStr].as<
double>();
1454 MACH3LOG_INFO(
" ::: setting custom range from config ::: {} -> {}", ParName, ParamShiftValue);
1463 hist->SetTitle(baseName.c_str());
1465 TString className = hist->ClassName();
1468 if (className.Contains(
"TH1")) {
1469 hist->GetYaxis()->SetTitle(
"Events");
1470 }
else if (className.Contains(
"TH2")) {
1471 hist->GetZaxis()->SetTitle(
"Events");
1473 hist->Write(baseName.c_str());
1479 const std::string& suffix,
1481 const bool by_channel,
1482 const std::vector<TDirectory*>& SampleDir) {
1485 for (
int iSample = 0; iSample < sample->
GetNSamples(); ++iSample) {
1486 SampleDir[iSample]->cd();
1488 for(
int iDim1 = 0; iDim1 < sample->
GetNDim(iSample); iDim1++) {
1489 std::string ProjectionName = sample->
GetKinVarName(iSample, iDim1);
1490 std::string ProjectionSuffix =
"_1DProj" + std::to_string(iDim1);
1494 for (
int iMode = 0; iMode < modes->
GetNModes(); ++iMode) {
1501 for (
int iChan = 0; iChan < sample->
GetNOscChannels(iSample); ++iChan) {
1507 if (by_mode && by_channel) {
1508 for (
int iMode = 0; iMode < modes->
GetNModes(); ++iMode) {
1509 for (
int iChan = 0; iChan < sample->
GetNOscChannels(iSample); ++iChan) {
1516 if (!by_mode && !by_channel) {
1517 auto hist = sample->
Get1DVarHist(iSample, ProjectionName);
1520 for (
int iDim2 = iDim1 + 1; iDim2 < sample->
GetNDim(iSample); ++iDim2) {
1522 std::string XVarName = sample->
GetKinVarName(iSample, iDim1);
1523 std::string YVarName = sample->
GetKinVarName(iSample, iDim2);
1526 auto hist2D = sample->
Get2DVarHist(iSample, XVarName, YVarName);
1529 std::string suffix2D =
"_2DProj_" + std::to_string(iDim1) +
"_vs_" + std::to_string(iDim2) + suffix;
1543 bool plot_by_mode = GetFromManager<bool>(
fitMan->
raw()[
"SigmaVar"][
"PlotByMode"],
false, __FILE__ , __LINE__);
1544 bool plot_by_channel = GetFromManager<bool>(
fitMan->
raw()[
"SigmaVar"][
"PlotByChannel"],
false, __FILE__ , __LINE__);
1545 auto SkipVector = GetFromManager<std::vector<std::string>>(
fitMan->
raw()[
"SigmaVar"][
"SkipVector"], {}, __FILE__ , __LINE__);
1547 if (plot_by_mode)
MACH3LOG_INFO(
"Plotting by sample and mode");
1548 if (plot_by_channel)
MACH3LOG_INFO(
"Plotting by sample and channel");
1549 if (!plot_by_mode && !plot_by_channel)
MACH3LOG_INFO(
"Plotting by sample only");
1550 if (plot_by_mode && plot_by_channel)
MACH3LOG_INFO(
"Plotting by sample, mode and channel");
1552 auto SigmaArray = GetFromManager<std::vector<double>>(
fitMan->
raw()[
"SigmaVar"][
"SigmaArray"], {-3, -1, 0, 1, 3}, __FILE__ , __LINE__);
1553 if (std::find(SigmaArray.begin(), SigmaArray.end(), 0.0) == SigmaArray.end()) {
1558 TDirectory* SigmaDir =
outputFile->mkdir(
"SigmaVar");
1563 for(
int i = 0; i <
systematics[s]->GetNumParams(); i++)
1565 std::string ParName =
systematics[s]->GetParFancyName(i);
1571 TDirectory* ParamDir = SigmaDir->mkdir(ParName.c_str());
1574 const double ParamCentralValue =
systematics[s]->GetParProp(i);
1575 const double Prior =
systematics[s]->GetParPreFit(i);
1576 const double ParamLower =
systematics[s]->GetLowerBound(i);
1577 const double ParamUpper =
systematics[s]->GetUpperBound(i);
1579 if (std::abs(ParamCentralValue - Prior) > 1e-10) {
1580 MACH3LOG_INFO(
"For {} scanning around value {} rather than prior {}", ParName, ParamCentralValue, Prior);
1583 for(
unsigned int iSample = 0; iSample <
samples.size(); ++iSample)
1585 auto* MaCh3Sample =
samples[iSample];
1586 std::vector<TDirectory*> SampleDir(MaCh3Sample->GetNSamples());
1587 for (
int SampleIndex = 0; SampleIndex < MaCh3Sample->GetNSamples(); ++SampleIndex) {
1588 SampleDir[SampleIndex] = ParamDir->mkdir(MaCh3Sample->GetSampleTitle(SampleIndex).c_str());
1591 for (
size_t j = 0; j < SigmaArray.size(); ++j) {
1592 double sigma = SigmaArray[j];
1594 double ParamShiftValue = ParamCentralValue + sigma * std::sqrt((*
systematics[s]->GetCovMatrix())(i,i));
1595 ParamShiftValue = std::max(std::min(ParamShiftValue, ParamUpper), ParamLower);
1600 MACH3LOG_INFO(
" - set to {:<5.2f} ({:<2} sigma shift)", ParamShiftValue, sigma);
1603 std::ostringstream valStream;
1604 valStream << std::fixed << std::setprecision(2) << ParamShiftValue;
1605 std::string valueStr = valStream.str();
1607 std::ostringstream sigmaStream;
1608 sigmaStream << std::fixed << std::setprecision(2) << std::abs(sigma);
1609 std::string sigmaStr = sigmaStream.str();
1613 suffix =
"_" + ParName +
"_nom_val_" + valueStr;
1615 std::string sign = (sigma > 0) ?
"p" :
"n";
1616 suffix =
"_" + ParName +
"_sig_" + sign + sigmaStr +
"_val_" + valueStr;
1620 MaCh3Sample->Reweight();
1624 for (
int subSampleIndex = 0; subSampleIndex < MaCh3Sample->GetNSamples(); ++subSampleIndex) {
1625 SampleDir[subSampleIndex]->Close();
1626 delete SampleDir[subSampleIndex];
1632 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.
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.
virtual std::string GetFancyName() const
This name is to get include some special algorithm extensions.
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 of systematic error parameters with different types defined in the con...
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.
std::string join(const Container &values, std::string_view separator=" ")
Join all values in a container into a single string.
void SetSeed(const std::uint64_t seed)
Set the global random seed.
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.