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 verbose, bool 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 RooAbsCategoryLValue const& idxCat = model.indexCat();
57 RooArgSet pdfVars(vars) ;
58
59 RooArgSet allPdfVars(pdfVars) ;
60
61 RooArgSet catsAmongAllVars;
62 allPdfVars.selectCommon(model.flattenedCatList(), catsAmongAllVars);
63
64 if(catsAmongAllVars.size() != model.flattenedCatList().size()) {
65 oocoutE(_pdf,Generation) << "RooSimSplitGenContext::ctor(" << GetName() << ") ERROR: This context must"
66 << " generate all components of the index category" << endl ;
67 _isValid = false ;
68 _numPdf = 0 ;
69 // coverity[UNINIT_CTOR]
70 return ;
71 }
72
73 // We must extended likelihood to determine the relative fractions of the components
74 _idxCatName = idxCat.GetName() ;
75 if (!model.canBeExtended()) {
76 oocoutE(_pdf,Generation) << "RooSimSplitGenContext::RooSimSplitGenContext(" << GetName() << "): All components of the simultaneous PDF "
77 << "must be extended PDFs. Otherwise, it is impossible to calculate the number of events to be generated per component." << endl ;
78 _isValid = false ;
79 _numPdf = 0 ;
80 // coverity[UNINIT_CTOR]
81 return ;
82 }
83
84 // Initialize fraction threshold array (used only in extended mode)
85 _numPdf = model._pdfProxyList.GetSize() ;
86 _fracThresh = new double[_numPdf+1] ;
87 _fracThresh[0] = 0 ;
88
89 // Generate index category and all registered PDFS
90 _allVarsPdf.add(allPdfVars) ;
91 Int_t i(1) ;
92 for(auto * proxy : static_range_cast<RooRealProxy*>(model._pdfProxyList)) {
93 auto pdf = static_cast<RooAbsPdf*>(proxy->absArg());
94
95 // Create generator context for this PDF
96 RooArgSet* compVars = pdf->getObservables(pdfVars) ;
97 RooAbsGenContext* cx = pdf->autoGenContext(*compVars,0,0,verbose,autoBinned,binnedTag) ;
98 delete compVars ;
99
100 const auto state = idxCat.lookupIndex(proxy->name());
101
102 cx->SetName(proxy->name()) ;
103 _gcList.push_back(cx) ;
104 _gcIndex.push_back(state);
105
106 // Fill fraction threshold array
107 _fracThresh[i] = _fracThresh[i-1] + pdf->expectedEvents(&allPdfVars) ;
108 i++ ;
109 }
110
111 for(i=0 ; i<_numPdf ; i++) {
113 }
114
115 // Clone the index category
116 if(RooArgSet(model.indexCat()).snapshot(_idxCatSet, true)) {
117 oocoutE(_pdf,Generation) << "RooSimSplitGenContext::RooSimSplitGenContext(" << GetName() << ") Couldn't deep-clone index category, abort," << endl ;
118 throw std::string("RooSimSplitGenContext::RooSimSplitGenContext() Couldn't deep-clone index category, abort") ;
119 }
120 _idxCat = static_cast<RooAbsCategoryLValue*>(_idxCatSet.find(model.indexCat().GetName()));
121}
122
123
124
125////////////////////////////////////////////////////////////////////////////////
126/// Destructor. Delete all owned subgenerator contexts
127
129{
130 delete[] _fracThresh ;
131 for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
132 delete (*iter) ;
133 }
134}
135
136
137
138////////////////////////////////////////////////////////////////////////////////
139/// Attach the index category clone to the given event buffer
140
142{
143 if (_idxCat->isDerived()) {
145 }
146
147 // Forward initGenerator call to all components
148 for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
149 (*iter)->attach(args) ;
150 }
151
152}
153
154
155////////////////////////////////////////////////////////////////////////////////
156/// Perform one-time initialization of generator context
157
159{
160 // Attach the index category clone to the event
161 if (_idxCat->isDerived()) {
163 } else {
165 }
166
167 // Forward initGenerator call to all components
168 for (vector<RooAbsGenContext*>::iterator iter = _gcList.begin() ; iter!=_gcList.end() ; ++iter) {
169 (*iter)->initGenerator(theEvent) ;
170 }
171
172}
173
174
175
176////////////////////////////////////////////////////////////////////////////////
177
178RooDataSet* RooSimSplitGenContext::generate(double nEvents, bool skipInit, bool extendedMode)
179{
180 if(!isValid()) {
181 coutE(Generation) << ClassName() << "::" << GetName() << ": context is not valid" << endl;
182 return 0;
183 }
184
185
186 // Calculate the expected number of events if necessary
187 if(nEvents <= 0) {
188 nEvents= _expectedEvents;
189 }
190 coutI(Generation) << ClassName() << "::" << GetName() << ":generate: will generate "
191 << nEvents << " events" << endl;
192
193 if (_verbose) Print("v") ;
194
195 // Perform any subclass implementation-specific initialization
196 // Can be skipped if this is a rerun with an identical configuration
197 if (!skipInit) {
199 }
200
201 // Generate lookup table from expected event counts
202 vector<double> nGen(_numPdf) ;
203 if (extendedMode ) {
204 Int_t i(0) ;
205 for(auto * proxy : static_range_cast<RooRealProxy*>(_pdf->_pdfProxyList)) {
206 RooAbsPdf* pdf=(RooAbsPdf*)proxy->absArg() ;
207 //nGen[i] = Int_t(pdf->expectedEvents(&_allVarsPdf)+0.5) ;
208 nGen[i] = pdf->expectedEvents(&_allVarsPdf) ;
209 i++ ;
210 }
211
212 } else {
213 Int_t i(1) ;
214 _fracThresh[0] = 0 ;
215 for(auto * proxy : static_range_cast<RooRealProxy*>(_pdf->_pdfProxyList)) {
216 RooAbsPdf* pdf=(RooAbsPdf*)proxy->absArg() ;
218 i++ ;
219 }
220 for(i=0 ; i<_numPdf ; i++) {
222 }
223
224 // Determine from that total number of events to be generated for each component
225 double nGenSoFar(0) ;
226 while (nGenSoFar<nEvents) {
227 double rand = RooRandom::uniform() ;
228 i=0 ;
229 for (i=0 ; i<_numPdf ; i++) {
230 if (rand>_fracThresh[i] && rand<_fracThresh[i+1]) {
231 nGen[i]++ ;
232 nGenSoFar++ ;
233 break ;
234 }
235 }
236 }
237 }
238
239
240
241 // Now loop over states
242 map<string,RooAbsData*> dataMap ;
243 Int_t icomp(0) ;
244 for(auto * proxy : static_range_cast<RooRealProxy*>(_pdf->_pdfProxyList)) {
245
246 // Calculate number of events to generate for this state
247 if (_gcList[icomp]) {
248 dataMap[proxy->GetName()] = _gcList[icomp]->generate(nGen[icomp],skipInit,extendedMode) ;
249 }
250
251 icomp++ ;
252 }
253
254 // Put all datasets together in a composite-store RooDataSet that links and owns the component datasets
255 RooDataSet* hmaster = new RooDataSet("hmaster","hmaster",_allVarsPdf,RooFit::Index((RooCategory&)*_idxCat),RooFit::Link(dataMap),RooFit::OwnLinked()) ;
256 return hmaster ;
257}
258
259
260
261////////////////////////////////////////////////////////////////////////////////
262/// Forward to components
263
265{
266 for(auto * elem : _gcList) {
267 elem->setExpectedData(flag) ;
268 }
269}
270
271
272
273////////////////////////////////////////////////////////////////////////////////
274/// this method is empty because it is not used by this context
275
276RooDataSet* RooSimSplitGenContext::createDataSet(const char* , const char* , const RooArgSet& )
277{
278 return nullptr;
279}
280
281
282
283////////////////////////////////////////////////////////////////////////////////
284/// this method is empty because it is not used in this type of context
285
287{
288 assert(0) ;
289}
290
291
292
293
294////////////////////////////////////////////////////////////////////////////////
295/// this method is empty because proto datasets are not supported by this context
296
298{
299 assert(0) ;
300}
301
302
303////////////////////////////////////////////////////////////////////////////////
304/// Detailed printing interface
305
306void RooSimSplitGenContext::printMultiline(ostream &os, Int_t content, bool verbose, TString indent) const
307{
309 os << indent << "--- RooSimSplitGenContext ---" << endl ;
310 os << indent << "Using PDF ";
312}
#define coutI(a)
Definition: RooMsgService.h:34
#define oocoutE(o, a)
Definition: RooMsgService.h:52
#define coutE(a)
Definition: RooMsgService.h:37
#define ClassImp(name)
Definition: Rtypes.h:375
static void indent(ostringstream &buf, int indent_level)
bool recursiveRedirectServers(const RooAbsCollection &newServerList, bool mustReplaceAll=false, bool nameChange=false, bool recurseInNewSet=true)
Recursively replace all servers with the new servers in newSet.
Definition: RooAbsArg.cxx:1219
virtual bool isDerived() const
Does value or shape of this arg depend on any other arg?
Definition: RooAbsArg.h:92
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
value_type lookupIndex(const std::string &stateName) const
Find the index number corresponding to the state name.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
bool selectCommon(const RooAbsCollection &refColl, RooAbsCollection &outColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
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
Pointer to observable event being generated.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Interface for multi-line printing.
void Print(Option_t *options=nullptr) const override
Print TNamed name and title.
UInt_t _expectedEvents
Number of expected events from extended p.d.f.
bool _verbose
Verbose messaging?
bool _isValid
Is context in valid state?
bool isValid() const
virtual double expectedEvents(const RooArgSet *nset) const
Return expected number of events to be used in calculation of extended likelihood.
Definition: RooAbsPdf.cxx:3255
bool canBeExtended() const
If true, PDF can provide extended likelihood term.
Definition: RooAbsPdf.h:278
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:56
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition: RooArgSet.h:179
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 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 setExpectedData(bool) override
Forward to components.
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.
RooSimSplitGenContext(const RooSimultaneous &model, const RooArgSet &vars, bool _verbose=false, bool autoBinned=true, const char *binnedTag="")
Constructor of specialized generator context for RooSimultaneous p.d.f.s.
void initGenerator(const RooArgSet &theEvent) override
Perform one-time initialization of generator context.
double * _fracThresh
fraction thresholds
RooDataSet * createDataSet(const char *name, const char *title, const RooArgSet &obs) override
this method is empty because it is not used by this context
Int_t _numPdf
Number of generated PDFs.
void printMultiline(std::ostream &os, Int_t content, bool verbose=false, TString indent="") const override
Detailed printing interface.
RooArgSet _idxCatSet
Owner of index category components.
const RooSimultaneous * _pdf
Original PDF.
RooDataSet * generate(double nEvents=0, bool skipInit=false, bool extendedMode=false) override
Generate the specified number of events with nEvents>0 and and return a dataset containing the genera...
std::vector< int > _gcIndex
Index value corresponding to component.
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.
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)
RooArgSet const & flattenedCatList() const
Internal utility function to get a list of all category components for this RooSimultaneous.
const RooAbsCategoryLValue & indexCat() const
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:184
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:207
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:62