MaCh3  2.6.1
Reference Guide
Public Member Functions | Private Member Functions | Private Attributes | List of all members
RHatCalculator Class Reference

Class responsible for calculating \( \hat{R} \) estimator for Markov Chain Monte Carlo (MCMC) convergence. More...

#include <Fitters/RHatCalculator.h>

Collaboration diagram for RHatCalculator:
[legend]

Public Member Functions

 RHatCalculator (bool HighMemory, std::vector< std::string > &Inputs, int entries)
 Constructor. More...
 
virtual ~RHatCalculator ()
 Destroys the RHatCalculator object. More...
 
void RunDiagnostic ()
 

Private Member Functions

void PrepareChains_HighMem ()
 Load chain and prepare toys. More...
 
void PrepareChains ()
 Load chain and prepare toys. More...
 
void InitialiseArrays ()
 Create all arrays we are going to use later. More...
 
void CalcRhat_HighMem ()
 KS: Based on Gelman et. al. arXiv:1903.08008v5. More...
 
void CalcRhat ()
 KS: Based on Gelman et. al. arXiv:1903.08008v5. More...
 
void SaveResults ()
 

Private Attributes

bool HighMemoryMode
 
int nDraw
 
int Nchains
 
std::vector< TString > BranchNames
 
std::vector< std::string > MCMCFile
 
std::vector< bool > ValidPar
 
std::vector< std::vector< double > > Mean
 
std::vector< std::vector< double > > StandardDeviation
 
std::vector< double > MeanGlobal
 
std::vector< double > StandardDeviationGlobal
 
std::vector< double > BetweenChainVariance
 
std::vector< double > MarginalPosteriorVariance
 
std::vector< double > RHat
 
std::vector< double > EffectiveSampleSize
 
int Ntoys
 
std::vector< std::vector< std::vector< double > > > Draws
 
std::vector< std::vector< std::vector< double > > > DrawsFolded
 
std::vector< double > MedianArr
 
std::vector< std::vector< double > > MeanFolded
 
std::vector< std::vector< double > > StandardDeviationFolded
 
std::vector< double > MeanGlobalFolded
 
std::vector< double > StandardDeviationGlobalFolded
 
std::vector< double > BetweenChainVarianceFolded
 
std::vector< double > MarginalPosteriorVarianceFolded
 
std::vector< double > RHatFolded
 
std::vector< double > EffectiveSampleSizeFolded
 
std::vector< int > Ntoys_requested
 
std::vector< int > Ntoys_filled
 
int TotToys
 
unsigned int NThin
 
std::vector< double > S1_global
 Sum_i^N x_i | total. More...
 
std::vector< double > S2_global
 Sum_i^N x_i^2 | total. More...
 
std::vector< std::vector< double > > S1_chain
 Sum_i^N x_i | for each chain. More...
 
std::vector< std::vector< double > > S2_chain
 Sum_i^N x_i^2 | for each chain. More...
 

Detailed Description

Class responsible for calculating \( \hat{R} \) estimator for Markov Chain Monte Carlo (MCMC) convergence.

[36].

Author
Kamil Skwarczynski
Michael Reh
Tomas Nosek

Definition at line 15 of file RHatCalculator.h.

Constructor & Destructor Documentation

◆ RHatCalculator()

_MaCh3_Safe_Include_Start_ _MaCh3_Safe_Include_End_ RHatCalculator::RHatCalculator ( bool  HighMemory,
std::vector< std::string > &  Inputs,
int  entries 
)

Constructor.

Parameters
HighMemoryHigh mem is generally slower but has calculates additional info
Inputsvector of paths to MCMC PrepareChains
entriesif in high mem mode this number of toys per chain, for low mem thinning setting

Definition at line 23 of file RHatCalculator.cpp.

23  {
24 // ****************************
26 
27  HighMemoryMode = HighMemory;
28 
29  MCMCFile = Inputs;
30  Nchains = static_cast<int>(MCMCFile.size());
31  if(HighMemoryMode){
32  Ntoys = entries;
33  } else{
34  NThin = entries;
35  }
36 }
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
Definition: MaCh3Logger.h:60
unsigned int NThin
std::vector< std::string > MCMCFile

◆ ~RHatCalculator()

RHatCalculator::~RHatCalculator ( )
virtual

Destroys the RHatCalculator object.

Definition at line 40 of file RHatCalculator.cpp.

40  {
41 // ****************************
42 }

Member Function Documentation

◆ CalcRhat()

void RHatCalculator::CalcRhat ( )
private

KS: Based on Gelman et. al. arXiv:1903.08008v5.

Definition at line 524 of file RHatCalculator.cpp.

