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