ROOT  6.06/09
Reference Guide
RooAbsCachedPdf.cxx
Go to the documentation of this file.
1  /*****************************************************************************
2  * Project: RooFit *
3  * *
4  * Copyright (c) 2000-2005, Regents of the University of California *
5  * and Stanford University. All rights reserved. *
6  * *
7  * Redistribution and use in source and binary forms, *
8  * with or without modification, are permitted according to the terms *
9  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
10  *****************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////////
13 //
14 // BEGIN_HTML
15 // RooAbsCachedPdf is the abstract base class for p.d.f.s that need or
16 // want to cache their evaluate() output in a RooHistPdf defined in
17 // terms of the used observables. This base class manages the creation
18 // and storage of all RooHistPdf cache p.d.fs and the RooDataHists
19 // that define their shape. Implementations of RooAbsCachedPdf must
20 // define member function fillCacheObject() which serves to fill an
21 // already created RooDataHist with the p.d.fs function values. In
22 // addition the member functions actualObservables() and
23 // actualParameters() must be define which report what the actual
24 // observables to be cached are for a given set of observables passed
25 // by the user to getVal() and on which parameters need to be tracked
26 // for changes to trigger a refilling of the cache histogram.
27 // END_HTML
28 //
29 //
30 //
31 //
32 
33 #include "Riostream.h"
34 using namespace std ;
35 
36 #include "RooFit.h"
37 #include "TString.h"
38 #include "RooAbsCachedPdf.h"
39 #include "RooAbsReal.h"
40 #include "RooMsgService.h"
41 #include "RooDataHist.h"
42 #include "RooHistPdf.h"
43 #include "RooGlobalFunc.h"
44 #include "RooRealVar.h"
45 #include "RooChangeTracker.h"
47 
49 
50 
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 /// Constructor
54 
55 RooAbsCachedPdf::RooAbsCachedPdf(const char *name, const char *title, Int_t ipOrder) :
56  RooAbsPdf(name,title),
57  _cacheMgr(this,10),
58  _ipOrder(ipOrder),
59  _disableCache(kFALSE)
60  {
61  }
62 
63 
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 /// Copy constructor
67 
69  RooAbsPdf(other,name),
70  _cacheMgr(other._cacheMgr,this),
71  _ipOrder(other._ipOrder),
72  _disableCache(other._disableCache)
73  {
74  }
75 
76 
77 
78 ////////////////////////////////////////////////////////////////////////////////
79 /// Destructor
80 
82 {
83 }
84 
85 
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 /// Implementation of getVal() overriding default implementation
89 /// of RooAbsPdf. Return normalized value stored in cache p.d.f
90 /// rather than return value of evaluate() which is undefined
91 /// for RooAbsCachedPdf
92 
94 {
95  if (_disableCache) {
96  return RooAbsPdf::getValV(nset) ;
97  }
98 
99  // Calculate current unnormalized value of object
100  PdfCacheElem* cache = getCache(nset) ;
101 
102  Double_t value = cache->pdf()->getVal(nset) ;
103 
104  _value = value ;
105  return _value ;
106 }
107 
108 
109 
110 ////////////////////////////////////////////////////////////////////////////////
111 /// Return pointer to RooHistPdf cache pdf for given choice of observables
112 
114 {
115  PdfCacheElem* cache = getCache(nset) ;
116 
117  if (cache) {
118  return cache->pdf() ;
119  } else {
120  return 0 ;
121  }
122 }
123 
124 
125 ////////////////////////////////////////////////////////////////////////////////
126 /// Return pointer to RooDataHist cache histogram for given choice of observables
127 
129 {
130  PdfCacheElem* cache = getCache(nset) ;
131 
132  if (cache) {
133  return cache->hist() ;
134  } else {
135  return 0 ;
136  }
137 }
138 
139 
140 ////////////////////////////////////////////////////////////////////////////////
141 /// Mark all bins of given cache as unitialized (value -1)
142 
144 {
145  cache.hist()->setAllWeights(-1) ;
146 }
147 
148 
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// Retrieve cache object associated with given choice of observables. If cache object
152 /// does not exist, create and fill and register it on the fly. If recalculate=false
153 /// recalculation of cache contents of existing caches that are marked dirty due to
154 /// dependent parameter changes is suppressed.
155 
157 {
158  // Check if this configuration was created becfore
159  Int_t sterileIdx(-1) ;
160  PdfCacheElem* cache = (PdfCacheElem*) _cacheMgr.getObj(nset,0,&sterileIdx) ;
161 
162  // Check if we have a cache histogram in the global expensive object cache
163  if (cache) {
164  if (cache->paramTracker()->hasChanged(kTRUE) && (recalculate || !cache->pdf()->haveUnitNorm()) ) {
165  cxcoutD(Eval) << "RooAbsCachedPdf::getCache(" << GetName() << ") cache " << cache << " pdf "
166  << cache->pdf()->GetName() << " requires recalculation as parameters changed" << endl ;
167  fillCacheObject(*cache) ;
168  cache->pdf()->setValueDirty() ;
169  }
170  return cache ;
171  }
172 
173  // Create and fill cache
174  cache = createCache(nset) ;
175 
176  // Check if we have contents registered already in global expensive object cache
178 
179  if (htmp) {
180 
181  cache->hist()->reset() ;
182  cache->hist()->add(*htmp) ;
183 
184  } else {
185 
186  fillCacheObject(*cache) ;
187 
188  RooDataHist* eoclone = new RooDataHist(*cache->hist()) ;
189  eoclone->removeSelfFromDir() ;
190  expensiveObjectCache().registerObject(GetName(),cache->hist()->GetName(),*eoclone,cache->paramTracker()->parameters()) ;
191 
192  }
193 
194 
195  // Store this cache configuration
196  Int_t code = _cacheMgr.setObj(nset,0,((RooAbsCacheElement*)cache),0) ;
197 
198  coutI(Caching) << "RooAbsCachedPdf::getCache(" << GetName() << ") creating new cache " << cache << " with pdf "
199  << cache->pdf()->GetName() << " for nset " << (nset?*nset:RooArgSet()) << " with code " << code ;
200  if (htmp) {
201  ccoutI(Caching) << " from preexisting content." ;
202  }
203  ccoutI(Caching) << endl ;
204 
205  return cache ;
206 }
207 
208 
209 
210 
211 ////////////////////////////////////////////////////////////////////////////////
212 /// Constructor of cache object which owns RooDataHist cache histogram,
213 /// RooHistPdf pdf that represents is shape and RooChangeTracker meta
214 /// object that tracks changes in listed dependent parameter of cache.
215 
217  _pdf(0), _paramTracker(0), _hist(0), _norm(0)
218 {
219  // Create cache object itself -- Default implementation is a RooHistPdf
220  RooArgSet* nset2 = self.actualObservables(nsetIn?*nsetIn:RooArgSet()) ;
221 
222  RooArgSet orderedObs ;
223  if (nset2) {
224  self.preferredObservableScanOrder(*nset2,orderedObs) ;
225  }
226 
227  // Create RooDataHist
228  TString hname = self.GetName() ;
229  hname.Append("_") ;
230  hname.Append(self.inputBaseName()) ;
231  hname.Append("_CACHEHIST") ;
232  hname.Append(self.cacheNameSuffix(orderedObs)) ;
233  hname.Append(self.histNameSuffix()) ;
234  _hist = new RooDataHist(hname,hname,orderedObs,self.binningName()) ;
236 
237  //RooArgSet* observables= self.getObservables(orderedObs) ;
238  // cout << "orderedObs = " << orderedObs << " observables = " << *observables << endl ;
239 
240  // Get set of p.d.f. observable corresponding to set of histogram observables
241  RooArgSet pdfObs ;
242  RooArgSet pdfFinalObs ;
243  TIterator* iter = orderedObs.createIterator() ;
244  RooAbsArg* harg ;
245  while((harg=(RooAbsArg*)iter->Next())) {
246  RooAbsArg& po = self.pdfObservable(*harg) ;
247  pdfObs.add(po) ;
248  if (po.isFundamental()) {
249  pdfFinalObs.add(po) ;
250  } else {
251  RooArgSet* tmp = po.getVariables() ;
252  pdfFinalObs.add(*tmp) ;
253  delete tmp ;
254  }
255  }
256  delete iter ;
257 
258  // Create RooHistPdf
259  TString pdfname = self.inputBaseName() ;
260  pdfname.Append("_CACHE") ;
261  pdfname.Append(self.cacheNameSuffix(pdfFinalObs)) ;
262  _pdf = new RooHistPdf(pdfname,pdfname,pdfObs,orderedObs,*_hist,self.getInterpolationOrder()) ;
263  if (nsetIn) {
264  _nset.addClone(*nsetIn) ;
265  }
266 
267  // Create pseudo-object that tracks changes in parameter values
268 
269  RooArgSet* params = self.actualParameters(pdfFinalObs) ;
270  params->remove(pdfFinalObs,kTRUE,kTRUE) ;
271 
272  string name= Form("%s_CACHEPARAMS",_pdf->GetName()) ;
273  _paramTracker = new RooChangeTracker(name.c_str(),name.c_str(),*params,kTRUE) ;
274  _paramTracker->hasChanged(kTRUE) ; // clear dirty flag as cache is up-to-date upon creation
275 
276  // Introduce formal dependency of RooHistPdf on parameters so that const optimization code
277  // makes the correct decisions
278  _pdf->addServerList(*params) ;
279 
280  // Set initial state of cache to dirty
281  _pdf->setValueDirty() ;
282 
283  //delete observables ;
284  delete params ;
285  delete nset2 ;
286 
287 }
288 
289 
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 /// Construct string with unique suffix for cache objects based on
293 /// observable names that define cache configuration
294 
296 {
297  TString name ;
298  name.Append("_Obs[") ;
299  if (nset.getSize()>0) {
300  TIterator* iter = nset.createIterator() ;
301  RooAbsArg* arg ;
302  Bool_t first(kTRUE) ;
303  while((arg=(RooAbsArg*)iter->Next())) {
304  if (first) {
305  first=kFALSE ;
306  } else {
307  name.Append(",") ;
308  }
309  name.Append(arg->GetName()) ;
310  }
311  delete iter ;
312  }
313 
314  name.Append("]") ;
315  const char* payloadUS = payloadUniqueSuffix() ;
316  if (payloadUS) {
317  name.Append(payloadUS) ;
318  }
319  return name ;
320 }
321 
322 
323 
324 ////////////////////////////////////////////////////////////////////////////////
325 /// Change the interpolation order that is used in RooHistPdf cache
326 /// representation smoothing the RooDataHist shapes.
327 
329 {
330  _ipOrder = order ;
331 
332  Int_t i ;
333  for (i=0 ; i<_cacheMgr.cacheSize() ; i++) {
335  if (cache) {
336  cache->pdf()->setInterpolationOrder(order) ;
337  }
338  }
339 }
340 
341 
342 
343 ////////////////////////////////////////////////////////////////////////////////
344 /// Returns all RooAbsArg objects contained in the cache element
345 
347 {
348  RooArgList ret(*_pdf) ;
349  ret.add(*_paramTracker) ;
350  if (_norm) ret.add(*_norm) ;
351  return ret ;
352 }
353 
354 
355 
356 ////////////////////////////////////////////////////////////////////////////////
357 /// Cache element destructor
358 
360 {
361  if (_norm) {
362  delete _norm ;
363  }
364  if (_pdf) {
365  delete _pdf ;
366  }
367  if (_paramTracker) {
368  delete _paramTracker ;
369  }
370  if (_hist) {
371  delete _hist ;
372  }
373 }
374 
375 
376 
377 ////////////////////////////////////////////////////////////////////////////////
378 /// Print contents of cache when printing self as part of object tree
379 
380 void RooAbsCachedPdf::PdfCacheElem::printCompactTreeHook(ostream& os, const char* indent, Int_t curElem, Int_t maxElem)
381 {
382  if (curElem==0) {
383  os << indent << "--- RooAbsCachedPdf begin cache ---" << endl ;
384  }
385 
386  TString indent2(indent) ;
387  os << Form("[%d] Configuration for observables ",curElem) << _nset << endl ;
388  indent2 += Form("[%d] ",curElem) ;
389  _pdf->printCompactTree(os,indent2) ;
390  if (_norm) {
391  os << Form("[%d] Norm ",curElem) ;
393  }
394 
395  if (curElem==maxElem) {
396  os << indent << "--- RooAbsCachedPdf end cache --- " << endl ;
397  }
398 }
399 
400 
401 
402 ////////////////////////////////////////////////////////////////////////////////
403 /// Force RooRealIntegral to offer all our actual observable for internal
404 /// integration
405 
407 {
408  RooArgSet* actObs = actualObservables(dep) ;
409  Bool_t ret = (actObs->getSize()>0) ;
410  delete actObs ;
411  return ret ;
412 }
413 
414 
415 
416 ////////////////////////////////////////////////////////////////////////////////
417 /// Advertises internal (analytical) integration capabilities. Call
418 /// is forwarded to RooHistPdf cache p.d.f of cache that is used for
419 /// given choice of observables
420 
421 Int_t RooAbsCachedPdf::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars, const RooArgSet* normSet, const char* rangeName) const
422 {
423  if (allVars.getSize()==0) {
424  return 0 ;
425  }
426 
427  PdfCacheElem* cache = getCache(normSet?normSet:&allVars) ;
428  Int_t code = cache->pdf()->getAnalyticalIntegralWN(allVars,analVars,normSet,rangeName) ;
429 
430  if (code==0) {
431  return 0 ;
432  }
433 
434  RooArgSet* all = new RooArgSet ;
435  RooArgSet* ana = new RooArgSet ;
436  RooArgSet* nrm = new RooArgSet ;
437  all->addClone(allVars) ;
438  ana->addClone(analVars) ;
439  if (normSet) {
440  nrm->addClone(*normSet) ;
441  }
442  std::vector<Int_t> codeList(2);
443  codeList[0] = code ;
444  codeList[1] = cache->pdf()->haveUnitNorm() ? 1 : 0 ;
445  Int_t masterCode = _anaReg.store(codeList,all,ana,nrm)+1 ; // takes ownership of all sets
446 
447 
448  // Mark all observables as internally integrated
449  if (cache->pdf()->haveUnitNorm()) {
450  analVars.add(allVars,kTRUE) ;
451  }
452 
453  return masterCode ;
454 }
455 
456 
457 
458 ////////////////////////////////////////////////////////////////////////////////
459 /// Implements internal (analytical) integration capabilities. Call
460 /// is forwarded to RooHistPdf cache p.d.f of cache that is used for
461 /// given choice of observables
462 
463 Double_t RooAbsCachedPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const
464 {
465  if (code==0) {
466  return getVal(normSet) ;
467  }
468 
469  RooArgSet *allVars(0),*anaVars(0),*normSet2(0),*dummy(0) ;
470  const std::vector<Int_t> codeList = _anaReg.retrieve(code-1,allVars,anaVars,normSet2,dummy) ;
471 
472  PdfCacheElem* cache = getCache(normSet2?normSet2:anaVars,kFALSE) ;
473  Double_t ret = cache->pdf()->analyticalIntegralWN(codeList[0],normSet,rangeName) ;
474 
475  if (codeList[1]>0) {
476  RooArgSet factObs(*allVars) ;
477  factObs.remove(*anaVars,kTRUE,kTRUE) ;
478  TIterator* iter = factObs.createIterator() ;
479  RooAbsLValue* arg ;
480  while((arg=dynamic_cast<RooAbsLValue*>(iter->Next()))) {
481  ret *= arg->volume(rangeName) ;
482  }
483  delete iter ;
484  }
485 
486  return ret ;
487 }
488 
489 
490 
491 
492 
Int_t cacheSize() const
Bool_t haveUnitNorm() const
Definition: RooHistPdf.h:71
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
virtual Bool_t forceAnalyticalInt(const RooAbsArg &dep) const
Force RooRealIntegral to offer all our actual observable for internal integration.
virtual void printStream(std::ostream &os, Int_t contents, StyleOption style, TString indent="") const
Print description of object on ostream, printing contents set by contents integer, which is interpreted as an OR of 'enum ContentsOptions' values and in the style given by 'enum StyleOption'.
virtual const char * binningName() const
#define coutI(a)
Definition: RooMsgService.h:32
void setInterpolationOrder(Int_t order)
Definition: RooHistPdf.h:46
#define cxcoutD(a)
Definition: RooMsgService.h:80
virtual Double_t analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=0) const
Implements internal (analytical) integration capabilities.
RooChangeTracker * _paramTracker
virtual Bool_t isFundamental() const
Definition: RooAbsArg.h:157
virtual const char * inputBaseName() const =0
virtual Double_t getValV(const RooArgSet *set=0) const
Implementation of getVal() overriding default implementation of RooAbsPdf.
RooAbsPdf * getCachePdf(const RooArgSet &nset) const
Bool_t hasChanged(Bool_t clearState)
Returns true if state has changes since last call with clearState=kTRUE If clearState is true...
Basic string class.
Definition: TString.h:137
virtual RooArgList containedArgs(Action)
Returns all RooAbsArg objects contained in the cache element.
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual const char * payloadUniqueSuffix() const
STL namespace.
RooExpensiveObjectCache & expensiveObjectCache() const
Definition: RooAbsArg.cxx:2341
PdfCacheElem(const RooAbsCachedPdf &self, const RooArgSet *nset)
Constructor of cache object which owns RooDataHist cache histogram, RooHistPdf pdf that represents is...
virtual ~PdfCacheElem()
Cache element destructor.
const TObject * retrieveObject(const char *name, TClass *tclass, const RooArgSet &params)
Retrieve object from cache that was registered under given name with given parameters, if current parameter values match those that were stored in the registry for this object.
#define ccoutI(a)
Definition: RooMsgService.h:39
Iterator abstract base class.
Definition: TIterator.h:32
PdfCacheElem * getCache(const RooArgSet *nset, Bool_t recalculate=kTRUE) const
Retrieve cache object associated with given choice of observables.
TString cacheNameSuffix(const RooArgSet &nset) const
Construct string with unique suffix for cache objects based on observable names that define cache con...
Int_t getInterpolationOrder() const
void Class()
Definition: Class.C:29
RooArgSet parameters() const
RooArgSet * getVariables(Bool_t stripDisconnected=kTRUE) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
Definition: RooAbsArg.cxx:2081
virtual ~RooAbsCachedPdf()
Destructor.
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=0, const TNamed *isetRangeName=0)
std::map< std::string, std::string >::const_iterator iter
Definition: TAlienJob.cxx:54
TIterator * createIterator(Bool_t dir=kIterForward) const
virtual Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet, const char *rangeName=0) const
Advertises internal (analytical) integration capabilities.
TString & Append(const char *cs)
Definition: TString.h:492
friend class RooArgSet
Definition: RooAbsArg.h:469
Double_t getVal(const RooArgSet *set=0) const
Definition: RooAbsReal.h:64
Bool_t _disableCache
Map for analytical integration codes.
friend class RooHistPdf
Definition: RooAbsArg.h:509
virtual PdfCacheElem * createCache(const RooArgSet *nset) const
ClassImp(RooAbsCachedPdf) RooAbsCachedPdf
Constructor.
void addServerList(RooAbsCollection &serverList, Bool_t valueProp=kTRUE, Bool_t shapeProp=kFALSE)
Register a list of RooAbsArg as servers to us by calls addServer() for each arg in the list...
Definition: RooAbsArg.cxx:397
RooAICRegistry _anaReg
virtual Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet, const char *rangeName=0) const
Variant of getAnalyticalIntegral that is also passed the normalization set that should be applied to ...
Definition: RooAbsReal.cxx:320
RooAbsReal * _norm
Definition: RooAbsPdf.h:301
virtual void add(const RooArgSet &row, Double_t wgt=1.0)
Definition: RooDataHist.h:65
virtual void fillCacheObject(PdfCacheElem &cache) const =0
char * Form(const char *fmt,...)
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
void removeSelfFromDir()
Definition: RooDataHist.h:131
static void indent(ostringstream &buf, int indent_level)
const std::vector< Int_t > & retrieve(Int_t masterCode) const
Retrieve the array of integer codes associated with the given master code.
virtual Double_t getValV(const RooArgSet *set=0) const
Return current value, normalizated by integrating over the observables in 'nset'. ...
Definition: RooAbsPdf.cxx:252
Int_t store(const std::vector< Int_t > &codeList, RooArgSet *set1=0, RooArgSet *set2=0, RooArgSet *set3=0, RooArgSet *set4=0)
Store given arrays of integer codes, and up to four RooArgSets in the registry (each setX pointer may...
RooDataHist * getCacheHist(const RooArgSet &nset) const
double Double_t
Definition: RtypesCore.h:55
static RooMathCoreReg dummy
void setValueDirty() const
Definition: RooAbsArg.h:439
virtual void printCompactTreeHook(std::ostream &, const char *, Int_t, Int_t)
Print contents of cache when printing self as part of object tree.
Double_t analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=0) const
Analytical integral with normalization (see RooAbsReal::analyticalIntegralWN() for further informatio...
Definition: RooAbsPdf.cxx:321
#define name(a, b)
Definition: linkTestLib0.cpp:5
Double_t _value
Definition: RooAbsReal.h:389
virtual RooArgSet * actualObservables(const RooArgSet &nset) const =0
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
T * getObjByIndex(Int_t index) const
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
virtual void reset()
Reset all bin weights to zero.
virtual TObject * Next()=0
void setInterpolationOrder(Int_t order)
Change the interpolation order that is used in RooHistPdf cache representation smoothing the RooDataH...
void clearCacheObject(PdfCacheElem &cache) const
Mark all bins of given cache as unitialized (value -1)
virtual RooAbsArg * addClone(const RooAbsArg &var, Bool_t silent=kFALSE)
Add clone of specified element to an owning set.
Definition: RooArgSet.cxx:475
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=0)
RooObjCacheManager _cacheMgr
RooChangeTracker * paramTracker()
Int_t getSize() const
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
const Bool_t kTRUE
Definition: Rtypes.h:91
void setAllWeights(Double_t value)
Set all the event weight of all bins to the specified value.
float value
Definition: math.cpp:443
virtual Double_t volume(const char *rangeName) const =0
Bool_t registerObject(const char *ownerName, const char *objectName, TObject &cacheObject, TIterator *paramIter)
Register object associated with given name and given associated parameters with given values in cache...
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add element to non-owning set.
Definition: RooArgSet.cxx:448
virtual TString histNameSuffix() const