ROOT logo
// @(#)root/roostats:$Id: ToyMCSampler.h 31276 2009-11-18 15:06:42Z moneta $
// Author: Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke
// Additions and modifications by Mario Pelliccioni
/*************************************************************************
 * 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.             *
 *************************************************************************/

#ifndef ROOSTATS_ToyMCSampler
#define ROOSTATS_ToyMCSampler

//_________________________________________________
/*
BEGIN_HTML
<p>
ToyMCSampler is a simple implementation of the TestStatSampler interface.
It generates Toy Monte Carlo for a given parameter point, and evaluates a 
test statistic that the user specifies (passed via the RooStats::TestStatistic interface).

Development notes: We need to provide a nice way for the user to:
<ul>
  <li>specify the number of toy experiments (needed to probe a given confidence level)</li>
  <li>specify if the number of events per toy experiment should be fixed (conditioning) or floating (unconditional)</li>
  <li>specify if any auxiliary observations should be fixed (conditioning) or floating (unconditional)</li>
  <li>specify if nuisance paramters should be part of the toy MC: eg: integrated out (Bayesian marginalization)</li>
</ul>

All of these should be made fairly explicit in the interface.
</p>
END_HTML
*/
//

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

#include <vector>
#include <sstream>

#include "RooStats/TestStatSampler.h"
#include "RooStats/SamplingDistribution.h"
#include "RooStats/TestStatistic.h"
#include "RooStats/RooStatsUtils.h"

#include "RooWorkspace.h"
#include "RooMsgService.h"
#include "RooAbsPdf.h"
#include "TRandom.h"

#include "RooDataSet.h"

namespace RooStats {

    class ToyMCSampler : public TestStatSampler {


  public:
    ToyMCSampler(TestStatistic &ts) {
      fTestStat = &ts;
      fWS = new RooWorkspace();
      fOwnsWorkspace = true;
      fDataName = "";
      fPdfName = "";
      fPOI = 0;
      fNuisParams=0;
      fObservables=0;
      fExtended = kTRUE;
      fRand = new TRandom();
      fCounter=0;
      fVarName = fTestStat->GetVarName();
      fLastDataSet = 0;
    }

    virtual ~ToyMCSampler() {
      if(fOwnsWorkspace) delete fWS;
      if(fRand) delete fRand;
      if(fLastDataSet) delete fLastDataSet;
    }
    
    // Extended interface to append to sampling distribution more samples
    virtual SamplingDistribution* AppendSamplingDistribution(RooArgSet& allParameters, 
							     SamplingDistribution* last, 
							     Int_t additionalMC) {

      Int_t tmp = fNtoys;
      fNtoys = additionalMC;
      SamplingDistribution* newSamples = GetSamplingDistribution(allParameters);
      fNtoys = tmp;

      if(last){
	last->Add(newSamples);
	delete newSamples;
	return last;
      }

      return newSamples;
    }

    // Main interface to get a SamplingDistribution
    virtual SamplingDistribution* GetSamplingDistribution(RooArgSet& allParameters) {
      std::vector<Double_t> testStatVec;
      //       cout << " about to generate sampling dist " << endl;

      RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;

      for(Int_t i=0; i<fNtoys; ++i){
	//cout << " on toy number " << i << endl;
	//	RooAbsData* toydata = (RooAbsData*)GenerateToyData(allParameters);
	//	testStatVec.push_back( fTestStat->Evaluate(*toydata, allParameters) );
	//	delete toydata;

	RooDataSet* toydata = (RooDataSet*)GenerateToyData(allParameters);
	testStatVec.push_back( fTestStat->Evaluate(*toydata, allParameters) );

	// want to clean up memory, but delete toydata causes problem with 
	// nll->setData(data, noclone) because pointer to last data set is no longer valid
	//	delete toydata; 

	// instead, delete previous data set
	if(fLastDataSet) delete fLastDataSet;
	fLastDataSet = toydata;
      }
     

      //      cout << " generated sampling dist " << endl;
      return new SamplingDistribution( "temp",//MakeName(allParameters).c_str(),
				       "Sampling Distribution of Test Statistic", testStatVec, fVarName );
    } 

     virtual RooAbsData* GenerateToyData(RooArgSet& allParameters) const {
       // This method generates a toy dataset for the given parameter point.


       //       cout << "fNevents = " << fNevents << endl;
       RooAbsPdf* pdf = fWS->pdf(fPdfName);
       if(!fObservables){
	 cout << "Observables not specified in ToyMCSampler, will try to determine.  "
	      << "Will ignore all constant parameters, parameters of interest, and nuisance parameters." << endl;
	 RooArgSet* observables = pdf->getVariables();
	 RemoveConstantParameters(observables); // observables might be set constant, this is just a guess


	 if(fPOI) observables->remove(*fPOI, kFALSE, kTRUE);
	 if(fNuisParams) observables->remove(*fNuisParams, kFALSE, kTRUE);
	 cout << "will use the following as observables when generating data" << endl;
	 observables->Print();
	 fObservables=observables;
       }

       //fluctuate the number of events if fExtended is on.  
       // This is a bit slippery for number counting expts. where entry in data and
       // model is number of events, and so number of entries in data always =1.
       Int_t nEvents = fNevents;
       if(fExtended) {
	 if( pdf->expectedEvents(*fObservables) > 0){
	   // if PDF knows expected events use it instead
	   nEvents = fRand->Poisson(pdf->expectedEvents(*fObservables));
	 } else{
	   nEvents = fRand->Poisson(fNevents);
	 }
       }

       // Set the parameters to desired values for generating toys
       RooArgSet* parameters = pdf->getParameters(fObservables);
       RooStats::SetParameters(&allParameters, parameters);

       /*       
	 cout << "expected events = " <<  pdf->expectedEvents(*observables) 
	    << "fExtended = " << fExtended
	    << "fNevents = " << fNevents << " fNevents " 
	    << "generating" << nEvents << " events " << endl;
       */
       
       RooFit::MsgLevel level = RooMsgService::instance().globalKillBelow();
       RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;

       //       cout << "nEvents = " << nEvents << endl;
       RooAbsData* data = (RooAbsData*)pdf->generate(*fObservables, nEvents);

       RooMsgService::instance().setGlobalKillBelow(level) ;
       delete parameters;
       return data;
     }

