MaCh3  2.2.3
Reference Guide
MinuitFit.cpp
Go to the documentation of this file.
1 #include "MinuitFit.h"
2 
3 // *******************
4 // Run the Minuit Fit with all the systematic objects added
6 // *******************
7  AlgorithmName = "MinuitFit";
9  // Minimizer type: determines the underlying implementation.
10  // Available types include:
11  // - "Minuit2" (recommended modern option)
12  // - "Minuit" (legacy)
13  // - "Fumili"
14  // - "GSLMultiMin" (for gradient-free minimization)
15  // - "GSLMultiFit"
16  // - "GSLSimAn" (Simulated Annealing)
17  const std::string MinimizerType = "Minuit2";
18  // Minimizer algorithm (specific to the selected type).
19  // For Minuit2, the following algorithms are available:
20  // - "Migrad" : gradient-based minimization (default)
21  // - "Simplex" : Nelder-Mead simplex method (derivative-free)
22  // - "Combined" : combination of Simplex and Migrad
23  // - "Scan" : parameter grid scan
24  const std::string MinimizerAlgo = "Migrad";
25 
26  MACH3LOG_INFO("Creating instance of Minimizer with {} and {}", MinimizerType, MinimizerAlgo);
27 
28  minuit = std::unique_ptr<ROOT::Math::Minimizer>(
29  ROOT::Math::Factory::CreateMinimizer(MinimizerType.c_str(), MinimizerAlgo.c_str()));
30 }
31 
32 // *************************
33 // Destructor: close the logger and output file
35 // *************************
36 }
37 
38 
39 // *******************
40 // Run the Minuit with all the systematic objects added
42 // *******************
43  PrepareFit();
44 
45  // Remove obsolete memory and make other checks before fit starts
47 
48  //KS: For none PCA this will be equal to normal parameters
49  const int NparsMinuitFull = NPars;
50  const int NparsMinuit = NParsPCA;
51 
52  //KS: Set SetFunction we will Minimize
53  ROOT::Math::Functor fChi2(this, &MinuitFit::CalcChi2, NparsMinuit);
54  minuit->SetFunction(fChi2);
55 
56  //KS: add config or something
57  minuit->SetPrintLevel(2);
58  minuit->SetTolerance(0.01);
59  minuit->SetMaxFunctionCalls(fitMan->raw()["General"]["Minuit2"]["NSteps"].as<unsigned>());
60  minuit->SetMaxIterations(10000);
61 
62  MACH3LOG_INFO("Preparing Minuit");
63  int ParCounter = 0;
64 
65  for (std::vector<ParameterHandlerBase*>::iterator it = systematics.begin(); it != systematics.end(); ++it)
66  {
67  if(!(*it)->IsPCA())
68  {
69  for(int i = 0; i < (*it)->GetNumParams(); ++i, ++ParCounter)
70  {
71  //KS: Index, name, prior, step scale [different to MCMC],
72  minuit->SetVariable(ParCounter, ((*it)->GetParName(i)), (*it)->GetParInit(i), (*it)->GetDiagonalError(i)/10);
73  minuit->SetVariableValue(ParCounter, (*it)->GetParInit(i));
74  //KS: lower bound, upper bound, if Mirroring enabled then ignore
75  if(!fMirroring) minuit->SetVariableLimits(ParCounter, (*it)->GetLowerBound(i), (*it)->GetUpperBound(i));
76  if((*it)->IsParameterFixed(i))
77  {
78  minuit->FixVariable(ParCounter);
79  }
80  }
81  }
82  else
83  {
84  for(int i = 0; i < (*it)->GetNParameters(); ++i, ++ParCounter)
85  {
86  minuit->SetVariable(ParCounter, Form("%i_PCA", i), (*it)->GetPCAHandler()->GetParPropPCA(i), (*it)->GetPCAHandler()->GetEigenValuesMaster()[i]/10);
87  if((*it)->GetPCAHandler()->IsParameterFixedPCA(i))
88  {
89  minuit->FixVariable(ParCounter);
90  }
91  }
92  }
93  }
94 
95  minuit->SetPrintLevel(2);
96 
97  MACH3LOG_INFO("Starting MIGRAD");
98  minuit->Minimize();
99 
100  MACH3LOG_INFO("Starting HESSE");
101  minuit->Hesse();
102  outputFile->cd();
103 
104  TVectorD* MinuitParValue = new TVectorD(NparsMinuitFull);
105  TVectorD* MinuitParError = new TVectorD(NparsMinuitFull);
106  TMatrixDSym* Postmatrix = new TMatrixDSym(NparsMinuitFull);
107 
108  for(int i = 0; i < NparsMinuitFull; ++i)
109  {
110  (*MinuitParValue)(i) = 0;
111  (*MinuitParError)(i) = 0;
112  for(int j = 0; j < NparsMinuitFull; ++j)
113  {
114  (*Postmatrix)(i,j) = 0;
115  (*Postmatrix)(i,j) = minuit->CovMatrix(i,j);
116  }
117  }
118 
119  ParCounter = 0;
120  const double *X = minuit->X();
121  const double *err = minuit->Errors();
122  for (std::vector<ParameterHandlerBase*>::iterator it = systematics.begin(); it != systematics.end(); ++it)
123  {
124  if(!(*it)->IsPCA())
125  {
126  for(int i = 0; i < (*it)->GetNumParams(); ++i, ++ParCounter)
127  {
128  double ParVal = X[ParCounter];
129  //KS: Basically apply mirroring for parameters out of bounds
130  if(fMirroring)
131  {
132  if(ParVal < (*it)->GetLowerBound(i))
133  {
134  ParVal = (*it)->GetLowerBound(i) + ((*it)->GetLowerBound(i) - ParVal);
135  }
136  else if (ParVal > (*it)->GetUpperBound(i))
137  {
138  ParVal = (*it)->GetUpperBound(i) - ( ParVal - (*it)->GetUpperBound(i));
139  }
140  }
141  (*MinuitParValue)(ParCounter) = ParVal;
142  (*MinuitParError)(ParCounter) = err[ParCounter];
143  //KS: For fixed params HESS will not calculate error so we need to pass prior error
144  if((*it)->IsParameterFixed(i))
145  {
146  (*MinuitParError)(ParCounter) = (*it)->GetDiagonalError(i);
147  (*Postmatrix)(ParCounter,ParCounter) = (*MinuitParError)(ParCounter) * (*MinuitParError)(ParCounter);
148  }
149  }
150  }
151  else
152  {
153  //KS: We need to convert parameters from PCA to normal base
154  TVectorD ParVals((*it)->GetNumParams());
155  TVectorD ParVals_PCA((*it)->GetNParameters());
156 
157  TVectorD ErrorVals((*it)->GetNumParams());
158  TVectorD ErrorVals_PCA((*it)->GetNParameters());
159 
160  TMatrixD MatrixVals((*it)->GetNumParams(), (*it)->GetNumParams());
161  TMatrixD MatrixVals_PCA((*it)->GetNParameters(), (*it)->GetNParameters());
162 
163  //First save them
164  //KS: This code is super convoluted as MaCh3 can store separate matrices while Minuit has one matrix. In future this will be simplified, keep it like this for now.
165  const int StartVal = ParCounter;
166  for(int i = 0; i < (*it)->GetNParameters(); ++i, ++ParCounter)
167  {
168  ParVals_PCA(i) = X[ParCounter];
169  ErrorVals_PCA(i) = err[ParCounter];
170  int ParCounterMatrix = StartVal;
171  for(int j = 0; j < (*it)->GetNParameters(); ++j, ++ParCounterMatrix)
172  {
173  MatrixVals_PCA(i,j) = minuit->CovMatrix(ParCounter,ParCounterMatrix);
174  }
175  }
176  ParVals = ((*it)->GetPCAHandler()->GetTransferMatrix())*ParVals_PCA;
177  ErrorVals = ((*it)->GetPCAHandler()->GetTransferMatrix())*ErrorVals_PCA;
178  MatrixVals.Mult(((*it)->GetPCAHandler()->GetTransferMatrix()),MatrixVals_PCA);
179 
180  ParCounter = StartVal;
181  //KS: Now after going from PCA to normal let';s save it
182  for(int i = 0; i < (*it)->GetNumParams(); ++i, ++ParCounter)
183  {
184  (*MinuitParValue)(ParCounter) = ParVals(i);
185  (*MinuitParError)(ParCounter) = std::fabs(ErrorVals(i));
186  int ParCounterMatrix = StartVal;
187  for(int j = 0; j < (*it)->GetNumParams(); ++j, ++ParCounterMatrix)
188  {
189  (*Postmatrix)(ParCounter,ParCounterMatrix) = MatrixVals(i,j);
190  }
191  //If fixed take prior
192  if((*it)->GetPCAHandler()->IsParameterFixedPCA(i))
193  {
194  (*MinuitParError)(ParCounter) = (*it)->GetDiagonalError(i);
195  (*Postmatrix)(ParCounter,ParCounter) = (*MinuitParError)(ParCounter) * (*MinuitParError)(ParCounter);
196  }
197  }
198  }
199  }
200 
201  MinuitParValue->Write("MinuitParValue");
202  MinuitParError->Write("MinuitParError");
203  Postmatrix->Write("Postmatrix");
204  delete MinuitParValue;
205  delete MinuitParError;
206  delete Postmatrix;
207  // Save all the output
208  SaveOutput();
209 }
210 
MaCh3Plotting::PlottingManager * man
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:25
void SaveOutput()
Save output and close files.
Definition: FitterBase.cpp:230
TFile * outputFile
Output.
Definition: FitterBase.h:149
manager * fitMan
The manager.
Definition: FitterBase.h:110
std::string AlgorithmName
Name of fitting algorithm that is being used.
Definition: FitterBase.h:170
void SanitiseInputs()
Remove obsolete memory and make other checks before fit starts.
Definition: FitterBase.cpp:222
std::vector< ParameterHandlerBase * > systematics
Systematic holder.
Definition: FitterBase.h:136
Implementation of base Likelihood Fit class, it is mostly responsible for likelihood calculation whil...
Definition: LikelihoodFit.h:6
int NParsPCA
Number of all parameters from all covariances in PCA base.
Definition: LikelihoodFit.h:25
int NPars
Number of all parameters from all covariances.
Definition: LikelihoodFit.h:23
void PrepareFit()
prepare output and perform sanity checks
bool fMirroring
Flag telling if mirroring is used or not.
Definition: LikelihoodFit.h:27
virtual double CalcChi2(const double *x)
Chi2 calculation over all included samples and syst objects.
std::unique_ptr< ROOT::Math::Minimizer > minuit
Pointer to minimizer, which most often is Minuit.
Definition: MinuitFit.h:25
MinuitFit(manager *const fitMan)
Constructor.
Definition: MinuitFit.cpp:5
void RunMCMC() override
Actual implementation of Minuit Fit algorithm.
Definition: MinuitFit.cpp:41
virtual ~MinuitFit()
Destructor.
Definition: MinuitFit.cpp:34
The manager class is responsible for managing configurations and settings.
Definition: Manager.h:16
YAML::Node const & raw()
Return config.
Definition: Manager.h:41