ROOT  6.06/09
Reference Guide
RooSimGenContext.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 // RooSimGenContext is an efficient implementation of the generator context
21 // specific for RooSimultaneous PDFs when generating more than one of the
22 // component pdfs.
23 // END_HTML
24 //
25 
26 #include "RooFit.h"
27 #include "Riostream.h"
28 
29 #include "RooSimGenContext.h"
30 #include "RooSimultaneous.h"
31 #include "RooRealProxy.h"
32 #include "RooDataSet.h"
33 #include "Roo1DTable.h"
34 #include "RooCategory.h"
35 #include "RooMsgService.h"
36 #include "RooRandom.h"
37 #include "RooGlobalFunc.h"
38 
39 using namespace RooFit ;
40 
41 #include <string>
42 
43 using namespace std;
44 
46 ;
47 
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 /// Constructor of specialized generator context for RooSimultaneous p.d.f.s. This
51 /// context creates a dedicated context for each component p.d.f.s and delegates
52 /// generation of events to the appropriate component generator context
53 
55  const RooDataSet *prototype, const RooArgSet* auxProto, Bool_t verbose) :
56  RooAbsGenContext(model,vars,prototype,auxProto,verbose), _pdf(&model), _protoData(0)
57 {
58  // Determine if we are requested to generate the index category
59  RooAbsCategory *idxCat = (RooAbsCategory*) model._indexCat.absArg() ;
60  RooArgSet pdfVars(vars) ;
61 
62  RooArgSet allPdfVars(pdfVars) ;
63  if (prototype) allPdfVars.add(*prototype->get(),kTRUE) ;
64 
65  if (!idxCat->isDerived()) {
66  pdfVars.remove(*idxCat,kTRUE,kTRUE) ;
67  Bool_t doGenIdx = allPdfVars.find(idxCat->GetName())?kTRUE:kFALSE ;
68 
69  if (!doGenIdx) {
70  oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: This context must"
71  << " generate the index category" << endl ;
72  _isValid = kFALSE ;
73  _numPdf = 0 ;
75  return ;
76  }
77  } else {
78  TIterator* sIter = idxCat->serverIterator() ;
79  RooAbsArg* server ;
80  Bool_t anyServer(kFALSE), allServers(kTRUE) ;
81  while((server=(RooAbsArg*)sIter->Next())) {
82  if (vars.find(server->GetName())) {
83  anyServer=kTRUE ;
84  pdfVars.remove(*server,kTRUE,kTRUE) ;
85  } else {
86  allServers=kFALSE ;
87  }
88  }
89  delete sIter ;
90 
91  if (anyServer && !allServers) {
92  oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: This context must"
93  << " generate all components of a derived index category" << endl ;
94  _isValid = kFALSE ;
95  _numPdf = 0 ;
97  return ;
98  }
99  }
100 
101  // We must either have the prototype or extended likelihood to determined
102  // the relative fractions of the components
103  _haveIdxProto = prototype ? kTRUE : kFALSE ;
104  _idxCatName = idxCat->GetName() ;
105  if (!_haveIdxProto && !model.canBeExtended()) {
106  oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: Need either extended mode"
107  << " or prototype data to calculate number of events per category" << endl ;
108  _isValid = kFALSE ;
109  _numPdf = 0 ;
110  return ;
111  }
112 
113  // Initialize fraction threshold array (used only in extended mode)
114  _numPdf = model._pdfProxyList.GetSize() ;
115  _fracThresh = new Double_t[_numPdf+1] ;
116  _fracThresh[0] = 0 ;
117 
118  // Generate index category and all registered PDFS
120  _allVarsPdf.add(allPdfVars) ;
121  RooRealProxy* proxy ;
122  RooAbsPdf* pdf ;
123  Int_t i(1) ;
124  while((proxy=(RooRealProxy*)_proxyIter->Next())) {
125  pdf=(RooAbsPdf*)proxy->absArg() ;
126 
127  // Create generator context for this PDF
128  RooAbsGenContext* cx = pdf->genContext(pdfVars,prototype,auxProto,verbose) ;
129 
130  // Name the context after the associated state and add to list
131  cx->SetName(proxy->name()) ;
132  _gcList.push_back(cx) ;
133  _gcIndex.push_back(idxCat->lookupType(proxy->name())->getVal()) ;
134 
135  // Fill fraction threshold array
136  _fracThresh[i] = _fracThresh[i-1] + (_haveIdxProto?0:pdf->expectedEvents(&allPdfVars)) ;
137  i++ ;
138  }
139 
140  // Normalize fraction threshold array
141  if (!_haveIdxProto) {
142  for(i=0 ; i<_numPdf ; i++)
143  _fracThresh[i] /= _fracThresh[_numPdf] ;
144  }
145 
146 
147  // Clone the index category
148  _idxCatSet = (RooArgSet*) RooArgSet(model._indexCat.arg()).snapshot(kTRUE) ;
149  if (!_idxCatSet) {
150  oocoutE(_pdf,Generation) << "RooSimGenContext::RooSimGenContext(" << GetName() << ") Couldn't deep-clone index category, abort," << endl ;
151  throw std::string("RooSimGenContext::RooSimGenContext() Couldn't deep-clone index category, abort") ;
152  }
153 
155 }
156 
157 
158 
159 ////////////////////////////////////////////////////////////////////////////////
160 /// Destructor. Delete all owned subgenerator contexts
161 
163 {
164  delete[] _fracThresh ;
165  delete _idxCatSet ;
166  for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
167  delete (*iter) ;
168  }
169  delete _proxyIter ;
170  if (_protoData) delete _protoData ;
171 }
172 
173 
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 /// Attach the index category clone to the given event buffer
177 
179 {
180  if (_idxCat->isDerived()) {
182  }
183 
184  // Forward initGenerator call to all components
185  for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
186  (*iter)->attach(args) ;
187  }
188 
189 }
190 
191 
192 ////////////////////////////////////////////////////////////////////////////////
193 /// Perform one-time initialization of generator context
194 
196 {
197  // Attach the index category clone to the event
198  if (_idxCat->isDerived()) {
200  } else {
201  _idxCat = (RooAbsCategoryLValue*) theEvent.find(_idxCat->GetName()) ;
202  }
203 
204  // Update fractions reflecting possible new parameter values
205  updateFractions() ;
206 
207  // Forward initGenerator call to all components
208  for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
209  (*iter)->initGenerator(theEvent) ;
210  }
211 
212 }
213 
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 /// Create an empty dataset to hold the events that will be generated
217 
218 RooDataSet* RooSimGenContext::createDataSet(const char* name, const char* title, const RooArgSet& obs)
219 {
220 
221  // If the observables do not contain the index, make a plain dataset
222  if (!obs.contains(*_idxCat)) {
223  return new RooDataSet(name,title,obs) ;
224  }
225 
226  if (!_protoData) {
227  map<string,RooAbsData*> dmap ;
228  RooCatType* state ;
230  while((state=(RooCatType*)iter->Next())) {
231  RooAbsPdf* slicePdf = _pdf->getPdf(state->GetName()) ;
232  RooArgSet* sliceObs = slicePdf->getObservables(obs) ;
233  std::string sliceName = Form("%s_slice_%s",name,state->GetName()) ;
234  std::string sliceTitle = Form("%s (index slice %s)",title,state->GetName()) ;
235  RooDataSet* dset = new RooDataSet(sliceName.c_str(),sliceTitle.c_str(),*sliceObs) ;
236  dmap[state->GetName()] = dset ;
237  delete sliceObs ;
238  }
239  delete iter ;
240  _protoData = new RooDataSet(name, title, obs, Index((RooCategory&)*_idxCat), Link(dmap), OwnLinked()) ;
241 
242 // RooDataSet* tmp = _protoData ;
243 // _protoData = 0 ;
244 // return tmp ;
245  }
246 
247  RooDataSet* emptyClone = new RooDataSet(*_protoData,name) ;
248 
249  return emptyClone ;
250 }
251 
252 
253 
254 
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// Generate event appropriate for current index state.
258 /// The index state is taken either from the prototype
259 /// or is generated from the fraction threshold table.
260 
262 {
263  if (_haveIdxProto) {
264 
265  // Lookup pdf from selected prototype index state
266  Int_t gidx(0), cidx =_idxCat->getIndex() ;
267  for (Int_t i=0 ; i<(Int_t)_gcIndex.size() ; i++) {
268  if (_gcIndex[i]==cidx) { gidx = i ; break ; }
269  }
270  RooAbsGenContext* cx = _gcList[gidx] ;
271  if (cx) {
272  cx->generateEvent(theEvent,remaining) ;
273  } else {
274  oocoutW(_pdf,Generation) << "RooSimGenContext::generateEvent: WARNING, no PDF to generate event of type " << cidx << endl ;
275  }
276 
277 
278  } else {
279 
280  // Throw a random number and select PDF from fraction threshold table
281  Double_t rand = RooRandom::uniform() ;
282  Int_t i=0 ;
283  for (i=0 ; i<_numPdf ; i++) {
284  if (rand>_fracThresh[i] && rand<_fracThresh[i+1]) {
285  RooAbsGenContext* gen=_gcList[i] ;
286  gen->generateEvent(theEvent,remaining) ;
288  return ;
289  }
290  }
291 
292  }
293 }
294 
295 
296 
297 ////////////////////////////////////////////////////////////////////////////////
298 /// No action needed if we have a proto index
299 
301 {
302  if (_haveIdxProto) return ;
303 
304  // Generate index category and all registered PDFS
305  RooRealProxy* proxy ;
306  RooAbsPdf* pdf ;
307  Int_t i(1) ;
308  _proxyIter->Reset() ;
309  while((proxy=(RooRealProxy*)_proxyIter->Next())) {
310  pdf=(RooAbsPdf*)proxy->absArg() ;
311 
312  // Fill fraction threshold array
314  i++ ;
315  }
316 
317  // Normalize fraction threshold array
318  if (!_haveIdxProto) {
319  for(i=0 ; i<_numPdf ; i++)
320  _fracThresh[i] /= _fracThresh[_numPdf] ;
321  }
322 
323 }
324 
325 
326 
327 ////////////////////////////////////////////////////////////////////////////////
328 /// Set the traversal order of the prototype data to that in the
329 /// given lookup table. This information is passed to all
330 /// component generator contexts
331 
333 {
335 
336  for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
337  (*iter)->setProtoDataOrder(lut) ;
338  }
339 }
340 
341 
342 ////////////////////////////////////////////////////////////////////////////////
343 /// Detailed printing interface
344 
346 {
347  RooAbsGenContext::printMultiline(os,content,verbose,indent) ;
348  os << indent << "--- RooSimGenContext ---" << endl ;
349  os << indent << "Using PDF ";
351  os << indent << "List of component generators" << endl ;
352 
353  TString indent2(indent) ;
354  indent2.Append(" ") ;
355 
356  for (vector<RooAbsGenContext*>::const_iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
357  (*iter)->printMultiline(os,content,verbose,indent2);
358  }
359 }
TIterator * _proxyIter
RooCategoryProxy _indexCat
virtual Bool_t isDerived() const
Definition: RooAbsArg.h:81
TIterator * serverIterator() const
Definition: RooAbsArg.h:112
virtual void Reset()=0
virtual ~RooSimGenContext()
Destructor. Delete all owned subgenerator contexts.
RooDataSet * createDataSet(const char *name, const char *title, const RooArgSet &obs)
Create an empty dataset to hold the events that will be generated.
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 Int_t getIndex() const
Return index number of current state.
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Definition: RooAbsArg.h:194
RooCmdArg Link(const char *state, RooAbsData &data)
Bool_t contains(const RooAbsArg &var) const
virtual const char * name() const
Definition: RooArgProxy.h:42
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
virtual void setIndexFast(Int_t index)
STL namespace.
RooAbsPdf * getPdf(const char *catName) const
Return the p.d.f associated with the given index category name.
RooArgSet _allVarsPdf
Prototype dataset.
virtual Double_t expectedEvents(const RooArgSet *nset) const
Return expected number of events from this p.d.f for use in extended likelihood calculations.
Definition: RooAbsPdf.cxx:2930
Iterator abstract base class.
Definition: TIterator.h:32
void updateFractions()
No action needed if we have a proto index.
virtual void generateEvent(RooArgSet &theEvent, Int_t remaining)
Generate event appropriate for current index state.
RooArgSet * _idxCatSet
#define oocoutE(o, a)
Definition: RooMsgService.h:48
std::map< std::string, std::string >::const_iterator iter
Definition: TAlienJob.cxx:54
TString & Append(const char *cs)
Definition: TString.h:492
RooSimGenContext(const RooSimultaneous &model, const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t _verbose=kFALSE)
Constructor of specialized generator context for RooSimultaneous p.d.f.s.
virtual void attach(const RooArgSet &params)
Attach the index category clone to the given event buffer.
RooCmdArg OwnLinked()
std::vector< int > _gcIndex
RooAbsArg * find(const char *name) const
Find object with given name in list.
return
Definition: TBase64.cxx:62
ClassImp(RooSimGenContext)
bool verbose
char * Form(const char *fmt,...)
virtual void generateEvent(RooArgSet &theEvent, Int_t remaining)=0
RooAbsArg * absArg() const
Definition: RooArgProxy.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual void initGenerator(const RooArgSet &theEvent)
Perform one-time initialization of generator context.
static void indent(ostringstream &buf, int indent_level)
Double_t * _fracThresh
RooCmdArg Index(RooCategory &icat)
virtual Int_t GetSize() const
Definition: TCollection.h:95
virtual void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Detailed printing interface.
static Double_t uniform(TRandom *generator=randomGenerator())
Return a number uniformly distributed from (0,1)
Definition: RooRandom.cxx:83
double Double_t
Definition: RtypesCore.h:55
Bool_t canBeExtended() const
Definition: RooAbsPdf.h:216
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.
const RooSimultaneous * _pdf
#define name(a, b)
Definition: linkTestLib0.cpp:5
#define oocoutW(o, a)
Definition: RooMsgService.h:47
std::vector< RooAbsGenContext * > _gcList
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
virtual TObject * Next()=0
RooAbsCategoryLValue * _idxCat
virtual TIterator * MakeIterator(Bool_t dir=kIterForward) const
Return a list iterator.
Definition: TList.cxx:603
const RooAbsCategory & arg() const
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
Bool_t recursiveRedirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t recurseInNewSet=kTRUE)
Definition: RooAbsArg.cxx:1087
RooDataSet * _protoData
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of the prototype data to that in the given lookup table.
virtual const RooArgSet * get(Int_t index) const
Return RooArgSet with coordinates of event 'index'.
virtual const Text_t * GetName() const
Returns name of object.
Definition: RooCatType.h:45
TIterator * typeIterator() const
Return iterator over all defined states.
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
const RooCatType * lookupType(Int_t index, Bool_t printError=kFALSE) const
Find our type corresponding to the specified index, or return 0 for no match.