Logo ROOT  
Reference Guide
RooProdGenContext.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 RooProdGenContext.cxx
19\class RooProdGenContext
20\ingroup Roofitcore
21
22RooProdGenContext is an efficient implementation of the generator context
23specific for RooProdPdf PDFs. The sim-context owns a list of
24component generator contexts that are used to generate the dependents
25for each component PDF sequentially.
26**/
27
28#include "RooFit.h"
29#include "Riostream.h"
30#include "RooMsgService.h"
31
32#include "RooProdGenContext.h"
33#include "RooProdPdf.h"
34#include "RooDataSet.h"
35#include "RooRealVar.h"
36#include "RooGlobalFunc.h"
37
38
39
40using namespace std;
41
43;
44
45
46////////////////////////////////////////////////////////////////////////////////
47
49 const RooDataSet *prototype, const RooArgSet* auxProto, Bool_t verbose) :
50 RooAbsGenContext(model,vars,prototype,auxProto,verbose), _uniIter(0), _pdf(&model)
51{
52 // Constructor of optimization generator context for RooProdPdf objects
53
54 //Build an array of generator contexts for each product component PDF
55 cxcoutI(Generation) << "RooProdGenContext::ctor() setting up event special generator context for product p.d.f. " << model.GetName()
56 << " for generation of observable(s) " << vars ;
57 if (prototype) ccxcoutI(Generation) << " with prototype data for " << *prototype->get() ;
58 if (auxProto && auxProto->getSize()>0) ccxcoutI(Generation) << " with auxiliary prototypes " << *auxProto ;
59 ccxcoutI(Generation) << endl ;
60
61 // Make full list of dependents (generated & proto)
62 RooArgSet deps(vars) ;
63 if (prototype) {
64 RooArgSet* protoDeps = model.getObservables(*prototype->get()) ;
65 deps.remove(*protoDeps,kTRUE,kTRUE) ;
66 delete protoDeps ;
67 }
68
69 // Factorize product in irreducible terms
70 RooLinkedList termList,depsList,impDepList,crossDepList,intList ;
71 model.factorizeProduct(deps,RooArgSet(),termList,depsList,impDepList,crossDepList,intList) ;
72 TIterator* termIter = termList.MakeIterator() ;
73 TIterator* normIter = depsList.MakeIterator() ;
74 TIterator* impIter = impDepList.MakeIterator() ;
75
76 if (dologD(Generation)) {
77 cxcoutD(Generation) << "RooProdGenContext::ctor() factorizing product expression in irriducible terms " ;
78 while(RooArgSet* t=(RooArgSet*)termIter->Next()) {
79 ccxcoutD(Generation) << *t ;
80 }
81 ccxcoutD(Generation) << endl ;
82 }
83
84 RooArgSet genDeps ;
85 // First add terms that do not import observables
86
87 Bool_t anyAction = kTRUE ;
88 Bool_t go=kTRUE ;
89 while(go) {
90
91 RooAbsPdf* pdf ;
92 RooArgSet* term ;
93 RooArgSet* impDeps ;
94 RooArgSet* termDeps ;
95
96 termIter->Reset() ;
97 impIter->Reset() ;
98 normIter->Reset() ;
99
100 Bool_t anyPrevAction=anyAction ;
101 anyAction=kFALSE ;
102
103 if (termList.GetSize()==0) {
104 break ;
105 }
106
107 while((term=(RooArgSet*)termIter->Next())) {
108
109 impDeps = (RooArgSet*)impIter->Next() ;
110 termDeps = (RooArgSet*)normIter->Next() ;
111 if (impDeps==0 || termDeps==0) {
112 break ;
113 }
114
115 cxcoutD(Generation) << "RooProdGenContext::ctor() analyzing product term " << *term << " with observable(s) " << *termDeps ;
116 if (impDeps->getSize()>0) {
117 ccxcoutD(Generation) << " which has dependence of external observable(s) " << *impDeps << " that to be generated first by other terms" ;
118 }
119 ccxcoutD(Generation) << endl ;
120
121 // Add this term if we have no imported dependents, or imported dependents are already generated
122 RooArgSet neededDeps(*impDeps) ;
123 neededDeps.remove(genDeps,kTRUE,kTRUE) ;
124
125 if (neededDeps.getSize()>0) {
126 if (!anyPrevAction) {
127 cxcoutD(Generation) << "RooProdGenContext::ctor() no convergence in single term analysis loop, terminating loop and process remainder of terms as single unit " << endl ;
128 go=kFALSE ;
129 break ;
130 }
131 cxcoutD(Generation) << "RooProdGenContext::ctor() skipping this term for now because it needs imported dependents that are not generated yet" << endl ;
132 continue ;
133 }
134
135 // Check if this component has any dependents that need to be generated
136 // e.g. it can happen that there are none if all dependents of this component are prototyped
137 if (termDeps->getSize()==0) {
138 cxcoutD(Generation) << "RooProdGenContext::ctor() term has no observables requested to be generated, removing it" << endl ;
139 termList.Remove(term) ;
140 depsList.Remove(termDeps) ;
141 impDepList.Remove(impDeps) ;
142 delete term ;
143 delete termDeps ;
144 delete impDeps ;
145 anyAction=kTRUE ;
146 continue ;
147 }
148
149 TIterator* pdfIter = term->createIterator() ;
150 if (term->getSize()==1) {
151 // Simple term
152
153 pdf = (RooAbsPdf*) pdfIter->Next() ;
154 RooArgSet* pdfDep = pdf->getObservables(termDeps) ;
155 if (pdfDep->getSize()>0) {
156 coutI(Generation) << "RooProdGenContext::ctor() creating subcontext for generation of observables " << *pdfDep << " from model " << pdf->GetName() << endl ;
157 RooArgSet* auxProto2 = pdf->getObservables(impDeps) ;
158 RooAbsGenContext* cx = pdf->genContext(*pdfDep,prototype,auxProto2,verbose) ;
159 delete auxProto2 ;
160 _gcList.push_back(cx) ;
161 }
162
163// cout << "adding following dependents to list of generated observables: " ; pdfDep->Print("1") ;
164 genDeps.add(*pdfDep) ;
165
166 delete pdfDep ;
167
168 } else {
169
170 // Composite term
171 if (termDeps->getSize()>0) {
172 const std::string name = model.makeRGPPName("PRODGEN_",*term,RooArgSet(),RooArgSet(),0) ;
173
174 // Construct auxiliary PDF expressing product of composite terms,
175 // following Conditional component specification of input model
176 RooLinkedList cmdList ;
177 RooLinkedList pdfSetList ;
178 pdfIter->Reset() ;
179 RooArgSet fullPdfSet ;
180 while((pdf=(RooAbsPdf*)pdfIter->Next())) {
181
182 RooArgSet* pdfnset = model.findPdfNSet(*pdf) ;
183 RooArgSet* pdfSet = new RooArgSet(*pdf) ;
184 pdfSetList.Add(pdfSet) ;
185
186 if (pdfnset && pdfnset->getSize()>0) {
187 // This PDF requires a Conditional() construction
188 cmdList.Add(RooFit::Conditional(*pdfSet,*pdfnset).Clone()) ;
189// cout << "Conditional " << pdf->GetName() << " " ; pdfnset->Print("1") ;
190 } else {
191 fullPdfSet.add(*pdfSet) ;
192 }
193
194 }
195 RooProdPdf* multiPdf = new RooProdPdf(name.c_str(),name.c_str(),fullPdfSet,cmdList) ;
196 cmdList.Delete() ;
197 pdfSetList.Delete() ;
198
200 multiPdf->useDefaultGen(kTRUE) ;
201 _ownedMultiProds.addOwned(*multiPdf) ;
202
203 coutI(Generation) << "RooProdGenContext()::ctor creating subcontext for generation of observables " << *termDeps
204 << "for irriducuble composite term using sub-product object " << multiPdf->GetName() ;
205 RooAbsGenContext* cx = multiPdf->genContext(*termDeps,prototype,auxProto,verbose) ;
206 _gcList.push_back(cx) ;
207
208 genDeps.add(*termDeps) ;
209
210 }
211 }
212
213 delete pdfIter ;
214
215// cout << "added generator for this term, removing from list" << endl ;
216
217 termList.Remove(term) ;
218 depsList.Remove(termDeps) ;
219 impDepList.Remove(impDeps) ;
220 delete term ;
221 delete termDeps ;
222 delete impDeps ;
223 anyAction=kTRUE ;
224 }
225 }
226
227 // Check if there are any left over terms that cannot be generated
228 // separately due to cross dependency of observables
229 if (termList.GetSize()>0) {
230
231 cxcoutD(Generation) << "RooProdGenContext::ctor() there are left-over terms that need to be generated separately" << endl ;
232
233 RooAbsPdf* pdf ;
234 RooArgSet* term ;
235
236 // Concatenate remaining terms
237 termIter->Reset() ;
238 normIter->Reset() ;
239 RooArgSet trailerTerm ;
240 RooArgSet trailerTermDeps ;
241 while((term=(RooArgSet*)termIter->Next())) {
242 RooArgSet* termDeps = (RooArgSet*)normIter->Next() ;
243 trailerTerm.add(*term) ;
244 trailerTermDeps.add(*termDeps) ;
245 }
246
247 const std::string name = model.makeRGPPName("PRODGEN_",trailerTerm,RooArgSet(),RooArgSet(),0) ;
248
249 // Construct auxiliary PDF expressing product of composite terms,
250 // following Partial/Full component specification of input model
251 RooLinkedList cmdList ;
252 RooLinkedList pdfSetList ;
253 RooArgSet fullPdfSet ;
254
255 TIterator* pdfIter = trailerTerm.createIterator() ;
256 while((pdf=(RooAbsPdf*)pdfIter->Next())) {
257
258 RooArgSet* pdfnset = model.findPdfNSet(*pdf) ;
259 RooArgSet* pdfSet = new RooArgSet(*pdf) ;
260 pdfSetList.Add(pdfSet) ;
261
262 if (pdfnset && pdfnset->getSize()>0) {
263 // This PDF requires a Conditional() construction
264 cmdList.Add(RooFit::Conditional(*pdfSet,*pdfnset).Clone()) ;
265 } else {
266 fullPdfSet.add(*pdfSet) ;
267 }
268
269 }
270// cmdList.Print("v") ;
271 RooProdPdf* multiPdf = new RooProdPdf(name.c_str(),name.c_str(),fullPdfSet,cmdList) ;
272 cmdList.Delete() ;
273 pdfSetList.Delete() ;
274
276 multiPdf->useDefaultGen(kTRUE) ;
277 _ownedMultiProds.addOwned(*multiPdf) ;
278
279 cxcoutD(Generation) << "RooProdGenContext(" << model.GetName() << "): creating context for irreducible composite trailer term "
280 << multiPdf->GetName() << " that generates observables " << trailerTermDeps << endl ;
281 RooAbsGenContext* cx = multiPdf->genContext(trailerTermDeps,prototype,auxProto,verbose) ;
282 _gcList.push_back(cx) ;
283 }
284
285 // Now check if the are observables in vars that are not generated by any of the above p.d.f.s
286 // If not, generate uniform distributions for these using a special context
287 _uniObs.add(vars) ;
288 _uniObs.remove(genDeps,kTRUE,kTRUE) ;
289 if (_uniObs.getSize()>0) {
291 coutI(Generation) << "RooProdGenContext(" << model.GetName() << "): generating uniform distribution for non-dependent observable(s) " << _uniObs << endl ;
292 }
293
294
295 delete termIter ;
296 delete impIter ;
297 delete normIter ;
298
299
300 // We own contents of lists filled by factorizeProduct()
301 termList.Delete() ;
302 depsList.Delete() ;
303 impDepList.Delete() ;
304 crossDepList.Delete() ;
305 intList.Delete() ;
306
307}
308
309
310
311////////////////////////////////////////////////////////////////////////////////
312/// Destructor. Delete all owned subgenerator contexts
313
315{
316 delete _uniIter ;
317 for (list<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
318 delete (*iter) ;
319 }
320}
321
322
323////////////////////////////////////////////////////////////////////////////////
324/// Attach generator to given event buffer
325
327{
328 //Forward initGenerator call to all components
329 for (list<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
330 (*iter)->attach(args) ;
331 }
332}
333
334
335////////////////////////////////////////////////////////////////////////////////
336/// One-time initialization of generator context, forward to component generators
337
339{
340 // Forward initGenerator call to all components
341 for (list<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
342 (*iter)->initGenerator(theEvent) ;
343 }
344}
345
346
347
348////////////////////////////////////////////////////////////////////////////////
349/// Generate a single event of the product by generating the components
350/// of the products sequentially. The subcontext have been order such
351/// that all conditional dependencies are correctly taken into account
352/// when processed in sequential order
353
355{
356 // Loop over the component generators
357
358 for (list<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
359 (*iter)->generateEvent(theEvent,remaining) ;
360 }
361
362 // Generate uniform variables (non-dependents)
363 if (_uniIter) {
364 _uniIter->Reset() ;
365 RooAbsArg* uniVar ;
366 while((uniVar=(RooAbsArg*)_uniIter->Next())) {
367 RooAbsLValue* arglv = dynamic_cast<RooAbsLValue*>(uniVar) ;
368 if (arglv) {
369 arglv->randomize() ;
370 }
371 }
372 theEvent.assign(_uniObs) ;
373 }
374
375}
376
377
378
379////////////////////////////////////////////////////////////////////////////////
380/// Set the traversal order of the prototype dataset by the
381/// given lookup table
382
384{
385 // Forward call to component generators
387
388 for (list<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
389 (*iter)->setProtoDataOrder(lut) ;
390 }
391
392}
393
394
395
396////////////////////////////////////////////////////////////////////////////////
397/// Detailed printing interface
398
400{
402 os << indent << "--- RooProdGenContext ---" << endl ;
403 os << indent << "Using PDF ";
405 os << indent << "List of component generators" << endl ;
406
407 TString indent2(indent) ;
408 indent2.Append(" ") ;
409
410 for (list<RooAbsGenContext*>::const_iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
411 (*iter)->printMultiline(os,content,verbose,indent2) ;
412 }
413}
#define coutI(a)
Definition: RooMsgService.h:30
#define cxcoutI(a)
Definition: RooMsgService.h:85
#define cxcoutD(a)
Definition: RooMsgService.h:81
#define dologD(a)
Definition: RooMsgService.h:65
#define ccxcoutD(a)
Definition: RooMsgService.h:82
#define ccxcoutI(a)
Definition: RooMsgService.h:86
int Int_t
Definition: RtypesCore.h:45
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:364
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition: TGX11.cxx:110
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:72
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Given a set of possible observables, return the observables that this PDF depends on.
Definition: RooAbsArg.h:295
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Set the operation mode of this node.
Definition: RooAbsArg.cxx:1819
Int_t getSize() const
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
virtual Bool_t addOwned(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.
TIterator * createIterator(Bool_t dir=kIterForward) const
TIterator-style iteration over contained elements.
RooAbsGenContext is the abstract base class for generator contexts of RooAbsPdf objects.
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Interface for multi-line printing.
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of prototype data to that in the lookup tables passed as argument.
Abstract base class for objects that are lvalues, i.e.
Definition: RooAbsLValue.h:26
virtual void randomize(const char *rangeName=0)=0
virtual RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE) const
Interface function to create a generator context from a p.d.f.
Definition: RooAbsPdf.cxx:1972
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:35
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:36
virtual const RooArgSet * get(Int_t index) const override
Return RooArgSet with coordinates of event 'index'.
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Definition: RooLinkedList.h:38
Int_t GetSize() const
Definition: RooLinkedList.h:63
TIterator * MakeIterator(Bool_t forward=kTRUE) const
Create a TIterator for this list.
void Delete(Option_t *o=0)
Remove all elements in collection and delete all elements NB: Collection does not own elements,...
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:67
virtual Bool_t Remove(TObject *arg)
Remove object from collection.
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,...
RooProdGenContext is an efficient implementation of the generator context specific for RooProdPdf PDF...
RooArgSet _ownedMultiProds
std::list< RooAbsGenContext * > _gcList
virtual void attach(const RooArgSet &params)
Attach generator to given event buffer.
const RooProdPdf * _pdf
RooProdGenContext(const RooProdPdf &model, const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t _verbose=kFALSE)
virtual void generateEvent(RooArgSet &theEvent, Int_t remaining)
Generate a single event of the product by generating the components of the products sequentially.
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of the prototype dataset by the given lookup table.
virtual void initGenerator(const RooArgSet &theEvent)
One-time initialization of generator context, forward to component generators.
virtual void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Detailed printing interface.
virtual ~RooProdGenContext()
Destructor. Delete all owned subgenerator contexts.
RooProdPdf is an efficient implementation of a product of PDFs of the form.
Definition: RooProdPdf.h:37
void factorizeProduct(const RooArgSet &normSet, const RooArgSet &intSet, RooLinkedList &termList, RooLinkedList &normList, RooLinkedList &impDepList, RooLinkedList &crossDepList, RooLinkedList &intList) const
Factorize product in irreducible terms for given choice of integration/normalization.
Definition: RooProdPdf.cxx:597
void useDefaultGen(Bool_t flag=kTRUE)
Definition: RooProdPdf.h:176
std::string makeRGPPName(const char *pfx, const RooArgSet &term, const RooArgSet &iset, const RooArgSet &nset, const char *isetRangeName) const
Make an appropriate automatic name for a RooGenProdProj object in getPartIntList()
RooArgSet * findPdfNSet(RooAbsPdf &pdf) const
Look up user specified normalization set for given input PDF component.
virtual RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE) const
Return generator context optimized for generating events from product p.d.f.s.
Iterator abstract base class.
Definition: TIterator.h:30
virtual void Reset()=0
virtual TObject * Next()=0
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:74
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Basic string class.
Definition: TString.h:136
TString & Append(const char *cs)
Definition: TString.h:564
RooCmdArg Conditional(const RooArgSet &pdfSet, const RooArgSet &depSet, Bool_t depsAreCond=kFALSE)
@ Generation
Definition: RooGlobalFunc.h:60