MaCh3  2.4.2
Reference Guide
Functions | Variables

This executable calculates the \( \hat{R} \) estimator for Markov Chain Monte Carlo (MCMC) convergence. More...

#include "Manager/Manager.h"
#include "Samples/SampleStructs.h"
#include "Samples/HistogramUtils.h"
#include "TObjArray.h"
#include "TChain.h"
#include "TFile.h"
#include "TBranch.h"
#include "TCanvas.h"
#include "TLine.h"
#include "TLegend.h"
#include "TString.h"
#include "TH1.h"
#include "TRandom3.h"
#include "TStopwatch.h"
#include "TColor.h"
#include "TStyle.h"
#include "TROOT.h"
Include dependency graph for RHat.cpp:

Go to the source code of this file.

Functions

void PrepareChains ()
 
void InitialiseArrays ()
 
void RunDiagnostic ()
 
void CalcRhat ()
 
void SaveResults ()
 
void DestroyArrays ()
 
double CalcMedian (double arr[], int size)
 
void CapVariable (double var, double cap)
 
int main (int argc, char *argv[])
 

Variables

int * Ntoys_requested
 
int * Ntoys_filled
 
int TotToys
 
unsigned int NThin
 
int Nchains
 
int nDraw
 
std::vector< TString > BranchNames
 
std::vector< std::string > MCMCFile
 
std::vector< bool > ValidPar
 
double * S1_global
 
double * S2_global
 
double ** S1_chain
 
double ** S2_chain
 
double ** Mean
 
double ** StandardDeviation
 
double * MeanGlobal
 
double * StandardDeviationGlobal
 
double * BetweenChainVariance
 
double * MarginalPosteriorVariance
 
double * RHat
 
double * EffectiveSampleSize
 

Detailed Description

This executable calculates the \( \hat{R} \) estimator for Markov Chain Monte Carlo (MCMC) convergence.

KS: This exe is meant to calculate the \( \hat{R} \) estimator. For a well-converged chain, this distribution should be centered at one. The \( \hat{R} \) statistic is used to assess the convergence of MCMC simulations and helps determine whether the chains have reached a stable distribution.

[33].

MJR: Update – Improved memory usage so that whole chains can be quickly loaded without requiring copious amounts of RAM. This comes at the cost of not being able to calculate the Folded RHat since finding the median requires the loading of full chains at a time. The method has been validated to give identical results to the "High Memory" (original) version at a fraction of the runtime and resources.

The input format is also slightly altered; since we can now load entire chains, there's less need to specify how many toys are desired for a sub-sample, so the Ntoys input has been removed.

Author
Kamil Skwarczynski
Michael Reh

KS: This exe is meant to calculate the \( \hat{R} \) estimator. For a well-converged chain, this distribution should be centered at one. The \( \hat{R} \) statistic is used to assess the convergence of MCMC simulations and helps determine whether the chains have reached a stable distribution.

[33].

Author
Kamil Skwarczynski
Michael Reh

Definition in file RHat.cpp.

Function Documentation

◆ CalcMedian()

double CalcMedian ( double  arr[],
int  size 
)

Definition at line 688 of file RHat.cpp.

688  {
689 // *******************
690  std::sort(arr, arr+size);
691  if (size % 2 != 0)
692  return arr[size/2];
693  return (arr[(size-1)/2] + arr[size/2])/2.0;
694 }

◆ CalcRhat()

void CalcRhat ( )

Definition at line 387 of file RHat.cpp.

