// @(#)root/roostats:$Id$
// Author: Sven Kreiss and Kyle Cranmer    January 2012
// Author: Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke
/*************************************************************************
 * 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_ToyMCImportanceSampler
#define ROOSTATS_ToyMCImportanceSampler

//_________________________________________________
/*
BEGIN_HTML
<p>
ToyMCImportanceSampler is an extension of the ToyMCSampler for Importance Sampling.
</p>

<p>
Implementation based on:
   Cranmer, Kreiss, Read (in Preparation)
</p>
END_HTML
*/
//

#include "RooStats/ToyMCSampler.h"

namespace RooStats {


enum toysStrategies { EQUALTOYSPERDENSITY, EXPONENTIALTOYDISTRIBUTION };


class ToyMCImportanceSampler: public ToyMCSampler {

   public:
      ToyMCImportanceSampler() :
         ToyMCSampler()
      {
         // Proof constructor. Do not use.

         fIndexGenDensity = 0;         
         fGenerateFromNull = true;
         fApplyVeto = true;
         fReuseNLL = true;
         fToysStrategy = EQUALTOYSPERDENSITY;
      }
      ToyMCImportanceSampler(TestStatistic &ts, Int_t ntoys) :
         ToyMCSampler(ts, ntoys)
      {
         fIndexGenDensity = 0;         
         fGenerateFromNull = true;
         fApplyVeto = true;
         fReuseNLL = true;
         fToysStrategy = EQUALTOYSPERDENSITY;
      }


      virtual ~ToyMCImportanceSampler();


      // overwrite GetSamplingDistributionsSingleWorker(paramPoint) with a version that loops
      // over nulls and importance densities, but calls the parent
      // ToyMCSampler::GetSamplingDistributionsSingleWorker(paramPoint).
      virtual RooDataSet* GetSamplingDistributionsSingleWorker(RooArgSet& paramPoint);






      using ToyMCSampler::GenerateToyData;
      virtual RooAbsData* GenerateToyData(RooArgSet& paramPoint, double& weight) const;
      virtual RooAbsData* GenerateToyData(RooArgSet& paramPoint, double& weight, std::vector<double>& impNLLs, double& nullNLL) const;
      virtual RooAbsData* GenerateToyData(std::vector<double>& weights) const;
      virtual RooAbsData* GenerateToyData(std::vector<double>& weights, std::vector<double>& nullNLLs, std::vector<double>& impNLLs) const;


      /// specifies the pdf to sample from
      void SetDensityToGenerateFromByIndex(unsigned int i, bool fromNull = false) {
         if( (fromNull  &&  i >= fNullDensities.size())  ||
             (!fromNull &&  i >= fImportanceDensities.size())
         ) {
            oocoutE((TObject*)0,InputArguments) << "Index out of range. Requested index: "<<i<<
               " , but null densities: "<<fNullDensities.size()<<
               " and importance densities: "<<fImportanceDensities.size() << std::endl;
         }
         
         fIndexGenDensity = i;
         fGenerateFromNull = fromNull;
         
         ClearCache();
      }
      
      // For importance sampling with multiple desnities/snapshots:
      // This is used to check the current Likelihood against Likelihoods from
      // other importance densities apart from the one given as importance snapshot.
      // The pdf can be NULL in which case the density from SetImportanceDensity()
      // is used. The snapshot is also optional.
      void AddImportanceDensity(RooAbsPdf* p, const RooArgSet* s) {
         if( p == NULL && s == NULL ) {
            oocoutI((TObject*)0,InputArguments) << "Neither density nor snapshot given. Doing nothing." << std::endl;
            return;
         }
         if( p == NULL && fPdf == NULL ) {
            oocoutE((TObject*)0,InputArguments) << "No density given, but snapshot is there. Aborting." << std::endl;
            return;
         }
         
         if( p == NULL ) p = fPdf;

         if( s ) s = (const RooArgSet*)s->snapshot();

         fImportanceDensities.push_back( p );
         fImportanceSnapshots.push_back( s );
         fImpNLLs.push_back( NULL );
      }      
      
