MaCh3  2.8.0
Reference Guide
Public Member Functions | Private Member Functions | List of all members
M3::GetPenaltyTermModule Class Reference

Module for extracting specific penalty terms from MCMC chains. More...

#include <CLI/Modules/GetPenaltyTermModule.hpp>

Inheritance diagram for M3::GetPenaltyTermModule:
[legend]
Collaboration diagram for M3::GetPenaltyTermModule:
[legend]

Public Member Functions

virtual ~GetPenaltyTermModule ()
 Destructor. More...
 
MaCh3ArgumentParser * get_parser () override
 Get the argument parser for this module. More...
 
int Run () override
 Execute the penalty term extraction. More...
 
- Public Member Functions inherited from M3::PluginBase
virtual ~PluginBase ()=default
 
- Public Member Functions inherited from M3::IPlugin
virtual ~IPlugin ()=default
 

Private Member Functions

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. More...
 
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. More...
 
void GetPenaltyTerm (const std::string &inputFile, const std::string &configFile)
 Calculate and plot penalty terms for parameter sets. More...
 

Additional Inherited Members

- Protected Attributes inherited from M3::PluginBase
std::unique_ptr< MaCh3ArgumentParser > m_parser
 Argument parser for this plugin. More...
 

Detailed Description

Module for extracting specific penalty terms from MCMC chains.

This module retrieves penalty terms from flux and cross-section systematic chains, since these systematic uncertainties are handled separately and the penalty term cannot be taken directly from the chain.

Definition at line 25 of file GetPenaltyTermModule.hpp.

Constructor & Destructor Documentation

◆ ~GetPenaltyTermModule()

M3::GetPenaltyTermModule::~GetPenaltyTermModule ( )
virtualdefault

Destructor.

Member Function Documentation

◆ get_parser()

MaCh3ArgumentParser * M3::GetPenaltyTermModule::get_parser ( )
overridevirtual

Get the argument parser for this module.

Returns
Pointer to the configured MaCh3ArgumentParser

Implements M3::IPlugin.

Definition at line 32 of file GetPenaltyTermModule.cpp.

32  {
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");
35  m_parser->add_argument("inputfile")
36  .help("Root file to analyse.")
37  .metavar("INPUTFILE")
38  .required();
39  m_parser->add_argument("config")
40  .help("Config file.")
41  .metavar("CONFIG")
42  .required();
43  return m_parser.get();
44  }
std::unique_ptr< MaCh3ArgumentParser > m_parser
Argument parser for this plugin.
Definition: plugin.hpp:44

◆ GetPenaltyTerm()

void M3::GetPenaltyTermModule::GetPenaltyTerm ( const std::string &  inputFile,
const std::string &  configFile 
)
private

Calculate and plot penalty terms for parameter sets.

Calculate and plot penalty terms for each parameter set.

Parameters
inputFilePath to the MCMC chain ROOT file
configFilePath to the YAML configuration file

Main function that reads the covariance, loads configuration, iterates through MCMC steps, and calculates penalty terms for each defined set. Results are saved to ROOT file and PDF plots.

Parameters
inputFilePath to the MCMC chain ROOT file
configFilePath to the YAML configuration file

Definition at line 242 of file GetPenaltyTermModule.cpp.