387  {
388 // *******************
389 
390  TStopwatch clock;
391  clock.Start();
392 
393  //KS: Start parallel region
394  // If we would like to do this for thousands of chains we might consider using GPU for this
395  #ifdef MULTITHREAD
396  #pragma omp parallel
397  {
398  #endif
399 
400  #ifdef MULTITHREAD
401  #pragma omp for
402  #endif
403  //KS: loop over chains and draws are independent so might as well collapse for sweet cache hits
404  //Calculate the mean for each parameter within each considered chain
405  // MJR: Calculate using running totals to massively save on time and memory
406  for (int m = 0; m < Nchains; ++m)
407  {
408  for (int j = 0; j < nDraw; ++j)
409  {
410  Mean[m][j] = S1_chain[m][j] / static_cast<double>(Ntoys_filled[m]);
411  StandardDeviation[m][j] = S2_chain[m][j]/static_cast<double>(Ntoys_filled[m]) - Mean[m][j]*Mean[m][j];
412  }
413  }
414 
415  #ifdef MULTITHREAD
416  #pragma omp for
417  #endif
418  //Calculate the mean for each parameter global means we include information from several chains
419  for (int j = 0; j < nDraw; ++j)
420  {
421  for (int m = 0; m < Nchains; ++m)
422  {
424  }
425  MeanGlobal[j] = S1_global[j] / static_cast<double>(TotToys);
426  StandardDeviationGlobal[j] = StandardDeviationGlobal[j] / static_cast<double>(Nchains);
427  }
428 
429  #ifdef MULTITHREAD
430  #pragma omp for
431  #endif
432  for (int j = 0; j < nDraw; ++j)
433  {
434  //KS: This term only makes sense if we have at least 2 chains
435  if(Nchains == 1)
436  {
437  BetweenChainVariance[j] = 0.;
438  }
439  else
440  {
441  for (int m = 0; m < Nchains; ++m)
442  {
443  BetweenChainVariance[j] += ( Mean[m][j] - MeanGlobal[j])*( Mean[m][j] - MeanGlobal[j]) * Ntoys_filled[m];
444  }
446  }
447  }
448 
449  int avgNtoys = TotToys/Nchains;
450  #ifdef MULTITHREAD
451  #pragma omp for
452  #endif
453  for (int j = 0; j < nDraw; ++j)
454  {
455  MarginalPosteriorVariance[j] = (avgNtoys-1) * StandardDeviationGlobal[j] / (avgNtoys) + BetweenChainVariance[j]/avgNtoys;
456  }
457 
458  #ifdef MULTITHREAD
459  #pragma omp for
460  #endif
461  //Finally calculate our estimator
462  for (int j = 0; j < nDraw; ++j)
463  {
465 
466  //KS: For flat params values can be crazy so cap at 0
467  CapVariable(RHat[j], 0);
468  }
469 
470  #ifdef MULTITHREAD
471  #pragma omp for
472  #endif
473  //KS: Additionally calculates effective step size which is an estimate of the sample size required to achieve the same level of precision if that sample was a simple random sample.
474  for (int j = 0; j < nDraw; ++j)
475  {
477 
478  //KS: For flat params values can be crazy so cap at 0
480  }
481  #ifdef MULTITHREAD
482  } //End parallel region
483  #endif
484 
485  clock.Stop();
486  MACH3LOG_INFO("Finished calculating RHat, it took {:.2f}s to finish", clock.RealTime());
487 }
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
double * S1_global
Definition: RHat.cpp:58
double ** S1_chain
Definition: RHat.cpp:60
int Nchains
Definition: RHat.cpp:51
void CapVariable(double var, double cap)
Definition: RHat.cpp:698
int * Ntoys_filled
Definition: RHat.cpp:48
double * MeanGlobal
Definition: RHat.cpp:66
double * BetweenChainVariance
Definition: RHat.cpp:69
double ** StandardDeviation
Definition: RHat.cpp:64
double * StandardDeviationGlobal
Definition: RHat.cpp:67
double * MarginalPosteriorVariance
Definition: RHat.cpp:70
int TotToys
Definition: RHat.cpp:49
double * RHat
Definition: RHat.cpp:71
double ** Mean
Definition: RHat.cpp:63
double ** S2_chain
Definition: RHat.cpp:61
int nDraw
Definition: RHat.cpp:52
double * EffectiveSampleSize
Definition: RHat.cpp:72

◆ CapVariable()

void CapVariable ( double  var,
double  cap 
)

Definition at line 698 of file RHat.cpp.

698  {
699 // *******************
700  if(std::isnan(var) || !std::isfinite(var)) var = cap;
701 }

◆ DestroyArrays()

void DestroyArrays ( )

Definition at line 657 of file RHat.cpp.

657  {
658 // *******************
659 
660  MACH3LOG_INFO("Killing all arrays");
661  delete[] MeanGlobal;
662  delete[] StandardDeviationGlobal;
663  delete[] BetweenChainVariance;
664  delete[] MarginalPosteriorVariance;
665  delete[] RHat;
666  delete[] EffectiveSampleSize;
667 
668  for(int m = 0; m < Nchains; m++)
669  {
670  delete[] Mean[m];
671  delete[] StandardDeviation[m];
672  delete[] S1_chain[m];
673  delete[] S2_chain[m];
674  }
675  delete[] Mean;
676  delete[] StandardDeviation;
677  delete[] S1_chain;
678  delete[] S2_chain;
679  delete[] S1_global;
680  delete[] S2_global;
681 
682  delete[] Ntoys_requested;
683  delete[] Ntoys_filled;
684 }
double * S2_global
Definition: RHat.cpp:59
int * Ntoys_requested
Definition: RHat.cpp:47