      // The pdf can be NULL in which case the density from SetPdf()
      // is used. The snapshot and TestStatistic is also optional.
      void AddNullDensity(RooAbsPdf* p, const RooArgSet* s = NULL) {
         if( p == NULL && s == NULL ) {
            oocoutI((TObject*)0,InputArguments) << "Neither density nor snapshot nor test statistic given. Doing nothing." << std::endl;
            return;
         }
         
         if( p == NULL && fNullDensities.size() >= 1 ) p = fNullDensities[0];
         if( s == NULL ) s = fParametersForTestStat;
         if( s ) s = (const RooArgSet*)s->snapshot();
         
         fNullDensities.push_back( p );
         fNullSnapshots.push_back( s );
         fNullNLLs.push_back( NULL );
         ClearCache();
      }
      // overwrite from ToyMCSampler
      virtual void SetPdf(RooAbsPdf& pdf) {
         ToyMCSampler::SetPdf(pdf);
         
         if( fNullDensities.size() == 1 ) { fNullDensities[0] = &pdf; }
         else if( fNullDensities.size() == 0) AddNullDensity( &pdf );
         else{
            oocoutE((TObject*)0,InputArguments) << "Cannot use SetPdf() when already multiple null densities are specified. Please use AddNullDensity()." << std::endl;
         }
      }
      // overwrite from ToyMCSampler
      void SetParametersForTestStat(const RooArgSet& nullpoi) {
         ToyMCSampler::SetParametersForTestStat(nullpoi);
         if( fNullSnapshots.size() == 0 ) AddNullDensity( NULL, &nullpoi );
         else if( fNullSnapshots.size() == 1 ) {
            oocoutI((TObject*)0,InputArguments) << "Overwriting snapshot for the only defined null density." << std::endl;
            if( fNullSnapshots[0] ) delete fNullSnapshots[0];
            fNullSnapshots[0] = (const RooArgSet*)nullpoi.snapshot();
         }else{
            oocoutE((TObject*)0,InputArguments) << "Cannot use SetParametersForTestStat() when already multiple null densities are specified. Please use AddNullDensity()." << std::endl;
         }
      }

      
      // When set to true, this sets the weight of all toys to zero that
      // do not have the largest likelihood under the density it was generated
      // compared to the other densities.
      void SetApplyVeto(bool b = true) { fApplyVeto = b; }

      void SetReuseNLL(bool r = true) { fReuseNLL = r; }


     // set the conditional observables which will be used when creating the NLL
     // so the pdf's will not be normalized on the conditional observables when computing the NLL 
     // Since the class use a NLL we need to set the ocnditional onservables if they exist in the model
     virtual void SetConditionalObservables(const RooArgSet& set) {fConditionalObs.removeAll(); fConditionalObs.add(set);}


      int CreateNImpDensitiesForOnePOI(
         RooAbsPdf& pdf, 
         const RooArgSet& allPOI,
         RooRealVar& poi, 
         int n, 
         double poiValueForBackground = 0.0 
      );
      int CreateImpDensitiesForOnePOIAdaptively(
         RooAbsPdf& pdf, 
         const RooArgSet& allPOI,
         RooRealVar& poi,
         double nStdDevOverlap = 0.5, 
         double poiValueForBackground = 0.0 
      );

      void SetEqualNumToysPerDensity( void ) { fToysStrategy = EQUALTOYSPERDENSITY; }
      void SetExpIncreasingNumToysPerDensity( void ) { fToysStrategy = EXPONENTIALTOYDISTRIBUTION; }

   protected:

      // helper method for clearing  the cache
      virtual void ClearCache();

      unsigned int fIndexGenDensity;
      bool fGenerateFromNull;
      bool fApplyVeto;

   RooArgSet fConditionalObs;  // set of conditional observables

      // support multiple null densities
      std::vector<RooAbsPdf*> fNullDensities;
      mutable std::vector<const RooArgSet*> fNullSnapshots;

      // densities and snapshots to generate from      
      std::vector<RooAbsPdf*> fImportanceDensities;
      std::vector<const RooArgSet*> fImportanceSnapshots;
      
      bool fReuseNLL;
      
      toysStrategies fToysStrategy;

      mutable std::vector<RooAbsReal*> fNullNLLs;    //!
      mutable std::vector<RooAbsReal*> fImpNLLs;     //!


   protected:
   ClassDef(ToyMCImportanceSampler,2) // An implementation of importance sampling
};
}