243  {
244  auto canvas = std::make_unique<TCanvas>("canvas", "canvas", 0, 0, 1024, 1024);
245  canvas->SetGrid();
246  canvas->SetTickx();
247  canvas->SetTicky();
248 
249  canvas->SetBottomMargin(0.1f);
250  canvas->SetTopMargin(0.02f);
251  canvas->SetRightMargin(0.08f);
252  canvas->SetLeftMargin(0.15f);
253 
254  gStyle->SetOptTitle(0);
255  gStyle->SetOptStat(0);
256  gStyle->SetPalette(51);
257 
258  std::vector <double> Prior;
259  std::vector <bool> isFlat;
260  std::vector<std::string> ParamNames;
261  std::vector<std::vector<double>> invCovMatrix;
262  int nParams;
263  this->ReadCovFile(inputFile, Prior, isFlat, ParamNames, invCovMatrix, nParams);
264 
265  std::vector<TString> BranchNames;
266 
267  // Open the Chain
268  TChain* Chain = new TChain("posteriors","");
269  Chain->Add(inputFile.c_str());
270 
271  // Get the list of branches
272  TObjArray* brlis = Chain->GetListOfBranches();
273 
274  // Get the number of branches
275  int nBranches = brlis->GetEntries();
276  int RelevantBranches = 0;
277  for (int i = 0; i < nBranches; i++)
278  {
279  // Get the TBranch and its name
280  TBranch* br = static_cast<TBranch*>(brlis->At(i));
281  if(!br){
282  MACH3LOG_ERROR("Invalid branch at position {}", i);
283  throw MaCh3Exception(__FILE__,__LINE__);
284  }
285  TString bname = br->GetName();
286 
287  // If we're on beam systematics
288  if(bname.BeginsWith("param_"))
289  {
290  BranchNames.push_back(bname);
291  RelevantBranches++;
292  }
293  }
294 
295  // Set all the branches to off
296  Chain->SetBranchStatus("*", false);
297 
298  std::vector<double> fParProp(RelevantBranches);
299  // Turn on the branches which we want for parameters
300  for (int i = 0; i < RelevantBranches; ++i)
301  {
302  Chain->SetBranchStatus(BranchNames[i].Data(), true);
303  Chain->SetBranchAddress(BranchNames[i].Data(), &fParProp[i]);
304  }
305 
306  YAML::Node Settings = M3OpenConfig(configFile);
307  std::vector<std::string> SetsNames;
308  std::vector<std::string> FancyTitle;
309  std::vector<std::vector<bool>> isRelevantParam;
310 
311  this->LoadSettings(Settings, SetsNames, FancyTitle, isRelevantParam, ParamNames, nParams);
312 
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);
320  }
321  #pragma GCC diagnostic push
322  #pragma GCC diagnostic ignored "-Walloca"
323  for(int n = 0; n < AllEvents; ++n)
324  {
325  if(n%10000 == 0) M3::Utils::PrintProgressBar(n, AllEvents);
326  Chain->GetEntry(n);
327 
328  std::vector<double> logL(NSets, 0.0);
329  double* _restrict_ logL_array = logL.data();
330  #ifdef MULTITHREAD
331  #pragma omp parallel for reduction(+:logL_array[:NSets])
332  #endif
333  for (int i = 0; i < nParams; i++)
334  {
335  for (int j = 0; j <= i; ++j)
336  {
337  //check if flat prior
338  if (!isFlat[i] && !isFlat[j])
339  {
340  for(int k = 0; k < NSets; ++k)
341  {
342  //Check if parameter is relevant for this set
343  if (isRelevantParam[k][i] && isRelevantParam[k][j])
344  {
345  //KS: Since matrix is symmetric we can calculate non diagonal elements only once and multiply by 2, can bring up to factor speed decrease.
346  int scale = 1;
347  if(i != j) scale = 2;
348  logL_array[k] += scale * 0.5*(fParProp[i] - Prior[i])*(fParProp[j] - Prior[j])*invCovMatrix[i][j];
349  }
350  }
351  }
352  }
353  } // end loop over params
354  for(int k = 0; k < NSets; ++k)
355  {
356  hLogL[k]->SetBinContent(n, logL_array[k]);
357  }
358  } //End loop over steps
359  #pragma GCC diagnostic pop
360  // Directory for posteriors
361  std::string OutputName = inputFile + "_PenaltyTerm" +".root";
362  TFile *OutputFile = M3::Open(OutputName, "recreate", __FILE__, __LINE__);
363  TDirectory *PenaltyTermDir = OutputFile->mkdir("PenaltyTerm");
364 
365  canvas->Print(Form("%s_PenaltyTerm.pdf[",inputFile.c_str()), "pdf");
366  for(int i = 0; i < NSets; i++)
367  {
368  const double Maximum = hLogL[i]->GetMaximum();
369  hLogL[i]->GetYaxis()->SetRangeUser(0., Maximum*1.2);
370  hLogL[i]->SetTitle(FancyTitle[i].c_str());
371  hLogL[i]->GetXaxis()->SetTitle("Step");
372  hLogL[i]->GetYaxis()->SetTitle(FancyTitle[i].c_str());
373  hLogL[i]->GetYaxis()->SetTitleOffset(1.4f);
374 
375  hLogL[i]->Draw("");
376 
377  PenaltyTermDir->cd();
378  hLogL[i]->Write();
379 
380  canvas->Print(Form("%s_PenaltyTerm.pdf",inputFile.c_str()), "pdf");
381  }
382  canvas->Print(Form("%s_PenaltyTerm.pdf]",inputFile.c_str()), "pdf");
383  delete Chain;
384 
385  OutputFile->Close();
386  delete OutputFile;
387  }
#define _restrict_
KS: Using restrict limits the effects of pointer aliasing, aiding optimizations. While reading I foun...
Definition: Core.h:108
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
bool isFlat(TSpline3_red *&spl)
CW: Helper function used in the constructor, tests to see if the spline is flat.
#define M3OpenConfig(filename)
Macro to simplify calling LoadYaml with file and line info.
Definition: YamlHelper.h:589
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.
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.
Custom exception class used throughout MaCh3.
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.
Definition: Monitor.cpp:229
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.