◆ InitialiseArrays()

void InitialiseArrays ( )

Definition at line 339 of file RHat.cpp.

339  {
340 // *******************
341 
342  MACH3LOG_INFO("Initialising arrays");
343  Mean = new double*[Nchains]();
344  StandardDeviation = new double*[Nchains]();
345 
346  MeanGlobal = new double[nDraw]();
347  StandardDeviationGlobal = new double[nDraw]();
348  BetweenChainVariance = new double[nDraw]();
349 
350  MarginalPosteriorVariance = new double[nDraw]();
351  RHat = new double[nDraw]();
352  EffectiveSampleSize = new double[nDraw]();
353 
354  for (int m = 0; m < Nchains; ++m)
355  {
356  Mean[m] = new double[nDraw]();
357  StandardDeviation[m] = new double[nDraw]();
358 
359  for (int j = 0; j < nDraw; ++j)
360  {
361  Mean[m][j] = 0.;
362  StandardDeviation[m][j] = 0.;
363 
364  if(m == 0)
365  {
366  MeanGlobal[j] = 0.;
367  StandardDeviationGlobal[j] = 0.;
368  BetweenChainVariance[j] = 0.;
370  RHat[j] = 0.;
371  EffectiveSampleSize[j] = 0.;
372  }
373  }
374  }
375 }

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 88 of file RHat.cpp.

