RooAbsCachedReal.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 // RooAbsCachedReal is the abstract base class for functions that need or
00016 // want to cache their evaluate() output in a RooHistFunc defined in
00017 // terms of the used observables. This base class manages the creation
00018 // and storage of all RooHistFunc cache p.d.fs and the RooDataHists
00019 // that define their shape. Implementations of RooAbsCachedReal must
00020 // define member function fillCacheObject() which serves to fill an
00021 // already created RooDataHist with the functions function values. In
00022 // addition the member functions actualObservables() and
00023 // actualParameters() must be define which report what the actual
00024 // observables to be cached are for a given set of observables passed
00025 // by the user to getVal() and on which parameters need to be tracked
00026 // for changes to trigger a refilling of the cache histogram.
00027 // END_HTML
00028 //
00029 
00030 #include "Riostream.h" 
00031 using namespace std ;
00032 
00033 #include "RooFit.h"
00034 #include "TString.h"
00035 #include "RooAbsCachedReal.h" 
00036 #include "RooAbsReal.h" 
00037 #include "RooMsgService.h"
00038 #include "RooDataHist.h"
00039 #include "RooHistFunc.h"
00040 #include "RooChangeTracker.h"
00041 #include "RooExpensiveObjectCache.h"
00042 
00043 ClassImp(RooAbsCachedReal) 
00044 
00045 
00046 
00047 //_____________________________________________________________________________
00048 RooAbsCachedReal::RooAbsCachedReal(const char *name, const char *title, Int_t ipOrder) :
00049   RooAbsReal(name,title), 
00050   _cacheMgr(this,10),
00051   _ipOrder(ipOrder),
00052   _disableCache(kFALSE)
00053  { 
00054    // Constructor
00055  } 
00056 
00057 
00058 
00059 //_____________________________________________________________________________
00060 RooAbsCachedReal::RooAbsCachedReal(const RooAbsCachedReal& other, const char* name) :  
00061    RooAbsReal(other,name), 
00062    _cacheMgr(other._cacheMgr,this),
00063    _ipOrder(other._ipOrder),
00064    _disableCache(other._disableCache)
00065  { 
00066    // Copy constructor
00067  } 
00068 
00069 
00070 
00071 //_____________________________________________________________________________
00072 RooAbsCachedReal::~RooAbsCachedReal() 
00073 {
00074   // Destructor
00075 }
00076 
00077 
00078 
00079 //_____________________________________________________________________________
00080 Double_t RooAbsCachedReal::getVal(const RooArgSet* nset) const 
00081 {
00082   // Implementation of getVal() overriding default implementation
00083   // of RooAbsReal. Return value stored in cache p.d.f
00084   // rather than return value of evaluate() which is undefined
00085   // for RooAbsCachedReal
00086 
00087   if (_disableCache) {
00088     return RooAbsReal::getVal(nset) ;
00089   }
00090 
00091   // Cannot call cached p.d.f w.o nset
00092   // if (!nset) return evaluate() ;
00093 
00094   // Calculate current unnormalized value of object
00095   FuncCacheElem* cache = getCache(nset) ;
00096  
00097   _value = cache->func()->getVal() ;
00098 
00099   return _value ;
00100 }
00101 
00102 
00103 
00104 //_____________________________________________________________________________
00105 void RooAbsCachedReal::clearCacheObject(FuncCacheElem& cache) const 
00106 {
00107   // Mark all bins as unitialized (value -1)
00108   cache.hist()->setAllWeights(-1) ;  
00109 }
00110 
00111 
00112 
00113 //_____________________________________________________________________________
00114 RooAbsCachedReal::FuncCacheElem* RooAbsCachedReal::createCache(const RooArgSet* nset) const
00115 {
00116   // Interface function to create an internal cache object that represent
00117   // each cached function configuration. This interface allows to create and
00118   // return a class derived from RooAbsCachedReal::FuncCacheElem so that
00119   // a derived class fillCacheObject implementation can utilize extra functionality
00120   // defined in such a derived cache class
00121 
00122   return new FuncCacheElem(const_cast<RooAbsCachedReal&>(*this),nset) ;
00123 }
00124 
00125 
00126 
00127 //_____________________________________________________________________________
00128 RooAbsCachedReal::FuncCacheElem* RooAbsCachedReal::getCache(const RooArgSet* nset) const
00129 {
00130   // Retrieve cache corresponding to observables in nset
00131  
00132   // Check if this configuration was created becfore
00133   Int_t sterileIdx(-1) ;
00134   FuncCacheElem* cache = (FuncCacheElem*) _cacheMgr.getObj(nset,0,&sterileIdx,0) ;
00135   if (cache) {
00136     if (cache->paramTracker()->hasChanged(kTRUE)) {
00137       coutI(Eval) << "RooAbsCachedReal::getCache(" << GetName() << ") cache " << cache << " function " 
00138                   << cache->func()->GetName() << " requires recalculation as parameters changed" << endl ;
00139       fillCacheObject(*cache) ;  
00140       cache->func()->setValueDirty() ;
00141     }
00142     return cache ;
00143   }
00144 
00145   cache = createCache(nset) ;
00146 
00147   // Check if we have contents registered already in global expensive object cache 
00148   RooDataHist* htmp = (RooDataHist*) expensiveObjectCache().retrieveObject(cache->hist()->GetName(),RooDataHist::Class(),cache->paramTracker()->parameters()) ;
00149 
00150   if (htmp) {    
00151 
00152     cache->hist()->reset() ;
00153     cache->hist()->add(*htmp) ;
00154 
00155   } else {
00156 
00157     fillCacheObject(*cache) ;  
00158 
00159     RooDataHist* eoclone = new RooDataHist(*cache->hist()) ;
00160     eoclone->removeSelfFromDir() ;
00161     expensiveObjectCache().registerObject(GetName(),cache->hist()->GetName(),*eoclone,cache->paramTracker()->parameters()) ;
00162   } 
00163 
00164   // Store this cache configuration
00165   Int_t code = _cacheMgr.setObj(nset,0,((RooAbsCacheElement*)cache),0) ;
00166   coutI(Caching) << "RooAbsCachedReal::getCache(" << GetName() << ") creating new cache " << cache->func()->GetName() << " for nset " << (nset?*nset:RooArgSet()) << " with code " << code << endl ;
00167   
00168   return cache ;
00169 }
00170 
00171 
00172 
00173 //_____________________________________________________________________________
00174 RooAbsCachedReal::FuncCacheElem::FuncCacheElem(const RooAbsCachedReal& self, const RooArgSet* nset) 
00175 {
00176   // Constructor of cache storage unit class
00177   //
00178   // Create RooDataHist that will cache function values and create
00179   // RooHistFunc that represent s RooDataHist shape as function, create
00180   // meta object that tracks changes in declared parameters of p.d.f
00181   // through actualParameters() 
00182 
00183   RooArgSet* nset2 = self.actualObservables(nset?*nset:RooArgSet()) ;
00184 
00185   RooArgSet orderedObs ;
00186   self.preferredObservableScanOrder(*nset2,orderedObs) ;
00187 
00188   // Create RooDataHist
00189   TString hname = self.inputBaseName() ;
00190   hname.Append("_CACHEHIST") ;
00191   hname.Append(self.cacheNameSuffix(*nset2)) ;
00192 
00193   _hist = new RooDataHist(hname,hname,*nset2,self.binningName()) ;
00194   _hist->removeSelfFromDir() ;
00195 
00196   RooArgSet* observables= self.actualObservables(*nset2) ;
00197 
00198   // Create RooHistFunc
00199   TString funcname = self.inputBaseName() ;
00200   funcname.Append("_CACHE") ;
00201   funcname.Append(self.cacheNameSuffix(*nset2)) ;
00202   _func = new RooHistFunc(funcname,funcname,*observables,*_hist,self.getInterpolationOrder()) ;
00203 
00204   // Set initial state of cache to dirty
00205   _func->setValueDirty() ;
00206 
00207   // Create pseudo-object that tracks changes in parameter values
00208   RooArgSet* params = self.actualParameters(orderedObs) ;
00209   string name= Form("%s_CACHEPARAMS",_func->GetName()) ;
00210   _paramTracker = new RooChangeTracker(name.c_str(),name.c_str(),*params,kTRUE) ;
00211   _paramTracker->hasChanged(kTRUE) ; // clear dirty flag as cache is up-to-date upon creation
00212 
00213   // Introduce formal dependency of RooHistFunc on parameters so that const optimization code
00214   // makes the correct decisions
00215   _func->addServerList(*params) ;
00216 
00217   delete observables ;
00218   delete params ;
00219   delete nset2 ;
00220   
00221 }
00222 
00223 
00224 
00225 TString RooAbsCachedReal::cacheNameSuffix(const RooArgSet& nset) const 
00226 {
00227   // Construct unique suffix name for cache p.d.f object 
00228 
00229   TString name ;
00230   name.Append("_Obs[") ;
00231   if (nset.getSize()>0) {
00232     TIterator* iter = nset.createIterator() ;
00233     RooAbsArg* arg ;
00234     Bool_t first(kTRUE) ;
00235     while((arg=(RooAbsArg*)iter->Next())) {
00236       if (first) {
00237         first=kFALSE ;
00238       } else {
00239         name.Append(",") ;
00240       }
00241       name.Append(arg->GetName()) ;
00242     }
00243     delete iter ;
00244   }
00245 
00246   name.Append("]") ;
00247   const char* payloadUS = payloadUniqueSuffix() ;
00248   if (payloadUS) {
00249     name.Append(payloadUS) ;
00250   }
00251   return name ;
00252 }
00253 
00254 
00255 
00256 //_____________________________________________________________________________
00257 void RooAbsCachedReal::setInterpolationOrder(Int_t order) 
00258 {
00259   // Set interpolation order of RooHistFunct representing cache histogram
00260 
00261   _ipOrder = order ;
00262 
00263   Int_t i ;
00264   for (i=0 ; i<_cacheMgr.cacheSize() ; i++) {
00265     FuncCacheElem* cache = (FuncCacheElem*) _cacheMgr.getObjByIndex(i) ;
00266     if (cache) {
00267       cache->func()->setInterpolationOrder(order) ;
00268     }
00269   }
00270 }
00271 
00272 
00273 
00274 //_____________________________________________________________________________
00275 RooArgList RooAbsCachedReal::FuncCacheElem::containedArgs(Action) 
00276 {
00277   // Return list of contained RooAbsArg objects
00278   RooArgList ret(*func()) ;
00279 
00280   ret.add(*_paramTracker) ;
00281   return ret ;
00282 }
00283 
00284 
00285 //_____________________________________________________________________________
00286 void RooAbsCachedReal::FuncCacheElem::printCompactTreeHook(ostream& os, const char* indent, Int_t curElem, Int_t maxElem) 
00287 {
00288   // Print contents of cache when printing self as part of object tree
00289 
00290   if (curElem==0) {
00291     os << indent << "--- RooAbsCachedReal begin cache ---" << endl ;
00292   }
00293 
00294   TString indent2(indent) ;
00295   indent2 += Form("[%d] ",curElem) ;
00296   func()->printCompactTree(os,indent2) ;
00297 
00298   if (curElem==maxElem) {
00299     os << indent << "--- RooAbsCachedReal end cache --- " << endl ;
00300   }
00301 }
00302 
00303 
00304 
00305 //_____________________________________________________________________________
00306 Int_t RooAbsCachedReal::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars, const RooArgSet* normSet, const char* rangeName) const 
00307 {
00308   // Return analytical integration capabilities of the RooHistFunc that corresponds to the set of observables in allVars
00309 
00310   FuncCacheElem* cache = getCache(normSet?normSet:&allVars) ;
00311   Int_t code = cache->func()->getAnalyticalIntegralWN(allVars,analVars,normSet,rangeName) ;
00312   _anaIntMap[code].first = &allVars ;
00313   _anaIntMap[code].second = normSet ;
00314   return code ;
00315 }
00316 
00317 
00318 
00319 //_____________________________________________________________________________
00320 Double_t RooAbsCachedReal::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const
00321 {  
00322   // Forward call to implementation in relevant RooHistFunc instance
00323 
00324   if (code==0) {
00325     return getVal(normSet) ; 
00326   }  
00327 
00328   const RooArgSet* anaVars = _anaIntMap[code].first ;
00329   const RooArgSet* normSet2 = _anaIntMap[code].second ;
00330 
00331   FuncCacheElem* cache = getCache(normSet2?normSet2:anaVars) ;
00332   return cache->func()->analyticalIntegralWN(code,normSet,rangeName) ;
00333   
00334 }
00335 
00336 
00337 
00338 
00339 

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