ROOT logo
// @(#)root/roostats:$Id: ProfileLikelihoodCalculator.cxx 29107 2009-06-19 14:26:42Z moneta $
// Author: Kyle Cranmer   28/07/2008

/*************************************************************************
 * 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>
ProfileLikelihoodCalculator is a concrete implementation of CombinedCalculator 
(the interface class for a tools which can produce both RooStats HypoTestResults and ConfIntervals).  
The tool uses the profile likelihood ratio as a test statistic, and assumes that Wilks' theorem is valid.  
Wilks' theorem states that -2* log (profile likelihood ratio) is asymptotically distributed as a chi^2 distribution 
with N-dof, where N is the number of degrees of freedom.  Thus, p-values can be constructed and the profile likelihood ratio
can be used to construct a LikelihoodInterval.
(In the future, this class could be extended to use toy Monte Carlo to calibrate the distribution of the test statistic).
</p>
<p> Usage: It uses the interface of the CombinedCalculator, so that it can be configured by specifying:
<ul>
 <li>a model common model (eg. a family of specific models which includes both the null and alternate),</li>
 <li>a data set, </li>
 <li>a set of parameters of which specify the null (including values and const/non-const status), </li>
 <li>a set of parameters of which specify the alternate (including values and const/non-const status),</li>
 <li>a set of parameters of nuisance parameters  (including values and const/non-const status).</li>
</ul>
The interface allows one to pass the model, data, and parameters via a workspace and then specify them with names.
The interface will be extended so that one does not need to use a workspace.
</p>
<p>
After configuring the calculator, one only needs to ask GetHypoTest() (which will return a HypoTestResult pointer) or GetInterval() (which will return an ConfInterval pointer).
</p>
<p>
The concrete implementations of this interface should deal with the details of how the nuisance parameters are
dealt with (eg. integration vs. profiling) and which test-statistic is used (perhaps this should be added to the interface).
</p>
<p>
The motivation for this interface is that we hope to be able to specify the problem in a common way for several concrete calculators.
</p>
END_HTML
*/
//

#ifndef RooStats_ProfileLikelihoodCalculator
#include "RooStats/ProfileLikelihoodCalculator.h"
#endif

#ifndef RooStats_RooStatsUtils
#include "RooStats/RooStatsUtils.h"
#endif

#include "RooStats/LikelihoodInterval.h"
#include "RooStats/HypoTestResult.h"

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

ClassImp(RooStats::ProfileLikelihoodCalculator) ;

using namespace RooFit;
using namespace RooStats;


//_______________________________________________________
ProfileLikelihoodCalculator::ProfileLikelihoodCalculator() : 
   CombinedCalculator() {
   // default constructor

}

ProfileLikelihoodCalculator::ProfileLikelihoodCalculator(RooWorkspace& ws, RooAbsData& data, RooAbsPdf& pdf, RooArgSet& paramsOfInterest, 
                                                         Double_t size, RooArgSet* nullParams, RooArgSet* altParams) :
   CombinedCalculator(ws,data,pdf, paramsOfInterest, size, nullParams, altParams)
{}

ProfileLikelihoodCalculator::ProfileLikelihoodCalculator(RooAbsData& data, RooAbsPdf& pdf, RooArgSet& paramsOfInterest, 
                                                         Double_t size, RooArgSet* nullParams, RooArgSet* altParams):
   CombinedCalculator(data,pdf, paramsOfInterest, size, nullParams, altParams)
{}


//_______________________________________________________
ProfileLikelihoodCalculator::~ProfileLikelihoodCalculator(){
   // destructor
}


//_______________________________________________________
ConfInterval* ProfileLikelihoodCalculator::GetInterval() const {
   // Main interface to get a RooStats::ConfInterval.  
   // It constructs a profile likelihood ratio and uses that to construct a RooStats::LikelihoodInterval.

   RooAbsPdf* pdf   = fWS->pdf(fPdfName);
   RooAbsData* data = fWS->data(fDataName);
   if (!data || !pdf || !fPOI) return 0;

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


   /*
   RooNLLVar* nll = new RooNLLVar("nll","",*pdf,*data, Extended(),Constrain(*constrainedParams));
   RooProfileLL* profile = new RooProfileLL("pll","",*nll, *fPOI);
   profile->addOwnedComponents(*nll) ;  // to avoid memory leak
   */

   RooAbsReal* nll = pdf->createNLL(*data, CloneData(kTRUE), Constrain(*constrainedParams));
   RooAbsReal* profile = nll->createProfile(*fPOI);
   profile->addOwnedComponents(*nll) ;  // to avoid memory leak


   RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL) ;
   profile->getVal(); // do this so profile will cache the minimum
   RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;

   LikelihoodInterval* interval 
      = new LikelihoodInterval("LikelihoodInterval", profile, fPOI);
   interval->SetConfidenceLevel(1.-fSize);
   delete constrainedParams;
   return interval;
}

