MaCh3  2.8.0
Reference Guide
Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | List of all members
ParameterHandlerBase Class Reference

Base class for handling systematic uncertainty parameters. More...

#include <Parameters/ParameterHandlerBase.h>

Inheritance diagram for ParameterHandlerBase:
[legend]
Collaboration diagram for ParameterHandlerBase:
[legend]

Public Member Functions

 ParameterHandlerBase (std::string name, std::string file, double threshold=-1, int FirstPCAdpar=-999, int LastPCAdpar=-999)
 "Usual" constructors from root file More...
 
 ParameterHandlerBase ()=default
 
virtual ~ParameterHandlerBase ()
 Destructor. More...
 
void SetCovMatrix (TMatrixDSym *cov)
 Set covariance matrix. More...
 
void SetName (const std::string &name)
 Set matrix name. More...
 
void SetParName (const int i, const std::string &name)
 change parameter name More...
 
void SetSingleParameter (const int parNo, const double parVal)
 Set value of single param to a given value. More...
 
void SetPar (const int i, const double val)
 Set all the covariance matrix parameters to a user-defined value. More...
 
void SetParCurrProp (const int i, const double val)
 Set current parameter value. More...
 
void SetParProp (const int i, const double val)
 Set proposed parameter value. More...
 
void SetParameters (const std::vector< double > &pars={})
 Set parameter values using vector, it has to have same size as covariance class. More...
 
void SetFlatPrior (const int i, const bool eL)
 Set if parameter should have flat prior or not. More...
 
void SetRandomThrow (const int i, const double rand)
 Set random value useful for debugging/CI. More...
 
double GetRandomThrow (const int i) const
 Get random value useful for debugging/CI. More...
 
void SetBranches (TTree &tree, const bool SaveProposal=false)
 set branches for output file More...
 
void SetStepScale (const double scale, const bool verbose=true)
 Set global step scale for covariance object. More...
 
void SetIndivStepScale (const int ParameterIndex, const double StepScale)
 DB Function to set fIndivStepScale from a vector (Can be used from execs and inside covariance constructors) More...
 
void SetIndivStepScale (const std::vector< double > &stepscale)
 DB Function to set fIndivStepScale from a vector (Can be used from execs and inside covariance constructors) More...
 
void SaveUpdatedMatrixConfig ()
 KS: After step scale, prefit etc. value were modified save this modified config. More...
 
void ThrowParameters ()
 Throw the parameters according to the covariance matrix. This shouldn't be used in MCMC code ase it can break Detailed Balance;. More...
 
void RandomConfiguration ()
 Randomly throw the parameters in their 1 sigma range. More...
 
int CheckBounds () const _noexcept_
 Check if parameters were proposed outside physical boundary. More...
 
double CalcLikelihood () const _noexcept_
 Calc penalty term based on inverted covariance matrix. More...
 
virtual double GetLikelihood ()
 Return CalcLikelihood if some params were thrown out of boundary return LARGE_LOGL More...
 
TMatrixDSym * GetCovMatrix () const
 Return covariance matrix. More...
 
TMatrixDSym * GetInvCovMatrix () const
 Return inverted covariance matrix. More...
 
double GetInvCovMatrix (const int i, const int j) const
 Return inverted covariance matrix. More...
 
double GetCorrThrows (const int i) const
 Return correlated throws. More...
 
bool GetFlatPrior (const int i) const
 Get if param has flat prior or not. More...
 
std::string GetName () const
 Get name of covariance. More...
 
std::string GetParName (const int i) const
 Get name of parameter. More...
 
int GetParIndex (const std::string &name) const
 Get index based on name. More...
 
std::string GetParFancyName (const int i) const
 Get fancy name of the Parameter. More...
 
double GetDiagonalError (const int i) const
 Get diagonal error for ith parameter. More...
 
double GetError (const int i) const
 Get the error for the ith parameter. More...
 
void ResetIndivStepScale ()
 Adaptive Step Tuning Stuff. More...
 
void SetIndivStepScaleForSkippedAdaptParams ()
 Set individual step scale for parameters which are skipped during adaption to initial values. More...
 
void InitialiseAdaption (const YAML::Node &adapt_manager)
 Initialise adaptive MCMC. More...
 
void SaveAdaptiveToFile (const std::string &outFileName, const std::string &systematicName)
 Save adaptive throw matrix to file. More...
 
bool GetDoAdaption () const
 Do we adapt or not. More...
 
void SetThrowMatrix (const TMatrixDSym *cov)
 Use new throw matrix, used in adaptive MCMC. More...
 
void SetSubThrowMatrix (int first_index, int last_index, TMatrixDSym const &subcov)
 
void UpdateThrowMatrix (TMatrixDSym *cov)
 Replaces old throw matrix with new one. More...
 
void SetNumberOfSteps (const int nsteps)
 Set number of MCMC step, when running adaptive MCMC it is updated with given frequency. We need number of steps to determine frequency. More...
 
TMatrixDSym * GetThrowMatrix () const
 Get matrix used for step proposal. More...
 
double GetThrowMatrix (const int i, const int j) const
 Get matrix used for step proposal. More...
 
TH2D * GetCorrelationMatrix () const
 KS: Convert covariance matrix to correlation matrix and return TH2D which can be used for fancy plotting. More...
 
const M3::float_t * RetPointer (const int iParam) const
 DB Pointer return to param position. More...
 
const std::vector< M3::float_t > & GetParPropVec ()
 Get a reference to the proposed parameter values Can be useful if you want to track these without having to copy values using getProposed() More...
 
int GetNumParams () const
 Get total number of parameters. More...
 
std::vector< double > GetPreFitValues () const
 Get the pre-fit values of the parameters. More...
 
std::vector< double > GetProposed () const
 Get vector of all proposed parameter values. More...
 
M3::float_t GetParProp (const int i) const
 Get proposed parameter value. More...
 
double GetParCurr (const int i) const
 Get current parameter value. More...
 
const std::vector< double > & GetParCurrVec () const
 Get vector of current parameter values. More...
 
double GetParPreFit (const int i) const
 Get prior parameter value. More...
 
double GetUpperBound (const int i) const
 Get upper parameter bound in which it is physically valid. More...
 
double GetLowerBound (const int i) const
 Get lower parameter bound in which it is physically valid. More...
 
double GetIndivStepScale (const int ParameterIndex) const
 Get individual step scale for selected parameter. More...
 
double GetGlobalStepScale () const
 Get global step scale for covariance object. More...
 
int GetNParameters () const
 Get number of params which will be different depending if using Eigen decomposition or not. More...
 
void PrintPreFitValues () const
 Print prior value for every parameter. More...
 
void PrintPreFitCurrPropValues () const
 Print prior, current and proposed value for each parameter. More...
 
void PrintIndivStepScale () const
 Print step scale for each parameter. More...
 
virtual void ProposeStep ()
 Generate a new proposed state. More...
 
void Randomize () _noexcept_
 "Randomize" the parameters in the covariance class for the proposed step. Used the proposal kernel and the current parameter value to set proposed step More...
 
void CorrelateSteps () _noexcept_
 Use Cholesky throw matrix for better step proposal. More...
 
void UpdateAdaptiveCovariance ()
 Method to update adaptive MCMC [17]. More...
 
void AcceptStep () _noexcept_
 Accepted this step. More...
 
void SetFixAllParameters ()
 Set all parameters to be fixed at prior values. More...
 
void SetFixParameter (const int i)
 Set parameter to be fixed at prior value. More...
 
void SetFixParameter (const std::string &name)
 Set parameter to be fixed at prior value. More...
 
void SetFreeAllParameters ()
 Set all parameters to be treated as free. More...
 
void SetFreeParameter (const int i)
 Set parameter to be treated as free. More...
 
void SetFreeParameter (const std::string &name)
 Set parameter to be treated as free. More...
 
bool IsParameterFixed (const int i) const
 Is parameter fixed or not. More...
 
bool IsParameterFixed (const std::string &name) const
 Is parameter fixed or not. More...
 
void ConstructPCA (const double eigen_threshold, int FirstPCAdpar, int LastPCAdpar)
 CW: Calculate eigen values, prepare transition matrices and remove param based on defined threshold. More...
 
bool IsPCA () const
 is PCA, can use to query e.g. LLH scans More...
 
YAML::Node GetConfig () const
 Getter to return a copy of the YAML node. More...
 
AdaptiveMCMCHandler * GetAdaptiveHandler () const
 Get pointer for AdaptiveHandler. More...
 
void SetTune (const std::string &TuneName)
 KS: Set proposed parameter values vector to be base on tune values, for example set proposed values to be of generated or maybe PostND. More...
 
PCAHandler * GetPCAHandler () const
 Get pointer for PCAHandler. More...
 
void MatchMaCh3OutputBranches (TTree *PosteriorFile, std::vector< double > &BranchValues, std::vector< std::string > &BranchNames, const std::vector< std::string > &FancyNames={})
 Matches branches in a TTree to parameters in a systematic handler. More...
 

Protected Member Functions

void InitFromFile (const std::string &name, const std::string &file)
 Initialisation of the class using matrix from root file. More...
 
void ReserveMemory (const int size)
 Initialise vectors with parameters information. More...
 
void MakePosDef (TMatrixDSym *cov=nullptr, bool verbose=true)
 Make matrix positive definite by adding small values to diagonal, necessary for inverting matrix. More...
 
void MakeClosestPosDef (TMatrixDSym *cov)
 HW: Finds closest possible positive definite matrix in Frobenius Norm ||.||_frob Where ||X||_frob=sqrt[sum_ij(x_ij^2)] (basically just turns an n,n matrix into vector in n^2 space then does Euclidean norm) More...
 
void SetThrowMatrixFromFile (const std::string &matrix_file_name, const std::string &matrix_name, const std::string &means_name)
 sets throw matrix from a file More...
 
void SanitizeAdaption () const
 Perform sanity check to ensure adaption isn't misbehaving before fit starts. More...
 
void FlipParameterGroup (const std::string &group)
 With a 50% chance, flip all parameters in a group around their respective flip points. More...
 
M3::float_t EvaluateFunctionalFlip (const FunctionalFlipProposal &flip, const std::vector< double > &proposed_values) const
 Evaluate a formula-driven flip for a target parameter. More...
 
void CircularParBounds (const int i, const double LowBound, const double UpBound)
 HW :: This method is a tad hacky but modular arithmetic gives me a headache. More...
 
void EnableSpecialProposal (const YAML::Node &param, const int Index)
 Enable special proposal. More...
 
void AddFunctionalFlip (const YAML::Node &param, const int index, const std::string &group_name)
 Parse and register a functional flip defined in YAML. More...
 
void QueueFunctionalFlip (const YAML::Node &param, const int index, const std::string &group_name)
 Queue a functional flip until all parameters have been loaded. More...
 
void ResolveFunctionalFlips ()
 Resolve queued functional flips after parameter names are known. More...
 
void SpecialStepProposal ()
 Perform Special Step Proposal. More...
 

Protected Attributes

bool doSpecialStepProposal
 Check if any of special step proposal were enabled. More...
 
std::string inputFile
 The input root file we read in. More...
 
std::string matrixName
 Name of cov matrix. More...
 
TMatrixDSym * covMatrix
 The covariance matrix. More...
 
TMatrixDSym * invCovMatrix
 The inverse covariance matrix. More...
 
std::vector< std::vector< double > > InvertCovMatrix
 KS: Same as above but much faster as TMatrixDSym cache miss. More...
 
double * randParams
 Random number taken from gaussian around prior error used for corr_throw. More...
 
double * corr_throw
 Result of multiplication of Cholesky matrix and randParams. More...
 
double _fGlobalStepScale
 Global step scale applied to all params in this class. More...
 
std::vector< std::string > _fNames
 ETA _fNames is set automatically in the covariance class to be something like param_i, this is currently to make things compatible with the Diagnostic tools. More...
 
std::vector< std::string > _fFancyNames
 Fancy name for example rather than param_0 it is MAQE, useful for human reading. More...
 
YAML::Node _fYAMLDoc
 Stores config describing systematics. More...
 
int _fNumPar
 Number of systematic parameters. More...
 
std::vector< double > _fPreFitValue
 Parameter value dictated by the prior model. Based on it penalty term is calculated. More...
 
std::vector< double > _fCurrVal
 Current value of the parameter. More...
 
std::vector< M3::float_t > _fPropVal
 Proposed value of the parameter. More...
 
std::vector< double > _fError
 Prior error on the parameter. More...
 
std::vector< double > _fLowBound
 Lowest physical bound, parameter will not be able to go beyond it. More...
 
std::vector< double > _fUpBound
 Upper physical bound, parameter will not be able to go beyond it. More...
 
std::vector< double > _fIndivStepScale
 Individual step scale used by MCMC algorithm. More...
 
std::vector< bool > _fFlatPrior
 Whether to apply flat prior or not. More...
 
std::vector< double > _fIndivStepScaleInitial
 Backup of _fIndivStepScale for parameters which are skipped during adaption. More...
 
double _fGlobalStepScaleInitial
 Backup of _fGlobalStepScale for parameters which are skipped during adaption. More...
 
std::vector< bool > param_skip_adapt_flags
 Flags telling if parameter should be skipped during adaption. More...
 
TMatrixDSym * throwMatrix
 Matrix which we use for step proposal before Cholesky decomposition (not actually used for step proposal) More...
 
double ** throwMatrixCholDecomp
 Throw matrix that is being used in the fit, much faster as TMatrixDSym cache miss. More...
 
bool pca
 perform PCA or not More...
 
bool use_adaptive
 Are we using AMCMC? More...
 
std::unique_ptr< PCAHandler > PCAObj
 Struct containing information about PCA. More...
 
std::unique_ptr< AdaptiveMCMCHandler > AdaptiveHandler
 Struct containing information about adaption. More...
 
std::unique_ptr< ParameterTunes > Tunes
 Struct containing information about adaption. More...
 
std::map< std::string, FlipGroup > FlipGroups
 Map of flip groups, where the key is the group name and the value is a FlipGroup struct. More...
 
std::vector< PendingFunctionalFlipProposal > PendingFunctionalFlipParameters
 Functional flips waiting for full parameter-name registration. More...
 
std::vector< int > CircularBoundsIndex
 Indices of parameters with circular bounds. More...
 
std::vector< std::pair< double, double > > CircularBoundsValues
 Circular bounds for each parameter (lower, upper) More...
 

Private Member Functions

void ToggleFixParameter (const int i)
 Toggle fixing parameter at prior values. More...
 
void ToggleFixParameter (const std::string &name)
 Toggle fixing parameter at prior values. More...
 

Detailed Description

Base class for handling systematic uncertainty parameters.

Provides core functionality for managing systematic parameters, including likelihood evaluation and covariance handling.

