ProfileLikelihoodTestStat.h

Go to the documentation of this file.
00001 // @(#)root/roostats:$Id: ProfileLikelihoodTestStat.h 38078 2011-02-15 18:28:29Z cranmer $
00002 // Author: Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke
00003 /*************************************************************************
00004  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
00005  * All rights reserved.                                                  *
00006  *                                                                       *
00007  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00008  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00009  *************************************************************************/
00010 
00011 #ifndef ROOSTATS_ProfileLikelihoodTestStat
00012 #define ROOSTATS_ProfileLikelihoodTestStat
00013 
00014 //_________________________________________________
00015 /*
00016 BEGIN_HTML
00017 <p>
00018 ProfileLikelihoodTestStat is an implementation of the TestStatistic interface that calculates the profile
00019 likelihood ratio at a particular parameter point given a dataset.  It does not constitute a statistical test, for that one may either use:
00020 <ul>
00021  <li> the ProfileLikelihoodCalculator that relies on asymptotic properties of the Profile Likelihood Ratio</li>
00022  <li> the Neyman Construction classes with this class as a test statistic</li>
00023  <li> the Hybrid Calculator class with this class as a test statistic</li>
00024 </ul>
00025 
00026 </p>
00027 END_HTML
00028 */
00029 //
00030 
00031 #ifndef ROOT_Rtypes
00032 #include "Rtypes.h"
00033 #endif
00034 
00035 #include <vector>
00036 
00037 #include "RooStats/RooStatsUtils.h"
00038 
00039 //#include "RooStats/DistributionCreator.h"
00040 #include "RooStats/SamplingDistribution.h"
00041 #include "RooStats/TestStatistic.h"
00042 
00043 #include "RooStats/RooStatsUtils.h"
00044 
00045 #include "RooRealVar.h"
00046 #include "RooProfileLL.h"
00047 #include "RooNLLVar.h"
00048 
00049 #include "RooMinuit.h"
00050 
00051 namespace RooStats {
00052 
00053   class ProfileLikelihoodTestStat : public TestStatistic{
00054 
00055    public:
00056      ProfileLikelihoodTestStat() {
00057         // Proof constructor. Do not use.
00058         fPdf = 0;
00059         fProfile = 0;
00060         fNll = 0;
00061         fCachedBestFitParams = 0;
00062         fLastData = 0;
00063         fOneSided = false;
00064      }
00065      ProfileLikelihoodTestStat(RooAbsPdf& pdf) {
00066        fPdf = &pdf;
00067        fProfile = 0;
00068        fNll = 0;
00069        fCachedBestFitParams = 0;
00070        fLastData = 0;
00071        fOneSided = false;
00072      }
00073      virtual ~ProfileLikelihoodTestStat() {
00074        //       delete fRand;
00075        //       delete fTestStatistic;
00076        if(fProfile) delete fProfile;
00077        if(fNll) delete fNll;
00078        if(fCachedBestFitParams) delete fCachedBestFitParams;
00079      }
00080      void SetOneSided(Bool_t flag=true) {fOneSided = flag;}
00081     
00082      // Main interface to evaluate the test statistic on a dataset
00083      virtual Double_t Evaluate(RooAbsData& data, RooArgSet& paramsOfInterest) {
00084        if (!&data) {
00085          cout << "problem with data" << endl;
00086          return 0 ;
00087        }
00088        
00089        RooRealVar* firstPOI = (RooRealVar*) paramsOfInterest.first();
00090        double initial_mu_value  = firstPOI->getVal();
00091        //paramsOfInterest.getRealValue(firstPOI->GetName());
00092 
00093        RooFit::MsgLevel msglevel = RooMsgService::instance().globalKillBelow();
00094        RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL);
00095 
00096 
00097        // simple
00098        RooAbsReal* nll = fPdf->createNLL(data, RooFit::CloneData(kFALSE));
00099        RooAbsReal* profile = nll->createProfile(paramsOfInterest);
00100        // make sure we set the variables attached to this nll
00101        RooArgSet* attachedSet = nll->getVariables();
00102        *attachedSet = paramsOfInterest;
00103        //       fPdf->setEvalErrorLoggingMode(RooAbsReal::CountErrors);
00104        //       profile->setEvalErrorLoggingMode(RooAbsReal::CountErrors);
00105        //       ((RooProfileLL*)profile)->nll().setEvalErrorLoggingMode(RooAbsReal::CountErrors);
00106        //       nll->setEvalErrorLoggingMode(RooAbsReal::CountErrors);
00107        double ret = profile->getVal();
00108        //       cout <<"eval errors pdf = "<<fPdf->numEvalErrors() << endl;
00109        //       cout <<"eval errors profile = "<<profile->numEvalErrors() << endl;
00110        //       cout <<"eval errors profile->nll = "<<((RooProfileLL*)profile)->nll().numEvalErrors() << endl;
00111        //       cout <<"eval errors nll = "<<nll->numEvalErrors() << endl;
00112        //       if(profile->numEvalErrors()>0)
00113        //                cout <<"eval errors = "<<profile->numEvalErrors() << endl;
00114        //       paramsOfInterest.Print("v");
00115        //       cout << "ret = " << ret << endl;
00116 
00117        if(fOneSided){
00118          double fit_favored_mu = ((RooProfileLL*) profile)->bestFitObs().getRealValue(firstPOI->GetName()) ;
00119        
00120          if( fit_favored_mu > initial_mu_value)
00121            // cout <<"fit-favored_mu, initial value" << fit_favored_mu << " " << initial_mu_value<<endl;
00122            ret = 0 ;
00123        }
00124        delete attachedSet;
00125        delete nll;
00126        nll = 0; 
00127        delete profile;
00128        RooMsgService::instance().setGlobalKillBelow(msglevel);
00129        
00130        //////////////////////////////////////////////////////
00131        // return here and forget about the following code
00132        return ret;
00133 
00134 
00135 
00136 
00137 
00138 
00139        //////////////////////////////////////////////////////////
00140        // OLD version with some handling for local minima
00141        // (not used right now)
00142        /////////////////////////////////////////////////////////
00143 
00144          bool needToRebuild = true; // try to avoid rebuilding if possible
00145 
00146          if (fLastData == &data) // simple pointer comparison for now (note NLL makes COPY of data)
00147             needToRebuild = false;
00148          else fLastData = &data; // keep a copy of pointer to original data
00149 
00150          // pointer comparison causing problems.  See multiple datasets with same value of pointer
00151          // but actually a new dataset
00152          needToRebuild = true;
00153 
00154          // check mem leak in NLL or Profile. Should remove.
00155          // if(fProfile) needToRebuild = false;
00156 
00157 
00158          if (needToRebuild) {
00159             if (fProfile) delete fProfile;
00160             if (fNll) delete fNll;
00161 
00162             /*
00163              RooNLLVar* nll = new RooNLLVar("nll","",*fPdf,data, RooFit::Extended());
00164              fNll = nll;
00165              fProfile = new RooProfileLL("pll","",*nll, paramsOfInterest);
00166              */
00167             RooArgSet* constrainedParams = fPdf->getParameters(data);
00168             RemoveConstantParameters(constrainedParams);
00169             //cout << "cons: " << endl;
00170             //constrainedParams->Print("v");
00171 
00172             RooNLLVar * nll2 = (RooNLLVar*) fPdf->createNLL(
00173                data, RooFit::CloneData(kFALSE), RooFit::Constrain(*constrainedParams)
00174             );
00175             fNll = nll2;
00176             fProfile = (RooProfileLL*) nll2->createProfile(paramsOfInterest);
00177             delete constrainedParams;
00178 
00179             //   paramsOfInterest.Print("v");
00180 
00181             // set parameters to previous best fit params, to speed convergence
00182             // and to avoid local minima
00183             if (fCachedBestFitParams) {
00184                // store original values, since minimization will change them.
00185                RooArgSet* origParamVals = (RooArgSet*) paramsOfInterest.snapshot();
00186 
00187                // these parameters are not guaranteed to be the best for this data
00188                SetParameters(fCachedBestFitParams, fProfile->getParameters(data));
00189                // now evaluate to force this profile to evaluate and store
00190                // best fit parameters for this data
00191                fProfile->getVal();
00192 
00193                // possibly store last MLE for reference
00194                //        Double mle = fNll->getVal();
00195 
00196                // restore parameters
00197                SetParameters(origParamVals, &paramsOfInterest);
00198 
00199                // cleanup
00200                delete origParamVals;
00201 
00202             } else {
00203 
00204                // store best fit parameters
00205                // RooProfileLL::bestFitParams returns best fit of nuisance parameters only
00206                //          fCachedBestFitParams = (RooArgSet*) (fProfile->bestFitParams().clone("lastBestFit"));
00207                // ProfileLL::getParameters returns current value of the parameters
00208                //          fCachedBestFitParams = (RooArgSet*) (fProfile->getParameters(data)->clone("lastBestFit"));
00209                //cout << "making fCachedBestFitParams: " << fCachedBestFitParams << fCachedBestFitParams->getSize() << endl;
00210 
00211                // store original values, since minimization will change them.
00212                RooArgSet* origParamVals = (RooArgSet*) paramsOfInterest.snapshot();
00213 
00214                // find minimum
00215                RooMinuit minuit(*nll);
00216                minuit.setPrintLevel(-999);
00217                minuit.setNoWarn();
00218                minuit.migrad();
00219 
00220                // store the best fit values for future use
00221                fCachedBestFitParams = (RooArgSet*) (nll->getParameters(data)->snapshot());
00222 
00223                // restore parameters
00224                SetParameters(origParamVals, &paramsOfInterest);
00225 
00226                // evaluate to force this profile to evaluate and store
00227                // best fit parameters for this data
00228                fProfile->getVal();
00229 
00230                // cleanup
00231                delete origParamVals;
00232 
00233             }
00234 
00235          }
00236          // issue warning if problems
00237          if (!fProfile) {
00238             cout << "problem making profile" << endl;
00239          }
00240 
00241          // set parameters to point being requested
00242          SetParameters(&paramsOfInterest, fProfile->getParameters(data));
00243 
00244          Double_t value = fProfile->getVal();
00245 
00246          /*
00247           // for debugging caching
00248           cout << "current value of input params: " << endl;
00249           paramsOfInterest.Print("verbose");
00250 
00251           cout << "current value of params in profile: " << endl;
00252           fProfile->getParameters(data)->Print("verbose");
00253 
00254           cout << "cached last best fit: " << endl;
00255           fCachedBestFitParams->Print("verbose");
00256           */
00257 
00258          // catch false minimum
00259          if (value < 0) {
00260             //   cout << "ProfileLikelihoodTestStat: problem that profileLL = " << value
00261             //        << " < 0, indicates false min.  Try again."<<endl;
00262             delete fNll;
00263             delete fProfile;
00264             /*
00265              RooNLLVar* nll = new RooNLLVar("nll","",*fPdf,data, RooFit::Extended());
00266              fNll = nll;
00267              fProfile = new RooProfileLL("pll","",*nll, paramsOfInterest);
00268              */
00269 
00270             RooArgSet* constrainedParams = fPdf->getParameters(data);
00271             RemoveConstantParameters(constrainedParams);
00272 
00273             RooNLLVar * nll2 = (RooNLLVar*) fPdf->createNLL(data, RooFit::CloneData(kFALSE), RooFit::Constrain(
00274                *constrainedParams));
00275             fNll = nll2;
00276             fProfile = (RooProfileLL*) nll2->createProfile(paramsOfInterest);
00277             delete constrainedParams;
00278 
00279             // set parameters to point being requested
00280             SetParameters(&paramsOfInterest, fProfile->getParameters(data));
00281 
00282             value = fProfile->getVal();
00283             //cout << "now profileLL = " << value << endl;
00284          }
00285          //       cout << "now profileLL = " << value << endl;
00286          RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG);
00287          return value;
00288       }
00289 
00290     
00291       virtual const TString GetVarName() const {return "Profile Likelihood Ratio";}
00292       
00293       //      const bool PValueIsRightTail(void) { return false; } // overwrites default
00294 
00295 
00296    private:
00297       RooProfileLL* fProfile;
00298       RooAbsPdf* fPdf;
00299       RooNLLVar* fNll;
00300       const RooArgSet* fCachedBestFitParams;
00301       RooAbsData* fLastData;
00302       //      Double_t fLastMLE;
00303       Bool_t fOneSided;
00304 
00305    protected:
00306       ClassDef(ProfileLikelihoodTestStat,2)   // implements the profile likelihood ratio as a test statistic to be used with several tools
00307    };
00308 }
00309 
00310 
00311 #endif

Generated on Tue Jul 5 14:26:26 2011 for ROOT_528-00b_version by  doxygen 1.5.1