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 auto * cachedPdf = getCache(nset)->pdf();
79 double value = cachedPdf->getVal(nset) ;
80 _norm = cachedPdf->_norm;
81 return _value = value ;
82}
83
84
85
86////////////////////////////////////////////////////////////////////////////////
87/// Return pointer to RooHistPdf cache pdf for given choice of observables
88
90{
91 PdfCacheElem* cache = getCache(nset) ;
92 return cache ? cache->pdf() : nullptr;
93}
94
95
96////////////////////////////////////////////////////////////////////////////////
97/// Return pointer to RooDataHist cache histogram for given choice of observables
98
100{
101 PdfCacheElem* cache = getCache(nset) ;
102 return cache ? cache->hist() : nullptr;
103}
104
105
106////////////////////////////////////////////////////////////////////////////////
107/// Mark all bins of given cache as unitialized (value -1)
108
110{
111 cache.hist()->setAllWeights(-1) ;
112}
113
114
115
116////////////////////////////////////////////////////////////////////////////////
117/// Retrieve cache object associated with given choice of observables. If cache object
118/// does not exist, create and fill and register it on the fly. If recalculate=false
119/// recalculation of cache contents of existing caches that are marked dirty due to
120/// dependent parameter changes is suppressed.
121
123{
124 // Check if this configuration was created becfore
125 int sterileIdx = -1 ;
126 auto cache = static_cast<PdfCacheElem*>(_cacheMgr.getObj(nset,0,&sterileIdx));
127
128 // Check if we have a cache histogram in the global expensive object cache
129 if (cache) {
130 if (cache->paramTracker()->hasChanged(true) && (recalculate || !cache->pdf()->haveUnitNorm()) ) {
131 cxcoutD(Eval) << "RooAbsCachedPdf::getCache(" << GetName() << ") cache " << cache << " pdf "
132 << cache->pdf()->GetName() << " requires recalculation as parameters changed" << std::endl ;
133 fillCacheObject(*cache) ;
134 cache->pdf()->setValueDirty() ;
135 }
136 return cache ;
137 }
138
139 // Create and fill cache
140 cache = createCache(nset) ;
141
142 // Check if we have contents registered already in global expensive object cache
143 auto htmp = static_cast<RooDataHist const*>(expensiveObjectCache().retrieveObject(cache->hist()->GetName(),RooDataHist::Class(),cache->paramTracker()->parameters()));
144
145 if (htmp) {
146
147 cache->hist()->reset() ;
148 cache->hist()->add(*htmp) ;
149
150 } else {
151
152 fillCacheObject(*cache) ;
153
154 auto eoclone = new RooDataHist(*cache->hist()) ;
155 eoclone->removeSelfFromDir() ;
156 expensiveObjectCache().registerObject(GetName(),cache->hist()->GetName(),*eoclone,cache->paramTracker()->parameters()) ;
157
158 }
159
160
161 // Store this cache configuration
162 int code = _cacheMgr.setObj(nset,0,(static_cast<RooAbsCacheElement*>(cache)),0) ;
163
164 coutI(Caching) << "RooAbsCachedPdf::getCache(" << GetName() << ") creating new cache " << cache << " with pdf "
165 << cache->pdf()->GetName() << " for nset " << (nset?*nset:RooArgSet()) << " with code " << code ;
166 if (htmp) {
167 ccoutI(Caching) << " from preexisting content." ;
168 }
169 ccoutI(Caching) << std::endl ;
170
171 return cache ;
172}
173
174
175
176
177////////////////////////////////////////////////////////////////////////////////
178/// Constructor of cache object which owns RooDataHist cache histogram,
179/// RooHistPdf pdf that represents is shape and RooChangeTracker meta
180/// object that tracks changes in listed dependent parameter of cache.
181
183{
184 // Create cache object itself -- Default implementation is a RooHistPdf
185 std::unique_ptr<RooArgSet> nset2{self.actualObservables(nsetIn?*nsetIn:RooArgSet())};
186
187 RooArgSet orderedObs ;
188 if (nset2) {
189 self.preferredObservableScanOrder(*nset2,orderedObs) ;
190 }
191
192 // Create RooDataHist
193 auto hname = std::string(self.GetName()) + "_" + self.inputBaseName() + "_CACHEHIST"
194 + self.cacheNameSuffix(orderedObs).c_str() + self.histNameSuffix().Data();
195 _hist = std::make_unique<RooDataHist>(hname,hname,orderedObs,self.binningName()) ;
196 _hist->removeSelfFromDir() ;
197
198 //RooArgSet* observables= self.getObservables(orderedObs) ;
199 // cout << "orderedObs = " << orderedObs << " observables = " << *observables << std::endl ;
200
201 // Get set of p.d.f. observable corresponding to set of histogram observables
202 RooArgSet pdfObs ;
203 RooArgSet pdfFinalObs ;
204 for(auto const& harg : orderedObs) {
205 RooAbsArg& po = self.pdfObservable(*harg) ;
206 pdfObs.add(po) ;
207 if (po.isFundamental()) {
208 pdfFinalObs.add(po) ;
209 } else {
210 pdfFinalObs.add(*std::unique_ptr<RooArgSet>(po.getVariables()));
211 }
212 }
213
214 // Create RooHistPdf
215 auto pdfname = std::string(self.inputBaseName()) + "_CACHE" + self.cacheNameSuffix(pdfFinalObs);
216 // add a different name when cache is built in case nsetIn is not an empty list
217 if (nsetIn && !nsetIn->empty()) {
218 pdfname += "_NORM";
219 for (auto *arg : *nsetIn)
220 pdfname += std::string("_") + arg->GetName();
221 }
222 _pdf = std::make_unique<RooHistPdf>(pdfname.c_str(),pdfname.c_str(),pdfObs,orderedObs,*_hist,self.getInterpolationOrder()) ;
223 if (nsetIn) {
224 _nset.addClone(*nsetIn) ;
225 }
226
227 // Create pseudo-object that tracks changes in parameter values
228
229 std::unique_ptr<RooArgSet> params{self.actualParameters(pdfFinalObs)};
230 params->remove(pdfFinalObs,true,true) ;
231
232 auto name = std::string(_pdf->GetName()) + "_CACHEPARAMS";
233 _paramTracker = std::make_unique<RooChangeTracker>(name.c_str(),name.c_str(),*params,true) ;
234 _paramTracker->hasChanged(true) ; // clear dirty flag as cache is up-to-date upon creation
235
236 // Introduce formal dependency of RooHistPdf on parameters so that const optimization code
237 // makes the correct decisions
238 _pdf->addServerList(*params) ;
239
240 // Set initial state of cache to dirty
241 _pdf->setValueDirty() ;
242}
243
244
245
246////////////////////////////////////////////////////////////////////////////////
247/// Construct string with unique suffix for cache objects based on
248/// observable names that define cache configuration
249
250std::string RooAbsCachedPdf::cacheNameSuffix(const RooArgSet& nset) const
251{
252 std::string name = "_Obs[";
253 if (!nset.empty()) {
254 bool first(true) ;
255 for(auto const& arg : nset) {
256 if (first) {
257 first=false ;
258 } else {
259 name += ",";
260 }
261 name += arg->GetName();
262 }
263 }
264
265 name += "]";
266 if (const char* payloadUS = payloadUniqueSuffix()) {
267 name += payloadUS;
268 }
269 return name ;
270}
271
272
273
274////////////////////////////////////////////////////////////////////////////////
275/// Change the interpolation order that is used in RooHistPdf cache
276/// representation smoothing the RooDataHist shapes.
277
279{
280 _ipOrder = order ;
281
282 for (int i=0 ; i<_cacheMgr.cacheSize() ; i++) {
283 if (auto cache = static_cast<PdfCacheElem*>(_cacheMgr.getObjByIndex(i))) {
284 cache->pdf()->setInterpolationOrder(order) ;
285 }
286 }
287}
288
289
290
291////////////////////////////////////////////////////////////////////////////////
292/// Returns all RooAbsArg objects contained in the cache element
293
295{
296 RooArgList ret(*_pdf) ;
297 ret.add(*_paramTracker) ;
298 if (_norm) ret.add(*_norm) ;
299 return ret ;
300}
301
302
303////////////////////////////////////////////////////////////////////////////////
304/// Print contents of cache when printing self as part of object tree
305
306void RooAbsCachedPdf::PdfCacheElem::printCompactTreeHook(std::ostream& os, const char* indent, int curElem, int maxElem)
307{
308 if (curElem==0) {
309 os << indent << "--- RooAbsCachedPdf begin cache ---" << std::endl ;
310 }
311
312 os << "[" << curElem << "]" << " Configuration for observables " << _nset << std::endl;
313 auto indent2 = std::string(indent) + "[" + std::to_string(curElem) + "]";
314 _pdf->printCompactTree(os,indent2.c_str()) ;
315 if (_norm) {
316 os << "[" << curElem << "] Norm ";
318 }
319
320 if (curElem==maxElem) {
321 os << indent << "--- RooAbsCachedPdf end cache --- " << std::endl ;
322 }
323}
324
325
326
327////////////////////////////////////////////////////////////////////////////////
328/// Force RooRealIntegral to offer all our actual observable for internal
329/// integration
330
332{
333 return !std::unique_ptr<RooArgSet>{actualObservables(dep)}->empty();
334}
335
336
337
338////////////////////////////////////////////////////////////////////////////////
339/// Advertises internal (analytical) integration capabilities. Call
340/// is forwarded to RooHistPdf cache p.d.f of cache that is used for
341/// given choice of observables
342
343int RooAbsCachedPdf::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars, const RooArgSet* normSet, const char* rangeName) const
344{
345 if (allVars.empty()) {
346 return 0 ;
347 }
348
349 PdfCacheElem* cache = getCache(normSet?normSet:&allVars) ;
350 int code = cache->pdf()->getAnalyticalIntegralWN(allVars,analVars,normSet,rangeName) ;
351
352 if (code==0) {
353 return 0 ;
354 }
355
356 RooArgSet* all = new RooArgSet ;
357 RooArgSet* ana = new RooArgSet ;
358 RooArgSet* nrm = new RooArgSet ;
359 all->addClone(allVars) ;
360 ana->addClone(analVars) ;
361 if (normSet) {
362 nrm->addClone(*normSet) ;
363 }
364 std::vector<int> codeList(2);
365 codeList[0] = code ;
366 codeList[1] = cache->pdf()->haveUnitNorm() ? 1 : 0 ;
367 int masterCode = _anaReg.store(codeList,all,ana,nrm)+1 ; // takes ownership of all sets
368
369
370 // Mark all observables as internally integrated
371 if (cache->pdf()->haveUnitNorm()) {
372 analVars.add(allVars,true) ;
373 }
374
375 return masterCode ;
376}
377
378
379
380////////////////////////////////////////////////////////////////////////////////
381/// Implements internal (analytical) integration capabilities. Call
382/// is forwarded to RooHistPdf cache p.d.f of cache that is used for
383/// given choice of observables
384
385double RooAbsCachedPdf::analyticalIntegralWN(int code, const RooArgSet* normSet, const char* rangeName) const
386{
387 if (code==0) {
388 return getVal(normSet) ;
389 }
390
391 RooArgSet *allVars(0),*anaVars(0),*normSet2(0),*dummy(0) ;
392 const std::vector<int> codeList = _anaReg.retrieve(code-1,allVars,anaVars,normSet2,dummy) ;
393
394 PdfCacheElem* cache = getCache(normSet2?normSet2:anaVars,false) ;
395 double ret = cache->pdf()->analyticalIntegralWN(codeList[0],normSet,rangeName) ;
396
397 if (codeList[1]>0) {
398 RooArgSet factObs(*allVars) ;
399 factObs.remove(*anaVars,true,true) ;
400 for(auto * arg : dynamic_range_cast<RooAbsLValue*>(factObs)) {
401 ret *= arg->volume(rangeName) ;
402 }
403 }
404
405 return ret ;
406}
407
408
409void RooAbsCachedPdf::computeBatch(cudaStream_t* stream, double* output, size_t nEvents, RooFit::Detail::DataMap const& dataMap) const
410{
411 auto * cachePdf = getCachePdf(_normSet);
412 cachePdf->computeBatch(stream, output, nEvents, dataMap);
413}
#define coutI(a)
Definition: RooMsgService.h:34
#define cxcoutD(a)
Definition: RooMsgService.h:85
#define ccoutI(a)
Definition: RooMsgService.h:42
#define ClassImp(name)
Definition: Rtypes.h:375
static void indent(ostringstream &buf, int indent_level)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
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:71
RooExpensiveObjectCache & expensiveObjectCache() const
Definition: RooAbsArg.cxx:2271
RooArgSet * getVariables(bool stripDisconnected=true) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
Definition: RooAbsArg.cxx:2057
virtual bool isFundamental() const
Is this object a fundamental type that can be added to a dataset? Fundamental-type subclasses overrid...
Definition: RooAbsArg.h:241
RooAbsCacheElement is the abstract base class for objects to be stored in RooAbsCache cache manager o...
RooArgList containedArgs(Action) override
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...
void printCompactTreeHook(std::ostream &, const char *, Int_t, Int_t) override
Print contents of cache when printing self as part of object tree.
std::unique_ptr< RooHistPdf > _pdf
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
Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Advertises internal (analytical) integration capabilities.
double getValV(const RooArgSet *set=nullptr) const override
Implementation of getVal() overriding default implementation of RooAbsPdf.
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
! Registry for analytical integration codes
virtual TString histNameSuffix() const
virtual const char * binningName() const
bool forceAnalyticalInt(const RooAbsArg &dep) const override
Force RooRealIntegral to offer all our actual observable for internal integration.
virtual const char * inputBaseName() const =0
void computeBatch(cudaStream_t *, double *output, size_t size, RooFit::Detail::DataMap const &) const override
Base function for computing multiple values of a RooAbsReal.
RooAbsPdf * getCachePdf(const RooArgSet &nset) const
RooDataHist * getCacheHist(const RooArgSet &nset) const
bool _disableCache
Flag to run object in passthrough (= non-caching mode)
virtual void fillCacheObject(PdfCacheElem &cache) const =0
void clearCacheObject(PdfCacheElem &cache) const
Mark all bins of given cache as unitialized (value -1)
RooObjCacheManager _cacheMgr
double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Implements internal (analytical) integration capabilities.
Int_t _ipOrder
The cache manager.
virtual const char * payloadUniqueSuffix() const
virtual RooArgSet * actualObservables(const RooArgSet &nset) const =0
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...
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
bool empty() const
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
double getValV(const RooArgSet *set=nullptr) const override
Return current value, normalized by integrating over the observables in nset.
Definition: RooAbsPdf.cxx:353
RooArgSet const * _normSet
Normalization integral (owned by _normMgr)
Definition: RooAbsPdf.h:359
RooAbsReal * _norm
Definition: RooAbsPdf.h:358
double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Analytical integral with normalization (see RooAbsReal::analyticalIntegralWN() for further informatio...
Definition: RooAbsPdf.cxx:424
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:91
virtual Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet, const char *rangeName=nullptr) const
Variant of getAnalyticalIntegral that is also passed the normalization set that should be applied to ...
Definition: RooAbsReal.cxx:364
double _value
Cache for current value of object.
Definition: RooAbsReal.h:480
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:56
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=nullptr)
Setter function without integration set.
Int_t cacheSize() const
Return size of cache.
T * getObjByIndex(Int_t index) const
Retrieve payload object by slot index.
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=nullptr, const TNamed *isetRangeName=nullptr)
Getter function without integration set.
The RooDataHist is a container class to hold N-dimensional binned data.
Definition: RooDataHist.h:45
void setAllWeights(double value)
Set all the event weight of all bins to the specified value.
static TClass * Class()
void reset() override
Reset all bin weights to zero.
bool registerObject(const char *ownerName, const char *objectName, TObject &cacheObject, const RooArgSet &params)
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 haveUnitNorm() const
Definition: RooHistPdf.h:91
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,...
const char * GetName() const override
Returns name of object.
Definition: TNamed.h:47
const char * Data() const
Definition: TString.h:369
Definition: first.py:1
static void output()