Logo ROOT  
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 \file RooSimGenContext.cxx
19 \class RooSimGenContext
20 \ingroup Roofitcore
21 
22 RooSimGenContext is an efficient implementation of the generator context
23 specific for RooSimultaneous PDFs when generating more than one of the
24 component pdfs.
25 It runs in two modes:
26 - Proto data with category entries are given: An event from the same category as
27 in the proto data is created.
28 - No proto data: A category is chosen randomly.
29 \note This requires that the PDFs are extended, to determine the relative probabilities
30 that an event originates from a certain category.
31 **/
32 
33 #include "RooFit.h"
34 
35 #include "RooSimGenContext.h"
36 #include "RooSimultaneous.h"
37 #include "RooRealProxy.h"
38 #include "RooDataSet.h"
39 #include "Roo1DTable.h"
40 #include "RooCategory.h"
41 #include "RooMsgService.h"
42 #include "RooRandom.h"
43 #include "RooGlobalFunc.h"
44 
45 using namespace RooFit;
46 
47 #include <iostream>
48 #include <string>
49 
50 using namespace std;
51 
53 ;
54 
55 
56 ////////////////////////////////////////////////////////////////////////////////
57 /// Constructor of specialized generator context for RooSimultaneous p.d.f.s. This
58 /// context creates a dedicated context for each component p.d.f.s and delegates
59 /// generation of events to the appropriate component generator context
60 
62  const RooDataSet *prototype, const RooArgSet* auxProto, Bool_t verbose) :
63  RooAbsGenContext(model,vars,prototype,auxProto,verbose), _pdf(&model), _protoData(0)
64 {
65  // Determine if we are requested to generate the index category
66  RooAbsCategory *idxCat = (RooAbsCategory*) model._indexCat.absArg() ;
67  RooArgSet pdfVars(vars) ;
68 
69  RooArgSet allPdfVars(pdfVars) ;
70  if (prototype) allPdfVars.add(*prototype->get(),kTRUE) ;
71 
72  if (!idxCat->isDerived()) {
73  pdfVars.remove(*idxCat,kTRUE,kTRUE) ;
74  Bool_t doGenIdx = allPdfVars.find(idxCat->GetName())?kTRUE:kFALSE ;
75 
76  if (!doGenIdx) {
77  oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: This context must"
78  << " generate the index category" << endl ;
79  _isValid = kFALSE ;
80  _numPdf = 0 ;
82  return ;
83  }
84  } else {
85  TIterator* sIter = idxCat->serverIterator() ;
86  RooAbsArg* server ;
87  Bool_t anyServer(kFALSE), allServers(kTRUE) ;
88  while((server=(RooAbsArg*)sIter->Next())) {
89  if (vars.find(server->GetName())) {
90  anyServer=kTRUE ;
91  pdfVars.remove(*server,kTRUE,kTRUE) ;
92  } else {
93  allServers=kFALSE ;
94  }
95  }
96  delete sIter ;
97 
98  if (anyServer && !allServers) {
99  oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: This context must"
100  << " generate all components of a derived index category" << endl ;
101  _isValid = kFALSE ;
102  _numPdf = 0 ;
104  return ;
105  }
106  }
107 
108  // We must either have the prototype or extended likelihood to determined
109  // the relative fractions of the components
110  _haveIdxProto = prototype ? kTRUE : kFALSE ;
111  _idxCatName = idxCat->GetName() ;
112  if (!_haveIdxProto && !model.canBeExtended()) {
113  oocoutE(_pdf,Generation) << "RooSimGenContext::ctor(" << GetName() << ") ERROR: Need either extended mode"
114  << " or prototype data to calculate number of events per category" << endl ;
115  _isValid = kFALSE ;
116  _numPdf = 0 ;
117  return ;
118  }
119 
120  // Initialize fraction threshold array (used only in extended mode)
121  _numPdf = model._pdfProxyList.GetSize() ;
122  _fracThresh = new Double_t[_numPdf+1] ;
123  _fracThresh[0] = 0 ;
124 
125  // Generate index category and all registered PDFS
126  _proxyIter = model._pdfProxyList.MakeIterator() ;
127  _allVarsPdf.add(allPdfVars) ;
128  RooRealProxy* proxy ;
129  RooAbsPdf* pdf ;
130  Int_t i(1) ;
131  while((proxy=(RooRealProxy*)_proxyIter->Next())) {
132  pdf=(RooAbsPdf*)proxy->absArg() ;
133 
134  // Create generator context for this PDF
135  RooAbsGenContext* cx = pdf->genContext(pdfVars,prototype,auxProto,verbose) ;
136 
137  // Name the context after the associated state and add to list
138  cx->SetName(proxy->name()) ;
139  _gcList.push_back(cx) ;
140  _gcIndex.push_back(idxCat->lookupIndex(proxy->name()));
141 
142  // Fill fraction threshold array
143  _fracThresh[i] = _fracThresh[i-1] + (_haveIdxProto?0:pdf->expectedEvents(&allPdfVars)) ;
144  i++ ;
145  }
146 
147  // Normalize fraction threshold array
148  if (!_haveIdxProto) {
149  for(i=0 ; i<_numPdf ; i++)
151  }
152 
153 
154  // Clone the index category
155  _idxCatSet = (RooArgSet*) RooArgSet(model._indexCat.arg()).snapshot(kTRUE) ;
156  if (!_idxCatSet) {
157  oocoutE(_pdf,Generation) << "RooSimGenContext::RooSimGenContext(" << GetName() << ") Couldn't deep-clone index category, abort," << endl ;
158  throw std::string("RooSimGenContext::RooSimGenContext() Couldn't deep-clone index category, abort") ;
159  }
160 
161  _idxCat = (RooAbsCategoryLValue*) _idxCatSet->find(model._indexCat.arg().GetName()) ;
162 }
163 
164 
165 
166 ////////////////////////////////////////////////////////////////////////////////
167 /// Destructor. Delete all owned subgenerator contexts
168 
170 {
171  delete[] _fracThresh ;
172  delete _idxCatSet ;
173  for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
174  delete (*iter) ;
175  }
176  delete _proxyIter ;
177  if (_protoData) delete _protoData ;
178 }
179 
180 
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 /// Attach the index category clone to the given event buffer
184 
186 {
187  if (_idxCat->isDerived()) {
189  }
190 
191  // Forward initGenerator call to all components
192  for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
193  (*iter)->attach(args) ;
194  }
195 
196 }
197 
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 /// Perform one-time initialization of generator context
201 
203 {
204  // Attach the index category clone to the event
205  if (_idxCat->isDerived()) {
207  } else {
208  _idxCat = (RooAbsCategoryLValue*) theEvent.find(_idxCat->GetName()) ;
209  }
210 
211  // Update fractions reflecting possible new parameter values
212  updateFractions() ;
213 
214  // Forward initGenerator call to all components
215  for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
216  (*iter)->initGenerator(theEvent) ;
217  }
218 
219 }
220 
221 
222 ////////////////////////////////////////////////////////////////////////////////
223 /// Create an empty dataset to hold the events that will be generated
224 
225 RooDataSet* RooSimGenContext::createDataSet(const char* name, const char* title, const RooArgSet& obs)
226 {
227 
228  // If the observables do not contain the index, make a plain dataset
229  if (!obs.contains(*_idxCat)) {
230  return new RooDataSet(name,title,obs) ;
231  }
232 
233  if (!_protoData) {
234  map<string,RooAbsData*> dmap ;
235  for (const auto& nameIdx : *_idxCat) {
236  RooAbsPdf* slicePdf = _pdf->getPdf(nameIdx.first.c_str());
237  RooArgSet* sliceObs = slicePdf->getObservables(obs) ;
238  std::string sliceName = Form("%s_slice_%s", name, nameIdx.first.c_str());
239  std::string sliceTitle = Form("%s (index slice %s)", title, nameIdx.first.c_str());
240  RooDataSet* dset = new RooDataSet(sliceName.c_str(),sliceTitle.c_str(),*sliceObs) ;
241  dmap[nameIdx.first] = dset ;
242  delete sliceObs ;
243  }
244  _protoData = new RooDataSet(name, title, obs, Index((RooCategory&)*_idxCat), Link(dmap), OwnLinked()) ;
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->getCurrentIndex() ;
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) ;
287  //Write through to sub-categories because they might be written to dataset:
289  return ;
290  }
291  }
292 
293  }
294 }
295 
296 
297 
298 ////////////////////////////////////////////////////////////////////////////////
299 /// No action needed if we have a proto index
300 
302 {
303  if (_haveIdxProto) return ;
304 
305  // Generate index category and all registered PDFS
306  RooRealProxy* proxy ;
307  RooAbsPdf* pdf ;
308  Int_t i(1) ;
309  _proxyIter->Reset() ;
310  while((proxy=(RooRealProxy*)_proxyIter->Next())) {
311  pdf=(RooAbsPdf*)proxy->absArg() ;
312 
313  // Fill fraction threshold array
315  i++ ;
316  }
317 
318  // Normalize fraction threshold array
319  if (!_haveIdxProto) {
320  for(i=0 ; i<_numPdf ; i++)
322  }
323 
324 }
325 
326 
327 
328 ////////////////////////////////////////////////////////////////////////////////
329 /// Set the traversal order of the prototype data to that in the
330 /// given lookup table. This information is passed to all
331 /// component generator contexts
332 
334 {
336 
337  for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
338  (*iter)->setProtoDataOrder(lut) ;
339  }
340 }
341 
342 
343 ////////////////////////////////////////////////////////////////////////////////
344 /// Detailed printing interface
345 
347 {
349  os << indent << "--- RooSimGenContext ---" << endl ;
350  os << indent << "Using PDF ";
352  os << indent << "List of component generators" << endl ;
353 
354  TString indent2(indent) ;
355  indent2.Append(" ") ;
356 
357  for (vector<RooAbsGenContext*>::const_iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
358  (*iter)->printMultiline(os,content,verbose,indent2);
359  }
360 }
RooSimGenContext::_idxCatSet
RooArgSet * _idxCatSet
Definition: RooSimGenContext.h:50
RooAbsArg::serverIterator
TIterator * serverIterator() const
Definition: RooAbsArg.h:141
RooAbsPdf::genContext
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:2005
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
RooMsgService.h
RooSimGenContext::attach
virtual void attach(const RooArgSet &params)
Attach the index category clone to the given event buffer.
Definition: RooSimGenContext.cxx:185
TNamed::SetName
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
RooAbsCategory::getCurrentIndex
virtual value_type getCurrentIndex() const
Return index number of current state.
Definition: RooAbsCategory.cxx:114
RooFit.h
RooSimultaneous.h
RooSimGenContext::_pdf
const RooSimultaneous * _pdf
Definition: RooSimGenContext.h:52
RooSimGenContext::_gcList
std::vector< RooAbsGenContext * > _gcList
Definition: RooSimGenContext.h:53
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
Form
char * Form(const char *fmt,...)
RooSimGenContext.h
RooAbsGenContext::_isValid
Bool_t _isValid
Definition: RooAbsGenContext.h:79
Int_t
int Int_t
Definition: RtypesCore.h:45
RooSimGenContext::_fracThresh
Double_t * _fracThresh
Definition: RooSimGenContext.h:58
RooAbsCollection::remove
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
Definition: RooAbsCollection.cxx:584
RooSimGenContext::printMultiline
virtual void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Detailed printing interface.
Definition: RooSimGenContext.cxx:346
RooAbsCollection::find
RooAbsArg * find(const char *name) const
Find object with given name in list.
Definition: RooAbsCollection.cxx:813
RooSimGenContext::setProtoDataOrder
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of the prototype data to that in the given lookup table.
Definition: RooSimGenContext.cxx:333
RooSimGenContext::_protoData
RooDataSet * _protoData
Definition: RooSimGenContext.h:59
indent
static void indent(ostringstream &buf, int indent_level)
Definition: TClingCallFunc.cxx:87
RooArgSet::add
virtual Bool_t add(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling add() for each element in the source coll...
Definition: RooArgSet.h:88
RooAbsArg::recursiveRedirectServers
Bool_t recursiveRedirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t recurseInNewSet=kTRUE)
Definition: RooAbsArg.cxx:1066
oocoutE
#define oocoutE(o, a)
Definition: RooMsgService.h:48
RooSimGenContext::_idxCatName
TString _idxCatName
Definition: RooSimGenContext.h:56
TString
Definition: TString.h:136
RooSimGenContext
Definition: RooSimGenContext.h:27
RooDataSet.h
bool
TIterator
Definition: TIterator.h:30
RooDataSet::get
virtual const RooArgSet * get(Int_t index) const override
Return RooArgSet with coordinates of event 'index'.
Definition: RooDataSet.cxx:1038
RooAbsGenContext::setProtoDataOrder
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of prototype data to that in the lookup tables passed as argument.
Definition: RooAbsGenContext.cxx:348
RooSimGenContext::_idxCat
RooAbsCategoryLValue * _idxCat
Definition: RooSimGenContext.h:49
RooAbsCategory
Definition: RooAbsCategory.h:38
RooAbsGenContext::printMultiline
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Interface for multi-line printing.
Definition: RooAbsGenContext.cxx:335
RooAbsArg::isDerived
virtual Bool_t isDerived() const
Does value or shape of this arg depend on any other arg?
Definition: RooAbsArg.h:93
RooAbsCollection::contains
Bool_t contains(const RooAbsArg &var) const
Check if collection contains an argument with the same name as var.
Definition: RooAbsCollection.h:102
RooPrintable::kName
@ kName
Definition: RooPrintable.h:33
RooSimGenContext::createDataSet
RooDataSet * createDataSet(const char *name, const char *title, const RooArgSet &obs)
Create an empty dataset to hold the events that will be generated.
Definition: RooSimGenContext.cxx:225
RooAbsCategoryLValue::setIndex
virtual bool setIndex(value_type index, bool printError=true)=0
Change category state by specifying the index code of the desired state.
RooFit
Definition: RooCFunction1Binding.h:29
RooSimGenContext::_numPdf
Int_t _numPdf
Definition: RooSimGenContext.h:57
RooFit::Generation
@ Generation
Definition: RooGlobalFunc.h:67
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TString::Append
TString & Append(const char *cs)
Definition: TString.h:564
RooRandom.h
RooPrintable::kArgs
@ kArgs
Definition: RooPrintable.h:33
RooRealProxy.h
RooAbsGenContext
Definition: RooAbsGenContext.h:26
RooCategory.h
oocoutW
#define oocoutW(o, a)
Definition: RooMsgService.h:47
TIterator::Next
virtual TObject * Next()=0
RooSimGenContext::_proxyIter
TIterator * _proxyIter
Definition: RooSimGenContext.h:62
RooGlobalFunc.h
TIterator::Reset
virtual void Reset()=0
RooSimGenContext::generateEvent
virtual void generateEvent(RooArgSet &theEvent, Int_t remaining)
Generate event appropriate for current index state.
Definition: RooSimGenContext.cxx:261
RooTemplateProxy< RooAbsReal >
RooPrintable::kClassName
@ kClassName
Definition: RooPrintable.h:33
RooSimGenContext::~RooSimGenContext
virtual ~RooSimGenContext()
Destructor. Delete all owned subgenerator contexts.
Definition: RooSimGenContext.cxx:169
Double_t
double Double_t
Definition: RtypesCore.h:59
RooAbsArg::getObservables
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Return the observables of this pdf given a set of observables.
Definition: RooAbsArg.h:294
RooSimGenContext::updateFractions
void updateFractions()
No action needed if we have a proto index.
Definition: RooSimGenContext.cxx:301
Roo1DTable.h
RooCategory
Definition: RooCategory.h:27
RooSimGenContext::RooSimGenContext
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.
Definition: RooSimGenContext.cxx:61
RooAbsCategory::lookupIndex
value_type lookupIndex(const std::string &stateName) const
Find the index number corresponding to the state name.
Definition: RooAbsCategory.cxx:283
name
char name[80]
Definition: TGX11.cxx:110
RooSimultaneous::getPdf
RooAbsPdf * getPdf(const char *catName) const
Return the p.d.f associated with the given index category name.
Definition: RooSimultaneous.cxx:351
RooFit::OwnLinked
RooCmdArg OwnLinked()
Definition: RooGlobalFunc.cxx:132
RooPrintable::printStream
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,...
Definition: RooPrintable.cxx:75
genreflex::verbose
bool verbose
Definition: rootcling_impl.cxx:133
RooPrintable::kSingleLine
@ kSingleLine
Definition: RooPrintable.h:34
RooDataSet
Definition: RooDataSet.h:33
make_cnn_model.model
model
Definition: make_cnn_model.py:6
RooAbsArg
Definition: RooAbsArg.h:73
RooSimGenContext::_gcIndex
std::vector< int > _gcIndex
Definition: RooSimGenContext.h:54
RooSimGenContext::_haveIdxProto
Bool_t _haveIdxProto
Definition: RooSimGenContext.h:55
RooAbsPdf
Definition: RooAbsPdf.h:40
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:53
RooFit::Index
RooCmdArg Index(RooCategory &icat)
Definition: RooGlobalFunc.cxx:97
RooSimultaneous
Definition: RooSimultaneous.h:37
RooAbsCategoryLValue
Definition: RooAbsCategoryLValue.h:25
RooSimGenContext::_allVarsPdf
RooArgSet _allVarsPdf
Prototype dataset.
Definition: RooSimGenContext.h:61
RooFit::Link
RooCmdArg Link(const char *state, RooAbsData &data)
Definition: RooGlobalFunc.cxx:125
RooRandom::uniform
static Double_t uniform(TRandom *generator=randomGenerator())
Return a number uniformly distributed from (0,1)
Definition: RooRandom.cxx:83
RooAbsGenContext::generateEvent
virtual void generateEvent(RooArgSet &theEvent, Int_t remaining)=0
RooArgSet
Definition: RooArgSet.h:28
RooSimGenContext::initGenerator
virtual void initGenerator(const RooArgSet &theEvent)
Perform one-time initialization of generator context.
Definition: RooSimGenContext.cxx:202
int
RooAbsPdf::expectedEvents
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:3309