//_______________________________________________________
HypoTestResult* ProfileLikelihoodCalculator::GetHypoTest() const {
   // Main interface to get a HypoTestResult.
   // It does two fits:
   // the first lets the null parameters float, so it's a maximum likelihood estimate
   // the second is to the null (fixing null parameters to their specified values): eg. a conditional maximum likelihood
   // the ratio of the likelihood at the conditional MLE to the MLE is the profile likelihood ratio.
   // Wilks' theorem is used to get p-values 

   RooAbsPdf* pdf   = fWS->pdf(fPdfName);
   RooAbsData* data = fWS->data(fDataName);
   if (!data || !pdf) return 0;

   // calculate MLE
   RooArgSet* constrainedParams = pdf->getParameters(*data);
   RemoveConstantParameters(constrainedParams);
   RooFitResult* fit = pdf->fitTo(*data,Extended(kFALSE), Constrain(*constrainedParams),Strategy(0),Hesse(kFALSE),Save(kTRUE),PrintLevel(-1));
  

   fit->Print();
   Double_t NLLatMLE= fit->minNll();


   // set POI to null values, set constant, calculate conditional MLE
   TIter it = fNullParams->createIterator();
   RooRealVar *myarg; 
   RooRealVar *mytarget; 
   while ((myarg = (RooRealVar *)it.Next())) { 
      if(!myarg) continue;

      mytarget = fWS->var(myarg->GetName());
      if(!mytarget) continue;
      mytarget->setVal( myarg->getVal() );
      mytarget->setConstant(kTRUE);
      cout << "setting null parameter:" << endl;
      mytarget->Print();
   }
  
   RooFitResult* fit2 = pdf->fitTo(*data,Extended(kFALSE),Constrain(*constrainedParams),Hesse(kFALSE),Strategy(0), Minos(kFALSE), Save(kTRUE),PrintLevel(-1));

   Double_t NLLatCondMLE= fit2->minNll();
   fit2->Print();

   // Use Wilks' theorem to translate -2 log lambda into a signifcance/p-value
   HypoTestResult* htr = 
      new HypoTestResult("ProfileLRHypoTestResult",
                         SignificanceToPValue(sqrt( 2*(NLLatCondMLE-NLLatMLE))), 0 );
   delete constrainedParams;
   return htr;

}

 ProfileLikelihoodCalculator.cxx:1
 ProfileLikelihoodCalculator.cxx:2
 ProfileLikelihoodCalculator.cxx:3
 ProfileLikelihoodCalculator.cxx:4
 ProfileLikelihoodCalculator.cxx:5
 ProfileLikelihoodCalculator.cxx:6
 ProfileLikelihoodCalculator.cxx:7
 ProfileLikelihoodCalculator.cxx:8
 ProfileLikelihoodCalculator.cxx:9
 ProfileLikelihoodCalculator.cxx:10
 ProfileLikelihoodCalculator.cxx:11
 ProfileLikelihoodCalculator.cxx:12
 ProfileLikelihoodCalculator.cxx:13
 ProfileLikelihoodCalculator.cxx:14
 ProfileLikelihoodCalculator.cxx:15
 ProfileLikelihoodCalculator.cxx:16
 ProfileLikelihoodCalculator.cxx:17
 ProfileLikelihoodCalculator.cxx:18
 ProfileLikelihoodCalculator.cxx:19
 ProfileLikelihoodCalculator.cxx:20
 ProfileLikelihoodCalculator.cxx:21
 ProfileLikelihoodCalculator.cxx:22
 ProfileLikelihoodCalculator.cxx:23
 ProfileLikelihoodCalculator.cxx:24
 ProfileLikelihoodCalculator.cxx:25
 ProfileLikelihoodCalculator.cxx:26
 ProfileLikelihoodCalculator.cxx:27
 ProfileLikelihoodCalculator.cxx:28
 ProfileLikelihoodCalculator.cxx:29
 ProfileLikelihoodCalculator.cxx:30
 ProfileLikelihoodCalculator.cxx:31
 ProfileLikelihoodCalculator.cxx:32
 ProfileLikelihoodCalculator.cxx:33
 ProfileLikelihoodCalculator.cxx:34
 ProfileLikelihoodCalculator.cxx:35
 ProfileLikelihoodCalculator.cxx:36
 ProfileLikelihoodCalculator.cxx:37
 ProfileLikelihoodCalculator.cxx:38
 ProfileLikelihoodCalculator.cxx:39
 ProfileLikelihoodCalculator.cxx:40
 ProfileLikelihoodCalculator.cxx:41
 ProfileLikelihoodCalculator.cxx:42
 ProfileLikelihoodCalculator.cxx:43
 ProfileLikelihoodCalculator.cxx:44
 ProfileLikelihoodCalculator.cxx:45
 ProfileLikelihoodCalculator.cxx:46
 ProfileLikelihoodCalculator.cxx:47
 ProfileLikelihoodCalculator.cxx:48
 ProfileLikelihoodCalculator.cxx:49
 ProfileLikelihoodCalculator.cxx:50
 ProfileLikelihoodCalculator.cxx:51
 ProfileLikelihoodCalculator.cxx:52
 ProfileLikelihoodCalculator.cxx:53
 ProfileLikelihoodCalculator.cxx:54
 ProfileLikelihoodCalculator.cxx:55
 ProfileLikelihoodCalculator.cxx:56
 ProfileLikelihoodCalculator.cxx:57
 ProfileLikelihoodCalculator.cxx:58
 ProfileLikelihoodCalculator.cxx:59
 ProfileLikelihoodCalculator.cxx:60
 ProfileLikelihoodCalculator.cxx:61
 ProfileLikelihoodCalculator.cxx:62
 ProfileLikelihoodCalculator.cxx:63
 ProfileLikelihoodCalculator.cxx:64
 ProfileLikelihoodCalculator.cxx:65
 ProfileLikelihoodCalculator.cxx:66
 ProfileLikelihoodCalculator.cxx:67
 ProfileLikelihoodCalculator.cxx:68
 ProfileLikelihoodCalculator.cxx:69
 ProfileLikelihoodCalculator.cxx:70
 ProfileLikelihoodCalculator.cxx:71
 ProfileLikelihoodCalculator.cxx:72
 ProfileLikelihoodCalculator.cxx:73
 ProfileLikelihoodCalculator.cxx:74
 ProfileLikelihoodCalculator.cxx:75
 ProfileLikelihoodCalculator.cxx:76
 ProfileLikelihoodCalculator.cxx:77
 ProfileLikelihoodCalculator.cxx:78
 ProfileLikelihoodCalculator.cxx:79
 ProfileLikelihoodCalculator.cxx:80
 ProfileLikelihoodCalculator.cxx:81
 ProfileLikelihoodCalculator.cxx:82
 ProfileLikelihoodCalculator.cxx:83
 ProfileLikelihoodCalculator.cxx:84
 ProfileLikelihoodCalculator.cxx:85
 ProfileLikelihoodCalculator.cxx:86
 ProfileLikelihoodCalculator.cxx:87
 ProfileLikelihoodCalculator.cxx:88
 ProfileLikelihoodCalculator.cxx:89
 ProfileLikelihoodCalculator.cxx:90
 ProfileLikelihoodCalculator.cxx:91
 ProfileLikelihoodCalculator.cxx:92
 ProfileLikelihoodCalculator.cxx:93
 ProfileLikelihoodCalculator.cxx:94
 ProfileLikelihoodCalculator.cxx:95
 ProfileLikelihoodCalculator.cxx:96
 ProfileLikelihoodCalculator.cxx:97
 ProfileLikelihoodCalculator.cxx:98
 ProfileLikelihoodCalculator.cxx:99
 ProfileLikelihoodCalculator.cxx:100
 ProfileLikelihoodCalculator.cxx:101
 ProfileLikelihoodCalculator.cxx:102
 ProfileLikelihoodCalculator.cxx:103
 ProfileLikelihoodCalculator.cxx:104
 ProfileLikelihoodCalculator.cxx:105
 ProfileLikelihoodCalculator.cxx:106
 ProfileLikelihoodCalculator.cxx:107
 ProfileLikelihoodCalculator.cxx:108
 ProfileLikelihoodCalculator.cxx:109
 ProfileLikelihoodCalculator.cxx:110
 ProfileLikelihoodCalculator.cxx:111
 ProfileLikelihoodCalculator.cxx:112
 ProfileLikelihoodCalculator.cxx:113
 ProfileLikelihoodCalculator.cxx:114
 ProfileLikelihoodCalculator.cxx:115
 ProfileLikelihoodCalculator.cxx:116
 ProfileLikelihoodCalculator.cxx:117
 ProfileLikelihoodCalculator.cxx:118
 ProfileLikelihoodCalculator.cxx:119
 ProfileLikelihoodCalculator.cxx:120
 ProfileLikelihoodCalculator.cxx:121
 ProfileLikelihoodCalculator.cxx:122
 ProfileLikelihoodCalculator.cxx:123
 ProfileLikelihoodCalculator.cxx:124
 ProfileLikelihoodCalculator.cxx:125
 ProfileLikelihoodCalculator.cxx:126
 ProfileLikelihoodCalculator.cxx:127
 ProfileLikelihoodCalculator.cxx:128
 ProfileLikelihoodCalculator.cxx:129
 ProfileLikelihoodCalculator.cxx:130
 ProfileLikelihoodCalculator.cxx:131
 ProfileLikelihoodCalculator.cxx:132
 ProfileLikelihoodCalculator.cxx:133
 ProfileLikelihoodCalculator.cxx:134
 ProfileLikelihoodCalculator.cxx:135
 ProfileLikelihoodCalculator.cxx:136
 ProfileLikelihoodCalculator.cxx:137
 ProfileLikelihoodCalculator.cxx:138
 ProfileLikelihoodCalculator.cxx:139
 ProfileLikelihoodCalculator.cxx:140
 ProfileLikelihoodCalculator.cxx:141
 ProfileLikelihoodCalculator.cxx:142
 ProfileLikelihoodCalculator.cxx:143
 ProfileLikelihoodCalculator.cxx:144
 ProfileLikelihoodCalculator.cxx:145
 ProfileLikelihoodCalculator.cxx:146
 ProfileLikelihoodCalculator.cxx:147
 ProfileLikelihoodCalculator.cxx:148
 ProfileLikelihoodCalculator.cxx:149
 ProfileLikelihoodCalculator.cxx:150
 ProfileLikelihoodCalculator.cxx:151
 ProfileLikelihoodCalculator.cxx:152
 ProfileLikelihoodCalculator.cxx:153
 ProfileLikelihoodCalculator.cxx:154
 ProfileLikelihoodCalculator.cxx:155
 ProfileLikelihoodCalculator.cxx:156
 ProfileLikelihoodCalculator.cxx:157
 ProfileLikelihoodCalculator.cxx:158
 ProfileLikelihoodCalculator.cxx:159
 ProfileLikelihoodCalculator.cxx:160
 ProfileLikelihoodCalculator.cxx:161
 ProfileLikelihoodCalculator.cxx:162
 ProfileLikelihoodCalculator.cxx:163
 ProfileLikelihoodCalculator.cxx:164
 ProfileLikelihoodCalculator.cxx:165
 ProfileLikelihoodCalculator.cxx:166
 ProfileLikelihoodCalculator.cxx:167
 ProfileLikelihoodCalculator.cxx:168
 ProfileLikelihoodCalculator.cxx:169
 ProfileLikelihoodCalculator.cxx:170
 ProfileLikelihoodCalculator.cxx:171
 ProfileLikelihoodCalculator.cxx:172
 ProfileLikelihoodCalculator.cxx:173
 ProfileLikelihoodCalculator.cxx:174
 ProfileLikelihoodCalculator.cxx:175
 ProfileLikelihoodCalculator.cxx:176
 ProfileLikelihoodCalculator.cxx:177
 ProfileLikelihoodCalculator.cxx:178
 ProfileLikelihoodCalculator.cxx:179
 ProfileLikelihoodCalculator.cxx:180
 ProfileLikelihoodCalculator.cxx:181
 ProfileLikelihoodCalculator.cxx:182