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
00031
00032
00033 #include "Riostream.h"
00034 using namespace std ;
00035
00036 #include "RooFit.h"
00037 #include "TString.h"
00038 #include "RooAbsCachedPdf.h"
00039 #include "RooAbsReal.h"
00040 #include "RooMsgService.h"
00041 #include "RooDataHist.h"
00042 #include "RooHistPdf.h"
00043 #include "RooGlobalFunc.h"
00044 #include "RooRealVar.h"
00045 #include "RooChangeTracker.h"
00046 #include "RooExpensiveObjectCache.h"
00047
00048 ClassImp(RooAbsCachedPdf)
00049
00050
00051
00052
00053 RooAbsCachedPdf::RooAbsCachedPdf(const char *name, const char *title, Int_t ipOrder) :
00054 RooAbsPdf(name,title),
00055 _cacheMgr(this,10),
00056 _ipOrder(ipOrder),
00057 _disableCache(kFALSE)
00058 {
00059
00060 }
00061
00062
00063
00064
00065 RooAbsCachedPdf::RooAbsCachedPdf(const RooAbsCachedPdf& other, const char* name) :
00066 RooAbsPdf(other,name),
00067 _cacheMgr(other._cacheMgr,this),
00068 _ipOrder(other._ipOrder),
00069 _disableCache(other._disableCache)
00070 {
00071
00072 }
00073
00074
00075
00076
00077 RooAbsCachedPdf::~RooAbsCachedPdf()
00078 {
00079
00080 }
00081
00082
00083
00084
00085 Double_t RooAbsCachedPdf::getVal(const RooArgSet* nset) const
00086 {
00087
00088
00089
00090
00091
00092 if (_disableCache) {
00093 return RooAbsPdf::getVal(nset) ;
00094 }
00095
00096
00097 PdfCacheElem* cache = getCache(nset) ;
00098
00099 Double_t value = cache->pdf()->getVal(nset) ;
00100
00101 _value = value ;
00102 return _value ;
00103 }
00104
00105
00106
00107
00108 RooAbsPdf* RooAbsCachedPdf::getCachePdf(const RooArgSet* nset) const
00109 {
00110
00111
00112 PdfCacheElem* cache = getCache(nset) ;
00113
00114 if (cache) {
00115 return cache->pdf() ;
00116 } else {
00117 return 0 ;
00118 }
00119 }
00120
00121
00122
00123 RooDataHist* RooAbsCachedPdf::getCacheHist(const RooArgSet* nset) const
00124 {
00125
00126
00127 PdfCacheElem* cache = getCache(nset) ;
00128
00129 if (cache) {
00130 return cache->hist() ;
00131 } else {
00132 return 0 ;
00133 }
00134 }
00135
00136
00137
00138 void RooAbsCachedPdf::clearCacheObject(PdfCacheElem& cache) const
00139 {
00140
00141
00142 cache.hist()->setAllWeights(-1) ;
00143 }
00144
00145
00146
00147
00148 RooAbsCachedPdf::PdfCacheElem* RooAbsCachedPdf::getCache(const RooArgSet* nset, Bool_t recalculate) const
00149 {
00150
00151
00152
00153
00154
00155
00156 Int_t sterileIdx(-1) ;
00157 PdfCacheElem* cache = (PdfCacheElem*) _cacheMgr.getObj(nset,0,&sterileIdx,0) ;
00158
00159
00160 if (cache) {
00161 if (cache->paramTracker()->hasChanged(kTRUE) && (recalculate || !cache->pdf()->haveUnitNorm()) ) {
00162 cxcoutD(Eval) << "RooAbsCachedPdf::getCache(" << GetName() << ") cache " << cache << " pdf "
00163 << cache->pdf()->GetName() << " requires recalculation as parameters changed" << endl ;
00164 fillCacheObject(*cache) ;
00165 cache->pdf()->setValueDirty() ;
00166 }
00167 return cache ;
00168 }
00169
00170
00171 cache = createCache(nset) ;
00172
00173
00174 RooDataHist* htmp = (RooDataHist*) expensiveObjectCache().retrieveObject(cache->hist()->GetName(),RooDataHist::Class(),cache->paramTracker()->parameters()) ;
00175
00176 if (htmp) {
00177
00178 cache->hist()->reset() ;
00179 cache->hist()->add(*htmp) ;
00180
00181 } else {
00182
00183 fillCacheObject(*cache) ;
00184
00185 RooDataHist* eoclone = new RooDataHist(*cache->hist()) ;
00186 eoclone->removeSelfFromDir() ;
00187 expensiveObjectCache().registerObject(GetName(),cache->hist()->GetName(),*eoclone,cache->paramTracker()->parameters()) ;
00188
00189 }
00190
00191
00192
00193 Int_t code = _cacheMgr.setObj(nset,0,((RooAbsCacheElement*)cache),0) ;
00194
00195 coutI(Caching) << "RooAbsCachedPdf::getCache(" << GetName() << ") creating new cache " << cache << " with pdf "
00196 << cache->pdf()->GetName() << " for nset " << (nset?*nset:RooArgSet()) << " with code " << code ;
00197 if (htmp) {
00198 ccoutI(Caching) << " from preexisting content." ;
00199 }
00200 ccoutI(Caching) << endl ;
00201
00202 return cache ;
00203 }
00204
00205
00206
00207
00208
00209 RooAbsCachedPdf::PdfCacheElem::PdfCacheElem(const RooAbsCachedPdf& self, const RooArgSet* nsetIn) :
00210 _pdf(0), _paramTracker(0), _hist(0), _norm(0)
00211 {
00212
00213
00214
00215
00216
00217 RooArgSet* nset2 = self.actualObservables(nsetIn?*nsetIn:RooArgSet()) ;
00218
00219 RooArgSet orderedObs ;
00220 if (nset2) {
00221 self.preferredObservableScanOrder(*nset2,orderedObs) ;
00222 }
00223
00224
00225 TString hname = self.GetName() ;
00226 hname.Append("_") ;
00227 hname.Append(self.inputBaseName()) ;
00228 hname.Append("_CACHEHIST") ;
00229 hname.Append(self.cacheNameSuffix(orderedObs)) ;
00230 hname.Append(self.histNameSuffix()) ;
00231 _hist = new RooDataHist(hname,hname,orderedObs,self.binningName()) ;
00232 _hist->removeSelfFromDir() ;
00233
00234
00235
00236
00237
00238 RooArgSet pdfObs ;
00239 RooArgSet pdfFinalObs ;
00240 TIterator* iter = orderedObs.createIterator() ;
00241 RooAbsArg* harg ;
00242 while((harg=(RooAbsArg*)iter->Next())) {
00243 RooAbsArg& po = self.pdfObservable(*harg) ;
00244 pdfObs.add(po) ;
00245 if (po.isFundamental()) {
00246 pdfFinalObs.add(po) ;
00247 } else {
00248 RooArgSet* tmp = po.getVariables() ;
00249 pdfFinalObs.add(*tmp) ;
00250 delete tmp ;
00251 }
00252 }
00253 delete iter ;
00254
00255
00256 TString pdfname = self.inputBaseName() ;
00257 pdfname.Append("_CACHE") ;
00258 pdfname.Append(self.cacheNameSuffix(pdfFinalObs)) ;
00259 _pdf = new RooHistPdf(pdfname,pdfname,pdfObs,orderedObs,*_hist,self.getInterpolationOrder()) ;
00260 if (nsetIn) {
00261 _nset.addClone(*nsetIn) ;
00262 }
00263
00264
00265
00266 RooArgSet* params = self.actualParameters(pdfFinalObs) ;
00267 params->remove(pdfFinalObs,kTRUE,kTRUE) ;
00268
00269 string name= Form("%s_CACHEPARAMS",_pdf->GetName()) ;
00270 _paramTracker = new RooChangeTracker(name.c_str(),name.c_str(),*params,kTRUE) ;
00271 _paramTracker->hasChanged(kTRUE) ;
00272
00273
00274
00275 _pdf->addServerList(*params) ;
00276
00277
00278 _pdf->setValueDirty() ;
00279
00280
00281 delete params ;
00282 delete nset2 ;
00283
00284 }
00285
00286
00287
00288
00289 TString RooAbsCachedPdf::cacheNameSuffix(const RooArgSet& nset) const
00290 {
00291
00292
00293
00294 TString name ;
00295 name.Append("_Obs[") ;
00296 if (nset.getSize()>0) {
00297 TIterator* iter = nset.createIterator() ;
00298 RooAbsArg* arg ;
00299 Bool_t first(kTRUE) ;
00300 while((arg=(RooAbsArg*)iter->Next())) {
00301 if (first) {
00302 first=kFALSE ;
00303 } else {
00304 name.Append(",") ;
00305 }
00306 name.Append(arg->GetName()) ;
00307 }
00308 delete iter ;
00309 }
00310
00311 name.Append("]") ;
00312 const char* payloadUS = payloadUniqueSuffix() ;
00313 if (payloadUS) {
00314 name.Append(payloadUS) ;
00315 }
00316 return name ;
00317 }
00318
00319
00320
00321
00322 void RooAbsCachedPdf::setInterpolationOrder(Int_t order)
00323 {
00324
00325
00326
00327 _ipOrder = order ;
00328
00329 Int_t i ;
00330 for (i=0 ; i<_cacheMgr.cacheSize() ; i++) {
00331 PdfCacheElem* cache = (PdfCacheElem*) _cacheMgr.getObjByIndex(i) ;
00332 if (cache) {
00333 cache->pdf()->setInterpolationOrder(order) ;
00334 }
00335 }
00336 }
00337
00338
00339
00340
00341 RooArgList RooAbsCachedPdf::PdfCacheElem::containedArgs(Action)
00342 {
00343
00344 RooArgList ret(*_pdf) ;
00345 ret.add(*_paramTracker) ;
00346 if (_norm) ret.add(*_norm) ;
00347 return ret ;
00348 }
00349
00350
00351
00352
00353 RooAbsCachedPdf::PdfCacheElem::~PdfCacheElem()
00354 {
00355
00356
00357 if (_norm) {
00358 delete _norm ;
00359 }
00360 if (_pdf) {
00361 delete _pdf ;
00362 }
00363 if (_paramTracker) {
00364 delete _paramTracker ;
00365 }
00366 if (_hist) {
00367 delete _hist ;
00368 }
00369 }
00370
00371
00372
00373
00374 void RooAbsCachedPdf::PdfCacheElem::printCompactTreeHook(ostream& os, const char* indent, Int_t curElem, Int_t maxElem)
00375 {
00376
00377
00378 if (curElem==0) {
00379 os << indent << "--- RooAbsCachedPdf begin cache ---" << endl ;
00380 }
00381
00382 TString indent2(indent) ;
00383 os << Form("[%d] Configuration for observables ",curElem) << _nset << endl ;
00384 indent2 += Form("[%d] ",curElem) ;
00385 _pdf->printCompactTree(os,indent2) ;
00386 if (_norm) {
00387 os << Form("[%d] Norm ",curElem) ;
00388 _norm->printStream(os,kName|kArgs,kSingleLine) ;
00389 }
00390
00391 if (curElem==maxElem) {
00392 os << indent << "--- RooAbsCachedPdf end cache --- " << endl ;
00393 }
00394 }
00395
00396
00397
00398
00399 Bool_t RooAbsCachedPdf::forceAnalyticalInt(const RooAbsArg& dep) const
00400 {
00401
00402
00403
00404 RooArgSet* actObs = actualObservables(dep) ;
00405 Bool_t ret = (actObs->getSize()>0) ;
00406 delete actObs ;
00407 return ret ;
00408 }
00409
00410
00411
00412
00413 Int_t RooAbsCachedPdf::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars, const RooArgSet* normSet, const char* rangeName) const
00414 {
00415
00416
00417
00418
00419 if (allVars.getSize()==0) {
00420 return 0 ;
00421 }
00422
00423 PdfCacheElem* cache = getCache(normSet?normSet:&allVars) ;
00424 Int_t code = cache->pdf()->getAnalyticalIntegralWN(allVars,analVars,normSet,rangeName) ;
00425
00426 if (code==0) {
00427 return 0 ;
00428 }
00429
00430 RooArgSet* all = new RooArgSet ;
00431 RooArgSet* ana = new RooArgSet ;
00432 RooArgSet* nrm = new RooArgSet ;
00433 all->addClone(allVars) ;
00434 ana->addClone(analVars) ;
00435 if (normSet) {
00436 nrm->addClone(*normSet) ;
00437 }
00438 Int_t codeList[2] ;
00439 codeList[0] = code ;
00440 codeList[1] = cache->pdf()->haveUnitNorm() ? 1 : 0 ;
00441 Int_t masterCode = _anaReg.store(codeList,2,all,ana,nrm)+1 ;
00442
00443
00444
00445 if (cache->pdf()->haveUnitNorm()) {
00446 analVars.add(allVars,kTRUE) ;
00447 }
00448
00449 return masterCode ;
00450 }
00451
00452
00453
00454
00455 Double_t RooAbsCachedPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const
00456 {
00457
00458
00459
00460
00461 if (code==0) {
00462 return getVal(normSet) ;
00463 }
00464
00465 RooArgSet *allVars(0),*anaVars(0),*normSet2(0),*dummy(0) ;
00466 const Int_t* codeList = _anaReg.retrieve(code-1,allVars,anaVars,normSet2,dummy) ;
00467
00468
00469
00470 PdfCacheElem* cache = getCache(normSet2?normSet2:anaVars,kFALSE) ;
00471 Double_t ret = cache->pdf()->analyticalIntegralWN(codeList[0],normSet,rangeName) ;
00472
00473 if (codeList[1]>0) {
00474 RooArgSet factObs(*allVars) ;
00475 factObs.remove(*anaVars,kTRUE,kTRUE) ;
00476 TIterator* iter = factObs.createIterator() ;
00477 RooAbsLValue* arg ;
00478 while((arg=dynamic_cast<RooAbsLValue*>(iter->Next()))) {
00479 ret *= arg->volume(rangeName) ;
00480 }
00481 delete iter ;
00482 }
00483
00484 return ret ;
00485 }
00486
00487
00488
00489
00490