524  {
525 // *******************
526  TStopwatch clock;
527  clock.Start();
528 
529  //KS: Start parallel region
530  // If we would like to do this for thousands of chains we might consider using GPU for this
531  #ifdef MULTITHREAD
532  #pragma omp parallel
533  {
534  #endif
535 
536  #ifdef MULTITHREAD
537  #pragma omp for
538  #endif
539  //KS: loop over chains and draws are independent so might as well collapse for sweet cache hits
540  //Calculate the mean for each parameter within each considered chain
541  // MJR: Calculate using running totals to massively save on time and memory
542  for (int m = 0; m < Nchains; ++m)
543  {
544  for (int j = 0; j < nDraw; ++j)
545  {
546  Mean[m][j] = S1_chain[m][j] / static_cast<double>(Ntoys_filled[m]);
547  StandardDeviation[m][j] = S2_chain[m][j]/static_cast<double>(Ntoys_filled[m]) - Mean[m][j]*Mean[m][j];
548  }
549  }
550 
551  #ifdef MULTITHREAD
552  #pragma omp for
553  #endif
554  //Calculate the mean for each parameter global means we include information from several chains
555  for (int j = 0; j < nDraw; ++j)
556  {
557  for (int m = 0; m < Nchains; ++m)
558  {
560  }
561  MeanGlobal[j] = S1_global[j] / static_cast<double>(TotToys);
562  StandardDeviationGlobal[j] = StandardDeviationGlobal[j] / static_cast<double>(Nchains);
563  }
564 
565  #ifdef MULTITHREAD
566  #pragma omp for
567  #endif
568  for (int j = 0; j < nDraw; ++j)
569  {
570  //KS: This term only makes sense if we have at least 2 chains
571  if(Nchains == 1)
572  {
573  BetweenChainVariance[j] = 0.;
574  }
575  else
576  {
577  for (int m = 0; m < Nchains; ++m)
578  {
579  BetweenChainVariance[j] += ( Mean[m][j] - MeanGlobal[j])*( Mean[m][j] - MeanGlobal[j]) * Ntoys_filled[m];
580  }
582  }
583  }
584 
585  int avgNtoys = TotToys/Nchains;
586  #ifdef MULTITHREAD
587  #pragma omp for
588  #endif
589  for (int j = 0; j < nDraw; ++j)
590  {
591  MarginalPosteriorVariance[j] = (avgNtoys-1) * StandardDeviationGlobal[j] / (avgNtoys) + BetweenChainVariance[j]/avgNtoys;
592  }
593 
594  #ifdef MULTITHREAD
595  #pragma omp for
596  #endif
597  //Finally calculate our estimator
598  for (int j = 0; j < nDraw; ++j)
599  {
601 
602  //KS: For flat params values can be crazy so cap at 0
603  CapVariable(RHat[j], 0);
604  }
605 
606  #ifdef MULTITHREAD
607  #pragma omp for
608  #endif
609  //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.
610  for (int j = 0; j < nDraw; ++j)
611  {
613 
614  //KS: For flat params values can be crazy so cap at 0
616  }
617  #ifdef MULTITHREAD
618  } //End parallel region
619  #endif
620 
621  clock.Stop();
622  MACH3LOG_INFO("Finished calculating RHat, it took {:.2f}s to finish", clock.RealTime());
623 }
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
void CapVariable(double var, const double cap)
std::vector< std::vector< double > > StandardDeviation
std::vector< double > BetweenChainVariance
std::vector< double > MeanGlobal
std::vector< std::vector< double > > S1_chain
Sum_i^N x_i | for each chain.
std::vector< double > StandardDeviationGlobal
std::vector< double > EffectiveSampleSize
std::vector< std::vector< double > > Mean
std::vector< double > MarginalPosteriorVariance
std::vector< int > Ntoys_filled
std::vector< double > S1_global
Sum_i^N x_i | total.
std::vector< std::vector< double > > S2_chain
Sum_i^N x_i^2 | for each chain.
std::vector< double > RHat

◆ CalcRhat_HighMem()

void RHatCalculator::CalcRhat_HighMem ( )
private

KS: Based on Gelman et. al. arXiv:1903.08008v5.

Definition at line 628 of file RHatCalculator.cpp.

628  {
629 // *******************
630  TStopwatch clock;
631  clock.Start();
632 
633  //KS: Start parallel region
634  // If we would like to do this for thousands of chains we might consider using GPU for this
635  #ifdef MULTITHREAD
636  #pragma omp parallel
637  {
638  #endif
639 
640  #ifdef MULTITHREAD
641  #pragma omp for collapse(2)
642  #endif
643  //KS: loop over chains and draws are independent so might as well collapse for sweet cache hits
644  //Calculate the mean for each parameter within each considered chain
645  for (int m = 0; m < Nchains; ++m)
646  {
647  for (int j = 0; j < nDraw; ++j)
648  {
649  for(int i = 0; i < Ntoys; i++)
650  {
651  Mean[m][j] += Draws[m][i][j];
652  MeanFolded[m][j] += DrawsFolded[m][i][j];
653  }
654  Mean[m][j] = Mean[m][j]/Ntoys;
655  MeanFolded[m][j] = MeanFolded[m][j]/Ntoys;
656  }
657  }
658 
659  #ifdef MULTITHREAD
660  #pragma omp for
661  #endif
662  //Calculate the mean for each parameter global means we include information from several chains
663  for (int j = 0; j < nDraw; ++j)
664  {
665  for (int m = 0; m < Nchains; ++m)
666  {
667  MeanGlobal[j] += Mean[m][j];
668  MeanGlobalFolded[j] += MeanFolded[m][j];
669  }
670  MeanGlobal[j] = MeanGlobal[j]/Nchains;
672  }
673 
674 
675  #ifdef MULTITHREAD
676  #pragma omp for collapse(2)
677  #endif
678  //Calculate the standard deviation for each parameter within each considered chain
679  for (int m = 0; m < Nchains; ++m)
680  {
681  for (int j = 0; j < nDraw; ++j)
682  {
683  for(int i = 0; i < Ntoys; i++)
684  {
685  StandardDeviation[m][j] += (Draws[m][i][j] - Mean[m][j])*(Draws[m][i][j] - Mean[m][j]);
686  StandardDeviationFolded[m][j] += (DrawsFolded[m][i][j] - MeanFolded[m][j])*(DrawsFolded[m][i][j] - MeanFolded[m][j]);
687  }
688  StandardDeviation[m][j] = StandardDeviation[m][j]/(Ntoys-1);
690  }
691  }
692 
693  #ifdef MULTITHREAD
694  #pragma omp for
695  #endif
696  //Calculate the standard deviation for each parameter combining information from all chains
697  for (int j = 0; j < nDraw; ++j)
698  {
699  for (int m = 0; m < Nchains; ++m)
700  {
703  }
706  }
707 
708  #ifdef MULTITHREAD
709  #pragma omp for
710  #endif
711  for (int j = 0; j < nDraw; ++j)
712  {
713  //KS: This term only makes sense if we have at least 2 chains
714  if(Nchains == 1)
715  {
716  BetweenChainVariance[j] = 0.;
718  }
719  else
720  {
721  for (int m = 0; m < Nchains; ++m)
722  {
723  BetweenChainVariance[j] += ( Mean[m][j] - MeanGlobal[j])*( Mean[m][j] - MeanGlobal[j]);
725  }
728  }
729  }
730 
731  #ifdef MULTITHREAD
732  #pragma omp for
733  #endif
734  for (int j = 0; j < nDraw; ++j)
735  {
738  }
739 
740  #ifdef MULTITHREAD
741  #pragma omp for
742  #endif
743  //Finally calculate our estimator
744  for (int j = 0; j < nDraw; ++j)
745  {
748 
749  //KS: For flat params values can be crazy so cap at 0
750  CapVariable(RHat[j], 0);
751  CapVariable(RHatFolded[j], 0);
752  }
753 
754  #ifdef MULTITHREAD
755  #pragma omp for
756  #endif
757  //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.
758  for (int j = 0; j < nDraw; ++j)
759  {
762 
763  //KS: For flat params values can be crazy so cap at 0
766  }
767  #ifdef MULTITHREAD
768  } //End parallel region
769  #endif
770 
771  clock.Stop();
772  MACH3LOG_INFO("Finished calculating RHat, it took {:.2f}s to finish", clock.RealTime());
773 }
std::vector< double > EffectiveSampleSizeFolded
std::vector< std::vector< std::vector< double > > > DrawsFolded
std::vector< std::vector< double > > StandardDeviationFolded
std::vector< double > BetweenChainVarianceFolded
std::vector< double > MarginalPosteriorVarianceFolded
std::vector< double > MeanGlobalFolded
std::vector< double > StandardDeviationGlobalFolded
std::vector< std::vector< std::vector< double > > > Draws
std::vector< std::vector< double > > MeanFolded
std::vector< double > RHatFolded

