Logo ROOT  
Reference Guide
RooAddGenContext.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 RooAddGenContext.cxx
19\class RooAddGenContext
20\ingroup Roofitcore
21
22RooAddGenContext is an efficient implementation of the
23generator context specific for RooAddPdf PDFs. The strategy
24of RooAddGenContext is to defer generation of each component
25to a dedicated generator context for that component and to
26randomly choose one of those context to generate an event,
27with a probability proportional to its associated coefficient.
28**/
29
30
31#include "RooFit.h"
32
33#include "Riostream.h"
34#include "TClass.h"
35
36#include "RooMsgService.h"
37#include "RooAddGenContext.h"
38#include "RooAddPdf.h"
39#include "RooDataSet.h"
40#include "RooRandom.h"
41#include "RooAddModel.h"
42
43using namespace std;
44
46;
47
48
49////////////////////////////////////////////////////////////////////////////////
50/// Constructor
51
53 const RooDataSet *prototype, const RooArgSet* auxProto,
55 RooAbsGenContext(model,vars,prototype,auxProto,verbose), _isModel(kFALSE)
56{
57 cxcoutI(Generation) << "RooAddGenContext::ctor() setting up event special generator context for sum p.d.f. " << model.GetName()
58 << " for generation of observable(s) " << vars ;
59 if (prototype) ccxcoutI(Generation) << " with prototype data for " << *prototype->get() ;
60 if (auxProto && auxProto->getSize()>0) ccxcoutI(Generation) << " with auxiliary prototypes " << *auxProto ;
61 ccxcoutI(Generation) << endl ;
62
63 // Constructor. Build an array of generator contexts for each product component PDF
65 _pdf = (RooAddPdf*) _pdfSet->find(model.GetName()) ;
67
68 // Fix normalization set of this RooAddPdf
69 if (prototype)
70 {
71 RooArgSet coefNSet(vars) ;
72 coefNSet.add(*prototype->get()) ;
74 }
75
76 _nComp = model._pdfList.getSize() ;
77 _coefThresh = new Double_t[_nComp+1] ;
78 _vars = (RooArgSet*) vars.snapshot(kFALSE) ;
79
80 for (const auto arg : model._pdfList) {
81 auto pdf = dynamic_cast<const RooAbsPdf *>(arg);
82 if (!pdf) {
83 coutF(Generation) << "Cannot generate events from an object that is not a PDF.\n\t"
84 << "The offending object is a " << arg->IsA()->GetName() << " named '" << arg->GetName() << "'." << std::endl;
85 throw std::invalid_argument("Trying to generate events from on object that is not a PDF.");
86 }
87
88 RooAbsGenContext* cx = pdf->genContext(vars,prototype,auxProto,verbose) ;
89 _gcList.push_back(cx) ;
90 }
91
92 ((RooAddPdf*)_pdf)->getProjCache(_vars) ;
94
95 _mcache = 0 ;
96 _pcache = 0 ;
97}
98
99
100
101////////////////////////////////////////////////////////////////////////////////
102/// Constructor
103
105 const RooDataSet *prototype, const RooArgSet* auxProto,
106 Bool_t verbose) :
107 RooAbsGenContext(model,vars,prototype,auxProto,verbose), _isModel(kTRUE)
108{
109 cxcoutI(Generation) << "RooAddGenContext::ctor() setting up event special generator context for sum resolution model " << model.GetName()
110 << " for generation of observable(s) " << vars ;
111 if (prototype) ccxcoutI(Generation) << " with prototype data for " << *prototype->get() ;
112 if (auxProto && auxProto->getSize()>0) ccxcoutI(Generation) << " with auxiliary prototypes " << *auxProto ;
113 ccxcoutI(Generation) << endl ;
114
115 // Constructor. Build an array of generator contexts for each product component PDF
117 _pdf = (RooAbsPdf*) _pdfSet->find(model.GetName()) ;
118
119 _nComp = model._pdfList.getSize() ;
120 _coefThresh = new Double_t[_nComp+1] ;
121 _vars = (RooArgSet*) vars.snapshot(kFALSE) ;
122
123 for (const auto obj : model._pdfList) {
124 auto pdf = static_cast<RooAbsPdf*>(obj);
125 RooAbsGenContext* cx = pdf->genContext(vars,prototype,auxProto,verbose) ;
126 _gcList.push_back(cx) ;
127 }
128
129 ((RooAddModel*)_pdf)->getProjCache(_vars) ;
131
132 _mcache = 0 ;
133 _pcache = 0 ;
134}
135
136
137
138////////////////////////////////////////////////////////////////////////////////
139/// Destructor. Delete all owned subgenerator contexts
140
142{
143 delete[] _coefThresh ;
144 for (vector<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
145 delete *iter ;
146 }
147 delete _vars ;
148 delete _pdfSet ;
149}
150
151
152
153////////////////////////////////////////////////////////////////////////////////
154/// Attach given set of variables to internal p.d.f. clone
155
157{
159
160 // Forward initGenerator call to all components
161 for (vector<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
162 (*iter)->attach(args) ;
163 }
164}
165
166
167
168////////////////////////////////////////////////////////////////////////////////
169/// One-time initialization of generator contex. Attach theEvent
170/// to internal p.d.f clone and forward initialization call to
171/// the component generators
172
174{
175 _pdf->recursiveRedirectServers(theEvent) ;
176
177 if (_isModel) {
178 RooAddModel* amod = (RooAddModel*) _pdf ;
179 _mcache = amod->getProjCache(_vars) ;
180 } else {
181 RooAddPdf* apdf = (RooAddPdf*) _pdf ;
182 _pcache = apdf->getProjCache(_vars,0,"FULL_RANGE_ADDGENCONTEXT") ;
183 }
184
185 // Forward initGenerator call to all components
186 for (vector<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
187 (*iter)->initGenerator(theEvent) ;
188 }
189}
190
191
192////////////////////////////////////////////////////////////////////////////////
193/// Randomly choose one of the component contexts to generate this event,
194/// with a probability proportional to its coefficient
195
197{
198 // Throw a random number to determin which component to generate
201 Int_t i=0 ;
202 for (i=0 ; i<_nComp ; i++) {
203 if (rand>_coefThresh[i] && rand<_coefThresh[i+1]) {
204 _gcList[i]->generateEvent(theEvent,remaining) ;
205 return ;
206 }
207 }
208}
209
210
211////////////////////////////////////////////////////////////////////////////////
212/// Update the cumulative threshold table from the current coefficient
213/// values
214
216{
217 if (_isModel) {
218
219 RooAddModel* amod = (RooAddModel*) _pdf ;
221
222 _coefThresh[0] = 0. ;
223 Int_t i ;
224 for (i=0 ; i<_nComp ; i++) {
225 _coefThresh[i+1] = amod->_coefCache[i] ;
226 _coefThresh[i+1] += _coefThresh[i] ;
227 }
228
229 } else {
230
231 RooAddPdf* apdf = (RooAddPdf*) _pdf ;
232
234
235 _coefThresh[0] = 0. ;
236 Int_t i ;
237 for (i=0 ; i<_nComp ; i++) {
238 _coefThresh[i+1] = apdf->_coefCache[i] ;
239 _coefThresh[i+1] += _coefThresh[i] ;
240// cout << "RooAddGenContext::updateThresholds(" << GetName() << ") _coefThresh[" << i+1 << "] = " << _coefThresh[i+1] << endl ;
241 }
242
243 }
244
245}
246
247
248////////////////////////////////////////////////////////////////////////////////
249/// Forward the setProtoDataOrder call to the component generator contexts
250
252{
254 for (vector<RooAbsGenContext*>::iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
255 (*iter)->setProtoDataOrder(lut) ;
256 }
257}
258
259
260
261////////////////////////////////////////////////////////////////////////////////
262/// Print the details of the context
263
265{
267 os << indent << "--- RooAddGenContext ---" << endl ;
268 os << indent << "Using PDF ";
270
271 os << indent << "List of component generators" << endl ;
272 TString indent2(indent) ;
273 indent2.Append(" ") ;
274 for (vector<RooAbsGenContext*>::const_iterator iter=_gcList.begin() ; iter!=_gcList.end() ; ++iter) {
275 (*iter)->printMultiline(os,content,verbose,indent2) ;
276 }
277}
#define cxcoutI(a)
Definition: RooMsgService.h:85
#define coutF(a)
Definition: RooMsgService.h:34
#define ccxcoutI(a)
Definition: RooMsgService.h:86
int Int_t
Definition: RtypesCore.h:43
const Bool_t kFALSE
Definition: RtypesCore.h:90
bool Bool_t
Definition: RtypesCore.h:61
double Double_t
Definition: RtypesCore.h:57
const Bool_t kTRUE
Definition: RtypesCore.h:89
#define ClassImp(name)
Definition: Rtypes.h:361
static void indent(ostringstream &buf, int indent_level)
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Change cache operation mode to given mode.
Definition: RooAbsArg.cxx:1718
Bool_t recursiveRedirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t recurseInNewSet=kTRUE)
Definition: RooAbsArg.cxx:1064
Int_t getSize() const
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
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Interface for multi-line printing.
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of prototype data to that in the lookup tables passed as argument.
virtual void fixAddCoefNormalization(const RooArgSet &addNormSet=RooArgSet(), Bool_t force=kTRUE)
Fix the interpretation of the coefficient of any RooAddPdf component in the expression tree headed by...
RooAddGenContext is an efficient implementation of the generator context specific for RooAddPdf PDFs.
RooAddGenContext(const RooAddPdf &model, const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t _verbose=kFALSE)
Constructor.
virtual void initGenerator(const RooArgSet &theEvent)
One-time initialization of generator contex.
virtual ~RooAddGenContext()
Destructor. Delete all owned subgenerator contexts.
virtual void setProtoDataOrder(Int_t *lut)
Forward the setProtoDataOrder call to the component generator contexts.
virtual void generateEvent(RooArgSet &theEvent, Int_t remaining)
Randomly choose one of the component contexts to generate this event, with a probability proportional...
virtual void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Print the details of the context.
void updateThresholds()
Update the cumulative threshold table from the current coefficient values.
std::vector< RooAbsGenContext * > _gcList
RooArgSet * _pdfSet
virtual void attach(const RooArgSet &params)
Attach given set of variables to internal p.d.f. clone.
RooAddModel::CacheElem * _mcache
Double_t * _coefThresh
RooAddPdf::CacheElem * _pcache
RooAddModel cache element.
const RooArgSet * _vars
CacheElem * getProjCache(const RooArgSet *nset, const RooArgSet *iset=0, const char *rangeName=0) const
Retrieve cache element with for calculation of p.d.f value with normalization set nset and integrated...
void updateCoefficients(CacheElem &cache, const RooArgSet *nset) const
Update the coefficient values in the given cache element: calculate new remainder fraction,...
RooListProxy _pdfList
Registry of component analytical integration codes.
Definition: RooAddModel.h:133
Double_t * _coefCache
Definition: RooAddModel.h:99
RooAddPdf is an efficient implementation of a sum of PDFs of the form.
Definition: RooAddPdf.h:29
void updateCoefficients(CacheElem &cache, const RooArgSet *nset) const
Update the coefficient values in the given cache element: calculate new remainder fraction,...
Definition: RooAddPdf.cxx:665
CacheElem * getProjCache(const RooArgSet *nset, const RooArgSet *iset=0, const char *rangeName=0) const
Retrieve cache element for the computation of the PDF normalisation.
Definition: RooAddPdf.cxx:422
RooListProxy _pdfList
Registry of component analytical integration codes.
Definition: RooAddPdf.h:136
std::vector< double > _coefCache
Definition: RooAddPdf.h:102
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition: RooArgSet.h:126
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
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:33
virtual const RooArgSet * get(Int_t index) const override
Return RooArgSet with coordinates of event 'index'.
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:83
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Basic string class.
Definition: TString.h:131
TString & Append(const char *cs)
Definition: TString.h:559
@ Generation
Definition: RooGlobalFunc.h:67