ROOT logo
// @(#)root/roostats:$Id: ProfileLikelihoodTestStat.h 36602 2010-11-11 16:52:13Z moneta $
// 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_ProfileLikelihoodTestStat
#define ROOSTATS_ProfileLikelihoodTestStat

//_________________________________________________
/*
BEGIN_HTML
<p>
ProfileLikelihoodTestStat is an implementation of the TestStatistic interface that calculates the profile
likelihood ratio at a particular parameter point given a dataset.  It does not constitute a statistical test, for that one may either use:
<ul>
 <li> the ProfileLikelihoodCalculator that relies on asymptotic properties of the Profile Likelihood Ratio</li>
 <li> the Neyman Construction classes with this class as a test statistic</li>
 <li> the Hybrid Calculator class with this class as a test statistic</li>
</ul>

</p>
END_HTML
*/
//

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

#include <vector>

#include "RooStats/RooStatsUtils.h"

//#include "RooStats/DistributionCreator.h"
#include "RooStats/SamplingDistribution.h"
#include "RooStats/TestStatistic.h"

#include "RooStats/RooStatsUtils.h"

#include "RooRealVar.h"
#include "RooProfileLL.h"
#include "RooNLLVar.h"

#include "RooMinuit.h"

namespace RooStats {

  class ProfileLikelihoodTestStat : public TestStatistic{

   public:
     ProfileLikelihoodTestStat() {
        // Proof constructor. Do not use.
        fPdf = 0;
        fProfile = 0;
        fNll = 0;
        fCachedBestFitParams = 0;
        fLastData = 0;
     }
     ProfileLikelihoodTestStat(RooAbsPdf& pdf) {
       fPdf = &pdf;
       fProfile = 0;
       fNll = 0;
       fCachedBestFitParams = 0;
       fLastData = 0;
     }
     virtual ~ProfileLikelihoodTestStat() {
       //       delete fRand;
       //       delete fTestStatistic;
       if(fProfile) delete fProfile;
       if(fNll) delete fNll;
       if(fCachedBestFitParams) delete fCachedBestFitParams;
     }
    
     // Main interface to evaluate the test statistic on a dataset
     virtual Double_t Evaluate(RooAbsData& data, RooArgSet& paramsOfInterest) {
       if (!&data) {
	 cout << "problem with data" << endl;
	 return 0 ;
       }
       
       RooFit::MsgLevel msglevel = RooMsgService::instance().globalKillBelow();
       RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL);


       // simple
       RooAbsReal* nll = fPdf->createNLL(data, RooFit::CloneData(kFALSE));
       RooAbsReal* profile = nll->createProfile(paramsOfInterest);
       // make sure we set the variables attached to this nll
       RooArgSet* attachedSet = nll->getVariables();
       *attachedSet = paramsOfInterest;
       double ret = profile->getVal();
       //       paramsOfInterest.Print("v");
       delete attachedSet;
       delete nll;
       nll = 0; 
       delete profile;
       RooMsgService::instance().setGlobalKillBelow(msglevel);
       //       cout << "ret = " << ret << endl;


       // return here and forget about the following code
       return ret;

       // OLD version with some handling for local minima
       // (not used right now)

         bool needToRebuild = true; // try to avoid rebuilding if possible

         if (fLastData == &data) // simple pointer comparison for now (note NLL makes COPY of data)
            needToRebuild = false;
         else fLastData = &data; // keep a copy of pointer to original data

         // pointer comparison causing problems.  See multiple datasets with same value of pointer
         // but actually a new dataset
         needToRebuild = true;

         // check mem leak in NLL or Profile. Should remove.
         // if(fProfile) needToRebuild = false;