◆ InitialiseArrays()

void RHatCalculator::InitialiseArrays ( )
private

Create all arrays we are going to use later.

Definition at line 484 of file RHatCalculator.cpp.

484  {
485 // *******************
486  MACH3LOG_INFO("Starting {}", __func__);
487  Mean.resize(Nchains);
488  StandardDeviation.resize(Nchains);
489 
490  for (int m = 0; m < Nchains; ++m) {
491  Mean[m].resize(nDraw, 0);
492  StandardDeviation[m].resize(nDraw, 0);
493  }
494 
495  MeanGlobal.resize(nDraw, 0);
496  StandardDeviationGlobal.resize(nDraw, 0);
497  BetweenChainVariance.resize(nDraw, 0);
498 
499  MarginalPosteriorVariance.resize(nDraw, 0);
500  RHat.resize(nDraw, 0);
501  EffectiveSampleSize.resize(nDraw, 0);
502 
503  if(HighMemoryMode){
504  MeanFolded.resize(Nchains);
506 
507  for (int m = 0; m < Nchains; ++m) {
508  MeanFolded[m].resize(nDraw, 0);
509  StandardDeviationFolded[m].resize(nDraw, 0);
510  }
511 
512  MeanGlobalFolded.resize(nDraw, 0);
515 
517  RHatFolded.resize(nDraw, 0);
518  EffectiveSampleSizeFolded.resize(nDraw, 0);
519  }
520 }

◆ PrepareChains()

void RHatCalculator::PrepareChains ( )
private

Load chain and prepare toys.

Definition at line 292 of file RHatCalculator.cpp.

