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
22RooConvGenContext is an efficient 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 "RooProdPdf.h"
36#include "RooDataSet.h"
37#include "RooArgSet.h"
38#include "RooTruthModel.h"
39#include "Riostream.h"
40
41
42using namespace std;
43
45;
46
47
48////////////////////////////////////////////////////////////////////////////////
49/// Constructor for specialized generator context for analytical convolutions.
50///
51/// Builds a generator for the physics PDF convoluted with the truth model
52/// and a generator for the resolution model as PDF. Events are generated
53/// by sampling events from the p.d.f and smearings from the resolution model
54/// and adding these to obtain a distribution of events consistent with the
55/// convolution of these two. The advantage of this procedure is so that
56/// both p.d.f and resolution model can take advantage of any internal
57/// generators that may be defined.
58
60 const RooDataSet *prototype, const RooArgSet* auxProto, bool verbose) :
61 RooAbsGenContext(model,vars,prototype,auxProto,verbose)
62{
63 cxcoutI(Generation) << "RooConvGenContext::ctor() setting up special generator context for analytical convolution p.d.f. " << model.GetName()
64 << " for generation of observable(s) " << vars << endl ;
65
66 // Clone PDF and change model to internal truth model
67 _pdfCloneSet.reset(RooArgSet(model).snapshot(true));
68 if (!_pdfCloneSet) {
69 coutE(Generation) << "RooConvGenContext::RooConvGenContext(" << GetName() << ") Couldn't deep-clone PDF, abort," << endl ;
71 }
72
73 RooAbsAnaConvPdf* pdfClone = (RooAbsAnaConvPdf*) _pdfCloneSet->find(model.GetName()) ;
74 RooTruthModel truthModel("truthModel","Truth resolution model",*pdfClone->convVar()) ;
75 pdfClone->changeModel(truthModel) ;
76 auto convV = dynamic_cast<RooRealVar*>(pdfClone->convVar());
77 if (!convV) {
78 throw std::runtime_error("RooConvGenContext only works with convolution variables of type RooRealVar.");
79 }
80 convV->removeRange();
81
82 // Create generator for physics X truth model
83 _pdfVars = std::unique_ptr<RooArgSet>{pdfClone->getObservables(&vars)};
84 _pdfGen.reset(pdfClone->genContext(*_pdfVars,prototype,auxProto,verbose));
85
86 // Clone resolution model and use as normal PDF
87 _modelCloneSet.reset(RooArgSet(*model._convSet.at(0)).snapshot(true));
88 if (!_modelCloneSet) {
89 coutE(Generation) << "RooConvGenContext::RooConvGenContext(" << GetName() << ") Couldn't deep-clone resolution model, abort," << std::endl;
91 }
92 std::unique_ptr<RooResolutionModel> modelClone{static_cast<RooResolutionModel*>(_modelCloneSet->find(model._convSet.at(0)->GetName())->Clone("smearing"))};
93 modelClone->changeBasis(0) ;
94 convV = dynamic_cast<RooRealVar*>(&modelClone->convVar());
95 if (!convV) {
96 throw std::runtime_error("RooConvGenContext only works with convolution variables of type RooRealVar.");
97 }
98 convV->removeRange();
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 << endl ;
140
141 // Create generator for physics X truth model
142 {
143 RooArgSet clonedPdfObservables;
144 model.conv().clonePdf().getObservables(&vars, clonedPdfObservables);
145 _pdfVarsOwned.reset(clonedPdfObservables.snapshot(true));
146 }
147 _pdfVars = std::make_unique<RooArgSet>(*_pdfVarsOwned) ;
148 _pdfGen.reset(static_cast<RooAbsPdf&>(model.conv().clonePdf()).genContext(*_pdfVars,prototype,auxProto,verbose));
149
150 // Create generator for resolution model as PDF
151 {
152 RooArgSet clonedModelObservables;
153 model.conv().cloneModel().getObservables(&vars, clonedModelObservables);
154 _modelVarsOwned.reset(clonedModelObservables.snapshot(true));
155 }
156 _modelVars = std::make_unique<RooArgSet>(*_modelVarsOwned) ;
157 _convVarName = model.conv().cloneVar().GetName() ;
158 _modelGen.reset(static_cast<RooAbsPdf&>(model.conv().cloneModel()).genContext(*_modelVars,prototype,auxProto,verbose));
159 _modelCloneSet = std::make_unique<RooArgSet>();
160 _modelCloneSet->add(model.conv().cloneModel()) ;
161
162 if (prototype) {
163 _pdfVars->add(*prototype->get()) ;
164 _modelVars->add(*prototype->get()) ;
165 }
166}
167
168
169
170////////////////////////////////////////////////////////////////////////////////
171/// Constructor for specialized generator context for FFT numerical convolutions.
172///
173/// Builds a generator for the physics PDF convoluted with the truth model
174/// and a generator for the resolution model as PDF. Events are generated
175/// by sampling events from the p.d.f and smearings from the resolution model
176/// and adding these to obtain a distribution of events consistent with the
177/// convolution of these two. The advantage of this procedure is so that
178/// both p.d.f and resolution model can take advantage of any internal
179/// generators that may be defined.
180
182 const RooDataSet *prototype, const RooArgSet* auxProto, bool verbose) :
183 RooAbsGenContext(model,vars,prototype,auxProto,verbose)
184{
185 cxcoutI(Generation) << "RooConvGenContext::ctor() setting up special generator context for fft convolution p.d.f. " << model.GetName()
186 << " for generation of observable(s) " << vars << endl ;
187
188 _convVarName = model._x.arg().GetName() ;
189
190 // Create generator for physics model
191 _pdfCloneSet.reset(RooArgSet(model._pdf1.arg()).snapshot(true));
192 RooAbsPdf* pdfClone = (RooAbsPdf*) _pdfCloneSet->find(model._pdf1.arg().GetName()) ;
193 RooRealVar* cvPdf = (RooRealVar*) _pdfCloneSet->find(model._x.arg().GetName()) ;
194 cvPdf->removeRange() ;
195 RooArgSet tmp1;
196 pdfClone->getObservables(&vars, tmp1) ;
197 _pdfVarsOwned.reset(tmp1.snapshot(true));
198 _pdfVars = std::make_unique<RooArgSet>(*_pdfVarsOwned) ;
199 _pdfGen.reset(pdfClone->genContext(*_pdfVars,prototype,auxProto,verbose));
200
201 // Create generator for resolution model
202 _modelCloneSet.reset(RooArgSet(model._pdf2.arg()).snapshot(true));
203 RooAbsPdf* modelClone = (RooAbsPdf*) _modelCloneSet->find(model._pdf2.arg().GetName()) ;
204 RooRealVar* cvModel = (RooRealVar*) _modelCloneSet->find(model._x.arg().GetName()) ;
205 cvModel->removeRange() ;
206 RooArgSet tmp2;
207 modelClone->getObservables(&vars, tmp2) ;
208 _modelVarsOwned.reset(tmp2.snapshot(true));
209 _modelVars = std::make_unique<RooArgSet>(*_modelVarsOwned) ;
210 _modelGen.reset(modelClone->genContext(*_pdfVars,prototype,auxProto,verbose));
211
212 if (prototype) {
213 _pdfVars->add(*prototype->get()) ;
214 _modelVars->add(*prototype->get()) ;
215 }
216}
217
218
219////////////////////////////////////////////////////////////////////////////////
220/// Attach given set of arguments to internal clones of
221/// pdf and resolution model
222
224{
225 // Find convolution variable in input and output sets
226 auto* cvModel = static_cast<RooRealVar*>(_modelVars->find(_convVarName));
227 auto* cvPdf = static_cast<RooRealVar*>(_pdfVars->find(_convVarName));
228
229 // Replace all servers in _pdfVars and _modelVars with those in theEvent, except for the convolution variable
230 std::unique_ptr<RooArgSet> pdfCommon{static_cast<RooArgSet*>(args.selectCommon(*_pdfVars))};
231 pdfCommon->remove(*cvPdf,true,true) ;
232
233 std::unique_ptr<RooArgSet> modelCommon{static_cast<RooArgSet*>(args.selectCommon(*_modelVars))};
234 modelCommon->remove(*cvModel,true,true) ;
235
236 _pdfGen->attach(*pdfCommon) ;
237 _modelGen->attach(*modelCommon) ;
238}
239
240
241////////////////////////////////////////////////////////////////////////////////
242/// One-time initialization of generator context, attaches
243/// the context to the supplied event container
244
246{
247 // Find convolution variable in input and output sets
250 _cvOut = (RooRealVar*) theEvent.find(_convVarName) ;
251
252 // Replace all servers in _pdfVars and _modelVars with those in theEvent, except for the convolution variable
253 std::unique_ptr<RooArgSet> pdfCommon{static_cast<RooArgSet*>(theEvent.selectCommon(*_pdfVars))};
254 pdfCommon->remove(*_cvPdf,true,true) ;
255 _pdfVars->replace(*pdfCommon) ;
256
257 std::unique_ptr<RooArgSet> modelCommon{static_cast<RooArgSet*>(theEvent.selectCommon(*_modelVars))};
258 modelCommon->remove(*_cvModel,true,true) ;
259 _modelVars->replace(*modelCommon) ;
260
261 // Initialize component generators
262 _pdfGen->initGenerator(*_pdfVars) ;
263 _modelGen->initGenerator(*_modelVars) ;
264}
265
266
267
268////////////////////////////////////////////////////////////////////////////////
269/// Generate a single event
270
272{
273 while(1) {
274
275 // Generate pdf and model data
276 _modelGen->generateEvent(*_modelVars,remaining) ;
277 _pdfGen->generateEvent(*_pdfVars,remaining) ;
278
279 // Construct smeared convolution variable
280 double convValSmeared = _cvPdf->getVal() + _cvModel->getVal() ;
281 if (_cvOut->isValidReal(convValSmeared)) {
282 // Smeared value in acceptance range, transfer values to output set
283 theEvent.assign(*_modelVars) ;
284 theEvent.assign(*_pdfVars) ;
285 _cvOut->setVal(convValSmeared) ;
286 return ;
287 }
288 }
289}
290
291
292
293////////////////////////////////////////////////////////////////////////////////
294/// Set the traversal order for events in the prototype dataset
295/// The argument is a array of integers with a size identical
296/// to the number of events in the prototype dataset. Each element
297/// should contain an integer in the range 1-N.
298
300{
302 _modelGen->setProtoDataOrder(lut) ;
303 _pdfGen->setProtoDataOrder(lut) ;
304}
305
306
307////////////////////////////////////////////////////////////////////////////////
308/// Print the details of this generator context
309
310void RooConvGenContext::printMultiline(ostream &os, Int_t content, bool verbose, TString indent) const
311{
312 RooAbsGenContext::printMultiline(os,content,verbose,indent) ;
313 os << indent << "--- RooConvGenContext ---" << endl ;
314 os << indent << "List of component generators" << endl ;
315
316 TString indent2(indent) ;
317 indent2.Append(" ") ;
318
319 _modelGen->printMultiline(os,content,verbose,indent2);
320 _pdfGen->printMultiline(os,content,verbose,indent2);
321}
#define cxcoutI(a)
#define coutE(a)
#define ClassImp(name)
Definition Rtypes.h:377
static void indent(ostringstream &buf, int indent_level)
RooAbsAnaConvPdf is the base class for PDFs that represent a physics model that can be analytically c...
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.
RooListProxy _convSet
Set of (resModel (x) basisFunc) convolution objects.
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...
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.
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.
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:91
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
Definition RooArgList.h:110
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
RooConvGenContext is an efficient implementation of the generator context specific for RooAbsAnaConvP...
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.
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'.
static void softAbort()
Soft abort function that interrupts macro execution but doesn't kill ROOT.
PDF for the numerical (FFT) convolution of two PDFs.
RooRealProxy _pdf1
First input p.d.f.
RooRealProxy _x
Convolution observable.
RooRealProxy _pdf2
Second input p.d.f.
Numeric 1-dimensional convolution operator PDF.
RooNumConvolution & conv() const
RooAbsReal & cloneModel() const
RooRealVar & cloneVar() const
RooAbsReal & clonePdf() const
RooRealVar represents a variable that can be changed from the outside.
Definition RooRealVar.h:40
void setVal(double value) override
Set value of variable to 'value'.
void removeRange(const char *name=nullptr)
Remove range limits 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.
const T & arg() const
Return reference to object held in proxy.
RooTruthModel is an implementation of RooResolution model that provides a delta-function resolution m...
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
Basic string class.
Definition TString.h:139
TString & Append(const char *cs)
Definition TString.h:576