Logo ROOT  
Reference Guide
RooAddGenContext.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17/**
18\file RooAddGenContext.cxx
19\class RooAddGenContext
20\ingroup Roofitcore
21
22RooAddGenContext is an efficient implementation of the
23generator context specific for RooAddPdf PDFs. The strategy
24of RooAddGenContext is to defer generation of each component
25to a dedicated generator context for that component and to
26randomly choose one of those context to generate an event,
27with a probability proportional to its associated coefficient.
28**/
29
30#include "Riostream.h"
31#include "TClass.h"
32
33#include "RooMsgService.h"
34#include "RooAddGenContext.h"
35#include "RooAddPdf.h"
36#include "RooDataSet.h"
37#include "RooRandom.h"
38#include "RooAddModel.h"
39
40using namespace std;
41
43;
44
45
46////////////////////////////////////////////////////////////////////////////////
47/// Constructor
48
50 const RooDataSet *prototype, const RooArgSet* auxProto,
52 RooAbsGenContext(model,vars,prototype,auxProto,verbose), _isModel(kFALSE)
53{
54 cxcoutI(Generation) << "RooAddGenContext::ctor() setting up event special generator context for sum p.d.f. " << model.GetName()
55 << " for generation of observable(s) " << vars ;
56 if (prototype) ccxcoutI(Generation) << " with prototype data for " << *prototype->get() ;
57 if (auxProto && auxProto->getSize()>0) ccxcoutI(Generation) << " with auxiliary prototypes " << *auxProto ;
58 ccxcoutI(Generation) << endl ;
59
60 // Constructor. Build an array of generator contexts for each product component PDF
62 _pdf = (RooAddPdf*) _pdfSet->find(model.GetName()) ;
64
65 // Fix normalization set of this RooAddPdf
66 if (prototype)
67 {
68 RooArgSet coefNSet(vars) ;
69 coefNSet.add(*prototype->get()) ;
71 }
72
73 _nComp = model._pdfList.getSize() ;
74 _coefThresh = new Double_t[_nComp+1] ;
75 _vars = (RooArgSet*) vars.snapshot(kFALSE) ;
76
77 for (const auto arg : model._pdfList) {
78 auto pdf = dynamic_cast<const RooAbsPdf *>(arg);
79 if (!pdf) {
80 coutF(Generation) << "Cannot generate events from an object that is not a PDF.\n\t"
81 << "The offending object is a " << arg->IsA()->GetName() << " named '" << arg->GetName() << "'." << std::endl;
82 throw std::invalid_argument("Trying to generate events from on object that is not a PDF.");
83 }
84
85 RooAbsGenContext* cx = pdf->genContext(vars,prototype,auxProto,verbose) ;
86 _gcList.push_back(cx) ;
87 }
88
89 ((RooAddPdf*)_pdf)->getProjCache(_vars) ;
91
92 _mcache = 0 ;
93 _pcache = 0 ;
94}
95
96
97
98////////////////////////////////////////////////////////////////////////////////
99/// Constructor
100
102 const RooDataSet *prototype, const RooArgSet* auxProto,
103 Bool_t verbose) :
104 RooAbsGenContext(model,vars,prototype,auxProto,verbose), _isModel(kTRUE)
105{
106 cxcoutI(Generation) << "RooAddGenContext::ctor() setting up event special generator context for sum resolution model " << model.GetName()
107 << " for generation of observable(s) " << vars ;
108 if (prototype) ccxcoutI(Generation) << " with prototype data for " << *prototype->get() ;
109 if (auxProto && auxProto->getSize()>0) ccxcoutI(Generation) << " with auxiliary prototypes " << *auxProto ;
110 ccxcoutI(Generation) << endl ;
111
112 // Constructor. Build an array of generator contexts for each product component PDF
114 _pdf = (RooAbsPdf*) _pdfSet->find(model.GetName()) ;
115
116 _nComp = model._pdfList.getSize() ;
117 _coefThresh = new Double_t[_nComp+1] ;
118 _vars = (RooArgSet*) vars.snapshot(kFALSE) ;
119
120 for (const auto obj : model._pdfList) {
121 auto pdf = static_cast<RooAbsPdf*>(obj);
122 RooAbsGenContext* cx = pdf->genContext(vars,prototype,auxProto,verbose) ;
123 _gcList.push_back(cx) ;
124 }
125
126 ((RooAddModel*)_pdf)->getProjCache(_vars) ;
128
129 _mcache = 0 ;
130 _pcache = 0 ;
131}
132
133
134
135////////////////////////////////////////////////////////////////////////////////
136/// Destructor. Delete all owned subgenerator contexts
137
139{
140 delete[] _coefThresh ;
141 for (vector<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
142 delete *iter ;
143 }
144 delete _vars ;
145 delete _pdfSet ;
146}
147
148
149
150////////////////////////////////////////////////////////////////////////////////
151/// Attach given set of variables to internal p.d.f. clone
152
154{
156
157 // Forward initGenerator call to all components
158 for (vector<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
159 (*iter)->attach(args) ;
160 }
161}
162
163
164
165////////////////////////////////////////////////////////////////////////////////
166/// One-time initialization of generator contex. Attach theEvent
167/// to internal p.d.f clone and forward initialization call to
168/// the component generators
169
171{
172 _pdf->recursiveRedirectServers(theEvent) ;
173
174 if (_isModel) {
175 RooAddModel* amod = (RooAddModel*) _pdf ;
176 _mcache = amod->getProjCache(_vars) ;
177 } else {
178 RooAddPdf* apdf = (RooAddPdf*) _pdf ;
179 _pcache = apdf->getProjCache(_vars,0,"FULL_RANGE_ADDGENCONTEXT") ;
180 }
181
182 // Forward initGenerator call to all components
183 for (vector<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
184 (*iter)->initGenerator(theEvent) ;
185 }
186}
187
188
189////////////////////////////////////////////////////////////////////////////////
190/// Randomly choose one of the component contexts to generate this event,
191/// with a probability proportional to its coefficient
192
194{
195 // Throw a random number to determin which component to generate
198 Int_t i=0 ;
199 for (i=0 ; i<_nComp ; i++) {
200 if (rand>_coefThresh[i] && rand<_coefThresh[i+1]) {
201 _gcList[i]->generateEvent(theEvent,remaining) ;
202 return ;
203 }
204 }
205}
206
207
208////////////////////////////////////////////////////////////////////////////////
209/// Update the cumulative threshold table from the current coefficient
210/// values
211
213{
214 if (_isModel) {
215
216 RooAddModel* amod = (RooAddModel*) _pdf ;
218
219 _coefThresh[0] = 0. ;
220 Int_t i ;
221 for (i=0 ; i<_nComp ; i++) {
222 _coefThresh[i+1] = amod->_coefCache[i] ;
223 _coefThresh[i+1] += _coefThresh[i] ;
224 }
225
226 } else {
227
228 RooAddPdf* apdf = (RooAddPdf*) _pdf ;
229
231
232 _coefThresh[0] = 0. ;
233 Int_t i ;
234 for (i=0 ; i<_nComp ; i++) {
235 _coefThresh[i+1] = apdf->_coefCache[i] ;
236 _coefThresh[i+1] += _coefThresh[i] ;
237// cout << "RooAddGenContext::updateThresholds(" << GetName() << ") _coefThresh[" << i+1 << "] = " << _coefThresh[i+1] << endl ;
238 }
239
240 }
241
242}
243
244
245////////////////////////////////////////////////////////////////////////////////
246/// Forward the setProtoDataOrder call to the component generator contexts
247
249{
251 for (vector<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
252 (*iter)->setProtoDataOrder(lut) ;
253 }
254}
255
256
257
258////////////////////////////////////////////////////////////////////////////////
259/// Print the details of the context
260
262{
264 os << indent << "--- RooAddGenContext ---" << endl ;
265 os << indent << "Using PDF ";
267
268 os << indent << "List of component generators" << endl ;
269 TString indent2(indent) ;
270 indent2.Append(" ") ;
271 for (vector<RooAbsGenContext*>::const_iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
272 (*iter)->printMultiline(os,content,verbose,indent2) ;
273 }
274}
#define cxcoutI(a)
Definition: RooMsgService.h:85
#define coutF(a)
Definition: RooMsgService.h:34
#define ccxcoutI(a)
Definition: RooMsgService.h:86
const Bool_t kFALSE
Definition: RtypesCore.h:101
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:375
static void indent(ostringstream &buf, int indent_level)
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Set the operation mode of this node.
Definition: RooAbsArg.cxx:1876
Bool_t recursiveRedirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t recurseInNewSet=kTRUE)
Recursively replace all servers with the new servers in newSet.
Definition: RooAbsArg.cxx:1197
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
Int_t getSize() const
Return the number of elements in the collection.
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsGenContext is the abstract base class for generator contexts of RooAbsPdf objects.
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const override
Interface for multi-line printing.
RooArgSet _theEvent
Pointer to observable event being generated.
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of prototype data to that in the lookup tables passed as argument.
virtual void fixAddCoefNormalization(const RooArgSet &addNormSet=RooArgSet(), Bool_t force=kTRUE)
Fix the interpretation of the coefficient of any RooAddPdf component in the expression tree headed by...
RooAddGenContext is an efficient implementation of the generator context specific for RooAddPdf PDFs.
void setProtoDataOrder(Int_t *lut) override
Forward the setProtoDataOrder call to the component generator contexts.
RooAddGenContext(const RooAddPdf &model, const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t _verbose=kFALSE)
Constructor.
Bool_t _isModel
Are we generating from a RooAddPdf or a RooAddModel.
void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const override
Print the details of the context.
void initGenerator(const RooArgSet &theEvent) override
One-time initialization of generator contex.
void updateThresholds()
Update the cumulative threshold table from the current coefficient values.
std::vector< RooAbsGenContext * > _gcList
List of component generator contexts.
RooArgSet * _pdfSet
Set owned all nodes of internal clone of p.d.f.
~RooAddGenContext() override
Destructor. Delete all owned subgenerator contexts.
RooAddModel::CacheElem * _mcache
! RooAddModel cache element
Double_t * _coefThresh
[_nComp] Array of coefficient thresholds
void attach(const RooArgSet &params) override
Attach given set of variables to internal p.d.f. clone.
Int_t _nComp
Number of PDF components.
RooAddPdf::CacheElem * _pcache
! RooAddPdf cache element
RooAbsPdf * _pdf
Pointer to cloned p.d.f.
void generateEvent(RooArgSet &theEvent, Int_t remaining) override
Randomly choose one of the component contexts to generate this event, with a probability proportional...
const RooArgSet * _vars
RooAddModel is an efficient implementation of a sum of PDFs of the form.
Definition: RooAddModel.h:26
CacheElem * getProjCache(const RooArgSet *nset, const RooArgSet *iset=0, const char *rangeName=0) const
Retrieve cache element with for calculation of p.d.f value with normalization set nset and integrated...
void updateCoefficients(CacheElem &cache, const RooArgSet *nset) const
Update the coefficient values in the given cache element: calculate new remainder fraction,...
RooListProxy _pdfList
List of component PDFs.
Definition: RooAddModel.h:131
Double_t * _coefCache
! Transiet cache with transformed values of coefficients
Definition: RooAddModel.h:97
RooAddPdf is an efficient implementation of a sum of PDFs of the form.
Definition: RooAddPdf.h:32
void updateCoefficients(CacheElem &cache, const RooArgSet *nset) const
Update the coefficient values in the given cache element: calculate new remainder fraction,...
Definition: RooAddPdf.cxx:580
CacheElem * getProjCache(const RooArgSet *nset, const RooArgSet *iset=0, const char *rangeName=0) const
Manager of cache with coefficient projections and transformations.
Definition: RooAddPdf.cxx:366
RooListProxy _pdfList
List of component PDFs.
Definition: RooAddPdf.h:140
std::vector< double > _coefCache
! Transient cache with transformed values of coefficients
Definition: RooAddPdf.h:102
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:57
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition: RooArgSet.h:180
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:55
const RooArgSet * get(Int_t index) const override
Return RooArgSet with coordinates of event 'index'.
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,...
static Double_t uniform(TRandom *generator=randomGenerator())
Return a number uniformly distributed from (0,1)
Definition: RooRandom.cxx:81
const char * GetName() const override
Returns name of object.
Definition: TNamed.h:47
Basic string class.
Definition: TString.h:136
TString & Append(const char *cs)
Definition: TString.h:564
@ Generation
Definition: RooGlobalFunc.h:63