292  {
293 // *******************
294  TStopwatch clock;
295  clock.Start();
296 
297  Ntoys_requested.resize(Nchains);
298  Ntoys_filled.resize(Nchains);
299  TotToys = 0;
300  std::vector<unsigned int> BurnIn(Nchains);
301  std::vector<unsigned int> nEntries(Nchains);
302  std::vector<int> nBranches(Nchains);
303  std::vector<unsigned int> step(Nchains);
304 
305  S1_chain.resize(Nchains);
306  S2_chain.resize(Nchains);
307 
308  std::unique_ptr<MCMCProcessor> Processor;
309 
310  // Open the Chain
311  //It is tempting to multithread here but unfortunately, ROOT files are not thread safe :(
312  for (int m = 0; m < Nchains; m++)
313  {
314  MACH3LOG_INFO("On file: {}", MCMCFile[m].c_str());
315  if (!std::filesystem::exists(MCMCFile[m])) {
316  MACH3LOG_ERROR("File: {}, doesn't exist", MCMCFile[m]);
317  throw MaCh3Exception(__FILE__, __LINE__);
318  }
319  TChain* Chain = new TChain("posteriors");
320  Chain->Add(MCMCFile[m].c_str());
321 
322  nEntries[m] = static_cast<unsigned int>(Chain->GetEntries());
323  Ntoys_requested[m] = nEntries[m]/NThin;
324  Ntoys_filled[m] = 0;
325 
326  MACH3LOG_INFO("On file: {}", MCMCFile[m].c_str());
327  MACH3LOG_INFO("Generating {} Toys", Ntoys_requested[m]);
328 
329  // Set the step cut to be 20%
330  BurnIn[m] = nEntries[m]/5;
331 
332  // Get the list of branches
333  TObjArray* brlis = Chain->GetListOfBranches();
334 
335  // Get the number of branches
336  nBranches[m] = brlis->GetEntries();
337 
338  // Set all the branches to off
339  Chain->SetBranchStatus("*", false);
340 
341  std::vector<TString> SampleLLH;
342  std::vector<TString> SystLLH;
343 
344  if(m == 0) {
345  Processor = std::make_unique<MCMCProcessor>(MCMCFile[m]);
346  Processor->Initialise();
347  nDraw = Processor->GetNParams();
348  SampleLLH = Processor->GetSampleBranchNames();
349  SystLLH = Processor->GetSystBranchNames();
350  nDraw = nDraw + static_cast<int>(SampleLLH.size()) + static_cast<int>(SystLLH.size());
351  BranchNames.reserve(nDraw);
352  }
353 
354  // Set all the branches to off
355  Chain->SetBranchStatus("*", false);
356 
357  // Loop over the number of branches
358  // Find the name and how many of each systematic we have
359  for (int i = 0; i < Processor->GetNParams(); i++)
360  {
361  TString bname = Processor->GetBranchNames()[i];
362  //KS: Save branch name only for one chain, we assume all chains have the same branches, otherwise this doesn't make sense either way
363  if(m == 0) {
364  BranchNames.push_back(bname);
365  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
366  ValidPar.push_back(true);
367  }
368  Chain->SetBranchStatus(bname, true);
369 
370  // Get the TBranch and its name
371  if (!Chain->GetBranch(bname)) {
372  MACH3LOG_ERROR("Branch '{}' does not exist in the TChain", bname.Data());
373  throw MaCh3Exception(__FILE__, __LINE__);
374  }
375  MACH3LOG_DEBUG("{}", bname);
376  }
377 
378  for (size_t i = 0; i < SampleLLH.size(); ++i) {
379  TString bname = SampleLLH[i];
380  Chain->SetBranchStatus(bname, true);
381  if(m == 0) {
382  BranchNames.push_back(bname);
383  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
384  ValidPar.push_back(false);
385  }
386  }
387  for (size_t i = 0; i < SystLLH.size(); ++i) {
388  TString bname = SystLLH[i];
389  Chain->SetBranchStatus(bname, true);
390  if(m == 0) {
391  BranchNames.push_back(bname);
392  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
393  ValidPar.push_back(false);
394  }
395  }
396  // Read in the step
397  Chain->SetBranchStatus("step", true);
398  Chain->SetBranchAddress("step", &step[m]);
399  // MJR: Initialize quantities needed for calculating RHat
400  S1_chain[m].resize(nDraw, 0);
401  S2_chain[m].resize(nDraw, 0);
402  if (m == 0)
403  {
404  S1_global.resize(nDraw, 0);
405  S2_global.resize(nDraw, 0);
406  }
407 
408  //TN: Qualitatively faster sanity check, with the very same outcome (all chains have the same #branches)
409  if(m > 0)
410  {
411  if(nBranches[m] != nBranches[0])
412  {
413  MACH3LOG_ERROR("Ups, something went wrong, chain {} called {} has {} branches, while 0 called {} has {} branches", m, MCMCFile[m], nBranches[m], MCMCFile[0], nBranches[0]);
414  MACH3LOG_ERROR("All chains should have the same number of branches");
415  throw MaCh3Exception(__FILE__ , __LINE__ );
416  }
417  }
418 
419  // MJR: Create an array to hold branch values. Resetting branch addresses
420  // for every step is very expensive.
421  std::vector<double> branch_values(nDraw, 0.0);
422  for (int id = 0; id < nDraw; ++id) {
423  Chain->SetBranchAddress(BranchNames[id].Data(), &branch_values[id]);
424  }
425 
426  //TN: move looping over toys here, so we don't need to loop over chains more than once
427  if(BurnIn[m] >= nEntries[m])
428  {
429  MACH3LOG_ERROR("You are running on a chain shorter than BurnIn cut");
430  MACH3LOG_ERROR("Number of entries {} BurnIn cut {}", nEntries[m], BurnIn[m]);
431  MACH3LOG_ERROR("You will run into the infinite loop");
432  MACH3LOG_ERROR("You can make a new chain or modify BurnIn cut");
433  throw MaCh3Exception(__FILE__ , __LINE__ );
434  }
435 
436  MACH3LOG_INFO("Loading chain {} / {}...", m, Nchains);
437  for (int i = 0; i < Ntoys_requested[m]; i++)
438  {
439  // This is here as a placeholder in case we want to do some thinning later
440  int entry = i*NThin;
441 
442  Chain->GetEntry(entry);
443 
444  // If we have combined chains by hadd need to check the step in the chain
445  // 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 :(
446  if (step[m] < BurnIn[m])
447  {
448  continue;
449  }
450 
451  // Output some info for the user
452  if (Ntoys_requested[m] > 10 && i % (Ntoys_requested[m]/10) == 0) {
453  M3::Utils::PrintProgressBar(i+m*Ntoys_requested[m], static_cast<Long64_t>(Ntoys_requested[m])*Nchains);
454  MACH3LOG_DEBUG("Getting random entry {}", entry);
455  }
456 
457  // MJR: Fill running quantities instead of loading everything into RAM.
458  // This is where we save big on both memory and time (resetting
459  // branch addresses and calling GetEntry() again here is very slow).
460  for (int j = 0; j < nDraw; ++j)
461  {
462  S1_global[j] += branch_values[j];
463  S2_global[j] += branch_values[j]*branch_values[j];
464  S1_chain[m][j] += branch_values[j];
465  S2_chain[m][j] += branch_values[j]*branch_values[j];
466  }
467 
468  // Increment counters
469  Ntoys_filled[m]++;
470  TotToys++;
471  }//end loop over toys
472 
473  //TN: There, we now don't need to keep the chain in memory anymore
474  delete Chain;
475  MACH3LOG_INFO("Finished loading chain {}!", m);
476  }
477 
478  clock.Stop();
479  MACH3LOG_INFO("Finished calculating Toys, it took {:.2f}s to finish", clock.RealTime());
480 }
#define MACH3LOG_DEBUG
Definition: MaCh3Logger.h:34
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
Custom exception class used throughout MaCh3.
std::vector< double > S2_global
Sum_i^N x_i^2 | total.
std::vector< bool > ValidPar
std::vector< TString > BranchNames
std::vector< int > Ntoys_requested
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.
Definition: Monitor.cpp:229

◆ PrepareChains_HighMem()

void RHatCalculator::PrepareChains_HighMem ( )
private

Load chain and prepare toys.

Definition at line 83 of file RHatCalculator.cpp.

