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
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#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 = (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.getSize() ;
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 ((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 = (RooAbsPdf*) _pdfSet->find(model.GetName()) ;
112
113 _nComp = model._pdfList.getSize() ;
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 ((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 = (RooAddModel*) _pdf ;
154 _pcache = amod->getProjCache(_vars.get()) ;
155 } else {
156 RooAddPdf* apdf = (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.
Int_t getSize() const
Return the number of elements in the collection.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
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...
RooAddGenContext is an 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
RooDataSet is a 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:81
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:576