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