         if (needToRebuild) {
            if (fProfile) delete fProfile;
            if (fNll) delete fNll;

            /*
             RooNLLVar* nll = new RooNLLVar("nll","",*fPdf,data, RooFit::Extended());
             fNll = nll;
             fProfile = new RooProfileLL("pll","",*nll, paramsOfInterest);
             */
            RooArgSet* constrainedParams = fPdf->getParameters(data);
            RemoveConstantParameters(constrainedParams);
            //cout << "cons: " << endl;
            //constrainedParams->Print("v");

            RooNLLVar * nll2 = (RooNLLVar*) fPdf->createNLL(
               data, RooFit::CloneData(kFALSE), RooFit::Constrain(*constrainedParams)
            );
            fNll = nll2;
            fProfile = (RooProfileLL*) nll2->createProfile(paramsOfInterest);
            delete constrainedParams;

            //	 paramsOfInterest.Print("v");

            // set parameters to previous best fit params, to speed convergence
            // and to avoid local minima
            if (fCachedBestFitParams) {
               // store original values, since minimization will change them.
               RooArgSet* origParamVals = (RooArgSet*) paramsOfInterest.snapshot();

               // these parameters are not guaranteed to be the best for this data
               SetParameters(fCachedBestFitParams, fProfile->getParameters(data));
               // now evaluate to force this profile to evaluate and store
               // best fit parameters for this data
               fProfile->getVal();

               // possibly store last MLE for reference
               //	 Double mle = fNll->getVal();

               // restore parameters
               SetParameters(origParamVals, &paramsOfInterest);

               // cleanup
               delete origParamVals;

            } else {

               // store best fit parameters
               // RooProfileLL::bestFitParams returns best fit of nuisance parameters only
               //	   fCachedBestFitParams = (RooArgSet*) (fProfile->bestFitParams().clone("lastBestFit"));
               // ProfileLL::getParameters returns current value of the parameters
               //	   fCachedBestFitParams = (RooArgSet*) (fProfile->getParameters(data)->clone("lastBestFit"));
               //cout << "making fCachedBestFitParams: " << fCachedBestFitParams << fCachedBestFitParams->getSize() << endl;

               // store original values, since minimization will change them.
               RooArgSet* origParamVals = (RooArgSet*) paramsOfInterest.snapshot();

               // find minimum
               RooMinuit minuit(*nll);
               minuit.setPrintLevel(-999);
               minuit.setNoWarn();
               minuit.migrad();

               // store the best fit values for future use
               fCachedBestFitParams = (RooArgSet*) (nll->getParameters(data)->snapshot());

               // restore parameters
               SetParameters(origParamVals, &paramsOfInterest);

               // evaluate to force this profile to evaluate and store
               // best fit parameters for this data
               fProfile->getVal();

               // cleanup
               delete origParamVals;

            }

         }
         // issue warning if problems
         if (!fProfile) {
            cout << "problem making profile" << endl;
         }

         // set parameters to point being requested
         SetParameters(&paramsOfInterest, fProfile->getParameters(data));

         Double_t value = fProfile->getVal();

         /*
          // for debugging caching
          cout << "current value of input params: " << endl;
          paramsOfInterest.Print("verbose");

          cout << "current value of params in profile: " << endl;
          fProfile->getParameters(data)->Print("verbose");

          cout << "cached last best fit: " << endl;
          fCachedBestFitParams->Print("verbose");
          */

         // catch false minimum
         if (value < 0) {
            //	 cout << "ProfileLikelihoodTestStat: problem that profileLL = " << value
            //	      << " < 0, indicates false min.  Try again."<<endl;
            delete fNll;
            delete fProfile;
            /*
             RooNLLVar* nll = new RooNLLVar("nll","",*fPdf,data, RooFit::Extended());
             fNll = nll;
             fProfile = new RooProfileLL("pll","",*nll, paramsOfInterest);
             */

            RooArgSet* constrainedParams = fPdf->getParameters(data);
            RemoveConstantParameters(constrainedParams);

            RooNLLVar * nll2 = (RooNLLVar*) fPdf->createNLL(data, RooFit::CloneData(kFALSE), RooFit::Constrain(
               *constrainedParams));
            fNll = nll2;
            fProfile = (RooProfileLL*) nll2->createProfile(paramsOfInterest);
            delete constrainedParams;

            // set parameters to point being requested
            SetParameters(&paramsOfInterest, fProfile->getParameters(data));

            value = fProfile->getVal();
            //cout << "now profileLL = " << value << endl;
         }
         //       cout << "now profileLL = " << value << endl;
         RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG);
         return value;
      }

    
      virtual const TString GetVarName() const {return "Profile Likelihood Ratio";}
      
      //      const bool PValueIsRightTail(void) { return false; } // overwrites default


   private:
      RooProfileLL* fProfile;
      RooAbsPdf* fPdf;
      RooNLLVar* fNll;
      const RooArgSet* fCachedBestFitParams;
      RooAbsData* fLastData;
      //      Double_t fLastMLE;

   protected:
      ClassDef(ProfileLikelihoodTestStat,1)   // implements the profile likelihood ratio as a test statistic to be used with several tools
   };
}


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