Logo ROOT  
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\file RooAbsCachedPdf.cxx
14\class RooAbsCachedPdf
15\ingroup Roofitcore
16
17RooAbsCachedPdf is the abstract base class for p.d.f.s that need or
18want to cache their evaluate() output in a RooHistPdf defined in
19terms of the used observables. This base class manages the creation
20and storage of all RooHistPdf cache p.d.fs and the RooDataHists
21that define their shape. Implementations of RooAbsCachedPdf must
22define member function fillCacheObject() which serves to fill an
23already created RooDataHist with the p.d.fs function values. In
24addition the member functions actualObservables() and
25actualParameters() must be define which report what the actual
26observables to be cached are for a given set of observables passed
27by the user to getVal() and on which parameters need to be tracked
28for changes to trigger a refilling of the cache histogram.
29**/
30
31#include "RooAbsCachedPdf.h"
32#include "RooMsgService.h"
33#include "RooDataHist.h"
34#include "RooHistPdf.h"
36
38
39
40
41////////////////////////////////////////////////////////////////////////////////
42/// Constructor
43
44RooAbsCachedPdf::RooAbsCachedPdf(const char *name, const char *title, int ipOrder) :
45 RooAbsPdf(name,title),
46 _cacheMgr(this,10),
47 _ipOrder(ipOrder)
48 {
49 }
50
51
52
53////////////////////////////////////////////////////////////////////////////////
54/// Copy constructor
55
57 RooAbsPdf(other,name),
58 _cacheMgr(other._cacheMgr,this),
59 _ipOrder(other._ipOrder),
60 _disableCache(other._disableCache)
61 {
62 }
63
64
65////////////////////////////////////////////////////////////////////////////////
66/// Implementation of getVal() overriding default implementation
67/// of RooAbsPdf. Return normalized value stored in cache p.d.f
68/// rather than return value of evaluate() which is undefined
69/// for RooAbsCachedPdf
70
71double RooAbsCachedPdf::getValV(const RooArgSet* nset) const
72{
73 if (_disableCache) {
74 return RooAbsPdf::getValV(nset) ;
75 }
76
77 // Calculate current unnormalized value of object
78 return _value = getCache(nset)->pdf()->getVal(nset) ;
79}
80
81
82
83////////////////////////////////////////////////////////////////////////////////
84/// Return pointer to RooHistPdf cache pdf for given choice of observables
85
87{
88 PdfCacheElem* cache = getCache(nset) ;
89 return cache ? cache->pdf() : nullptr;
90}
91
92
93////////////////////////////////////////////////////////////////////////////////
94/// Return pointer to RooDataHist cache histogram for given choice of observables
95
97{
98 PdfCacheElem* cache = getCache(nset) ;
99 return cache ? cache->hist() : nullptr;
100}
101
102
103////////////////////////////////////////////////////////////////////////////////
104/// Mark all bins of given cache as unitialized (value -1)
105
107{
108 cache.hist()->setAllWeights(-1) ;
109}
110
111
112
113////////////////////////////////////////////////////////////////////////////////
114/// Retrieve cache object associated with given choice of observables. If cache object
115/// does not exist, create and fill and register it on the fly. If recalculate=false
116/// recalculation of cache contents of existing caches that are marked dirty due to
117/// dependent parameter changes is suppressed.
118
120{
121 // Check if this configuration was created becfore
122 int sterileIdx = -1 ;
123 auto cache = static_cast<PdfCacheElem*>(_cacheMgr.getObj(nset,0,&sterileIdx));
124
125 // Check if we have a cache histogram in the global expensive object cache
126 if (cache) {
127 if (cache->paramTracker()->hasChanged(true) && (recalculate || !cache->pdf()->haveUnitNorm()) ) {
128 cxcoutD(Eval) << "RooAbsCachedPdf::getCache(" << GetName() << ") cache " << cache << " pdf "
129 << cache->pdf()->GetName() << " requires recalculation as parameters changed" << std::endl ;
130 fillCacheObject(*cache) ;
131 cache->pdf()->setValueDirty() ;
132 }
133 return cache ;
134 }
135
136 // Create and fill cache
137 cache = createCache(nset) ;
138
139 // Check if we have contents registered already in global expensive object cache
140 auto htmp = static_cast<RooDataHist const*>(expensiveObjectCache().retrieveObject(cache->hist()->GetName(),RooDataHist::Class(),cache->paramTracker()->parameters()));
141
142 if (htmp) {
143
144 cache->hist()->reset() ;
145 cache->hist()->add(*htmp) ;
146
147 } else {
148
149 fillCacheObject(*cache) ;
150
151 auto eoclone = new RooDataHist(*cache->hist()) ;
152 eoclone->removeSelfFromDir() ;
153 expensiveObjectCache().registerObject(GetName(),cache->hist()->GetName(),*eoclone,cache->paramTracker()->parameters()) ;
154
155 }
156
157
158 // Store this cache configuration
159 int code = _cacheMgr.setObj(nset,0,(static_cast<RooAbsCacheElement*>(cache)),0) ;
160
161 coutI(Caching) << "RooAbsCachedPdf::getCache(" << GetName() << ") creating new cache " << cache << " with pdf "
162 << cache->pdf()->GetName() << " for nset " << (nset?*nset:RooArgSet()) << " with code " << code ;
163 if (htmp) {
164 ccoutI(Caching) << " from preexisting content." ;
165 }
166 ccoutI(Caching) << std::endl ;
167
168 return cache ;
169}
170
171
172
173
174////////////////////////////////////////////////////////////////////////////////
175/// Constructor of cache object which owns RooDataHist cache histogram,
176/// RooHistPdf pdf that represents is shape and RooChangeTracker meta
177/// object that tracks changes in listed dependent parameter of cache.
178
180{
181 // Create cache object itself -- Default implementation is a RooHistPdf
182 std::unique_ptr<RooArgSet> nset2{self.actualObservables(nsetIn?*nsetIn:RooArgSet())};
183
184 RooArgSet orderedObs ;
185 if (nset2) {
186 self.preferredObservableScanOrder(*nset2,orderedObs) ;
187 }
188
189 // Create RooDataHist
190 auto hname = std::string(self.GetName()) + "_" + self.inputBaseName() + "_CACHEHIST"
191 + self.cacheNameSuffix(orderedObs).c_str() + self.histNameSuffix().Data();
192 _hist = std::make_unique<RooDataHist>(hname,hname,orderedObs,self.binningName()) ;
193 _hist->removeSelfFromDir() ;
194
195 //RooArgSet* observables= self.getObservables(orderedObs) ;
196 // cout << "orderedObs = " << orderedObs << " observables = " << *observables << std::endl ;
197
198 // Get set of p.d.f. observable corresponding to set of histogram observables
199 RooArgSet pdfObs ;
200 RooArgSet pdfFinalObs ;
201 for(auto const& harg : orderedObs) {
202 RooAbsArg& po = self.pdfObservable(*harg) ;
203 pdfObs.add(po) ;
204 if (po.isFundamental()) {
205 pdfFinalObs.add(po) ;
206 } else {
207 pdfFinalObs.add(*std::unique_ptr<RooArgSet>(po.getVariables()));
208 }
209 }
210
211 // Create RooHistPdf
212 auto pdfname = std::string(self.inputBaseName()) + "_CACHE" + self.cacheNameSuffix(pdfFinalObs);
213 // add a different name when cache is built in case nsetIn is not an empty list
214 if (nsetIn && !nsetIn->empty()) {
215 pdfname += "_NORM";
216 for (auto *arg : *nsetIn)
217 pdfname += std::string("_") + arg->GetName();
218 }
219 _pdf = std::make_unique<RooHistPdf>(pdfname.c_str(),pdfname.c_str(),pdfObs,orderedObs,*_hist,self.getInterpolationOrder()) ;
220 if (nsetIn) {
221 _nset.addClone(*nsetIn) ;
222 }
223
224 // Create pseudo-object that tracks changes in parameter values
225
226 std::unique_ptr<RooArgSet> params{self.actualParameters(pdfFinalObs)};
227 params->remove(pdfFinalObs,true,true) ;
228
229 auto name = std::string(_pdf->GetName()) + "_CACHEPARAMS";
230 _paramTracker = std::make_unique<RooChangeTracker>(name.c_str(),name.c_str(),*params,true) ;
231 _paramTracker->hasChanged(true) ; // clear dirty flag as cache is up-to-date upon creation
232
233 // Introduce formal dependency of RooHistPdf on parameters so that const optimization code
234 // makes the correct decisions
235 _pdf->addServerList(*params) ;
236
237 // Set initial state of cache to dirty
238 _pdf->setValueDirty() ;
239}
240
241
242
243////////////////////////////////////////////////////////////////////////////////
244/// Construct string with unique suffix for cache objects based on
245/// observable names that define cache configuration
246
247std::string RooAbsCachedPdf::cacheNameSuffix(const RooArgSet& nset) const
248{
249 std::string name = "_Obs[";
250 if (!nset.empty()) {
251 bool first(true) ;
252 for(auto const& arg : nset) {
253 if (first) {
254 first=false ;
255 } else {
256 name += ",";
257 }
258 name += arg->GetName();
259 }
260 }
261
262 name += "]";
263 if (const char* payloadUS = payloadUniqueSuffix()) {
264 name += payloadUS;
265 }
266 return name ;
267}
268
269
270
271////////////////////////////////////////////////////////////////////////////////
272/// Change the interpolation order that is used in RooHistPdf cache
273/// representation smoothing the RooDataHist shapes.
274
276{
277 _ipOrder = order ;
278
279 for (int i=0 ; i<_cacheMgr.cacheSize() ; i++) {
280 if (auto cache = static_cast<PdfCacheElem*>(_cacheMgr.getObjByIndex(i))) {
281 cache->pdf()->setInterpolationOrder(order) ;
282 }
283 }
284}
285
286
287
288////////////////////////////////////////////////////////////////////////////////
289/// Returns all RooAbsArg objects contained in the cache element
290
292{
293 RooArgList ret(*_pdf) ;
294 ret.add(*_paramTracker) ;
295 if (_norm) ret.add(*_norm) ;
296 return ret ;
297}
298
299
300////////////////////////////////////////////////////////////////////////////////
301/// Print contents of cache when printing self as part of object tree
302
303void RooAbsCachedPdf::PdfCacheElem::printCompactTreeHook(std::ostream& os, const char* indent, int curElem, int maxElem)
304{
305 if (curElem==0) {
306 os << indent << "--- RooAbsCachedPdf begin cache ---" << std::endl ;
307 }
308
309 os << "[" << curElem << "]" << " Configuration for observables " << _nset << std::endl;
310 auto indent2 = std::string(indent) + "[" + std::to_string(curElem) + "]";
311 _pdf->printCompactTree(os,indent2.c_str()) ;
312 if (_norm) {
313 os << "[" << curElem << "] Norm ";
315 }
316
317 if (curElem==maxElem) {
318 os << indent << "--- RooAbsCachedPdf end cache --- " << std::endl ;
319 }
320}
321
322
323
324////////////////////////////////////////////////////////////////////////////////
325/// Force RooRealIntegral to offer all our actual observable for internal
326/// integration
327
329{
330 return !std::unique_ptr<RooArgSet>{actualObservables(dep)}->empty();
331}
332
333
334
335////////////////////////////////////////////////////////////////////////////////
336/// Advertises internal (analytical) integration capabilities. Call
337/// is forwarded to RooHistPdf cache p.d.f of cache that is used for
338/// given choice of observables
339
340int RooAbsCachedPdf::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars, const RooArgSet* normSet, const char* rangeName) const
341{
342 if (allVars.empty()) {
343 return 0 ;
344 }
345
346 PdfCacheElem* cache = getCache(normSet?normSet:&allVars) ;
347 int code = cache->pdf()->getAnalyticalIntegralWN(allVars,analVars,normSet,rangeName) ;
348
349 if (code==0) {
350 return 0 ;
351 }
352
353 RooArgSet* all = new RooArgSet ;
354 RooArgSet* ana = new RooArgSet ;
355 RooArgSet* nrm = new RooArgSet ;
356 all->addClone(allVars) ;
357 ana->addClone(analVars) ;
358 if (normSet) {
359 nrm->addClone(*normSet) ;
360 }
361 std::vector<int> codeList(2);
362 codeList[0] = code ;
363 codeList[1] = cache->pdf()->haveUnitNorm() ? 1 : 0 ;
364 int masterCode = _anaReg.store(codeList,all,ana,nrm)+1 ; // takes ownership of all sets
365
366
367 // Mark all observables as internally integrated
368 if (cache->pdf()->haveUnitNorm()) {
369 analVars.add(allVars,true) ;
370 }
371
372 return masterCode ;
373}
374
375
376
377////////////////////////////////////////////////////////////////////////////////
378/// Implements internal (analytical) integration capabilities. Call
379/// is forwarded to RooHistPdf cache p.d.f of cache that is used for
380/// given choice of observables
381
382double RooAbsCachedPdf::analyticalIntegralWN(int code, const RooArgSet* normSet, const char* rangeName) const
383{
384 if (code==0) {
385 return getVal(normSet) ;
386 }
387
388 RooArgSet *allVars(0),*anaVars(0),*normSet2(0),*dummy(0) ;
389 const std::vector<int> codeList = _anaReg.retrieve(code-1,allVars,anaVars,normSet2,dummy) ;
390
391 PdfCacheElem* cache = getCache(normSet2?normSet2:anaVars,false) ;
392 double ret = cache->pdf()->analyticalIntegralWN(codeList[0],normSet,rangeName) ;
393
394 if (codeList[1]>0) {
395 RooArgSet factObs(*allVars) ;
396 factObs.remove(*anaVars,true,true) ;
397 for(auto * arg : dynamic_range_cast<RooAbsLValue*>(factObs)) {
398 ret *= arg->volume(rangeName) ;
399 }
400 }
401
402 return ret ;
403}
void Class()
Definition: Class.C:29
#define coutI(a)
Definition: RooMsgService.h:30
#define cxcoutD(a)
Definition: RooMsgService.h:81
#define ccoutI(a)
Definition: RooMsgService.h:38
#define ClassImp(name)
Definition: Rtypes.h:364
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition: TGX11.cxx:110
const std::vector< Int_t > & retrieve(Int_t masterCode) const
Retrieve the array of integer codes associated with the given master code.
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...
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:72
RooExpensiveObjectCache & expensiveObjectCache() const
Definition: RooAbsArg.cxx:2279
friend class RooArgSet
Definition: RooAbsArg.h:600
virtual Bool_t isFundamental() const
Is this object a fundamental type that can be added to a dataset? Fundamental-type subclasses overrid...
Definition: RooAbsArg.h:243
RooArgSet * getVariables(Bool_t stripDisconnected=kTRUE) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
Definition: RooAbsArg.cxx:2010
RooAbsCacheElement is the abstract base class for objects to be stored in RooAbsCache cache manager o...
virtual RooArgList containedArgs(Action)
Returns all RooAbsArg objects contained in the cache element.
std::unique_ptr< RooChangeTracker > _paramTracker
PdfCacheElem(const RooAbsCachedPdf &self, const RooArgSet *nset)
Constructor of cache object which owns RooDataHist cache histogram, RooHistPdf pdf that represents is...
std::unique_ptr< RooHistPdf > _pdf
virtual void printCompactTreeHook(std::ostream &, const char *, Int_t, Int_t)
Print contents of cache when printing self as part of object tree.
std::unique_ptr< RooDataHist > _hist
RooAbsCachedPdf is the abstract base class for p.d.f.s that need or want to cache their evaluate() ou...
Int_t getInterpolationOrder() const
virtual RooAbsArg & pdfObservable(RooAbsArg &histObservable) const
virtual PdfCacheElem * createCache(const RooArgSet *nset) const
PdfCacheElem * getCache(const RooArgSet *nset, bool recalculate=true) const
Retrieve cache object associated with given choice of observables.
virtual RooArgSet * actualParameters(const RooArgSet &nset) const =0
RooAICRegistry _anaReg
virtual TString histNameSuffix() const
virtual const char * binningName() const
virtual const char * inputBaseName() const =0
virtual bool forceAnalyticalInt(const RooAbsArg &dep) const
Force RooRealIntegral to offer all our actual observable for internal integration.
virtual Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet, const char *rangeName=nullptr) const
Advertises internal (analytical) integration capabilities.
RooAbsPdf * getCachePdf(const RooArgSet &nset) const
RooDataHist * getCacheHist(const RooArgSet &nset) const
bool _disableCache
Map for analytical integration codes.
virtual void fillCacheObject(PdfCacheElem &cache) const =0
void clearCacheObject(PdfCacheElem &cache) const
Mark all bins of given cache as unitialized (value -1)
virtual double getValV(const RooArgSet *set=nullptr) const
Implementation of getVal() overriding default implementation of RooAbsPdf.
RooObjCacheManager _cacheMgr
Int_t _ipOrder
The cache manager
virtual const char * payloadUniqueSuffix() const
virtual RooArgSet * actualObservables(const RooArgSet &nset) const =0
virtual double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=nullptr) const
Implements internal (analytical) integration capabilities.
std::string cacheNameSuffix(const RooArgSet &nset) const
Construct string with unique suffix for cache objects based on observable names that define cache con...
void setInterpolationOrder(int order)
Change the interpolation order that is used in RooHistPdf cache representation smoothing the RooDataH...
bool empty() const
virtual RooAbsArg * addClone(const RooAbsArg &var, Bool_t silent=kFALSE)
Add a clone of the specified argument to list.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
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:413
RooAbsReal * _norm
Definition: RooAbsPdf.h:351
virtual Double_t getValV(const RooArgSet *set=0) const
Return current value, normalized by integrating over the observables in nset.
Definition: RooAbsPdf.cxx:283
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:385
Double_t _value
Definition: RooAbsReal.h:477
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:91
virtual void preferredObservableScanOrder(const RooArgSet &obs, RooArgSet &orderedObs) const
Interface method for function objects to indicate their preferred order of observables for scanning t...
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:22
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:35
Int_t cacheSize() const
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=0, const TNamed *isetRangeName=0)
T * getObjByIndex(Int_t index) const
Retrieve payload object by slot index.
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=0)
The RooDataHist is a container class to hold N-dimensional binned data.
Definition: RooDataHist.h:44
void setAllWeights(Double_t value)
Set all the event weight of all bins to the specified value.
void reset() override
Reset all bin weights to zero.
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...
const TObject * retrieveObject(const char *name, TClass *tclass, const RooArgSet &params)
Retrieve object from cache that was registered under given name with given parameters,...
Bool_t haveUnitNorm() const
Definition: RooHistPdf.h:86
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,...
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
const char * Data() const
Definition: TString.h:369
Definition: first.py:1