ROOT logo
// @(#)root/roostats:$Id: MCMCInterval.cxx 31276 2009-11-18 15:06:42Z moneta $
// Authors: Kevin Belasco        17/06/2009
// Authors: Kyle Cranmer         17/06/2009
/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//_________________________________________________
/*
BEGIN_HTML
<p>
MCMCInterval is a concrete implementation of the RooStats::ConfInterval interface.
It takes as input Markov Chain of data points in the parameter space generated by
Monte Carlo using the Metropolis algorithm.  From the Markov Chain, the confidence
interval can be determined in two ways:
</p>

<p>
Using a Kernel-Estimated PDF: (not the default method)
</p>
<p>
A RooNDKeysPdf is constructed from the data set using adaptive kernel width.
With this RooNDKeysPdf F, we then integrate over the most likely domain in the
parameter space (tallest points in the posterior RooNDKeysPdf) until the target
confidence level is reached within an acceptable neighborhood as defined by
SetEpsilon(). More specifically: we calculate the following for different cutoff
values C until we reach the target confidence level: \int_{ F >= C } F d{normset}.
Important note: this is not the default method because of a bug in constructing
the RooNDKeysPdf from a weighted data set.  Configure to use this method by
calling SetUseKeys(true), and the data set will be interpreted without weights.
</p>

<p>
Using a binned data set: (the default method)
</p>
This is the binned analog of the continuous integrative method that uses the
kernel-estimated PDF.  The points in the Markov Chain are put into a binned
data set and the interval is then calculated by adding the heights of the
bins in decreasing order until the desired level of confidence has been
reached.  Note that this means the actual confidence level is >= the
confidence level prescribed by the client (unless the user calls
SetHistStrict(kFALSE)).  This method is the default but may not remain as such
in future releases, so you may wish to explicitly configure to use this
method by calling SetUseKeys(false)
</p>

<p>
These are not the only ways for the confidence interval to be determined, and
other possibilities are being considered being added, especially for the
1-dimensional case.
</p>

<p>
One can ask an MCMCInterval for the lower and upper limits on a specific
parameter of interest in the interval.  Note that this works better for
some distributions (ones with exactly one local maximum) than others, and sometimes
has little value.
</p>
END_HTML
*/
//_________________________________________________

#ifndef ROOT_Rtypes
#include "Rtypes.h"
#endif

#ifndef ROOT_TMath
#include "TMath.h"
#endif

#ifndef RooStats_MCMCInterval
#include "RooStats/MCMCInterval.h"
#endif
#ifndef ROOSTATS_MarkovChain
#include "RooStats/MarkovChain.h"
#endif
#ifndef RooStats_Heavyside
#include "RooStats/Heavyside.h"
#endif
#ifndef ROO_DATA_HIST
#include "RooDataHist.h"
#endif
#ifndef ROO_KEYS_PDF
#include "RooNDKeysPdf.h"
#endif
#ifndef ROO_PRODUCT
#include "RooProduct.h"
#endif
#ifndef RooStats_RooStatsUtils
#include "RooStats/RooStatsUtils.h"
#endif
#ifndef ROO_REAL_VAR
#include "RooRealVar.h"
#endif
#ifndef ROO_ARG_LIST
#include "RooArgList.h"
#endif
#ifndef ROOT_TIterator
#include "TIterator.h"
#endif
#ifndef ROOT_TH1
#include "TH1.h"
#endif
#ifndef ROOT_TH1F
#include "TH1F.h"
#endif
#ifndef ROOT_TH2F
#include "TH2F.h"
#endif
#ifndef ROOT_TH3F
#include "TH3F.h"
#endif
#ifndef ROO_MSG_SERVICE
#include "RooMsgService.h"
#endif
#ifndef ROO_GLOBAL_FUNC
#include "RooGlobalFunc.h"
#endif
#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_THnSparse
#include "THnSparse.h"
#endif
//#ifndef ROOT_TFile
//#include "TFile.h"
//#endif

#include <cstdlib>
#include <string>
#include <algorithm>

ClassImp(RooStats::MCMCInterval);

using namespace RooFit;
using namespace RooStats;
using namespace std;

static const Double_t DEFAULT_EPSILON = 0.01;


MCMCInterval::MCMCInterval(const char* name)
   : ConfInterval(name)
{
   fConfidenceLevel = 0.0;
   fHistConfLevel = 0.0;
   fKeysConfLevel = 0.0;
   fFull = 0.0;
   fChain = NULL;
   fAxes = NULL;
   fDataHist = NULL;
   fSparseHist = NULL;
   fKeysPdf = NULL;
   fProduct = NULL;
   fHeavyside = NULL;
   fKeysDataHist = NULL;
   fCutoffVar = NULL;
   fHist = NULL;
   fNumBurnInSteps = 0;
   fHistCutoff = -1;
   fKeysCutoff = -1;
   fDimension = 1;
   fUseKeys = kFALSE;
   fUseSparseHist = kFALSE;
   fIsHistStrict = kTRUE;
   fEpsilon = DEFAULT_EPSILON;
}

MCMCInterval::MCMCInterval(const char* name,
        const RooArgSet& parameters, MarkovChain& chain) : ConfInterval(name)
{
   fNumBurnInSteps = 0;
   fConfidenceLevel = 0.0;
   fHistConfLevel = 0.0;
   fKeysConfLevel = 0.0;
   fFull = 0.0;
   fAxes = NULL;
   fChain = &chain;
   fDataHist = NULL;
   fSparseHist = NULL;
   fKeysPdf = NULL;
   fProduct = NULL;
   fHeavyside = NULL;
   fKeysDataHist = NULL;
   fCutoffVar = NULL;
   fHist = NULL;
   fHistCutoff = -1;
   fKeysCutoff = -1;
   fUseKeys = kFALSE;
   fUseSparseHist = kFALSE;
   fIsHistStrict = kTRUE;
   fEpsilon = DEFAULT_EPSILON;
   SetParameters(parameters);
}

MCMCInterval::~MCMCInterval()
{
   // destructor
   delete[] fAxes;
   delete fHist;
   delete fChain;
   // kbelasco: check here for memory management errors
   delete fDataHist;
   delete fSparseHist;
   delete fKeysPdf;
   delete fProduct;
   delete fHeavyside;
   delete fKeysDataHist;
   delete fCutoffVar;
}

struct CompareDataHistBins {
   CompareDataHistBins(RooDataHist* hist) : fDataHist(hist) {}
   bool operator() (Int_t bin1 , Int_t bin2) { 
      fDataHist->get(bin1);
      Double_t n1 = fDataHist->weight();
      fDataHist->get(bin2);
      Double_t n2 = fDataHist->weight();
      return (n1 < n2);
   }
   RooDataHist* fDataHist; 
};

struct CompareSparseHistBins {
   CompareSparseHistBins(THnSparse* hist) : fSparseHist(hist) {}
   bool operator() (Long_t bin1, Long_t bin2) { 
      Double_t n1 = fSparseHist->GetBinContent(bin1);
      Double_t n2 = fSparseHist->GetBinContent(bin2);
      return (n1 < n2);
   }
   THnSparse* fSparseHist; 
};

Bool_t MCMCInterval::IsInInterval(const RooArgSet& point) const 
{
   if (fUseKeys) {
      // evaluate keyspdf at point and return whether >= cutoff
      // kbelasco: is this right?
      RooStats::SetParameters(&point, const_cast<RooArgSet *>(&fParameters) );
      return fKeysPdf->getVal(&fParameters) >= fKeysCutoff;
   } else {
      if (fUseSparseHist) {
         Long_t bin;
         // kbelasco: consider making x static
         Double_t* x = new Double_t[fDimension];
         for (Int_t i = 0; i < fDimension; i++)
            x[i] = fAxes[i]->getVal();
         bin = fSparseHist->GetBin(x, kFALSE);
         Double_t weight = fSparseHist->GetBinContent((Long64_t)bin);
         delete[] x;
         return (weight >= (Double_t)fHistCutoff);
      } else {
         Int_t bin;
         bin = fDataHist->getIndex(point);
         fDataHist->get(bin);
         return (fDataHist->weight() >= (Double_t)fHistCutoff);
      }
   }
}

void MCMCInterval::SetConfidenceLevel(Double_t cl)
{
   fConfidenceLevel = cl;
   DetermineInterval();
}

// kbelasco: update this or just take it out
// kbelasco: consider keeping this around but changing the implementation
// to set the number of bins for each RooRealVar and then reacreating the
// histograms
//void MCMCInterval::SetNumBins(Int_t numBins)
//{
//   if (numBins > 0) {
//      fPreferredNumBins = numBins;
//      for (Int_t d = 0; d < fDimension; d++)
//         fNumBins[d] = numBins;
//   }
//   else {
//      coutE(Eval) << "* Error in MCMCInterval::SetNumBins: " <<
//                     "Negative number of bins given: " << numBins << endl;
//      return;
//   }
//
//   // If the histogram already exists, recreate it with the new bin numbers
//   if (fHist != NULL)
//      CreateHist();
//}