#endif
 ToyMCImportanceSampler.h:1
 ToyMCImportanceSampler.h:2
 ToyMCImportanceSampler.h:3
 ToyMCImportanceSampler.h:4
 ToyMCImportanceSampler.h:5
 ToyMCImportanceSampler.h:6
 ToyMCImportanceSampler.h:7
 ToyMCImportanceSampler.h:8
 ToyMCImportanceSampler.h:9
 ToyMCImportanceSampler.h:10
 ToyMCImportanceSampler.h:11
 ToyMCImportanceSampler.h:12
 ToyMCImportanceSampler.h:13
 ToyMCImportanceSampler.h:14
 ToyMCImportanceSampler.h:15
 ToyMCImportanceSampler.h:16
 ToyMCImportanceSampler.h:17
 ToyMCImportanceSampler.h:18
 ToyMCImportanceSampler.h:19
 ToyMCImportanceSampler.h:20
 ToyMCImportanceSampler.h:21
 ToyMCImportanceSampler.h:22
 ToyMCImportanceSampler.h:23
 ToyMCImportanceSampler.h:24
 ToyMCImportanceSampler.h:25
 ToyMCImportanceSampler.h:26
 ToyMCImportanceSampler.h:27
 ToyMCImportanceSampler.h:28
 ToyMCImportanceSampler.h:29
 ToyMCImportanceSampler.h:30
 ToyMCImportanceSampler.h:31
 ToyMCImportanceSampler.h:32
 ToyMCImportanceSampler.h:33
 ToyMCImportanceSampler.h:34
 ToyMCImportanceSampler.h:35
 ToyMCImportanceSampler.h:36
 ToyMCImportanceSampler.h:37
 ToyMCImportanceSampler.h:38
 ToyMCImportanceSampler.h:39
 ToyMCImportanceSampler.h:40
 ToyMCImportanceSampler.h:41
 ToyMCImportanceSampler.h:42
 ToyMCImportanceSampler.h:43
 ToyMCImportanceSampler.h:44
 ToyMCImportanceSampler.h:45
 ToyMCImportanceSampler.h:46
 ToyMCImportanceSampler.h:47
 ToyMCImportanceSampler.h:48
 ToyMCImportanceSampler.h:49
 ToyMCImportanceSampler.h:50
 ToyMCImportanceSampler.h:51
 ToyMCImportanceSampler.h:52
 ToyMCImportanceSampler.h:53
 ToyMCImportanceSampler.h:54
 ToyMCImportanceSampler.h:55
 ToyMCImportanceSampler.h:56
 ToyMCImportanceSampler.h:57
 ToyMCImportanceSampler.h:58
 ToyMCImportanceSampler.h:59
 ToyMCImportanceSampler.h:60
 ToyMCImportanceSampler.h:61
 ToyMCImportanceSampler.h:62
 ToyMCImportanceSampler.h:63
 ToyMCImportanceSampler.h:64
 ToyMCImportanceSampler.h:65
 ToyMCImportanceSampler.h:66
 ToyMCImportanceSampler.h:67
 ToyMCImportanceSampler.h:68
 ToyMCImportanceSampler.h:69
 ToyMCImportanceSampler.h:70
 ToyMCImportanceSampler.h:71
 ToyMCImportanceSampler.h:72
 ToyMCImportanceSampler.h:73
 ToyMCImportanceSampler.h:74
 ToyMCImportanceSampler.h:75
 ToyMCImportanceSampler.h:76
 ToyMCImportanceSampler.h:77
 ToyMCImportanceSampler.h:78
 ToyMCImportanceSampler.h:79
 ToyMCImportanceSampler.h:80
 ToyMCImportanceSampler.h:81
 ToyMCImportanceSampler.h:82
 ToyMCImportanceSampler.h:83
 ToyMCImportanceSampler.h:84
 ToyMCImportanceSampler.h:85
 ToyMCImportanceSampler.h:86
 ToyMCImportanceSampler.h:87
 ToyMCImportanceSampler.h:88
 ToyMCImportanceSampler.h:89
 ToyMCImportanceSampler.h:90
 ToyMCImportanceSampler.h:91
 ToyMCImportanceSampler.h:92
 ToyMCImportanceSampler.h:93
 ToyMCImportanceSampler.h:94
 ToyMCImportanceSampler.h:95
 ToyMCImportanceSampler.h:96
 ToyMCImportanceSampler.h:97
 ToyMCImportanceSampler.h:98
 ToyMCImportanceSampler.h:99
 ToyMCImportanceSampler.h:100
 ToyMCImportanceSampler.h:101
 ToyMCImportanceSampler.h:102
 ToyMCImportanceSampler.h:103
 ToyMCImportanceSampler.h:104
 ToyMCImportanceSampler.h:105
 ToyMCImportanceSampler.h:106
 ToyMCImportanceSampler.h:107
 ToyMCImportanceSampler.h:108
 ToyMCImportanceSampler.h:109
 ToyMCImportanceSampler.h:110
 ToyMCImportanceSampler.h:111
 ToyMCImportanceSampler.h:112
 ToyMCImportanceSampler.h:113
 ToyMCImportanceSampler.h:114
 ToyMCImportanceSampler.h:115
 ToyMCImportanceSampler.h:116
 ToyMCImportanceSampler.h:117
 ToyMCImportanceSampler.h:118
 ToyMCImportanceSampler.h:119
 ToyMCImportanceSampler.h:120
 ToyMCImportanceSampler.h:121
 ToyMCImportanceSampler.h:122
 ToyMCImportanceSampler.h:123
 ToyMCImportanceSampler.h:124
 ToyMCImportanceSampler.h:125
 ToyMCImportanceSampler.h:126
 ToyMCImportanceSampler.h:127
 ToyMCImportanceSampler.h:128
 ToyMCImportanceSampler.h:129
 ToyMCImportanceSampler.h:130
 ToyMCImportanceSampler.h:131
 ToyMCImportanceSampler.h:132
 ToyMCImportanceSampler.h:133
 ToyMCImportanceSampler.h:134
 ToyMCImportanceSampler.h:135
 ToyMCImportanceSampler.h:136
 ToyMCImportanceSampler.h:137
 ToyMCImportanceSampler.h:138
 ToyMCImportanceSampler.h:139
 ToyMCImportanceSampler.h:140
 ToyMCImportanceSampler.h:141
 ToyMCImportanceSampler.h:142
 ToyMCImportanceSampler.h:143
 ToyMCImportanceSampler.h:144
 ToyMCImportanceSampler.h:145
 ToyMCImportanceSampler.h:146
 ToyMCImportanceSampler.h:147
 ToyMCImportanceSampler.h:148
 ToyMCImportanceSampler.h:149
 ToyMCImportanceSampler.h:150
 ToyMCImportanceSampler.h:151
 ToyMCImportanceSampler.h:152
 ToyMCImportanceSampler.h:153
 ToyMCImportanceSampler.h:154
 ToyMCImportanceSampler.h:155
 ToyMCImportanceSampler.h:156
 ToyMCImportanceSampler.h:157
 ToyMCImportanceSampler.h:158
 ToyMCImportanceSampler.h:159
 ToyMCImportanceSampler.h:160
 ToyMCImportanceSampler.h:161
 ToyMCImportanceSampler.h:162
 ToyMCImportanceSampler.h:163
 ToyMCImportanceSampler.h:164
 ToyMCImportanceSampler.h:165
 ToyMCImportanceSampler.h:166
 ToyMCImportanceSampler.h:167
 ToyMCImportanceSampler.h:168
 ToyMCImportanceSampler.h:169
 ToyMCImportanceSampler.h:170
 ToyMCImportanceSampler.h:171
 ToyMCImportanceSampler.h:172
 ToyMCImportanceSampler.h:173
 ToyMCImportanceSampler.h:174
 ToyMCImportanceSampler.h:175
 ToyMCImportanceSampler.h:176
 ToyMCImportanceSampler.h:177
 ToyMCImportanceSampler.h:178
 ToyMCImportanceSampler.h:179
 ToyMCImportanceSampler.h:180
 ToyMCImportanceSampler.h:181
 ToyMCImportanceSampler.h:182
 ToyMCImportanceSampler.h:183
 ToyMCImportanceSampler.h:184
 ToyMCImportanceSampler.h:185
 ToyMCImportanceSampler.h:186
 ToyMCImportanceSampler.h:187
 ToyMCImportanceSampler.h:188
 ToyMCImportanceSampler.h:189
 ToyMCImportanceSampler.h:190
 ToyMCImportanceSampler.h:191
 ToyMCImportanceSampler.h:192
 ToyMCImportanceSampler.h:193
 ToyMCImportanceSampler.h:194
 ToyMCImportanceSampler.h:195
 ToyMCImportanceSampler.h:196
 ToyMCImportanceSampler.h:197
 ToyMCImportanceSampler.h:198
 ToyMCImportanceSampler.h:199
 ToyMCImportanceSampler.h:200
 ToyMCImportanceSampler.h:201
 ToyMCImportanceSampler.h:202
 ToyMCImportanceSampler.h:203
 ToyMCImportanceSampler.h:204
 ToyMCImportanceSampler.h:205
 ToyMCImportanceSampler.h:206
 ToyMCImportanceSampler.h:207
 ToyMCImportanceSampler.h:208
 ToyMCImportanceSampler.h:209
 ToyMCImportanceSampler.h:210
 ToyMCImportanceSampler.h:211
 ToyMCImportanceSampler.h:212
 ToyMCImportanceSampler.h:213
 ToyMCImportanceSampler.h:214
 ToyMCImportanceSampler.h:215
 ToyMCImportanceSampler.h:216
 ToyMCImportanceSampler.h:217
 ToyMCImportanceSampler.h:218
 ToyMCImportanceSampler.h:219
 ToyMCImportanceSampler.h:220
 ToyMCImportanceSampler.h:221
 ToyMCImportanceSampler.h:222
 ToyMCImportanceSampler.h:223
 ToyMCImportanceSampler.h:224
 ToyMCImportanceSampler.h:225
 ToyMCImportanceSampler.h:226
 ToyMCImportanceSampler.h:227
 ToyMCImportanceSampler.h:228
 ToyMCImportanceSampler.h:229