ROOT logo
// @(#)root/roostats:$Id: MCMCCalculator.cxx 31876 2009-12-14 11:11:27Z brun $
// 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>
MCMCCalculator is a concrete implementation of IntervalCalculator.
It uses a MetropolisHastings object to construct a Markov Chain of data points in the
parameter space.  From this Markov Chain, this class can generate a MCMCInterval as
per user specification.
</p>

<p>
The interface allows one to pass the model, data, and parameters  or eventually 
specify them with names via the ModelConfig class.
</p>

<p>
After configuring the calculator, one only needs to ask GetInterval(), which will
return an ConfInterval (MCMCInterval in this case).
</p>
END_HTML
*/
//_________________________________________________

#ifndef ROOT_Rtypes
#include "Rtypes.h"
#endif
#ifndef ROO_GLOBAL_FUNC
#include "RooGlobalFunc.h"
#endif
#ifndef ROO_ABS_REAL
#include "RooAbsReal.h"
#endif
#ifndef ROO_ARG_SET
#include "RooArgSet.h"
#endif
#ifndef ROO_ARG_LIST
#include "RooArgList.h"
#endif
#ifndef ROOSTATS_ModelConfig
#include "RooStats/ModelConfig.h"
#endif
#ifndef RooStats_RooStatsUtils
#include "RooStats/RooStatsUtils.h"
#endif
#ifndef ROOSTATS_MCMCCalculator
#include "RooStats/MCMCCalculator.h"
#endif
#ifndef ROOSTATS_MetropolisHastings
#include "RooStats/MetropolisHastings.h"
#endif
#ifndef ROOSTATS_MarkovChain
#include "RooStats/MarkovChain.h"
#endif
#ifndef RooStats_MCMCInterval
#include "RooStats/MCMCInterval.h"
#endif
#ifndef ROOT_TIterator
#include "TIterator.h"
#endif
#ifndef ROOSTATS_UniformProposal
#include "RooStats/UniformProposal.h"
#endif
#ifndef ROOSTATS_PdfProposal
#include "RooStats/PdfProposal.h"
#endif

#include "RooProdPdf.h"

ClassImp(RooStats::MCMCCalculator);

using namespace RooFit;
using namespace RooStats;

// default constructor
MCMCCalculator::MCMCCalculator() : 
   fPropFunc(0), 
   fPdf(0), 
   fPriorPdf(0),
   fData(0),
   fAxes(0)
{
   // default constructor
   fNumIters = 0;
   fNumBurnInSteps = 0;
   fNumBins = 0;
   fUseKeys = kFALSE;
   fUseSparseHist = kFALSE;
}

MCMCCalculator::MCMCCalculator(RooAbsData& data, RooAbsPdf& pdf,
                               const RooArgSet& paramsOfInterest,
                               RooAbsPdf & prior) : 
   fPOI(paramsOfInterest),
   fPropFunc(0), 
   fPdf(&pdf), 
   fPriorPdf(&prior),
   fData(&data),
   fAxes(0)
{
// Constructor for automatic configuration with basic settings.  Uses a
// UniformProposal,10,000 iterations, 40 burn in steps, 50 bins for each
// RooRealVar, determines interval by keys, and turns on sparse histogram
// mode in the MCMCInterval.  Finds a 95% confidence interval.
   SetupBasicUsage();
}

MCMCCalculator::MCMCCalculator(RooAbsData& data, RooAbsPdf& pdf,
                               const RooArgSet& paramsOfInterest) :
   fPOI(paramsOfInterest),
   fPropFunc(0), 
   fPdf(&pdf), 
   fPriorPdf(0),
   fData(&data),
   fAxes(0)
{
// same constructor as before but not passing a prior pdf
   SetupBasicUsage();
}

MCMCCalculator::MCMCCalculator(RooAbsData& data, const ModelConfig & model) :
   fPropFunc(0), 
   fPdf(model.GetPdf()), 
   fPriorPdf(0),
   fData(&data)
{
// Constructor for automatic configuration with basic settings.  Uses a
// UniformProposal,10,000 iterations, 40 burn in steps, 50 bins for each
// RooRealVar, determines interval by keys, and turns on sparse histogram
// mode in the MCMCInterval.  Finds a 95% confidence interval.
   SetModel(model);
   SetupBasicUsage();
}

