MaCh3  2.6.0
Reference Guide
MCMCBase.cpp
Go to the documentation of this file.
1 #include "Fitters/MCMCBase.h"
2 
3 // *************************
4 // Initialise the Manager and make it an object of mcmc class
5 // Now we can dump Manager settings to the output file
7 // *************************
8  // Beginning step number
9  stepStart = 0;
10 
11  // Starting parameters should be thrown
12  out_of_bounds = false;
13  chainLength = Get<unsigned>(fitMan->raw()["General"]["MCMC"]["NSteps"], __FILE__, __LINE__);
14  if (chainLength < 10){
15  MACH3LOG_ERROR("MCMC chain length must be at least 10 steps, otherwise this will result in a floating point exception.");
16  throw MaCh3Exception(__FILE__, __LINE__);
17  }
18 
19  AnnealTemp = GetFromManager<double>(fitMan->raw()["General"]["MCMC"]["AnnealTemp"], -999, __FILE__ , __LINE__);
20  if (AnnealTemp < 0)
21  anneal = false;
22  else
23  {
24  MACH3LOG_INFO("Enabling simulated annealing with T = {}", AnnealTemp);
25  anneal = true;
26  }
27 }
28 
29 
30 // *******************
31 // Run the Markov chain with all the systematic objects added
33 // *******************
34  // Multicanonical method toggle from yaml config
35  multicanonical = GetFromManager<bool>(fitMan->raw()["General"]["MCMC"]["Multicanonical"]["Enabled"], false);
36  MACH3LOG_INFO("Multicanonical Method: {}", multicanonical);
37 
38  if (multicanonical) {
40  multicanonicalHandler = std::make_unique<MulticanonicalMCMCHandler>();
41 
42  // Initialize the multicanonical handler with the systematics
43  multicanonicalHandler->InitializeMulticanonicalHandlerConfig(fitMan, systematics);
44  AlgorithmName += "_UmbrellaSampling"; // Append to the algorithm name
45 #ifdef DEBUG
46  // Enable debug output stream for multicanonical handler if debug is enabled
47  multicanonicalHandler->setDebugStream(&debugFile, debug);
48 #endif
49  }
50 
51  // Save the settings into the output file
52  SaveSettings();
53 
54  // Prepare the output branches
55  PrepareOutput();
56 
57  // Remove obsolete memory and make other checks before fit starts
59 
60  // Print Progress before Propose Step
61  PrintProgress(false);
62 
63  // Only propose step if we are running fresh chain. If we are running from previous chain then it's not needed and we can use usual pipeline
64  if(stepStart == 0) {
65  // Reconfigure the samples, systematics and oscillation for first weight
66  // ProposeStep sets logLProp
67  ProposeStep();
68 
69  // Initialise the value of the multicanonical parameter to the centres of the umbrellas
70  if (multicanonical){
71  multicanonicalHandler->InitializeMulticanonicalParams(systematics);
72  }
73  // Set the current logL to the proposed logL for the 0th step
74  // Accept the first step to set logLCurr: this shouldn't affect the MCMC because we ignore the first N steps in burn-in
76  }
77 
78  // Begin MCMC
79  const auto StepEnd = stepStart + chainLength;
80  for (step = stepStart; step < StepEnd; ++step)
81  {
82  DoMCMCStep();
83  }
84  // Save all the MCMC output
85  SaveOutput();
86 
87  // Process MCMC
88  ProcessMCMC();
89 
90  // Save the adaptive MCMC
91  for (const auto &syst : systematics)
92  {
93  if (syst->GetDoAdaption())
94  {
95  auto adaptive_handler = syst->GetAdaptiveHandler();
96  adaptive_handler->SaveAdaptiveToFile(adaptive_handler->GetOutFileName(), syst->GetName(), true);
97  }
98  }
99 }
100 
101 // *******************
103 // *******************
105  PreStepProcess();
107  DoStep();
109  PostStepProcess();
110 }
111 
112 // *******************
114 // *******************
115  stepClock->Start();
116  out_of_bounds = false;
117 
118  // Print 10 steps in total
119  if ((step - stepStart) % (chainLength / 10) == 0)
120  {
121  PrintProgress();
122  }
123 }
124 
125 // *************************
127 // *************************
128  //KS: Some version of ROOT keep spamming about accessing already deleted object which is wrong and not helpful...
129  int originalErrorLevel = gErrorIgnoreLevel;
130  gErrorIgnoreLevel = kFatal;
131 
132  stepClock->Stop();
133  stepTime = stepClock->RealTime();
134 
135  // Write step to output tree
136  outTree->Fill();
137 
138  // Do Adaptive MCMC
139  AdaptiveStep();
140 
141  if (step % auto_save == 0){
142  outTree->AutoSave();
143  }
144  gErrorIgnoreLevel = originalErrorLevel;
145 }
146 
147 // *******************
148 // Print the fit output progress
149 void MCMCBase::PrintProgress(bool StepsPrint) {
150 // *******************
151  if(StepsPrint) MACH3LOG_INFO("Step:\t{}/{}, current: {:.2f}, proposed: {:.2f}", step - stepStart, chainLength, logLCurr, logLProp);
152  if(StepsPrint) MACH3LOG_INFO("Accepted/Total steps: {}/{} = {:.2f}", accCount, step - stepStart, static_cast<double>(accCount) / static_cast<double>(step - stepStart));
153 
154  for (size_t i = 0; i < samples.size(); ++i) {
155  samples[i]->PrintRates();
156  }
157 
158  for (ParameterHandlerBase *cov : systematics) {
159  cov->PrintPreFitCurrPropValues();
160  }
161 #ifdef MACH3_DEBUG
162  if (debug)
163  {
164  debugFile << "\n-------------------------------------------------------" << std::endl;
165  debugFile << "Step:\t" << step + 1 << "/" << chainLength << " | current: " << logLCurr << " proposed: " << logLProp << std::endl;
166  }
167 #endif
168 }
169 
170 // *******************
171 void MCMCBase::StartFromPreviousFit(const std::string &FitName) {
172 // *******************
173  // Use base class
175 
176  // For MCMC we also need to set stepStart
177  TFile *infile = M3::Open(FitName, "READ", __FILE__, __LINE__);
178  TTree *posts = infile->Get<TTree>("posteriors");
179  unsigned int step_val = 0;
180 
181  posts->SetBranchAddress("step", &step_val);
182  posts->GetEntry(posts->GetEntries() - 1);
183 
184  stepStart = step_val;
185  // KS: Also update number of steps if using adaption
186  for (unsigned int i = 0; i < systematics.size(); ++i) {
187  if (systematics[i]->GetDoAdaption()) {
188  systematics[i]->SetNumberOfSteps(stepStart);
189  }
190  }
191  infile->Close();
192  delete infile;
193 }
194 
195 // *************************
197 // *************************
198  // Save the Adaptive output
199  for (const auto &syst : systematics)
200  {
201  if (syst->GetDoAdaption()){
202  syst->UpdateAdaptiveCovariance();
203  }
204  }
205 }
206 
207 // *************************
208 bool MCMCBase::IsStepAccepted(const double acc_prob) {
209 // *************************
210  // Get the random number
211  const double fRandom = random->Rndm();
212  // Do the accept/reject
213  #ifdef MACH3_DEBUG
214  debugFile << " logLProp: " << logLProp << " logLCurr: " << logLCurr << " acc_prob: " << acc_prob << " fRandom: " << fRandom << std::endl;
215  #endif
216 
217  if (fRandom > acc_prob)
218  {
219  // Reject
220  return false;
221  }
222  return true;
223 }
224 
225 // *************************
227 // *************************
228  ++accCount;
229  logLCurr = logLProp;
230 
231  // Loop over systematics and accept
232  for (size_t s = 0; s < systematics.size(); ++s)
233  {
234  systematics[s]->AcceptStep();
235  }
236 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
Base class for implementing fitting algorithms.
Definition: FitterBase.h:29
std::unique_ptr< TRandom3 > random
Random number.
Definition: FitterBase.h:149
double logLProp
proposed likelihood
Definition: FitterBase.h:120
void ProcessMCMC()
Process MCMC output.
Definition: FitterBase.cpp:404
int accCount
counts accepted steps
Definition: FitterBase.h:124
void SaveOutput()
Save output and close files.
Definition: FitterBase.cpp:229
void SaveSettings()
Save the settings that the MCMC was run with.
Definition: FitterBase.cpp:77
unsigned int step
current state
Definition: FitterBase.h:116
void PrepareOutput()
Prepare the output file.
Definition: FitterBase.cpp:151
virtual void StartFromPreviousFit(const std::string &FitName)
Allow to start from previous fit/chain.
Definition: FitterBase.cpp:346
std::string AlgorithmName
Name of fitting algorithm that is being used.
Definition: FitterBase.h:173
std::vector< SampleHandlerInterface * > samples
Sample holder.
Definition: FitterBase.h:134
double stepTime
Time of single step.
Definition: FitterBase.h:146
Manager * fitMan
The manager for configuration handling.
Definition: FitterBase.h:113
unsigned int stepStart
step start, by default 0 if we start from previous chain then it will be different
Definition: FitterBase.h:126
std::unique_ptr< TStopwatch > stepClock
tells how long single step/fit iteration took
Definition: FitterBase.h:144
double logLCurr
current likelihood
Definition: FitterBase.h:118
int auto_save
auto save every N steps
Definition: FitterBase.h:160
TTree * outTree
Output tree with posteriors.
Definition: FitterBase.h:158
void SanitiseInputs()
Remove obsolete memory and make other checks before fit starts.
Definition: FitterBase.cpp:221
std::vector< ParameterHandlerBase * > systematics
Systematic holder.
Definition: FitterBase.h:139
std::unique_ptr< MulticanonicalMCMCHandler > multicanonicalHandler
multicanonical handler for umbrella sampling
Definition: MCMCBase.h:61
MCMCBase(Manager *const fitMan)
Constructor.
Definition: MCMCBase.cpp:6
bool anneal
simulated annealing
Definition: MCMCBase.h:73
void RunMCMC() final
Actual implementation of MCMC fitting algorithm.
Definition: MCMCBase.cpp:32
unsigned int chainLength
number of steps in chain
Definition: MCMCBase.h:70
void StartFromPreviousFit(const std::string &FitName) final
Allow to start from previous fit/chain.
Definition: MCMCBase.cpp:171
void AcceptStep()
Accept a step.
Definition: MCMCBase.cpp:226
double AnnealTemp
simulated annealing temperature
Definition: MCMCBase.h:75
bool out_of_bounds
Do we reject based on hitting boundaries in systs.
Definition: MCMCBase.h:64
bool IsStepAccepted(const double acc_prob)
Is step accepted?
Definition: MCMCBase.cpp:208
void DoMCMCStep()
The full StartStep->DoStep->EndStep chain.
Definition: MCMCBase.cpp:102
void PreStepProcess()
Actions before step proposal [start stopwatch].
Definition: MCMCBase.cpp:113
bool multicanonical
multi-canonical method toggle on/off
Definition: MCMCBase.h:78
virtual void ProposeStep()=0
Propose a step.
void PrintProgress(const bool StepsPrint=true)
Print the progress.
Definition: MCMCBase.cpp:149
virtual void DoStep()=0
The MCMC step proposal and acceptance.
void PostStepProcess()
Actions after step proposal [end stopwatch, fill tree].
Definition: MCMCBase.cpp:126
void AdaptiveStep()
Adaptive MCMC step.
Definition: MCMCBase.cpp:196
Custom exception class used throughout MaCh3.
The manager class is responsible for managing configurations and settings.
Definition: Manager.h:16
YAML::Node const & raw() const
Return config.
Definition: Manager.h:47
Base class for handling systematic uncertainty parameters.
TFile * Open(const std::string &Name, const std::string &Type, const std::string &File, const int Line)
Opens a ROOT file with the given name and mode.