83  {
84 // *******************
85  auto rnd = std::make_unique<TRandom3>(0);
86 
87  MACH3LOG_INFO("Generating {}", Ntoys);
88 
89  TStopwatch clock;
90  clock.Start();
91 
92  std::vector<unsigned int> BurnIn(Nchains);
93  std::vector<unsigned int> nEntries(Nchains);
94  std::vector<int> nBranches(Nchains);
95  std::vector<unsigned int> step(Nchains);
96 
97  Draws.resize(Nchains);
98  DrawsFolded.resize(Nchains);
99 
100  std::unique_ptr<MCMCProcessor> Processor;
101 
102  // Open the Chain
103  //It is tempting to multithread here but unfortunately, ROOT files are not thread safe :(
104  for (int m = 0; m < Nchains; m++)
105  {
106  MACH3LOG_INFO("On file: {}", MCMCFile[m].c_str());
107  if (!std::filesystem::exists(MCMCFile[m])) {
108  MACH3LOG_ERROR("File: {}, doesn't exist", MCMCFile[m]);
109  throw MaCh3Exception(__FILE__, __LINE__);
110  }
111  TChain* Chain = new TChain("posteriors");
112  Chain->Add(MCMCFile[m].c_str());
113  nEntries[m] = static_cast<unsigned int>(Chain->GetEntries());
114 
115  // Set the step cut to be 20%
116  BurnIn[m] = nEntries[m]/5;
117 
118  // Get the list of branches
119  TObjArray* brlis = Chain->GetListOfBranches();
120 
121  // Get the number of branches
122  nBranches[m] = brlis->GetEntries();
123 
124  // Set all the branches to off
125  Chain->SetBranchStatus("*", false);
126 
127  std::vector<TString> SampleLLH;
128  std::vector<TString> SystLLH;
129 
130  if(m == 0) {
131  Processor = std::make_unique<MCMCProcessor>(MCMCFile[m]);
132  Processor->Initialise();
133  nDraw = Processor->GetNParams();
134  SampleLLH = Processor->GetSampleBranchNames();
135  SystLLH = Processor->GetSystBranchNames();
136  nDraw = nDraw + static_cast<int>(SampleLLH.size()) + static_cast<int>(SystLLH.size());
137  BranchNames.reserve(nDraw);
138  }
139 
140  // Set all the branches to off
141  Chain->SetBranchStatus("*", false);
142 
143  // Loop over the number of branches
144  // Find the name and how many of each systematic we have
145  for (int i = 0; i < Processor->GetNParams(); i++)
146  {
147  TString bname = Processor->GetBranchNames()[i];
148  //KS: Save branch name only for one chain, we assume all chains have the same branches, otherwise this doesn't make sense either way
149  if(m == 0) {
150  BranchNames.push_back(bname);
151  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
152  ValidPar.push_back(true);
153  }
154  Chain->SetBranchStatus(bname, true);
155  // Get the TBranch and its name
156  if (!Chain->GetBranch(bname)) {
157  MACH3LOG_ERROR("Branch '{}' does not exist in the TChain", bname.Data());
158  throw MaCh3Exception(__FILE__, __LINE__);
159  }
160  MACH3LOG_DEBUG("{}", bname);
161  }
162 
163  for (size_t i = 0; i < SampleLLH.size(); ++i) {
164  TString bname = SampleLLH[i];
165  Chain->SetBranchStatus(bname, true);
166  if(m == 0) {
167  BranchNames.push_back(bname);
168  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
169  ValidPar.push_back(false);
170  }
171  }
172  for (size_t i = 0; i < SystLLH.size(); ++i) {
173  TString bname = SystLLH[i];
174  Chain->SetBranchStatus(bname, true);
175  if(m == 0) {
176  BranchNames.push_back(bname);
177  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
178  ValidPar.push_back(false);
179  }
180  }
181  // Read in the step
182  Chain->SetBranchStatus("step", true);
183  Chain->SetBranchAddress("step", &step[m]);
184  //TN: Qualitatively faster sanity check, with the very same outcome (all chains have the same #branches)
185  if(m > 0)
186  {
187  if(nBranches[m] != nBranches[0])
188  {
189  MACH3LOG_ERROR("Ups, something went wrong, chain {} called {} has {} branches, while 0 called {} has {} branches", m, MCMCFile[m], nBranches[m], MCMCFile[0], nBranches[0]);
190  MACH3LOG_ERROR("All chains should have the same number of branches");
191  throw MaCh3Exception(__FILE__ , __LINE__ );
192  }
193  }
194 
195  //TN: move the Draws here, so we need to iterate over every chain only once
196  Draws[m].resize(Ntoys);
197  DrawsFolded[m].resize(Ntoys);
198  for(int i = 0; i < Ntoys; i++)
199  {
200  Draws[m][i].resize(nDraw, 0.0);
201  DrawsFolded[m][i].resize(nDraw, 0.0);
202  }
203 
204  // MJR: array to hold branch values; SetBranchAddress in every step is very
205  // expensive, so doing it once only here saves time
206  std::vector<double> branch_values(nDraw, 0.0);
207  for (int j = 0; j < nDraw; ++j) {
208  Chain->SetBranchAddress(BranchNames[j].Data(), &branch_values[j]);
209  }
210 
211  //TN: move looping over toys here, so we don't need to loop over chains more than once
212  if(BurnIn[m] >= nEntries[m])
213  {
214  MACH3LOG_ERROR("You are running on a chain shorter than BurnIn cut");
215  MACH3LOG_ERROR("Number of entries {} BurnIn cut {}", nEntries[m], BurnIn[m]);
216  MACH3LOG_ERROR("You will run into the infinite loop");
217  MACH3LOG_ERROR("You can make a new chain or modify BurnIn cut");
218  throw MaCh3Exception(__FILE__ , __LINE__ );
219  }
220 
221  for (int i = 0; i < Ntoys; i++)
222  {
223  // Get a random entry after burn in
224  int entry = int(nEntries[m]*rnd->Rndm());
225 
226  Chain->GetEntry(entry);
227 
228  // If we have combined chains by hadd need to check the step in the chain
229  // 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 :(
230  if (step[m] < BurnIn[m]) {
231  i--;
232  continue;
233  }
234 
235  // Output some info for the user
236  if (Ntoys > 10 && i % (Ntoys/10) == 0) {
237  M3::Utils::PrintProgressBar(i+m*Ntoys, static_cast<Long64_t>(Ntoys)*Nchains);
238  MACH3LOG_DEBUG("Getting random entry {}", entry);
239  }
240 
241  // Set the branch addresses for params
242  for (int j = 0; j < nDraw; ++j) {
243  Draws[m][i][j] = branch_values[j];
244  }
245  }//end loop over toys
246 
247  //TN: There, we now don't need to keep the chain in memory anymore
248  delete Chain;
249  }
250 
251  //KS: Now prepare folded draws, quoting Gelman
252  //"We propose to report the maximum of rank normalized split-Rb and rank normalized folded-split-Rb for each parameter"
253  MedianArr.resize(nDraw);
254  #ifdef MULTITHREAD
255  #pragma omp parallel for
256  #endif
257  for(int j = 0; j < nDraw; j++)
258  {
259  MedianArr[j] = 0.;
260  std::vector<double> TempDraws(static_cast<size_t>(Ntoys) * Nchains);
261  for(int m = 0; m < Nchains; m++)
262  {
263  for(int i = 0; i < Ntoys; i++)
264  {
265  const int im = i+m;
266  TempDraws[im] = Draws[m][i][j];
267  }
268  }
269  MedianArr[j] = CalcMedian(TempDraws.data(), Ntoys*Nchains);
270  }
271 
272  #ifdef MULTITHREAD
273  #pragma omp parallel for collapse(3)
274  #endif
275  for(int m = 0; m < Nchains; m++)
276  {
277  for(int i = 0; i < Ntoys; i++)
278  {
279  for(int j = 0; j < nDraw; j++)
280  {
281  DrawsFolded[m][i][j] = std::fabs(Draws[m][i][j] - MedianArr[j]);
282  }
283  }
284  }
285  clock.Stop();
286  MACH3LOG_INFO("Finished calculating Toys, it took {:.2f}s to finish", clock.RealTime());
287 }
double CalcMedian(double arr[], const int size)
std::vector< double > MedianArr

◆ RunDiagnostic()