◆ LoadSettings()

void M3::GetPenaltyTermModule::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 
)
private

Load penalty term sets from YAML configuration.

Load penalty term set definitions from YAML configuration.

Parameters
SettingsYAML configuration node
SetsNamesVector to store set names
FancyTitleVector to store fancy titles for each set
isRelevantParam2D vector indicating which parameters belong to each set
ParamNamesVector of all parameter names
nParamsTotal number of parameters

Parses the configuration to determine which parameters belong to each penalty term set, based on either inclusion or exclusion patterns.

Parameters
SettingsYAML configuration node
SetsNamesVector to be filled with set names
FancyTitleVector to be filled with fancy titles for plotting
isRelevantParam2D vector to be filled with parameter relevance flags
ParamNamesVector of all parameter names from the covariance
nParamsTotal number of parameters

Definition at line 163 of file GetPenaltyTermModule.cpp.

169  {
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;
173 
174  for (unsigned int i = 0; i < node.size(); i++)
175  {
176  std::string ParName = node[i];
177  SetsNames.push_back(ParName);
178 
179  const auto& Set = Settings["GetPenaltyTerm"][ParName];
180 
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>());
184  }
185 
186  const int NSets = int(SetsNames.size());
187 
188  isRelevantParam.resize(NSets);
189  //Loop over sets in the config
190  for(int i = 0; i < NSets; i++)
191  {
192  isRelevantParam[i].resize(nParams);
193  int counter = 0;
194  //Loop over parameters in the Covariance object
195  for (int j = 0; j < nParams; j++)
196  {
197  isRelevantParam[i][j] = false;
198 
199  //KS: Here we loop over all names and if parameters wasn't matched then we set it is relevant.
200  if(Exclude[i])
201  {
202  bool found = false;
203  for (unsigned int k = 0; k < RemoveNames[i].size(); k++)
204  {
205  if (ParamNames[j].rfind(RemoveNames[i][k], 0) == 0)
206  {
207  found = true;
208  }
209  }
210  if(!found)
211  {
212  isRelevantParam[i][j] = true;
213  counter++;
214  }
215  }
216  //KS: Here is much simpler, if parameter matched then it is relevant
217  else
218  {
219  for (unsigned int k = 0; k < RemoveNames[i].size(); k++)
220  {
221  if (ParamNames[j].rfind(RemoveNames[i][k], 0) == 0)
222  {
223  isRelevantParam[i][j] = true;
224  counter++;
225  break;
226  }
227  }
228  }
229  }
230  MACH3LOG_INFO(" Found {} params for set {}", counter, SetsNames[i]);
231  }
232  }
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35

◆ ReadCovFile()

void M3::GetPenaltyTermModule::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 
)
private

Read covariance matrix and parameter information from file.

Read covariance matrix and prior information from ROOT file.

Parameters
inputFilePath to the ROOT file containing the covariance
PriorVector to store prior parameter values
isFlatVector to store flat prior flags
ParamNamesVector to store parameter names
invCovMatrix2D vector to store inverted covariance matrix
nParamsReference to store the number of parameters

Loads the covariance matrix, inverts it, and extracts parameter priors and flat prior flags from the MCMC output file.

Parameters
inputFilePath to the ROOT file containing MCMC output
PriorVector to be filled with prior parameter values
isFlatVector to be filled with flat prior flags
ParamNamesVector to be filled with parameter names
invCovMatrix2D vector to be filled with inverted covariance matrix
nParamsReference to store the number of parameters