How parameters are loaded (e.g. from configuration files or ROOT inputs) is left to derived classes.

In the context of MCMC, the class may also be responsible for proposing parameter steps. Proposal strategies may include PCA-based sampling or adaptive proposal matrices.

Author
Dan Barrow
Ed Atkin
Kamil Skwarczynski

Definition at line 27 of file ParameterHandlerBase.h.

Constructor & Destructor Documentation

◆ ParameterHandlerBase() [1/2]

ParameterHandlerBase::ParameterHandlerBase ( std::string  name,
std::string  file,
double  threshold = -1,
int  FirstPCAdpar = -999,
int  LastPCAdpar = -999 
)

"Usual" constructors from root file

Parameters
nameMatrix name
filePath to matrix root file

Definition at line 7 of file ParameterHandlerBase.cpp.

8  : inputFile(file), pca(true) {
9 // ********************************************
10  MACH3LOG_DEBUG("Constructing instance of ParameterHandler");
11  doSpecialStepProposal = false;
12  // Not using adaptive by default
13  use_adaptive = false;
14  if (threshold < 0 || threshold >= 1) {
15  MACH3LOG_INFO("NOTE: {} {}", name, file);
16  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");
17  MACH3LOG_INFO("Please specify a number between 0 and 1");
18  MACH3LOG_INFO("You specified: ");
19  MACH3LOG_INFO("Am instead calling the usual non-PCA constructor...");
20  pca = false;
21  }
22 
23  InitFromFile(name, file);
24 
25  // Call the innocent helper function
26  if (pca) ConstructPCA(threshold, FirstPCA, LastPCA);
27 }
#define MACH3LOG_DEBUG
Definition: MaCh3Logger.h:34
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
bool use_adaptive
Are we using AMCMC?
std::string inputFile
The input root file we read in.
bool doSpecialStepProposal
Check if any of special step proposal were enabled.
void InitFromFile(const std::string &name, const std::string &file)
Initialisation of the class using matrix from root file.
void ConstructPCA(const double eigen_threshold, int FirstPCAdpar, int LastPCAdpar)
CW: Calculate eigen values, prepare transition matrices and remove param based on defined threshold.
bool pca
perform PCA or not

◆ ParameterHandlerBase() [2/2]

ParameterHandlerBase::ParameterHandlerBase ( )
default

◆ ~ParameterHandlerBase()

ParameterHandlerBase::~ParameterHandlerBase ( )
virtual

Destructor.

Definition at line 31 of file ParameterHandlerBase.cpp.