MCMCCalculator::MCMCCalculator(RooAbsData& data, const ModelConfig & model,
                               ProposalFunction& proposalFunction, Int_t numIters,
                               RooArgList* axes, Double_t size) : 
   fPropFunc(&proposalFunction), 
   fPdf(model.GetPdf()), 
   fPriorPdf(0),
   fData(&data), 
   fAxes(axes)
{
// alternate constructor, specifying many arguments
   SetModel(model);
   SetTestSize(size);
   fNumIters = numIters;
   fNumBurnInSteps = 0;
   fNumBins = 0;
   fUseKeys = kFALSE;
   fUseSparseHist = kFALSE;
}

void MCMCCalculator::SetModel(const ModelConfig & model) { 
   // set the model
   fPdf = model.GetPdf();  
   fPriorPdf = model.GetPriorPdf();
   fPOI.removeAll();
   fNuisParams.removeAll();
   if (model.GetParametersOfInterest() ) fPOI.add(*model.GetParametersOfInterest());
   if (model.GetNuisanceParameters() )   fNuisParams.add(*model.GetNuisanceParameters());
}

// alternate constructor, specifying many arguments
MCMCCalculator::MCMCCalculator(RooAbsData& data, RooAbsPdf& pdf,
                               const RooArgSet& paramsOfInterest, RooAbsPdf & prior, ProposalFunction& proposalFunction,
                               Int_t numIters, RooArgList* axes, Double_t size) : 
   fPOI(paramsOfInterest),
   fPropFunc(&proposalFunction), 
   fPdf(&pdf), 
   fPriorPdf(&prior),
   fData(&data), 
   fAxes(axes)
{
   SetTestSize(size);
   fNumIters = numIters;
   fNumBurnInSteps = 0;
   fNumBins = 0;
   fAxes = axes;
   fUseKeys = kFALSE;
   fUseSparseHist = kFALSE;
}

void MCMCCalculator::SetupBasicUsage()
{
// Setting automatic configuration with basic settings.  Uses a
// UniformProposal,10,000 iterations, 40 burn in steps, 50 bins for each
// RooRealVar, determines interval by keys, and turns on sparse histogram
// mode in the MCMCInterval.  Finds a 95% confidence interval.
   fPropFunc = 0;
   fNumIters = 10000;
   fNumBurnInSteps = 40;
   //fNumBins = 0;
   fNumBins = 50;
   fUseKeys = kTRUE;
   fUseSparseHist = kTRUE;
   SetTestSize(0.05);
}

