Logo ROOT  
Reference Guide
RooSimSplitGenContext.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 RooSimSplitGenContext.cxx
19\class RooSimSplitGenContext
20\ingroup Roofitcore
21
22RooSimSplitGenContext is an efficient implementation of the generator context
23specific for RooSimultaneous PDFs when generating more than one of the
24component pdfs.
25**/
26
28#include "RooSimultaneous.h"
29#include "RooRealProxy.h"
30#include "RooDataSet.h"
31#include "Roo1DTable.h"
32#include "RooCategory.h"
33#include "RooMsgService.h"
34#include "RooRandom.h"
35#include "RooGlobalFunc.h"
36
37using namespace RooFit;
38
39#include <iostream>
40#include <string>
41
42using namespace std;
43
45
46
47////////////////////////////////////////////////////////////////////////////////
48/// Constructor of specialized generator context for RooSimultaneous p.d.f.s. This
49/// context creates a dedicated context for each component p.d.f.s and delegates
50/// generation of events to the appropriate component generator context
51
52RooSimSplitGenContext::RooSimSplitGenContext(const RooSimultaneous &model, const RooArgSet &vars, Bool_t verbose, Bool_t autoBinned, const char* binnedTag) :
53 RooAbsGenContext(model,vars,0,0,verbose), _pdf(&model)
54{
55 // Determine if we are requested to generate the index category
56 RooAbsCategory *idxCat = (RooAbsCategory*) model._indexCat.absArg() ;
57 RooArgSet pdfVars(vars) ;
58
59 RooArgSet allPdfVars(pdfVars) ;
60
61 if (!idxCat->isDerived()) {
62 pdfVars.remove(*idxCat,kTRUE,kTRUE) ;
63 Bool_t doGenIdx = allPdfVars.find(idxCat->GetName())?kTRUE:kFALSE ;
64
65 if (!doGenIdx) {
66 oocoutE(_pdf,Generation) << "RooSimSplitGenContext::ctor(" << GetName() << ") ERROR: This context must"
67 << " generate the index category" << endl ;
69 _numPdf = 0 ;
70 // coverity[UNINIT_CTOR]
71 return ;
72 }
73 } else {
74 TIterator* sIter = idxCat->serverIterator() ;
75 RooAbsArg* server ;
76 Bool_t anyServer(kFALSE), allServers(kTRUE) ;
77 while((server=(RooAbsArg*)sIter->Next())) {
78 if (vars.find(server->GetName())) {
79 anyServer=kTRUE ;
80 pdfVars.remove(*server,kTRUE,kTRUE) ;
81 } else {
82 allServers=kFALSE ;
83 }
84 }
85 delete sIter ;
86
87 if (anyServer && !allServers) {
88 oocoutE(_pdf,Generation) << "RooSimSplitGenContext::ctor(" << GetName() << ") ERROR: This context must"
89 << " generate all components of a derived index category" << endl ;
91 _numPdf = 0 ;
92 // coverity[UNINIT_CTOR]
93 return ;
94 }
95 }
96
97 // We must extended likelihood to determine the relative fractions of the components
98 _idxCatName = idxCat->GetName() ;
99 if (!model.canBeExtended()) {
100 oocoutE(_pdf,Generation) << "RooSimSplitGenContext::RooSimSplitGenContext(" << GetName() << "): All components of the simultaneous PDF "
101 << "must be extended PDFs. Otherwise, it is impossible to calculate the number of events to be generated per component." << endl ;
102 _isValid = kFALSE ;
103 _numPdf = 0 ;
104 // coverity[UNINIT_CTOR]
105 return ;
106 }
107
108 // Initialize fraction threshold array (used only in extended mode)
109 _numPdf = model._pdfProxyList.GetSize() ;
110 _fracThresh = new Double_t[_numPdf+1] ;
111 _fracThresh[0] = 0 ;
112
113 // Generate index category and all registered PDFS
115 _allVarsPdf.add(allPdfVars) ;
116 RooRealProxy* proxy ;
117 RooAbsPdf* pdf ;
118 Int_t i(1) ;
119 while((proxy=(RooRealProxy*)_proxyIter->Next())) {
120 pdf=(RooAbsPdf*)proxy->absArg() ;
121
122 // Create generator context for this PDF
123 RooArgSet* compVars = pdf->getObservables(pdfVars) ;
124 RooAbsGenContext* cx = pdf->autoGenContext(*compVars,0,0,verbose,autoBinned,binnedTag) ;
125 delete compVars ;
126
127 const auto state = idxCat->lookupIndex(proxy->name());
128
129 cx->SetName(proxy->name()) ;
130 _gcList.push_back(cx) ;
131 _gcIndex.push_back(state);
132
133 // Fill fraction threshold array
134 _fracThresh[i] = _fracThresh[i-1] + pdf->expectedEvents(&allPdfVars) ;
135 i++ ;
136 }
137
138 for(i=0 ; i<_numPdf ; i++) {
140 }
141
142 // Clone the index category
143 _idxCatSet = (RooArgSet*) RooArgSet(model._indexCat.arg()).snapshot(kTRUE) ;
144 if (!_idxCatSet) {
145 oocoutE(_pdf,Generation) << "RooSimSplitGenContext::RooSimSplitGenContext(" << GetName() << ") Couldn't deep-clone index category, abort," << endl ;
146 throw std::string("RooSimSplitGenContext::RooSimSplitGenContext() Couldn't deep-clone index category, abort") ;
147 }
148
150}
151
152
153
154////////////////////////////////////////////////////////////////////////////////
155/// Destructor. Delete all owned subgenerator contexts
156
158{
159 delete[] _fracThresh ;
160 delete _idxCatSet ;
161 for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
162 delete (*iter) ;
163 }
164 delete _proxyIter ;
165}
166
167
168
169////////////////////////////////////////////////////////////////////////////////
170/// Attach the index category clone to the given event buffer
171
173{
174 if (_idxCat->isDerived()) {
176 }
177
178 // Forward initGenerator call to all components
179 for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
180 (*iter)->attach(args) ;
181 }
182
183}
184
185
186////////////////////////////////////////////////////////////////////////////////
187/// Perform one-time initialization of generator context
188
190{
191 // Attach the index category clone to the event
192 if (_idxCat->isDerived()) {
194 } else {
196 }
197
198 // Forward initGenerator call to all components
199 for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
200 (*iter)->initGenerator(theEvent) ;
201 }
202
203}
204
205
206
207////////////////////////////////////////////////////////////////////////////////
208
210{
211 if(!isValid()) {
212 coutE(Generation) << ClassName() << "::" << GetName() << ": context is not valid" << endl;
213 return 0;
214 }
215
216
217 // Calculate the expected number of events if necessary
218 if(nEvents <= 0) {
219 nEvents= _expectedEvents;
220 }
221 coutI(Generation) << ClassName() << "::" << GetName() << ":generate: will generate "
222 << nEvents << " events" << endl;
223
224 if (_verbose) Print("v") ;
225
226 // Perform any subclass implementation-specific initialization
227 // Can be skipped if this is a rerun with an identical configuration
228 if (!skipInit) {
230 }
231
232 // Generate lookup table from expected event counts
233 vector<Double_t> nGen(_numPdf) ;
234 if (extendedMode ) {
235 _proxyIter->Reset() ;
236 RooRealProxy* proxy ;
237 Int_t i(0) ;
238 while((proxy=(RooRealProxy*)_proxyIter->Next())) {
239 RooAbsPdf* pdf=(RooAbsPdf*)proxy->absArg() ;
240 //nGen[i] = Int_t(pdf->expectedEvents(&_allVarsPdf)+0.5) ;
241 nGen[i] = pdf->expectedEvents(&_allVarsPdf) ;
242 i++ ;
243 }
244
245 } else {
246 _proxyIter->Reset() ;
247 RooRealProxy* proxy ;
248 Int_t i(1) ;
249 _fracThresh[0] = 0 ;
250 while((proxy=(RooRealProxy*)_proxyIter->Next())) {
251 RooAbsPdf* pdf=(RooAbsPdf*)proxy->absArg() ;
253 i++ ;
254 }
255 for(i=0 ; i<_numPdf ; i++) {
257 }
258
259 // Determine from that total number of events to be generated for each component
260 Double_t nGenSoFar(0) ;
261 while (nGenSoFar<nEvents) {
263 i=0 ;
264 for (i=0 ; i<_numPdf ; i++) {
265 if (rand>_fracThresh[i] && rand<_fracThresh[i+1]) {
266 nGen[i]++ ;
267 nGenSoFar++ ;
268 break ;
269 }
270 }
271 }
272 }
273
274
275
276 // Now loop over states
277 _proxyIter->Reset() ;
278 map<string,RooAbsData*> dataMap ;
279 Int_t icomp(0) ;
280 RooRealProxy* proxy ;
281 while((proxy=(RooRealProxy*)_proxyIter->Next())) {
282
283 // Calculate number of events to generate for this state
284 if (_gcList[icomp]) {
285 dataMap[proxy->GetName()] = _gcList[icomp]->generate(nGen[icomp],skipInit,extendedMode) ;
286 }
287
288 icomp++ ;
289 }
290
291 // Put all datasets together in a composite-store RooDataSet that links and owns the component datasets
292 RooDataSet* hmaster = new RooDataSet("hmaster","hmaster",_allVarsPdf,RooFit::Index((RooCategory&)*_idxCat),RooFit::Link(dataMap),RooFit::OwnLinked()) ;
293 return hmaster ;
294}
295
296
297
298////////////////////////////////////////////////////////////////////////////////
299/// Forward to components
300
302{
303 for (vector<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
304 (*iter)->setExpectedData(flag) ;
305 }
306}
307
308
309
310////////////////////////////////////////////////////////////////////////////////
311/// this method is empty because it is not used by this context
312
313RooDataSet* RooSimSplitGenContext::createDataSet(const char* , const char* , const RooArgSet& )
314{
315 return 0 ;
316}
317
318
319
320////////////////////////////////////////////////////////////////////////////////
321/// this method is empty because it is not used in this type of context
322
324{
325 assert(0) ;
326}
327
328
329
330
331////////////////////////////////////////////////////////////////////////////////
332/// this method is empty because proto datasets are not supported by this context
333
335{
336 assert(0) ;
337}
338
339
340////////////////////////////////////////////////////////////////////////////////
341/// Detailed printing interface
342
344{
346 os << indent << "--- RooSimSplitGenContext ---" << endl ;
347 os << indent << "Using PDF ";
349}
#define coutI(a)
Definition: RooMsgService.h:30
#define oocoutE(o, a)
Definition: RooMsgService.h:48
#define coutE(a)
Definition: RooMsgService.h:33
const Bool_t kFALSE
Definition: RtypesCore.h:101
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:375
static void indent(ostringstream &buf, int indent_level)
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:78
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Given a set of possible observables, return the observables that this PDF depends on.
Definition: RooAbsArg.h:318
virtual Bool_t isDerived() const
Does value or shape of this arg depend on any other arg?
Definition: RooAbsArg.h:98
TIterator * serverIterator() const
Definition: RooAbsArg.h:146
Bool_t recursiveRedirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t recurseInNewSet=kTRUE)
Recursively replace all servers with the new servers in newSet.
Definition: RooAbsArg.cxx:1197
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
A space to attach TBranches.
value_type lookupIndex(const std::string &stateName) const
Find the index number corresponding to the state name.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsGenContext is the abstract base class for generator contexts of RooAbsPdf objects.
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const override
Interface for multi-line printing.
Bool_t isValid() const
RooArgSet _theEvent
Pointer to observable event being generated.
void Print(Option_t *options=0) const override
Print TNamed name and title.
Bool_t _isValid
Is context in valid state?
UInt_t _expectedEvents
Number of expected events from extended p.d.f.
Bool_t _verbose
Verbose messaging?
Bool_t canBeExtended() const
If true, PDF can provide extended likelihood term.
Definition: RooAbsPdf.h:263
virtual RooAbsGenContext * autoGenContext(const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE, Bool_t autoBinned=kTRUE, const char *binnedTag="") const
Definition: RooAbsPdf.cxx:1912
virtual Double_t expectedEvents(const RooArgSet *nset) const
Return expected number of events to be used in calculation of extended likelihood.
Definition: RooAbsPdf.cxx:3231
RooAbsArg * absArg() const
Return pointer to contained argument.
Definition: RooArgProxy.h:40
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:57
RooCategory is an object to represent discrete states.
Definition: RooCategory.h:28
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:55
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,...
static Double_t uniform(TRandom *generator=randomGenerator())
Return a number uniformly distributed from (0,1)
Definition: RooRandom.cxx:81
RooSimSplitGenContext is an efficient implementation of the generator context specific for RooSimulta...
void generateEvent(RooArgSet &theEvent, Int_t remaining) override
this method is empty because it is not used in this type of context
std::vector< RooAbsGenContext * > _gcList
List of component generator contexts.
RooArgSet _allVarsPdf
All pdf variables.
void attach(const RooArgSet &params) override
Attach the index category clone to the given event buffer.
Double_t * _fracThresh
fraction thresholds
void initGenerator(const RooArgSet &theEvent) override
Perform one-time initialization of generator context.
void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const override
Detailed printing interface.
RooDataSet * createDataSet(const char *name, const char *title, const RooArgSet &obs) override
this method is empty because it is not used by this context
RooDataSet * generate(Double_t nEvents=0, Bool_t skipInit=kFALSE, Bool_t extendedMode=kFALSE) override
Generate the specified number of events with nEvents>0 and and return a dataset containing the genera...
Int_t _numPdf
Number of generated PDFs.
void setExpectedData(Bool_t) override
Forward to components.
RooSimSplitGenContext(const RooSimultaneous &model, const RooArgSet &vars, Bool_t _verbose=kFALSE, Bool_t autoBinned=kTRUE, const char *binnedTag="")
Constructor of specialized generator context for RooSimultaneous p.d.f.s.
const RooSimultaneous * _pdf
Original PDF.
std::vector< int > _gcIndex
Index value corresponding to component.
TIterator * _proxyIter
Iterator over pdf proxies.
void setProtoDataOrder(Int_t *lut) override
this method is empty because proto datasets are not supported by this context
~RooSimSplitGenContext() override
Destructor. Delete all owned subgenerator contexts.
RooArgSet * _idxCatSet
Owner of index category components.
RooAbsCategoryLValue * _idxCat
Clone of index category.
TString _idxCatName
Name of index category.
RooSimultaneous facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
TList _pdfProxyList
List of PDF proxies (named after applicable category state)
RooCategoryProxy _indexCat
Index category.
const T & arg() const
Return reference to object held in proxy.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:184
Iterator abstract base class.
Definition: TIterator.h:30
virtual void Reset()=0
virtual TObject * Next()=0
TIterator * MakeIterator(Bool_t dir=kIterForward) const override
Return a list iterator.
Definition: TList.cxx:722
const char * GetName() const override
Returns name of object.
Definition: TNamed.h:47
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
Basic string class.
Definition: TString.h:136
RooCmdArg OwnLinked()
RooCmdArg Index(RooCategory &icat)
RooCmdArg Link(const char *state, RooAbsData &data)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition: Common.h:18
@ Generation
Definition: RooGlobalFunc.h:63