31  {
32 // ********************************************
33  delete[] randParams;
34  delete[] corr_throw;
35 
36  if (covMatrix != nullptr) delete covMatrix;
37  if (invCovMatrix != nullptr) delete invCovMatrix;
38  if (throwMatrix != nullptr) delete throwMatrix;
39  for(int i = 0; i < _fNumPar; i++) {
40  delete[] throwMatrixCholDecomp[i];
41  }
42  delete[] throwMatrixCholDecomp;
43 }
double * randParams
Random number taken from gaussian around prior error used for corr_throw.
double ** throwMatrixCholDecomp
Throw matrix that is being used in the fit, much faster as TMatrixDSym cache miss.
TMatrixDSym * invCovMatrix
The inverse covariance matrix.
TMatrixDSym * throwMatrix
Matrix which we use for step proposal before Cholesky decomposition (not actually used for step propo...
int _fNumPar
Number of systematic parameters.
TMatrixDSym * covMatrix
The covariance matrix.
double * corr_throw
Result of multiplication of Cholesky matrix and randParams.

Member Function Documentation

◆ AcceptStep()

void ParameterHandlerBase::AcceptStep ( )

Accepted this step.

Definition at line 611 of file ParameterHandlerBase.cpp.

611  {
612 // ********************************************
613  if (!pca) {
614  #ifdef MULTITHREAD
615  #pragma omp parallel for
616  #endif
617  for (int i = 0; i < _fNumPar; ++i) {
618  // Update state so that current state is proposed state
619  _fCurrVal[i] = _fPropVal[i];
620  }
621  } else {
622  PCAObj->AcceptStep();
623  }
624 
625  if (AdaptiveHandler) {
626  AdaptiveHandler->IncrementAcceptedSteps();
627  }
628 }
std::unique_ptr< AdaptiveMCMCHandler > AdaptiveHandler
Struct containing information about adaption.
std::vector< M3::float_t > _fPropVal
Proposed value of the parameter.
std::unique_ptr< PCAHandler > PCAObj
Struct containing information about PCA.
std::vector< double > _fCurrVal
Current value of the parameter.

◆ AddFunctionalFlip()

void ParameterHandlerBase::AddFunctionalFlip ( const YAML::Node &  param,
const int  index,
const std::string &  group_name 
)
protected

Parse and register a functional flip defined in YAML.

Definition at line 249 of file ParameterHandlerBase.cpp.

249  {
250 // ********************************************
251  YAML::Node functional_flip = YAML::Clone(param);
252  const YAML::Node formula = functional_flip["Formula"];
253  const YAML::Node parameters = functional_flip["Parameters"];
254 
255  if (!formula) {
256  MACH3LOG_ERROR("FunctionalFlip for parameter {} is missing Formula", GetParFancyName(index));
257  throw MaCh3Exception(__FILE__, __LINE__);
258  }
259  if (!parameters) {
260  MACH3LOG_ERROR("FunctionalFlip for parameter {} is missing Parameters list", GetParFancyName(index));
261  throw MaCh3Exception(__FILE__, __LINE__);
262  }
263 
265  flip.target_index = index;
266  flip.formula = Get<std::string>(formula, __FILE__, __LINE__);
267  flip.argument_names = Get<std::vector<std::string>>(parameters, __FILE__, __LINE__);
268 
269  for (const auto& name : flip.argument_names) {
270  const int argument_index = GetParIndex(name);
271  if (argument_index == M3::_BAD_INT_) {
272  MACH3LOG_ERROR("FunctionalFlip for parameter {} refers to unknown parameter {}",
273  GetParFancyName(index), name);
274  throw MaCh3Exception(__FILE__, __LINE__);
275  }
276  flip.argument_indices.push_back(argument_index);
277  }
278 
279  const std::string flip_name = fmt::format("{}_{}_functional_flip_{}",
280  matrixName,
281  group_name,
282  FlipGroups[group_name].FunctionalFlipParameters.size());
283  flip.evaluator = std::make_unique<TF1>(flip_name.c_str(), flip.formula.c_str(), 0.0, 1.0);
284 
285  if (!flip.evaluator || flip.evaluator->IsZombie()) {
286  MACH3LOG_ERROR("Failed to parse FunctionalFlip formula for parameter {}: {}",
287  GetParFancyName(index), flip.formula);
288  throw MaCh3Exception(__FILE__, __LINE__);
289  }
290 
291  if (flip.evaluator->GetNpar() != static_cast<int>(flip.argument_names.size())) {
292  MACH3LOG_ERROR("FunctionalFlip formula for parameter {} expects {} auxiliary parameters, but {} names were provided",
293  GetParFancyName(index), flip.evaluator->GetNpar(), flip.argument_names.size());
294  MACH3LOG_ERROR("Use x for the target parameter and [0], [1], ... for the listed Parameters entries");
295  throw MaCh3Exception(__FILE__, __LINE__);
296  }
297 
298  MACH3LOG_INFO("Enabling FunctionalFlip for parameter {} with formula '{}'",
299  GetParFancyName(index), flip.formula);
300  FlipGroups[group_name].FunctionalFlipParameters.push_back(std::move(flip));
301 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
Custom exception class used throughout MaCh3.
std::map< std::string, FlipGroup > FlipGroups
Map of flip groups, where the key is the group name and the value is a FlipGroup struct.
int GetParIndex(const std::string &name) const
Get index based on name.
std::string matrixName
Name of cov matrix.
std::string GetParFancyName(const int i) const
Get fancy name of the Parameter.
std::unique_ptr< ObjectType > Clone(const ObjectType *obj, const std::string &name="")
KS: Creates a copy of a ROOT-like object and wraps it in a smart pointer.
constexpr static const int _BAD_INT_
Default value used for int initialisation.
Definition: Core.h:55
Configuration for a formula-based functional flip.
std::vector< int > argument_indices
std::vector< std::string > argument_names
std::unique_ptr< TF1 > evaluator

◆ CalcLikelihood()

double ParameterHandlerBase::CalcLikelihood ( ) const

Calc penalty term based on inverted covariance matrix.

The log-likelihood is computed as:

\[ \log \mathcal{L} = \frac{1}{2} \sum_{i}^{\textrm{pars}} \sum_{j}^{\textrm{pars}} \Delta \vec{p}_i \left( V^{-1} \right)_{i,j} \Delta \vec{p}_j \]

where:

  • \(\Delta \vec{p}_i = \theta_i - \theta_{i,0}\) is the difference between the current and pre-fit parameter values,
  • \(V^{-1}\) is the inverted covariance matrix.
Note
  • If _fFlatPrior[i] is true, the parameter is excluded from the calculation.

Definition at line 744 of file ParameterHandlerBase.cpp.

744  {
745 // ********************************************
746  double logL = 0.0;
747  #ifdef MULTITHREAD
748  #pragma omp parallel for reduction(+:logL)
749  #endif
750  for(int i = 0; i < _fNumPar; ++i) {
751  if(_fFlatPrior[i]){
752  //HW: Flat prior, no need to calculate anything
753  continue;
754  }
755  // KS: Precalculate Diff once per "i" without doing this for every "j"
756  const double Diff = _fPropVal[i] - _fPreFitValue[i];
757  #ifdef MULTITHREAD
758  #pragma omp simd
759  #endif
760  for (int j = 0; j <= i; ++j) {
761  if (!_fFlatPrior[j]) {
762  //KS: Since matrix is symmetric we can calculate non diagonal elements only once and multiply by 2, can bring up to factor speed decrease.
763  double scale = (i != j) ? 1. : 0.5;
764  logL += scale * Diff * (_fPropVal[j] - _fPreFitValue[j])*InvertCovMatrix[i][j];
765  }
766  }
767  }
768  return logL;
769 }
std::vector< bool > _fFlatPrior
Whether to apply flat prior or not.
std::vector< std::vector< double > > InvertCovMatrix
KS: Same as above but much faster as TMatrixDSym cache miss.
std::vector< double > _fPreFitValue
Parameter value dictated by the prior model. Based on it penalty term is calculated.

◆ CheckBounds()

int ParameterHandlerBase::CheckBounds ( ) const

Check if parameters were proposed outside physical boundary.

Definition at line 772 of file ParameterHandlerBase.cpp.

772  {
773 // ********************************************
774  int NOutside = 0;
775  for (int i = 0; i < _fNumPar; ++i) {
776  // KS: Count how many parameters are outside bounds using branchless logic
777  // faster by at least factor two
778  // Do not multithread even with 5k params no gains
779  NOutside += (_fPropVal[i] > _fUpBound[i]) | (_fPropVal[i] < _fLowBound[i]);
780  }
781  return NOutside;
782 }
std::vector< double > _fLowBound
Lowest physical bound, parameter will not be able to go beyond it.
std::vector< double > _fUpBound
Upper physical bound, parameter will not be able to go beyond it.

◆ CircularParBounds()

void ParameterHandlerBase::CircularParBounds ( const int  i,
const double  LowBound,
const double  UpBound 
)
protected

HW :: This method is a tad hacky but modular arithmetic gives me a headache.

Author
Henry Wallace

Definition at line 634 of file ParameterHandlerBase.cpp.

634  {
635 // *************************************
636  if(_fPropVal[index] > UpBound) {
637  _fPropVal[index] = static_cast<M3::float_t>(LowBound + std::fmod(_fPropVal[index] - UpBound, UpBound - LowBound));
638  } else if (_fPropVal[index] < LowBound) {
639  _fPropVal[index] = static_cast<M3::float_t>(UpBound - std::fmod(LowBound - _fPropVal[index], UpBound - LowBound));
640  }
641 }
double float_t
Definition: Core.h:37

◆ ConstructPCA()

void ParameterHandlerBase::ConstructPCA ( const double  eigen_threshold,
int  FirstPCAdpar,
int  LastPCAdpar 
)

CW: Calculate eigen values, prepare transition matrices and remove param based on defined threshold.

Parameters
eigen_thresholdPCA threshold from 0 to 1. Default is -1 and means no PCA
FirstPCAdparFirst PCA parameter that will be decomposed.
LastPCAdparFirst PCA parameter that will be decomposed.
See also
For more details, visit the PCAHandler

Definition at line 46 of file ParameterHandlerBase.cpp.

46  {
47 // ********************************************
48  if(AdaptiveHandler) {
49  MACH3LOG_ERROR("Adaption has been enabled and now trying to enable PCA. Right now both configuration don't work with each other");
50  throw MaCh3Exception(__FILE__ , __LINE__ );
51  }
52 
53  PCAObj = std::make_unique<PCAHandler>();
54  //Check whether first and last pcadpar are set and if not just PCA everything
55  if(FirstPCAdpar == -999 || LastPCAdpar == -999) {
56  if(FirstPCAdpar == -999 && LastPCAdpar == -999) {
57  FirstPCAdpar = 0;
58  LastPCAdpar = covMatrix->GetNrows()-1;
59  }
60  else{
61  MACH3LOG_ERROR("You must either leave FirstPCAdpar and LastPCAdpar at -999 or set them both to something");
62  throw MaCh3Exception(__FILE__ , __LINE__ );
63  }
64  }
65 
66  PCAObj->ConstructPCA(covMatrix, FirstPCAdpar, LastPCAdpar, eigen_threshold, _fNumPar);
67  PCAObj->SetupPointers(&_fCurrVal, &_fPropVal);
68  // Make a note that we have now done PCA
69  pca = true;
70 }

◆ CorrelateSteps()

void ParameterHandlerBase::CorrelateSteps ( )

Use Cholesky throw matrix for better step proposal.

Definition at line 586 of file ParameterHandlerBase.cpp.

586  {
587 // ************************************************
588  //KS: Using custom function compared to ROOT one with 8 threads we have almost factor 2 performance increase, by replacing TMatrix with just double we increase it even more
590 
591  // If not doing PCA
592  if (!pca) {
593  #ifdef MULTITHREAD
594  #pragma omp parallel for
595  #endif
596  for (int i = 0; i < _fNumPar; ++i) {
597  if (!IsParameterFixed(i) > 0.) {
598  #pragma GCC diagnostic push
599  #pragma GCC diagnostic ignored "-Wuseless-cast"
601  #pragma GCC diagnostic pop
602  }
603  }
604  // If doing PCA throw uncorrelated in PCA basis (orthogonal basis by definition)
605  } else {
607  }
608 }
double _fGlobalStepScale
Global step scale applied to all params in this class.
bool IsParameterFixed(const int i) const
Is parameter fixed or not.
std::vector< double > _fIndivStepScale
Individual step scale used by MCMC algorithm.
void MatrixVectorMulti(double *_restrict_ VecMulti, double **_restrict_ matrix, const double *_restrict_ vector, const int n)
KS: Custom function to perform multiplication of matrix and vector with multithreading.

◆ EnableSpecialProposal()

void ParameterHandlerBase::EnableSpecialProposal ( const YAML::Node &  param,
const int  Index 
)
protected

Enable special proposal.

Definition at line 107 of file ParameterHandlerBase.cpp.

107  {
108 // ********************************************
109  doSpecialStepProposal = true;
110 
111  bool CircEnabled = false;
112  std::pair<double, double> circular_bounds;
113 
114  bool FlipEnabled = false;
115  std::string flip_group;
116  double flip_point;
117 
118  bool FunctionalFlipEnabled = false;
119  YAML::Node functional_flip;
120 
121  if (param["CircularBounds"]) {
122  CircEnabled = true;
123  circular_bounds = Get<std::pair<double, double>>(param["CircularBounds"], __FILE__, __LINE__);
124  }
125 
126  if (param["FlipParameter"]) {
127  FlipEnabled = true;
128  // grab flip group if it exists, otherwise use the parameter name as the group
129  if (param["FlipGroup"]) {
130  flip_group = Get<std::string>(param["FlipGroup"], __FILE__, __LINE__);
131  } else {
132  flip_group = GetParFancyName(Index);
133  }
134  flip_point = Get<double>(param["FlipParameter"], __FILE__, __LINE__);
135  }
136 
137  if (param["FunctionalFlip"]) {
138  FunctionalFlipEnabled = true;
139  // grab functional flip details if needed
140  if (param["FlipGroup"]) {
141  flip_group = Get<std::string>(param["FlipGroup"], __FILE__, __LINE__);
142  } else {
143  flip_group = GetParFancyName(Index);
144  }
145  functional_flip = param["FunctionalFlip"];
146  }
147 
148  if (!CircEnabled && !FlipEnabled && !FunctionalFlipEnabled) {
149  MACH3LOG_ERROR("None of Special Proposal were enabled even though param {}, has SpecialProposal entry in Yaml", GetParFancyName(Index));
150  throw MaCh3Exception(__FILE__, __LINE__);
151  }
152 
153 
154  if (FlipEnabled && FunctionalFlipEnabled) {
155  MACH3LOG_ERROR("Parameter {} enables both FlipParameter and FunctionalFlip; choose exactly one flip type", GetParFancyName(Index));
156  throw MaCh3Exception(__FILE__, __LINE__);
157  }
158 
159  if (CircEnabled) {
160  CircularBoundsIndex.push_back(Index);
161  CircularBoundsValues.push_back(circular_bounds);
162  MACH3LOG_INFO("Enabling CircularBounds for parameter {} with range [{}, {}]",
163  GetParFancyName(Index),
164  circular_bounds.first,
165  circular_bounds.second);
166  // KS: Make sure circular bounds are within physical bounds. If we are outside of physics bound MCMC will never explore such phase space region
167  if (circular_bounds.first < _fLowBound.at(Index) || circular_bounds.second > _fUpBound.at(Index)) {
168  MACH3LOG_ERROR("Circular bounds [{}, {}] for parameter {} exceed physical bounds [{}, {}]",
169  circular_bounds.first, circular_bounds.second,
170  GetParFancyName(Index),
171  _fLowBound.at(Index), _fUpBound.at(Index));
172  throw MaCh3Exception(__FILE__, __LINE__);
173  }
174  // KS: Make sure CircularPrior is applied only to param with flat prior. Sadly doesn't work with Gaussian
175  if(GetFlatPrior(Index) == false) {
176  MACH3LOG_ERROR("Enabled CircularPrior for parameter {}, which has gaussian prior", GetParFancyName(Index));
177  MACH3LOG_ERROR("This is not supported, CircularPrior only works with flat prior");
178  MACH3LOG_ERROR("Change FlatPrior in Parameter config to true");
179  throw MaCh3Exception(__FILE__, __LINE__);
180  }
181  }
182 
183  if (FlipEnabled) {
184  FlipGroup& group = FlipGroups[flip_group];
185  group.FlipParameterIndex.push_back(Index);
186  group.FlipParameterPoint.push_back(flip_point);
187 
188  MACH3LOG_INFO("Enabling Flipping for parameter {} in group {} with value {}",
189  GetParFancyName(Index),
190  flip_group,
191  flip_point);
192  }
193 
194  if (FunctionalFlipEnabled) {
195  FlipGroups[flip_group];
196  QueueFunctionalFlip(functional_flip, Index, flip_group); // leave the resolution of the functional flips until after all the params have been loaded in
197 
198  MACH3LOG_INFO("Enabling Functional Flipping for parameter {} in group {} with config {}",
199  GetParFancyName(Index),
200  flip_group,
201  YAML::Dump(functional_flip));
202  }
203 
204  if (CircEnabled && FlipEnabled) {
205  if (flip_point < circular_bounds.first || flip_point > circular_bounds.second) {
206  MACH3LOG_ERROR("FlipParameter value {} for parameter {} is outside the CircularBounds [{}, {}]",
207  flip_point, GetParFancyName(Index), circular_bounds.first, circular_bounds.second);
208  throw MaCh3Exception(__FILE__, __LINE__);
209  }
210 
211  const double low = circular_bounds.first;
212  const double high = circular_bounds.second;
213 
214  // Sanity check: ensure flipping any x in [low, high] keeps the result in [low, high]
215  const double flipped_low = 2 * flip_point - low;
216  const double flipped_high = 2 * flip_point - high;
217  const double min_flip = std::min(flipped_low, flipped_high);
218  const double max_flip = std::max(flipped_low, flipped_high);
219 
220  if (min_flip < low || max_flip > high) {
221  MACH3LOG_ERROR("Flipping about point {} for parameter {} would leave circular bounds [{}, {}]",
222  flip_point, GetParFancyName(Index), low, high);
223  throw MaCh3Exception(__FILE__, __LINE__);
224  }
225  }
226 }
std::vector< int > CircularBoundsIndex
Indices of parameters with circular bounds.
void QueueFunctionalFlip(const YAML::Node &param, const int index, const std::string &group_name)
Queue a functional flip until all parameters have been loaded.
std::vector< std::pair< double, double > > CircularBoundsValues
Circular bounds for each parameter (lower, upper)
bool GetFlatPrior(const int i) const
Get if param has flat prior or not.
Struct to hold information about a group of parameters that flip together at the same time.
std::vector< int > FlipParameterIndex
Indices of parameters with flip symmetry.
std::vector< double > FlipParameterPoint
Central points around which parameters are flipped.

◆ EvaluateFunctionalFlip()

M3::float_t ParameterHandlerBase::EvaluateFunctionalFlip ( const FunctionalFlipProposal &  flip,
const std::vector< double > &  proposed_values 
) const
protected

Evaluate a formula-driven flip for a target parameter.

Parameters
flipFunctional flip configuration.

Definition at line 682 of file ParameterHandlerBase.cpp.

683  {
684 // *************************************
685  std::vector<double> parameter_values(flip.argument_indices.size(), 0.0);
686  for (size_t i = 0; i < flip.argument_indices.size(); ++i) {
687  parameter_values[i] = proposed_values[flip.argument_indices[i]];
688  }
689 
690  const double target_value = proposed_values[flip.target_index];
691  const double flipped_value = flip.evaluator->EvalPar(&target_value, parameter_values.data());
692  return static_cast<M3::float_t>(flipped_value);
693 }

◆ FlipParameterGroup()

void ParameterHandlerBase::FlipParameterGroup ( const std::string &  group)
protected

With a 50% chance, flip all parameters in a group around their respective flip points.

Parameters
groupName of the flip group

Definition at line 644 of file ParameterHandlerBase.cpp.

644  {
645 // *************************************
646  const FlipGroup& flip_group = FlipGroups.at(group);
647  // All standard and functional flip groups use the same 50% gate
648  // The exact value doesn't matter: studies with different probabilities showed
649  // it doesn't help exploration even for very unlikely hypotheses, because once
650  // the chain flips to a state, it stays there for a very long time regardless.
651  if (M3::rand::Uniform() >= 0.5) {
652  return;
653  }
654 
655  // store the proposed values before doing any flipping, so that the functional flip can see the unflipped values for any standard flips
656  std::vector<double> proposed_values(_fNumPar, 0.0);
657  for (int i = 0; i < _fNumPar; ++i) {
658  proposed_values[i] = _fPropVal[i];
659  }
660 
661  // perform standard flips first
662  for (size_t i = 0; i < flip_group.FlipParameterIndex.size(); ++i) {
663  const int index = flip_group.FlipParameterIndex[i];
664  if (!IsParameterFixed(index)) {
665  const double flip_point = flip_group.FlipParameterPoint[i];
666  _fPropVal[index] = static_cast<M3::float_t>(2 * flip_point - proposed_values[index]);
667  }
668  }
669 
670  // perform functional flips next
671  for (const auto& functional_flip : flip_group.FunctionalFlipParameters) {
672  if (IsParameterFixed(functional_flip.target_index)) {
673  continue;
674  }
675 
676  _fPropVal[functional_flip.target_index] = EvaluateFunctionalFlip(functional_flip, proposed_values);
677  }
678 }
M3::float_t EvaluateFunctionalFlip(const FunctionalFlipProposal &flip, const std::vector< double > &proposed_values) const
Evaluate a formula-driven flip for a target parameter.
double Uniform(const double min=0.0, const double max=1.0)
Generate a uniform random number in [min, max).
Definition: Random.h:116
std::vector< FunctionalFlipProposal > FunctionalFlipParameters
Formula-driven flips that should be applied when this group flips.

◆ GetAdaptiveHandler()

AdaptiveMCMCHandler* ParameterHandlerBase::GetAdaptiveHandler ( ) const
inline

Get pointer for AdaptiveHandler.

Definition at line 310 of file ParameterHandlerBase.h.

310  {
311  if (!use_adaptive) {
312  MACH3LOG_ERROR("Am not running in Adaptive mode");
313  throw MaCh3Exception(__FILE__ , __LINE__ );
314  }
315  return AdaptiveHandler.get();
316  }

◆ GetConfig()

YAML::Node ParameterHandlerBase::GetConfig ( ) const
inline

Getter to return a copy of the YAML node.

Definition at line 307 of file ParameterHandlerBase.h.

307 { return _fYAMLDoc; }
YAML::Node _fYAMLDoc
Stores config describing systematics.

◆ GetCorrelationMatrix()

TH2D * ParameterHandlerBase::GetCorrelationMatrix ( ) const

KS: Convert covariance matrix to correlation matrix and return TH2D which can be used for fancy plotting.

This function converts the covariance matrix to a correlation matrix and returns a TH2D object, which can be used for advanced plotting purposes.

Returns
A pointer to a TH2D object representing the correlation matrix

Definition at line 1342 of file ParameterHandlerBase.cpp.

1342  {
1343 // ********************************************
1344  TH2D* hMatrix = new TH2D(GetName().c_str(), GetName().c_str(), _fNumPar, 0.0, _fNumPar, _fNumPar, 0.0, _fNumPar);
1345  hMatrix->SetDirectory(nullptr);
1346  for(int i = 0; i < _fNumPar; i++)
1347  {
1348  hMatrix->SetBinContent(i+1, i+1, 1.);
1349  hMatrix->GetXaxis()->SetBinLabel(i+1, GetParFancyName(i).c_str());
1350  hMatrix->GetYaxis()->SetBinLabel(i+1, GetParFancyName(i).c_str());
1351  }
1352 
1353  #ifdef MULTITHREAD
1354  #pragma omp parallel for
1355  #endif
1356  for(int i = 0; i < _fNumPar; i++)
1357  {
1358  for(int j = 0; j <= i; j++)
1359  {
1360  const double Corr = (*covMatrix)(i,j) / ( GetDiagonalError(i) * GetDiagonalError(j));
1361  hMatrix->SetBinContent(i+1, j+1, Corr);
1362  hMatrix->SetBinContent(j+1, i+1, Corr);
1363  }
1364  }
1365  return hMatrix;
1366 }
std::string GetName() const
Get name of covariance.
double GetDiagonalError(const int i) const
Get diagonal error for ith parameter.

◆ GetCorrThrows()

double ParameterHandlerBase::GetCorrThrows ( const int  i) const
inline

Return correlated throws.

Parameters
iParameter index

Definition at line 134 of file ParameterHandlerBase.h.

134 { return corr_throw[i]; }

◆ GetCovMatrix()

TMatrixDSym* ParameterHandlerBase::GetCovMatrix ( ) const
inline

Return covariance matrix.

Definition at line 126 of file ParameterHandlerBase.h.

126 { return covMatrix; }

◆ GetDiagonalError()

double ParameterHandlerBase::GetDiagonalError ( const int  i) const
inline

Get diagonal error for ith parameter.

Parameters
iParameter index

Definition at line 155 of file ParameterHandlerBase.h.

155 { return std::sqrt((*covMatrix)(i,i)); }

◆ GetDoAdaption()

bool ParameterHandlerBase::GetDoAdaption ( ) const
inline

Do we adapt or not.

Definition at line 174 of file ParameterHandlerBase.h.

174 {return use_adaptive;}

◆ GetError()

double ParameterHandlerBase::GetError ( const int  i) const
inline

Get the error for the ith parameter.

Parameters
iParameter index

Definition at line 158 of file ParameterHandlerBase.h.

158 {return _fError[i];}
std::vector< double > _fError
Prior error on the parameter.

◆ GetFlatPrior()

bool ParameterHandlerBase::GetFlatPrior ( const int  i) const
inline

Get if param has flat prior or not.

Parameters
iParameter index

Definition at line 138 of file ParameterHandlerBase.h.

138 { return _fFlatPrior[i]; }

◆ GetGlobalStepScale()

double ParameterHandlerBase::GetGlobalStepScale ( ) const
inline

Get global step scale for covariance object.

Definition at line 240 of file ParameterHandlerBase.h.

240 {return _fGlobalStepScale; }

◆ GetIndivStepScale()

double ParameterHandlerBase::GetIndivStepScale ( const int  ParameterIndex) const
inline

Get individual step scale for selected parameter.

Parameters
ParameterIndexParameter index

Definition at line 238 of file ParameterHandlerBase.h.

238 {return _fIndivStepScale.at(ParameterIndex); }

◆ GetInvCovMatrix() [1/2]

TMatrixDSym* ParameterHandlerBase::GetInvCovMatrix ( ) const
inline

Return inverted covariance matrix.

Definition at line 128 of file ParameterHandlerBase.h.

128 { return invCovMatrix; }

◆ GetInvCovMatrix() [2/2]

double ParameterHandlerBase::GetInvCovMatrix ( const int  i,
const int  j 
) const
inline

Return inverted covariance matrix.

Definition at line 130 of file ParameterHandlerBase.h.

130 { return InvertCovMatrix[i][j]; }

◆ GetLikelihood()

double ParameterHandlerBase::GetLikelihood ( )
virtual

Return CalcLikelihood if some params were thrown out of boundary return LARGE_LOGL

Reimplemented in PyParameterHandlerBase.

Definition at line 785 of file ParameterHandlerBase.cpp.

785  {
786 // ********************************************
787  // Default behaviour is to reject negative values + do std llh calculation
788  const int NOutside = CheckBounds();
789 
790  if(NOutside > 0) return NOutside*M3::_LARGE_LOGL_;
791 
792  return CalcLikelihood();
793 }
double CalcLikelihood() const _noexcept_
Calc penalty term based on inverted covariance matrix.
int CheckBounds() const _noexcept_
Check if parameters were proposed outside physical boundary.
constexpr static const double _LARGE_LOGL_
Large Likelihood is used it parameter go out of physical boundary, this indicates in MCMC that such s...
Definition: Core.h:80

◆ GetLowerBound()

double ParameterHandlerBase::GetLowerBound ( const int  i) const
inline

Get lower parameter bound in which it is physically valid.

Parameters
iParameter index

Definition at line 235 of file ParameterHandlerBase.h.

235 { return _fLowBound[i]; }

◆ GetName()

std::string ParameterHandlerBase::GetName ( ) const
inline

Get name of covariance.

Definition at line 141 of file ParameterHandlerBase.h.

141 { return matrixName; }

◆ GetNParameters()

int ParameterHandlerBase::GetNParameters ( ) const
inline

Get number of params which will be different depending if using Eigen decomposition or not.

Definition at line 243 of file ParameterHandlerBase.h.

243  {
244  if (pca) return PCAObj->GetNumberPCAedParameters();
245  else return _fNumPar;
246  }

◆ GetNumParams()

int ParameterHandlerBase::GetNumParams ( ) const
inline

Get total number of parameters.

Definition at line 213 of file ParameterHandlerBase.h.

213 {return _fNumPar;}

◆ GetParCurr()

double ParameterHandlerBase::GetParCurr ( const int  i) const
inline

Get current parameter value.

Parameters
iParameter index

Definition at line 223 of file ParameterHandlerBase.h.

223 { return _fCurrVal[i]; }

◆ GetParCurrVec()

const std::vector<double>& ParameterHandlerBase::GetParCurrVec ( ) const
inline

Get vector of current parameter values.

Definition at line 225 of file ParameterHandlerBase.h.

225 { return _fCurrVal; }

◆ GetParFancyName()

std::string ParameterHandlerBase::GetParFancyName ( const int  i) const
inline

Get fancy name of the Parameter.

Parameters
iParameter index

Definition at line 151 of file ParameterHandlerBase.h.

151 {return _fFancyNames[i];}
std::vector< std::string > _fFancyNames
Fancy name for example rather than param_0 it is MAQE, useful for human reading.

◆ GetParIndex()

int ParameterHandlerBase::GetParIndex ( const std::string &  name) const

Get index based on name.

Definition at line 873 of file ParameterHandlerBase.cpp.

873  {
874 // ********************************************
875  int Index = M3::_BAD_INT_;
876  for (int i = 0; i <_fNumPar; ++i) {
877  if(name == _fFancyNames[i]) {
878  Index = i;
879  break;
880  }
881  }
882  return Index;
883 }

◆ GetParName()

std::string ParameterHandlerBase::GetParName ( const int  i) const
inline

Get name of parameter.

Parameters
iParameter index

Definition at line 144 of file ParameterHandlerBase.h.

144 {return _fNames[i];}
std::vector< std::string > _fNames
ETA _fNames is set automatically in the covariance class to be something like param_i,...

◆ GetParPreFit()

double ParameterHandlerBase::GetParPreFit ( const int  i) const
inline

Get prior parameter value.

Parameters
iParameter index

Definition at line 229 of file ParameterHandlerBase.h.

229 { return _fPreFitValue[i]; }

◆ GetParProp()

M3::float_t ParameterHandlerBase::GetParProp ( const int  i) const
inline

Get proposed parameter value.

Parameters
iParameter index

Definition at line 220 of file ParameterHandlerBase.h.

220 { return _fPropVal[i]; }

◆ GetParPropVec()

const std::vector<M3::float_t>& ParameterHandlerBase::GetParPropVec ( )
inline

Get a reference to the proposed parameter values Can be useful if you want to track these without having to copy values using getProposed()

Definition at line 210 of file ParameterHandlerBase.h.

210 {return _fPropVal;}

◆ GetPCAHandler()

PCAHandler* ParameterHandlerBase::GetPCAHandler ( ) const
inline

Get pointer for PCAHandler.

Definition at line 322 of file ParameterHandlerBase.h.

322  {
323  if (!pca) {
324  MACH3LOG_ERROR("Am not running in PCA mode");
325  throw MaCh3Exception(__FILE__ , __LINE__ );
326  }
327  return PCAObj.get();
328  }

◆ GetPreFitValues()

std::vector<double> ParameterHandlerBase::GetPreFitValues ( ) const
inline

Get the pre-fit values of the parameters.

Definition at line 215 of file ParameterHandlerBase.h.

215 {return _fPreFitValue;}

◆ GetProposed()

std::vector< double > ParameterHandlerBase::GetProposed ( ) const

Get vector of all proposed parameter values.

Definition at line 385 of file ParameterHandlerBase.cpp.

385  {
386 // ********************************************
387  std::vector<double> props(_fNumPar);
388  for (int i = 0; i < _fNumPar; ++i) props[i] = _fPropVal[i];
389  return props;
390 }

◆ GetRandomThrow()

double ParameterHandlerBase::GetRandomThrow ( const int  i) const
inline

Get random value useful for debugging/CI.

Parameters
iParameter index

Definition at line 79 of file ParameterHandlerBase.h.

79 { return randParams[i];}

◆ GetThrowMatrix() [1/2]

TMatrixDSym* ParameterHandlerBase::GetThrowMatrix ( ) const
inline

Get matrix used for step proposal.

Definition at line 187 of file ParameterHandlerBase.h.

187 {return throwMatrix;}

◆ GetThrowMatrix() [2/2]

double ParameterHandlerBase::GetThrowMatrix ( const int  i,
const int  j 
) const
inline

Get matrix used for step proposal.

Definition at line 189 of file ParameterHandlerBase.h.

189 { return throwMatrixCholDecomp[i][j];}

◆ GetUpperBound()

double ParameterHandlerBase::GetUpperBound ( const int  i) const
inline

Get upper parameter bound in which it is physically valid.

Parameters
iParameter index

Definition at line 232 of file ParameterHandlerBase.h.

232 { return _fUpBound[i];}

◆ InitFromFile()

void ParameterHandlerBase::InitFromFile ( const std::string &  name,
const std::string &  file 
)
protected

Initialisation of the class using matrix from root file.

Definition at line 73 of file ParameterHandlerBase.cpp.

73  {
74 // ********************************************
75  // Set the covariance matrix from input ROOT file (e.g. flux, ND280, NIWG)
76  TFile *infile = new TFile(file.c_str(), "READ");
77  if (infile->IsZombie()) {
78  MACH3LOG_ERROR("Could not open input covariance ROOT file {} !!!", file);
79  MACH3LOG_ERROR("Was about to retrieve matrix with name {}", name);
80  throw MaCh3Exception(__FILE__ , __LINE__ );
81  }
82 
83  TMatrixDSym *CovMat = static_cast<TMatrixDSym*>(infile->Get(name.c_str()));
84 
85  if (!CovMat) {
86  MACH3LOG_ERROR("Could not find covariance matrix name {} in file {}", name, file);
87  MACH3LOG_ERROR("Are you really sure {} exists in the file?", name);
88  throw MaCh3Exception(__FILE__ , __LINE__ );
89  }
90 
91  // Set the covariance matrix
92  _fNumPar = CovMat->GetNrows();
93 
95  SetName(name);
96  MakePosDef(CovMat);
97  SetCovMatrix(CovMat);
98 
99  infile->Close();
100 
101  MACH3LOG_INFO("Created covariance matrix named: {}", GetName());
102  MACH3LOG_INFO("from file: {}", file);
103  delete infile;
104 }
void SetName(const std::string &name)
Set matrix name.
void SetCovMatrix(TMatrixDSym *cov)
Set covariance matrix.
void ReserveMemory(const int size)
Initialise vectors with parameters information.
void MakePosDef(TMatrixDSym *cov=nullptr, bool verbose=true)
Make matrix positive definite by adding small values to diagonal, necessary for inverting matrix.

◆ InitialiseAdaption()

void ParameterHandlerBase::InitialiseAdaption ( const YAML::Node &  adapt_manager)

Initialise adaptive MCMC.

Parameters
adapt_managerNode having from which we load all adaptation options

Definition at line 1173 of file ParameterHandlerBase.cpp.

1173  {
1174 // ********************************************
1175  if(PCAObj){
1176  MACH3LOG_ERROR("PCA has been enabled and now trying to enable Adaption. Right now both configuration don't work with each other");
1177  throw MaCh3Exception(__FILE__ , __LINE__ );
1178  }
1179  if(AdaptiveHandler){
1180  MACH3LOG_ERROR("Adaptive Handler has already been initialise can't do it again so skipping.");
1181  return;
1182  }
1183  AdaptiveHandler = std::make_unique<AdaptiveMCMCHandler>();
1184 
1185  // HH: Backing up _fIndivStepScale and _fGlobalStepScale before adaption
1188 
1189  // HH: adding these here because they will be used to set the individual step scales for non-adapting parameters
1190  auto params_to_skip = GetFromManager<std::vector<std::string>>(adapt_manager["AdaptionOptions"]["Covariance"][matrixName]["ParametersToSkip"], {}, __FILE__ , __LINE__);
1191  // Build a list of skip flags
1192  param_skip_adapt_flags.resize(_fNumPar, false);
1193  for (int i = 0; i <_fNumPar; ++i) {
1195  }
1196 
1197  // Now we read the general settings [these SHOULD be common across all matrices!]
1198  bool success = AdaptiveHandler->InitFromConfig(adapt_manager, matrixName,
1201  );
1202  if (success) {
1203  // Ensure there is no misconfiguration in adaption config
1204  SanitizeAdaption();
1205  AdaptiveHandler->Print();
1206  } else {
1207  MACH3LOG_INFO("Not using adaptive MCMC for {}. Checking external matrix options...", matrixName);
1208  }
1209 
1210  // HH: Adjusting the external matrix reading logic such that you can not do adaptive
1211  // and still read an external matrix
1212  // Logic:
1213  // if read external matrix:
1214  // set throw matrix regardless of adaptive or not
1215  // else:
1216  // if adaptive:
1217  // create new adaptive matrix from scratch
1218  // else:
1219  // do nothing
1220  if(GetFromManager<bool>(adapt_manager["AdaptionOptions"]["Covariance"][matrixName]["UseExternalMatrix"], false, __FILE__ , __LINE__)) {
1221  // Finally, we accept that we want to read the matrix from a file!
1222  auto external_file_name = GetFromManager<std::string>(adapt_manager["AdaptionOptions"]["Covariance"][matrixName]["ExternalMatrixFileName"], "", __FILE__ , __LINE__);
1223  auto external_matrix_name = GetFromManager<std::string>(adapt_manager["AdaptionOptions"]["Covariance"][matrixName]["ExternalMatrixName"], "", __FILE__ , __LINE__);
1224  auto external_mean_name = GetFromManager<std::string>(adapt_manager["AdaptionOptions"]["Covariance"][matrixName]["ExternalMeansName"], "", __FILE__ , __LINE__);
1225 
1226  AdaptiveHandler->SetThrowMatrixFromFile(external_file_name, external_matrix_name, external_mean_name, use_adaptive);
1227  SetThrowMatrix(AdaptiveHandler->GetAdaptiveCovariance());
1228 
1230  // HH: Set individual step scales for non-adapting parameters to the default individual step scales
1231  // global step scale should be 1 so no need to adjust for that
1233 
1234  MACH3LOG_INFO("Successfully Set External Throw Matrix Stored in {}", external_file_name);
1235  } else {
1236  MACH3LOG_INFO("Not using external matrix for {}", matrixName);
1237  if (!success) return; // Not adaptive either so nothing to do
1238  MACH3LOG_INFO("Initialising adaption from scratch");
1239  // If we don't have a covariance matrix to start from for adaptive tune we need to make one!
1240  use_adaptive = true;
1241  AdaptiveHandler->CheckMatrixValidityForAdaption(GetCovMatrix());
1242  AdaptiveHandler->CreateNewAdaptiveCovariance();
1243  return;
1244  }
1245 }
std::vector< bool > param_skip_adapt_flags
Flags telling if parameter should be skipped during adaption.
void SanitizeAdaption() const
Perform sanity check to ensure adaption isn't misbehaving before fit starts.
double _fGlobalStepScaleInitial
Backup of _fGlobalStepScale for parameters which are skipped during adaption.
TMatrixDSym * GetCovMatrix() const
Return covariance matrix.
void SetThrowMatrix(const TMatrixDSym *cov)
Use new throw matrix, used in adaptive MCMC.
void ResetIndivStepScale()
Adaptive Step Tuning Stuff.
std::vector< double > _fIndivStepScaleInitial
Backup of _fIndivStepScale for parameters which are skipped during adaption.
void SetIndivStepScaleForSkippedAdaptParams()
Set individual step scale for parameters which are skipped during adaption to initial values.
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.

◆ IsParameterFixed() [1/2]

bool ParameterHandlerBase::IsParameterFixed ( const int  i) const
inline

Is parameter fixed or not.

Parameters
iParameter index

Definition at line 288 of file ParameterHandlerBase.h.

288  {
289  if (_fError[i] < 0) { return true; }
290  else { return false; }
291  }

◆ IsParameterFixed() [2/2]

bool ParameterHandlerBase::IsParameterFixed ( const std::string &  name) const

Is parameter fixed or not.

Parameters
nameName of parameter you want to check if is fixed

Definition at line 963 of file ParameterHandlerBase.cpp.

963  {
964 // ********************************************
965  const int Index = GetParIndex(name);
966  if(Index != M3::_BAD_INT_) {
967  return IsParameterFixed(Index);
968  }
969 
970  MACH3LOG_WARN("I couldn't find parameter with name {}, therefore don't know if it fixed", name);
971  return false;
972 }
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36

◆ IsPCA()

bool ParameterHandlerBase::IsPCA ( ) const
inline

is PCA, can use to query e.g. LLH scans

Definition at line 304 of file ParameterHandlerBase.h.

304 { return pca; }

◆ MakeClosestPosDef()

void ParameterHandlerBase::MakeClosestPosDef ( TMatrixDSym *  cov)
protected

HW: Finds closest possible positive definite matrix in Frobenius Norm ||.||_frob Where ||X||_frob=sqrt[sum_ij(x_ij^2)] (basically just turns an n,n matrix into vector in n^2 space then does Euclidean norm)

Definition at line 1295 of file ParameterHandlerBase.cpp.

1295  {
1296 // ********************************************
1297  // Want to get cov' = (cov_sym+cov_polar)/2
1298  // cov_sym=(cov+cov^T)/2
1299  // cov_polar-> SVD cov to cov=USV^T then cov_polar=VSV^T
1300 
1301  //Get frob norm of cov
1302  // Double_t cov_norm=cov->E2Norm();
1303 
1304  TMatrixDSym* cov_trans = cov;
1305  cov_trans->T();
1306  TMatrixDSym cov_sym = 0.5*(*cov+*cov_trans); //If cov is symmetric does nothing, otherwise just ensures symmetry
1307 
1308  //Do SVD to get polar form
1309  TDecompSVD cov_sym_svd=TDecompSVD(cov_sym);
1310  if(!cov_sym_svd.Decompose()){
1311  MACH3LOG_WARN("Cannot do SVD on input matrix, trying MakePosDef() first!");
1312  MakePosDef(&cov_sym);
1313  }
1314 
1315  TMatrixD cov_sym_v = cov_sym_svd.GetV();
1316  TMatrixD cov_sym_vt = cov_sym_v;
1317  cov_sym_vt.T();
1318  //SVD returns as vector (grrr) so need to get into matrix form for multiplying!
1319  TVectorD cov_sym_sigvect = cov_sym_svd.GetSig();
1320 
1321  const Int_t nCols = cov_sym_v.GetNcols(); //square so only need rows hence lack of cols
1322  TMatrixDSym cov_sym_sig(nCols);
1323  TMatrixDDiag cov_sym_sig_diag(cov_sym_sig);
1324  cov_sym_sig_diag=cov_sym_sigvect;
1325 
1326  //Can finally get H=VSV
1327  TMatrixDSym cov_sym_polar = cov_sym_sig.SimilarityT(cov_sym_vt);//V*S*V^T (this took forver to find!)
1328 
1329  //Now we can construct closest approximater Ahat=0.5*(B+H)
1330  TMatrixDSym cov_closest_approx = 0.5*(cov_sym+cov_sym_polar);//Not fully sure why this is even needed since symmetric B -> U=V
1331  //Get norm of transformed
1332  // Double_t approx_norm=cov_closest_approx.E2Norm();
1333  //MACH3LOG_INFO("Initial Norm: {:.6f} | Norm after transformation: {:.6f} | Ratio: {:.6f}", cov_norm, approx_norm, cov_norm / approx_norm);
1334 
1335  *cov = cov_closest_approx;
1336  //Now can just add a makeposdef!
1337  MakePosDef(cov);
1338 }

◆ MakePosDef()

void ParameterHandlerBase::MakePosDef ( TMatrixDSym *  cov = nullptr,
bool  verbose = true 
)
protected

Make matrix positive definite by adding small values to diagonal, necessary for inverting matrix.

Parameters
covMatrix which we evaluate Positive Definitiveness
verboseDo we want it to print warning if it was not positive definite and we had to fix it

Definition at line 1027 of file ParameterHandlerBase.cpp.

1027  {
1028 // ********************************************
1029  if(cov == nullptr){
1030  cov = &*covMatrix;
1031  MACH3LOG_WARN("Passed nullptr to cov matrix in {}", matrixName);
1032  }
1033 
1034  int n_attempts = M3::MakeMatrixPosDef(cov);
1035 
1036  if(n_attempts > 0 && verbose) {
1037  MACH3LOG_WARN("Covariance matrix {} was not positive-definite, made it positive-definite after {} attempts", matrixName, n_attempts);
1038  }
1039 }
int MakeMatrixPosDef(TMatrixDSym *cov)
Makes sure that matrix is positive-definite by adding a small number to on-diagonal elements.

◆ MatchMaCh3OutputBranches()

void ParameterHandlerBase::MatchMaCh3OutputBranches ( TTree *  PosteriorFile,
std::vector< double > &  BranchValues,
std::vector< std::string > &  BranchNames,
const std::vector< std::string > &  FancyNames = {} 
)

Matches branches in a TTree to parameters in a systematic handler.

Parameters
PosteriorFilePointer to the ROOT TTree from MaCh3 fit.
BranchValuesVector to store the values of the branches (resized inside).
BranchNamesVector to store the names of the branches (resized inside).
FancyNamesOptional vector of "fancy names" to match. If empty, all parameters are matched.
  • If FancyNames is provided, it matches only the parameters whose "fancy names" are in FancyNames. This is useful for studies where one performs ND fits and passes them to FD fits, which may have additional parameters (e.g., oscillations).
  • If FancyNames is empty, it matches all parameters in the systematic handler.

Definition at line 1408 of file ParameterHandlerBase.cpp.

1411  {
1412 // *************************************
1413  BranchValues.resize(GetNumParams());
1414  BranchNames.resize(GetNumParams());
1415 
1416  // if fancy names are passed match ONLY them
1417  // this allow to perform studies where one perform ND fits and pass it to FD fits
1418  // which usually have more params like osc...
1419  if(FancyNames.size() != 0){
1420  for (int i = 0; i < GetNumParams(); ++i) {
1421  BranchNames[i] = GetParName(i);
1422  // by default set current step
1423  BranchValues[i] = _fPropVal[i];
1424  bool matched = false;
1425  for (size_t iPar = 0; iPar < FancyNames.size(); ++iPar) {
1426  if(GetParFancyName(i) == FancyNames[iPar]) {
1427  MACH3LOG_DEBUG("Matched name {} in config", FancyNames[iPar]);
1428  PosteriorFile->SetBranchStatus(BranchNames[iPar].c_str(), true);
1429  PosteriorFile->SetBranchAddress(BranchNames[iPar].c_str(), &BranchValues[i]);
1430  matched = true;
1431  break;
1432  }
1433  }
1434  if(!matched) {
1435  MACH3LOG_WARN("Didn't match param {}, is this what you want?", GetParFancyName(i));
1436  }
1437  }
1438  } else {
1439  // simply loop over params and match them
1440  for (int i = 0; i < GetNumParams(); ++i) {
1441  BranchNames[i] = GetParName(i);
1442  if (!PosteriorFile->GetBranch(BranchNames[i].c_str())) {
1443  MACH3LOG_WARN("Branch '{}' does not exist in the TTree, is this what you want?", BranchNames[i]);
1444  continue;
1445  }
1446  PosteriorFile->SetBranchStatus(BranchNames[i].c_str(), true);
1447  PosteriorFile->SetBranchAddress(BranchNames[i].c_str(), &BranchValues[i]);
1448  }
1449  }
1450 }
int GetNumParams() const
Get total number of parameters.
std::string GetParName(const int i) const
Get name of parameter.

◆ PrintIndivStepScale()

void ParameterHandlerBase::PrintIndivStepScale ( ) const

Print step scale for each parameter.

Definition at line 1011 of file ParameterHandlerBase.cpp.

1011  {
1012 // ********************************************
1013  M3::Utils::TablePrinter table({{"Parameter", 10, 40, M3::Utils::Alignment::Left},
1014  {"Step scale", 10, 15, M3::Utils::Alignment::Right},});
1015 
1016  for (int iParam = 0; iParam < _fNumPar; ++iParam) {
1017  table.AddRow(_fFancyNames[iParam], _fIndivStepScale[iParam]);
1018  }
1019 
1020  for (const auto& line : table.Render()) {
1021  MACH3LOG_INFO("{}", line);
1022  }
1023 }
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
@ Right
Align text to the right.
@ Left
Align text to the left.

◆ PrintPreFitCurrPropValues()

void ParameterHandlerBase::PrintPreFitCurrPropValues ( ) const

Print prior, current and proposed value for each parameter.

Definition at line 715 of file ParameterHandlerBase.cpp.

715  {
716 // ********************************************
717  MACH3LOG_INFO("Printing parameters for {}", GetName());
718  // Dump out the PCA parameters too
719  if (pca) {
720  PCAObj->Print();
721  }
722  M3::Utils::TablePrinter table({{"Name", 10, 40, M3::Utils::Alignment::Left},
723  {"Prior", 10, 15, M3::Utils::Alignment::Right},
724  {"Current", 10, 15, M3::Utils::Alignment::Right},
725  {"Proposed", 10, 15, M3::Utils::Alignment::Right},});
726 
727  for (int i = 0; i < _fNumPar; ++i) {
728  table.AddRow(GetParFancyName(i),
729  M3::Utils::Cell(_fPreFitValue[i], "{:.2f}"),
730  M3::Utils::Cell(_fCurrVal[i], "{:.2f}"),
731  M3::Utils::Cell(_fPropVal[i], "{:.2f}"));
732  }
733 
734  for (const auto& line : table.Render()) {
735  MACH3LOG_INFO("{}", line);
736  }
737 }
static std::string Cell(T &&value, std::string_view format)
Format a value using a runtime fmt format string.
Definition: TablePrinter.h:44

◆ PrintPreFitValues()

void ParameterHandlerBase::PrintPreFitValues ( ) const

Print prior value for every parameter.

Definition at line 697 of file ParameterHandlerBase.cpp.

697  {
698 // ********************************************
699  MACH3LOG_INFO("Prior values for {} ParameterHandler:", GetName());
700 
701  M3::Utils::TablePrinter table({{"Parameter", 10, 40, M3::Utils::Alignment::Left},
702  {"Prior", 10, 15, M3::Utils::Alignment::Right},});
703 
704  for (int i = 0; i < _fNumPar; ++i) {
705  table.AddRow(GetParFancyName(i), GetParPreFit(i));
706  }
707 
708  for (const auto& line : table.Render()) {
709  MACH3LOG_INFO("{}", line);
710  }
711 }
double GetParPreFit(const int i) const
Get prior parameter value.

◆ ProposeStep()

void ParameterHandlerBase::ProposeStep ( )
virtual

Generate a new proposed state.

Reimplemented in PyParameterHandlerBase.

Definition at line 514 of file ParameterHandlerBase.cpp.

514  {
515 // ************************************************
516  // Make the random numbers for the step proposal
517  Randomize();
518  CorrelateSteps();
519 
520  // KS: According to Dr Wallace we update using previous not proposed step
521  // this way we do special proposal after adaptive after.
522  // This way we can shortcut and skip rest of proposal
523  if(!doSpecialStepProposal) return;
524 
526 }
void Randomize() _noexcept_
"Randomize" the parameters in the covariance class for the proposed step. Used the proposal kernel an...
void SpecialStepProposal()
Perform Special Step Proposal.
void CorrelateSteps() _noexcept_
Use Cholesky throw matrix for better step proposal.

◆ QueueFunctionalFlip()

void ParameterHandlerBase::QueueFunctionalFlip ( const YAML::Node &  param,
const int  index,
const std::string &  group_name 
)
protected

Queue a functional flip until all parameters have been loaded.

Definition at line 229 of file ParameterHandlerBase.cpp.

229  {
230 // ********************************************
231  PendingFunctionalFlipProposal pending_flip;
232  pending_flip.target_index = index;
233  pending_flip.group_name = group_name;
234  pending_flip.config = YAML::Clone(param);
235  PendingFunctionalFlipParameters.push_back(std::move(pending_flip));
236 }
std::vector< PendingFunctionalFlipProposal > PendingFunctionalFlipParameters
Functional flips waiting for full parameter-name registration.
Configuration for a pending functional flip awaiting all parameters to be initialised.

◆ RandomConfiguration()

void ParameterHandlerBase::RandomConfiguration ( )

Randomly throw the parameters in their 1 sigma range.

Definition at line 452 of file ParameterHandlerBase.cpp.

452  {
453 // *************************************
454  #pragma GCC diagnostic push
455  #pragma GCC diagnostic ignored "-Wuseless-cast"
456  // Have the 1 sigma for each parameter in each covariance class, sweet!
457  // Don't want to change the prior array because that's what determines our likelihood
458  // Want to change the _fPropVal, _fCurrVal, _fPreFitValue
459  // _fPreFitValue and the others will already be set
460  for (int i = 0; i < _fNumPar; ++i) {
461  // Check if parameter is fixed first: if so don't randomly throw
462  if (IsParameterFixed(i)) continue;
463  // Check that the sigma range is larger than the parameter range
464  // If not, throw in the valid parameter range instead
465  const double paramrange = _fUpBound[i] - _fLowBound[i];
466  const double sigma = sqrt((*covMatrix)(i,i));
467  double throwrange = sigma;
468  if (paramrange < sigma) throwrange = paramrange;
469 
470  _fPropVal[i] = static_cast<M3::float_t>(_fPreFitValue[i] + M3::rand::Gaus(0, 1)*throwrange);
471  // Try again if we the initial parameter proposal falls outside of the range of the parameter
472  int throws = 0;
473  while (_fPropVal[i] > _fUpBound[i] || _fPropVal[i] < _fLowBound[i]) {
474  if (throws > 1000) {
475  MACH3LOG_WARN("Tried {} times to throw parameter {} but failed", throws, i);
476  MACH3LOG_WARN("Matrix: {}", matrixName);
477  MACH3LOG_WARN("Param: {}", _fNames[i]);
478  throw MaCh3Exception(__FILE__ , __LINE__ );
479  }
480  _fPropVal[i] = static_cast<M3::float_t>(_fPreFitValue[i] + M3::rand::Gaus(0, 1)*throwrange);
481  throws++;
482  }
483  MACH3LOG_INFO("Setting current step in {} param {} = {} from {}", matrixName, i, _fPropVal[i], _fCurrVal[i]);
484  _fCurrVal[i] = _fPropVal[i];
485  }
486  #pragma GCC diagnostic pop
487  if (pca) PCAObj->TransferToPCA();
488 
489  // KS: At the end once we are happy with proposal do special proposal
491 }
double Gaus(const double mean=0.0, const double sigma=1.0)
Generate a Gaussian random number.
Definition: Random.h:137

◆ Randomize()

void ParameterHandlerBase::Randomize ( )

"Randomize" the parameters in the covariance class for the proposed step. Used the proposal kernel and the current parameter value to set proposed step

Definition at line 550 of file ParameterHandlerBase.cpp.

550  {
551 // ************************************************
552  if (!pca) {
553  //KS: By multithreading here we gain at least factor 2 with 8 threads with ND only fit
554  #ifdef MULTITHREAD
555  #pragma omp parallel for
556  #endif
557  for (int i = 0; i < _fNumPar; ++i) {
558  // If parameter isn't fixed
559  if (!IsParameterFixed(i) > 0.0) {
560  randParams[i] = M3::rand::Gaus(0, 1);
561  // If parameter IS fixed
562  } else {
563  randParams[i] = 0.0;
564  }
565  } // end for
566  // If we're in the PCA basis we instead throw parameters there (only _fNumParPCA parameter)
567  } else {
568  // Scale the random parameters by the sqrt of eigen values for the throw
569  #ifdef MULTITHREAD
570  #pragma omp parallel for
571  #endif
572  for (int i = 0; i < PCAObj->GetNumberPCAedParameters(); ++i)
573  {
574  // If parameter IS fixed or out of bounds
575  if (PCAObj->IsParameterFixedPCA(i)) {
576  randParams[i] = 0.0;
577  } else {
578  randParams[i] = M3::rand::Gaus(0, 1);
579  }
580  }
581  }
582 }

◆ ReserveMemory()

void ParameterHandlerBase::ReserveMemory ( const int  size)
protected

Initialise vectors with parameters information.

Parameters
sizeinteger telling size to which we will resize all vectors/allocate memory

Definition at line 327 of file ParameterHandlerBase.cpp.

327  {
328 // ********************************************
329  if (SizeVec <= 0) {
330  MACH3LOG_CRITICAL("Covariance matrix {} has {} entries!", GetName(), SizeVec);
331  throw MaCh3Exception(__FILE__ , __LINE__ );
332  }
333 
334  _fNames = std::vector<std::string>(SizeVec);
335  _fFancyNames = std::vector<std::string>(SizeVec);
336  _fPreFitValue = std::vector<double>(SizeVec, 1.0);
337  _fError = std::vector<double>(SizeVec, 1.0);
338  _fCurrVal = std::vector<double>(SizeVec, 0.0);
339  _fPropVal = std::vector<M3::float_t>(SizeVec, 0.0);
340  _fLowBound = std::vector<double>(SizeVec, -999.99);
341  _fUpBound = std::vector<double>(SizeVec, 999.99);
342  _fFlatPrior = std::vector<bool>(SizeVec, false);
343  _fIndivStepScale = std::vector<double>(SizeVec, 1.0);
344 
345  corr_throw = new double[SizeVec];
346  // set random parameter vector (for correlated steps)
347  randParams = new double[SizeVec];
348 
349  // Set the defaults to true
350  for(int i = 0; i < SizeVec; i++) {
351  corr_throw[i] = 0.0;
352  randParams[i] = 0.0;
353  }
354 
355  InvertCovMatrix.resize(SizeVec, std::vector<double>(SizeVec, 0.0));
356  throwMatrixCholDecomp = new double*[SizeVec]();
357  // Set the defaults to true
358  for(int i = 0; i < SizeVec; i++) {
359  throwMatrixCholDecomp[i] = new double[SizeVec]();
360  for (int j = 0; j < SizeVec; j++) {
361  throwMatrixCholDecomp[i][j] = 0.;
362  }
363  }
364 
365  _fGlobalStepScale = 1.0;
366 }
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:38

◆ ResetIndivStepScale()

void ParameterHandlerBase::ResetIndivStepScale ( )

Adaptive Step Tuning Stuff.

Definition at line 1042 of file ParameterHandlerBase.cpp.

1042  {
1043 // ********************************************
1044  std::vector<double> stepScales(_fNumPar, 1.0);
1045  _fGlobalStepScale = 1.0;
1046  SetIndivStepScale(stepScales);
1047 }
void SetIndivStepScale(const int ParameterIndex, const double StepScale)
DB Function to set fIndivStepScale from a vector (Can be used from execs and inside covariance constr...

◆ ResolveFunctionalFlips()

void ParameterHandlerBase::ResolveFunctionalFlips ( )
protected

Resolve queued functional flips after parameter names are known.

Definition at line 239 of file ParameterHandlerBase.cpp.

239  {
240 // ********************************************
241  for (const auto& pending_flip : PendingFunctionalFlipParameters) {
242  AddFunctionalFlip(pending_flip.config, pending_flip.target_index, pending_flip.group_name);
243  }
244 
246 }
void AddFunctionalFlip(const YAML::Node &param, const int index, const std::string &group_name)
Parse and register a functional flip defined in YAML.

◆ RetPointer()

const M3::float_t* ParameterHandlerBase::RetPointer ( const int  iParam) const
inline

DB Pointer return to param position.

Parameters
iParamThe index of the parameter in the vector.
Returns
A pointer to the parameter value at the specified index.
Warning
ETA - This might be a bit squiffy? If the vector gots moved from say a push_back then the pointer is no longer valid... maybe need a better way to deal with this? It was fine before when the return was to an element of a new array. There must be a clever C++ way to be careful

Definition at line 206 of file ParameterHandlerBase.h.

206 {return &(_fPropVal.data()[iParam]);}

◆ SanitizeAdaption()

void ParameterHandlerBase::SanitizeAdaption ( ) const
protected

Perform sanity check to ensure adaption isn't misbehaving before fit starts.

Definition at line 1138 of file ParameterHandlerBase.cpp.

1138  {
1139 // ********************************************
1140  for (const auto& [_, group] : FlipGroups) {
1141  for (size_t i = 0; i < group.FlipParameterIndex.size(); ++i) {
1142  const int index = group.FlipParameterIndex[i];
1143  if(!param_skip_adapt_flags[index]) {
1144  MACH3LOG_ERROR("You enabled adaption for parameter which has enabled flipping ({})", _fFancyNames[index]);
1145  MACH3LOG_ERROR("Right now flipping and adapting doesn't work very well");
1146  MACH3LOG_ERROR("Please skip adaption for param {}, using ParametersToSkip option in config", _fFancyNames[index]);
1147  throw MaCh3Exception(__FILE__, __LINE__);
1148  }
1149  }
1150  }
1151 
1152  // HH: Loop over correlations to check if any skipped parameter is correlated with adapted one
1153  // We don't want to change one parameter while keeping the other fixed as this would
1154  // lead to weird penalty terms in the prior after adapting
1155  double max_correlation = 0.01; // Define a threshold for significant correlation above which we throw an error
1156  for (int i = 0; i < _fNumPar; ++i) {
1157  for (int j = 0; j <= i; ++j) {
1158  // The symmetry should have been checked during the Init phase
1160  double corr = (*covMatrix)(i,j)/std::sqrt((*covMatrix)(i,i)*(*covMatrix)(j,j));
1161  if(std::fabs(corr) > max_correlation) {
1162  MACH3LOG_ERROR("Correlation between skipped parameter {} ({}) and non-skipped parameter {} ({}) is {:.6e}, above the allowed threshold of {:.6e}.",
1163  i, _fFancyNames[i], j, _fFancyNames[j], corr, max_correlation);
1164  throw MaCh3Exception(__FILE__, __LINE__);
1165  }
1166  }
1167  }
1168  }
1169 }

◆ SaveAdaptiveToFile()

void ParameterHandlerBase::SaveAdaptiveToFile ( const std::string &  outFileName,
const std::string &  systematicName 
)
inline

Save adaptive throw matrix to file.

Definition at line 170 of file ParameterHandlerBase.h.

170  {
171  AdaptiveHandler->SaveAdaptiveToFile(outFileName, systematicName); }

◆ SaveUpdatedMatrixConfig()

void ParameterHandlerBase::SaveUpdatedMatrixConfig ( )

KS: After step scale, prefit etc. value were modified save this modified config.

Definition at line 1370 of file ParameterHandlerBase.cpp.

1370  {
1371 // ********************************************
1372  if (!_fYAMLDoc)
1373  {
1374  MACH3LOG_CRITICAL("Yaml node hasn't been initialised for matrix {}, something is not right", matrixName);
1375  MACH3LOG_CRITICAL("I am not throwing error but should be investigated");
1376  return;
1377  }
1378 
1379  YAML::Node copyNode = _fYAMLDoc;
1380  int i = 0;
1381 
1382  for (YAML::Node param : copyNode["Systematics"])
1383  {
1384  //KS: Feel free to update it, if you need updated prefit value etc
1385  param["Systematic"]["StepScale"] = M3::Utils::FormatDouble(_fIndivStepScale[i], 4);
1386  i++;
1387  }
1388  // Save the modified node to a file
1389  std::ofstream fout("Modified_Matrix.yaml");
1390  fout << copyNode;
1391  fout.close();
1392 }
std::string FormatDouble(const double value, const int precision)
Convert double into string for precision, useful for playing with yaml if you don't want to have in c...

◆ SetBranches()

void ParameterHandlerBase::SetBranches ( TTree &  tree,
const bool  SaveProposal = false 
)

set branches for output file

Parameters
treeTree to which we will save branches
SaveProposalNormally we only save parameter after is accepted, for debugging purpose it is helpful to see also proposed values. That's what this variable controls

Definition at line 832 of file ParameterHandlerBase.cpp.

832  {
833 // ********************************************
834  // loop over parameters and set a branch
835  for (int i = 0; i < _fNumPar; ++i) {
836  tree.Branch(_fNames[i].c_str(), &_fCurrVal[i], Form("%s/D", _fNames[i].c_str()));
837  }
838  // When running PCA, also save PCA parameters
839  if (pca) {
840  PCAObj->SetBranches(tree, SaveProposal, _fNames);
841  }
842  if(SaveProposal)
843  {
844  // loop over parameters and set a branch
845  for (int i = 0; i < _fNumPar; ++i) {
846  tree.Branch(Form("%s_Prop", _fNames[i].c_str()), &_fPropVal[i], Form("%s_Prop/D", _fNames[i].c_str()));
847  }
848  }
849  if(use_adaptive && AdaptiveHandler->GetUseRobbinsMonro()){
850  tree.Branch(Form("GlobalStepScale_%s", GetName().c_str()), &_fGlobalStepScale, Form("GlobalStepScale_%s/D", GetName().c_str()));
851  }
852 }

◆ SetCovMatrix()

void ParameterHandlerBase::SetCovMatrix ( TMatrixDSym *  cov)

Set covariance matrix.

Parameters
covCovariance matrix which we set and will be used later for evaluation of penalty term

Definition at line 305 of file ParameterHandlerBase.cpp.

305  {
306 // ********************************************
307  if (cov == nullptr) {
308  MACH3LOG_ERROR("Could not find covariance matrix you provided to {}", __func__ );
309  throw MaCh3Exception(__FILE__ , __LINE__ );
310  }
311  covMatrix = cov;
312 
313  invCovMatrix = static_cast<TMatrixDSym *>(cov->Clone());
314  invCovMatrix->Invert();
315  //KS: ROOT has bad memory management, using standard double means we can decrease most operation by factor 2 simply due to cache hits
316  for (int i = 0; i < _fNumPar; i++)
317  {
318  for (int j = 0; j < _fNumPar; ++j)
319  {
320  InvertCovMatrix[i][j] = (*invCovMatrix)(i,j);
321  }
322  }
323 
324  SetThrowMatrix(cov);
325 }

◆ SetFixAllParameters()

void ParameterHandlerBase::SetFixAllParameters ( )

Set all parameters to be fixed at prior values.

Definition at line 886 of file ParameterHandlerBase.cpp.

886  {
887 // ********************************************
888  // Check if the parameter is fixed and if not, toggle fix it
889  for (int i = 0; i < _fNumPar; ++i)
891 }
void ToggleFixParameter(const int i)
Toggle fixing parameter at prior values.

◆ SetFixParameter() [1/2]

void ParameterHandlerBase::SetFixParameter ( const int  i)

Set parameter to be fixed at prior value.

Parameters
iParameter index

Definition at line 894 of file ParameterHandlerBase.cpp.

894  {
895 // ********************************************
896  // Check if the parameter is fixed and if not, toggle fix it
898 }

◆ SetFixParameter() [2/2]

void ParameterHandlerBase::SetFixParameter ( const std::string &  name)

Set parameter to be fixed at prior value.

Parameters
nameName of the parameter to be fixed

Definition at line 901 of file ParameterHandlerBase.cpp.

901  {
902 // ********************************************
903  // Check if the parameter is fixed and if not, toggle fix it
904  if(!IsParameterFixed(name)) ToggleFixParameter(name);
905 }

◆ SetFlatPrior()

void ParameterHandlerBase::SetFlatPrior ( const int  i,
const bool  eL 
)

Set if parameter should have flat prior or not.

Parameters
iParameter index
eLbool telling if it will be flat or not

Definition at line 975 of file ParameterHandlerBase.cpp.

975  {
976 // ********************************************
977  if (i > _fNumPar) {
978  MACH3LOG_INFO("Can't {} for Cov={}/Param={} because size of Covariance = {}", __func__, GetName(), i, _fNumPar);
979  MACH3LOG_ERROR("Fix this in your config file please!");
980  throw MaCh3Exception(__FILE__ , __LINE__ );
981  } else {
982  if(eL){
983  MACH3LOG_INFO("Setting {} (parameter {}) to flat prior", GetParName(i), i);
984  }
985  else{
986  // HW :: This is useful
987  MACH3LOG_INFO("Setting {} (parameter {}) to non-flat prior", GetParName(i), i);
988  }
989  _fFlatPrior[i] = eL;
990  }
991 }

◆ SetFreeAllParameters()

void ParameterHandlerBase::SetFreeAllParameters ( )

Set all parameters to be treated as free.

Definition at line 908 of file ParameterHandlerBase.cpp.

908  {
909 // ********************************************
910  // Check if the parameter is fixed and if not, toggle fix it
911  for (int i = 0; i < _fNumPar; ++i)
913 }

◆ SetFreeParameter() [1/2]

void ParameterHandlerBase::SetFreeParameter ( const int  i)

Set parameter to be treated as free.

Parameters
iParameter index

Definition at line 916 of file ParameterHandlerBase.cpp.

916  {
917 // ********************************************
918  // Check if the parameter is fixed and if not, toggle fix it
920 }

◆ SetFreeParameter() [2/2]

void ParameterHandlerBase::SetFreeParameter ( const std::string &  name)

Set parameter to be treated as free.

Parameters
nameName of the parameter to be treated as free

Definition at line 923 of file ParameterHandlerBase.cpp.

923  {
924 // ********************************************
925  // Check if the parameter is fixed and if not, toggle fix it
926  if(IsParameterFixed(name)) ToggleFixParameter(name);
927 }

◆ SetIndivStepScale() [1/2]

void ParameterHandlerBase::SetIndivStepScale ( const int  ParameterIndex,
const double  StepScale 
)
inline

DB Function to set fIndivStepScale from a vector (Can be used from execs and inside covariance constructors)

Parameters
ParameterIndexParameter Index
StepScaleValue of individual step scale

Definition at line 93 of file ParameterHandlerBase.h.

93 { _fIndivStepScale.at(ParameterIndex) = StepScale; }

◆ SetIndivStepScale() [2/2]

void ParameterHandlerBase::SetIndivStepScale ( const std::vector< double > &  stepscale)

DB Function to set fIndivStepScale from a vector (Can be used from execs and inside covariance constructors)

Parameters
stepscaleVector of individual step scale, should have same

Definition at line 994 of file ParameterHandlerBase.cpp.

994  {
995 // ********************************************
996  if (static_cast<int>(stepscale.size()) != _fNumPar)
997  {
998  MACH3LOG_WARN("Stepscale vector not equal to number of parameters. Quitting..");
999  MACH3LOG_WARN("Size of argument vector: {}", stepscale.size());
1000  MACH3LOG_WARN("Expected size: {}", _fNumPar);
1001  return;
1002  }
1003 
1004  for (int iParam = 0 ; iParam < _fNumPar; iParam++) {
1005  _fIndivStepScale[iParam] = stepscale[iParam];
1006  }
1008 }
void PrintIndivStepScale() const
Print step scale for each parameter.

◆ SetIndivStepScaleForSkippedAdaptParams()

void ParameterHandlerBase::SetIndivStepScaleForSkippedAdaptParams ( )

Set individual step scale for parameters which are skipped during adaption to initial values.

Definition at line 1050 of file ParameterHandlerBase.cpp.

1050  {
1051 // ********************************************
1052  if (!param_skip_adapt_flags.size()) {
1053  MACH3LOG_ERROR("Parameter skip adapt flags not set, cannot set individual step scales for skipped parameters.");
1054  throw MaCh3Exception(__FILE__ , __LINE__ );
1055  }
1056  // HH: Cancel the effect of global step scale change for parameters that are not adapting
1057  for (int i = 0; i <_fNumPar; i++) {
1058  if (param_skip_adapt_flags[i]) {
1060  }
1061  }
1062  MACH3LOG_DEBUG("Updating individual step scales for non-adapting parameters to cancel global step scale change.");
1063  MACH3LOG_DEBUG("Global step scale initial: {}, current: {}", _fGlobalStepScaleInitial, _fGlobalStepScale);
1064 }

◆ SetName()

void ParameterHandlerBase::SetName ( const std::string &  name)
inline

Set matrix name.

Definition at line 43 of file ParameterHandlerBase.h.

43 { matrixName = name; }

◆ SetNumberOfSteps()

void ParameterHandlerBase::SetNumberOfSteps ( const int  nsteps)
inline

Set number of MCMC step, when running adaptive MCMC it is updated with given frequency. We need number of steps to determine frequency.

Definition at line 181 of file ParameterHandlerBase.h.

181  {
182  AdaptiveHandler->SetTotalSteps(nsteps);
183  if(AdaptiveHandler->AdaptionUpdate()) ResetIndivStepScale();
184  }

◆ SetPar()

void ParameterHandlerBase::SetPar ( const int  i,
const double  val 
)

Set all the covariance matrix parameters to a user-defined value.

Parameters
iParameter index
valnew value which will be set

Definition at line 371 of file ParameterHandlerBase.cpp.

371  {
372 // ********************************************
373  MACH3LOG_DEBUG("Over-riding {}: _fPropVal ({}), _fCurrVal ({}), _fPreFitValue ({}) to ({})",
374  GetParFancyName(i), _fPropVal[i], _fCurrVal[i], _fPreFitValue[i], val);
375 
376  _fPropVal[i] = static_cast<M3::float_t>(val);
377  _fCurrVal[i] = val;
378  _fPreFitValue[i] = val;
379 
380  // Transfer the parameter values to the PCA basis
381  if (pca) PCAObj->TransferToPCA();
382 }

◆ SetParameters()

void ParameterHandlerBase::SetParameters ( const std::vector< double > &  pars = {})

Set parameter values using vector, it has to have same size as covariance class.

Parameters
parsVector holding new values for every parameter

Definition at line 797 of file ParameterHandlerBase.cpp.

797  {
798 // ********************************************
799  #pragma GCC diagnostic push
800  #pragma GCC diagnostic ignored "-Wuseless-cast"
801  // If empty, set the proposed to prior
802  if (pars.empty()) {
803  for (int i = 0; i < _fNumPar; i++) {
804  _fPropVal[i] = static_cast<M3::float_t>(_fPreFitValue[i]);
805  }
806  // If not empty, set the parameters to the specified
807  } else {
808  if (pars.size() != static_cast<size_t>(_fNumPar)) {
809  MACH3LOG_ERROR("Parameter arrays of incompatible size! Not changing parameters! {} has size {} but was expecting {}", matrixName, pars.size(), _fNumPar);
810  throw MaCh3Exception(__FILE__ , __LINE__ );
811  }
812  int parsSize = int(pars.size());
813  for (int i = 0; i < parsSize; i++) {
814  //Make sure that you are actually passing a number to set the parameter to
815  if(std::isnan(pars[i])) {
816  MACH3LOG_ERROR("Trying to set parameter value to a nan for parameter {} in matrix {}. This will not go well!", GetParName(i), matrixName);
817  throw MaCh3Exception(__FILE__ , __LINE__ );
818  } else {
819  _fPropVal[i] = static_cast<M3::float_t>(pars[i]);
820  }
821  }
822  }
823  // And if pca make the transfer
824  if (pca) {
825  PCAObj->TransferToPCA();
826  PCAObj->TransferToParam();
827  }
828  #pragma GCC diagnostic pop
829 }

◆ SetParCurrProp()

void ParameterHandlerBase::SetParCurrProp ( const int  i,
const double  val 
)

Set current parameter value.

Parameters
iParameter index
valnew value which will be set

Definition at line 504 of file ParameterHandlerBase.cpp.

504  {
505 // ********************************************
506  _fPropVal[parNo] = static_cast<M3::float_t>(parVal);
507  _fCurrVal[parNo] = parVal;
508  MACH3LOG_DEBUG("Setting {} (parameter {}) to {})", GetParFancyName(parNo), parNo, parVal);
509  if (pca) PCAObj->TransferToPCA();
510 }

◆ SetParName()

void ParameterHandlerBase::SetParName ( const int  i,
const std::string &  name 
)
inline

change parameter name

Parameters
iParameter index
namenew name which will be set

Definition at line 47 of file ParameterHandlerBase.h.

47 { _fNames.at(i) = name; }

◆ SetParProp()

void ParameterHandlerBase::SetParProp ( const int  i,
const double  val 
)
inline

Set proposed parameter value.

Parameters
iParameter index
valnew value which will be set

Definition at line 61 of file ParameterHandlerBase.h.

61  {
62  _fPropVal[i] = static_cast<M3::float_t>(val);
63  if (pca) PCAObj->TransferToPCA();
64  }

◆ SetRandomThrow()

void ParameterHandlerBase::SetRandomThrow ( const int  i,
const double  rand 
)
inline

Set random value useful for debugging/CI.

Parameters
iParameter index
randNew value for random number

Definition at line 76 of file ParameterHandlerBase.h.

76 { randParams[i] = rand;}

◆ SetSingleParameter()

void ParameterHandlerBase::SetSingleParameter ( const int  parNo,
const double  parVal 
)

Set value of single param to a given value.

Definition at line 495 of file ParameterHandlerBase.cpp.

495  {
496 // *************************************
497  _fPropVal[parNo] = static_cast<M3::float_t>(parVal);
498  _fCurrVal[parNo] = parVal;
499  MACH3LOG_DEBUG("Setting {} (parameter {}) to {})", GetParFancyName(parNo), parNo, parVal);
500  if (pca) PCAObj->TransferToPCA();
501 }

◆ SetStepScale()

void ParameterHandlerBase::SetStepScale ( const double  scale,
const bool  verbose = true 
)

Set global step scale for covariance object.

Parameters
scaleValue of global step scale
verbosePrint that we've changed scale + use warnings [default: true] [28]

Definition at line 855 of file ParameterHandlerBase.cpp.

855  {
856 // ********************************************
857  if(scale <= 0) {
858  MACH3LOG_ERROR("You are trying so set StepScale to 0 or negative this will not work");
859  throw MaCh3Exception(__FILE__ , __LINE__ );
860  }
861 
862  if(verbose){
863  MACH3LOG_INFO("{} setStepScale() = {}", GetName(), scale);
864  const double SuggestedScale = 2.38/std::sqrt(_fNumPar);
865  if(std::fabs(scale - SuggestedScale)/SuggestedScale > 1) {
866  MACH3LOG_WARN("Defined Global StepScale is {}, while suggested suggested {}", scale, SuggestedScale);
867  }
868  }
869  _fGlobalStepScale = scale;
870 }

◆ SetSubThrowMatrix()

void ParameterHandlerBase::SetSubThrowMatrix ( int  first_index,
int  last_index,
TMatrixDSym const &  subcov 
)

Definition at line 1106 of file ParameterHandlerBase.cpp.

1107  {
1108 // ********************************************
1109  if ((last_index - first_index) >= subcov.GetNrows()) {
1110  MACH3LOG_ERROR("Trying to SetSubThrowMatrix into range: ({},{}) with a "
1111  "submatrix with only {} rows {}",
1112  first_index, last_index, subcov.GetNrows(), __func__);
1113  throw MaCh3Exception(__FILE__, __LINE__);
1114  }
1115 
1116  TMatrixDSym *current_ThrowMatrix =
1117  static_cast<TMatrixDSym *>(throwMatrix->Clone());
1118  for (int i = first_index; i <= last_index; ++i) {
1119  for (int j = first_index; j <= last_index; ++j) {
1120  current_ThrowMatrix->operator()(i, j) =
1121  subcov(i - first_index, j - first_index);
1122  }
1123  }
1124 
1125  SetThrowMatrix(current_ThrowMatrix);
1126  delete current_ThrowMatrix;
1127 }

◆ SetThrowMatrix()

void ParameterHandlerBase::SetThrowMatrix ( const TMatrixDSym *  cov)

Use new throw matrix, used in adaptive MCMC.

Definition at line 1068 of file ParameterHandlerBase.cpp.

1068  {
1069 // ********************************************
1070  if (cov == nullptr) {
1071  MACH3LOG_ERROR("Could not find covariance matrix you provided to {}", __func__);
1072  throw MaCh3Exception(__FILE__ , __LINE__ );
1073  }
1074 
1075  if (covMatrix->GetNrows() != cov->GetNrows()) {
1076  MACH3LOG_ERROR("Matrix given for throw Matrix is not the same size as the covariance matrix stored in object!");
1077  MACH3LOG_ERROR("Stored covariance matrix size: {}", covMatrix->GetNrows());
1078  MACH3LOG_ERROR("Given matrix size: {}", cov->GetNrows());
1079  throw MaCh3Exception(__FILE__ , __LINE__ );
1080  }
1081 
1082  throwMatrix = static_cast<TMatrixDSym*>(cov->Clone());
1083  if(use_adaptive && AdaptiveHandler->AdaptionUpdate()) MakeClosestPosDef(throwMatrix);
1084  else {
1085  // HW: Prevent spam from adaptive handler
1086  bool verbose = AdaptiveHandler ? AdaptiveHandler->GetTotalSteps() < 2 : true;
1087  MakePosDef(throwMatrix, verbose);
1088  }
1089 
1090  auto throwMatrix_CholDecomp = M3::GetCholeskyDecomposedMatrix(*throwMatrix, matrixName);
1091 
1092  //KS: ROOT has bad memory management, using standard double means we can decrease most operation by factor 2 simply due to cache hits
1093  #ifdef MULTITHREAD
1094  #pragma omp parallel for collapse(2)
1095  #endif
1096  for (int i = 0; i < _fNumPar; ++i)
1097  {
1098  for (int j = 0; j < _fNumPar; ++j)
1099  {
1100  throwMatrixCholDecomp[i][j] = throwMatrix_CholDecomp[i][j];
1101  }
1102  }
1103 }
void MakeClosestPosDef(TMatrixDSym *cov)
HW: Finds closest possible positive definite matrix in Frobenius Norm ||.||_frob Where ||X||_frob=sqr...
std::vector< std::vector< double > > GetCholeskyDecomposedMatrix(const TMatrixDSym &matrix, const std::string &matrixName)
Computes Cholesky decomposition of a symmetric positive definite matrix using custom function which c...

◆ SetThrowMatrixFromFile()

void ParameterHandlerBase::SetThrowMatrixFromFile ( const std::string &  matrix_file_name,
const std::string &  matrix_name,
const std::string &  means_name 
)
protected

sets throw matrix from a file

Parameters
matrix_file_namename of file matrix lives in
matrix_namename of matrix in file
means_namename of means vec in file

◆ SetTune()

void ParameterHandlerBase::SetTune ( const std::string &  TuneName)

KS: Set proposed parameter values vector to be base on tune values, for example set proposed values to be of generated or maybe PostND.

Definition at line 1396 of file ParameterHandlerBase.cpp.

1396  {
1397 // ********************************************
1398  if(Tunes == nullptr) {
1399  MACH3LOG_ERROR("Tunes haven't been initialised, which are being loaded from YAML, have you used some deprecated constructor");
1400  throw MaCh3Exception(__FILE__, __LINE__);
1401  }
1402  auto Values = Tunes->GetTune(TuneName);
1403 
1404  SetParameters(Values);
1405 }
std::unique_ptr< ParameterTunes > Tunes
Struct containing information about adaption.
void SetParameters(const std::vector< double > &pars={})
Set parameter values using vector, it has to have same size as covariance class.

◆ SpecialStepProposal()

void ParameterHandlerBase::SpecialStepProposal ( )
protected

Perform Special Step Proposal.

Warning
KS: Following Asher comment we do "Step->Circular Bounds->Flip"
Warning
KS: Following Asher comment we do "Step->Circular Bounds->Flip"

Definition at line 529 of file ParameterHandlerBase.cpp.

529  {
530 // ************************************************
532 
533  // HW It should now automatically set dcp to be with [-pi, pi]
534  for (size_t i = 0; i < CircularBoundsIndex.size(); ++i) {
535  const int index = CircularBoundsIndex[i];
536  if(!IsParameterFixed(index))
537  CircularParBounds(index, CircularBoundsValues[i].first, CircularBoundsValues[i].second);
538  }
539 
540  // // Okay now we've done the standard steps, we can add in our nice flips hierarchy flip first
541  for (const auto& [group_name, group] : FlipGroups) {
542  FlipParameterGroup(group_name);
543  }
544 }
void FlipParameterGroup(const std::string &group)
With a 50% chance, flip all parameters in a group around their respective flip points.
void CircularParBounds(const int i, const double LowBound, const double UpBound)
HW :: This method is a tad hacky but modular arithmetic gives me a headache.

◆ ThrowParameters()

void ParameterHandlerBase::ThrowParameters ( )

Throw the parameters according to the covariance matrix. This shouldn't be used in MCMC code ase it can break Detailed Balance;.

Definition at line 395 of file ParameterHandlerBase.cpp.

395  {
396 // *************************************
397  // First draw new randParams
398  Randomize();
399 
401  #pragma GCC diagnostic push
402  #pragma GCC diagnostic ignored "-Wuseless-cast"
403  // KS: We use PCA very rarely on top PCA functionality isn't implemented for this function.
404  // Use __builtin_expect to give compiler a hint which option is more likely, which should help
405  // with better optimisation. This isn't critical but more to have example
406  if (__builtin_expect(!pca, 1)) {
407  #ifdef MULTITHREAD
408  #pragma omp parallel for
409  #endif
410  for (int i = 0; i < _fNumPar; ++i) {
411  // Check if parameter is fixed first: if so don't randomly throw
412  if (IsParameterFixed(i)) continue;
413  _fPropVal[i] = static_cast<M3::float_t>(_fPreFitValue[i] + corr_throw[i]);
414 
415  int throws = 0;
416  // Try again if we the initial parameter proposal falls outside of the range of the parameter
417  while (_fPropVal[i] > _fUpBound[i] || _fPropVal[i] < _fLowBound[i]) {
418  randParams[i] = M3::rand::Gaus(0, 1);
419  const double corr_throw_single = M3::MatrixVectorMultiSingle(throwMatrixCholDecomp, randParams, _fNumPar, i);
420  _fPropVal[i] = static_cast<M3::float_t>(_fPreFitValue[i] + corr_throw_single);
421  if (throws > 10000)
422  {
423  //KS: Since we are multithreading there is danger that those messages
424  //will be all over the place, small price to pay for faster code
425  MACH3LOG_WARN("Tried {} times to throw parameter {} but failed", throws, i);
426  MACH3LOG_WARN("Matrix: {}", matrixName);
427  MACH3LOG_WARN("Param: {}", _fNames[i]);
428  MACH3LOG_WARN("Setting _fPropVal: {} to {}", _fPropVal[i], _fPreFitValue[i]);
429  MACH3LOG_WARN("I live at {}:{}", __FILE__, __LINE__);
430  _fPropVal[i] = static_cast<M3::float_t>(_fPreFitValue[i]);
431  //throw MaCh3Exception(__FILE__ , __LINE__ );
432  }
433  throws++;
434  }
435  _fCurrVal[i] = _fPropVal[i];
436  }
437  }
438  else
439  {
440  PCAObj->ThrowParameters(throwMatrixCholDecomp,
443  } // end if pca
444  #pragma GCC diagnostic pop
445  // KS: At the end once we are happy with proposal do special proposal
447 }
double MatrixVectorMultiSingle(double **_restrict_ matrix, const double *_restrict_ vector, const int Length, const int i)
KS: Custom function to perform multiplication of matrix and single element which is thread safe.

◆ ToggleFixParameter() [1/2]

void ParameterHandlerBase::ToggleFixParameter ( const int  i)
private

Toggle fixing parameter at prior values.

Parameters
iParameter index

Definition at line 930 of file ParameterHandlerBase.cpp.

930  {
931 // ********************************************
932  if(!pca) {
933  if (i > _fNumPar) {
934  MACH3LOG_ERROR("Can't {} for parameter {} because size of covariance ={}", __func__, i, _fNumPar);
935  MACH3LOG_ERROR("Fix this in your config file please!");
936  throw MaCh3Exception(__FILE__ , __LINE__ );
937  } else {
938  _fError[i] *= -1.0;
939  if(IsParameterFixed(i)) MACH3LOG_INFO("Setting {}(parameter {}) to fixed at {}", GetParFancyName(i), i, _fCurrVal[i]);
940  else MACH3LOG_INFO("Setting {}(parameter {}) free", GetParFancyName(i), i);
941  }
942  if( (_fCurrVal[i] > _fUpBound[i] || _fCurrVal[i] < _fLowBound[i]) && IsParameterFixed(i) ) {
943  MACH3LOG_ERROR("Parameter {} (index {}) is fixed at {}, which is outside of its bounds [{}, {}]", GetParFancyName(i), i, _fCurrVal[i], _fLowBound[i], _fUpBound[i]);
944  throw MaCh3Exception(__FILE__ , __LINE__ );
945  }
946  } else {
947  PCAObj->ToggleFixParameter(i, _fNames);
948  }
949 }

◆ ToggleFixParameter() [2/2]

void ParameterHandlerBase::ToggleFixParameter ( const std::string &  name)
private

Toggle fixing parameter at prior values.

Parameters
nameName of parameter you want to fix

Definition at line 952 of file ParameterHandlerBase.cpp.

952  {
953 // ********************************************
954  const int Index = GetParIndex(name);
955  if(Index != M3::_BAD_INT_) {
956  ToggleFixParameter(Index);
957  return;
958  }
959  MACH3LOG_WARN("I couldn't find parameter with name {}, therefore will not fix it", name);
960 }

◆ UpdateAdaptiveCovariance()

void ParameterHandlerBase::UpdateAdaptiveCovariance ( )

Method to update adaptive MCMC [17].

Need to adjust the scale every step

Definition at line 1249 of file ParameterHandlerBase.cpp.

1249  {
1250 // ********************************************
1251  // Updates adaptive matrix
1252  // First we update the total means
1253 
1254  // Skip this if we're at a large number of steps
1255  if(AdaptiveHandler->SkipAdaption()) {
1256  AdaptiveHandler->IncrementNSteps();
1257  return;
1258  }
1259 
1261  if(AdaptiveHandler->GetStartRobbinsMonro()){
1262  bool verbose=false;
1263  #ifdef MACH3_DEBUG
1264  verbose=true;
1265  #endif
1266  AdaptiveHandler->UpdateRobbinsMonroScale();
1267  SetStepScale(AdaptiveHandler->GetAdaptionScale(), verbose);
1269  }
1270 
1271  // Call main adaption function
1272  AdaptiveHandler->UpdateAdaptiveCovariance();
1273 
1274  // Set scales to 1 * optimal scale
1275  if(AdaptiveHandler->IndivStepScaleAdapt()) {
1277  SetStepScale(AdaptiveHandler->GetAdaptionScale());
1279  }
1280 
1281  if(AdaptiveHandler->UpdateMatrixAdapt()) {
1282  TMatrixDSym* update_matrix = static_cast<TMatrixDSym*>(AdaptiveHandler->GetAdaptiveCovariance()->Clone());
1283  UpdateThrowMatrix(update_matrix); //Now we update and continue!
1284  //Also Save the adaptive to file
1285  AdaptiveHandler->SaveAdaptiveToFile(AdaptiveHandler->GetOutFileName(), GetName());
1286  }
1287 
1288  AdaptiveHandler->IncrementNSteps();
1289 }
void SetStepScale(const double scale, const bool verbose=true)
Set global step scale for covariance object.
void UpdateThrowMatrix(TMatrixDSym *cov)
Replaces old throw matrix with new one.

◆ UpdateThrowMatrix()

void ParameterHandlerBase::UpdateThrowMatrix ( TMatrixDSym *  cov)

Replaces old throw matrix with new one.

Definition at line 1130 of file ParameterHandlerBase.cpp.

1130  {
1131 // ********************************************
1132  delete throwMatrix;
1133  throwMatrix = nullptr;
1134  SetThrowMatrix(cov);
1135 }

Member Data Documentation

◆ _fCurrVal

std::vector<double> ParameterHandlerBase::_fCurrVal
protected

Current value of the parameter.

Definition at line 429 of file ParameterHandlerBase.h.

◆ _fError

std::vector<double> ParameterHandlerBase::_fError
protected

Prior error on the parameter.

Definition at line 433 of file ParameterHandlerBase.h.

◆ _fFancyNames

std::vector<std::string> ParameterHandlerBase::_fFancyNames
protected

Fancy name for example rather than param_0 it is MAQE, useful for human reading.

Definition at line 421 of file ParameterHandlerBase.h.

◆ _fFlatPrior

std::vector<bool> ParameterHandlerBase::_fFlatPrior
protected

Whether to apply flat prior or not.

Definition at line 441 of file ParameterHandlerBase.h.

◆ _fGlobalStepScale

double ParameterHandlerBase::_fGlobalStepScale
protected

Global step scale applied to all params in this class.

Definition at line 416 of file ParameterHandlerBase.h.

◆ _fGlobalStepScaleInitial

double ParameterHandlerBase::_fGlobalStepScaleInitial
protected

Backup of _fGlobalStepScale for parameters which are skipped during adaption.

Definition at line 447 of file ParameterHandlerBase.h.

◆ _fIndivStepScale

std::vector<double> ParameterHandlerBase::_fIndivStepScale
protected

Individual step scale used by MCMC algorithm.

Definition at line 439 of file ParameterHandlerBase.h.

◆ _fIndivStepScaleInitial

std::vector<double> ParameterHandlerBase::_fIndivStepScaleInitial
protected

Backup of _fIndivStepScale for parameters which are skipped during adaption.

Definition at line 444 of file ParameterHandlerBase.h.

◆ _fLowBound

std::vector<double> ParameterHandlerBase::_fLowBound
protected

Lowest physical bound, parameter will not be able to go beyond it.

Definition at line 435 of file ParameterHandlerBase.h.

◆ _fNames

std::vector<std::string> ParameterHandlerBase::_fNames
protected

ETA _fNames is set automatically in the covariance class to be something like param_i, this is currently to make things compatible with the Diagnostic tools.

Definition at line 419 of file ParameterHandlerBase.h.

◆ _fNumPar

int ParameterHandlerBase::_fNumPar
protected

Number of systematic parameters.

Definition at line 425 of file ParameterHandlerBase.h.

◆ _fPreFitValue

std::vector<double> ParameterHandlerBase::_fPreFitValue
protected

Parameter value dictated by the prior model. Based on it penalty term is calculated.

Definition at line 427 of file ParameterHandlerBase.h.

◆ _fPropVal

std::vector<M3::float_t> ParameterHandlerBase::_fPropVal
protected

Proposed value of the parameter.

Definition at line 431 of file ParameterHandlerBase.h.

◆ _fUpBound

std::vector<double> ParameterHandlerBase::_fUpBound
protected

Upper physical bound, parameter will not be able to go beyond it.

Definition at line 437 of file ParameterHandlerBase.h.

◆ _fYAMLDoc

YAML::Node ParameterHandlerBase::_fYAMLDoc
protected

Stores config describing systematics.

Definition at line 423 of file ParameterHandlerBase.h.

◆ AdaptiveHandler

std::unique_ptr<AdaptiveMCMCHandler> ParameterHandlerBase::AdaptiveHandler
protected

Struct containing information about adaption.

Definition at line 465 of file ParameterHandlerBase.h.

◆ CircularBoundsIndex

std::vector<int> ParameterHandlerBase::CircularBoundsIndex
protected

Indices of parameters with circular bounds.

Definition at line 474 of file ParameterHandlerBase.h.

◆ CircularBoundsValues

std::vector<std::pair<double,double> > ParameterHandlerBase::CircularBoundsValues
protected

Circular bounds for each parameter (lower, upper)

Definition at line 476 of file ParameterHandlerBase.h.

◆ corr_throw

double* ParameterHandlerBase::corr_throw
protected

Result of multiplication of Cholesky matrix and randParams.

Definition at line 414 of file ParameterHandlerBase.h.

◆ covMatrix

TMatrixDSym* ParameterHandlerBase::covMatrix
protected

The covariance matrix.

Definition at line 405 of file ParameterHandlerBase.h.

◆ doSpecialStepProposal

bool ParameterHandlerBase::doSpecialStepProposal
protected

Check if any of special step proposal were enabled.

Definition at line 397 of file ParameterHandlerBase.h.

◆ FlipGroups

std::map<std::string, FlipGroup> ParameterHandlerBase::FlipGroups
protected

Map of flip groups, where the key is the group name and the value is a FlipGroup struct.

Definition at line 470 of file ParameterHandlerBase.h.

◆ inputFile

std::string ParameterHandlerBase::inputFile
protected

The input root file we read in.

Definition at line 400 of file ParameterHandlerBase.h.

◆ invCovMatrix

TMatrixDSym* ParameterHandlerBase::invCovMatrix
protected

The inverse covariance matrix.

Definition at line 407 of file ParameterHandlerBase.h.

◆ InvertCovMatrix

std::vector<std::vector<double> > ParameterHandlerBase::InvertCovMatrix
protected

KS: Same as above but much faster as TMatrixDSym cache miss.

Definition at line 409 of file ParameterHandlerBase.h.

◆ matrixName

std::string ParameterHandlerBase::matrixName
protected

Name of cov matrix.

Definition at line 403 of file ParameterHandlerBase.h.

◆ param_skip_adapt_flags

std::vector<bool> ParameterHandlerBase::param_skip_adapt_flags
protected

Flags telling if parameter should be skipped during adaption.

Definition at line 450 of file ParameterHandlerBase.h.

◆ pca

bool ParameterHandlerBase::pca
protected

perform PCA or not

Definition at line 458 of file ParameterHandlerBase.h.

◆ PCAObj

std::unique_ptr<PCAHandler> ParameterHandlerBase::PCAObj
protected

Struct containing information about PCA.

Definition at line 463 of file ParameterHandlerBase.h.

◆ PendingFunctionalFlipParameters

std::vector<PendingFunctionalFlipProposal> ParameterHandlerBase::PendingFunctionalFlipParameters
protected

Functional flips waiting for full parameter-name registration.

Definition at line 472 of file ParameterHandlerBase.h.

◆ randParams

double* ParameterHandlerBase::randParams
protected

Random number taken from gaussian around prior error used for corr_throw.

Definition at line 412 of file ParameterHandlerBase.h.

◆ throwMatrix

TMatrixDSym* ParameterHandlerBase::throwMatrix
protected

Matrix which we use for step proposal before Cholesky decomposition (not actually used for step proposal)

Definition at line 453 of file ParameterHandlerBase.h.

◆ throwMatrixCholDecomp

double** ParameterHandlerBase::throwMatrixCholDecomp
protected

Throw matrix that is being used in the fit, much faster as TMatrixDSym cache miss.

Definition at line 455 of file ParameterHandlerBase.h.

◆ Tunes

std::unique_ptr<ParameterTunes> ParameterHandlerBase::Tunes
protected

Struct containing information about adaption.

Definition at line 467 of file ParameterHandlerBase.h.

◆ use_adaptive

bool ParameterHandlerBase::use_adaptive
protected

Are we using AMCMC?

Definition at line 460 of file ParameterHandlerBase.h.


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