Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
17Abstract 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"
37
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
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/// Retrieve cache object associated with given choice of observables. If cache object
108/// does not exist, create and fill and register it on the fly. If recalculate=false
109/// recalculation of cache contents of existing caches that are marked dirty due to
110/// dependent parameter changes is suppressed.
111
113{
114 // Check if this configuration was created becfore
115 int sterileIdx = -1 ;
116 auto cache = static_cast<PdfCacheElem*>(_cacheMgr.getObj(nset,nullptr,&sterileIdx));
117
118 // Check if we have a cache histogram in the global expensive object cache
119 if (cache) {
120 if (cache->paramTracker()->hasChanged(true) && (recalculate || !cache->pdf()->haveUnitNorm()) ) {
121 cxcoutD(Eval) << "RooAbsCachedPdf::getCache(" << GetName() << ") cache " << cache << " pdf "
122 << cache->pdf()->GetName() << " requires recalculation as parameters changed" << std::endl ;
123 fillCacheObject(*cache) ;
124 cache->pdf()->setValueDirty() ;
125 }
126 return cache ;
127 }
128
129 // Create and fill cache
130 cache = createCache(nset) ;
131
132 // Check if we have contents registered already in global expensive object cache
133 auto histTmp = static_cast<RooDataHist const*>(expensiveObjectCache().retrieveObject(cache->hist()->GetName(),RooDataHist::Class(),cache->paramTracker()->parameters()));
134
135 if (histTmp) {
136
137 cache->hist()->reset() ;
138 cache->hist()->add(*histTmp) ;
139
140 } else {
141
142 fillCacheObject(*cache) ;
143
144 auto eoclone = new RooDataHist(*cache->hist()) ;
145 eoclone->removeSelfFromDir() ;
146 expensiveObjectCache().registerObject(GetName(),cache->hist()->GetName(),*eoclone,cache->paramTracker()->parameters()) ;
147
148 }
149
150
151 // Store this cache configuration
152 int code = _cacheMgr.setObj(nset,nullptr,(static_cast<RooAbsCacheElement*>(cache)),nullptr) ;
153
154 coutI(Caching) << "RooAbsCachedPdf::getCache(" << GetName() << ") creating new cache " << cache << " with pdf "
155 << cache->pdf()->GetName() << " for nset " << (nset?*nset:RooArgSet()) << " with code " << code ;
156 if (histTmp) {
157 ccoutI(Caching) << " from preexisting content." ;
158 }
159 ccoutI(Caching) << std::endl ;
160
161 return cache ;
162}
163
164
165
166
167////////////////////////////////////////////////////////////////////////////////
168/// Constructor of cache object which owns RooDataHist cache histogram,
169/// RooHistPdf pdf that represents is shape and RooChangeTracker meta
170/// object that tracks changes in listed dependent parameter of cache.
171
173{
174 // Create cache object itself -- Default implementation is a RooHistPdf
175 std::unique_ptr<RooArgSet> nset2{self.actualObservables(nsetIn?*nsetIn:RooArgSet())};
176
178 if (nset2) {
179 self.preferredObservableScanOrder(*nset2,orderedObs) ;
180 }
181
182 // Create RooDataHist
183 auto hname = std::string(self.GetName()) + "_" + self.inputBaseName() + "_CACHEHIST"
184 + self.cacheNameSuffix(orderedObs) + self.histNameSuffix().Data();
185 _hist = std::make_unique<RooDataHist>(hname,hname,orderedObs,self.binningName()) ;
186 _hist->removeSelfFromDir() ;
187
188 //RooArgSet* observables= self.getObservables(orderedObs) ;
189 // std::cout << "orderedObs = " << orderedObs << " observables = " << *observables << std::endl ;
190
191 // Get set of p.d.f. observable corresponding to set of histogram observables
194 for(auto const& harg : orderedObs) {
195 RooAbsArg& po = self.pdfObservable(*harg) ;
196 pdfObs.add(po) ;
197 if (po.isFundamental()) {
198 pdfFinalObs.add(po) ;
199 } else {
200 pdfFinalObs.add(*std::unique_ptr<RooArgSet>(po.getVariables()));
201 }
202 }
203
204 // Create RooHistPdf
205 auto pdfname = std::string(self.inputBaseName()) + "_CACHE" + self.cacheNameSuffix(pdfFinalObs);
206 // add a different name when cache is built in case nsetIn is not an empty list
207 if (nsetIn && !nsetIn->empty()) {
208 pdfname += "_NORM";
209 for (auto *arg : *nsetIn)
210 pdfname += std::string("_") + arg->GetName();
211 }
212 _pdf = std::make_unique<RooHistPdf>(pdfname.c_str(),pdfname.c_str(),pdfObs,orderedObs,*_hist,self.getInterpolationOrder()) ;
213 if (nsetIn) {
215 }
216
217 // Create pseudo-object that tracks changes in parameter values
218
219 std::unique_ptr<RooArgSet> params{self.actualParameters(pdfFinalObs)};
220 params->remove(pdfFinalObs,true,true) ;
221
222 auto name = std::string(_pdf->GetName()) + "_CACHEPARAMS";
223 _paramTracker = std::make_unique<RooChangeTracker>(name.c_str(),name.c_str(),*params,true) ;
224 _paramTracker->hasChanged(true) ; // clear dirty flag as cache is up-to-date upon creation
225
226 // Introduce formal dependency of RooHistPdf on parameters so that const optimization code
227 // makes the correct decisions
228 _pdf->addServerList(*params) ;
229
230 // Set initial state of cache to dirty
231 _pdf->setValueDirty() ;
232}
233
234
235
236////////////////////////////////////////////////////////////////////////////////
237/// Construct string with unique suffix for cache objects based on
238/// observable names that define cache configuration
239
240std::string RooAbsCachedPdf::cacheNameSuffix(const RooArgSet& nset) const
241{
242 std::string name = "_Obs[";
243 if (!nset.empty()) {
244 bool first(true) ;
245 for(auto const& arg : nset) {
246 if (first) {
247 first=false ;
248 } else {
249 name += ",";
250 }
251 name += arg->GetName();
252 }
253 }
254
255 name += "]";
256 if (const char* payloadUS = payloadUniqueSuffix()) {
257 name += payloadUS;
258 }
259 return name ;
260}
261
262
263
264////////////////////////////////////////////////////////////////////////////////
265/// Change the interpolation order that is used in RooHistPdf cache
266/// representation smoothing the RooDataHist shapes.
267
269{
270 _ipOrder = order ;
271
272 for (int i=0 ; i<_cacheMgr.cacheSize() ; i++) {
273 if (auto cache = static_cast<PdfCacheElem*>(_cacheMgr.getObjByIndex(i))) {
274 cache->pdf()->setInterpolationOrder(order) ;
275 }
276 }
277}
278
279
280
281////////////////////////////////////////////////////////////////////////////////
282/// Returns all RooAbsArg objects contained in the cache element
283
285{
286 RooArgList ret(*_pdf) ;
287 ret.add(*_paramTracker) ;
288 if (_norm) ret.add(*_norm) ;
289 return ret ;
290}
291
292
293////////////////////////////////////////////////////////////////////////////////
294/// Print contents of cache when printing self as part of object tree
295
297{
298 if (curElem==0) {
299 os << indent << "--- RooAbsCachedPdf begin cache ---" << std::endl ;
300 }
301
302 os << "[" << curElem << "]" << " Configuration for observables " << _nset << std::endl;
303 auto indent2 = std::string(indent) + "[" + std::to_string(curElem) + "]";
304 _pdf->printCompactTree(os,indent2.c_str()) ;
305 if (_norm) {
306 os << "[" << curElem << "] Norm ";
308 }
309
310 if (curElem==maxElem) {
311 os << indent << "--- RooAbsCachedPdf end cache --- " << std::endl ;
312 }
313}
314
315
316
317////////////////////////////////////////////////////////////////////////////////
318/// Force RooRealIntegral to offer all our actual observable for internal
319/// integration
320
322{
323 return !std::unique_ptr<RooArgSet>{actualObservables(dep)}->empty();
324}
325
326
327
328////////////////////////////////////////////////////////////////////////////////
329/// Advertises internal (analytical) integration capabilities. Call
330/// is forwarded to RooHistPdf cache p.d.f of cache that is used for
331/// given choice of observables
332
334{
335 if (allVars.empty()) {
336 return 0 ;
337 }
338
339 PdfCacheElem* cache = getCache(normSet?normSet:&allVars) ;
340 int code = cache->pdf()->getAnalyticalIntegralWN(allVars,analVars,normSet,rangeName) ;
341
342 if (code==0) {
343 return 0 ;
344 }
345
346 RooArgSet* all = new RooArgSet ;
347 RooArgSet* ana = new RooArgSet ;
348 RooArgSet* nrm = new RooArgSet ;
349 all->addClone(allVars) ;
350 ana->addClone(analVars) ;
351 if (normSet) {
352 nrm->addClone(*normSet) ;
353 }
354 std::vector<int> codeList(2);
355 codeList[0] = code ;
356 codeList[1] = cache->pdf()->haveUnitNorm() ? 1 : 0 ;
357 int masterCode = _anaReg.store(codeList,all,ana,nrm)+1 ; // takes ownership of all sets
358
359
360 // Mark all observables as internally integrated
361 if (cache->pdf()->haveUnitNorm()) {
362 analVars.add(allVars,true) ;
363 }
364
365 return masterCode ;
366}
367
368
369
370////////////////////////////////////////////////////////////////////////////////
371/// Implements internal (analytical) integration capabilities. Call
372/// is forwarded to RooHistPdf cache p.d.f of cache that is used for
373/// given choice of observables
374
375double RooAbsCachedPdf::analyticalIntegralWN(int code, const RooArgSet* normSet, const char* rangeName) const
376{
377 if (code==0) {
378 return getVal(normSet) ;
379 }
380
381 RooArgSet *allVars(nullptr);
382 RooArgSet *anaVars(nullptr);
383 RooArgSet *normSet2(nullptr);
384 RooArgSet *dummy(nullptr);
385 const std::vector<int> codeList = _anaReg.retrieve(code-1,allVars,anaVars,normSet2,dummy) ;
386
388 double ret = cache->pdf()->analyticalIntegralWN(codeList[0],normSet,rangeName) ;
389
390 if (codeList[1]>0) {
391 RooArgSet factObs(*allVars) ;
392 factObs.remove(*anaVars,true,true) ;
393 for(auto * arg : dynamic_range_cast<RooAbsLValue*>(factObs)) {
394 ret *= arg->volume(rangeName) ;
395 }
396 }
397
398 return ret ;
399}
400
401
406
407
408std::unique_ptr<RooAbsArg>
410{
411 if (normSet.empty()) {
413 }
414 std::unique_ptr<RooAbsPdf> pdfClone(static_cast<RooAbsPdf *>(this->Clone()));
415 ctx.compileServers(*pdfClone, {});
416
417 auto newArg = std::make_unique<RooFit::Detail::RooNormalizedPdf>(*pdfClone, normSet);
418
419 // The direct servers are this pdf and the normalization integral, which
420 // don't need to be compiled further.
421 for (RooAbsArg *server : newArg->servers()) {
423 }
425 newArg->addOwnedComponents(std::move(pdfClone));
426 return newArg;
427}
#define coutI(a)
#define cxcoutD(a)
#define ccoutI(a)
static void indent(ostringstream &buf, int indent_level)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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
@ kName
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=nullptr, RooArgSet *set2=nullptr, RooArgSet *set3=nullptr, RooArgSet *set4=nullptr)
Store given arrays of integer codes, and up to four RooArgSets in the registry (each setX pointer may...
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
RooExpensiveObjectCache & expensiveObjectCache() const
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
Definition RooAbsArg.h:89
Abstract base class for objects to be stored in RooAbsCache cache manager objects.
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
Abstract base class for p.d.f.s that need or want to cache their evaluate() output in a RooHistPdf de...
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 RooFit::OwningPtr< RooArgSet > actualObservables(const RooArgSet &nset) const =0
RooAICRegistry _anaReg
! Registry for analytical integration codes
bool forceAnalyticalInt(const RooAbsArg &dep) const override
Force RooRealIntegral to offer all our actual observable for internal integration.
RooAbsPdf * getCachePdf(const RooArgSet &nset) const
RooDataHist * getCacheHist(const RooArgSet &nset) const
std::unique_ptr< RooAbsArg > compileForNormSet(RooArgSet const &normSet, RooFit::Detail::CompileContext &ctx) const override
bool _disableCache
Flag to run object in passthrough (= non-caching mode)
virtual void fillCacheObject(PdfCacheElem &cache) const =0
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
std::string cacheNameSuffix(const RooArgSet &nset) const
Construct string with unique suffix for cache objects based on observable names that define cache con...
void doEval(RooFit::EvalContext &) const override
Base function for computing multiple values of a RooAbsReal.
void setInterpolationOrder(int order)
Change the interpolation order that is used in RooHistPdf cache representation smoothing the RooDataH...
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:40
std::unique_ptr< RooAbsArg > compileForNormSet(RooArgSet const &normSet, RooFit::Detail::CompileContext &ctx) const override
double getValV(const RooArgSet *set=nullptr) const override
Return current value, normalized by integrating over the observables in nset.
RooArgSet const * _normSet
Normalization integral (owned by _normMgr)
Definition RooAbsPdf.h:320
RooAbsReal * _norm
Definition RooAbsPdf.h:319
double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Analytical integral with normalization (see RooAbsReal::analyticalIntegralWN() for further informatio...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
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 ...
double _value
Cache for current value of object.
Definition RooAbsReal.h:535
virtual void doEval(RooFit::EvalContext &) const
Base function for computing multiple values of a RooAbsReal.
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:24
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.
Container class to hold N-dimensional binned data.
Definition RooDataHist.h:40
static TClass * Class()
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,...
void markAsCompiled(RooAbsArg &arg) const
void compileServers(RooAbsArg &arg, RooArgSet const &normSet)
bool haveUnitNorm() const
Definition RooHistPdf.h:82
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:49