ROOT  6.06/08
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 
RooArgSet * getVariables(Bool_t stripDisconnected=kTRUE) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
Definition: RooAbsArg.cxx:2081
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
TIterator * createIterator(Bool_t dir=kIterForward) const
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 &#39;enum ContentsOptions&#39; values and in the style given by &#39;enum StyleOption&#39;.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
PdfCacheElem * getCache(const RooArgSet *nset, Bool_t recalculate=kTRUE) const
Retrieve cache object associated with given choice of observables.
#define coutI(a)
Definition: RooMsgService.h:32
void setInterpolationOrder(Int_t order)
Definition: RooHistPdf.h:46
Double_t getVal(const RooArgSet *set=0) const
Definition: RooAbsReal.h:64
#define cxcoutD(a)
Definition: RooMsgService.h:80
virtual PdfCacheElem * createCache(const RooArgSet *nset) const
RooChangeTracker * _paramTracker
virtual const char * inputBaseName() const =0
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
T * getObjByIndex(Int_t index) const
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
STL namespace.
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
virtual TString histNameSuffix() const
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
void clearCacheObject(PdfCacheElem &cache) const
Mark all bins of given cache as unitialized (value -1)
RooAbsPdf * getCachePdf(const RooArgSet &nset) const
void setValueDirty() const
Definition: RooAbsArg.h:439
virtual Double_t analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=0) const
Implements internal (analytical) integration capabilities.
void printCompactTree(const char *indent="", const char *fileName=0, const char *namePat=0, RooAbsArg *client=0)
Print tree structure of expression tree on stdout, or to file if filename is specified.
Definition: RooAbsArg.cxx:1782
void Class()
Definition: Class.C:29
virtual Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet, const char *rangeName=0) const
Advertises internal (analytical) integration capabilities.
virtual ~RooAbsCachedPdf()
Destructor.
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=0, const TNamed *isetRangeName=0)
TString & Append(const char *cs)
Definition: TString.h:492
friend class RooArgSet
Definition: RooAbsArg.h:469
Bool_t _disableCache
Map for analytical integration codes.
friend class RooHistPdf
Definition: RooAbsArg.h:509
Int_t cacheSize() const
virtual Bool_t isFundamental() const
Definition: RooAbsArg.h:157
virtual const char * payloadUniqueSuffix() const
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
virtual const char * binningName() const
virtual Bool_t forceAnalyticalInt(const RooAbsArg &dep) const
Force RooRealIntegral to offer all our actual observable for internal integration.
virtual Double_t getValV(const RooArgSet *set=0) const
Implementation of getVal() overriding default implementation of RooAbsPdf.
virtual Double_t getValV(const RooArgSet *set=0) const
Return current value, normalizated by integrating over the observables in &#39;nset&#39;. ...
Definition: RooAbsPdf.cxx:252
RooAICRegistry _anaReg
RooAbsReal * _norm
Definition: RooAbsPdf.h:301
Int_t getSize() const
RooArgSet parameters() const
virtual void add(const RooArgSet &row, Double_t wgt=1.0)
Definition: RooDataHist.h:65
RooExpensiveObjectCache & expensiveObjectCache() const
Definition: RooAbsArg.cxx:2341
RooDataHist * getCacheHist(const RooArgSet &nset) const
virtual void fillCacheObject(PdfCacheElem &cache) const =0
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
char * Form(const char *fmt,...)
void removeSelfFromDir()
Definition: RooDataHist.h:131
static void indent(ostringstream &buf, int indent_level)
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...
#define ClassImp(name)
Definition: Rtypes.h:279
double Double_t
Definition: RtypesCore.h:55
Bool_t haveUnitNorm() const
Definition: RooHistPdf.h:71
static RooMathCoreReg dummy
TString cacheNameSuffix(const RooArgSet &nset) const
Construct string with unique suffix for cache objects based on observable names that define cache con...
virtual void printCompactTreeHook(std::ostream &, const char *, Int_t, Int_t)
Print contents of cache when printing self as part of object tree.
#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.
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...
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()
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.
Int_t getInterpolationOrder() const
float value
Definition: math.cpp:443
virtual Double_t volume(const char *rangeName) const =0
const std::vector< Int_t > & retrieve(Int_t masterCode) const
Retrieve the array of integer codes associated with the given master code.
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