void RHatCalculator::RunDiagnostic ( )

Definition at line 62 of file RHatCalculator.cpp.

62  {
63 // *******************
64  if(HighMemoryMode) {
66  } else {
67  PrepareChains();
68  }
69 
71 
72  //KS: Main function
73  if(HighMemoryMode) {
75  } else {
76  CalcRhat();
77  }
78  SaveResults();
79 }
void PrepareChains()
Load chain and prepare toys.
void PrepareChains_HighMem()
Load chain and prepare toys.
void CalcRhat_HighMem()
KS: Based on Gelman et. al. arXiv:1903.08008v5.
void CalcRhat()
KS: Based on Gelman et. al. arXiv:1903.08008v5.
void InitialiseArrays()
Create all arrays we are going to use later.

◆ SaveResults()

void RHatCalculator::SaveResults ( )
private

Definition at line 776 of file RHatCalculator.cpp.

776  {
777 // *******************
778  #pragma GCC diagnostic push
779  #pragma GCC diagnostic ignored "-Wfloat-conversion"
780 
781  std::string NameTemp = "";
782  //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 :(
783  if(Nchains < 5)
784  {
785  for (int i = 0; i < Nchains; i++)
786  {
787  std::string temp = MCMCFile[i];
788 
789  while (temp.find(".root") != std::string::npos) {
790  temp = temp.substr(0, temp.find(".root"));
791  }
792  // Strip directory path
793  const auto slash = temp.find_last_of("/\\");
794  if (slash != std::string::npos) {
795  temp = temp.substr(slash + 1);
796  }
797 
798  NameTemp = NameTemp + temp + "_";
799  }
800  }
801  else {
802  NameTemp = std::to_string(Nchains) + "Chains" + "_";
803  }
804  NameTemp += "diag.root";
805 
806  TFile *DiagFile = M3::Open(NameTemp, "recreate", __FILE__, __LINE__);
807  DiagFile->cd();
808 
809  TH1D *StandardDeviationGlobalPlot = new TH1D("StandardDeviationGlobalPlot", "StandardDeviationGlobalPlot", nDraw, 0, nDraw);
810  TH1D *BetweenChainVariancePlot = new TH1D("BetweenChainVariancePlot", "BetweenChainVariancePlot", nDraw, 0, nDraw);
811  TH1D *MarginalPosteriorVariancePlot = new TH1D("MarginalPosteriorVariancePlot", "MarginalPosteriorVariancePlot", nDraw, 0, nDraw);
812  TH1D *RhatPlot = new TH1D("RhatPlot", "RhatPlot", 200, 0, 2);
813  TH1D *EffectiveSampleSizePlot = new TH1D("EffectiveSampleSizePlot", "EffectiveSampleSizePlot", 400, 0, 10000);
814 
815  TH1D *RhatLogPlot = new TH1D("RhatLogPlot", "RhatLogPlot", 200, 0, 2);
816 
817  TH1D *StandardDeviationGlobalFoldedPlot = nullptr;
818  TH1D *BetweenChainVarianceFoldedPlot = nullptr;
819  TH1D *MarginalPosteriorVarianceFoldedPlot = nullptr;
820  TH1D *RhatFoldedPlot = nullptr;
821  TH1D *EffectiveSampleSizeFoldedPlot = nullptr;
822  TH1D *RhatFoldedLogPlot = nullptr;
823 
824  if (HighMemoryMode)
825  {
826  StandardDeviationGlobalFoldedPlot = new TH1D("StandardDeviationGlobalFoldedPlot", "StandardDeviationGlobalFoldedPlot", nDraw, 0, nDraw);
827  BetweenChainVarianceFoldedPlot = new TH1D("BetweenChainVarianceFoldedPlot", "BetweenChainVarianceFoldedPlot", nDraw, 0, nDraw);
828  MarginalPosteriorVarianceFoldedPlot = new TH1D("MarginalPosteriorVarianceFoldedPlot", "MarginalPosteriorVarianceFoldedPlot", nDraw, 0, nDraw);
829  RhatFoldedPlot = new TH1D("RhatFoldedPlot", "RhatFoldedPlot", 200, 0, 2);
830  EffectiveSampleSizeFoldedPlot = new TH1D("EffectiveSampleSizeFoldedPlot", "EffectiveSampleSizeFoldedPlot", 400, 0, 10000);
831  RhatFoldedLogPlot = new TH1D("RhatFoldedLogPlot", "RhatFoldedLogPlot", 200, 0, 2);
832  }
833 
834  int Criterium = 0;
835  int CiteriumFolded = 0;
836  for(int j = 0; j < nDraw; j++)
837  {
838  //KS: Fill only valid parameters
839  if(ValidPar[j])
840  {
841  StandardDeviationGlobalPlot->Fill(j,StandardDeviationGlobal[j]);
842  BetweenChainVariancePlot->Fill(j,BetweenChainVariance[j]);
843  MarginalPosteriorVariancePlot->Fill(j,MarginalPosteriorVariance[j]);
844  RhatPlot->Fill(RHat[j]);
845  EffectiveSampleSizePlot->Fill(EffectiveSampleSize[j]);
846  if(RHat[j] > 1.1) Criterium++;
847  if(HighMemoryMode) {
848  StandardDeviationGlobalFoldedPlot->Fill(j,StandardDeviationGlobalFolded[j]);
849  BetweenChainVarianceFoldedPlot->Fill(j,BetweenChainVarianceFolded[j]);
850  MarginalPosteriorVarianceFoldedPlot->Fill(j,MarginalPosteriorVarianceFolded[j]);
851  RhatFoldedPlot->Fill(RHatFolded[j]);
852  EffectiveSampleSizeFoldedPlot->Fill(EffectiveSampleSizeFolded[j]);
853  if(RHatFolded[j] > 1.1) CiteriumFolded++;
854  }
855  }
856  else
857  {
858  RhatLogPlot->Fill(RHat[j]);
859  if(HighMemoryMode) RhatFoldedLogPlot->Fill(RHatFolded[j]);
860  }
861  }
862 
863  if (HighMemoryMode)
864  {
865  //KS: We set criterium of 1.1 based on Gelman et al. (2003) Bayesian Data Analysis
866  MACH3LOG_WARN("Number of parameters which has R hat greater than 1.1 is {}({:.2f}%) while for R hat folded {}({:.2f}%)",
867  Criterium, 100*double(Criterium)/double(nDraw), CiteriumFolded, 100*double(CiteriumFolded)/double(nDraw));
868  for(int j = 0; j < nDraw; j++)
869  {
870  if( (RHat[j] > 1.1 || RHatFolded[j] > 1.1) && ValidPar[j])
871  {
872  MACH3LOG_CRITICAL("Parameter {} has R hat higher than 1.1", BranchNames[j]);
873  }
874  }
875  }
876  else
877  {
878  //KS: We set criterium of 1.1 based on Gelman et al. (2003) Bayesian Data Analysis
879  MACH3LOG_WARN("Number of parameters which has R hat greater than 1.1 is {}({:.2f}%)", Criterium, 100*double(Criterium)/double(nDraw));
880  for(int j = 0; j < nDraw; j++)
881  {
882  if( (RHat[j] > 1.1) && ValidPar[j])
883  {
884  MACH3LOG_CRITICAL("Parameter {} has R hat higher than 1.1", BranchNames[j]);
885  }
886  }
887  }
888 
889  StandardDeviationGlobalPlot->Write();
890  BetweenChainVariancePlot->Write();
891  MarginalPosteriorVariancePlot->Write();
892  RhatPlot->Write();
893  EffectiveSampleSizePlot->Write();
894 
895  RhatLogPlot->Write();
896 
897  if (HighMemoryMode)
898  {
899  StandardDeviationGlobalFoldedPlot->Write();
900  BetweenChainVarianceFoldedPlot->Write();
901  MarginalPosteriorVarianceFoldedPlot->Write();
902  RhatFoldedPlot->Write();
903  EffectiveSampleSizeFoldedPlot->Write();
904 
905  RhatFoldedLogPlot->Write();
906  }
907 
908  //KS: Now we make fancy canvases, consider some function to have less copy pasting
909  auto TempCanvas = std::make_unique<TCanvas>("Canvas", "Canvas", 1024, 1024);
910  gStyle->SetOptStat(0);
911  TempCanvas->SetGridx();
912  TempCanvas->SetGridy();
913 
914  // Random line to write useful information to TLegend
915  auto TempLine = std::make_unique<TLine>(0, 0, 0, 0);
916  TempLine->SetLineColor(kBlack);
917 
918  RhatPlot->GetXaxis()->SetTitle("R hat");
919  RhatPlot->SetLineColor(kRed);
920  RhatPlot->SetFillColor(kRed);
921 
922  if(HighMemoryMode){
923  RhatFoldedPlot->SetLineColor(kBlue);
924  RhatFoldedPlot->SetFillColor(kBlue);
925  }
926 
927  TLegend Legend(0.55, 0.6, 0.9, 0.9);
928  Legend.SetTextSize(0.04);
929  Legend.SetFillColor(0);
930  Legend.SetFillStyle(0);
931  Legend.SetLineWidth(0);
932  Legend.SetLineColor(0);
933 
934  Legend.AddEntry(TempLine.get(), Form("Number of throws=%.0i, Number of chains=%.1i", TotToys, Nchains), "");
935  Legend.AddEntry(RhatPlot, "Rhat Gelman 2013", "l");
936  if(HighMemoryMode) Legend.AddEntry(RhatFoldedPlot, "Rhat-Folded Gelman 2021", "l");
937 
938  RhatPlot->Draw();
939  Legend.Draw("same");
940  if(HighMemoryMode) RhatFoldedPlot->Draw("same");
941  TempCanvas->Write("Rhat");
942 
943  //Now R hat for log L
944  RhatLogPlot->GetXaxis()->SetTitle("R hat for LogL");
945  RhatLogPlot->SetLineColor(kRed);
946  RhatLogPlot->SetFillColor(kRed);
947  if(HighMemoryMode) RhatFoldedLogPlot->SetLineColor(kBlue);
948  if(HighMemoryMode) RhatFoldedLogPlot->SetFillColor(kBlue);
949 
950  TLegend LegendFolded(0.55, 0.6, 0.9, 0.9);
951 
952  LegendFolded.SetTextSize(0.04);
953  LegendFolded.SetFillColor(0);
954  LegendFolded.SetFillStyle(0);
955  LegendFolded.SetLineWidth(0);
956  LegendFolded.SetLineColor(0);
957 
958  LegendFolded.AddEntry(TempLine.get(), Form("Number of throws=%.0i, Number of chains=%.1i", TotToys, Nchains), "");
959  LegendFolded.AddEntry(RhatLogPlot, "Rhat Gelman 2013", "l");
960  if(HighMemoryMode) LegendFolded.AddEntry(RhatFoldedLogPlot, "Rhat-Folded Gelman 2021", "l");
961 
962  RhatLogPlot->Draw();
963  LegendFolded.Draw("same");
964  TempCanvas->Write("RhatLog");
965 
966  //Now canvas for effective sample size
967  EffectiveSampleSizePlot->GetXaxis()->SetTitle("S_{eff, BDA2}");
968  EffectiveSampleSizePlot->SetLineColor(kRed);
969  if(HighMemoryMode) EffectiveSampleSizeFoldedPlot->SetLineColor(kBlue);
970 
971  TLegend LegendESS(0.45, 0.6, 0.9, 0.9);
972  LegendESS.SetTextSize(0.03);
973  LegendESS.SetFillColor(0);
974  LegendESS.SetFillStyle(0);
975  LegendESS.SetLineWidth(0);
976  LegendESS.SetLineColor(0);
977 
978  const double Mean1 = EffectiveSampleSizePlot->GetMean();
979  const double RMS1 = EffectiveSampleSizePlot->GetRMS();
980 
981  LegendESS.AddEntry(TempLine.get(), Form("Number of throws=%.0i, Number of chains=%.1i", TotToys, Nchains), "");
982  LegendESS.AddEntry(EffectiveSampleSizePlot, Form("S_{eff, BDA2} #mu = %.2f, #sigma = %.2f",Mean1 ,RMS1), "l");
983  if (HighMemoryMode)
984  {
985  const double Mean2 = EffectiveSampleSizeFoldedPlot->GetMean();
986  const double RMS2 = EffectiveSampleSizeFoldedPlot->GetRMS();
987  LegendESS.AddEntry(EffectiveSampleSizeFoldedPlot, Form("S_{eff, BDA2} Folded, #mu = %.2f, #sigma = %.2f", Mean2, RMS2), "l");
988  }
989  EffectiveSampleSizePlot->Draw();
990  LegendESS.Draw("same");
991  if(HighMemoryMode) EffectiveSampleSizeFoldedPlot->Draw("same");
992  TempCanvas->Write("EffectiveSampleSize");
993 
994 
995  //Fancy memory cleaning
996  delete StandardDeviationGlobalPlot;
997  delete BetweenChainVariancePlot;
998  delete MarginalPosteriorVariancePlot;
999  delete RhatPlot;
1000  delete EffectiveSampleSizePlot;
1001 
1002  delete RhatLogPlot;
1003 
1004  if (HighMemoryMode)
1005  {
1006  delete StandardDeviationGlobalFoldedPlot;
1007  delete BetweenChainVarianceFoldedPlot;
1008  delete MarginalPosteriorVarianceFoldedPlot;
1009  delete RhatFoldedPlot;
1010  delete EffectiveSampleSizeFoldedPlot;
1011 
1012  delete RhatFoldedLogPlot;
1013  }
1014 
1015  DiagFile->Close();
1016  delete DiagFile;
1017 
1018  MACH3LOG_INFO("Finished and wrote results to {}", NameTemp);
1019  #pragma GCC diagnostic pop
1020 }
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:38
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36
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.

