18 #include "TMatrixDSym.h"
24 #include "TObjString.h"
33 m_parser = std::make_unique<MaCh3ArgumentParser>(
"penterm",
"1.0", argparse::default_arguments::help);
34 m_parser->add_description(
"Calculate penalty term for selected parameters, for every step");
36 .help(
"Root file to analyse.")
50 std::string inputFile =
m_parser->get<std::string>(
"inputfile");
51 std::string config =
m_parser->get<std::string>(
"config");
69 std::vector <double>& Prior,
70 std::vector <bool>&
isFlat,
71 std::vector<std::string>& ParamNames,
72 std::vector<std::vector<double>>& invCovMatrix,
76 TFile *TempFile =
M3::Open(inputFile,
"open", __FILE__, __LINE__);
79 TDirectory* CovarianceFolder = TempFile->Get<TDirectory>(
"CovarianceFolder");
83 TMacro *Config = TempFile->Get<TMacro>(
"MaCh3_Config");
84 if (Config ==
nullptr) {
85 MACH3LOG_ERROR(
"Didn't find MaCh3_Config tree in MCMC file! {}", inputFile);
93 std::vector<std::string> CovPos = GetFromManager<std::vector<std::string>>(Settings[
"General"][
"Systematics"][
"XsecCovFile"], {
"none"}, __FILE__, __LINE__);
94 if(CovPos.back() ==
"none")
102 if (std::getenv(
"MACH3") !=
nullptr) {
103 MACH3LOG_INFO(
"Found MACH3 environment variable: {}", std::getenv(
"MACH3"));
104 for(
unsigned int i = 0; i < CovPos.size(); i++)
105 CovPos[i].insert(0, std::string(std::getenv(
"MACH3"))+
"/");
109 CovFile[
"Systematics"] = YAML::Node(YAML::NodeType::Sequence);
110 for(
unsigned int i = 0; i < CovPos.size(); i++)
113 for (
const auto& item : YAMLDocTemp[
"Systematics"]) {
114 CovFile[
"Systematics"].push_back(item);
118 nParams = CovMatrix->GetNrows();
120 auto systematics = CovFile[
"Systematics"];
121 for (
auto it = systematics.begin(); it != systematics.end(); ++it)
123 auto const ¶m = *it;
125 ParamNames.push_back(param[
"Systematic"][
"Names"][
"FancyName"].as<std::string>());
126 Prior.push_back( param[
"Systematic"][
"ParameterValues"][
"PreFitValue"].as<double>() );
129 if (param[
"Systematic"][
"FlatPrior"]) { flat = param[
"Systematic"][
"FlatPrior"].as<
bool>(); }
135 invCovMatrix.resize(nParams, std::vector<double>(nParams, -999));
138 #pragma omp parallel for collapse(2)
140 for (
int i = 0; i < nParams; i++)
142 for (
int j = 0; j < nParams; ++j)
144 invCovMatrix[i][j] = (*CovMatrix)(i,j);
164 std::vector<std::string>& SetsNames,
165 std::vector<std::string>& FancyTitle,
166 std::vector<std::vector<bool>>& isRelevantParam,
167 const std::vector<std::string>& ParamNames,
170 std::vector<std::string> node = Settings[
"GetPenaltyTerm"][
"PenaltySets"].as<std::vector<std::string>>();
171 std::vector<std::vector<std::string>> RemoveNames;
172 std::vector<bool> Exclude;
174 for (
unsigned int i = 0; i < node.size(); i++)
176 std::string ParName = node[i];
177 SetsNames.push_back(ParName);
179 const auto& Set = Settings[
"GetPenaltyTerm"][ParName];
181 RemoveNames.push_back(Set[0].as<std::vector<std::string>>());
182 Exclude.push_back(Set[1].as<bool>());
183 FancyTitle.push_back(Set[2].as<std::string>());
186 const int NSets = int(SetsNames.size());
188 isRelevantParam.resize(NSets);
190 for(
int i = 0; i < NSets; i++)
192 isRelevantParam[i].resize(nParams);
195 for (
int j = 0; j < nParams; j++)
197 isRelevantParam[i][j] =
false;
203 for (
unsigned int k = 0; k < RemoveNames[i].size(); k++)
205 if (ParamNames[j].rfind(RemoveNames[i][k], 0) == 0)
212 isRelevantParam[i][j] =
true;
219 for (
unsigned int k = 0; k < RemoveNames[i].size(); k++)
221 if (ParamNames[j].rfind(RemoveNames[i][k], 0) == 0)
223 isRelevantParam[i][j] =
true;
230 MACH3LOG_INFO(
" Found {} params for set {}", counter, SetsNames[i]);
244 auto canvas = std::make_unique<TCanvas>(
"canvas",
"canvas", 0, 0, 1024, 1024);
249 canvas->SetBottomMargin(0.1f);
250 canvas->SetTopMargin(0.02f);
251 canvas->SetRightMargin(0.08f);
252 canvas->SetLeftMargin(0.15f);
254 gStyle->SetOptTitle(0);
255 gStyle->SetOptStat(0);
256 gStyle->SetPalette(51);
258 std::vector <double> Prior;
259 std::vector <bool>
isFlat;
260 std::vector<std::string> ParamNames;
261 std::vector<std::vector<double>> invCovMatrix;
265 std::vector<TString> BranchNames;
268 TChain* Chain =
new TChain(
"posteriors",
"");
269 Chain->Add(inputFile.c_str());
272 TObjArray* brlis = Chain->GetListOfBranches();
275 int nBranches = brlis->GetEntries();
276 int RelevantBranches = 0;
277 for (
int i = 0; i < nBranches; i++)
280 TBranch* br =
static_cast<TBranch*
>(brlis->At(i));
285 TString bname = br->GetName();
288 if(bname.BeginsWith(
"param_"))
290 BranchNames.push_back(bname);
296 Chain->SetBranchStatus(
"*",
false);
298 std::vector<double> fParProp(RelevantBranches);
300 for (
int i = 0; i < RelevantBranches; ++i)
302 Chain->SetBranchStatus(BranchNames[i].Data(),
true);
303 Chain->SetBranchAddress(BranchNames[i].Data(), &fParProp[i]);
307 std::vector<std::string> SetsNames;
308 std::vector<std::string> FancyTitle;
309 std::vector<std::vector<bool>> isRelevantParam;
311 this->
LoadSettings(Settings, SetsNames, FancyTitle, isRelevantParam, ParamNames, nParams);
313 const int NSets = int(SetsNames.size());
314 int AllEvents = int(Chain->GetEntries());
315 std::vector<std::unique_ptr<TH1D>> hLogL(NSets);
316 for (
int i = 0; i < NSets; i++) {
317 std::string NameTemp =
"LogL_" + SetsNames[i];
318 hLogL[i] = std::make_unique<TH1D>(NameTemp.c_str(), NameTemp.c_str(), AllEvents, 0, AllEvents);
319 hLogL[i]->SetLineColor(kBlue);
321 std::vector<double> logL(NSets, 0.0);
322 for(
int n = 0; n < AllEvents; ++n)
328 for(
int k = 0; k < NSets; ++k) logL[k] = 0.;
331 double *logL_private =
nullptr;
335 #pragma omp parallel private(logL_private)
337 logL_private =
new double[NSets];
338 for(
int k = 0; k < NSets; ++k) logL_private[k] = 0.;
341 for (
int i = 0; i < nParams; i++)
343 for (
int j = 0; j <= i; ++j)
348 for(
int k = 0; k < NSets; ++k)
351 if (isRelevantParam[k][i] && isRelevantParam[k][j])
355 if(i != j) scale = 2;
356 logL_private[k] += scale * 0.5*(fParProp[i] - Prior[i])*(fParProp[j] - Prior[j])*invCovMatrix[i][j];
363 for(
int k = 0; k < NSets; ++k)
366 logL[k] += logL_private[k];
369 delete[] logL_private;
373 for (
int i = 0; i < nParams; i++)
375 for (
int j = 0; j <= i; ++j)
380 for(
int k = 0; k < NSets; ++k)
383 if (isRelevantParam[k][i] && isRelevantParam[k][j])
387 if(i != j) scale = 2;
388 logL[k] += scale * 0.5*(fParProp[i] - Prior[i])*(fParProp[j] - Prior[j])*invCovMatrix[i][j];
395 for(
int k = 0; k < NSets; ++k)
397 hLogL[k]->SetBinContent(n, logL[k]);
402 std::string OutputName = inputFile +
"_PenaltyTerm" +
".root";
403 TFile *OutputFile =
M3::Open(OutputName,
"recreate", __FILE__, __LINE__);
404 TDirectory *PenaltyTermDir = OutputFile->mkdir(
"PenaltyTerm");
406 canvas->Print(Form(
"%s_PenaltyTerm.pdf[",inputFile.c_str()),
"pdf");
407 for(
int i = 0; i < NSets; i++)
409 const double Maximum = hLogL[i]->GetMaximum();
410 hLogL[i]->GetYaxis()->SetRangeUser(0., Maximum*1.2);
411 hLogL[i]->SetTitle(FancyTitle[i].c_str());
412 hLogL[i]->GetXaxis()->SetTitle(
"Step");
413 hLogL[i]->GetYaxis()->SetTitle(FancyTitle[i].c_str());
414 hLogL[i]->GetYaxis()->SetTitleOffset(1.4f);
418 PenaltyTermDir->cd();
421 canvas->Print(Form(
"%s_PenaltyTerm.pdf",inputFile.c_str()),
"pdf");
423 canvas->Print(Form(
"%s_PenaltyTerm.pdf]",inputFile.c_str()),
"pdf");
#define _MaCh3_Safe_Include_Start_
KS: Avoiding warning checking for headers.
#define _MaCh3_Safe_Include_End_
Module for extracting penalty terms from systematic chains.
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
bool isFlat(TSpline3_red *&spl)
CW: Helper function used in the constructor, tests to see if the spline is flat.
YAML::Node TMacroToYAML(const TMacro ¯o)
KS: Convert a ROOT TMacro object to a YAML node.
#define M3OpenConfig(filename)
Macro to simplify calling LoadYaml with file and line info.
void LoadSettings(YAML::Node &Settings, std::vector< std::string > &SetsNames, std::vector< std::string > &FancyTitle, std::vector< std::vector< bool >> &isRelevantParam, const std::vector< std::string > &ParamNames, const int nParams)
Load penalty term sets from YAML configuration.
MaCh3ArgumentParser * get_parser() override
Get the argument parser for this module.
void ReadCovFile(const std::string &inputFile, std::vector< double > &Prior, std::vector< bool > &isFlat, std::vector< std::string > &ParamNames, std::vector< std::vector< double >> &invCovMatrix, int &nParams)
Read covariance matrix and parameter information from file.
void GetPenaltyTerm(const std::string &inputFile, const std::string &configFile)
Calculate and plot penalty terms for parameter sets.
int Run() override
Execute the penalty term extraction.
virtual ~GetPenaltyTermModule()
Destructor.
Extended ArgumentParser with MaCh3-specific functionality.
std::unique_ptr< MaCh3ArgumentParser > m_parser
Argument parser for this plugin.
Custom exception class used throughout MaCh3.
void PrintConfig(const YAML::Node &node)
KS: Print Yaml config using logger.
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.
void MaCh3Welcome()
KS: Prints welcome message with MaCh3 logo.
Main namespace for MaCh3 software.
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.
TMatrixDSym * GetCovMatrixFromChain(TDirectory *TempFile)
KS: Retrieve the cross-section covariance matrix from the given TDirectory. Historically,...