MaCh3  2.8.0
Reference Guide
ParameterHandlerGeneric.cpp
Go to the documentation of this file.
2 
3 // ********************************************
4 // ETA - YAML constructor
5 // this will replace the root file constructor but let's keep it in
6 // to do some validations
7 ParameterHandlerGeneric::ParameterHandlerGeneric(const std::vector<std::string>& YAMLFile, std::string name,
8  double threshold, int FirstPCA, int LastPCA) {
9 // ********************************************
10  MACH3LOG_INFO("Constructing instance of ParameterHandler using");
11  inputFile = YAMLFile[0];
12  matrixName = name;
13  pca = true;
14 
15  doSpecialStepProposal = false;
16  // Not using adaptive by default
17  use_adaptive = false;
18  for(unsigned int i = 0; i < YAMLFile.size(); i++)
19  {
20  MACH3LOG_INFO("{}", YAMLFile[i]);
21  }
22  MACH3LOG_INFO("as an input");
23 
24  if (threshold < 0 || threshold >= 1) {
25  MACH3LOG_INFO("Principal component analysis but given the threshold for the principal components to be less than 0, or greater than (or equal to) 1. This will not work");
26  MACH3LOG_INFO("Please specify a number between 0 and 1");
27  MACH3LOG_INFO("You specified: ");
28  MACH3LOG_INFO("Am instead calling the usual non-PCA constructor...");
29  pca = false;
30  }
31 
32  InitialiseFromConfig(YAMLFile);
33  // Call the innocent helper function
34  if (pca) ConstructPCA(threshold, FirstPCA, LastPCA);
35 
37 
38  MACH3LOG_DEBUG("Constructing instance of ParameterHandler");
40  // Print
41  Print();
42 }
43 
44 // ********************************************
45 void ParameterHandlerGeneric::LoadAndMergeYAML(const std::vector<std::string>& YAMLFile,
46  std::map<std::pair<int,int>, std::unique_ptr<TMatrixDSym>>& ThrowSubMatrixOverrides) {
47 // ********************************************
48  int running_num_file_pars = 0;
49 
50  _fYAMLDoc["Systematics"] = YAML::Node(YAML::NodeType::Sequence);
51  for(unsigned int i = 0; i < YAMLFile.size(); i++)
52  {
53  YAML::Node YAMLDocTemp = M3OpenConfig(YAMLFile[i]);
54 
55  if (YAMLDocTemp["ThrowMatrixOverride"]) { // LP: this allows us to put in
56  // proposal matrix overrides per
57  // parameter-containing file, add
58  // the block diagonal proposal
59  // matrix to a list and overwrite
60  // the throw matrix after set up.
61  auto filename =
62  YAMLDocTemp["ThrowMatrixOverride"]["file"].as<std::string>();
63  TFile *submatrix_file = TFile::Open(filename.c_str());
64 
65  auto matrixname =
66  YAMLDocTemp["ThrowMatrixOverride"]["matrix"].as<std::string>();
67  std::unique_ptr<TMatrixDSym> submatrix{
68  submatrix_file->Get<TMatrixDSym>(matrixname.c_str())};
69  if (!submatrix) {
70  MACH3LOG_CRITICAL("Covariance matrix {} doesn't exist in file: {}",
71  matrixname, filename);
72  throw MaCh3Exception(__FILE__, __LINE__);
73  }
74  auto numrows = submatrix->GetNrows();
75  // LP: the -1 here is because we specify the last index for consistency
76  // with PCAHandler, not the first index after the end as is more common
77  // throughout computer science...
78  ThrowSubMatrixOverrides[{running_num_file_pars,
79  running_num_file_pars + (numrows - 1)}] = std::move(submatrix);
80 
81  // LP: check names by default, but have option to disable check if you
82  // know what you're doing
83  if (!bool(YAMLDocTemp["ThrowMatrixOverride"]["check_names"]) ||
84  YAMLDocTemp["ThrowMatrixOverride"]["check_names"].as<bool>()) {
85  auto nametree = submatrix_file->Get<TTree>("param_names");
86  if (!nametree) {
87  MACH3LOG_CRITICAL("TTree param_names doesn't exist in file: {}. Set "
88  "ThrowMatrixOverride: {{ check_names: False }} to "
89  "disable this check.",
90  filename);
91  throw MaCh3Exception(__FILE__, __LINE__);
92  }
93  std::string *param_name = nullptr;
94  nametree->SetBranchAddress("name", &param_name);
95 
96  if (nametree->GetEntries() != int(YAMLDocTemp["Systematics"].size())) {
97  MACH3LOG_CRITICAL("TTree param_names in file: {} has {} entries, but "
98  "the corresponding yaml file only declares {} "
99  "parameters. Set ThrowMatrixOverride: {{ "
100  "check_names: False }} to disable this check.",
101  filename, nametree->GetEntries(),
102  YAMLDocTemp["Systematics"].size());
103  throw MaCh3Exception(__FILE__, __LINE__);
104  }
105 
106  int pit = 0;
107  for (const auto &param : YAMLDocTemp["Systematics"]) {
108  nametree->GetEntry(pit++);
109  auto yaml_pname = Get<std::string>(
110  param["Systematic"]["Names"]["FancyName"], __FILE__, __LINE__);
111  if ((*param_name) != yaml_pname) {
113  "TTree param_names in file: {} at entry {} has parameter {}, "
114  "but "
115  "the corresponding yaml parameter is named {}. Set "
116  "ThrowMatrixOverride: {{ "
117  "check_names: False }} to disable this check.",
118  filename, pit, (*param_name), yaml_pname);
119  throw MaCh3Exception(__FILE__, __LINE__);
120  }
121  }
122  }
123  submatrix_file->Close();
124  }
125 
126  for (const auto& item : YAMLDocTemp["Systematics"]) {
127  _fYAMLDoc["Systematics"].push_back(item);
128  running_num_file_pars++;
129  }
130  }
131 }
132 
133 // ********************************************
134 void ParameterHandlerGeneric::LoadCorrelationFromConfig(std::vector<std::map<std::string,double>>& Correlations,
135  std::map<std::string, int>& CorrNamesMap) {
136 // ********************************************
137  // ETA Now that we've been through all systematic let's fill the covmatrix
138  //This makes the root TCov from YAML
139  TMatrixDSym* _fCovMatrix = new TMatrixDSym(_fNumPar);
140  for(int j = 0; j < _fNumPar; j++) {
141  (*_fCovMatrix)(j, j) = _fError[j]*_fError[j];
142  //Get the map of parameter name to correlation from the Correlations object
143  for (auto const& pair : Correlations[j]) {
144  auto const& key = pair.first;
145  auto const& val = pair.second;
146  int index = -1;
147  //If you found the parameter name then get the index
148  if (CorrNamesMap.find(key) != CorrNamesMap.end()) {
149  index = CorrNamesMap[key];
150  } else {
151  MACH3LOG_ERROR("Parameter {} not in list! Check your spelling?", key);
152  throw MaCh3Exception(__FILE__ , __LINE__ );
153  }
154  double Corr1 = val;
155  double Corr2 = 0;
156  if(Correlations[index].find(_fFancyNames[j]) != Correlations[index].end()) {
157  Corr2 = Correlations[index][_fFancyNames[j]];
158  //Do they agree to better than float precision?
159  constexpr double tolerance = 1e-6;
160  if(std::abs(Corr2 - Corr1) > tolerance) {
161  MACH3LOG_ERROR("Correlations are not equal between {} and {}", _fFancyNames[j], key);
162  MACH3LOG_ERROR("Got : {} and {}", Corr2, Corr1);
163  throw MaCh3Exception(__FILE__ , __LINE__ );
164  }
165  } else {
166  MACH3LOG_ERROR("Correlation does not appear reciprocally between {} and {}", _fFancyNames[j], key);
167  throw MaCh3Exception(__FILE__ , __LINE__ );
168  }
169  (*_fCovMatrix)(j, index)= (*_fCovMatrix)(index, j) = Corr1*_fError[j]*_fError[index];
170  }
171  }
172 
173  //Now make positive definite
174  MakePosDef(_fCovMatrix);
175  SetCovMatrix(_fCovMatrix);
176 }
177 
178 // ********************************************
179 // ETA An init function for the YAML constructor
180 // All you really need from the YAML file is the number of Systematics
181 void ParameterHandlerGeneric::InitialiseFromConfig(const std::vector<std::string>& YAMLFile) {
182 // ********************************************
183  std::map<std::pair<int, int>, std::unique_ptr<TMatrixDSym>> ThrowSubMatrixOverrides;
184  LoadAndMergeYAML(YAMLFile, ThrowSubMatrixOverrides);
185 
186  // Set the covariance matrix
187  _fNumPar = int(_fYAMLDoc["Systematics"].size());
188 
190 
191  int i = 0;
192  std::vector<std::map<std::string,double>> Correlations(_fNumPar);
193  std::map<std::string, int> CorrNamesMap;
194 
195  //ETA - read in the systematics. Would be good to add in some checks to make sure
196  //that there are the correct number of entries i.e. are the _fNumPar for Names,
197  //PreFitValues etc etc.
198  for (auto const &param : _fYAMLDoc["Systematics"])
199  {
200  _fFancyNames[i] = Get<std::string>(param["Systematic"]["Names"]["FancyName"], __FILE__ , __LINE__);
201  _fPreFitValue[i] = Get<double>(param["Systematic"]["ParameterValues"]["PreFitValue"], __FILE__ , __LINE__);
202  _fIndivStepScale[i] = Get<double>(param["Systematic"]["StepScale"], __FILE__ , __LINE__);
203  _fError[i] = Get<double>(param["Systematic"]["Error"], __FILE__ , __LINE__);
204  if(_fError[i] <= 0) {
205  MACH3LOG_ERROR("Error for param {}({}) is negative and equal to {}", _fFancyNames[i], i, _fError[i]);
206  throw MaCh3Exception(__FILE__ , __LINE__ );
207  }
208  //ETA - a bit of a fudge but works
209  auto TempBoundsVec = GetBounds(param["Systematic"]["ParameterBounds"]);
210  _fLowBound[i] = TempBoundsVec[0];
211  _fUpBound[i] = TempBoundsVec[1];
212 
213  //ETA - now for parameters which are optional and have default values
214  _fFlatPrior[i] = GetFromManager<bool>(param["Systematic"]["FlatPrior"], false, __FILE__ , __LINE__);
215 
216  // Allow to fix param, this setting should be used only for params which are permanently fixed like baseline, please use global config for fixing param more flexibly
217  if(GetFromManager<bool>(param["Systematic"]["FixParam"], false, __FILE__ , __LINE__)) {
219  }
220 
221  if(param["Systematic"]["SpecialProposal"]) {
222  EnableSpecialProposal(param["Systematic"]["SpecialProposal"], i);
223  }
224 
225  //Fill the map to get the correlations later as well
226  CorrNamesMap[param["Systematic"]["Names"]["FancyName"].as<std::string>()]=i;
227 
228  //Also loop through the correlations
229  if(param["Systematic"]["Correlations"]) {
230  for(unsigned int Corr_i = 0; Corr_i < param["Systematic"]["Correlations"].size(); ++Corr_i){
231  for (YAML::const_iterator it = param["Systematic"]["Correlations"][Corr_i].begin(); it!=param["Systematic"]["Correlations"][Corr_i].end();++it) {
232  Correlations[i][it->first.as<std::string>()] = it->second.as<double>();
233  }
234  }
235  }
236  i++;
237  } // end loop over para
238  if(i != _fNumPar) {
239  MACH3LOG_CRITICAL("Inconsistent number of params in Yaml {} vs {}, this indicate wrong syntax", i, i, _fNumPar);
240  throw MaCh3Exception(__FILE__ , __LINE__ );
241  }
242 
244 
245  // load correlation
246  LoadCorrelationFromConfig(Correlations, CorrNamesMap);
247  if (_fNumPar <= 0) {
248  MACH3LOG_ERROR("ParameterHandler object has {} systematics!", _fNumPar);
249  throw MaCh3Exception(__FILE__ , __LINE__ );
250  }
251 
252  for(auto const & matovr : ThrowSubMatrixOverrides){
253  SetSubThrowMatrix(matovr.first.first, matovr.first.second, *matovr.second);
254  }
255 
256  Tunes = std::make_unique<ParameterTunes>(_fYAMLDoc["Systematics"]);
257 
258  MACH3LOG_INFO("Created covariance matrix from files: ");
259  for(const auto &file : YAMLFile){
260  MACH3LOG_INFO("{} ", file);
261  }
262  MACH3LOG_INFO("----------------");
263  MACH3LOG_INFO("Found {} systematics parameters in total", _fNumPar);
264  MACH3LOG_INFO("----------------");
265 }
266 
267 // ********************************************
269 // ********************************************
271 
272  _fParamType = std::vector<SystType>(_fNumPar);
273  _ParameterGroup = std::vector<std::string>(_fNumPar);
274  _fSampleNames = std::vector<std::vector<std::string>>(_fNumPar);
275 
276  //KS: We know at most how params we expect so reserve memory for max possible params. Later we will shrink to size to not waste memory. Reserving means slightly faster loading and possible less memory fragmentation.
277  NormParams.reserve(_fNumPar);
278  SplineParams.reserve(_fNumPar);
279  FuncParams.reserve(_fNumPar);
280  OscParams.reserve(_fNumPar);
281 
282  int i = 0;
283  unsigned int ParamCounter[SystType::kSystTypes] = {0};
284  //ETA - read in the systematics. Would be good to add in some checks to make sure
285  //that there are the correct number of entries i.e. are the _fNumPars for Names,
286  //PreFitValues etc etc.
287  for (auto const &param : _fYAMLDoc["Systematics"])
288  {
289  _ParameterGroup[i] = Get<std::string>(param["Systematic"]["ParameterGroup"], __FILE__ , __LINE__);
290  _fSampleNames[i] = GetFromManager<std::vector<std::string>>(param["Systematic"]["SampleNames"], {}, __FILE__, __LINE__);
291 
292  //Fill the map to get the correlations later as well
293  auto ParamType = Get<std::string>(param["Systematic"]["Type"], __FILE__ , __LINE__);
294  //Now load in variables for spline systematics only
295  if (ParamType == SystType_ToString(SystType::kSpline))
296  {
297  //Set param type
299  // Fill Spline info
300  SplineParams.push_back(GetSplineParameter(param["Systematic"], i));
301 
302  //Insert the mapping from the spline index i.e. the length of _fSplineNames etc
303  //to the Systematic index i.e. the counter for things like _fSampleID
304  _fSystToGlobalSystIndexMap[SystType::kSpline].insert(std::make_pair(ParamCounter[SystType::kSpline], i));
305  ParamCounter[SystType::kSpline]++;
306  } else if(ParamType == SystType_ToString(SystType::kNorm)) {
308  NormParams.push_back(GetNormParameter(param["Systematic"], i));
309  _fSystToGlobalSystIndexMap[SystType::kNorm].insert(std::make_pair(ParamCounter[SystType::kNorm], i));
310  ParamCounter[SystType::kNorm]++;
311  } else if(ParamType == SystType_ToString(SystType::kFunc)){
313  FuncParams.push_back(GetFunctionalParameters(param["Systematic"], i));
314  _fSystToGlobalSystIndexMap[SystType::kFunc].insert(std::make_pair(ParamCounter[SystType::kFunc], i));
315  ParamCounter[SystType::kFunc]++;
316  } else if(ParamType == SystType_ToString(SystType::kOsc)){
318  OscParams.push_back(GetOscillationParameters(param["Systematic"], i));
319  _fSystToGlobalSystIndexMap[SystType::kOsc].insert(std::make_pair(ParamCounter[SystType::kOsc], i));
320  ParamCounter[SystType::kOsc]++;
321  } else{
322  MACH3LOG_ERROR("Given unrecognised systematic type: {}", ParamType);
323  std::string expectedTypes = "Expecting ";
324  for (int s = 0; s < SystType::kSystTypes; ++s) {
325  if (s > 0) expectedTypes += ", ";
326  expectedTypes += SystType_ToString(static_cast<SystType>(s)) + "\"";
327  }
328  expectedTypes += ".";
329  MACH3LOG_ERROR(expectedTypes);
330  throw MaCh3Exception(__FILE__, __LINE__);
331  }
332  i++;
333  } //end loop over params
334 
335  //KS We resized them above to all params to fight memory fragmentation, now let's resize to fit only allocated memory to save RAM
336  NormParams.shrink_to_fit();
337  SplineParams.shrink_to_fit();
338  FuncParams.shrink_to_fit();
339  OscParams.shrink_to_fit();
340 }
341 
342 // ********************************************
344 // ********************************************
345  MACH3LOG_DEBUG("Deleting ParameterHandler");
346 }
347 
348 // ********************************************
349 // DB Grab the Spline Names for the relevant SampleName
350 const std::vector<std::string> ParameterHandlerGeneric::GetSplineParsNamesFromSampleName(const std::string& SampleName) const {
351 // ********************************************
352  std::vector<std::string> returnVec;
353  for (auto &pair : _fSystToGlobalSystIndexMap[SystType::kSpline]) {
354  auto &SplineIndex = pair.first;
355  auto &SystIndex = pair.second;
356  if (AppliesToSample(SystIndex, SampleName)) { //If parameter applies to required Sample
357  returnVec.push_back(SplineParams[SplineIndex]._fSplineNames);
358  }
359  }
360  return returnVec;
361 }
362 
363 // ********************************************
364 const std::vector<SplineInterpolation> ParameterHandlerGeneric::GetSplineInterpolationFromSampleName(const std::string& SampleName) const {
365 // ********************************************
366  std::vector<SplineInterpolation> returnVec;
367  for (auto &pair : _fSystToGlobalSystIndexMap[SystType::kSpline]) {
368  auto &SplineIndex = pair.first;
369  auto &SystIndex = pair.second;
370 
371  if (AppliesToSample(SystIndex, SampleName)) { //If parameter applies to required SampleID
372  returnVec.push_back(SplineParams.at(SplineIndex)._SplineInterpolationType);
373  }
374  }
375  return returnVec;
376 }
377 
378 // ********************************************
379 // DB Grab the Spline Modes for the relevant SampleName
380 const std::vector< std::vector<int> > ParameterHandlerGeneric::GetSplineModeVecFromSampleName(const std::string& SampleName) const {
381 // ********************************************
382  std::vector< std::vector<int> > returnVec;
383  //Need a counter or something to correctly get the index in _fSplineModes since it's not of length nPars
384  //Should probably just make a std::map<std::string, int> for param name to FD spline index
385  for (auto &pair : _fSystToGlobalSystIndexMap[SystType::kSpline]) {
386  auto &SplineIndex = pair.first;
387  auto &SystIndex = pair.second;
388  if (AppliesToSample(SystIndex, SampleName)) { //If parameter applies to required SampleID
389  returnVec.push_back(SplineParams.at(SplineIndex)._fSplineModes);
390  }
391  }
392  return returnVec;
393 }
394 
395 // ********************************************
396 // Get Norm params
397 NormParameter ParameterHandlerGeneric::GetNormParameter(const YAML::Node& param, const int Index) const {
398 // ********************************************
399  NormParameter norm;
400 
401  GetBaseParameter(param, Index, norm);
402 
403  // ETA size 0 to mean apply to all
404  // Ultimately all this information ends up in the NormParams vector
405  norm.modes = GetFromManager<std::vector<int>>(param["Mode"], {}, __FILE__ , __LINE__);
406  norm.pdgs = GetFromManager<std::vector<int>>(param["NeutrinoFlavour"], {}, __FILE__ , __LINE__);
407  norm.preoscpdgs = GetFromManager<std::vector<int>>(param["NeutrinoFlavourUnosc"], {}, __FILE__ , __LINE__);
408  norm.targets = GetFromManager<std::vector<int>>(param["TargetNuclei"], {}, __FILE__ , __LINE__);
409 
410  if(_fLowBound[Index] < 0.) {
411  MACH3LOG_ERROR("Normalisation Parameter {} ({}), has lower parameters bound which can go below 0 and is equal {}",
412  GetParFancyName(Index), Index, _fLowBound[Index]);
413  MACH3LOG_ERROR("Normalisation parameters can't go bellow 0 as this is unphysical");
414  throw MaCh3Exception(__FILE__, __LINE__);
415  }
416 
417  return norm;
418 }
419 
420 // ********************************************
421 // Get Base Param
422 void ParameterHandlerGeneric::GetBaseParameter(const YAML::Node& param, const int Index, TypeParameterBase& Parameter) const {
423 // ********************************************
424  Parameter.name = GetParFancyName(Index);
425 
426  // Set the global parameter index of the normalisation parameter
427  Parameter.index = Index;
428 
429  int NumKinematicCuts = 0;
430  if(param["KinematicCuts"]) {
431  NumKinematicCuts = int(param["KinematicCuts"].size());
432 
433  std::vector<std::string> TempKinematicStrings;
434  std::vector<std::vector<std::vector<double>>> TempKinematicBounds;
435  //First element of TempKinematicBounds is always -999, and size is then 3
436  for(int KinVar_i = 0 ; KinVar_i < NumKinematicCuts ; ++KinVar_i) {
437  //ETA: This is a bit messy, Kinematic cuts is a list of maps
438  for (YAML::const_iterator it = param["KinematicCuts"][KinVar_i].begin();it!=param["KinematicCuts"][KinVar_i].end();++it) {
439  TempKinematicStrings.push_back(it->first.as<std::string>());
440  TempKinematicBounds.push_back(Get2DBounds(it->second));
441  }
442  if(TempKinematicStrings.size() == 0) {
443  MACH3LOG_ERROR("Received a KinematicCuts node but couldn't read the contents (it's a list of single-element dictionaries (python) = map of pairs (C++))");
444  MACH3LOG_ERROR("For Param {}", Parameter.name);
445  throw MaCh3Exception(__FILE__, __LINE__);
446  }
447  }//KinVar_i
448  Parameter.KinematicVarStr = TempKinematicStrings;
449  Parameter.Selection = TempKinematicBounds;
450  }
451 
452  //Next ones are kinematic bounds on where normalisation parameter should apply
453  //We set a bool to see if any bounds exist so we can short-circuit checking all of them every step
454  bool HasKinBounds = false;
455 
456  if(Parameter.KinematicVarStr.size() > 0) HasKinBounds = true;
457 
458  Parameter.hasKinBounds = HasKinBounds;
459  //End of kinematic bound checking
460 }
461 
462 // ********************************************
463 // Grab the global syst index for the relevant SampleName
464 // i.e. get a vector of size nSplines where each entry is filled with the global syst number
465 const std::vector<int> ParameterHandlerGeneric::GetGlobalSystIndexFromSampleName(const std::string& SampleName, const SystType Type) const {
466 // ********************************************
467  std::vector<int> returnVec;
468  for (auto &pair : _fSystToGlobalSystIndexMap[Type]) {
469  auto &SystIndex = pair.second;
470  if (AppliesToSample(SystIndex, SampleName)) { //If parameter applies to required SampleID
471  returnVec.push_back(SystIndex);
472  }
473  }
474  return returnVec;
475 }
476 
477 // ********************************************
478 // Grab the global syst index for the relevant SampleName
479 // i.e. get a vector of size nSplines where each entry is filled with the global syst number
480 const std::vector<int> ParameterHandlerGeneric::GetSystIndexFromSampleName(const std::string& SampleName, const SystType Type) const {
481 // ********************************************
482  std::vector<int> returnVec;
483  for (auto &pair : _fSystToGlobalSystIndexMap[Type]) {
484  auto &SplineIndex = pair.first;
485  auto &systIndex = pair.second;
486  if (AppliesToSample(systIndex, SampleName)) { //If parameter applies to required SampleID
487  returnVec.push_back(SplineIndex);
488  }
489  }
490  return returnVec;
491 }
492 
493 // ********************************************
494 // Get Spline params
495 SplineParameter ParameterHandlerGeneric::GetSplineParameter(const YAML::Node& param, const int Index) const {
496 // ********************************************
497  SplineParameter Spline;
498 
499  GetBaseParameter(param, Index, Spline);
500  auto& SplinePar = param["SplineInformation"];
501  //Now get the Spline interpolation type
502  if (SplinePar["InterpolationType"]) {
503  for(int InterpType = 0; InterpType < kSplineInterpolations ; ++InterpType){
504  if(SplinePar["InterpolationType"].as<std::string>() == SplineInterpolation_ToString(SplineInterpolation(InterpType)))
505  Spline._SplineInterpolationType = SplineInterpolation(InterpType);
506  }
507  } else { //KS: By default use TSpline3
509  }
510 
511  Spline._fSplineNames = Get<std::string>(SplinePar["SplineName"], __FILE__ , __LINE__);
512  Spline._SplineKnotUpBound = GetFromManager<double>(SplinePar["SplineKnotUpBound"], M3::DefSplineKnotUpBound, __FILE__ , __LINE__);
513  Spline._SplineKnotLowBound = GetFromManager<double>(SplinePar["SplineKnotLowBound"], M3::DefSplineKnotLowBound, __FILE__ , __LINE__);
514 
516  MACH3LOG_WARN("Spline knot capping enabled with bounds [{}, {}]. For reliable fits, consider modifying the input generation instead.",
517  Spline._SplineKnotLowBound, Spline._SplineKnotUpBound);
518  }
519  //If there is no mode information given then this will be an empty vector
520  Spline._fSplineModes = GetFromManager(SplinePar["Mode"], std::vector<int>(), __FILE__ , __LINE__);
521 
522  return Spline;
523 }
524 
525 // ********************************************
526 bool ParameterHandlerGeneric::AppliesToSample(const int SystIndex, const std::string& SampleName) const {
527 // ********************************************
528  // Empty means apply to all
529  if (_fSampleNames[SystIndex].size() == 0) return true;
530 
531  // Check for unsupported wildcards in SampleName
532  if (SampleName.find('*') != std::string::npos) {
533  MACH3LOG_ERROR("Wildcards ('*') are not supported in sample name: '{}'", SampleName);
534  throw MaCh3Exception(__FILE__ , __LINE__ );
535  }
536  return M3::CaseInsensitiveMatchAny(SampleName, _fSampleNames[SystIndex]);
537 }
538 
539 // ********************************************
540 // Get Func params
541 FunctionalParameter ParameterHandlerGeneric::GetFunctionalParameters(const YAML::Node& param, const int Index) const {
542 // ********************************************
543  FunctionalParameter func;
544  GetBaseParameter(param, Index, func);
545 
546  func.modes = GetFromManager<std::vector<int>>(param["Mode"], std::vector<int>(), __FILE__ , __LINE__);
547 
548  return func;
549 }
550 
551 // ********************************************
552 // Get Osc params
553 OscillationParameter ParameterHandlerGeneric::GetOscillationParameters(const YAML::Node& param, const int Index) const {
554 // ********************************************
555  OscillationParameter OscParamInfo;
556  GetBaseParameter(param, Index, OscParamInfo);
557  OscParamInfo.NuOscName = Get<std::string>(param["NuOscName"], __FILE__ , __LINE__);
558 
559  return OscParamInfo;
560 }
561 
562 // ********************************************
563 // HH: Grab the Functional parameters for the relevant SampleName
564 const std::vector<FunctionalParameter> ParameterHandlerGeneric::GetFunctionalParametersFromSampleName(const std::string& SampleName) const {
565 // ********************************************
567 }
568 
569 // ********************************************
570 // DB Grab the Normalisation parameters for the relevant SampleName
571 const std::vector<NormParameter> ParameterHandlerGeneric::GetNormParsFromSampleName(const std::string& SampleName) const {
572 // ********************************************
574 }
575 
576 // ********************************************
577 // KS Grab the Osc parameters for the relevant SampleName
578 const std::vector<OscillationParameter> ParameterHandlerGeneric::GetOscParsFromSampleName(const std::string& SampleName) const {
579 // ********************************************
581 }
582 
583 // ********************************************
584 // KS Grab the Spline parameters for the relevant SampleName
585 const std::vector<SplineParameter> ParameterHandlerGeneric::GetSplineParsFromSampleName(const std::string& SampleName) const {
586 // ********************************************
588 }
589 
590 // ********************************************
591 template<typename ParamT>
592 std::vector<ParamT> ParameterHandlerGeneric::GetTypeParamsFromSampleName(const std::map<int, int>& indexMap,
593  const std::vector<ParamT>& params, const std::string& SampleName) const {
594 // ********************************************
595  std::vector<ParamT> returnVec;
596  for (const auto& pair : indexMap) {
597  const auto& localIndex = pair.first;
598  const auto& globalIndex = pair.second;
599  if (AppliesToSample(globalIndex, SampleName)) {
600  returnVec.push_back(params[localIndex]);
601  }
602  }
603  return returnVec;
604 }
605 
606 // ********************************************
607 // DB Grab the number of parameters for the relevant SampleName
608 int ParameterHandlerGeneric::GetNumParamsFromSampleName(const std::string& SampleName, const SystType Type) const {
609 // ********************************************
610  int returnVal = 0;
611  IterateOverParams(SampleName,
612  [&](int i) { return GetParamType(i) == Type; }, // Filter condition
613  [&](int) { returnVal += 1; } // Action to perform if filter passes
614  );
615  return returnVal;
616 }
617 
618 // ********************************************
619 // DB Grab the parameter names for the relevant SampleName
620 const std::vector<std::string> ParameterHandlerGeneric::GetParsNamesFromSampleName(const std::string& SampleName, const SystType Type) const {
621 // ********************************************
622  std::vector<std::string> returnVec;
623  IterateOverParams(SampleName,
624  [&](int i) { return GetParamType(i) == Type; }, // Filter condition
625  [&](int i) { returnVec.push_back(GetParFancyName(i)); } // Action to perform if filter passes
626  );
627  return returnVec;
628 }
629 
630 // ********************************************
631 // DB DB Grab the parameter indices for the relevant SampleName
632 const std::vector<int> ParameterHandlerGeneric::GetParsIndexFromSampleName(const std::string& SampleName, const SystType Type) const {
633 // ********************************************
634  std::vector<int> returnVec;
635  IterateOverParams(SampleName,
636  [&](int i) { return GetParamType(i) == Type; }, // Filter condition
637  [&](int i) { returnVec.push_back(i); } // Action to perform if filter passes
638  );
639  return returnVec;
640 }
641 
642 // ********************************************
643 template <typename FilterFunc, typename ActionFunc>
644 void ParameterHandlerGeneric::IterateOverParams(const std::string& SampleName, FilterFunc filter, ActionFunc action) const {
645 // ********************************************
646  for (int i = 0; i < _fNumPar; ++i) {
647  if ((AppliesToSample(i, SampleName)) && filter(i)) { // Common filter logic
648  action(i); // Specific action for each function
649  }
650  }
651 }
652 
653 // ********************************************
655 // ********************************************
656  for (int i = 0; i < _fNumPar; ++i) {
657  //ETA - set the name to be param_% as this is what ProcessorMCMC expects
658  _fNames[i] = "param_"+std::to_string(i);
659 
660  // KS: Plenty of MaCh3 processing script rely on osc params having "fancy name" this is to maintain backward compatibility with them
661  if(_fParamType[i] == kOsc) {
662  _fNames[i] = _fFancyNames[i];
663 
664  if(_ParameterGroup[i] != "Osc"){
665  MACH3LOG_ERROR("Parameter {}, is of type Oscillation but doesn't belong to Osc group", _fFancyNames[i]);
666  MACH3LOG_ERROR("It belongs to {} group", _ParameterGroup[i]);
667  throw MaCh3Exception(__FILE__ , __LINE__ );
668  }
669  }
670  #pragma GCC diagnostic push
671  #pragma GCC diagnostic ignored "-Wuseless-cast"
672  // Set ParameterHandler parameters (Curr = current, Prop = proposed, Sigma = step)
673  _fCurrVal[i] = _fPreFitValue[i];
674  _fPropVal[i] = static_cast<M3::float_t>(_fCurrVal[i]);
675  #pragma GCC diagnostic pop
676  }
677  Randomize();
678  //KS: Transfer the starting parameters to the PCA basis, you don't want to start with zero..
679  if (pca) {
680  PCAObj->SetInitialParameters();
681  }
682 }
683 
684 // ********************************************
685 // Print everything we know about the inputs we're Getting
687 // ********************************************
688  MACH3LOG_INFO("#################################################");
689  MACH3LOG_INFO("Printing ParameterHandlerGeneric:");
690 
692 
693  PrintNormParams();
694 
696 
698 
700 
702 
703  MACH3LOG_INFO("Finished");
704  MACH3LOG_INFO("#################################################");
705 
707 } // End
708 
709 // ********************************************
711 // ********************************************
713  {"Name", 10, 40, M3::Utils::Alignment::Left},
714  {"Prior", 10, 15, M3::Utils::Alignment::Right},
715  {"Error", 10, 15, M3::Utils::Alignment::Right},
716  {"Lower", 10, 15, M3::Utils::Alignment::Right},
717  {"Upper", 10, 15, M3::Utils::Alignment::Right},
718  {"StepScale", 10, 15, M3::Utils::Alignment::Right},
719  {"SampleNames", 10, 20, M3::Utils::Alignment::Left},
720  {"Type", 10, 20, M3::Utils::Alignment::Left},});
721 
722  for (int i = 0; i < GetNumParams(); ++i) {
723  const std::string errorString = fmt::format("{:.2f}", _fError[i]);
724  const std::string sampleNameString = M3::Utils::join(_fSampleNames[i], ", ");
725 
726  table.AddRow(i,
727  GetParFancyName(i),
728  M3::Utils::Cell(_fPreFitValue[i], "{:.2f}"),
729  "+/- " + errorString,
730  M3::Utils::Cell(_fLowBound[i], "{:.2f}"),
731  M3::Utils::Cell(_fUpBound[i], "{:.2f}"),
732  M3::Utils::Cell(_fIndivStepScale[i], "{:.2f}"),
733  sampleNameString,
735  }
736 
737  for (const auto& line : table.Render()) {
738  MACH3LOG_INFO("{}", line);
739  }
740 }
741 
742 // ********************************************
744 // ********************************************
745  // Output the normalisation parameters as a sanity check!
746  MACH3LOG_INFO("Normalisation parameters: {}", NormParams.size());
747  if(_fSystToGlobalSystIndexMap[SystType::kNorm].size() == 0) return;
748 
750  {"Global #", 10, 10, M3::Utils::Alignment::Right},
751  {"Name", 10, 40, M3::Utils::Alignment::Left},
752  {"Int. mode", 10, 20, M3::Utils::Alignment::Left},
753  {"Target", 10, 20, M3::Utils::Alignment::Left},
754  {"pdg", 10, 20, M3::Utils::Alignment::Left},});
755 
756  bool have_parameter_with_kin_bounds = false;
757 
758  for (std::size_t i = 0; i < NormParams.size(); ++i) {
759  table.AddRow(i,
760  NormParams[i].index,
761  NormParams[i].name,
762  NormParams[i].modes.empty() ? "all" : M3::Utils::join(NormParams[i].modes),
763  NormParams[i].targets.empty() ? "all" : M3::Utils::join(NormParams[i].targets),
764  NormParams[i].pdgs.empty() ? "all" : M3::Utils::join(NormParams[i].pdgs));
765 
766  if(NormParams[i].hasKinBounds) have_parameter_with_kin_bounds = true;
767  }
768 
769  for (const auto& line : table.Render()) {
770  MACH3LOG_INFO("{}", line);
771  }
772  if(have_parameter_with_kin_bounds) {
773  MACH3LOG_INFO("Normalisation parameters KinematicCuts information");
774 
776  {"Global #", 10, 10, M3::Utils::Alignment::Right},
777  {"Name", 10, 40, M3::Utils::Alignment::Left},
778  {"KinematicCut", 10, 20, M3::Utils::Alignment::Left},
779  {"Value", 10, 40, M3::Utils::Alignment::Left},});
780 
781  for (std::size_t i = 0; i < NormParams.size(); ++i) {
782  //skip parameters with no KinematicCuts
783  if(!NormParams[i].hasKinBounds) continue;
784 
785  const std::size_t ncuts = NormParams[i].KinematicVarStr.size();
786 
787  for(std::size_t icut = 0; icut < ncuts; ++icut) {
788  std::string kinematicCutValueString;
789 
790  for(const auto& value : NormParams[i].Selection[icut]) {
791  for (const auto& v : value) {
792  kinematicCutValueString += fmt::format("{:.2f} ", v);
793  }
794  }
795 
796  if(icut == 0) {
797  kinTable.AddRow(i,
798  NormParams[i].index,
799  NormParams[i].name,
800  NormParams[i].KinematicVarStr[icut],
801  kinematicCutValueString);
802  }
803  else {
804  kinTable.AddRow("",
805  "",
806  "",
807  NormParams[i].KinematicVarStr[icut],
808  kinematicCutValueString);
809  }
810  }
811  }
812 
813  for (const auto& line : kinTable.Render()) {
814  MACH3LOG_INFO("{}", line);
815  }
816  }
817  else
818  MACH3LOG_INFO("No normalisation parameters have KinematicCuts defined");
819 }
820 
821 // ********************************************
823 // ********************************************
824  MACH3LOG_INFO("Spline parameters: {}", _fSystToGlobalSystIndexMap[SystType::kSpline].size());
825  if(_fSystToGlobalSystIndexMap[SystType::kSpline].size() == 0) return;
826 
828  {"Name", 10, 40, M3::Utils::Alignment::Left},
829  {"Spline Name", 10, 40, M3::Utils::Alignment::Left},
830  {"Spline Interpolation", 10, 20, M3::Utils::Alignment::Left},
831  {"Low Knot Bound", 10, 20, M3::Utils::Alignment::Right},
832  {"Up Knot Bound", 10, 20, M3::Utils::Alignment::Right},});
833 
834  for (const auto& pair : _fSystToGlobalSystIndexMap[SystType::kSpline]) {
835  const auto& SplineIndex = pair.first;
836  const auto& GlobalIndex = pair.second;
837 
838  table.AddRow(SplineIndex,
839  GetParFancyName(GlobalIndex),
840  SplineParams[SplineIndex]._fSplineNames,
844  }
845 
846  for (const auto& line : table.Render()) {
847  MACH3LOG_INFO("{}", line);
848  }
849 }
850 
851 // ********************************************
853 // ********************************************
854  MACH3LOG_INFO("Functional parameters: {}", _fSystToGlobalSystIndexMap[SystType::kFunc].size());
855  if(_fSystToGlobalSystIndexMap[SystType::kFunc].size() == 0) return;
856 
858  {"Global #", 10, 10, M3::Utils::Alignment::Right},
859  {"Name", 10, 40, M3::Utils::Alignment::Left},});
860 
861  for (const auto& pair : _fSystToGlobalSystIndexMap[SystType::kFunc]) {
862  const auto& FuncIndex = pair.first;
863  const auto& GlobalIndex = pair.second;
864 
865  table.AddRow(FuncIndex,
866  GlobalIndex,
867  GetParFancyName(GlobalIndex));
868  }
869 
870  for (const auto& line : table.Render()) {
871  MACH3LOG_INFO("{}", line);
872  }
873 }
874 
875 // ********************************************
877 // ********************************************
878  MACH3LOG_INFO("Oscillation parameters: {}", _fSystToGlobalSystIndexMap[SystType::kOsc].size());
879  if(_fSystToGlobalSystIndexMap[SystType::kOsc].size() == 0) return;
880 
882  {"Global #", 10, 10, M3::Utils::Alignment::Right},
883  {"Name", 10, 40, M3::Utils::Alignment::Left},
884  {"NuOscName", 10, 40, M3::Utils::Alignment::Left},});
885 
886  for (const auto& pair : _fSystToGlobalSystIndexMap[SystType::kOsc]) {
887  const auto& OscIndex = pair.first;
888  const auto& GlobalIndex = pair.second;
889 
890  table.AddRow(OscIndex,
891  GlobalIndex,
892  GetParFancyName(GlobalIndex),
893  OscParams[OscIndex].NuOscName);
894  }
895 
896  for (const auto& line : table.Render()){
897  MACH3LOG_INFO("{}", line);
898  }
899 }
900 
901 // ********************************************
903 // ********************************************
904  // KS: Create a map to store the counts of unique strings, in principle this could be in header file
905  std::unordered_map<std::string, int> paramCounts;
906 
907  std::for_each(_ParameterGroup.begin(), _ParameterGroup.end(),
908  [&paramCounts](const std::string& param) {
909  paramCounts[param]++;
910  });
911 
912  MACH3LOG_INFO("Printing parameter groups");
913  // Output the counts
914  for (const auto& pair : paramCounts) {
915  MACH3LOG_INFO("Found {}: {} params", pair.second, pair.first);
916  }
917 }
918 
919 // ********************************************
920 std::vector<std::string> ParameterHandlerGeneric::GetUniqueParameterGroups() const {
921 // ********************************************
922  std::unordered_set<std::string> uniqueGroups;
923 
924  // Fill the set with unique values
925  for (const auto& param : _ParameterGroup) {
926  uniqueGroups.insert(param);
927  }
928 
929  // Convert to vector and return
930  std::vector<std::string> result(uniqueGroups.begin(), uniqueGroups.end());
931  return result;
932 }
933 
934 // ********************************************
935 // KS: Check if matrix is correctly initialised
937 // ********************************************
938  // KS: Lambda Function which simply checks if there are no duplicates in std::vector
939  auto CheckForDuplicates = [](const std::vector<std::string>& names, const std::string& nameType, bool Warning) {
940  std::unordered_map<std::string, size_t> seenStrings;
941  for (size_t i = 0; i < names.size(); ++i) {
942  const auto& name = names[i];
943  if (seenStrings.find(name) != seenStrings.end()) {
944  size_t firstIndex = seenStrings[name];
945  if(Warning){
946  MACH3LOG_WARN("There are two systematics with the same {} '{}', first at index {}, and again at index {}", nameType, name, firstIndex, i);
947  MACH3LOG_WARN("Is this desired?");
948  return;
949  } else {
950  MACH3LOG_CRITICAL("There are two systematics with the same {} '{}', first at index {}, and again at index {}", nameType, name, firstIndex, i);
951  throw MaCh3Exception(__FILE__, __LINE__);
952  }
953  }
954  seenStrings[name] = i;
955  }
956  };
957  std::vector<std::string> SplineNameTemp(SplineParams.size());
958  for(size_t it = 0; it < SplineParams.size(); it++){
959  SplineNameTemp[it] = SplineParams[it]._fSplineNames;
960  }
961  // KS: Checks if there are no duplicates in fancy names etc, this can happen if we merge configs etc
962  CheckForDuplicates(_fFancyNames, "_fFancyNames", false);
963  CheckForDuplicates(SplineNameTemp, "_fSplineNames", true);
964 }
965 
966 // ********************************************
967 // Function to set to prior parameters of a given group
968 void ParameterHandlerGeneric::SetGroupOnlyParameters(const std::vector< std::string>& Groups) {
969 // ********************************************
970  for(size_t i = 0; i < Groups.size(); i++){
971  SetGroupOnlyParameters(Groups[i]);
972  }
973 }
974 
975 // ********************************************
976 // Function to set to prior parameters of a given group
977 void ParameterHandlerGeneric::SetGroupOnlyParameters(const std::string& Group, const std::vector<double>& Pars) {
978 // ********************************************
979  #pragma GCC diagnostic push
980  #pragma GCC diagnostic ignored "-Wuseless-cast"
981  // If empty, set the proposed to prior
982  if (Pars.empty()) {
983  for (int i = 0; i < _fNumPar; i++) {
984  if(IsParFromGroup(i, Group)) _fPropVal[i] = static_cast<M3::float_t>(_fPreFitValue[i]);
985  }
986  } else{
987  const size_t ExpectedSize = static_cast<size_t>(GetNumParFromGroup(Group));
988  if (Pars.size() != ExpectedSize) {
989  MACH3LOG_ERROR("Number of param in group {} is {}, while you passed {}", Group, ExpectedSize, Pars.size());
990  throw MaCh3Exception(__FILE__, __LINE__);
991  }
992  int Counter = 0;
993  for (int i = 0; i < _fNumPar; i++) {
994  // If belongs to group set value from parsed vector, otherwise use propose value
995  if(IsParFromGroup(i, Group)){
996  _fPropVal[i] = static_cast<M3::float_t>(Pars[Counter]);
997  Counter++;
998  }
999  }
1000  }
1001  // And if pca make the transfer
1002  if (pca) {
1003  PCAObj->TransferToPCA();
1004  PCAObj->TransferToParam();
1005  }
1006  #pragma GCC diagnostic pop
1007 }
1008 
1009 // ********************************************
1010 // Set parameters to be fixed in a given group
1012 // ********************************************
1013  for (int i = 0; i < _fNumPar; ++i)
1014  if(IsParFromGroup(i, Group)) SetFixParameter(i);
1015 }
1016 
1017 // ********************************************
1018 // Set parameters of several groups to be fixed
1019 void ParameterHandlerGeneric::SetFixGroupOnlyParameters(const std::vector< std::string>& Groups) {
1020 // ********************************************
1021  for(size_t i = 0; i < Groups.size(); i++)
1022  SetFixGroupOnlyParameters(Groups[i]);
1023 }
1024 
1025 // ********************************************
1026 // Set parameters to be free in a given group
1028 // ********************************************
1029  for (int i = 0; i < _fNumPar; ++i)
1030  if(IsParFromGroup(i, Group)) SetFreeParameter(i);
1031 }
1032 
1033 // ********************************************
1034 // Set parameters of several groups to be fixed
1035 void ParameterHandlerGeneric::SetFreeGroupOnlyParameters(const std::vector< std::string>& Groups) {
1036 // ********************************************
1037  for(size_t i = 0; i < Groups.size(); i++)
1038  SetFreeGroupOnlyParameters(Groups[i]);
1039 }
1040 
1041 // ********************************************
1042 // Checks if parameter belongs to a given group
1043 bool ParameterHandlerGeneric::IsParFromGroup(const int i, const std::string& Group) const {
1044 // ********************************************
1045  std::string groupLower = Group;
1046  std::string paramGroupLower = _ParameterGroup[i];
1047 
1048  // KS: Convert both strings to lowercase, this way comparison will be case insensitive
1049  std::transform(groupLower.begin(), groupLower.end(), groupLower.begin(), ::tolower);
1050  std::transform(paramGroupLower.begin(), paramGroupLower.end(), paramGroupLower.begin(), ::tolower);
1051 
1052  return groupLower == paramGroupLower;
1053 }
1054 
1055 // ********************************************
1056 int ParameterHandlerGeneric::GetNumParFromGroup(const std::string& Group) const {
1057 // ********************************************
1058  int Counter = 0;
1059  for (int i = 0; i < _fNumPar; i++) {
1060  if(IsParFromGroup(i, Group)) Counter++;
1061  }
1062  return Counter;
1063 }
1064 
1065 // ********************************************
1066 // Dump Matrix to ROOT file, useful when we need to pass matrix info to another fitting group
1067 void ParameterHandlerGeneric::DumpMatrixToFile(const std::string& Name) {
1068 // ********************************************
1069  // KS: Ideally we remove it eventually...
1070  TH2D* CorrMatrix = GetCorrelationMatrix();
1072  _fPreFitValue,
1073  _fError,
1074  _fLowBound,
1075  _fUpBound,
1077  _fFancyNames,
1078  _fFlatPrior,
1079  SplineParams,
1080  covMatrix,
1081  CorrMatrix,
1082  Name);
1083  delete CorrMatrix;
1084  MACH3LOG_INFO("Finished dumping ParameterHandler object");
1085 }
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:38
#define MACH3LOG_DEBUG
Definition: MaCh3Logger.h:34
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36
std::string SplineInterpolation_ToString(const SplineInterpolation i)
Convert a LLH type to a string.
SplineInterpolation
Make an enum of the spline interpolation type.
@ kTSpline3
Default TSpline3 interpolation .
@ kSplineInterpolations
This only enumerates.
std::string SystType_ToString(const SystType i)
Convert a Syst type type to a string.
SystType
@ kNorm
For normalisation parameters.
@ kSpline
For splined parameters (1D)
@ kSystTypes
This only enumerates.
@ kOsc
For oscillation parameters.
@ kFunc
For functional parameters.
#define Get2DBounds(filename)
Definition: YamlHelper.h:591
Type GetFromManager(const YAML::Node &node, const Type defval, const std::string &File, const int Line)
Get content of config file if node is not found take default value specified.
Definition: YamlHelper.h:328
#define M3OpenConfig(filename)
Macro to simplify calling LoadYaml with file and line info.
Definition: YamlHelper.h:589
#define GetBounds(filename)
Definition: YamlHelper.h:590
Creates fancy formatted text tables for terminal output.
Definition: TablePrinter.h:50
void AddRow(Args &&... args)
Add a row to the table.
Definition: TablePrinter.h:57
Custom exception class used throughout MaCh3.
int GetNumParams() const
Get total number of parameters.
bool use_adaptive
Are we using AMCMC?
std::string inputFile
The input root file we read in.
TH2D * GetCorrelationMatrix() const
KS: Convert covariance matrix to correlation matrix and return TH2D which can be used for fancy plott...
void SetCovMatrix(TMatrixDSym *cov)
Set covariance matrix.
void ResolveFunctionalFlips()
Resolve queued functional flips after parameter names are known.
std::vector< M3::float_t > _fPropVal
Proposed value of the parameter.
std::unique_ptr< ParameterTunes > Tunes
Struct containing information about adaption.
void ReserveMemory(const int size)
Initialise vectors with parameters information.
std::vector< std::string > _fFancyNames
Fancy name for example rather than param_0 it is MAQE, useful for human reading.
bool doSpecialStepProposal
Check if any of special step proposal were enabled.
std::vector< bool > _fFlatPrior
Whether to apply flat prior or not.
std::string matrixName
Name of cov matrix.
std::string GetParFancyName(const int i) const
Get fancy name of the Parameter.
std::vector< double > _fError
Prior error on the parameter.
void SetFixParameter(const int i)
Set parameter to be fixed at prior value.
YAML::Node _fYAMLDoc
Stores config describing systematics.
std::unique_ptr< PCAHandler > PCAObj
Struct containing information about PCA.
int _fNumPar
Number of systematic parameters.
void ConstructPCA(const double eigen_threshold, int FirstPCAdpar, int LastPCAdpar)
CW: Calculate eigen values, prepare transition matrices and remove param based on defined threshold.
std::vector< double > _fLowBound
Lowest physical bound, parameter will not be able to go beyond it.
std::vector< double > _fCurrVal
Current value of the parameter.
TMatrixDSym * covMatrix
The covariance matrix.
std::vector< double > _fPreFitValue
Parameter value dictated by the prior model. Based on it penalty term is calculated.
void Randomize() _noexcept_
"Randomize" the parameters in the covariance class for the proposed step. Used the proposal kernel an...
std::vector< std::string > _fNames
ETA _fNames is set automatically in the covariance class to be something like param_i,...
void EnableSpecialProposal(const YAML::Node &param, const int Index)
Enable special proposal.
void SetFreeParameter(const int i)
Set parameter to be treated as free.
std::vector< double > _fUpBound
Upper physical bound, parameter will not be able to go beyond it.
void SetSubThrowMatrix(int first_index, int last_index, TMatrixDSym const &subcov)
bool pca
perform PCA or not
std::vector< double > _fIndivStepScale
Individual step scale used by MCMC algorithm.
void MakePosDef(TMatrixDSym *cov=nullptr, bool verbose=true)
Make matrix positive definite by adding small values to diagonal, necessary for inverting matrix.
void PrintGlobablInfo() const
Prints general information about the ParameterHandler object.
void Print() const
Print information about the whole object once it is set.
std::vector< SplineParameter > SplineParams
Vector containing info for normalisation systematics.
FunctionalParameter GetFunctionalParameters(const YAML::Node &param, const int Index) const
Get Func params.
const std::vector< NormParameter > GetNormParsFromSampleName(const std::string &SampleName) const
DB Get norm/func parameters depending on given SampleName.
std::vector< std::string > GetUniqueParameterGroups() const
KS: Get names of all unique parameter groups.
ParameterHandlerGeneric(const std::vector< std::string > &FileNames, std::string name="xsec_cov", double threshold=-1, int FirstPCAdpar=-999, int LastPCAdpar=-999)
Constructor.
void PrintSplineParams() const
Prints spline parameters.
void IterateOverParams(const std::string &SampleName, FilterFunc filter, ActionFunc action) const
Iterates over parameters and applies a filter and action function.
const std::vector< int > GetParsIndexFromSampleName(const std::string &SampleName, const SystType Type) const
DB Grab the parameter indices for the relevant SampleName.
SplineParameter GetSplineParameter(const YAML::Node &param, const int Index) const
Get Spline params.
SystType GetParamType(const int i) const
Returns enum describing our param type.
const std::vector< int > GetSystIndexFromSampleName(const std::string &SampleName, const SystType Type) const
Grab the index of the syst relative to global numbering.
const std::vector< OscillationParameter > GetOscParsFromSampleName(const std::string &SampleName) const
KS Grab the Osc parameters for the relevant SampleName.
void GetBaseParameter(const YAML::Node &param, const int Index, TypeParameterBase &Parameter) const
Fill base parameters.
std::vector< NormParameter > NormParams
Vector containing info for normalisation systematics.
double GetParSplineKnotUpperBound(const int i) const
EM: value at which we cap spline knot weight.
std::vector< std::map< int, int > > _fSystToGlobalSystIndexMap
Map between number of given parameter type with global parameter numbering. For example 2nd norm para...
void LoadCorrelationFromConfig(std::vector< std::map< std::string, double >> &Correlations, std::map< std::string, int > &CorrNamesMap)
Load correlation from yaml config.
void SetGroupOnlyParameters(const std::string &Group, const std::vector< double > &Pars={})
KS Function to set to prior parameters of a given group or values from vector.
std::vector< SystType > _fParamType
Type of parameter like norm, spline etc.
const std::vector< SplineParameter > GetSplineParsFromSampleName(const std::string &SampleName) const
KS: Grab the Spline parameters for the relevant SampleName.
void PrintOscillationParams() const
Prints oscillation parameters.
const std::vector< FunctionalParameter > GetFunctionalParametersFromSampleName(const std::string &SampleName) const
HH Get functional parameters for the relevant SampleName.
void SetFreeGroupOnlyParameters(const std::string &Group)
TN Method to set parameters within a group to be treated as free.
void InitParametersTypeFromConfig()
Parses the YAML configuration to set up cross-section parameters. The YAML file defines the types of ...
std::vector< std::vector< std::string > > _fSampleNames
Tells to which samples object param should be applied.
std::vector< ParamT > GetTypeParamsFromSampleName(const std::map< int, int > &indexMap, const std::vector< ParamT > &params, const std::string &SampleName) const
Retrieve parameters that apply to a given sample name.
std::vector< FunctionalParameter > FuncParams
Vector containing info for functional systematics.
int GetNumParamsFromSampleName(const std::string &SampleName, const SystType Type) const
DB Grab the number of parameters for the relevant SampleName.
void PrintFunctionalParams() const
Prints functional parameters.
const std::vector< std::string > GetParsNamesFromSampleName(const std::string &SampleName, const SystType Type) const
DB Grab the parameter names for the relevant SampleName.
std::vector< OscillationParameter > OscParams
Vector containing info for functional systematics.
void DumpMatrixToFile(const std::string &Name)
Dump Matrix to ROOT file, useful when we need to pass matrix info to another fitting group.
const std::vector< std::string > GetSplineParsNamesFromSampleName(const std::string &SampleName) const
DB Get spline parameters depending on given SampleName.
SplineInterpolation GetParSplineInterpolation(const int i) const
Get interpolation type for a given parameter.
void InitParameters()
Initializes the systematic parameters from the configuration file. This function loads parameters lik...
const std::vector< int > GetGlobalSystIndexFromSampleName(const std::string &SampleName, const SystType Type) const
DB Get spline parameters depending on given SampleName.
OscillationParameter GetOscillationParameters(const YAML::Node &param, const int Index) const
Get Osc params.
NormParameter GetNormParameter(const YAML::Node &param, const int Index) const
Get Norm params.
bool AppliesToSample(const int SystIndex, const std::string &SampleName) const
Check if parameter is affecting given sample name.
const std::vector< SplineInterpolation > GetSplineInterpolationFromSampleName(const std::string &SampleName) const
Get the interpolation types for splines affecting a particular SampleName.
bool IsParFromGroup(const int i, const std::string &Group) const
Checks if parameter belongs to a given group.
void CheckCorrectInitialisation() const
KS: Check if matrix is correctly initialised.
void InitialiseFromConfig(const std::vector< std::string > &YAMLFile)
Initialisation of the class using config.
void SetFixGroupOnlyParameters(const std::string &Group)
TN Method to set parameters within a group to be fixed to their prior values.
std::vector< std::string > _ParameterGroup
KS: Allow to group parameters for example to affect only cross-section or only flux etc.
void LoadAndMergeYAML(const std::vector< std::string > &YAMLFile, std::map< std::pair< int, int >, std::unique_ptr< TMatrixDSym >> &overrides)
Initialise single yaml based on several yaml files.
double GetParSplineKnotLowerBound(const int i) const
EM: value at which we cap spline knot weight.
void PrintNormParams() const
Prints normalization parameters.
int GetNumParFromGroup(const std::string &Group) const
KS: Check how many parameters are associated with given group.
const std::vector< std::vector< int > > GetSplineModeVecFromSampleName(const std::string &SampleName) const
DB Grab the Spline Modes for the relevant SampleName.
void PrintParameterGroups() const
Prints groups of parameters.
static std::string Cell(T &&value, std::string_view format)
Format a value using a runtime fmt format string.
Definition: TablePrinter.h:44
std::string join(const Container &values, std::string_view separator=" ")
Join all values in a container into a single string.
Definition: TablePrinter.h:36
@ Right
Align text to the right.
@ Left
Align text to the left.
constexpr static const double DefSplineKnotUpBound
Default value for spline knot capping, default mean not capping is being applied.
Definition: Core.h:86
double float_t
Definition: Core.h:37
constexpr static const double DefSplineKnotLowBound
Default value for spline knot capping, default mean not capping is being applied.
Definition: Core.h:88
void DumpParamHandlerToFile(const int _fNumPar, const std::vector< double > &_fPreFitValue, const std::vector< double > &_fError, const std::vector< double > &_fLowBound, const std::vector< double > &_fUpBound, const std::vector< double > &_fIndivStepScale, const std::vector< std::string > &_fFancyNames, const std::vector< bool > &_fFlatPrior, const std::vector< SplineParameter > &SplineParams, TMatrixDSym *covMatrix, TH2D *CorrMatrix, const std::string &Name)
Dump Matrix to ROOT file, useful when we need to pass matrix info to another fitting group.
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.
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.
HH - Functional parameters Carrier for whether you want to apply a systematic to an event or not.
std::vector< int > modes
Mode which parameter applies to.
ETA - Normalisations for cross-section parameters Carrier for whether you want to apply a systematic ...
std::vector< int > preoscpdgs
Preosc PDG which parameter applies to.
std::vector< int > modes
Mode which parameter applies to.
std::vector< int > pdgs
PDG which parameter applies to.
std::vector< int > targets
Targets which parameter applies to.
KS: Struct holding info about oscillation Systematics.
std::string NuOscName
Parameter name in NuOscillator.
Flat representation of a spline index entry.
Definition: SplineCommon.h:33
KS: Struct holding info about Spline Systematics.
SplineInterpolation _SplineInterpolationType
Spline interpolation vector.
double _SplineKnotUpBound
EM: Cap spline knot higher value.
double _SplineKnotLowBound
EM: Cap spline knot lower value.
std::vector< int > _fSplineModes
Modes to which spline applies (valid only for binned splines)
std::string _fSplineNames
Name of spline in TTree (TBranch),.
Base class storing info for parameters types, helping unify codebase.
int index
Parameter number of this normalisation in current systematic model.
bool hasKinBounds
Does this parameter have kinematic bounds.
std::string name
Name of parameters.
std::vector< std::string > KinematicVarStr
std::vector< std::vector< std::vector< double > > > Selection