ROOT  6.06/08
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 //
19 // BEGIN_HTML
20 // RooProdGenContext is an efficient implementation of the generator context
21 // specific for RooProdPdf PDFs. The sim-context owns a list of
22 // component generator contexts that are used to generate the dependents
23 // for each component PDF sequentially.
24 // END_HTML
25 //
26 
27 #include "RooFit.h"
28 #include "Riostream.h"
29 #include "RooMsgService.h"
30 
31 #include "RooProdGenContext.h"
32 #include "RooProdGenContext.h"
33 #include "RooProdPdf.h"
34 #include "RooDataSet.h"
35 #include "RooRealVar.h"
36 #include "RooGlobalFunc.h"
37 
38 
39 
40 using 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 
199  multiPdf->setOperMode(RooAbsArg::ADirty,kTRUE) ;
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 
275  multiPdf->setOperMode(RooAbsArg::ADirty,kTRUE) ;
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 = _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 {
401  RooAbsGenContext::printMultiline(os,content,verbose,indent) ;
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 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
TIterator * createIterator(Bool_t dir=kIterForward) const
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, which is interpreted as an OR of &#39;enum ContentsOptions&#39; values and in the style given by &#39;enum StyleOption&#39;.
const RooProdPdf * _pdf
#define cxcoutI(a)
Definition: RooMsgService.h:84
virtual void Reset()=0
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Definition: RooAbsArg.h:194
virtual Bool_t Remove(TObject *arg)
Remove object from collection.
#define coutI(a)
Definition: RooMsgService.h:32
#define cxcoutD(a)
Definition: RooMsgService.h:80
RooCmdArg Conditional(const RooArgSet &pdfSet, const RooArgSet &depSet, Bool_t depsAreCond=kFALSE)
RooArgSet * findPdfNSet(RooAbsPdf &pdf) const
Look up user specified normalization set for given input PDF component.
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
STL namespace.
virtual void attach(const RooArgSet &params)
Attach generator to given event buffer.
Int_t GetSize() const
Definition: RooLinkedList.h:60
Iterator abstract base class.
Definition: TIterator.h:32
RooArgSet _ownedMultiProds
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.
virtual Bool_t addOwned(RooAbsArg &var, Bool_t silent=kFALSE)
Add element to an owning set.
Definition: RooArgSet.cxx:461
if on multiple lines(like in C++). **The " * configuration fragment. * * The "import myobject continue
Parses the configuration file.
Definition: HLFactory.cxx:368
TString & Append(const char *cs)
Definition: TString.h:492
#define ccxcoutD(a)
Definition: RooMsgService.h:81
std::list< RooAbsGenContext * > _gcList
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of the prototype dataset by the given lookup table.
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:62
Int_t getSize() const
bool verbose
static void indent(ostringstream &buf, int indent_level)
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:592
virtual const RooArgSet * get(Int_t index) const
Return RooArgSet with coordinates of event &#39;index&#39;.
virtual void randomize(const char *rangeName=0)=0
void Delete(Option_t *o=0)
Remove all elements in collection and delete all elements NB: Collection does not own elements...
virtual void generateEvent(RooArgSet &theEvent, Int_t remaining)
Generate a single event of the product by generating the components of the products sequentially...
#define ClassImp(name)
Definition: Rtypes.h:279
void useDefaultGen(Bool_t flag=kTRUE)
Definition: RooProdPdf.h:171
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:1638
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of prototype data to that in the lookup tables passed as argument.
virtual void initGenerator(const RooArgSet &theEvent)
One-time initialization of generator context, forward to component generators.
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Interface for multi-line printing.
#define name(a, b)
Definition: linkTestLib0.cpp:5
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:63
RooProdGenContext(const RooProdPdf &model, const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t _verbose=kFALSE)
#define dologD(a)
Definition: RooMsgService.h:64
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
#define ccxcoutI(a)
Definition: RooMsgService.h:85
TIterator * MakeIterator(Bool_t dir=kTRUE) const
Return an iterator over this list.
virtual TObject * Next()=0
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() ...
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Change cache operation mode to given mode.
Definition: RooAbsArg.cxx:1753
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
const Bool_t kTRUE
Definition: Rtypes.h:91
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.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add element to non-owning set.
Definition: RooArgSet.cxx:448