void MCMCInterval::SetAxes(RooArgList& axes)
{
   Int_t size = axes.getSize();
   if (size != fDimension) {
      coutE(InputArguments) << "* Error in MCMCInterval::SetAxes: " <<
                               "number of variables in axes (" << size <<
                               ") doesn't match number of parameters ("
                               << fDimension << ")" << endl;
      return;
   }
   for (Int_t i = 0; i < size; i++)
      fAxes[i] = (RooRealVar*)axes.at(i);
}

void MCMCInterval::CreateKeysPdf()
{
   // kbelasco: check here for memory leak.  does RooNDKeysPdf use
   // the RooArgList passed to it or does it make a clone?
   // also check for memory leak from chain, does RooNDKeysPdf clone that?
   if (fAxes == NULL || fParameters.getSize() == 0) {
      coutE(InputArguments) << "Error in MCMCInterval::CreateKeysPdf: "
         << "parameters have not been set." << endl;
      return;
   }

   RooDataSet* chain = fChain->GetAsDataSet(SelectVars(fParameters),
         EventRange(fNumBurnInSteps, fChain->Size()));
   RooArgList* paramsList = new RooArgList();
   for (Int_t i = 0; i < fDimension; i++)
      paramsList->add(*fAxes[i]);

   fKeysPdf = new RooNDKeysPdf("keysPDF", "Keys PDF", *paramsList, *chain, "a");
   //fKeysPdf = new RooNDKeysPdf("keysPDF", "Keys PDF", *paramsList, *chain, "a");
   fCutoffVar = new RooRealVar("cutoff", "cutoff", 0);
   fHeavyside = new Heavyside("heavyside", "Heavyside", *fKeysPdf, *fCutoffVar);
   fProduct = new RooProduct("product", "Keys PDF & Heavyside Product",
                                        RooArgSet(*fKeysPdf, *fHeavyside));
}