Definition at line 68 of file GetPenaltyTermModule.cpp.

74  {
75  // Now read the MCMC file
76  TFile *TempFile = M3::Open(inputFile, "open", __FILE__, __LINE__);
77 
78  // Get the matrix
79  TDirectory* CovarianceFolder = TempFile->Get<TDirectory>("CovarianceFolder");
80  TMatrixDSym *CovMatrix = M3::GetCovMatrixFromChain(CovarianceFolder);
81 
82  // Get the settings for the MCMC
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);
86  TempFile->ls();
87  throw MaCh3Exception(__FILE__ , __LINE__ );
88  }
89 
90  YAML::Node Settings = TMacroToYAML(*Config);
91 
92  //CW: Get the Covariance matrix
93  std::vector<std::string> CovPos = GetFromManager<std::vector<std::string>>(Settings["General"]["Systematics"]["XsecCovFile"], {"none"}, __FILE__, __LINE__);
94  if(CovPos.back() == "none")
95  {
96  MACH3LOG_WARN("Couldn't find Cov branch in output");
97  M3::Utils::PrintConfig(Settings);
98  throw MaCh3Exception(__FILE__ , __LINE__ );
99  }
100 
101  //KS:Most inputs are in ${MACH3}/inputs/blarb.root
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"))+"/");
106  }
107 
108  YAML::Node CovFile;
109  CovFile["Systematics"] = YAML::Node(YAML::NodeType::Sequence);
110  for(unsigned int i = 0; i < CovPos.size(); i++)
111  {
112  YAML::Node YAMLDocTemp = M3OpenConfig(CovPos[i]);
113  for (const auto& item : YAMLDocTemp["Systematics"]) {
114  CovFile["Systematics"].push_back(item);
115  }
116  }
117 
118  nParams = CovMatrix->GetNrows();
119 
120  auto systematics = CovFile["Systematics"];
121  for (auto it = systematics.begin(); it != systematics.end(); ++it)
122  {
123  auto const &param = *it;
124 
125  ParamNames.push_back(param["Systematic"]["Names"]["FancyName"].as<std::string>());
126  Prior.push_back( param["Systematic"]["ParameterValues"]["PreFitValue"].as<double>() );
127 
128  bool flat = false;
129  if (param["Systematic"]["FlatPrior"]) { flat = param["Systematic"]["FlatPrior"].as<bool>(); }
130  isFlat.push_back( flat );
131  }
132 
133  CovMatrix->Invert();
134  //KS: Let's use double as it is faster than TMatrix
135  invCovMatrix.resize(nParams, std::vector<double>(nParams, -999));
136 
137  #ifdef MULTITHREAD
138  #pragma omp parallel for collapse(2)
139  #endif
140  for (int i = 0; i < nParams; i++)
141  {
142  for (int j = 0; j < nParams; ++j)
143  {
144  invCovMatrix[i][j] = (*CovMatrix)(i,j);
145  }
146  }
147 
148  TempFile->Close();
149  delete TempFile;
150  }
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36
YAML::Node TMacroToYAML(const TMacro &macro)
KS: Convert a ROOT TMacro object to a YAML node.
Definition: YamlHelper.h:151
void PrintConfig(const YAML::Node &node)
KS: Print Yaml config using logger.
Definition: Monitor.cpp:311
TMatrixDSym * GetCovMatrixFromChain(TDirectory *TempFile)
KS: Retrieve the cross-section covariance matrix from the given TDirectory. Historically,...

◆ Run()

int M3::GetPenaltyTermModule::Run ( )
overridevirtual

Execute the penalty term extraction.

Returns
Exit code (0 on success)

Implements M3::IPlugin.

Definition at line 46 of file GetPenaltyTermModule.cpp.

47  {
50  std::string inputFile = m_parser->get<std::string>("inputfile");
51  std::string config = m_parser->get<std::string>("config");
52  this->GetPenaltyTerm(inputFile, config);
53 
54  return 0;
55  }
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
Definition: MaCh3Logger.h:60
void GetPenaltyTerm(const std::string &inputFile, const std::string &configFile)
Calculate and plot penalty terms for parameter sets.
void MaCh3Welcome()
KS: Prints welcome message with MaCh3 logo.
Definition: Monitor.cpp:13

The documentation for this class was generated from the following files: