ROOT logo
// @(#)root/roostats:$Id: MCMCInterval.cxx 26805 2009-06-17 14:31:02Z kbelasco $
// 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.  The points in the Markov Chain are put into a histogram 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 SetStrict(false)).
The level to use to make a contour plot is the cutoff histogram bin height.  Because a histogram is
used, MCMCInterval currently supports up to 3 dimensions for the interval (i.e. 3 parameters of
interest).
</p>

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

<p>
It 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
maximum) than others, and sometimes has little value.
</p>
END_HTML
*/
//_________________________________________________

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

#include "RooStats/MCMCInterval.h"

#include "RooRealVar.h"
#include "RooArgList.h"
#include "RooDataSet.h"
#include "TIterator.h"
#include "TH1.h"
#include "TH1F.h"
#include "TH2F.h"
#include "TH3F.h"
#include "RooMsgService.h"
#include "RooMsgService.h"
#include "TObject.h"
//#include "TFile.h"

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


ClassImp(RooStats::MCMCInterval);

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

MCMCInterval::MCMCInterval() : ConfInterval()
{
   fPreferredNumBins = DEFAULT_NUM_BINS;
   fConfidenceLevel = 0.0;
   fData = NULL;
   fAxes = NULL;
   fHist = NULL;
   fNumBins = NULL;
   fNumBurnInSteps = 0;
   fCutoff = 0;
   fDimension = 1;
   fIsStrict = true;
   fParameters = NULL;
}

MCMCInterval::MCMCInterval(const char* name) : ConfInterval(name, name)
{
   fPreferredNumBins = DEFAULT_NUM_BINS;
   fConfidenceLevel = 0.0;
   fData = NULL;
   fAxes = NULL;
   fHist = NULL;
   fNumBins = NULL;
   fNumBurnInSteps = 0;
   fCutoff = 0;
   fDimension = 1;
   fIsStrict = true;
   fParameters = NULL;
}

MCMCInterval::MCMCInterval(const char* name, const char* title)
   : ConfInterval(name, title)
{
   fPreferredNumBins = DEFAULT_NUM_BINS;
   fConfidenceLevel = 0.0;
   fData = NULL;
   fAxes = NULL;
   fHist = NULL;
   fNumBins = NULL;
   fNumBurnInSteps = 0;
   fCutoff = 0;
   fDimension = 1;
   fIsStrict = true;
   fParameters = NULL;
}

MCMCInterval::MCMCInterval(const char* name, const char* title,
        RooArgSet& parameters, RooDataSet& chain) : ConfInterval(name, title)
{
   fPreferredNumBins = DEFAULT_NUM_BINS;
   fNumBins = NULL;
   fNumBurnInSteps = 0;
   fConfidenceLevel = 0.0;
   fAxes = NULL;
   fData = &chain;
   fHist = NULL;
   fCutoff = 0;
   fIsStrict = true;
   SetParameters(parameters);
}

struct CompareBins { 

   CompareBins( TH1 * hist) : fHist(hist) {}
   bool operator() ( Int_t bin1 , Int_t bin2 ) { 
      // bins must have content >= 0, so this is safe:
      Double_t n1 = fHist->GetBinContent(bin1);
      Double_t n2 = fHist->GetBinContent(bin2);
      
      return    (n1 < n2) ;
   }
   TH1 * fHist; 
};


Bool_t MCMCInterval::IsInInterval(RooArgSet& point) 
{
   Int_t bin;
   if (fDimension == 1) {
      bin = fHist->FindBin(point.getRealValue(fAxes[0]->GetName()));
   } else if (fDimension == 2) {
      bin = fHist->FindBin(point.getRealValue(fAxes[0]->GetName()),
                           point.getRealValue(fAxes[1]->GetName()));
   } else if (fDimension == 3) {
      bin = fHist->FindBin(point.getRealValue(fAxes[0]->GetName()),
                           point.getRealValue(fAxes[1]->GetName()),
                           point.getRealValue(fAxes[2]->GetName()));
   } else {
      coutE(Eval) << "* Error in MCMCInterval::IsInInterval: " <<
                     "Couldn't handle dimension: " << fDimension << endl;
      return false;
   }

   return fHist->GetBinContent(bin) >= (Double_t)fCutoff;
}

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