void MCMCInterval::CreateHist()
{
   if (fAxes == NULL || fChain == NULL) {
      coutE(Eval) << "* Error in MCMCInterval::CreateHist(): " <<
                     "Crucial data member was NULL." << endl;
      coutE(Eval) << "Make sure to fully construct/initialize." << endl;
      return;
   }
   if (fHist == NULL)
      delete fHist;

   if (fDimension == 1)
      fHist = new TH1F("posterior", "MCMC Posterior Histogram",
            fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax());

   else if (fDimension == 2)
      fHist = new TH2F("posterior", "MCMC Posterior Histogram",
            fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax(),
            fAxes[1]->numBins(), fAxes[1]->getMin(), fAxes[1]->getMax());

   else if (fDimension == 3) 
      fHist = new TH3F("posterior", "MCMC Posterior Histogram",
            fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax(),
            fAxes[1]->numBins(), fAxes[1]->getMin(), fAxes[1]->getMax(),
            fAxes[2]->numBins(), fAxes[2]->getMin(), fAxes[2]->getMax());

   else {
      coutE(Eval) << "* Error in MCMCInterval::CreateHist() : " <<
                     "TH1* couldn't handle dimension: " << fDimension << endl;
      return;
   }

   // Fill histogram
   Int_t size = fChain->Size();
   const RooArgSet* entry;
   for (Int_t i = fNumBurnInSteps; i < size; i++) {
      entry = fChain->Get(i);
      if (fDimension == 1)
         ((TH1F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
                              fChain->Weight());
      else if (fDimension == 2)
         ((TH2F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
                              entry->getRealValue(fAxes[1]->GetName()),
                              fChain->Weight());
      else
         ((TH3F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
                              entry->getRealValue(fAxes[1]->GetName()),
                              entry->getRealValue(fAxes[2]->GetName()),
                              fChain->Weight());
   }
}

void MCMCInterval::CreateSparseHist()
{
   if (fAxes == NULL || fChain == NULL) {
      coutE(Eval) << "* Error in MCMCInterval::CreateSparseHist(): " <<
                     "Crucial data member was NULL." << endl;
      coutE(Eval) << "Make sure to fully construct/initialize." << endl;
      return;
   }
   if (fSparseHist != NULL)
      delete fSparseHist;

   Double_t* min = new Double_t[fDimension];
   Double_t* max = new Double_t[fDimension];
   Int_t* bins = new Int_t[fDimension];
   for (Int_t i = 0; i < fDimension; i++) {
      min[i] = fAxes[i]->getMin();
      max[i] = fAxes[i]->getMax();
      bins[i] = fAxes[i]->numBins();
   }
   fSparseHist = new THnSparseF("posterior", "MCMC Posterior Histogram",
         fDimension, bins, min, max);
   // kbelasco: check here for memory leaks: does THnSparse copy min, max, and bins
   // or can we not delete them?
   //delete[] min;
   //delete[] max;
   //delete[] bins;

   // kbelasco: it appears we need to call Sumw2() just to get the
   // histogram to keep a running total of the weight so that Getsumw doesn't
   // just return 0
   fSparseHist->Sumw2();

   // Fill histogram
   Int_t size = fChain->Size();
   const RooArgSet* entry;
   Double_t* x = new Double_t[fDimension];
   for (Int_t i = fNumBurnInSteps; i < size; i++) {
      entry = fChain->Get(i);
      for (Int_t ii = 0; ii < fDimension; ii++)
         x[ii] = entry->getRealValue(fAxes[ii]->GetName());
      fSparseHist->Fill(x, fChain->Weight());
   }
   delete[] x;
}

void MCMCInterval::CreateDataHist()
{
   if (fParameters.getSize() == 0 || fChain == NULL) {
      coutE(Eval) << "* Error in MCMCInterval::CreateDataHist(): " <<
                     "Crucial data member was NULL." << endl;
      coutE(Eval) << "Make sure to fully construct/initialize." << endl;
      return;
   }
   fDataHist = fChain->GetAsDataHist(SelectVars(fParameters),
         EventRange(fNumBurnInSteps, fChain->Size()));
}

void MCMCInterval::SetParameters(const RooArgSet& parameters)
{
   fParameters.removeAll();
   fParameters.add(parameters);
   fDimension = fParameters.getSize();
   if (fAxes != NULL)
      delete[] fAxes;
   fAxes = new RooRealVar*[fDimension];
   TIterator* it = fParameters.createIterator();
   Int_t n = 0;
   TObject* obj;
   while ((obj = it->Next()) != NULL) {
      if (dynamic_cast<RooRealVar*>(obj) != NULL)
         fAxes[n] = (RooRealVar*)obj;
      else
         coutE(Eval) << "* Error in MCMCInterval::SetParameters: " <<
                     obj->GetName() << " not a RooRealVar*" << std::endl;
      n++;
   }
   delete it;
}

void MCMCInterval::DetermineInterval()
{
   if (fUseKeys)
      DetermineByKeys();
   else
      DetermineByHist();
}

void MCMCInterval::DetermineByKeys()
{
   if (fKeysPdf == NULL)
      CreateKeysPdf();
   // now we have a keys pdf of the posterior

   Double_t cutoff = 0.0;
   fCutoffVar->setVal(cutoff);
   RooAbsReal* integral = fProduct->createIntegral(fParameters, NormSet(fParameters));
   Double_t full = integral->getVal(fParameters);
   fFull = full;
   delete integral;
   if (full < 0.98) {
      coutW(Eval) << "Warning: Integral of Keys PDF came out to " << full
         << " intead of expected value 1.  Will continue using this "
         << "factor to normalize further integrals of this PDF." << endl;
   }

   // kbelasco: Is there a better way to set the search range?
   // from 0 to max value of Keys
   // kbelasco: how to get max value?
   //Double_t max = product.maxVal(product.getMaxVal(fParameters));

   Double_t volume = 1.0;
   TIterator* it = fParameters.createIterator();
   RooRealVar* var;
   while ((var = (RooRealVar*)it->Next()) != NULL)
      volume *= (var->getMax() - var->getMin());
   delete it;

   Double_t topCutoff = full / volume;
   Double_t bottomCutoff = topCutoff;
   Double_t confLevel = CalcConfLevel(topCutoff, full);
   if (AcceptableConfLevel(confLevel)) {
      fKeysConfLevel = confLevel;
      fKeysCutoff = topCutoff;
      return;
   }
   Bool_t changed = kFALSE;
   // find high end of range
   while (confLevel > fConfidenceLevel) {
      topCutoff *= 2.0;
      confLevel = CalcConfLevel(topCutoff, full);
      if (AcceptableConfLevel(confLevel)) {
         fKeysConfLevel = confLevel;
         fKeysCutoff = topCutoff;
         return;
      }
      changed = kTRUE;
   }
   if (changed) {
      bottomCutoff = topCutoff / 2.0;
   } else {
      changed = kFALSE;
      bottomCutoff /= 2.0;
      confLevel = CalcConfLevel(bottomCutoff, full);
      if (AcceptableConfLevel(confLevel)) {
         fKeysConfLevel = confLevel;
         fKeysCutoff = bottomCutoff;
         return;
      }
      while (confLevel < fConfidenceLevel) {
         bottomCutoff /= 2.0;
         confLevel = CalcConfLevel(bottomCutoff, full);
         if (AcceptableConfLevel(confLevel)) {
            fKeysConfLevel = confLevel;
            fKeysCutoff = bottomCutoff;
            return;
         }
         changed = kTRUE;
      }
      if (changed) {
         topCutoff = bottomCutoff * 2.0;
      }
   }

   cutoff = (topCutoff + bottomCutoff) / 2.0;
   confLevel = CalcConfLevel(cutoff, full);

   while (!AcceptableConfLevel(confLevel)) {
      if (confLevel > fConfidenceLevel)
         bottomCutoff = cutoff;
      else if (confLevel < fConfidenceLevel)
         topCutoff = cutoff;
      cutoff = (topCutoff + bottomCutoff) / 2.0;
      confLevel = CalcConfLevel(cutoff, full);
   }

   fKeysCutoff = cutoff;
   fKeysConfLevel = confLevel;
}

void MCMCInterval::DetermineByHist()
{
   if (fUseSparseHist)
      DetermineBySparseHist();
   else
      DetermineByDataHist();
}

void MCMCInterval::DetermineBySparseHist()
{
   Long_t numBins;
   if (fSparseHist == NULL)
      CreateSparseHist();

   numBins = (Long_t)fSparseHist->GetNbins();

   std::vector<Long_t> bins(numBins);
   for (Int_t ibin = 0; ibin < numBins; ibin++)
      bins[ibin] = (Long_t)ibin;
   std::stable_sort(bins.begin(), bins.end(), CompareSparseHistBins(fSparseHist));

   Double_t nEntries = fSparseHist->GetSumw();
   Double_t sum = 0;
   Double_t content;
   Int_t i;
   // see above note on indexing to understand numBins - 3
   for (i = numBins - 1; i >= 0; i--) {
      content = fSparseHist->GetBinContent(bins[i]);
      if ((sum + content) / nEntries >= fConfidenceLevel) {
         fHistCutoff = content;
         if (fIsHistStrict) {
            sum += content;
            i--;
            break;
         } else {
            i++;
            break;
         }
      }
      sum += content;
   }

   if (fIsHistStrict) {
      // keep going to find the sum
      for ( ; i >= 0; i--) {
         content = fSparseHist->GetBinContent(bins[i]);
         if (content == fHistCutoff)
            sum += content;
         else
            break; // content must be < fHistCutoff
      }
   } else {
      // backtrack to find the cutoff and sum
      for ( ; i < numBins; i++) {
         content = fSparseHist->GetBinContent(bins[i]);
         if (content > fHistCutoff) {
            fHistCutoff = content;
            break;
         } else // content == fHistCutoff
            sum -= content;
         if (i == numBins - 1)
            // still haven't set fHistCutoff correctly yet, and we have no bins
            // left, so set fHistCutoff to something higher than the tallest bin
            fHistCutoff = content + 1.0;
      }
   }

   fHistConfLevel = sum / nEntries;
}

void MCMCInterval::DetermineByDataHist()
{
   Int_t numBins;
   if (fDataHist == NULL)
      CreateDataHist();

   numBins = fDataHist->numEntries();

   std::vector<Int_t> bins(numBins);
   for (Int_t ibin = 0; ibin < numBins; ibin++)
      bins[ibin] = ibin;
   std::stable_sort(bins.begin(), bins.end(), CompareDataHistBins(fDataHist));

   Double_t nEntries = fDataHist->sum(kFALSE);
   Double_t sum = 0;
   Double_t content;
   Int_t i;
   for (i = numBins - 1; i >= 0; i--) {
      fDataHist->get(bins[i]);
      content = fDataHist->weight();
      if ((sum + content) / nEntries >= fConfidenceLevel) {
         fHistCutoff = content;
         if (fIsHistStrict) {
            sum += content;
            i--;
            break;
         } else {
            i++;
            break;
         }
      }
      sum += content;
   }

   if (fIsHistStrict) {
      // keep going to find the sum
      for ( ; i >= 0; i--) {
         fDataHist->get(bins[i]);
         content = fDataHist->weight();
         if (content == fHistCutoff)
            sum += content;
         else
            break; // content must be < fHistCutoff
      }
   } else {
      // backtrack to find the cutoff and sum
      for ( ; i < numBins; i++) {
         fDataHist->get(bins[i]);
         content = fDataHist->weight();
         if (content > fHistCutoff) {
            fHistCutoff = content;
            break;
         } else // content == fHistCutoff
            sum -= content;
         if (i == numBins - 1)
            // still haven't set fHistCutoff correctly yet, and we have no bins
            // left, so set fHistCutoff to something higher than the tallest bin
            fHistCutoff = content + 1.0;
      }
   }

   fHistConfLevel = sum / nEntries;
}

Double_t MCMCInterval::GetActualConfidenceLevel()
{
   if (fUseKeys)
      return fKeysConfLevel;
   else
      return fHistConfLevel;
}

Double_t  MCMCInterval::GetSumOfWeights() const { 
   return fDataHist->sum(kFALSE);
}

Double_t MCMCInterval::LowerLimit(RooRealVar& param)
{
   if (fUseKeys)
      return LowerLimitByKeys(param);
   else
      return LowerLimitByHist(param);
}

Double_t MCMCInterval::UpperLimit(RooRealVar& param)
{
   if (fUseKeys)
      return UpperLimitByKeys(param);
   else
      return UpperLimitByHist(param);
}

// Determine the lower limit for param on this interval
// using the binned data set
Double_t MCMCInterval::LowerLimitByHist(RooRealVar& param)
{
   if (fUseSparseHist)
      return LowerLimitBySparseHist(param);
   else
      return LowerLimitByDataHist(param);
}

// Determine the upper limit for param on this interval
// using the binned data set
Double_t MCMCInterval::UpperLimitByHist(RooRealVar& param)
{
   if (fUseSparseHist)
      return UpperLimitBySparseHist(param);
   else
      return UpperLimitByDataHist(param);
}

// Determine the lower limit for param on this interval
// using the binned data set
Double_t MCMCInterval::LowerLimitBySparseHist(RooRealVar& param)
{
   if (fDimension != 1) {
      coutE(InputArguments) << "In MCMCInterval::LowerLimitBySparseHist: "
         << "Sorry, will not compute lower limit unless dimension == 1" << endl;
      return param.getMin();
   }
   if (fHistCutoff < 0)
      DetermineBySparseHist(); // this initializes fSparseHist

   for (Int_t d = 0; d < fDimension; d++) {
      if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
         Long_t numBins = (Long_t)fSparseHist->GetNbins();
         Double_t lowerLimit = param.getMax();
         Double_t val;
         Int_t coord;
         for (Long_t i = 0; i < numBins; i++) {
            if (fSparseHist->GetBinContent(i, &coord) >= fHistCutoff) {
               val = fSparseHist->GetAxis(d)->GetBinCenter(coord);
               if (val < lowerLimit)
                  lowerLimit = val;
            }
         }
         return lowerLimit;
      }
   }
   return param.getMin();
}

// Determine the lower limit for param on this interval
// using the binned data set
Double_t MCMCInterval::LowerLimitByDataHist(RooRealVar& param)
{
   if (fHistCutoff < 0)
      DetermineByDataHist(); // this initializes fDataHist

   for (Int_t d = 0; d < fDimension; d++) {
      if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
         Int_t numBins = fDataHist->numEntries();
         Double_t lowerLimit = param.getMax();
         Double_t val;
         for (Int_t i = 0; i < numBins; i++) {
            fDataHist->get(i);
            if (fDataHist->weight() >= fHistCutoff) {
               val = fDataHist->get()->getRealValue(param.GetName());
               if (val < lowerLimit)
                  lowerLimit = val;
            }
         }
         return lowerLimit;
      }
   }
   return param.getMin();
}

// Determine the upper limit for param on this interval
// using the binned data set
Double_t MCMCInterval::UpperLimitBySparseHist(RooRealVar& param)
{
   if (fDimension != 1) {
      coutE(InputArguments) << "In MCMCInterval::UpperLimitBySparseHist: "
         << "Sorry, will not compute upper limit unless dimension == 1" << endl;
      return param.getMax();
   }
   if (fHistCutoff < 0)
      DetermineBySparseHist(); // this initializes fSparseHist

   for (Int_t d = 0; d < fDimension; d++) {
      if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
         Long_t numBins = (Long_t)fSparseHist->GetNbins();
         Double_t upperLimit = param.getMin();
         Double_t val;
         Int_t coord;
         for (Long_t i = 0; i < numBins; i++) {
            if (fSparseHist->GetBinContent(i, &coord) >= fHistCutoff) {
               val = fSparseHist->GetAxis(d)->GetBinCenter(coord);
               if (val > upperLimit)
                  upperLimit = val;
            }
         }
         return upperLimit;
      }
   }
   return param.getMax();
}