Member Data Documentation

◆ BetweenChainVariance

std::vector<double> RHatCalculator::BetweenChainVariance
private

Definition at line 57 of file RHatCalculator.h.

◆ BetweenChainVarianceFolded

std::vector<double> RHatCalculator::BetweenChainVarianceFolded
private

Definition at line 75 of file RHatCalculator.h.

◆ BranchNames

std::vector<TString> RHatCalculator::BranchNames
private

Definition at line 47 of file RHatCalculator.h.

◆ Draws

std::vector<std::vector<std::vector<double> > > RHatCalculator::Draws
private

Definition at line 64 of file RHatCalculator.h.

◆ DrawsFolded

std::vector<std::vector<std::vector<double> > > RHatCalculator::DrawsFolded
private

Definition at line 65 of file RHatCalculator.h.

◆ EffectiveSampleSize

std::vector<double> RHatCalculator::EffectiveSampleSize
private

Definition at line 60 of file RHatCalculator.h.

◆ EffectiveSampleSizeFolded

std::vector<double> RHatCalculator::EffectiveSampleSizeFolded
private

Definition at line 78 of file RHatCalculator.h.

◆ HighMemoryMode

bool RHatCalculator::HighMemoryMode
private

Definition at line 43 of file RHatCalculator.h.

◆ MarginalPosteriorVariance