88  {
89 // *******************
90 
93 
94  Mean = nullptr;
95  StandardDeviation = nullptr;
96 
97  MeanGlobal = nullptr;
98  StandardDeviationGlobal = nullptr;
99 
100  BetweenChainVariance = nullptr;
101  MarginalPosteriorVariance = nullptr;
102  RHat = nullptr;
103  EffectiveSampleSize = nullptr;
104 
105  Nchains = 0;
106 
107  if (argc < 2)
108  {
109  MACH3LOG_ERROR("Wrong arguments");
110  MACH3LOG_ERROR("./RHat NThin MCMCchain_1.root MCMCchain_2.root MCMCchain_3.root ... [how many you like]");
111  throw MaCh3Exception(__FILE__ , __LINE__ );
112  }
113 
114  NThin = atoi(argv[1]);
115 
116  //KS Gelman suggests to diagnose on more than one chain
117  for (int i = 2; i < argc; i++)
118  {
119  MCMCFile.push_back(std::string(argv[i]));
120  MACH3LOG_INFO("Adding file: {}", MCMCFile.back());
121  Nchains++;
122  }
123 
124  if(Nchains == 1)
125  {
126  MACH3LOG_WARN("Gelman is going to be sad :(. He suggested you should use more than one chain (at least 4). Code works fine for one chain, however, estimator might be biased.");
127  MACH3LOG_WARN("Multiple chains are more likely to reveal multimodality and poor adaptation or mixing:");
128  }
129  MACH3LOG_INFO("Diagnosing {} chains", Nchains);
130 
131  PrepareChains();
132 
134 
135  //KS: Main function
136  RunDiagnostic();
137 
138  SaveResults();
139 
140  DestroyArrays();
141 
142  return 0;
143 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
Definition: MaCh3Logger.h:61
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36
void SaveResults()
Definition: RHat.cpp:491
unsigned int NThin
Definition: RHat.cpp:50
void InitialiseArrays()
Definition: RHat.cpp:339
void RunDiagnostic()
Definition: RHat.cpp:378
std::vector< std::string > MCMCFile
Definition: RHat.cpp:55
void DestroyArrays()
Definition: RHat.cpp:657
void PrepareChains()
Definition: RHat.cpp:147
Custom exception class used throughout MaCh3.
void MaCh3Welcome()
KS: Prints welcome message with MaCh3 logo.
Definition: Monitor.cpp:12

◆ PrepareChains()

void PrepareChains ( )

Definition at line 147 of file RHat.cpp.

147  {
148 // *******************
149 
150  TStopwatch clock;
151  clock.Start();
152 
153  Ntoys_requested = new int[Nchains]();
154  Ntoys_filled = new int[Nchains]();
155  TotToys = 0;
156  std::vector<unsigned int> BurnIn(Nchains);
157  std::vector<unsigned int> nEntries(Nchains);
158  std::vector<int> nBranches(Nchains);
159  std::vector<unsigned int> step(Nchains);
160 
161  S1_chain = new double*[Nchains]();
162  S2_chain = new double*[Nchains]();
163 
164  // KS: This can reduce time necessary for caching even by half
165  #ifdef MULTITHREAD
166  //ROOT::EnableImplicitMT();
167  #endif
168 
169  // Open the Chain
170  //It is tempting to multithread here but unfortunately, ROOT files are not thread safe :(
171  for (int m = 0; m < Nchains; m++)
172  {
173  TChain* Chain = new TChain("posteriors");
174  Chain->Add(MCMCFile[m].c_str());
175 
176  nEntries[m] = static_cast<unsigned int>(Chain->GetEntries());
177  Ntoys_requested[m] = nEntries[m]/NThin;
178  Ntoys_filled[m] = 0;
179 
180  MACH3LOG_INFO("On file: {}", MCMCFile[m].c_str());
181  MACH3LOG_INFO("Generating {} Toys", Ntoys_requested[m]);
182 
183  // Set the step cut to be 20%
184  BurnIn[m] = nEntries[m]/5;
185 
186  // Get the list of branches
187  TObjArray* brlis = Chain->GetListOfBranches();
188 
189  // Get the number of branches
190  nBranches[m] = brlis->GetEntries();
191 
192  if(m == 0) BranchNames.reserve(nBranches[m]);
193 
194  // Set all the branches to off
195  Chain->SetBranchStatus("*", false);
196 
197  // Loop over the number of branches
198  // Find the name and how many of each systematic we have
199  for (int i = 0; i < nBranches[m]; i++)
200  {
201  // Get the TBranch and its name
202  TBranch* br = static_cast<TBranch *>(brlis->At(i));
203  if(!br){
204  MACH3LOG_ERROR("Invalid branch at position {}", i);
205  throw MaCh3Exception(__FILE__,__LINE__);
206  }
207  TString bname = br->GetName();
208 
209  // Read in the step
210  if (bname == "step") {
211  Chain->SetBranchStatus(bname, true);
212  Chain->SetBranchAddress(bname, &step[m]);
213  }
214  //Count all branches
215  else if (bname.BeginsWith("PCA_") || bname.BeginsWith("accProb") || bname.BeginsWith("stepTime") )
216  {
217  continue;
218  }
219  else
220  {
221  //KS: Save branch name only for one chain, we assume all chains have the same branches, otherwise this doesn't make sense either way
222  if(m == 0)
223  {
224  BranchNames.push_back(bname);
225  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
226  if(bname.BeginsWith("LogL"))
227  {
228  ValidPar.push_back(false);
229  }
230  else
231  {
232  ValidPar.push_back(true);
233  }
234  }
235  Chain->SetBranchStatus(bname, true);
236  MACH3LOG_DEBUG("{}", bname);
237  }
238  }
239 
240  if(m == 0) nDraw = int(BranchNames.size());
241 
242  // MJR: Initialize quantities needed for calculating RHat
243  S1_chain[m] = new double[nDraw]();
244  S2_chain[m] = new double[nDraw]();
245  if (m == 0)
246  {
247  S1_global = new double[nDraw]();
248  S2_global = new double[nDraw]();
249  }
250  for (int id = 0; id < nDraw; ++id)
251  {
252  S1_chain[m][id] = 0.0;
253  S2_chain[m][id] = 0.0;
254  if (m == 0)
255  {
256  S1_global[id] = 0.0;
257  S2_global[id] = 0.0;
258  }
259  }
260 
261  //TN: Qualitatively faster sanity check, with the very same outcome (all chains have the same #branches)
262  if(m > 0)
263  {
264  if(nBranches[m] != nBranches[0])
265  {
266  MACH3LOG_ERROR("Ups, something went wrong, chain {} called {} has {} branches, while 0 called {} has {} branches", m, MCMCFile[m], nBranches[m], MCMCFile[0], nBranches[0]);
267  MACH3LOG_ERROR("All chains should have the same number of branches");
268  throw MaCh3Exception(__FILE__ , __LINE__ );
269  }
270  }
271 
272  // MJR: Create an array to hold branch values. Resetting branch addresses
273  // for every step is very expensive.
274  double* branch_values = new double[nDraw]();
275  for (int id = 0; id < nDraw; ++id)
276  {
277  Chain->SetBranchAddress(BranchNames[id].Data(), &branch_values[id]);
278  }
279 
280  //TN: move looping over toys here, so we don't need to loop over chains more than once
281  if(BurnIn[m] >= nEntries[m])
282  {
283  MACH3LOG_ERROR("You are running on a chain shorter than BurnIn cut");
284  MACH3LOG_ERROR("Number of entries {} BurnIn cut {}", nEntries[m], BurnIn[m]);
285  MACH3LOG_ERROR("You will run into the infinite loop");
286  MACH3LOG_ERROR("You can make a new chain or modify BurnIn cut");
287  throw MaCh3Exception(__FILE__ , __LINE__ );
288  }
289 
290  MACH3LOG_INFO("Loading chain {} / {}...", m, Nchains);
291  for (int i = 0; i < Ntoys_requested[m]; i++)
292  {
293  // This is here as a placeholder in case we want to do some thinning later
294  int entry = i*NThin;
295 
296  Chain->GetEntry(entry);
297 
298  // If we have combined chains by hadd need to check the step in the chain
299  // Note, entry is not necessarily the same as the step due to merged ROOT files, so can't choose an entry in the range BurnIn - nEntries :(
300  if (step[m] < BurnIn[m])
301  {
302  continue;
303  }
304 
305  // Output some info for the user
306  if (Ntoys_requested[m] > 10 && i % (Ntoys_requested[m]/10) == 0) {
307  MaCh3Utils::PrintProgressBar(i+m*Ntoys_requested[m], static_cast<Long64_t>(Ntoys_requested[m])*Nchains);
308  MACH3LOG_DEBUG("Getting random entry {}", entry);
309  }
310 
311  // MJR: Fill running quantities instead of loading everything into RAM.
312  // This is where we save big on both memory and time (resetting
313  // branch addresses and calling GetEntry() again here is very slow).
314  for (int j = 0; j < nDraw; ++j)
315  {
316  S1_global[j] += branch_values[j];
317  S2_global[j] += branch_values[j]*branch_values[j];
318  S1_chain[m][j] += branch_values[j];
319  S2_chain[m][j] += branch_values[j]*branch_values[j];
320  }
321 
322  // Increment counters
323  Ntoys_filled[m]++;
324  TotToys++;
325  }//end loop over toys
326 
327  //TN: There, we now don't need to keep the chain in memory anymore
328  delete Chain;
329  delete[] branch_values;
330  MACH3LOG_INFO("Finished loading chain {}!", m);
331  }
332 
333  clock.Stop();
334  MACH3LOG_INFO("Finished calculating Toys, it took {:.2f}s to finish", clock.RealTime());
335 }
#define MACH3LOG_DEBUG
Definition: MaCh3Logger.h:34
std::vector< bool > ValidPar
Definition: RHat.cpp:56
std::vector< TString > BranchNames
Definition: RHat.cpp:54
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.
Definition: Monitor.cpp:228

◆ RunDiagnostic()

void RunDiagnostic ( )

Definition at line 378 of file RHat.cpp.

378  {
379 // *******************
380  CalcRhat();
381  //In case in future we expand this
382 }
void CalcRhat()
Definition: RHat.cpp:387

◆ SaveResults()

void SaveResults ( )

Definition at line 491 of file RHat.cpp.

491  {
492 // *******************
493  #pragma GCC diagnostic ignored "-Wfloat-conversion"
494 
495  std::string NameTemp = "";
496  //KS: If we run over many many chains there is danger that name will be so absurdly long we run over system limit and job will be killed :(
497  if(Nchains < 5)
498  {
499  for (int i = 0; i < Nchains; i++)
500  {
501  std::string temp = MCMCFile[i];
502 
503  while (temp.find(".root") != std::string::npos) {
504  temp = temp.substr(0, temp.find(".root"));
505  }
506  // Strip directory path
507  const auto slash = temp.find_last_of("/\\");
508  if (slash != std::string::npos) {
509  temp = temp.substr(slash + 1);
510  }
511 
512  NameTemp = NameTemp + temp + "_";
513  }
514  }
515  else {
516  NameTemp = std::to_string(Nchains) + "Chains" + "_";
517  }
518  NameTemp += "diag.root";
519 
520  TFile *DiagFile = M3::Open(NameTemp, "recreate", __FILE__, __LINE__);
521  DiagFile->cd();
522 
523  TH1D *StandardDeviationGlobalPlot = new TH1D("StandardDeviationGlobalPlot", "StandardDeviationGlobalPlot", nDraw, 0, nDraw);
524  TH1D *BetweenChainVariancePlot = new TH1D("BetweenChainVariancePlot", "BetweenChainVariancePlot", nDraw, 0, nDraw);
525  TH1D *MarginalPosteriorVariancePlot = new TH1D("MarginalPosteriorVariancePlot", "MarginalPosteriorVariancePlot", nDraw, 0, nDraw);
526  TH1D *RhatPlot = new TH1D("RhatPlot", "RhatPlot", 200, 0, 2);
527  TH1D *EffectiveSampleSizePlot = new TH1D("EffectiveSampleSizePlot", "EffectiveSampleSizePlot", 400, 0, 10000);
528 
529  TH1D *RhatLogPlot = new TH1D("RhatLogPlot", "RhatLogPlot", 200, 0, 2);
530 
531  int Criterium = 0;
532  for(int j = 0; j < nDraw; j++)
533  {
534  //KS: Fill only valid parameters
535  if(ValidPar[j])
536  {
537  StandardDeviationGlobalPlot->Fill(j,StandardDeviationGlobal[j]);
538  BetweenChainVariancePlot->Fill(j,BetweenChainVariance[j]);
539  MarginalPosteriorVariancePlot->Fill(j,MarginalPosteriorVariance[j]);
540  RhatPlot->Fill(RHat[j]);
541  EffectiveSampleSizePlot->Fill(EffectiveSampleSize[j]);
542  if(RHat[j] > 1.1) Criterium++;
543  }
544  else
545  {
546  RhatLogPlot->Fill(RHat[j]);
547  }
548  }
549  //KS: We set criterium of 1.1 based on Gelman et al. (2003) Bayesian Data Analysis
550  MACH3LOG_WARN("Number of parameters which has R hat greater than 1.1 is {}({:.2f}%)", Criterium, 100*double(Criterium)/double(nDraw));
551  for(int j = 0; j < nDraw; j++)
552  {
553  if( (RHat[j] > 1.1) && ValidPar[j])
554  {
555  MACH3LOG_CRITICAL("Parameter {} has R hat higher than 1.1", BranchNames[j]);
556  }
557  }
558  StandardDeviationGlobalPlot->Write();
559  BetweenChainVariancePlot->Write();
560  MarginalPosteriorVariancePlot->Write();
561  RhatPlot->Write();
562  EffectiveSampleSizePlot->Write();
563 
564  RhatLogPlot->Write();
565 
566  //KS: Now we make fancy canvases, consider some function to have less copy pasting
567  auto TempCanvas = std::make_unique<TCanvas>("Canvas", "Canvas", 1024, 1024);
568  gStyle->SetOptStat(0);
569  TempCanvas->SetGridx();
570  TempCanvas->SetGridy();
571 
572  // Random line to write useful information to TLegend
573  auto TempLine = std::make_unique<TLine>(0, 0, 0, 0);
574  TempLine->SetLineColor(kBlack);
575 
576  RhatPlot->GetXaxis()->SetTitle("R hat");
577  RhatPlot->SetLineColor(kRed);
578  RhatPlot->SetFillColor(kRed);
579 
580  TLegend *Legend = new TLegend(0.55, 0.6, 0.9, 0.9);
581  Legend->SetTextSize(0.04);
582  Legend->SetFillColor(0);
583  Legend->SetFillStyle(0);
584  Legend->SetLineWidth(0);
585  Legend->SetLineColor(0);
586 
587  Legend->AddEntry(TempLine.get(), Form("Number of throws=%.0i, Number of chains=%.1i", TotToys, Nchains), "");
588  Legend->AddEntry(RhatPlot, "Rhat Gelman 2013", "l");
589 
590  RhatPlot->Draw();
591  Legend->Draw("same");
592  TempCanvas->Write("Rhat");
593  delete Legend;
594  Legend = nullptr;
595 
596  //Now R hat for log L
597  RhatLogPlot->GetXaxis()->SetTitle("R hat for LogL");
598  RhatLogPlot->SetLineColor(kRed);
599  RhatLogPlot->SetFillColor(kRed);
600 
601  Legend = new TLegend(0.55, 0.6, 0.9, 0.9);
602  Legend->SetTextSize(0.04);
603  Legend->SetFillColor(0);
604  Legend->SetFillStyle(0);
605  Legend->SetLineWidth(0);
606  Legend->SetLineColor(0);
607 
608  Legend->AddEntry(TempLine.get(), Form("Number of throws=%.0i, Number of chains=%.1i", TotToys, Nchains), "");
609  Legend->AddEntry(RhatLogPlot, "Rhat Gelman 2013", "l");
610 
611  RhatLogPlot->Draw();
612  Legend->Draw("same");
613  TempCanvas->Write("RhatLog");
614  delete Legend;
615  Legend = nullptr;
616 
617  //Now canvas for effective sample size
618  EffectiveSampleSizePlot->GetXaxis()->SetTitle("S_{eff, BDA2}");
619  EffectiveSampleSizePlot->SetLineColor(kRed);
620 
621  Legend = new TLegend(0.45, 0.6, 0.9, 0.9);
622  Legend->SetTextSize(0.03);
623  Legend->SetFillColor(0);
624  Legend->SetFillStyle(0);
625  Legend->SetLineWidth(0);
626  Legend->SetLineColor(0);
627 
628  const double Mean1 = EffectiveSampleSizePlot->GetMean();
629  const double RMS1 = EffectiveSampleSizePlot->GetRMS();
630 
631  Legend->AddEntry(TempLine.get(), Form("Number of throws=%.0i, Number of chains=%.1i", TotToys, Nchains), "");
632  Legend->AddEntry(EffectiveSampleSizePlot, Form("S_{eff, BDA2} #mu = %.2f, #sigma = %.2f",Mean1 ,RMS1), "l");
633 
634  EffectiveSampleSizePlot->Draw();
635  Legend->Draw("same");
636  TempCanvas->Write("EffectiveSampleSize");
637 
638  //Fancy memory cleaning
639  delete StandardDeviationGlobalPlot;
640  delete BetweenChainVariancePlot;
641  delete MarginalPosteriorVariancePlot;
642  delete RhatPlot;
643  delete EffectiveSampleSizePlot;
644 
645  delete Legend;
646 
647  delete RhatLogPlot;
648 
649  DiagFile->Close();
650  delete DiagFile;
651 
652  MACH3LOG_INFO("Finished and wrote results to {}", NameTemp);
653 }
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:38
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.

Variable Documentation

◆ BetweenChainVariance

double* BetweenChainVariance

Definition at line 69 of file RHat.cpp.

◆ BranchNames

std::vector<TString> BranchNames

Definition at line 54 of file RHat.cpp.

◆ EffectiveSampleSize

double* EffectiveSampleSize

Definition at line 72 of file RHat.cpp.

◆ MarginalPosteriorVariance

double* MarginalPosteriorVariance

Definition at line 70 of file RHat.cpp.

◆ MCMCFile

std::vector<std::string> MCMCFile

Definition at line 55 of file RHat.cpp.

◆ Mean

double** Mean

Definition at line 63 of file RHat.cpp.

◆ MeanGlobal

double* MeanGlobal

Definition at line 66 of file RHat.cpp.

◆ Nchains

int Nchains

Definition at line 51 of file RHat.cpp.

◆ nDraw

int nDraw

Definition at line 52 of file RHat.cpp.

◆ NThin

unsigned int NThin

Definition at line 50 of file RHat.cpp.

◆ Ntoys_filled

int* Ntoys_filled

Definition at line 48 of file RHat.cpp.

◆ Ntoys_requested

int* Ntoys_requested

Definition at line 47 of file RHat.cpp.

◆ RHat

double* RHat

Definition at line 71 of file RHat.cpp.

◆ S1_chain

double** S1_chain

Definition at line 60 of file RHat.cpp.

◆ S1_global

double* S1_global

Definition at line 58 of file RHat.cpp.

◆ S2_chain

double** S2_chain

Definition at line 61 of file RHat.cpp.

◆ S2_global

double* S2_global

Definition at line 59 of file RHat.cpp.

◆ StandardDeviation

double** StandardDeviation

Definition at line 64 of file RHat.cpp.

◆ StandardDeviationGlobal

double* StandardDeviationGlobal

Definition at line 67 of file RHat.cpp.

◆ TotToys

int TotToys

Definition at line 49 of file RHat.cpp.

◆ ValidPar

std::vector<bool> ValidPar

Definition at line 56 of file RHat.cpp.