ROOT  6.06/09
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 }
const RooProdPdf * _pdf
#define cxcoutI(a)
Definition: RooMsgService.h:84
virtual void Reset()=0
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 'enum ContentsOptions' values and in the style given by 'enum StyleOption'.
virtual Bool_t Remove(TObject *arg)
Remove object from collection.
#define coutI(a)
Definition: RooMsgService.h:32
#define cxcoutD(a)
Definition: RooMsgService.h:80
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Definition: RooAbsArg.h:194
RooCmdArg Conditional(const RooArgSet &pdfSet, const RooArgSet &depSet, Bool_t depsAreCond=kFALSE)
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.
Iterator abstract base class.
Definition: TIterator.h:32
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.
RooArgSet _ownedMultiProds
virtual ~RooProdGenContext()
Destructor. Delete all owned subgenerator contexts.
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 Bool_t addOwned(RooAbsArg &var, Bool_t silent=kFALSE)
Add element to an owning set.
Definition: RooArgSet.cxx:461
std::map< std::string, std::string >::const_iterator iter
Definition: TAlienJob.cxx:54
TIterator * createIterator(Bool_t dir=kIterForward) const
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
TIterator * MakeIterator(Bool_t dir=kTRUE) const
Return an iterator over this list.
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:63
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
virtual void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Detailed printing interface.
bool verbose
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
RooArgSet * findPdfNSet(RooAbsPdf &pdf) const
Look up user specified normalization set for given input PDF component.
static void indent(ostringstream &buf, int indent_level)
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...
void useDefaultGen(Bool_t flag=kTRUE)
Definition: RooProdPdf.h:171
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() ...
ClassImp(RooProdGenContext)
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.
virtual void initGenerator(const RooArgSet &theEvent)
One-time initialization of generator context, forward to component generators.
#define name(a, b)
Definition: linkTestLib0.cpp:5
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
virtual TObject * Next()=0
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Change cache operation mode to given mode.
Definition: RooAbsArg.cxx:1753
Int_t GetSize() const
Definition: RooLinkedList.h:60
Int_t getSize() const
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 const RooArgSet * get(Int_t index) const
Return RooArgSet with coordinates of event 'index'.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add element to non-owning set.
Definition: RooArgSet.cxx:448
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