void MCMCInterval::SetNumBins(Int_t numBins)
{
   if (!fNumBins) {
      coutE(Eval) << "* Error in MCMCInterval::SetNumBins: " <<
                     "fNumBins not initialized.  Returning immediately" << endl;
      return;
   }
   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)
      CreateHistogram();
}

void MCMCInterval::SetAxes(RooArgList& axes)
{
   Int_t size = axes.getSize();
   if (size != fDimension) {
      coutE(Eval) << "* Error in MCMCInterval::SetAxes: " <<
                     "list size (" << size << ") and " << "dimension ("
                     << fDimension << ") don't match" << endl;
      return;
   }
   for (Int_t i = 0; i < size; i++)
      fAxes[i] = (RooRealVar*)axes.at(i);
}

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

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

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

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

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

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

void MCMCInterval::SetParameters(RooArgSet& parameters)
{
   fParameters = &parameters;
   fDimension = fParameters->getSize();
   if (fAxes != NULL)
      delete[] fAxes;
   fAxes = new RooRealVar*[fDimension];
   if (fNumBins != NULL)
      delete[] fNumBins;
   fNumBins = new Int_t[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;
      fNumBins[n] = fPreferredNumBins;
      n++;
   }
}

void MCMCInterval::DetermineInterval()
{
   Int_t numBins;
   if (fHist == NULL)
      CreateHistogram();

   if (fDimension == 1)
      numBins = fNumBins[0];
   else if (fDimension == 2)
      numBins = fNumBins[0] * fNumBins[1];
   else if (fDimension == 3)
      numBins = fNumBins[0] * fNumBins[1] * fNumBins[2];
   else {
      coutE(Eval) << "* Error in MCMCInterval::DetermineInterval: " <<
                     "Couldn't handle dimension: " << fDimension << endl;
      numBins = 0;
   }

   //TFile chainHistFile("chainHist.root", "recreate");
   //fHist->Write();
   //chainHistFile.Close();

   std::vector<Int_t> bins(numBins);
   // index 1 to numBins because TH1 uses bin 0 for underflow and 
   // bin numBins+1 for overflow
   for (Int_t ibin = 1; ibin <= numBins; ibin++)
      bins[ibin - 1] = ibin;
   std::stable_sort( bins.begin(), bins.end(), CompareBins(fHist) );

   Double_t nEntries = fHist->GetSumOfWeights();
   Double_t sum = 0;
   Double_t content;
   Int_t i;
   for (i = numBins - 1; i >= 0; i--) {
      content = fHist->GetBinContent(bins[i]);
      if ((sum + content) / nEntries >= fConfidenceLevel) {
         fCutoff = content;
         if (fIsStrict) {
            sum += content;
            i--;
            break;
         } else {
            i++;
            break;
         }
      }
      sum += content;
   }

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

   fIntervalSum = sum;
}

// Determine the lower limit for param on this interval
Double_t MCMCInterval::LowerLimit(RooRealVar& param)
{
   for (Int_t d = 0; d < fDimension; d++) {
      if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
         Int_t numBins = fNumBins[d];
         for (Int_t i = 1; i <= numBins; i++)
            if (fHist->GetBinContent(i) >= fCutoff)
                return fHist->GetBinCenter(i);
      }
   }
   return param.getMin();
}

// Determine the upper limit for each param on this interval
Double_t MCMCInterval::UpperLimit(RooRealVar& param)
{
   for (Int_t d = 0; d < fDimension; d++) {
      if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
         Int_t numBins = fNumBins[d];
         Double_t upperLimit = param.getMin();
         for (Int_t i = 1; i <= numBins; i++)
            if (fHist->GetBinContent(i) >= fCutoff)
               upperLimit = fHist->GetBinCenter(i);
         return upperLimit;
      }
   }
   return param.getMax();
}

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

RooArgSet* MCMCInterval::GetParameters() const
{  
   // returns list of parameters
   return (RooArgSet*) fParameters->clone((std::string(fParameters->GetName())+"_clone").c_str());
}

Bool_t MCMCInterval::CheckParameters(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 false;
   }
   if ( ! parameterPoint.equals( *fParameters ) ) {
     coutE(Eval) << "MCMCInterval: size is ok, but parameters don't match" << std::endl;
     return false;
   }
   return true;
}
 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