// @(#)root/roostats:$Id$
// Authors: Kyle Cranmer, Sven Kreiss    June 2010
/*************************************************************************
 * 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_RatioOfProfiledLikelihoodsTestStat
#define ROOSTATS_RatioOfProfiledLikelihoodsTestStat

//_________________________________________________
/*
BEGIN_HTML
<p>
TestStatistic that returns the ratio of profiled likelihoods.
</p>
END_HTML
*/
//

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

#ifndef ROO_NLL_VAR
#include "RooNLLVar.h"
#endif

#ifndef ROOSTATS_TestStatistic
#include "RooStats/TestStatistic.h"
#endif

#ifndef ROOSTATS_ProfileLikelihoodTestStat
#include "RooStats/ProfileLikelihoodTestStat.h"
#endif

namespace RooStats {

class RatioOfProfiledLikelihoodsTestStat: public TestStatistic {

  public:

   RatioOfProfiledLikelihoodsTestStat() :
      fNullProfile(),
      fAltProfile(),
      fAltPOI(NULL),
      fSubtractMLE(true),
      fDetailedOutputEnabled(false),
      fDetailedOutput(NULL)
   {
      // Proof constructor. Don't use.
   }

  RatioOfProfiledLikelihoodsTestStat(RooAbsPdf& nullPdf, RooAbsPdf& altPdf, 
				     const RooArgSet* altPOI=0) :
    fNullProfile(nullPdf), 
    fAltProfile(altPdf), 
    fSubtractMLE(true),
    fDetailedOutputEnabled(false),
    fDetailedOutput(NULL)
      {
	/*
         Calculates the ratio of profiled likelihoods. 

	 By default the calculation is:

	    Lambda(mu_alt , conditional MLE for alt nuisance) 
	log --------------------------------------------
   	    Lambda(mu_null , conditional MLE for null nuisance)

	where Lambda is the profile likeihood ratio, so the 
	MLE for the null and alternate are subtracted off.

	If SetSubtractMLE(false) then it calculates:

	    L(mu_alt , conditional MLE for alt nuisance) 
	log --------------------------------------------
	    L(mu_null , conditional MLE for null nuisance)


	The values of the parameters of interest for the alternative 
	hypothesis are taken at the time of the construction.
	If empty, it treats all free parameters as nuisance parameters.

	The value of the parameters of interest for the null hypotheses 
	are given at each call of Evaluate(data,nullPOI).
	*/
	if(altPOI)
	  fAltPOI = (RooArgSet*) altPOI->snapshot();
	else
	  fAltPOI = new RooArgSet(); // empty set

      }

    //__________________________________________
    ~RatioOfProfiledLikelihoodsTestStat(void) {
      if(fAltPOI) delete fAltPOI;
      if(fDetailedOutput) delete fDetailedOutput;
    }
   
   
   // returns -logL(poi, conditional MLE of nuisance params)
   // it does not subtract off the global MLE
   // because  nuisance parameters of null and alternate may not
   // be the same.
   Double_t ProfiledLikelihood(RooAbsData& data, RooArgSet& poi, RooAbsPdf& pdf);
    
    // evaluate the ratio of profile likelihood
   virtual Double_t Evaluate(RooAbsData& data, RooArgSet& nullParamsOfInterest);
    
   virtual void EnableDetailedOutput( bool e=true ) { 
      fDetailedOutputEnabled = e; 
      fNullProfile.EnableDetailedOutput(fDetailedOutputEnabled);
      fAltProfile.EnableDetailedOutput(fDetailedOutputEnabled);
   }

   static void SetAlwaysReuseNLL(Bool_t flag); 

   void SetReuseNLL(Bool_t flag) { 
      fNullProfile.SetReuseNLL(flag);  
      fAltProfile.SetReuseNLL(flag);  
   }

   void SetMinimizer(const char* minimizer){ 
      fNullProfile.SetMinimizer(minimizer);  
      fAltProfile.SetMinimizer(minimizer);  
   }
   void SetStrategy(Int_t strategy){
      fNullProfile.SetStrategy(strategy);  
      fAltProfile.SetStrategy(strategy);  
   }
   void SetTolerance(Double_t tol){
      fNullProfile.SetTolerance(tol);  
      fAltProfile.SetTolerance(tol);  
   }
   void SetPrintLevel(Int_t printLevel){
      fNullProfile.SetPrintLevel(printLevel);  
      fAltProfile.SetPrintLevel(printLevel);  
   }
  
     // 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 
     virtual void SetConditionalObservables(const RooArgSet& set) { 
        fNullProfile.SetConditionalObservables(set);  
        fAltProfile.SetConditionalObservables(set);  
    }

     virtual const RooArgSet* GetDetailedOutput(void) const {
	     // Returns detailed output. The value returned by this function is updated after each call to Evaluate().
	     // The returned RooArgSet contains the following for the alternative and null hypotheses:
	     // <ul>
	     // <li> the minimum nll, fitstatus and convergence quality for each fit </li> 
	     // <li> for each fit and for each non-constant parameter, the value, error and pull of the parameter are stored </li>
	     // </ul>
	     return fDetailedOutput;
     }


    

   virtual const TString GetVarName() const { return "log(L(#mu_{1},#hat{#nu}_{1}) / L(#mu_{0},#hat{#nu}_{0}))"; }
    
    //    const bool PValueIsRightTail(void) { return false; } // overwrites default
    
    void SetSubtractMLE(bool subtract){fSubtractMLE = subtract;}
    
  private:

    ProfileLikelihoodTestStat fNullProfile;
    ProfileLikelihoodTestStat fAltProfile;

    RooArgSet* fAltPOI;
    Bool_t fSubtractMLE;
   static Bool_t fgAlwaysReuseNll ;

    bool fDetailedOutputEnabled;
    RooArgSet* fDetailedOutput;

    
  protected:
    ClassDef(RatioOfProfiledLikelihoodsTestStat,3)  // implements the ratio of profiled likelihood as test statistic
};

}


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