// Determine the upper limit for param on this interval
// using the binned data set
Double_t MCMCInterval::UpperLimitByDataHist(RooRealVar& param)
{
   if (fHistCutoff < 0)
      DetermineByDataHist(); // this initializes fDataHist

   for (Int_t d = 0; d < fDimension; d++) {
      if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
         Int_t numBins = fDataHist->numEntries();
         Double_t upperLimit = param.getMin();
         Double_t val;
         for (Int_t i = 0; i < numBins; i++) {
            fDataHist->get(i);
            if (fDataHist->weight() >= fHistCutoff) {
               val = fDataHist->get()->getRealValue(param.GetName());
               if (val > upperLimit)
                  upperLimit = val;
            }
         }
         return upperLimit;
      }
   }
   return param.getMax();
}

// Determine the lower limit for param on this interval
// using the keys pdf
Double_t MCMCInterval::LowerLimitByKeys(RooRealVar& param)
{
   if (fKeysCutoff < 0)
      DetermineByKeys();

   if (fKeysDataHist == NULL)
      CreateKeysDataHist();

   if (fKeysDataHist == NULL) {
      // if its still NULL, there was an error in making it
      coutE(Eval) << "in MCMCInterval::LowerLimitByKeys(): "
                  << "Could not fill RooDataHist from RooProduct.  "
                  << "Returning param.getMin()" << endl;
      return param.getMin();
   }

   for (Int_t d = 0; d < fDimension; d++) {
      if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
         Int_t numBins = fKeysDataHist->numEntries();
         Double_t lowerLimit = param.getMax();
         Double_t val;
         for (Int_t i = 0; i < numBins; i++) {
            fKeysDataHist->get(i);
            if (fKeysDataHist->weight() >= fKeysCutoff) {
               val = fKeysDataHist->get()->getRealValue(param.GetName());
               if (val < lowerLimit)
                  lowerLimit = val;
            }
         }
         return lowerLimit;
      }
   }
   return param.getMin();
}

// Determine the upper limit for param on this interval
// using the keys pdf
Double_t MCMCInterval::UpperLimitByKeys(RooRealVar& param)
{
   if (fKeysCutoff < 0)
      DetermineByKeys();

   if (fKeysDataHist == NULL)
      CreateKeysDataHist();

   if (fKeysDataHist == NULL) {
      // if its still NULL, there was an error in making it
      coutE(Eval) << "in MCMCInterval::UpperLimitByKeys(): "
                  << "Could not fill RooDataHist from RooProduct.  "
                  << "Returning param.getMax()" << endl;
      return param.getMax();
   }

   for (Int_t d = 0; d < fDimension; d++) {
      if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
         Int_t numBins = fKeysDataHist->numEntries();
         Double_t upperLimit = param.getMin();
         Double_t val;
         for (Int_t i = 0; i < numBins; i++) {
            fKeysDataHist->get(i);
            if (fKeysDataHist->weight() >= fKeysCutoff) {
               val = fKeysDataHist->get()->getRealValue(param.GetName());
               if (val > upperLimit)
                  upperLimit = val;
            }
         }
         return upperLimit;
      }
   }
   return param.getMax();
}

Double_t MCMCInterval::GetHistCutoff()
{
   if (fHistCutoff < 0)
      DetermineByHist();

   return fHistCutoff;
}

Double_t MCMCInterval::GetKeysPdfCutoff()
{
   if (fKeysCutoff < 0)
      DetermineByKeys();

   return fKeysCutoff / fFull;
}

Double_t MCMCInterval::CalcConfLevel(Double_t cutoff, Double_t full)
{
   RooAbsReal* integral;
   Double_t confLevel;
   fCutoffVar->setVal(cutoff);
   integral = fProduct->createIntegral(fParameters, NormSet(fParameters));
   confLevel = integral->getVal(fParameters) / full;
   coutI(Eval) << "cutoff = " << cutoff << ", conf = " << confLevel << endl;
   delete integral;
   return confLevel;
}

TH1* MCMCInterval::GetPosteriorHist()
{
  if(fConfidenceLevel == 0)
     coutE(InputArguments) << "Error in MCMCInterval::GetPosteriorHist: "
                           << "confidence level not set " << endl;
  if (fHist == NULL)
     CreateHist();
  return (TH1*) fHist->Clone("MCMCposterior_hist");
}

RooNDKeysPdf* MCMCInterval::GetPosteriorKeysPdf()
{
   if (fConfidenceLevel == 0)
      coutE(InputArguments) << "Error in MCMCInterval::GetPosteriorKeysPdf: "
                            << "confidence level not set " << endl;
   if (fKeysPdf == NULL)
      CreateKeysPdf();
   return (RooNDKeysPdf*) fKeysPdf->Clone("MCMCPosterior_keys");
}

RooProduct* MCMCInterval::GetPosteriorKeysProduct()
{
   if (fConfidenceLevel == 0)
      coutE(InputArguments) << "Error in MCMCInterval::GetPosteriorKeysProduct: "
                            << "confidence level not set " << endl;
   if (fKeysPdf == NULL)
      CreateKeysPdf();
   return (RooProduct*) fProduct->Clone("MCMCPosterior_keysproduct");
}

RooArgSet* MCMCInterval::GetParameters() const
{  
   // returns list of parameters
   return new RooArgSet(fParameters);
}

Bool_t MCMCInterval::AcceptableConfLevel(Double_t confLevel)
{
   return (TMath::Abs(confLevel - fConfidenceLevel) < fEpsilon);
}

void MCMCInterval::CreateKeysDataHist()
{
   if (fProduct == NULL)
      DetermineByKeys();

   fKeysDataHist = new RooDataHist("_productDataHist",
         "Keys PDF & Heavyside Product Data Hist", fParameters);
   fKeysDataHist = fProduct->fillDataHist(fKeysDataHist, &fParameters, 1.);
}

