RooProfileLL.cxx

Go to the documentation of this file.
00001  /***************************************************************************** 
00002   * Project: RooFit                                                           * 
00003   *                                                                           * 
00004   * Copyright (c) 2000-2005, Regents of the University of California          * 
00005   *                          and Stanford University. All rights reserved.    * 
00006   *                                                                           * 
00007   * Redistribution and use in source and binary forms,                        * 
00008   * with or without modification, are permitted according to the terms        * 
00009   * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             * 
00010   *****************************************************************************/ 
00011 
00012 //////////////////////////////////////////////////////////////////////////////
00013 //
00014 // BEGIN_HTML
00015 // Class RooProfileLL implements the profile likelihood estimator for
00016 // a given likelihood and set of parameters of interest. The value return by 
00017 // RooProfileLL is the input likelihood nll minimized w.r.t all nuisance parameters
00018 // (which are all parameters except for those listed in the constructor) minus
00019 // the -log(L) of the best fit. Note that this function is slow to evaluate
00020 // as a MIGRAD minimization step is executed for each function evaluation
00021 // END_HTML
00022 //
00023 
00024 #include "Riostream.h" 
00025 
00026 #include "RooFit.h"
00027 #include "RooProfileLL.h" 
00028 #include "RooAbsReal.h" 
00029 #include "RooMinuit.h"
00030 #include "RooMsgService.h"
00031 #include "RooRealVar.h"
00032 #include "RooMsgService.h"
00033 
00034 using namespace std ;
00035 
00036 ClassImp(RooProfileLL) 
00037 
00038 
00039 //_____________________________________________________________________________ 
00040  RooProfileLL::RooProfileLL() : 
00041    RooAbsReal("RooProfileLL","RooProfileLL"), 
00042    _nll(), 
00043    _obs("paramOfInterest","Parameters of interest",this), 
00044    _par("nuisanceParam","Nuisance parameters",this,kFALSE,kFALSE), 
00045    _startFromMin(kTRUE), 
00046    _minuit(0), 
00047    _absMinValid(kFALSE), 
00048    _absMin(0) 
00049 { 
00050   // Default constructor 
00051   // Should only be used by proof. 
00052   _piter = _par.createIterator() ; 
00053   _oiter = _obs.createIterator() ; 
00054 } 
00055 
00056 
00057 //_____________________________________________________________________________
00058 RooProfileLL::RooProfileLL(const char *name, const char *title, 
00059                            RooAbsReal& nllIn, const RooArgSet& observables) :
00060   RooAbsReal(name,title), 
00061   _nll("input","-log(L) function",this,nllIn),
00062   _obs("paramOfInterest","Parameters of interest",this),
00063   _par("nuisanceParam","Nuisance parameters",this,kFALSE,kFALSE),
00064   _startFromMin(kTRUE),
00065   _minuit(0),
00066   _absMinValid(kFALSE),
00067   _absMin(0)
00068 { 
00069   // Constructor of profile likelihood given input likelihood nll w.r.t
00070   // the given set of variables. The input log likelihood is minimized w.r.t
00071   // to all other variables of the likelihood at each evaluation and the
00072   // value of the global log likelihood minimum is always subtracted.
00073 
00074   // Determine actual parameters and observables
00075   RooArgSet* actualObs = nllIn.getObservables(observables) ;
00076   RooArgSet* actualPars = nllIn.getParameters(observables) ;
00077 
00078   _obs.add(*actualObs) ;
00079   _par.add(*actualPars) ;
00080 
00081   delete actualObs ;
00082   delete actualPars ;
00083 
00084   _piter = _par.createIterator() ;
00085   _oiter = _obs.createIterator() ;
00086 } 
00087 
00088 
00089 
00090 //_____________________________________________________________________________
00091 RooProfileLL::RooProfileLL(const RooProfileLL& other, const char* name) :  
00092   RooAbsReal(other,name), 
00093   _nll("nll",this,other._nll),
00094   _obs("obs",this,other._obs),
00095   _par("par",this,other._par),
00096   _startFromMin(other._startFromMin),
00097   _minuit(0),
00098   _absMinValid(kFALSE),
00099   _absMin(0),
00100   _paramFixed(other._paramFixed)
00101 { 
00102   // Copy constructor
00103 
00104   _piter = _par.createIterator() ;
00105   _oiter = _obs.createIterator() ;
00106 
00107   _paramAbsMin.addClone(other._paramAbsMin) ;
00108   _obsAbsMin.addClone(other._obsAbsMin) ;
00109     
00110 } 
00111 
00112 
00113 
00114 //_____________________________________________________________________________
00115 RooProfileLL::~RooProfileLL()
00116 {
00117   // Destructor
00118 
00119   // Delete instance of minuit if it was ever instantiated
00120   if (_minuit) {
00121     delete _minuit ;
00122   }
00123 
00124   delete _piter ;
00125   delete _oiter ;
00126 }
00127 
00128 
00129 
00130 
00131 //_____________________________________________________________________________
00132 const RooArgSet& RooProfileLL::bestFitParams() const 
00133 {
00134   validateAbsMin() ;
00135   return _paramAbsMin ;
00136 }
00137 
00138 
00139 //_____________________________________________________________________________
00140 const RooArgSet& RooProfileLL::bestFitObs() const 
00141 {
00142   validateAbsMin() ;
00143   return _obsAbsMin ;
00144 }
00145 
00146 
00147 
00148 
00149 //_____________________________________________________________________________
00150 RooAbsReal* RooProfileLL::createProfile(const RooArgSet& paramsOfInterest) 
00151 {
00152   // Optimized implementation of createProfile for profile likelihoods.
00153   // Return profile of original function in terms of stated parameters 
00154   // of interest rather than profiling recursively.
00155 
00156   return nll().createProfile(paramsOfInterest) ;
00157 }
00158 
00159 
00160 
00161 
00162 //_____________________________________________________________________________
00163 Double_t RooProfileLL::evaluate() const 
00164 { 
00165   // Evaluate profile likelihood by minimizing likelihood w.r.t. all
00166   // parameters that are not considered observables of this profile
00167   // likelihood object.
00168 
00169   // Instantiate minuit if we haven't done that already
00170   if (!_minuit) {
00171     coutI(Minimization) << "RooProfileLL::evaluate(" << GetName() << ") Creating instance of MINUIT" << endl ;
00172     
00173     Bool_t smode = RooMsgService::instance().silentMode() ;
00174     RooMsgService::instance().setSilentMode(kTRUE) ;
00175     _minuit = new RooMinuit(const_cast<RooAbsReal&>(_nll.arg())) ;
00176     if (!smode) RooMsgService::instance().setSilentMode(kFALSE) ;
00177 
00178     _minuit->setPrintLevel(-999) ;
00179     //_minuit->setNoWarn() ;
00180     //_minuit->setVerbose(1) ;
00181   }
00182 
00183   // Save current value of observables
00184   RooArgSet* obsSetOrig = (RooArgSet*) _obs.snapshot() ;
00185 
00186   validateAbsMin() ;
00187 
00188   
00189   // Set all observables constant in the minimization
00190   const_cast<RooSetProxy&>(_obs).setAttribAll("Constant",kTRUE) ;  
00191   ccoutP(Eval) << "." ; ccoutP(Eval).flush() ;
00192 
00193   // If requested set initial parameters to those corresponding to absolute minimum
00194   if (_startFromMin) {
00195     const_cast<RooProfileLL&>(*this)._par = _paramAbsMin ;
00196   }
00197 
00198   _minuit->migrad() ;
00199   
00200   // Restore original values and constant status of observables
00201   TIterator* iter = obsSetOrig->createIterator() ;
00202   RooRealVar* var ;
00203   while((var=(RooRealVar*)iter->Next())) {
00204     RooRealVar* target = (RooRealVar*) _obs.find(var->GetName()) ;
00205     target->setVal(var->getVal()) ;
00206     target->setConstant(var->isConstant()) ;
00207   }
00208   delete iter ;
00209   delete obsSetOrig ;
00210 
00211   return _nll - _absMin ; 
00212 } 
00213 
00214 
00215 
00216 //_____________________________________________________________________________
00217 void RooProfileLL::validateAbsMin() const 
00218 {
00219   // Check that parameters and likelihood value for 'best fit' are still valid. If not,
00220   // because the best fit has never been calculated, or because constant parameters have
00221   // changed value or parameters have changed const/float status, the minimum is recalculated
00222 
00223   // Check if constant status of any of the parameters have changed
00224   if (_absMinValid) {
00225     _piter->Reset() ;
00226     RooAbsArg* par ;
00227     while((par=(RooAbsArg*)_piter->Next())) {
00228       if (_paramFixed[par->GetName()] != par->isConstant()) {
00229         cxcoutI(Minimization) << "RooProfileLL::evaluate(" << GetName() << ") constant status of parameter " << par->GetName() << " has changed from " 
00230                                 << (_paramFixed[par->GetName()]?"fixed":"floating") << " to " << (par->isConstant()?"fixed":"floating") 
00231                                 << ", recalculating absolute minimum" << endl ;
00232         _absMinValid = kFALSE ;
00233         break ;
00234       }
00235     }
00236   }
00237 
00238 
00239   // If we don't have the absolute minimum w.r.t all observables, calculate that first
00240   if (!_absMinValid) {
00241     
00242     cxcoutI(Minimization) << "RooProfileLL::evaluate(" << GetName() << ") determining minimum likelihood for current configurations w.r.t all observable" << endl ;
00243 
00244 
00245     // Save current values of non-marginalized parameters
00246     RooArgSet* obsStart = (RooArgSet*) _obs.snapshot(kFALSE) ;
00247 
00248     // Start from previous global minimum 
00249     if (_paramAbsMin.getSize()>0) {
00250       const_cast<RooSetProxy&>(_par).assignValueOnly(_paramAbsMin) ;
00251     }
00252     if (_obsAbsMin.getSize()>0) {
00253       const_cast<RooSetProxy&>(_obs).assignValueOnly(_obsAbsMin) ;
00254     }
00255 
00256     // Find minimum with all observables floating
00257     const_cast<RooSetProxy&>(_obs).setAttribAll("Constant",kFALSE) ;  
00258     _minuit->migrad() ;
00259 
00260     // Save value and remember
00261     _absMin = _nll ;
00262     _absMinValid = kTRUE ;
00263 
00264     // Save parameter values at abs minimum as well
00265     _paramAbsMin.removeAll() ;
00266     _paramAbsMin.addClone(_par) ;
00267     _obsAbsMin.addClone(_obs) ;
00268 
00269     // Save constant status of all parameters
00270     _piter->Reset() ;
00271     RooAbsArg* par ;
00272     while((par=(RooAbsArg*)_piter->Next())) {
00273       _paramFixed[par->GetName()] = par->isConstant() ;
00274     }
00275     
00276     if (dologI(Minimization)) {
00277       cxcoutI(Minimization) << "RooProfileLL::evaluate(" << GetName() << ") minimum found at (" ;
00278 
00279       RooAbsReal* arg ;
00280       Bool_t first=kTRUE ;
00281       _oiter->Reset() ;
00282       while ((arg=(RooAbsReal*)_oiter->Next())) {
00283         ccxcoutI(Minimization) << (first?"":", ") << arg->GetName() << "=" << arg->getVal() ;   
00284         first=kFALSE ;
00285       }      
00286       ccxcoutI(Minimization) << ")" << endl ;            
00287     }
00288 
00289     // Restore original parameter values
00290     const_cast<RooSetProxy&>(_obs) = *obsStart ;
00291     delete obsStart ;
00292 
00293   }
00294 }
00295 
00296 
00297 
00298 //_____________________________________________________________________________
00299 Bool_t RooProfileLL::redirectServersHook(const RooAbsCollection& /*newServerList*/, Bool_t /*mustReplaceAll*/, 
00300                                          Bool_t /*nameChange*/, Bool_t /*isRecursive*/) 
00301 { 
00302   if (_minuit) {
00303     delete _minuit ;
00304     _minuit = 0 ;
00305   }
00306   return kFALSE ;
00307 } 
00308 
00309 

Generated on Tue Jul 5 15:07:07 2011 for ROOT_528-00b_version by  doxygen 1.5.1