Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooConvGenContext.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 RooConvGenContext.cxx
19\class RooConvGenContext
20\ingroup Roofitcore
21
22Efficient implementation of the generator context
23specific for RooAbsAnaConvPdf objects. The physics model is generated
24with a truth resolution model and the requested resolution model is generated
25separately as a PDF. The convolution variable of the physics model is
26subsequently explicitly smeared with the resolution model distribution.
27**/
28
29#include "RooMsgService.h"
30#include "RooErrorHandler.h"
31#include "RooConvGenContext.h"
32#include "RooAbsAnaConvPdf.h"
33#include "RooNumConvPdf.h"
34#include "RooFFTConvPdf.h"
35#include "RooDataSet.h"
36#include "RooArgSet.h"
37#include "RooTruthModel.h"
38
39#include <ostream>
40
41using std::ostream;
42
43
44////////////////////////////////////////////////////////////////////////////////
45/// Constructor for specialized generator context for analytical convolutions.
46///
47/// Builds a generator for the physics PDF convoluted with the truth model
48/// and a generator for the resolution model as PDF. Events are generated
49/// by sampling events from the p.d.f and smearings from the resolution model
50/// and adding these to obtain a distribution of events consistent with the
51/// convolution of these two. The advantage of this procedure is so that
52/// both p.d.f and resolution model can take advantage of any internal
53/// generators that may be defined.
54
56 const RooDataSet *prototype, const RooArgSet* auxProto, bool verbose) :
57 RooAbsGenContext(model,vars,prototype,auxProto,verbose)
58{
59 cxcoutI(Generation) << "RooConvGenContext::ctor() setting up special generator context for analytical convolution p.d.f. " << model.GetName()
60 << " for generation of observable(s) " << vars << std::endl ;
61
62 // Clone PDF and change model to internal truth model
63 _pdfCloneSet = std::make_unique<RooArgSet>();
64 RooArgSet(model).snapshot(*_pdfCloneSet, true);
65 if (!_pdfCloneSet) {
66 coutE(Generation) << "RooConvGenContext::RooConvGenContext(" << GetName() << ") Couldn't deep-clone PDF, abort," << std::endl ;
68 }
69
70 RooAbsAnaConvPdf* pdfClone = static_cast<RooAbsAnaConvPdf*>(_pdfCloneSet->find(model.GetName())) ;
71 RooTruthModel truthModel("truthModel","Truth resolution model",*pdfClone->convVar()) ;
72 pdfClone->changeModel(truthModel) ;
73 auto convV = dynamic_cast<RooRealVar*>(pdfClone->convVar());
74 if (!convV) {
75 throw std::runtime_error("RooConvGenContext only works with convolution variables of type RooRealVar.");
76 }
77 convV->removeMin();
78 convV->removeMax();
79
80 // Create generator for physics X truth model
81 _pdfVars = std::unique_ptr<RooArgSet>{pdfClone->getObservables(&vars)};
82 _pdfGen.reset(pdfClone->genContext(*_pdfVars,prototype,auxProto,verbose));
83
84 // Clone resolution model and use as normal PDF
85 _modelCloneSet = std::make_unique<RooArgSet>();
86 RooArgSet(*model._convSet.at(0)).snapshot(*_modelCloneSet, true);
87 if (!_modelCloneSet) {
88 coutE(Generation) << "RooConvGenContext::RooConvGenContext(" << GetName() << ") Couldn't deep-clone resolution model, abort," << std::endl;
90 }
91 std::unique_ptr<RooResolutionModel> modelClone{static_cast<RooResolutionModel*>(_modelCloneSet->find(model._convSet.at(0)->GetName())->Clone("smearing"))};
92 modelClone->changeBasis(nullptr) ;
93 convV = dynamic_cast<RooRealVar*>(&modelClone->convVar());
94 if (!convV) {
95 throw std::runtime_error("RooConvGenContext only works with convolution variables of type RooRealVar.");
96 }
97 convV->removeMin();
98 convV->removeMax();
99
100 // Create generator for resolution model as PDF
101 _modelVars = std::unique_ptr<RooArgSet>{modelClone->getObservables(&vars)};
102
103 _modelVars->add(modelClone->convVar()) ;
104 _convVarName = modelClone->convVar().GetName() ;
105 _modelGen.reset(modelClone->genContext(*_modelVars,prototype,auxProto,verbose));
106
107 _modelCloneSet->addOwned(std::move(modelClone));
108
109 if (prototype) {
110 _pdfVars->add(*prototype->get()) ;
111 _modelVars->add(*prototype->get()) ;
112 }
113
114 // WVE ADD FOR DEBUGGING
115 if (auxProto) {
116 _pdfVars->add(*auxProto) ;
117 _modelVars->add(*auxProto) ;
118 }
119}
120
121
122
123////////////////////////////////////////////////////////////////////////////////
124/// Constructor for specialized generator context for numerical convolutions.
125///
126/// Builds a generator for the physics PDF convoluted with the truth model
127/// and a generator for the resolution model as PDF. Events are generated
128/// by sampling events from the p.d.f and smearings from the resolution model
129/// and adding these to obtain a distribution of events consistent with the
130/// convolution of these two. The advantage of this procedure is so that
131/// both p.d.f and resolution model can take advantage of any internal
132/// generators that may be defined.
133
135 const RooDataSet *prototype, const RooArgSet* auxProto, bool verbose) :
136 RooAbsGenContext(model,vars,prototype,auxProto,verbose)
137{
138 cxcoutI(Generation) << "RooConvGenContext::ctor() setting up special generator context for numeric convolution p.d.f. " << model.GetName()
139 << " for generation of observable(s) " << vars << std::endl ;
140
141 // Create generator for physics X truth model
142 {
143 RooArgSet clonedPdfObservables;
144 model.conv().clonePdf().getObservables(&vars, clonedPdfObservables);
145 _pdfVarsOwned = std::make_unique<RooArgSet>();
146 clonedPdfObservables.snapshot(*_pdfVarsOwned, true);
147 }
148 _pdfVars = std::make_unique<RooArgSet>(*_pdfVarsOwned) ;
149 _pdfGen.reset(static_cast<RooAbsPdf&>(model.conv().clonePdf()).genContext(*_pdfVars,prototype,auxProto,verbose));
150
151 // Create generator for resolution model as PDF
152 {
153 RooArgSet clonedModelObservables;
154 model.conv().cloneModel().getObservables(&vars, clonedModelObservables);
155 _modelVarsOwned = std::make_unique<RooArgSet>();
156 clonedModelObservables.snapshot(*_modelVarsOwned, true);
157 }
158 _modelVars = std::make_unique<RooArgSet>(*_modelVarsOwned) ;
159 _convVarName = model.conv().cloneVar().GetName() ;
160 _modelGen.reset(static_cast<RooAbsPdf&>(model.conv().cloneModel()).genContext(*_modelVars,prototype,auxProto,verbose));
161 _modelCloneSet = std::make_unique<RooArgSet>();
162 _modelCloneSet->add(model.conv().cloneModel()) ;
163
164 if (prototype) {
165 _pdfVars->add(*prototype->get()) ;
166 _modelVars->add(*prototype->get()) ;
167 }
168}
169
170
171
172////////////////////////////////////////////////////////////////////////////////
173/// Constructor for specialized generator context for FFT numerical convolutions.
174///
175/// Builds a generator for the physics PDF convoluted with the truth model
176/// and a generator for the resolution model as PDF. Events are generated
177/// by sampling events from the p.d.f and smearings from the resolution model
178/// and adding these to obtain a distribution of events consistent with the
179/// convolution of these two. The advantage of this procedure is so that
180/// both p.d.f and resolution model can take advantage of any internal
181/// generators that may be defined.
182
184 const RooDataSet *prototype, const RooArgSet* auxProto, bool verbose) :
185 RooAbsGenContext(model,vars,prototype,auxProto,verbose)
186{
187 cxcoutI(Generation) << "RooConvGenContext::ctor() setting up special generator context for fft convolution p.d.f. " << model.GetName()
188 << " for generation of observable(s) " << vars << std::endl ;
189
190 _convVarName = model._x.arg().GetName() ;
191
192 // Create generator for physics model
193 _pdfCloneSet = std::make_unique<RooArgSet>();
194 RooArgSet(model._pdf1.arg()).snapshot(*_pdfCloneSet, true);
195 RooAbsPdf* pdfClone = static_cast<RooAbsPdf*>(_pdfCloneSet->find(model._pdf1.arg().GetName())) ;
196 RooRealVar* cvPdf = static_cast<RooRealVar*>(_pdfCloneSet->find(model._x.arg().GetName())) ;
197 cvPdf->removeMin() ;
198 cvPdf->removeMax() ;
199 RooArgSet tmp1;
200 pdfClone->getObservables(&vars, tmp1) ;
201 _pdfVarsOwned = std::make_unique<RooArgSet>();
202 tmp1.snapshot(*_pdfVarsOwned, true);
203 _pdfVars = std::make_unique<RooArgSet>(*_pdfVarsOwned) ;
204 _pdfGen.reset(pdfClone->genContext(*_pdfVars,prototype,auxProto,verbose));
205
206 // Create generator for resolution model
207 _modelCloneSet = std::make_unique<RooArgSet>();
208 RooArgSet(model._pdf2.arg()).snapshot(*_modelCloneSet, true);
209 RooAbsPdf* modelClone = static_cast<RooAbsPdf*>(_modelCloneSet->find(model._pdf2.arg().GetName())) ;
210 RooRealVar* cvModel = static_cast<RooRealVar*>(_modelCloneSet->find(model._x.arg().GetName())) ;
211 cvModel->removeMin() ;
212 cvModel->removeMax() ;
213 RooArgSet tmp2;
214 modelClone->getObservables(&vars, tmp2) ;
215 _modelVarsOwned = std::make_unique<RooArgSet>();
216 tmp2.snapshot(*_modelVarsOwned, true);
217 _modelVars = std::make_unique<RooArgSet>(*_modelVarsOwned) ;
218 _modelGen.reset(modelClone->genContext(*_pdfVars,prototype,auxProto,verbose));
219
220 if (prototype) {
221 _pdfVars->add(*prototype->get()) ;
222 _modelVars->add(*prototype->get()) ;
223 }
224}
225
226
227////////////////////////////////////////////////////////////////////////////////
228/// Attach given set of arguments to internal clones of
229/// pdf and resolution model
230
232{
233 // Find convolution variable in input and output sets
234 auto* cvModel = static_cast<RooRealVar*>(_modelVars->find(_convVarName));
235 auto* cvPdf = static_cast<RooRealVar*>(_pdfVars->find(_convVarName));
236
237 // Replace all servers in _pdfVars and _modelVars with those in theEvent, except for the convolution variable
238 std::unique_ptr<RooArgSet> pdfCommon{args.selectCommon(*_pdfVars)};
239 pdfCommon->remove(*cvPdf,true,true) ;
240
241 std::unique_ptr<RooArgSet> modelCommon{args.selectCommon(*_modelVars)};
242 modelCommon->remove(*cvModel,true,true) ;
243
244 _pdfGen->attach(*pdfCommon) ;
245 _modelGen->attach(*modelCommon) ;
246}
247
248
249////////////////////////////////////////////////////////////////////////////////
250/// One-time initialization of generator context, attaches
251/// the context to the supplied event container
252
254{
255 // Find convolution variable in input and output sets
256 _cvModel = static_cast<RooRealVar*>(_modelVars->find(_convVarName)) ;
257 _cvPdf = static_cast<RooRealVar*>(_pdfVars->find(_convVarName)) ;
258 _cvOut = static_cast<RooRealVar*>(theEvent.find(_convVarName)) ;
259
260 // Replace all servers in _pdfVars and _modelVars with those in theEvent, except for the convolution variable
261 std::unique_ptr<RooArgSet> pdfCommon{theEvent.selectCommon(*_pdfVars)};
262 pdfCommon->remove(*_cvPdf,true,true) ;
263 _pdfVars->replace(*pdfCommon) ;
264
265 std::unique_ptr<RooArgSet> modelCommon{theEvent.selectCommon(*_modelVars)};
266 modelCommon->remove(*_cvModel,true,true) ;
267 _modelVars->replace(*modelCommon) ;
268
269 // Initialize component generators
270 _pdfGen->initGenerator(*_pdfVars) ;
271 _modelGen->initGenerator(*_modelVars) ;
272}
273
274
275
276////////////////////////////////////////////////////////////////////////////////
277/// Generate a single event
278
280{
281 while(true) {
282
283 // Generate pdf and model data
284 _modelGen->generateEvent(*_modelVars,remaining) ;
285 _pdfGen->generateEvent(*_pdfVars,remaining) ;
286
287 // Construct smeared convolution variable
288 double convValSmeared = _cvPdf->getVal() + _cvModel->getVal() ;
289 if (_cvOut->isValidReal(convValSmeared)) {
290 // Smeared value in acceptance range, transfer values to output set
291 theEvent.assign(*_modelVars) ;
292 theEvent.assign(*_pdfVars) ;
293 _cvOut->setVal(convValSmeared) ;
294 return ;
295 }
296 }
297}
298
299
300
301////////////////////////////////////////////////////////////////////////////////
302/// Set the traversal order for events in the prototype dataset
303/// The argument is a array of integers with a size identical
304/// to the number of events in the prototype dataset. Each element
305/// should contain an integer in the range 1-N.
306
308{
310 _modelGen->setProtoDataOrder(lut) ;
311 _pdfGen->setProtoDataOrder(lut) ;
312}
313
314
315////////////////////////////////////////////////////////////////////////////////
316/// Print the details of this generator context
317
318void RooConvGenContext::printMultiline(ostream &os, Int_t content, bool verbose, TString indent) const
319{
320 RooAbsGenContext::printMultiline(os,content,verbose,indent) ;
321 os << indent << "--- RooConvGenContext ---" << std::endl ;
322 os << indent << "List of component generators" << std::endl ;
323
324 TString indent2(indent) ;
325 indent2.Append(" ") ;
326
327 _modelGen->printMultiline(os,content,verbose,indent2);
328 _pdfGen->printMultiline(os,content,verbose,indent2);
329}
#define cxcoutI(a)
#define coutE(a)
static void indent(ostringstream &buf, int indent_level)
Base class for PDFs that represent a physics model that can be analytically convolved with a resoluti...
virtual bool changeModel(const RooResolutionModel &newModel)
Change the current resolution model to newModel.
RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=nullptr, const RooArgSet *auxProto=nullptr, bool verbose=false) const override
Create a generator context for this p.d.f.
RooAbsRealLValue * convVar()
Retrieve the convolution variable.
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for generator contexts of RooAbsPdf objects.
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:32
virtual RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=nullptr, const RooArgSet *auxProto=nullptr, bool verbose=false) const
Interface function to create a generator context from a p.d.f.
bool isValidReal(double value, bool printError=false) const override
Check if given value is valid.
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:107
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:159
RooArgSet * selectCommon(const RooAbsCollection &refColl) const
Use RooAbsCollection::selecCommon(), but return as RooArgSet.
Definition RooArgSet.h:154
std::unique_ptr< RooAbsGenContext > _modelGen
Resolution model generator context.
RooConvGenContext(const RooFFTConvPdf &model, const RooArgSet &vars, const RooDataSet *prototype=nullptr, const RooArgSet *auxProto=nullptr, bool _verbose=false)
Constructor for specialized generator context for FFT numerical convolutions.
std::unique_ptr< RooArgSet > _pdfCloneSet
Owner of PDF clone.
void setProtoDataOrder(Int_t *lut) override
Set the traversal order for events in the prototype dataset The argument is a array of integers with ...
std::unique_ptr< RooArgSet > _pdfVars
Holder of PDF x truth event.
std::unique_ptr< RooArgSet > _modelVars
Holder of resModel event.
RooRealVar * _cvPdf
Convolution variable in PDFxTruth event.
std::unique_ptr< RooArgSet > _modelVarsOwned
Owning version of modelVars ;.
void attach(const RooArgSet &params) override
Attach given set of arguments to internal clones of pdf and resolution model.
std::unique_ptr< RooArgSet > _modelCloneSet
Owner of resModel clone.
RooRealVar * _cvOut
Convolution variable in output event.
RooRealVar * _cvModel
Convolution variable in resModel event.
void generateEvent(RooArgSet &theEvent, Int_t remaining) override
Generate a single event.
void initGenerator(const RooArgSet &theEvent) override
One-time initialization of generator context, attaches the context to the supplied event container.
std::unique_ptr< RooArgSet > _pdfVarsOwned
Owning version of pdfVars ;.
TString _convVarName
Name of convolution variable.
void printMultiline(std::ostream &os, Int_t content, bool verbose=false, TString indent="") const override
Print the details of this generator context.
std::unique_ptr< RooAbsGenContext > _pdfGen
Physics model generator context.
Container class to hold unbinned data.
Definition RooDataSet.h:32
const RooArgSet * get(Int_t index) const override
Return RooArgSet with coordinates of event 'index'.
static void softAbort()
Soft abort function that interrupts macro execution but doesn't kill ROOT.
PDF for the numerical (FFT) convolution of two PDFs.
Numeric 1-dimensional convolution operator PDF.
Variable that can be changed from the outside.
Definition RooRealVar.h:37
void removeMin(const char *name=nullptr)
Remove lower range limit for binning with given name. Empty name means default range.
void setVal(double value) override
Set value of variable to 'value'.
void removeMax(const char *name=nullptr)
Remove upper range limit for binning with given name. Empty name means default range.
RooResolutionModel is the base class for PDFs that represent a resolution model that can be convolute...
virtual void changeBasis(RooFormulaVar *basis)
Change the basis function we convolute with.
Implements a RooResolution model that corresponds to a delta function.
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Basic string class.
Definition TString.h:137
TString & Append(const char *cs)
Definition TString.h:582