MCMCInterval* MCMCCalculator::GetInterval() const
{
   // Main interface to get a RooStats::ConfInterval.  

   if (!fData || !fPdf   ) return 0;
   if (fPOI.getSize() == 0) return 0;

   // if a proposal function has not been specified create a default one
   bool useDefaultPropFunc = (fPropFunc == 0); 
   bool usePriorPdf = (fPriorPdf != 0);
   if (useDefaultPropFunc) fPropFunc = new UniformProposal(); 

   // if prior is given create product 
   RooAbsPdf * prodPdf = fPdf;
   if (usePriorPdf) { 
      TString prodName = TString("product_") + TString(fPdf->GetName()) + TString("_") + TString(fPriorPdf->GetName() );   
      prodPdf = new RooProdPdf(prodName,prodName,RooArgList(*fPdf,*fPriorPdf) );
   }

   RooArgSet* constrainedParams = prodPdf->getParameters(*fData);
   RooAbsReal* nll = prodPdf->createNLL(*fData, Constrain(*constrainedParams));
   delete constrainedParams;

   RooArgSet* params = nll->getParameters(*fData);
   RemoveConstantParameters(params);
   if (fNumBins > 0) {
      SetBins(*params, fNumBins);
      SetBins(fPOI, fNumBins);
      if (dynamic_cast<PdfProposal*>(fPropFunc)) {
         RooArgSet* proposalVars = ((PdfProposal*)fPropFunc)->GetPdf()->
                                               getParameters((RooAbsData*)NULL);
         SetBins(*proposalVars, fNumBins);
      }
   }

   MetropolisHastings mh;
   mh.SetFunction(*nll);
   mh.SetType(MetropolisHastings::kLog);
   mh.SetSign(MetropolisHastings::kNegative);
   mh.SetParameters(*params);
   mh.SetProposalFunction(*fPropFunc);
   mh.SetNumIters(fNumIters);

   MarkovChain* chain = mh.ConstructChain();

   TString name = TString("MCMCInterval_") + TString(GetName() ); 
   MCMCInterval* interval = new MCMCInterval(name, fPOI, *chain);
   if (fAxes != NULL)
      interval->SetAxes(*fAxes);
   if (fNumBurnInSteps > 0)
      interval->SetNumBurnInSteps(fNumBurnInSteps);
   interval->SetUseKeys(fUseKeys);
   interval->SetUseSparseHist(fUseSparseHist);
   interval->SetConfidenceLevel(1.0 - fSize);

   if (useDefaultPropFunc) delete fPropFunc; 
   if (usePriorPdf) delete prodPdf; 
   delete nll; 
   delete params;
   
   return interval;
}
 MCMCCalculator.cxx:1
 MCMCCalculator.cxx:2
 MCMCCalculator.cxx:3
 MCMCCalculator.cxx:4
 MCMCCalculator.cxx:5
 MCMCCalculator.cxx:6
 MCMCCalculator.cxx:7
 MCMCCalculator.cxx:8
 MCMCCalculator.cxx:9
 MCMCCalculator.cxx:10
 MCMCCalculator.cxx:11
 MCMCCalculator.cxx:12
 MCMCCalculator.cxx:13
 MCMCCalculator.cxx:14
 MCMCCalculator.cxx:15
 MCMCCalculator.cxx:16
 MCMCCalculator.cxx:17
 MCMCCalculator.cxx:18
 MCMCCalculator.cxx:19
 MCMCCalculator.cxx:20
 MCMCCalculator.cxx:21
 MCMCCalculator.cxx:22
 MCMCCalculator.cxx:23
 MCMCCalculator.cxx:24
 MCMCCalculator.cxx:25
 MCMCCalculator.cxx:26
 MCMCCalculator.cxx:27
 MCMCCalculator.cxx:28
 MCMCCalculator.cxx:29
 MCMCCalculator.cxx:30
 MCMCCalculator.cxx:31
 MCMCCalculator.cxx:32
 MCMCCalculator.cxx:33
 MCMCCalculator.cxx:34
 MCMCCalculator.cxx:35
 MCMCCalculator.cxx:36
 MCMCCalculator.cxx:37
 MCMCCalculator.cxx:38
 MCMCCalculator.cxx:39
 MCMCCalculator.cxx:40
 MCMCCalculator.cxx:41
 MCMCCalculator.cxx:42
 MCMCCalculator.cxx:43
 MCMCCalculator.cxx:44
 MCMCCalculator.cxx:45
 MCMCCalculator.cxx:46
 MCMCCalculator.cxx:47
 MCMCCalculator.cxx:48
 MCMCCalculator.cxx:49
 MCMCCalculator.cxx:50
 MCMCCalculator.cxx:51
 MCMCCalculator.cxx:52
 MCMCCalculator.cxx:53
 MCMCCalculator.cxx:54
 MCMCCalculator.cxx:55
 MCMCCalculator.cxx:56
 MCMCCalculator.cxx:57
 MCMCCalculator.cxx:58
 MCMCCalculator.cxx:59
 MCMCCalculator.cxx:60
 MCMCCalculator.cxx:61
 MCMCCalculator.cxx:62
 MCMCCalculator.cxx:63
 MCMCCalculator.cxx:64
 MCMCCalculator.cxx:65
 MCMCCalculator.cxx:66
 MCMCCalculator.cxx:67
 MCMCCalculator.cxx:68
 MCMCCalculator.cxx:69
 MCMCCalculator.cxx:70
 MCMCCalculator.cxx:71
 MCMCCalculator.cxx:72
 MCMCCalculator.cxx:73
 MCMCCalculator.cxx:74
 MCMCCalculator.cxx:75
 MCMCCalculator.cxx:76
 MCMCCalculator.cxx:77
 MCMCCalculator.cxx:78
 MCMCCalculator.cxx:79
 MCMCCalculator.cxx:80
 MCMCCalculator.cxx:81
 MCMCCalculator.cxx:82
 MCMCCalculator.cxx:83
 MCMCCalculator.cxx:84
 MCMCCalculator.cxx:85
 MCMCCalculator.cxx:86
 MCMCCalculator.cxx:87
 MCMCCalculator.cxx:88
 MCMCCalculator.cxx:89
 MCMCCalculator.cxx:90
 MCMCCalculator.cxx:91
 MCMCCalculator.cxx:92
 MCMCCalculator.cxx:93
 MCMCCalculator.cxx:94
 MCMCCalculator.cxx:95
 MCMCCalculator.cxx:96
 MCMCCalculator.cxx:97
 MCMCCalculator.cxx:98
 MCMCCalculator.cxx:99
 MCMCCalculator.cxx:100
 MCMCCalculator.cxx:101
 MCMCCalculator.cxx:102
 MCMCCalculator.cxx:103
 MCMCCalculator.cxx:104
 MCMCCalculator.cxx:105
 MCMCCalculator.cxx:106
 MCMCCalculator.cxx:107
 MCMCCalculator.cxx:108
 MCMCCalculator.cxx:109
 MCMCCalculator.cxx:110
 MCMCCalculator.cxx:111
 MCMCCalculator.cxx:112
 MCMCCalculator.cxx:113
 MCMCCalculator.cxx:114
 MCMCCalculator.cxx:115
 MCMCCalculator.cxx:116
 MCMCCalculator.cxx:117
 MCMCCalculator.cxx:118
 MCMCCalculator.cxx:119
 MCMCCalculator.cxx:120
 MCMCCalculator.cxx:121
 MCMCCalculator.cxx:122
 MCMCCalculator.cxx:123
 MCMCCalculator.cxx:124
 MCMCCalculator.cxx:125
 MCMCCalculator.cxx:126
 MCMCCalculator.cxx:127
 MCMCCalculator.cxx:128
 MCMCCalculator.cxx:129
 MCMCCalculator.cxx:130
 MCMCCalculator.cxx:131
 MCMCCalculator.cxx:132
 MCMCCalculator.cxx:133
 MCMCCalculator.cxx:134
 MCMCCalculator.cxx:135
 MCMCCalculator.cxx:136
 MCMCCalculator.cxx:137
 MCMCCalculator.cxx:138
 MCMCCalculator.cxx:139
 MCMCCalculator.cxx:140
 MCMCCalculator.cxx:141
 MCMCCalculator.cxx:142
 MCMCCalculator.cxx:143
 MCMCCalculator.cxx:144
 MCMCCalculator.cxx:145
 MCMCCalculator.cxx:146
 MCMCCalculator.cxx:147
 MCMCCalculator.cxx:148
 MCMCCalculator.cxx:149
 MCMCCalculator.cxx:150
 MCMCCalculator.cxx:151
 MCMCCalculator.cxx:152
 MCMCCalculator.cxx:153
 MCMCCalculator.cxx:154
 MCMCCalculator.cxx:155
 MCMCCalculator.cxx:156
 MCMCCalculator.cxx:157
 MCMCCalculator.cxx:158
 MCMCCalculator.cxx:159
 MCMCCalculator.cxx:160
 MCMCCalculator.cxx:161
 MCMCCalculator.cxx:162
 MCMCCalculator.cxx:163
 MCMCCalculator.cxx:164
 MCMCCalculator.cxx:165
 MCMCCalculator.cxx:166
 MCMCCalculator.cxx:167
 MCMCCalculator.cxx:168
 MCMCCalculator.cxx:169
 MCMCCalculator.cxx:170
 MCMCCalculator.cxx:171
 MCMCCalculator.cxx:172
 MCMCCalculator.cxx:173
 MCMCCalculator.cxx:174
 MCMCCalculator.cxx:175
 MCMCCalculator.cxx:176
 MCMCCalculator.cxx:177
 MCMCCalculator.cxx:178
 MCMCCalculator.cxx:179
 MCMCCalculator.cxx:180
 MCMCCalculator.cxx:181
 MCMCCalculator.cxx:182
 MCMCCalculator.cxx:183
 MCMCCalculator.cxx:184
 MCMCCalculator.cxx:185
 MCMCCalculator.cxx:186
 MCMCCalculator.cxx:187
 MCMCCalculator.cxx:188
 MCMCCalculator.cxx:189
 MCMCCalculator.cxx:190
 MCMCCalculator.cxx:191
 MCMCCalculator.cxx:192
 MCMCCalculator.cxx:193
 MCMCCalculator.cxx:194
 MCMCCalculator.cxx:195
 MCMCCalculator.cxx:196
 MCMCCalculator.cxx:197
 MCMCCalculator.cxx:198
 MCMCCalculator.cxx:199
 MCMCCalculator.cxx:200
 MCMCCalculator.cxx:201
 MCMCCalculator.cxx:202
 MCMCCalculator.cxx:203
 MCMCCalculator.cxx:204
 MCMCCalculator.cxx:205
 MCMCCalculator.cxx:206
 MCMCCalculator.cxx:207
 MCMCCalculator.cxx:208
 MCMCCalculator.cxx:209
 MCMCCalculator.cxx:210
 MCMCCalculator.cxx:211
 MCMCCalculator.cxx:212
 MCMCCalculator.cxx:213
 MCMCCalculator.cxx:214
 MCMCCalculator.cxx:215
 MCMCCalculator.cxx:216
 MCMCCalculator.cxx:217
 MCMCCalculator.cxx:218
 MCMCCalculator.cxx:219
 MCMCCalculator.cxx:220
 MCMCCalculator.cxx:221
 MCMCCalculator.cxx:222
 MCMCCalculator.cxx:223
 MCMCCalculator.cxx:224
 MCMCCalculator.cxx:225
 MCMCCalculator.cxx:226
 MCMCCalculator.cxx:227
 MCMCCalculator.cxx:228
 MCMCCalculator.cxx:229
 MCMCCalculator.cxx:230
 MCMCCalculator.cxx:231
 MCMCCalculator.cxx:232
 MCMCCalculator.cxx:233
 MCMCCalculator.cxx:234
 MCMCCalculator.cxx:235
 MCMCCalculator.cxx:236
 MCMCCalculator.cxx:237
 MCMCCalculator.cxx:238
 MCMCCalculator.cxx:239
 MCMCCalculator.cxx:240
 MCMCCalculator.cxx:241
 MCMCCalculator.cxx:242
 MCMCCalculator.cxx:243
 MCMCCalculator.cxx:244
 MCMCCalculator.cxx:245
 MCMCCalculator.cxx:246
 MCMCCalculator.cxx:247
 MCMCCalculator.cxx:248
 MCMCCalculator.cxx:249
 MCMCCalculator.cxx:250
 MCMCCalculator.cxx:251
 MCMCCalculator.cxx:252
 MCMCCalculator.cxx:253
 MCMCCalculator.cxx:254
 MCMCCalculator.cxx:255
 MCMCCalculator.cxx:256
 MCMCCalculator.cxx:257
 MCMCCalculator.cxx:258
 MCMCCalculator.cxx:259
 MCMCCalculator.cxx:260
 MCMCCalculator.cxx:261
 MCMCCalculator.cxx:262
 MCMCCalculator.cxx:263
 MCMCCalculator.cxx:264
 MCMCCalculator.cxx:265
 MCMCCalculator.cxx:266
 MCMCCalculator.cxx:267
 MCMCCalculator.cxx:268
 MCMCCalculator.cxx:269
 MCMCCalculator.cxx:270
 MCMCCalculator.cxx:271