00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
00067 }
00068
00069
00070
00071
00072 RooAbsCachedReal::~RooAbsCachedReal()
00073 {
00074
00075 }
00076
00077
00078
00079
00080 Double_t RooAbsCachedReal::getVal(const RooArgSet* nset) const
00081 {
00082
00083
00084
00085
00086
00087 if (_disableCache) {
00088 return RooAbsReal::getVal(nset) ;
00089 }
00090
00091
00092
00093
00094
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
00108 cache.hist()->setAllWeights(-1) ;
00109 }
00110
00111
00112
00113
00114 RooAbsCachedReal::FuncCacheElem* RooAbsCachedReal::createCache(const RooArgSet* nset) const
00115 {
00116
00117
00118
00119
00120
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
00131
00132
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
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
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
00177
00178
00179
00180
00181
00182
00183 RooArgSet* nset2 = self.actualObservables(nset?*nset:RooArgSet()) ;
00184
00185 RooArgSet orderedObs ;
00186 self.preferredObservableScanOrder(*nset2,orderedObs) ;
00187
00188
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
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
00205 _func->setValueDirty() ;
00206
00207
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) ;
00212
00213
00214
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
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
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
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
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
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
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