std::vector<double> RHatCalculator::MarginalPosteriorVariance
private

Definition at line 58 of file RHatCalculator.h.

◆ MarginalPosteriorVarianceFolded

std::vector<double> RHatCalculator::MarginalPosteriorVarianceFolded
private

Definition at line 76 of file RHatCalculator.h.

◆ MCMCFile

std::vector<std::string> RHatCalculator::MCMCFile
private

Definition at line 48 of file RHatCalculator.h.

◆ Mean

std::vector<std::vector<double> > RHatCalculator::Mean
private

Definition at line 51 of file RHatCalculator.h.

◆ MeanFolded

std::vector<std::vector<double> > RHatCalculator::MeanFolded
private

Definition at line 69 of file RHatCalculator.h.

◆ MeanGlobal

std::vector<double> RHatCalculator::MeanGlobal
private

Definition at line 54 of file RHatCalculator.h.

◆ MeanGlobalFolded

std::vector<double> RHatCalculator::MeanGlobalFolded
private

Definition at line 72 of file RHatCalculator.h.

◆ MedianArr

std::vector<double> RHatCalculator::MedianArr
private

Definition at line 67 of file RHatCalculator.h.

◆ Nchains

int RHatCalculator::Nchains
private

Definition at line 45 of file RHatCalculator.h.

◆ nDraw

int RHatCalculator::nDraw
private

Definition at line 44 of file RHatCalculator.h.

◆ NThin

unsigned int RHatCalculator::NThin
private

Definition at line 84 of file RHatCalculator.h.

◆ Ntoys

int RHatCalculator::Ntoys
private

Definition at line 63 of file RHatCalculator.h.

◆ Ntoys_filled

std::vector<int> RHatCalculator::Ntoys_filled
private

Definition at line 82 of file RHatCalculator.h.

◆ Ntoys_requested

std::vector<int> RHatCalculator::Ntoys_requested
private

Definition at line 81 of file RHatCalculator.h.

◆ RHat

std::vector<double> RHatCalculator::RHat
private

Definition at line 59 of file RHatCalculator.h.

◆ RHatFolded

std::vector<double> RHatCalculator::RHatFolded
private

Definition at line 77 of file RHatCalculator.h.

◆ S1_chain

std::vector<std::vector<double> > RHatCalculator::S1_chain
private

Sum_i^N x_i | for each chain.

Definition at line 91 of file RHatCalculator.h.

◆ S1_global

std::vector<double> RHatCalculator::S1_global
private

Sum_i^N x_i | total.

Definition at line 87 of file RHatCalculator.h.

◆ S2_chain

std::vector<std::vector<double> > RHatCalculator::S2_chain
private

Sum_i^N x_i^2 | for each chain.

Definition at line 93 of file RHatCalculator.h.

◆ S2_global

std::vector<double> RHatCalculator::S2_global
private

Sum_i^N x_i^2 | total.

Definition at line 89 of file RHatCalculator.h.

◆ StandardDeviation

std::vector<std::vector<double> > RHatCalculator::StandardDeviation
private

Definition at line 52 of file RHatCalculator.h.

◆ StandardDeviationFolded

std::vector<std::vector<double> > RHatCalculator::StandardDeviationFolded
private

Definition at line 70 of file RHatCalculator.h.

◆ StandardDeviationGlobal

std::vector<double> RHatCalculator::StandardDeviationGlobal
private

Definition at line 55 of file RHatCalculator.h.

◆ StandardDeviationGlobalFolded

std::vector<double> RHatCalculator::StandardDeviationGlobalFolded
private

Definition at line 73 of file RHatCalculator.h.

◆ TotToys

int RHatCalculator::TotToys
private

Definition at line 83 of file RHatCalculator.h.

◆ ValidPar

std::vector<bool> RHatCalculator::ValidPar
private

Definition at line 49 of file RHatCalculator.h.


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