MaCh3  2.8.0
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/Processing/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.

[39].

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 522 of file RHatCalculator.cpp.

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

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

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

◆ PrepareChains()

void RHatCalculator::PrepareChains ( )
private

Load chain and prepare toys.

Definition at line 290 of file RHatCalculator.cpp.

290  {
291 // *******************
292  TStopwatch clock;
293  clock.Start();
294 
295  Ntoys_requested.resize(Nchains);
296  Ntoys_filled.resize(Nchains);
297  TotToys = 0;
298  std::vector<unsigned int> BurnIn(Nchains);
299  std::vector<unsigned int> nEntries(Nchains);
300  std::vector<int> nBranches(Nchains);
301  std::vector<unsigned int> step(Nchains);
302 
303  S1_chain.resize(Nchains);
304  S2_chain.resize(Nchains);
305 
306  std::unique_ptr<MCMCProcessor> Processor;
307 
308  // Open the Chain
309  //It is tempting to multithread here but unfortunately, ROOT files are not thread safe :(
310  for (int m = 0; m < Nchains; m++)
311  {
312  MACH3LOG_INFO("On file: {}", MCMCFile[m].c_str());
313  if (!std::filesystem::exists(MCMCFile[m])) {
314  MACH3LOG_ERROR("File: {}, doesn't exist", MCMCFile[m]);
315  throw MaCh3Exception(__FILE__, __LINE__);
316  }
317  TChain* Chain = new TChain("posteriors");
318  Chain->Add(MCMCFile[m].c_str());
319 
320  nEntries[m] = static_cast<unsigned int>(Chain->GetEntries());
321  Ntoys_requested[m] = nEntries[m]/NThin;
322  Ntoys_filled[m] = 0;
323 
324  MACH3LOG_INFO("On file: {}", MCMCFile[m].c_str());
325  MACH3LOG_INFO("Generating {} Toys", Ntoys_requested[m]);
326 
327  // Set the step cut to be 20%
328  BurnIn[m] = nEntries[m]/5;
329 
330  // Get the list of branches
331  TObjArray* brlis = Chain->GetListOfBranches();
332 
333  // Get the number of branches
334  nBranches[m] = brlis->GetEntries();
335 
336  // Set all the branches to off
337  Chain->SetBranchStatus("*", false);
338 
339  std::vector<TString> SampleLLH;
340  std::vector<TString> SystLLH;
341 
342  if(m == 0) {
343  Processor = std::make_unique<MCMCProcessor>(MCMCFile[m]);
344  Processor->Initialise();
345  nDraw = Processor->GetNParams();
346  SampleLLH = Processor->GetSampleBranchNames();
347  SystLLH = Processor->GetSystBranchNames();
348  nDraw = nDraw + static_cast<int>(SampleLLH.size()) + static_cast<int>(SystLLH.size());
349  BranchNames.reserve(nDraw);
350  }
351 
352  // Set all the branches to off
353  Chain->SetBranchStatus("*", false);
354 
355  // Loop over the number of branches
356  // Find the name and how many of each systematic we have
357  for (int i = 0; i < Processor->GetNParams(); i++)
358  {
359  TString bname = Processor->GetBranchNames()[i];
360  //KS: Save branch name only for one chain, we assume all chains have the same branches, otherwise this doesn't make sense either way
361  if(m == 0) {
362  BranchNames.push_back(bname);
363  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
364  ValidPar.push_back(true);
365  }
366  Chain->SetBranchStatus(bname, true);
367 
368  // Get the TBranch and its name
369  if (!Chain->GetBranch(bname)) {
370  MACH3LOG_ERROR("Branch '{}' does not exist in the TChain", bname.Data());
371  throw MaCh3Exception(__FILE__, __LINE__);
372  }
373  MACH3LOG_DEBUG("{}", bname);
374  }
375 
376  for (size_t i = 0; i < SampleLLH.size(); ++i) {
377  TString bname = SampleLLH[i];
378  Chain->SetBranchStatus(bname, true);
379  if(m == 0) {
380  BranchNames.push_back(bname);
381  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
382  ValidPar.push_back(false);
383  }
384  }
385  for (size_t i = 0; i < SystLLH.size(); ++i) {
386  TString bname = SystLLH[i];
387  Chain->SetBranchStatus(bname, true);
388  if(m == 0) {
389  BranchNames.push_back(bname);
390  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
391  ValidPar.push_back(false);
392  }
393  }
394  // Read in the step
395  Chain->SetBranchStatus("step", true);
396  Chain->SetBranchAddress("step", &step[m]);
397  // MJR: Initialize quantities needed for calculating RHat
398  S1_chain[m].resize(nDraw, 0);
399  S2_chain[m].resize(nDraw, 0);
400  if (m == 0)
401  {
402  S1_global.resize(nDraw, 0);
403  S2_global.resize(nDraw, 0);
404  }
405 
406  //TN: Qualitatively faster sanity check, with the very same outcome (all chains have the same #branches)
407  if(m > 0)
408  {
409  if(nBranches[m] != nBranches[0])
410  {
411  MACH3LOG_ERROR("Ups, something went wrong, chain {} called {} has {} branches, while 0 called {} has {} branches", m, MCMCFile[m], nBranches[m], MCMCFile[0], nBranches[0]);
412  MACH3LOG_ERROR("All chains should have the same number of branches");
413  throw MaCh3Exception(__FILE__ , __LINE__ );
414  }
415  }
416 
417  // MJR: Create an array to hold branch values. Resetting branch addresses
418  // for every step is very expensive.
419  std::vector<double> branch_values(nDraw, 0.0);
420  for (int id = 0; id < nDraw; ++id) {
421  Chain->SetBranchAddress(BranchNames[id].Data(), &branch_values[id]);
422  }
423 
424  //TN: move looping over toys here, so we don't need to loop over chains more than once
425  if(BurnIn[m] >= nEntries[m])
426  {
427  MACH3LOG_ERROR("You are running on a chain shorter than BurnIn cut");
428  MACH3LOG_ERROR("Number of entries {} BurnIn cut {}", nEntries[m], BurnIn[m]);
429  MACH3LOG_ERROR("You will run into the infinite loop");
430  MACH3LOG_ERROR("You can make a new chain or modify BurnIn cut");
431  throw MaCh3Exception(__FILE__ , __LINE__ );
432  }
433 
434  MACH3LOG_INFO("Loading chain {} / {}...", m, Nchains);
435  for (int i = 0; i < Ntoys_requested[m]; i++)
436  {
437  // This is here as a placeholder in case we want to do some thinning later
438  int entry = i*NThin;
439 
440  Chain->GetEntry(entry);
441 
442  // If we have combined chains by hadd need to check the step in the chain
443  // 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 :(
444  if (step[m] < BurnIn[m])
445  {
446  continue;
447  }
448 
449  // Output some info for the user
450  if (Ntoys_requested[m] > 10 && i % (Ntoys_requested[m]/10) == 0) {
451  M3::Utils::PrintProgressBar(i+m*Ntoys_requested[m], static_cast<Long64_t>(Ntoys_requested[m])*Nchains);
452  MACH3LOG_DEBUG("Getting random entry {}", entry);
453  }
454 
455  // MJR: Fill running quantities instead of loading everything into RAM.
456  // This is where we save big on both memory and time (resetting
457  // branch addresses and calling GetEntry() again here is very slow).
458  for (int j = 0; j < nDraw; ++j)
459  {
460  S1_global[j] += branch_values[j];
461  S2_global[j] += branch_values[j]*branch_values[j];
462  S1_chain[m][j] += branch_values[j];
463  S2_chain[m][j] += branch_values[j]*branch_values[j];
464  }
465 
466  // Increment counters
467  Ntoys_filled[m]++;
468  TotToys++;
469  }//end loop over toys
470 
471  //TN: There, we now don't need to keep the chain in memory anymore
472  delete Chain;
473  MACH3LOG_INFO("Finished loading chain {}!", m);
474  }
475 
476  clock.Stop();
477  MACH3LOG_INFO("Finished calculating Toys, it took {:.2f}s to finish", clock.RealTime());
478 }
#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  MACH3LOG_INFO("Generating {}", Ntoys);
86 
87  TStopwatch clock;
88  clock.Start();
89 
90  std::vector<unsigned int> BurnIn(Nchains);
91  std::vector<unsigned int> nEntries(Nchains);
92  std::vector<int> nBranches(Nchains);
93  std::vector<unsigned int> step(Nchains);
94 
95  Draws.resize(Nchains);
96  DrawsFolded.resize(Nchains);
97 
98  std::unique_ptr<MCMCProcessor> Processor;
99 
100  // Open the Chain
101  //It is tempting to multithread here but unfortunately, ROOT files are not thread safe :(
102  for (int m = 0; m < Nchains; m++)
103  {
104  MACH3LOG_INFO("On file: {}", MCMCFile[m].c_str());
105  if (!std::filesystem::exists(MCMCFile[m])) {
106  MACH3LOG_ERROR("File: {}, doesn't exist", MCMCFile[m]);
107  throw MaCh3Exception(__FILE__, __LINE__);
108  }
109  TChain* Chain = new TChain("posteriors");
110  Chain->Add(MCMCFile[m].c_str());
111  nEntries[m] = static_cast<unsigned int>(Chain->GetEntries());
112 
113  // Set the step cut to be 20%
114  BurnIn[m] = nEntries[m]/5;
115 
116  // Get the list of branches
117  TObjArray* brlis = Chain->GetListOfBranches();
118 
119  // Get the number of branches
120  nBranches[m] = brlis->GetEntries();
121 
122  // Set all the branches to off
123  Chain->SetBranchStatus("*", false);
124 
125  std::vector<TString> SampleLLH;
126  std::vector<TString> SystLLH;
127 
128  if(m == 0) {
129  Processor = std::make_unique<MCMCProcessor>(MCMCFile[m]);
130  Processor->Initialise();
131  nDraw = Processor->GetNParams();
132  SampleLLH = Processor->GetSampleBranchNames();
133  SystLLH = Processor->GetSystBranchNames();
134  nDraw = nDraw + static_cast<int>(SampleLLH.size()) + static_cast<int>(SystLLH.size());
135  BranchNames.reserve(nDraw);
136  }
137 
138  // Set all the branches to off
139  Chain->SetBranchStatus("*", false);
140 
141  // Loop over the number of branches
142  // Find the name and how many of each systematic we have
143  for (int i = 0; i < Processor->GetNParams(); i++)
144  {
145  TString bname = Processor->GetBranchNames()[i];
146  //KS: Save branch name only for one chain, we assume all chains have the same branches, otherwise this doesn't make sense either way
147  if(m == 0) {
148  BranchNames.push_back(bname);
149  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
150  ValidPar.push_back(true);
151  }
152  Chain->SetBranchStatus(bname, true);
153  // Get the TBranch and its name
154  if (!Chain->GetBranch(bname)) {
155  MACH3LOG_ERROR("Branch '{}' does not exist in the TChain", bname.Data());
156  throw MaCh3Exception(__FILE__, __LINE__);
157  }
158  MACH3LOG_DEBUG("{}", bname);
159  }
160 
161  for (size_t i = 0; i < SampleLLH.size(); ++i) {
162  TString bname = SampleLLH[i];
163  Chain->SetBranchStatus(bname, true);
164  if(m == 0) {
165  BranchNames.push_back(bname);
166  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
167  ValidPar.push_back(false);
168  }
169  }
170  for (size_t i = 0; i < SystLLH.size(); ++i) {
171  TString bname = SystLLH[i];
172  Chain->SetBranchStatus(bname, true);
173  if(m == 0) {
174  BranchNames.push_back(bname);
175  //KS: We calculate R Hat also for LogL, just in case, however we plot them separately
176  ValidPar.push_back(false);
177  }
178  }
179  // Read in the step
180  Chain->SetBranchStatus("step", true);
181  Chain->SetBranchAddress("step", &step[m]);
182  //TN: Qualitatively faster sanity check, with the very same outcome (all chains have the same #branches)
183  if(m > 0)
184  {
185  if(nBranches[m] != nBranches[0])
186  {
187  MACH3LOG_ERROR("Ups, something went wrong, chain {} called {} has {} branches, while 0 called {} has {} branches", m, MCMCFile[m], nBranches[m], MCMCFile[0], nBranches[0]);
188  MACH3LOG_ERROR("All chains should have the same number of branches");
189  throw MaCh3Exception(__FILE__ , __LINE__ );
190  }
191  }
192 
193  //TN: move the Draws here, so we need to iterate over every chain only once
194  Draws[m].resize(Ntoys);
195  DrawsFolded[m].resize(Ntoys);
196  for(int i = 0; i < Ntoys; i++)
197  {
198  Draws[m][i].resize(nDraw, 0.0);
199  DrawsFolded[m][i].resize(nDraw, 0.0);
200  }
201 
202  // MJR: array to hold branch values; SetBranchAddress in every step is very
203  // expensive, so doing it once only here saves time
204  std::vector<double> branch_values(nDraw, 0.0);
205  for (int j = 0; j < nDraw; ++j) {
206  Chain->SetBranchAddress(BranchNames[j].Data(), &branch_values[j]);
207  }
208 
209  //TN: move looping over toys here, so we don't need to loop over chains more than once
210  if(BurnIn[m] >= nEntries[m])
211  {
212  MACH3LOG_ERROR("You are running on a chain shorter than BurnIn cut");
213  MACH3LOG_ERROR("Number of entries {} BurnIn cut {}", nEntries[m], BurnIn[m]);
214  MACH3LOG_ERROR("You will run into the infinite loop");
215  MACH3LOG_ERROR("You can make a new chain or modify BurnIn cut");
216  throw MaCh3Exception(__FILE__ , __LINE__ );
217  }
218 
219  for (int i = 0; i < Ntoys; i++)
220  {
221  // Get a random entry after burn in
222  int entry = int(nEntries[m]*M3::rand::Uniform());
223 
224  Chain->GetEntry(entry);
225 
226  // If we have combined chains by hadd need to check the step in the chain
227  // 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 :(
228  if (step[m] < BurnIn[m]) {
229  i--;
230  continue;
231  }
232 
233  // Output some info for the user
234  if (Ntoys > 10 && i % (Ntoys/10) == 0) {
235  M3::Utils::PrintProgressBar(i+m*Ntoys, static_cast<Long64_t>(Ntoys)*Nchains);
236  MACH3LOG_DEBUG("Getting random entry {}", entry);
237  }
238 
239  // Set the branch addresses for params
240  for (int j = 0; j < nDraw; ++j) {
241  Draws[m][i][j] = branch_values[j];
242  }
243  }//end loop over toys
244 
245  //TN: There, we now don't need to keep the chain in memory anymore
246  delete Chain;
247  }
248 
249  //KS: Now prepare folded draws, quoting Gelman
250  //"We propose to report the maximum of rank normalized split-Rb and rank normalized folded-split-Rb for each parameter"
251  MedianArr.resize(nDraw);
252  #ifdef MULTITHREAD
253  #pragma omp parallel for
254  #endif
255  for(int j = 0; j < nDraw; j++)
256  {
257  MedianArr[j] = 0.;
258  std::vector<double> TempDraws(static_cast<size_t>(Ntoys) * Nchains);
259  for(int m = 0; m < Nchains; m++)
260  {
261  for(int i = 0; i < Ntoys; i++)
262  {
263  const int im = i+m;
264  TempDraws[im] = Draws[m][i][j];
265  }
266  }
267  MedianArr[j] = CalcMedian(TempDraws.data(), Ntoys*Nchains);
268  }
269 
270  #ifdef MULTITHREAD
271  #pragma omp parallel for collapse(3)
272  #endif
273  for(int m = 0; m < Nchains; m++)
274  {
275  for(int i = 0; i < Ntoys; i++)
276  {
277  for(int j = 0; j < nDraw; j++)
278  {
279  DrawsFolded[m][i][j] = std::fabs(Draws[m][i][j] - MedianArr[j]);
280  }
281  }
282  }
283  clock.Stop();
284  MACH3LOG_INFO("Finished calculating Toys, it took {:.2f}s to finish", clock.RealTime());
285 }
double CalcMedian(double arr[], const int size)
std::vector< double > MedianArr
double Uniform(const double min=0.0, const double max=1.0)
Generate a uniform random number in [min, max).
Definition: Random.h:116

◆ 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 774 of file RHatCalculator.cpp.

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