Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
22Efficient 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#include "RooAddGenContext.h"
31
32#include "Riostream.h"
33#include "TClass.h"
34
35#include "RooDataSet.h"
36#include "RooRandom.h"
37
38#include <sstream>
39
40
42
43
44////////////////////////////////////////////////////////////////////////////////
45/// Constructor
46
48 const RooDataSet *prototype, const RooArgSet* auxProto,
49 bool verbose) :
50 RooAbsGenContext(model,vars,prototype,auxProto,verbose), _isModel(false)
51{
52 cxcoutI(Generation) << "RooAddGenContext::ctor() setting up event special generator context for sum p.d.f. " << model.GetName()
53 << " for generation of observable(s) " << vars ;
54 if (prototype) ccxcoutI(Generation) << " with prototype data for " << *prototype->get() ;
55 if (auxProto && !auxProto->empty()) ccxcoutI(Generation) << " with auxiliary prototypes " << *auxProto ;
56 ccxcoutI(Generation) << std::endl;
57
58 // Constructor. Build an array of generator contexts for each product component PDF
59 _pdfSet = std::make_unique<RooArgSet>();
60 RooArgSet(model).snapshot(*_pdfSet, true);
61 _pdf = static_cast<RooAddPdf*>(_pdfSet->find(model.GetName())) ;
63
64 // Fix normalization set of this RooAddPdf
65 if (prototype)
66 {
67 RooArgSet coefNSet(vars) ;
68 coefNSet.add(*prototype->get()) ;
69 _pdf->fixAddCoefNormalization(coefNSet,false) ;
70 }
71
72 _nComp = model._pdfList.size() ;
73 _coefThresh.resize(_nComp+1);
74 _vars = std::make_unique<RooArgSet>();
75 vars.snapshot(*_vars, false);
76
77 for (const auto arg : model._pdfList) {
78 auto pdf = dynamic_cast<const RooAbsPdf *>(arg);
79 if (!pdf) {
80 coutF(Generation) << "Cannot generate events from an object that is not a PDF.\n\t"
81 << "The offending object is a " << arg->ClassName() << " named '" << arg->GetName() << "'." << std::endl;
82 throw std::invalid_argument("Trying to generate events from on object that is not a PDF.");
83 }
84
85 _gcList.emplace_back(pdf->genContext(vars,prototype,auxProto,verbose));
86 }
87
88 (static_cast<RooAddPdf*>(_pdf))->getProjCache(_vars.get()) ;
90}
91
92
93
94////////////////////////////////////////////////////////////////////////////////
95/// Constructor
96
98 const RooDataSet *prototype, const RooArgSet* auxProto,
99 bool verbose) :
100 RooAbsGenContext(model,vars,prototype,auxProto,verbose), _isModel(true)
101{
102 cxcoutI(Generation) << "RooAddGenContext::ctor() setting up event special generator context for sum resolution model " << model.GetName()
103 << " for generation of observable(s) " << vars ;
104 if (prototype) ccxcoutI(Generation) << " with prototype data for " << *prototype->get() ;
105 if (auxProto && !auxProto->empty()) ccxcoutI(Generation) << " with auxiliary prototypes " << *auxProto ;
106 ccxcoutI(Generation) << std::endl;
107
108 // Constructor. Build an array of generator contexts for each product component PDF
109 _pdfSet = std::make_unique<RooArgSet>();
110 RooArgSet(model).snapshot(*_pdfSet, true);
111 _pdf = static_cast<RooAbsPdf*>(_pdfSet->find(model.GetName())) ;
112
113 _nComp = model._pdfList.size() ;
114 _coefThresh.resize(_nComp+1);
115 _vars = std::make_unique<RooArgSet>();
116 vars.snapshot(*_vars, false);
117
118 for (const auto obj : model._pdfList) {
119 auto pdf = static_cast<RooAbsPdf*>(obj);
120 _gcList.emplace_back(pdf->genContext(vars,prototype,auxProto,verbose));
121 }
122
123 (static_cast<RooAddModel*>(_pdf))->getProjCache(_vars.get()) ;
125}
126
127
128////////////////////////////////////////////////////////////////////////////////
129/// Attach given set of variables to internal p.d.f. clone
130
132{
134
135 // Forward initGenerator call to all components
136 for(auto& gc : _gcList) {
137 gc->attach(args) ;
138 }
139}
140
141
142
143////////////////////////////////////////////////////////////////////////////////
144/// One-time initialization of generator context. Attach theEvent
145/// to internal p.d.f clone and forward initialization call to
146/// the component generators
147
149{
150 _pdf->recursiveRedirectServers(theEvent) ;
151
152 if (_isModel) {
153 RooAddModel* amod = static_cast<RooAddModel*>(_pdf) ;
154 _pcache = amod->getProjCache(_vars.get()) ;
155 } else {
156 RooAddPdf* apdf = static_cast<RooAddPdf*>(_pdf) ;
157 _pcache = apdf->getProjCache(_vars.get(),nullptr) ;
158 }
159
160 // Forward initGenerator call to all components
161 for(auto& gc : _gcList) {
162 gc->initGenerator(theEvent) ;
163 }
164}
165
166
167////////////////////////////////////////////////////////////////////////////////
168/// Randomly choose one of the component contexts to generate this event,
169/// with a probability proportional to its coefficient
170
172{
173 // Throw a random number to determine which component to generate
175 double rand = RooRandom::uniform() ;
176 for (Int_t i=0 ; i<_nComp ; i++) {
177 if (rand>_coefThresh[i] && rand<_coefThresh[i+1]) {
178 _gcList[i]->generateEvent(theEvent,remaining) ;
179 return ;
180 }
181 }
182}
183
184
185////////////////////////////////////////////////////////////////////////////////
186/// Update the cumulative threshold table from the current coefficient
187/// values
188
190{
191 // Templated lambda to support RooAddModel and RooAddPdf
192 auto updateThresholdsImpl = [&](auto* pdf, auto * cache) {
193 pdf->updateCoefficients(*cache,_vars.get()) ;
194
195 _coefThresh[0] = 0. ;
196 for (Int_t i=0 ; i<_nComp ; i++) {
197 double coef = pdf->_coefCache[i];
198 if(coef < 0.0) {
199 std::stringstream errMsgStream;
200 errMsgStream << "RooAddGenContext::updateThresholds(): coefficient number " << i << " of the "
201 << pdf->ClassName() << " \"" << pdf->GetName() << "\"" << " is negative!"
202 << " The current RooAddGenContext doesn't support negative coefficients."
203 << " Please recreate a new generator context with " << pdf->ClassName() << "::genContext()";
204 auto const errMsg = errMsgStream.str();
205 cxcoutE(Generation) << errMsg << std::endl;
206 throw std::runtime_error(errMsg);
207 }
208 _coefThresh[i+1] = coef + _coefThresh[i];
209 }
210 };
211
212 _isModel ? updateThresholdsImpl(static_cast<RooAddModel*>(_pdf), _pcache)
213 : updateThresholdsImpl(static_cast<RooAddPdf*>(_pdf), _pcache);
214}
215
216
217////////////////////////////////////////////////////////////////////////////////
218/// Forward the setProtoDataOrder call to the component generator contexts
219
221{
223 for(auto& gc : _gcList) {
224 gc->setProtoDataOrder(lut) ;
225 }
226}
227
228
229
230////////////////////////////////////////////////////////////////////////////////
231/// Print the details of the context
232
233void RooAddGenContext::printMultiline(std::ostream &os, Int_t content, bool verbose, TString indent) const
234{
235 RooAbsGenContext::printMultiline(os,content,verbose,indent) ;
236 os << indent << "--- RooAddGenContext ---" << std::endl;
237 os << indent << "Using PDF ";
239
240 os << indent << "List of component generators" << std::endl;
241 TString indent2(indent) ;
242 indent2.Append(" ") ;
243 for(auto& gc : _gcList) {
244 gc->printMultiline(os,content,verbose,indent2) ;
245 }
246}
#define cxcoutI(a)
#define coutF(a)
#define cxcoutE(a)
#define ccxcoutI(a)
#define ClassImp(name)
Definition Rtypes.h:377
static void indent(ostringstream &buf, int indent_level)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void gc
bool recursiveRedirectServers(const RooAbsCollection &newServerList, bool mustReplaceAll=false, bool nameChange=false, bool recurseInNewSet=true)
Recursively replace all servers with the new servers in newSet.
void setOperMode(OperMode mode, bool recurseADirty=true)
Set the operation mode of this node.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
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.
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of prototype data to that in the lookup tables passed as argument.
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:40
virtual void fixAddCoefNormalization(const RooArgSet &addNormSet=RooArgSet(), bool force=true)
Fix the interpretation of the coefficient of any RooAddPdf component in the expression tree headed by...
Efficient implementation of the generator context specific for RooAddPdf PDFs.
void setProtoDataOrder(Int_t *lut) override
Forward the setProtoDataOrder call to the component generator contexts.
std::vector< double > _coefThresh
[_nComp] Array of coefficient thresholds
std::unique_ptr< RooArgSet > _pdfSet
Set owned all nodes of internal clone of p.d.f.
std::unique_ptr< RooArgSet > _vars
bool _isModel
Are we generating from a RooAddPdf or a RooAddModel.
void initGenerator(const RooArgSet &theEvent) override
One-time initialization of generator context.
std::vector< std::unique_ptr< RooAbsGenContext > > _gcList
List of component generator contexts.
void updateThresholds()
Update the cumulative threshold table from the current coefficient values.
void printMultiline(std::ostream &os, Int_t content, bool verbose=false, TString indent="") const override
Print the details of the context.
AddCacheElem * _pcache
! RooAddPdf cache element
void attach(const RooArgSet &params) override
Attach given set of variables to internal p.d.f. clone.
Int_t _nComp
Number of PDF components.
RooAddGenContext(const RooAddPdf &model, const RooArgSet &vars, const RooDataSet *prototype=nullptr, const RooArgSet *auxProto=nullptr, bool _verbose=false)
Constructor.
RooAbsPdf * _pdf
Pointer to cloned p.d.f.
void generateEvent(RooArgSet &theEvent, Int_t remaining) override
Randomly choose one of the component contexts to generate this event, with a probability proportional...
RooAddModel is an efficient implementation of a sum of PDFs of the form.
Definition RooAddModel.h:27
RooListProxy _pdfList
List of component PDFs.
AddCacheElem * getProjCache(const RooArgSet *nset, const RooArgSet *iset=nullptr) const
Retrieve cache element with for calculation of p.d.f value with normalization set nset and integrated...
Efficient implementation of a sum of PDFs of the form.
Definition RooAddPdf.h:33
AddCacheElem * getProjCache(const RooArgSet *nset, const RooArgSet *iset=nullptr) const
Manager of cache with coefficient projections and transformations.
RooListProxy _pdfList
List of component PDFs.
Definition RooAddPdf.h:131
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:178
Container class to hold unbinned data.
Definition RooDataSet.h:57
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 uniform(TRandom *generator=randomGenerator())
Return a number uniformly distributed from (0,1)
Definition RooRandom.cxx:78
const char * GetName() const override
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:207
Basic string class.
Definition TString.h:139
TString & Append(const char *cs)
Definition TString.h:572