Bool_t MCMCInterval::CheckParameters(const RooArgSet& parameterPoint) const
{  
   // check that the parameters are correct

   if (parameterPoint.getSize() != fParameters.getSize() ) {
     coutE(Eval) << "MCMCInterval: size is wrong, parameters don't match" << std::endl;
     return kFALSE;
   }
   if ( ! parameterPoint.equals( fParameters ) ) {
     coutE(Eval) << "MCMCInterval: size is ok, but parameters don't match" << std::endl;
     return kFALSE;
   }
   return kTRUE;
}
 MCMCInterval.cxx:1
 MCMCInterval.cxx:2
 MCMCInterval.cxx:3
 MCMCInterval.cxx:4
 MCMCInterval.cxx:5
 MCMCInterval.cxx:6
 MCMCInterval.cxx:7
 MCMCInterval.cxx:8
 MCMCInterval.cxx:9
 MCMCInterval.cxx:10
 MCMCInterval.cxx:11
 MCMCInterval.cxx:12
 MCMCInterval.cxx:13
 MCMCInterval.cxx:14
 MCMCInterval.cxx:15
 MCMCInterval.cxx:16
 MCMCInterval.cxx:17
 MCMCInterval.cxx:18
 MCMCInterval.cxx:19
 MCMCInterval.cxx:20
 MCMCInterval.cxx:21
 MCMCInterval.cxx:22
 MCMCInterval.cxx:23
 MCMCInterval.cxx:24
 MCMCInterval.cxx:25
 MCMCInterval.cxx:26
 MCMCInterval.cxx:27
 MCMCInterval.cxx:28
 MCMCInterval.cxx:29
 MCMCInterval.cxx:30
 MCMCInterval.cxx:31
 MCMCInterval.cxx:32
 MCMCInterval.cxx:33
 MCMCInterval.cxx:34
 MCMCInterval.cxx:35
 MCMCInterval.cxx:36
 MCMCInterval.cxx:37
 MCMCInterval.cxx:38
 MCMCInterval.cxx:39
 MCMCInterval.cxx:40
 MCMCInterval.cxx:41
 MCMCInterval.cxx:42
 MCMCInterval.cxx:43
 MCMCInterval.cxx:44
 MCMCInterval.cxx:45
 MCMCInterval.cxx:46
 MCMCInterval.cxx:47
 MCMCInterval.cxx:48
 MCMCInterval.cxx:49
 MCMCInterval.cxx:50
 MCMCInterval.cxx:51
 MCMCInterval.cxx:52
 MCMCInterval.cxx:53
 MCMCInterval.cxx:54
 MCMCInterval.cxx:55
 MCMCInterval.cxx:56
 MCMCInterval.cxx:57
 MCMCInterval.cxx:58
 MCMCInterval.cxx:59
 MCMCInterval.cxx:60
 MCMCInterval.cxx:61
 MCMCInterval.cxx:62
 MCMCInterval.cxx:63
 MCMCInterval.cxx:64
 MCMCInterval.cxx:65
 MCMCInterval.cxx:66
 MCMCInterval.cxx:67
 MCMCInterval.cxx:68
 MCMCInterval.cxx:69
 MCMCInterval.cxx:70
 MCMCInterval.cxx:71
 MCMCInterval.cxx:72
 MCMCInterval.cxx:73
 MCMCInterval.cxx:74
 MCMCInterval.cxx:75
 MCMCInterval.cxx:76
 MCMCInterval.cxx:77
 MCMCInterval.cxx:78
 MCMCInterval.cxx:79
 MCMCInterval.cxx:80
 MCMCInterval.cxx:81
 MCMCInterval.cxx:82
 MCMCInterval.cxx:83
 MCMCInterval.cxx:84
 MCMCInterval.cxx:85
 MCMCInterval.cxx:86
 MCMCInterval.cxx:87
 MCMCInterval.cxx:88
 MCMCInterval.cxx:89
 MCMCInterval.cxx:90
 MCMCInterval.cxx:91
 MCMCInterval.cxx:92
 MCMCInterval.cxx:93
 MCMCInterval.cxx:94
 MCMCInterval.cxx:95
 MCMCInterval.cxx:96
 MCMCInterval.cxx:97
 MCMCInterval.cxx:98
 MCMCInterval.cxx:99
 MCMCInterval.cxx:100
 MCMCInterval.cxx:101
 MCMCInterval.cxx:102
 MCMCInterval.cxx:103
 MCMCInterval.cxx:104
 MCMCInterval.cxx:105
 MCMCInterval.cxx:106
 MCMCInterval.cxx:107
 MCMCInterval.cxx:108
 MCMCInterval.cxx:109
 MCMCInterval.cxx:110
 MCMCInterval.cxx:111
 MCMCInterval.cxx:112
 MCMCInterval.cxx:113
 MCMCInterval.cxx:114
 MCMCInterval.cxx:115
 MCMCInterval.cxx:116
 MCMCInterval.cxx:117
 MCMCInterval.cxx:118
 MCMCInterval.cxx:119
 MCMCInterval.cxx:120
 MCMCInterval.cxx:121
 MCMCInterval.cxx:122
 MCMCInterval.cxx:123
 MCMCInterval.cxx:124
 MCMCInterval.cxx:125
 MCMCInterval.cxx:126
 MCMCInterval.cxx:127
 MCMCInterval.cxx:128
 MCMCInterval.cxx:129
 MCMCInterval.cxx:130
 MCMCInterval.cxx:131
 MCMCInterval.cxx:132
 MCMCInterval.cxx:133
 MCMCInterval.cxx:134
 MCMCInterval.cxx:135
 MCMCInterval.cxx:136
 MCMCInterval.cxx:137
 MCMCInterval.cxx:138
 MCMCInterval.cxx:139
 MCMCInterval.cxx:140
 MCMCInterval.cxx:141
 MCMCInterval.cxx:142
 MCMCInterval.cxx:143
 MCMCInterval.cxx:144
 MCMCInterval.cxx:145
 MCMCInterval.cxx:146
 MCMCInterval.cxx:147
 MCMCInterval.cxx:148
 MCMCInterval.cxx:149
 MCMCInterval.cxx:150
 MCMCInterval.cxx:151
 MCMCInterval.cxx:152
 MCMCInterval.cxx:153
 MCMCInterval.cxx:154
 MCMCInterval.cxx:155
 MCMCInterval.cxx:156
 MCMCInterval.cxx:157
 MCMCInterval.cxx:158
 MCMCInterval.cxx:159
 MCMCInterval.cxx:160
 MCMCInterval.cxx:161
 MCMCInterval.cxx:162
 MCMCInterval.cxx:163
 MCMCInterval.cxx:164
 MCMCInterval.cxx:165
 MCMCInterval.cxx:166
 MCMCInterval.cxx:167
 MCMCInterval.cxx:168
 MCMCInterval.cxx:169
 MCMCInterval.cxx:170
 MCMCInterval.cxx:171
 MCMCInterval.cxx:172
 MCMCInterval.cxx:173
 MCMCInterval.cxx:174
 MCMCInterval.cxx:175
 MCMCInterval.cxx:176
 MCMCInterval.cxx:177
 MCMCInterval.cxx:178
 MCMCInterval.cxx:179
 MCMCInterval.cxx:180
 MCMCInterval.cxx:181
 MCMCInterval.cxx:182
 MCMCInterval.cxx:183
 MCMCInterval.cxx:184
 MCMCInterval.cxx:185
 MCMCInterval.cxx:186
 MCMCInterval.cxx:187
 MCMCInterval.cxx:188
 MCMCInterval.cxx:189
 MCMCInterval.cxx:190
 MCMCInterval.cxx:191
 MCMCInterval.cxx:192
 MCMCInterval.cxx:193
 MCMCInterval.cxx:194
 MCMCInterval.cxx:195
 MCMCInterval.cxx:196
 MCMCInterval.cxx:197
 MCMCInterval.cxx:198
 MCMCInterval.cxx:199
 MCMCInterval.cxx:200
 MCMCInterval.cxx:201
 MCMCInterval.cxx:202
 MCMCInterval.cxx:203
 MCMCInterval.cxx:204
 MCMCInterval.cxx:205
 MCMCInterval.cxx:206
 MCMCInterval.cxx:207
 MCMCInterval.cxx:208
 MCMCInterval.cxx:209
 MCMCInterval.cxx:210
 MCMCInterval.cxx:211
 MCMCInterval.cxx:212
 MCMCInterval.cxx:213
 MCMCInterval.cxx:214
 MCMCInterval.cxx:215
 MCMCInterval.cxx:216
 MCMCInterval.cxx:217
 MCMCInterval.cxx:218
 MCMCInterval.cxx:219
 MCMCInterval.cxx:220
 MCMCInterval.cxx:221
 MCMCInterval.cxx:222
 MCMCInterval.cxx:223
 MCMCInterval.cxx:224
 MCMCInterval.cxx:225
 MCMCInterval.cxx:226
 MCMCInterval.cxx:227
 MCMCInterval.cxx:228
 MCMCInterval.cxx:229
 MCMCInterval.cxx:230
 MCMCInterval.cxx:231
 MCMCInterval.cxx:232
 MCMCInterval.cxx:233
 MCMCInterval.cxx:234
 MCMCInterval.cxx:235
 MCMCInterval.cxx:236
 MCMCInterval.cxx:237
 MCMCInterval.cxx:238
 MCMCInterval.cxx:239
 MCMCInterval.cxx:240
 MCMCInterval.cxx:241
 MCMCInterval.cxx:242
 MCMCInterval.cxx:243
 MCMCInterval.cxx:244
 MCMCInterval.cxx:245
 MCMCInterval.cxx:246
 MCMCInterval.cxx:247
 MCMCInterval.cxx:248
 MCMCInterval.cxx:249
 MCMCInterval.cxx:250
 MCMCInterval.cxx:251
 MCMCInterval.cxx:252
 MCMCInterval.cxx:253
 MCMCInterval.cxx:254
 MCMCInterval.cxx:255
 MCMCInterval.cxx:256
 MCMCInterval.cxx:257
 MCMCInterval.cxx:258
 MCMCInterval.cxx:259
 MCMCInterval.cxx:260
 MCMCInterval.cxx:261
 MCMCInterval.cxx:262
 MCMCInterval.cxx:263
 MCMCInterval.cxx:264
 MCMCInterval.cxx:265
 MCMCInterval.cxx:266
 MCMCInterval.cxx:267
 MCMCInterval.cxx:268
 MCMCInterval.cxx:269
 MCMCInterval.cxx:270
 MCMCInterval.cxx:271
 MCMCInterval.cxx:272
 MCMCInterval.cxx:273
 MCMCInterval.cxx:274
 MCMCInterval.cxx:275
 MCMCInterval.cxx:276
 MCMCInterval.cxx:277
 MCMCInterval.cxx:278
 MCMCInterval.cxx:279
 MCMCInterval.cxx:280
 MCMCInterval.cxx:281
 MCMCInterval.cxx:282
 MCMCInterval.cxx:283
 MCMCInterval.cxx:284
 MCMCInterval.cxx:285
 MCMCInterval.cxx:286
 MCMCInterval.cxx:287
 MCMCInterval.cxx:288
 MCMCInterval.cxx:289
 MCMCInterval.cxx:290
 MCMCInterval.cxx:291
 MCMCInterval.cxx:292
 MCMCInterval.cxx:293
 MCMCInterval.cxx:294
 MCMCInterval.cxx:295
 MCMCInterval.cxx:296
 MCMCInterval.cxx:297
 MCMCInterval.cxx:298
 MCMCInterval.cxx:299
 MCMCInterval.cxx:300
 MCMCInterval.cxx:301
 MCMCInterval.cxx:302
 MCMCInterval.cxx:303
 MCMCInterval.cxx:304
 MCMCInterval.cxx:305
 MCMCInterval.cxx:306
 MCMCInterval.cxx:307
 MCMCInterval.cxx:308
 MCMCInterval.cxx:309
 MCMCInterval.cxx:310
 MCMCInterval.cxx:311
 MCMCInterval.cxx:312
 MCMCInterval.cxx:313
 MCMCInterval.cxx:314
 MCMCInterval.cxx:315
 MCMCInterval.cxx:316
 MCMCInterval.cxx:317
 MCMCInterval.cxx:318
 MCMCInterval.cxx:319
 MCMCInterval.cxx:320
 MCMCInterval.cxx:321
 MCMCInterval.cxx:322
 MCMCInterval.cxx:323
 MCMCInterval.cxx:324
 MCMCInterval.cxx:325
 MCMCInterval.cxx:326
 MCMCInterval.cxx:327
 MCMCInterval.cxx:328
 MCMCInterval.cxx:329
 MCMCInterval.cxx:330
 MCMCInterval.cxx:331
 MCMCInterval.cxx:332
 MCMCInterval.cxx:333
 MCMCInterval.cxx:334
 MCMCInterval.cxx:335
 MCMCInterval.cxx:336
 MCMCInterval.cxx:337
 MCMCInterval.cxx:338
 MCMCInterval.cxx:339
 MCMCInterval.cxx:340
 MCMCInterval.cxx:341
 MCMCInterval.cxx:342
 MCMCInterval.cxx:343
 MCMCInterval.cxx:344
 MCMCInterval.cxx:345
 MCMCInterval.cxx:346
 MCMCInterval.cxx:347
 MCMCInterval.cxx:348
 MCMCInterval.cxx:349
 MCMCInterval.cxx:350
 MCMCInterval.cxx:351
 MCMCInterval.cxx:352
 MCMCInterval.cxx:353
 MCMCInterval.cxx:354
 MCMCInterval.cxx:355
 MCMCInterval.cxx:356
 MCMCInterval.cxx:357
 MCMCInterval.cxx:358
 MCMCInterval.cxx:359
 MCMCInterval.cxx:360
 MCMCInterval.cxx:361
 MCMCInterval.cxx:362
 MCMCInterval.cxx:363
 MCMCInterval.cxx:364
 MCMCInterval.cxx:365
 MCMCInterval.cxx:366
 MCMCInterval.cxx:367
 MCMCInterval.cxx:368
 MCMCInterval.cxx:369
 MCMCInterval.cxx:370
 MCMCInterval.cxx:371
 MCMCInterval.cxx:372
 MCMCInterval.cxx:373
 MCMCInterval.cxx:374
 MCMCInterval.cxx:375
 MCMCInterval.cxx:376
 MCMCInterval.cxx:377
 MCMCInterval.cxx:378
 MCMCInterval.cxx:379
 MCMCInterval.cxx:380
 MCMCInterval.cxx:381
 MCMCInterval.cxx:382
 MCMCInterval.cxx:383
 MCMCInterval.cxx:384
 MCMCInterval.cxx:385
 MCMCInterval.cxx:386
 MCMCInterval.cxx:387
 MCMCInterval.cxx:388
 MCMCInterval.cxx:389
 MCMCInterval.cxx:390
 MCMCInterval.cxx:391
 MCMCInterval.cxx:392
 MCMCInterval.cxx:393
 MCMCInterval.cxx:394
 MCMCInterval.cxx:395
 MCMCInterval.cxx:396
 MCMCInterval.cxx:397
 MCMCInterval.cxx:398
 MCMCInterval.cxx:399
 MCMCInterval.cxx:400
 MCMCInterval.cxx:401
 MCMCInterval.cxx:402
 MCMCInterval.cxx:403
 MCMCInterval.cxx:404
 MCMCInterval.cxx:405
 MCMCInterval.cxx:406
 MCMCInterval.cxx:407
 MCMCInterval.cxx:408
 MCMCInterval.cxx:409
 MCMCInterval.cxx:410
 MCMCInterval.cxx:411
 MCMCInterval.cxx:412
 MCMCInterval.cxx:413
 MCMCInterval.cxx:414
 MCMCInterval.cxx:415
 MCMCInterval.cxx:416
 MCMCInterval.cxx:417
 MCMCInterval.cxx:418
 MCMCInterval.cxx:419
 MCMCInterval.cxx:420
 MCMCInterval.cxx:421
 MCMCInterval.cxx:422
 MCMCInterval.cxx:423
 MCMCInterval.cxx:424
 MCMCInterval.cxx:425
 MCMCInterval.cxx:426
 MCMCInterval.cxx:427
 MCMCInterval.cxx:428
 MCMCInterval.cxx:429
 MCMCInterval.cxx:430
 MCMCInterval.cxx:431
 MCMCInterval.cxx:432
 MCMCInterval.cxx:433
 MCMCInterval.cxx:434
 MCMCInterval.cxx:435
 MCMCInterval.cxx:436
 MCMCInterval.cxx:437
 MCMCInterval.cxx:438
 MCMCInterval.cxx:439
 MCMCInterval.cxx:440
 MCMCInterval.cxx:441
 MCMCInterval.cxx:442
 MCMCInterval.cxx:443
 MCMCInterval.cxx:444
 MCMCInterval.cxx:445
 MCMCInterval.cxx:446
 MCMCInterval.cxx:447
 MCMCInterval.cxx:448
 MCMCInterval.cxx:449
 MCMCInterval.cxx:450
 MCMCInterval.cxx:451
 MCMCInterval.cxx:452
 MCMCInterval.cxx:453
 MCMCInterval.cxx:454
 MCMCInterval.cxx:455
 MCMCInterval.cxx:456
 MCMCInterval.cxx:457
 MCMCInterval.cxx:458
 MCMCInterval.cxx:459
 MCMCInterval.cxx:460
 MCMCInterval.cxx:461
 MCMCInterval.cxx:462
 MCMCInterval.cxx:463
 MCMCInterval.cxx:464
 MCMCInterval.cxx:465
 MCMCInterval.cxx:466
 MCMCInterval.cxx:467
 MCMCInterval.cxx:468
 MCMCInterval.cxx:469
 MCMCInterval.cxx:470
 MCMCInterval.cxx:471
 MCMCInterval.cxx:472
 MCMCInterval.cxx:473
 MCMCInterval.cxx:474
 MCMCInterval.cxx:475
 MCMCInterval.cxx:476
 MCMCInterval.cxx:477
 MCMCInterval.cxx:478
 MCMCInterval.cxx:479
 MCMCInterval.cxx:480
 MCMCInterval.cxx:481
 MCMCInterval.cxx:482
 MCMCInterval.cxx:483
 MCMCInterval.cxx:484
 MCMCInterval.cxx:485
 MCMCInterval.cxx:486
 MCMCInterval.cxx:487
 MCMCInterval.cxx:488
 MCMCInterval.cxx:489
 MCMCInterval.cxx:490
 MCMCInterval.cxx:491
 MCMCInterval.cxx:492
 MCMCInterval.cxx:493
 MCMCInterval.cxx:494
 MCMCInterval.cxx:495
 MCMCInterval.cxx:496
 MCMCInterval.cxx:497
 MCMCInterval.cxx:498
 MCMCInterval.cxx:499
 MCMCInterval.cxx:500
 MCMCInterval.cxx:501
 MCMCInterval.cxx:502
 MCMCInterval.cxx:503
 MCMCInterval.cxx:504
 MCMCInterval.cxx:505
 MCMCInterval.cxx:506
 MCMCInterval.cxx:507
 MCMCInterval.cxx:508
 MCMCInterval.cxx:509
 MCMCInterval.cxx:510
 MCMCInterval.cxx:511
 MCMCInterval.cxx:512
 MCMCInterval.cxx:513
 MCMCInterval.cxx:514
 MCMCInterval.cxx:515
 MCMCInterval.cxx:516
 MCMCInterval.cxx:517
 MCMCInterval.cxx:518
 MCMCInterval.cxx:519
 MCMCInterval.cxx:520
 MCMCInterval.cxx:521
 MCMCInterval.cxx:522
 MCMCInterval.cxx:523
 MCMCInterval.cxx:524
 MCMCInterval.cxx:525
 MCMCInterval.cxx:526
 MCMCInterval.cxx:527
 MCMCInterval.cxx:528
 MCMCInterval.cxx:529
 MCMCInterval.cxx:530
 MCMCInterval.cxx:531
 MCMCInterval.cxx:532
 MCMCInterval.cxx:533
 MCMCInterval.cxx:534
 MCMCInterval.cxx:535
 MCMCInterval.cxx:536
 MCMCInterval.cxx:537
 MCMCInterval.cxx:538
 MCMCInterval.cxx:539
 MCMCInterval.cxx:540
 MCMCInterval.cxx:541
 MCMCInterval.cxx:542
 MCMCInterval.cxx:543
 MCMCInterval.cxx:544
 MCMCInterval.cxx:545
 MCMCInterval.cxx:546
 MCMCInterval.cxx:547
 MCMCInterval.cxx:548
 MCMCInterval.cxx:549
 MCMCInterval.cxx:550
 MCMCInterval.cxx:551
 MCMCInterval.cxx:552
 MCMCInterval.cxx:553
 MCMCInterval.cxx:554
 MCMCInterval.cxx:555
 MCMCInterval.cxx:556
 MCMCInterval.cxx:557
 MCMCInterval.cxx:558
 MCMCInterval.cxx:559
 MCMCInterval.cxx:560
 MCMCInterval.cxx:561
 MCMCInterval.cxx:562
 MCMCInterval.cxx:563
 MCMCInterval.cxx:564
 MCMCInterval.cxx:565
 MCMCInterval.cxx:566
 MCMCInterval.cxx:567
 MCMCInterval.cxx:568
 MCMCInterval.cxx:569
 MCMCInterval.cxx:570
 MCMCInterval.cxx:571
 MCMCInterval.cxx:572
 MCMCInterval.cxx:573
 MCMCInterval.cxx:574
 MCMCInterval.cxx:575
 MCMCInterval.cxx:576
 MCMCInterval.cxx:577
 MCMCInterval.cxx:578
 MCMCInterval.cxx:579
 MCMCInterval.cxx:580
 MCMCInterval.cxx:581
 MCMCInterval.cxx:582
 MCMCInterval.cxx:583
 MCMCInterval.cxx:584
 MCMCInterval.cxx:585
 MCMCInterval.cxx:586
 MCMCInterval.cxx:587
 MCMCInterval.cxx:588
 MCMCInterval.cxx:589
 MCMCInterval.cxx:590
 MCMCInterval.cxx:591
 MCMCInterval.cxx:592
 MCMCInterval.cxx:593
 MCMCInterval.cxx:594
 MCMCInterval.cxx:595
 MCMCInterval.cxx:596
 MCMCInterval.cxx:597
 MCMCInterval.cxx:598
 MCMCInterval.cxx:599
 MCMCInterval.cxx:600
 MCMCInterval.cxx:601
 MCMCInterval.cxx:602
 MCMCInterval.cxx:603
 MCMCInterval.cxx:604
 MCMCInterval.cxx:605
 MCMCInterval.cxx:606
 MCMCInterval.cxx:607
 MCMCInterval.cxx:608
 MCMCInterval.cxx:609
 MCMCInterval.cxx:610
 MCMCInterval.cxx:611
 MCMCInterval.cxx:612
 MCMCInterval.cxx:613
 MCMCInterval.cxx:614
 MCMCInterval.cxx:615
 MCMCInterval.cxx:616
 MCMCInterval.cxx:617
 MCMCInterval.cxx:618
 MCMCInterval.cxx:619
 MCMCInterval.cxx:620
 MCMCInterval.cxx:621
 MCMCInterval.cxx:622
 MCMCInterval.cxx:623
 MCMCInterval.cxx:624
 MCMCInterval.cxx:625
 MCMCInterval.cxx:626
 MCMCInterval.cxx:627
 MCMCInterval.cxx:628
 MCMCInterval.cxx:629
 MCMCInterval.cxx:630
 MCMCInterval.cxx:631
 MCMCInterval.cxx:632
 MCMCInterval.cxx:633
 MCMCInterval.cxx:634
 MCMCInterval.cxx:635
 MCMCInterval.cxx:636
 MCMCInterval.cxx:637
 MCMCInterval.cxx:638
 MCMCInterval.cxx:639
 MCMCInterval.cxx:640
 MCMCInterval.cxx:641
 MCMCInterval.cxx:642
 MCMCInterval.cxx:643
 MCMCInterval.cxx:644
 MCMCInterval.cxx:645
 MCMCInterval.cxx:646
 MCMCInterval.cxx:647
 MCMCInterval.cxx:648
 MCMCInterval.cxx:649
 MCMCInterval.cxx:650
 MCMCInterval.cxx:651
 MCMCInterval.cxx:652
 MCMCInterval.cxx:653
 MCMCInterval.cxx:654
 MCMCInterval.cxx:655
 MCMCInterval.cxx:656
 MCMCInterval.cxx:657
 MCMCInterval.cxx:658
 MCMCInterval.cxx:659
 MCMCInterval.cxx:660
 MCMCInterval.cxx:661
 MCMCInterval.cxx:662
 MCMCInterval.cxx:663
 MCMCInterval.cxx:664
 MCMCInterval.cxx:665
 MCMCInterval.cxx:666
 MCMCInterval.cxx:667
 MCMCInterval.cxx:668
 MCMCInterval.cxx:669
 MCMCInterval.cxx:670
 MCMCInterval.cxx:671
 MCMCInterval.cxx:672
 MCMCInterval.cxx:673
 MCMCInterval.cxx:674
 MCMCInterval.cxx:675
 MCMCInterval.cxx:676
 MCMCInterval.cxx:677
 MCMCInterval.cxx:678
 MCMCInterval.cxx:679
 MCMCInterval.cxx:680
 MCMCInterval.cxx:681
 MCMCInterval.cxx:682
 MCMCInterval.cxx:683
 MCMCInterval.cxx:684
 MCMCInterval.cxx:685
 MCMCInterval.cxx:686
 MCMCInterval.cxx:687
 MCMCInterval.cxx:688
 MCMCInterval.cxx:689
 MCMCInterval.cxx:690
 MCMCInterval.cxx:691
 MCMCInterval.cxx:692
 MCMCInterval.cxx:693
 MCMCInterval.cxx:694
 MCMCInterval.cxx:695
 MCMCInterval.cxx:696
 MCMCInterval.cxx:697
 MCMCInterval.cxx:698
 MCMCInterval.cxx:699
 MCMCInterval.cxx:700
 MCMCInterval.cxx:701
 MCMCInterval.cxx:702
 MCMCInterval.cxx:703
 MCMCInterval.cxx:704
 MCMCInterval.cxx:705
 MCMCInterval.cxx:706
 MCMCInterval.cxx:707
 MCMCInterval.cxx:708
 MCMCInterval.cxx:709
 MCMCInterval.cxx:710
 MCMCInterval.cxx:711
 MCMCInterval.cxx:712
 MCMCInterval.cxx:713
 MCMCInterval.cxx:714
 MCMCInterval.cxx:715
 MCMCInterval.cxx:716
 MCMCInterval.cxx:717
 MCMCInterval.cxx:718
 MCMCInterval.cxx:719
 MCMCInterval.cxx:720
 MCMCInterval.cxx:721
 MCMCInterval.cxx:722
 MCMCInterval.cxx:723
 MCMCInterval.cxx:724
 MCMCInterval.cxx:725
 MCMCInterval.cxx:726
 MCMCInterval.cxx:727
 MCMCInterval.cxx:728
 MCMCInterval.cxx:729
 MCMCInterval.cxx:730
 MCMCInterval.cxx:731
 MCMCInterval.cxx:732
 MCMCInterval.cxx:733
 MCMCInterval.cxx:734
 MCMCInterval.cxx:735
 MCMCInterval.cxx:736
 MCMCInterval.cxx:737
 MCMCInterval.cxx:738
 MCMCInterval.cxx:739
 MCMCInterval.cxx:740
 MCMCInterval.cxx:741
 MCMCInterval.cxx:742
 MCMCInterval.cxx:743
 MCMCInterval.cxx:744
 MCMCInterval.cxx:745
 MCMCInterval.cxx:746
 MCMCInterval.cxx:747
 MCMCInterval.cxx:748
 MCMCInterval.cxx:749
 MCMCInterval.cxx:750
 MCMCInterval.cxx:751
 MCMCInterval.cxx:752
 MCMCInterval.cxx:753
 MCMCInterval.cxx:754
 MCMCInterval.cxx:755
 MCMCInterval.cxx:756
 MCMCInterval.cxx:757
 MCMCInterval.cxx:758
 MCMCInterval.cxx:759
 MCMCInterval.cxx:760
 MCMCInterval.cxx:761
 MCMCInterval.cxx:762
 MCMCInterval.cxx:763
 MCMCInterval.cxx:764
 MCMCInterval.cxx:765
 MCMCInterval.cxx:766
 MCMCInterval.cxx:767
 MCMCInterval.cxx:768
 MCMCInterval.cxx:769
 MCMCInterval.cxx:770
 MCMCInterval.cxx:771
 MCMCInterval.cxx:772
 MCMCInterval.cxx:773
 MCMCInterval.cxx:774
 MCMCInterval.cxx:775
 MCMCInterval.cxx:776
 MCMCInterval.cxx:777
 MCMCInterval.cxx:778
 MCMCInterval.cxx:779
 MCMCInterval.cxx:780
 MCMCInterval.cxx:781
 MCMCInterval.cxx:782
 MCMCInterval.cxx:783
 MCMCInterval.cxx:784
 MCMCInterval.cxx:785
 MCMCInterval.cxx:786
 MCMCInterval.cxx:787
 MCMCInterval.cxx:788
 MCMCInterval.cxx:789
 MCMCInterval.cxx:790
 MCMCInterval.cxx:791
 MCMCInterval.cxx:792
 MCMCInterval.cxx:793
 MCMCInterval.cxx:794
 MCMCInterval.cxx:795
 MCMCInterval.cxx:796
 MCMCInterval.cxx:797
 MCMCInterval.cxx:798
 MCMCInterval.cxx:799
 MCMCInterval.cxx:800
 MCMCInterval.cxx:801
 MCMCInterval.cxx:802
 MCMCInterval.cxx:803
 MCMCInterval.cxx:804
 MCMCInterval.cxx:805
 MCMCInterval.cxx:806
 MCMCInterval.cxx:807
 MCMCInterval.cxx:808
 MCMCInterval.cxx:809
 MCMCInterval.cxx:810
 MCMCInterval.cxx:811
 MCMCInterval.cxx:812
 MCMCInterval.cxx:813
 MCMCInterval.cxx:814
 MCMCInterval.cxx:815
 MCMCInterval.cxx:816
 MCMCInterval.cxx:817
 MCMCInterval.cxx:818
 MCMCInterval.cxx:819
 MCMCInterval.cxx:820
 MCMCInterval.cxx:821
 MCMCInterval.cxx:822
 MCMCInterval.cxx:823
 MCMCInterval.cxx:824
 MCMCInterval.cxx:825
 MCMCInterval.cxx:826
 MCMCInterval.cxx:827
 MCMCInterval.cxx:828
 MCMCInterval.cxx:829
 MCMCInterval.cxx:830
 MCMCInterval.cxx:831
 MCMCInterval.cxx:832
 MCMCInterval.cxx:833
 MCMCInterval.cxx:834
 MCMCInterval.cxx:835
 MCMCInterval.cxx:836
 MCMCInterval.cxx:837
 MCMCInterval.cxx:838
 MCMCInterval.cxx:839
 MCMCInterval.cxx:840
 MCMCInterval.cxx:841
 MCMCInterval.cxx:842
 MCMCInterval.cxx:843
 MCMCInterval.cxx:844
 MCMCInterval.cxx:845
 MCMCInterval.cxx:846
 MCMCInterval.cxx:847
 MCMCInterval.cxx:848
 MCMCInterval.cxx:849
 MCMCInterval.cxx:850
 MCMCInterval.cxx:851
 MCMCInterval.cxx:852
 MCMCInterval.cxx:853
 MCMCInterval.cxx:854
 MCMCInterval.cxx:855
 MCMCInterval.cxx:856
 MCMCInterval.cxx:857
 MCMCInterval.cxx:858
 MCMCInterval.cxx:859
 MCMCInterval.cxx:860
 MCMCInterval.cxx:861
 MCMCInterval.cxx:862
 MCMCInterval.cxx:863
 MCMCInterval.cxx:864
 MCMCInterval.cxx:865
 MCMCInterval.cxx:866
 MCMCInterval.cxx:867
 MCMCInterval.cxx:868
 MCMCInterval.cxx:869
 MCMCInterval.cxx:870
 MCMCInterval.cxx:871
 MCMCInterval.cxx:872
 MCMCInterval.cxx:873
 MCMCInterval.cxx:874
 MCMCInterval.cxx:875
 MCMCInterval.cxx:876
 MCMCInterval.cxx:877
 MCMCInterval.cxx:878
 MCMCInterval.cxx:879
 MCMCInterval.cxx:880
 MCMCInterval.cxx:881
 MCMCInterval.cxx:882
 MCMCInterval.cxx:883
 MCMCInterval.cxx:884
 MCMCInterval.cxx:885
 MCMCInterval.cxx:886
 MCMCInterval.cxx:887
 MCMCInterval.cxx:888
 MCMCInterval.cxx:889
 MCMCInterval.cxx:890
 MCMCInterval.cxx:891
 MCMCInterval.cxx:892
 MCMCInterval.cxx:893
 MCMCInterval.cxx:894
 MCMCInterval.cxx:895
 MCMCInterval.cxx:896
 MCMCInterval.cxx:897
 MCMCInterval.cxx:898
 MCMCInterval.cxx:899
 MCMCInterval.cxx:900
 MCMCInterval.cxx:901
 MCMCInterval.cxx:902
 MCMCInterval.cxx:903
 MCMCInterval.cxx:904
 MCMCInterval.cxx:905
 MCMCInterval.cxx:906
 MCMCInterval.cxx:907
 MCMCInterval.cxx:908
 MCMCInterval.cxx:909
 MCMCInterval.cxx:910
 MCMCInterval.cxx:911
 MCMCInterval.cxx:912
 MCMCInterval.cxx:913
 MCMCInterval.cxx:914
 MCMCInterval.cxx:915
 MCMCInterval.cxx:916
 MCMCInterval.cxx:917
 MCMCInterval.cxx:918
 MCMCInterval.cxx:919
 MCMCInterval.cxx:920
 MCMCInterval.cxx:921
 MCMCInterval.cxx:922
 MCMCInterval.cxx:923
 MCMCInterval.cxx:924
 MCMCInterval.cxx:925
 MCMCInterval.cxx:926
 MCMCInterval.cxx:927
 MCMCInterval.cxx:928
 MCMCInterval.cxx:929
 MCMCInterval.cxx:930
 MCMCInterval.cxx:931
 MCMCInterval.cxx:932
 MCMCInterval.cxx:933
 MCMCInterval.cxx:934
 MCMCInterval.cxx:935
 MCMCInterval.cxx:936
 MCMCInterval.cxx:937
 MCMCInterval.cxx:938
 MCMCInterval.cxx:939
 MCMCInterval.cxx:940
 MCMCInterval.cxx:941
 MCMCInterval.cxx:942
 MCMCInterval.cxx:943
 MCMCInterval.cxx:944
 MCMCInterval.cxx:945
 MCMCInterval.cxx:946
 MCMCInterval.cxx:947
 MCMCInterval.cxx:948
 MCMCInterval.cxx:949
 MCMCInterval.cxx:950
 MCMCInterval.cxx:951
 MCMCInterval.cxx:952
 MCMCInterval.cxx:953
 MCMCInterval.cxx:954
 MCMCInterval.cxx:955
 MCMCInterval.cxx:956
 MCMCInterval.cxx:957
 MCMCInterval.cxx:958
 MCMCInterval.cxx:959
 MCMCInterval.cxx:960
 MCMCInterval.cxx:961
 MCMCInterval.cxx:962
 MCMCInterval.cxx:963
 MCMCInterval.cxx:964
 MCMCInterval.cxx:965
 MCMCInterval.cxx:966
 MCMCInterval.cxx:967
 MCMCInterval.cxx:968
 MCMCInterval.cxx:969
 MCMCInterval.cxx:970
 MCMCInterval.cxx:971
 MCMCInterval.cxx:972
 MCMCInterval.cxx:973
 MCMCInterval.cxx:974
 MCMCInterval.cxx:975
 MCMCInterval.cxx:976
 MCMCInterval.cxx:977
 MCMCInterval.cxx:978
 MCMCInterval.cxx:979
 MCMCInterval.cxx:980
 MCMCInterval.cxx:981
 MCMCInterval.cxx:982
 MCMCInterval.cxx:983
 MCMCInterval.cxx:984
 MCMCInterval.cxx:985
 MCMCInterval.cxx:986
 MCMCInterval.cxx:987
 MCMCInterval.cxx:988
 MCMCInterval.cxx:989
 MCMCInterval.cxx:990
 MCMCInterval.cxx:991
 MCMCInterval.cxx:992
 MCMCInterval.cxx:993
 MCMCInterval.cxx:994
 MCMCInterval.cxx:995
 MCMCInterval.cxx:996
 MCMCInterval.cxx:997
 MCMCInterval.cxx:998
 MCMCInterval.cxx:999
 MCMCInterval.cxx:1000
 MCMCInterval.cxx:1001
 MCMCInterval.cxx:1002
 MCMCInterval.cxx:1003
 MCMCInterval.cxx:1004
 MCMCInterval.cxx:1005
 MCMCInterval.cxx:1006
 MCMCInterval.cxx:1007
 MCMCInterval.cxx:1008
 MCMCInterval.cxx:1009
 MCMCInterval.cxx:1010
 MCMCInterval.cxx:1011
 MCMCInterval.cxx:1012
 MCMCInterval.cxx:1013
 MCMCInterval.cxx:1014
 MCMCInterval.cxx:1015
 MCMCInterval.cxx:1016
 MCMCInterval.cxx:1017
 MCMCInterval.cxx:1018
 MCMCInterval.cxx:1019
 MCMCInterval.cxx:1020
 MCMCInterval.cxx:1021
 MCMCInterval.cxx:1022
 MCMCInterval.cxx:1023
 MCMCInterval.cxx:1024
 MCMCInterval.cxx:1025