     // helper method to create meaningful names for sampling dist
     string MakeName(RooArgSet& /*params*/){
       std::stringstream str;
       str<<"SamplingDist_"<< fCounter;
       fCounter++;

       // WVE -- Return pointer to static buffer
       static char buf[1024] ;
       strcpy(buf,str.str().c_str()) ;

       return buf ;       
     }

      // Main interface to evaluate the test statistic on a dataset
     virtual Double_t EvaluateTestStatistic(RooAbsData& data, RooArgSet& allParameters) {
       return fTestStat->Evaluate(data, allParameters);
     }

      // Get the TestStatistic
      virtual const RooAbsArg* GetTestStatistic()  const {
	 return fTestStat->GetTestStatistic();}  
    
      // Get the Confidence level for the test
      virtual Double_t ConfidenceLevel()  const {return 1.-fSize;}  

      // Common Initialization
      virtual void Initialize(RooAbsArg& /*testStatistic*/, 
			      RooArgSet& /*paramsOfInterest*/, 
			      RooArgSet& /*nuisanceParameters*/) {}

      //set the parameters for the toyMC generation
      virtual void SetNToys(const Int_t ntoy) {
        fNtoys = ntoy;
      }

      virtual void SetNEventsPerToy(const Int_t nevents) {
        fNevents = nevents;
      }


      virtual void SetExtended(const Bool_t isExtended) {
        fExtended = isExtended;
      }

      // Set the DataSet, add to the the workspace if not already there
      virtual void SetData(RooAbsData& data) {
	if(&data){
	  fWS->import(data);
	  fDataName = data.GetName();
	  fWS->Print();
	}
      }
      // Set the Pdf, add to the the workspace if not already there
      virtual void SetPdf(RooAbsPdf& pdf) { 
	if(&pdf){
	  fWS->import(pdf);
	  fPdfName = pdf.GetName();
	}
      }

      // specify the name of the dataset in the workspace to be used
      virtual void SetData(const char* name) {fDataName = name;}
      // specify the name of the PDF in the workspace to be used
      virtual void SetPdf(const char* name) {fPdfName = name;}

      // specify the parameters of interest in the interval
      virtual void SetParameters(RooArgSet& set) {fPOI = &set;}
      // specify the nuisance parameters (eg. the rest of the parameters)
      virtual void SetNuisanceParameters(RooArgSet& set) {fNuisParams = &set;}
      // specify the observables in the dataset (needed to evaluate the test statistic)
      virtual void SetObservables(RooArgSet& set) {fObservables = &set;}

      // set the size of the test (rate of Type I error) ( Eg. 0.05 for a 95% Confidence Interval)
      virtual void SetTestSize(Double_t size) {fSize = size;}
      // set the confidence level for the interval (eg. 0.95 for a 95% Confidence Interval)
      virtual void SetConfidenceLevel(Double_t cl) {fSize = 1.-cl;}

      // Set the TestStatistic (want the argument to be a function of the data & parameter points
      virtual void SetTestStatistic(RooAbsArg&)  const {}  


      
   private:
      Double_t fSize;
      RooWorkspace* fWS; // a workspace that owns all the components to be used by the calculator
      Bool_t fOwnsWorkspace; // flag if this object owns its workspace
      const char* fPdfName; // name of  common PDF in workspace
      const char* fDataName; // name of data set in workspace
      RooArgSet* fPOI; // RooArgSet specifying  parameters of interest for interval
      RooArgSet* fNuisParams;// RooArgSet specifying  nuisance parameters for interval
      mutable RooArgSet* fObservables; // RooArgSet specifying the observables in the dataset (needed to evaluate the test statistic)
      TestStatistic* fTestStat; // pointer to the test statistic that is being sampled
      Int_t fNtoys; // number of toys to generate
      Int_t fNevents; // number of events per toy (may be ignored depending on settings)
      Bool_t fExtended; // if nEvents should fluctuate
      TRandom* fRand; // random generator
      TString fVarName; // name of test statistic

      Int_t fCounter; // counter for naming sampling dist objects

      RooDataSet* fLastDataSet; // work around for memory issues in nllvar->setData(data, noclone)

   protected:
      ClassDef(ToyMCSampler,1)   // A simple implementation of the TestStatSampler interface
	};
}


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