Logo ROOT   6.08/07
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 
22 RooSimSplitGenContext is an efficient implementation of the generator context
23 specific for RooSimultaneous PDFs when generating more than one of the
24 component pdfs.
25 **/
26 
27 #include "RooFit.h"
28 #include "Riostream.h"
29 
30 #include "RooSimSplitGenContext.h"
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 
40 using namespace RooFit ;
41 
42 #include <string>
43 
44 using 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 
55 RooSimSplitGenContext::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 ;
71  _isValid = kFALSE ;
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 ;
93  _isValid = kFALSE ;
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::ctor(" << GetName() << ") ERROR: Need either extended mode"
104  << " to calculate number of events per category" << 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 {
198  _idxCat = (RooAbsCategoryLValue*) theEvent.find(_idxCat->GetName()) ;
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) {
265  Double_t rand = RooRandom::uniform() ;
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 
316 RooDataSet* 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 
346 void RooSimSplitGenContext::printMultiline(ostream &os, Int_t content, Bool_t verbose, TString indent) const
347 {
348  RooAbsGenContext::printMultiline(os,content,verbose,indent) ;
349  os << indent << "--- RooSimSplitGenContext ---" << endl ;
350  os << indent << "Using PDF ";
352 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
#define coutE(a)
Definition: RooMsgService.h:35
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 generateEvent(RooArgSet &theEvent, Int_t remaining)
this method is empty because it is not used in this type of context
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:86
virtual void Reset()=0
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Definition: RooAbsArg.h:194
#define coutI(a)
Definition: RooMsgService.h:32
virtual void setExpectedData(Bool_t)
Forward to components.
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
RooCmdArg Link(const char *state, RooAbsData &data)
Bool_t isValid() const
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
RooSimSplitGenContext is an efficient implementation of the generator context specific for RooSimulta...
STL namespace.
Iterator abstract base class.
Definition: TIterator.h:32
RooDataSet * createDataSet(const char *name, const char *title, const RooArgSet &obs)
this method is empty because it is not used by this context
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:188
#define oocoutE(o, a)
Definition: RooMsgService.h:48
virtual void attach(const RooArgSet &params)
Attach the index category clone to the given event buffer.
virtual void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Detailed printing interface.
virtual void initGenerator(const RooArgSet &theEvent)
Perform one-time initialization of generator context.
const RooAbsCategory & arg() const
RooCatType is an auxilary class for RooAbsCategory and defines a a single category state...
Definition: RooCatType.h:23
RooAbsGenContext is the abstract base class for generator contexts of RooAbsPdf objects.
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
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:604
virtual const char * name() const
Definition: RooArgProxy.h:42
const int nEvents
Definition: testRooFit.cxx:42
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
RooAbsArg * absArg() const
Definition: RooArgProxy.h:37
static void indent(ostringstream &buf, int indent_level)
const RooSimultaneous * _pdf
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:29
RooCategory represents a fundamental (non-derived) discrete value object.
Definition: RooCategory.h:25
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:1647
Bool_t canBeExtended() const
Definition: RooAbsPdf.h:216
TIterator * serverIterator() const
Definition: RooAbsArg.h:112
RooCmdArg Index(RooCategory &icat)
RooArgSet * _theEvent
#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:84
RooAbsArg * find(const char *name) const
Find object with given name in list.
double Double_t
Definition: RtypesCore.h:55
std::vector< int > _gcIndex
virtual void setProtoDataOrder(Int_t *lut)
this method is empty because proto datasets are not supported by this context
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.
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 Bool_t isDerived() const
Definition: RooAbsArg.h:81
Int_t getVal() const
Definition: RooCatType.h:80
virtual TObject * Next()=0
RooAbsCategory is the common abstract base class for objects that represent a discrete value with a f...
RooRealProxy is the concrete proxy for RooAbsReal objects A RooRealProxy is the general mechanism to ...
Definition: RooRealProxy.h:23
virtual ~RooSimSplitGenContext()
Destructor. Delete all owned subgenerator contexts.
RooAbsCategoryLValue * _idxCat
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...
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:1088
const Bool_t kTRUE
Definition: Rtypes.h:91
RooSimultaneous facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset...
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.
return
Definition: HLFactory.cxx:514