ROOT  6.06/08
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 ;
229  TIterator* iter = _idxCat->typeIterator() ;
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 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
TIterator * _proxyIter
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;.
RooCategoryProxy _indexCat
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.
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Definition: RooAbsArg.h:194
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
RooCmdArg Link(const char *state, RooAbsData &data)
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)
virtual Int_t getIndex() const
Return index number of current state.
STL namespace.
RooArgSet _allVarsPdf
Prototype dataset.
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
TString & Append(const char *cs)
Definition: TString.h:492
const RooAbsCategory & arg() const
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.
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
RooCmdArg OwnLinked()
virtual TIterator * MakeIterator(Bool_t dir=kIterForward) const
Return a list iterator.
Definition: TList.cxx:603
virtual const char * name() const
Definition: RooArgProxy.h:42
std::vector< int > _gcIndex
TIterator * typeIterator() const
Return iterator over all defined states.
virtual const Text_t * GetName() const
Returns name of object.
Definition: RooCatType.h:45
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.
bool verbose
char * Form(const char *fmt,...)
RooAbsArg * absArg() const
Definition: RooArgProxy.h:37
virtual void generateEvent(RooArgSet &theEvent, Int_t remaining)=0
virtual void initGenerator(const RooArgSet &theEvent)
Perform one-time initialization of generator context.
static void indent(ostringstream &buf, int indent_level)
Bool_t canBeExtended() const
Definition: RooAbsPdf.h:216
TIterator * serverIterator() const
Definition: RooAbsArg.h:112
virtual const RooArgSet * get(Int_t index) const
Return RooArgSet with coordinates of event &#39;index&#39;.
Double_t * _fracThresh
RooCmdArg Index(RooCategory &icat)
#define ClassImp(name)
Definition: Rtypes.h:279
static Double_t uniform(TRandom *generator=randomGenerator())
Return a number uniformly distributed from (0,1)
Definition: RooRandom.cxx:83
RooAbsArg * find(const char *name) const
Find object with given name in list.
double Double_t
Definition: RtypesCore.h:55
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.
const RooSimultaneous * _pdf
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 void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Detailed printing interface.
#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 * getPdf(const char *catName) const
Return the p.d.f associated with the given index category name.
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
virtual Bool_t isDerived() const
Definition: RooAbsArg.h:81
virtual TObject * Next()=0
RooAbsCategoryLValue * _idxCat
Bool_t contains(const RooAbsArg &var) const
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
virtual Int_t GetSize() const
Definition: TCollection.h:95
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.
return
Definition: HLFactory.cxx:514
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add element to non-owning set.
Definition: RooArgSet.cxx:448