Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
RooResolutionModel.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/**
19 * \class RooResolutionModel
20 * RooResolutionModel is the base class for PDFs that represent a
21 * resolution model that can be convoluted with a physics model of the form
22 * \f[
23 * \mathrm{Phys}(x,a,b) = \sum_k \mathrm{coef}_k(a) * \mathrm{basis}_k(x,b)
24 * \f]
25 * where basis_k are a limited number of functions in terms of the variable
26 * to be convoluted and coef_k are coefficients independent of the convolution
27 * variable.
28 *
29 * Classes derived from RooResolutionModel implement
30 * \f[
31 * R_k(x,\bar{b},\bar{c}) = \int \mathrm{basis}_k(x',\bar{b}) * \mathrm{resModel}(x-x',\bar{c}) \; \mathrm{d} x',
32 * \f]
33 * which RooAbsAnaConvPdf uses to construct the pdf for [ Phys (x) R ] :
34 * \f[
35 * \mathrm{PDF}(x,\bar a, \bar b, \bar c) = \sum_k \mathrm{coef}_k(\bar a) * R_k(x, \bar b, \bar c)
36 * \f]
37 *
38 * A minimal implementation of a RooResolutionModel consists of a
39 * ```
40 * Int_t basisCode(const char* name)
41 * ```
42 * function indicating which basis functions this resolution model supports, and
43 * ```
44 * double evaluate(),
45 * ```
46 * which should implement the resolution model (optionally convoluted with one of the
47 * supported basis functions). RooResolutionModel objects can be used as regular
48 * PDFs (They inherit from RooAbsPdf), or as resolution model convoluted with
49 * a basis function. The implementation of evaluate() can identify the requested
50 * mode using basisCode(). If zero, the regular PDF value
51 * should be calculated. If non-zero, the model's value convoluted with the
52 * basis function identified by the code should be calculated.
53 *
54 * Optionally, analytical integrals can be advertised and implemented, in the
55 * same way as done for regular PDFS (see RooAbsPdf for further details).
56 * Also in getAnalyticalIntegral() / analyticalIntegral(), the implementation
57 * should use basisCode() to determine for which scenario the integral is
58 * requested.
59 *
60 * The choice of basis returned by basisCode() is guaranteed not to change
61 * during the lifetime of a RooResolutionModel object.
62 *
63 */
64
65#include "TClass.h"
66#include "TMath.h"
67#include "Riostream.h"
68#include "RooResolutionModel.h"
69#include "RooMsgService.h"
70
71using std::endl, std::ostream;
72
73
74
75////////////////////////////////////////////////////////////////////////////////
76/// Constructor with convolution variable 'x'.
77/// The convolution variable needs to be convertible to real values, and be able
78/// to give information about its range. This is supported by e.g. RooRealVar or RooLinearVar, which
79/// accepts offsetting and scaling an observable.
81 : RooAbsPdf(name, title), x("x", "Dependent or convolution variable", this, _x), _basisCode(0), _ownBasis(false)
82{
83
84}
85
86
87
88////////////////////////////////////////////////////////////////////////////////
89/// Copy constructor
90
92 : RooAbsPdf(other, name), x("x", this, other.x), _basisCode(other._basisCode), _ownBasis(false)
93{
94 if (other._basis) {
95 _basis = static_cast<RooFormulaVar*>(other._basis->Clone()) ;
96 _ownBasis = true ;
97 //_basis = other._basis ;
98 }
99
100 if (_basis) {
101 for (RooAbsArg * basisServer : _basis->servers()) {
102 addServer(*basisServer,true,false) ;
103 }
104 }
105}
106
107
108
109////////////////////////////////////////////////////////////////////////////////
110/// Destructor
111
113{
114 if (_ownBasis && _basis) {
115 delete _basis ;
116 }
117}
118
119
120
121////////////////////////////////////////////////////////////////////////////////
122/// Return identity formula pointer
123
125{
126 static RooFormulaVar identity("identity","1",RooArgSet(""));
127 return &identity;
128}
129
130
131
132////////////////////////////////////////////////////////////////////////////////
133/// Instantiate a clone of this resolution model representing a convolution with given
134/// basis function. The owners object name is incorporated in the clones name
135/// to avoid multiple convolution objects with the same name in complex PDF structures.
136///
137/// Note: The 'inBasis' formula expression must be a RooFormulaVar that encodes the formula
138/// in the title of the object and this expression must be an exact match against the
139/// implemented basis function strings (see derived class implementation of method basisCode()
140/// for those strings
141
143{
144 // Check that primary variable of basis functions is our convolution variable
145 if (inBasis->getParameter(0) != x.absArg()) {
146 coutE(InputArguments) << "RooResolutionModel::convolution(" << GetName() << "," << this
147 << ") convolution parameter of basis function and PDF don't match" << std::endl
148 << "basis->findServer(0) = " << inBasis->findServer(0) << std::endl
149 << "x.absArg() = " << x.absArg() << std::endl ;
150 return nullptr ;
151 }
152
153 if (basisCode(inBasis->GetTitle())==0) {
154 coutE(InputArguments) << "RooResolutionModel::convolution(" << GetName() << "," << this
155 << ") basis function '" << inBasis->GetTitle() << "' is not supported." << std::endl ;
156 return nullptr ;
157 }
158
159 TString newName(GetName()) ;
160 newName.Append("_conv_") ;
161 newName.Append(inBasis->GetName()) ;
162 newName.Append("_[") ;
163 newName.Append(owner->GetName()) ;
164 newName.Append("]") ;
165
166 RooResolutionModel* conv = static_cast<RooResolutionModel*>(clone(newName)) ;
167
168 TString newTitle(conv->GetTitle()) ;
169 newTitle.Append(" convoluted with basis function ") ;
170 newTitle.Append(inBasis->GetName()) ;
171 conv->SetTitle(newTitle.Data()) ;
172
173 conv->changeBasis(inBasis) ;
174
175 return conv ;
176}
177
178
179
180////////////////////////////////////////////////////////////////////////////////
181/// Change the basis function we convolute with.
182/// For one-time use by convolution() only.
183
185{
186 // Remove client-server link to old basis
187 if (_basis) {
188 for (RooAbsArg* basisServer : _basis->servers()) {
189 removeServer(*basisServer) ;
190 }
191
192 if (_ownBasis) {
193 delete _basis ;
194 }
195 }
196 _ownBasis = false ;
197
198 // Change basis pointer and update client-server link
199 _basis = inBasis ;
200 if (_basis) {
201 for (RooAbsArg* basisServer : _basis->servers()) {
202 addServer(*basisServer,true,false) ;
203 }
204 }
205
206 _basisCode = inBasis?basisCode(inBasis->GetTitle()):0 ;
207}
208
209
210
211////////////////////////////////////////////////////////////////////////////////
212/// Return the convolution variable of the selection basis function.
213/// This is, by definition, the first parameter of the basis function
214
216{
217 // Convolution variable is by definition first server of basis function
218 return *static_cast<RooRealVar const*>(*basis().servers().begin());
219}
220
221
222////////////////////////////////////////////////////////////////////////////////
223/// Modified version of RooAbsPdf::getValF(). If used as regular PDF,
224/// call RooAbsPdf::getValF(), otherwise return unnormalized value
225/// regardless of specified normalization set
226
227double RooResolutionModel::getValV(const RooArgSet* nset) const
228{
229 if (!_basis) return RooAbsPdf::getValV(nset) ;
230
231 // Return value of object. Calculated if dirty, otherwise cached value is returned.
232 if (isValueDirty()) {
233 _value = evaluate() ;
234
235 // WVE insert traceEval traceEval
236 if (_verboseDirty) cxcoutD(Tracing) << "RooResolutionModel(" << GetName() << ") value = " << _value << std::endl ;
237
240 }
241
242 return _value ;
243}
244
245
246
247////////////////////////////////////////////////////////////////////////////////
248/// Forward redirectServers call to our basis function, which is not connected to either resolution
249/// model or the physics model.
250
251bool RooResolutionModel::redirectServersHook(const RooAbsCollection& newServerList, bool mustReplaceAll, bool nameChange, bool isRecursive)
252{
253 if (!_basis) {
254 _norm = nullptr ;
255 return false ;
256 }
257
258 RooFormulaVar* newBasis = static_cast<RooFormulaVar*>(newServerList.find(_basis->GetName())) ;
259 if (newBasis) {
260
261 if (_ownBasis) {
262 delete _basis ;
263 }
264
265 _basis = newBasis ;
266 _ownBasis = false ;
267 }
268
269 _basis->redirectServers(newServerList,mustReplaceAll,nameChange) ;
270
271 return (mustReplaceAll && !newBasis) || RooAbsPdf::redirectServersHook(newServerList, mustReplaceAll, nameChange, isRecursive);
272}
273
274
275
276////////////////////////////////////////////////////////////////////////////////
277/// Floating point error checking and tracing for given float value
278
279//bool RooResolutionModel::traceEvalHook(double value) const
280//{
281// // check for a math error or negative value
282// return TMath::IsNaN(value) ;
283//}
284
285
286
287////////////////////////////////////////////////////////////////////////////////
288/// Return the list of servers used by our normalization integral
289
291{
292 _norm->leafNodeServerList(&list) ;
293}
294
295
296
297////////////////////////////////////////////////////////////////////////////////
298/// Return the integral of this PDF over all elements of 'nset'.
299
300double RooResolutionModel::getNorm(const RooArgSet* nset) const
301{
302 if (!nset) {
303 return getVal() ;
304 }
305
306 syncNormalization(nset,false) ;
307 if (_verboseEval>1) cxcoutD(Tracing) << ClassName() << "::getNorm(" << GetName()
308 << "): norm(" << _norm << ") = " << _norm->getVal() << std::endl ;
309
310 double ret = _norm->getVal() ;
311 return ret ;
312}
313
314
315
316////////////////////////////////////////////////////////////////////////////////
317/// Print info about this object to the specified stream. In addition to the info
318/// from RooAbsArg::printStream() we add:
319///
320/// Shape : value, units, plot range
321/// Verbose : default binning and print label
322
323void RooResolutionModel::printMultiline(ostream& os, Int_t content, bool verbose, TString indent) const
324{
325 RooAbsPdf::printMultiline(os,content,verbose,indent) ;
326
327 if(verbose) {
328 os << indent << "--- RooResolutionModel ---" << std::endl;
329 os << indent << "basis function = " ;
330 if (_basis) {
331 _basis->printStream(os,kName|kAddress|kTitle,kSingleLine,indent) ;
332 } else {
333 os << "<none>" << std::endl ;
334 }
335 }
336}
337
#define cxcoutD(a)
#define coutE(a)
char * ret
Definition Rotated.cxx:221
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
static void indent(ostringstream &buf, int indent_level)
if(name) objname
char name[80]
Definition TGX11.cxx:148
@ kName
@ kTitle
void removeServer(RooAbsArg &server, bool force=false)
Unregister another RooAbsArg as a server to us, ie, declare that we no longer depend on its value and...
static bool _verboseDirty
Definition RooAbsArg.h:624
void clearValueDirty() const
Definition RooAbsArg.h:541
const RefCountList_t & servers() const
List of all servers of this object.
Definition RooAbsArg.h:145
void addServer(RooAbsArg &server, bool valueProp=true, bool shapeProp=false, std::size_t refCount=1)
Register another RooAbsArg as a server to us, ie, declare that we depend on it.
bool isValueDirty() const
Definition RooAbsArg.h:356
void clearShapeDirty() const
Definition RooAbsArg.h:542
RooAbsArg()
Default constructor.
friend class RooAbsCollection
Definition RooAbsArg.h:561
RooAbsArg * findServer(const char *name) const
Return server of this with name name. Returns nullptr if not found.
Definition RooAbsArg.h:147
RooAbsArg * find(const char *name) const
Find object with given name in list.
virtual bool syncNormalization(const RooArgSet *dset, bool adjustProxies=true) const
Verify that the normalization integral cached with this PDF is valid for given set of normalization o...
double getValV(const RooArgSet *set=nullptr) const override
Return current value, normalized by integrating over the observables in nset.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Print multi line detailed information of this RooAbsPdf.
RooAbsReal * _norm
! Normalization integral (owned by _normMgr)
Definition RooAbsPdf.h:313
RooAbsPdf()
Default constructor.
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursiveStep) override
Hook function intercepting redirectServer calls.
static Int_t _verboseEval
Definition RooAbsPdf.h:308
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:107
double _value
Cache for current value of object.
Definition RooAbsReal.h:539
virtual double evaluate() const =0
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
RooAbsArg * getParameter(const char *name) const
Return pointer to parameter with given name.
Variable that can be changed from the outside.
Definition RooRealVar.h:37
~RooResolutionModel() override
Destructor.
double getValV(const RooArgSet *nset=nullptr) const override
Modified version of RooAbsPdf::getValF().
virtual void changeBasis(RooFormulaVar *basis)
Change the basis function we convolute with.
virtual Int_t basisCode(const char *name) const =0
virtual RooResolutionModel * convolution(RooFormulaVar *basis, RooAbsArg *owner) const
Instantiate a clone of this resolution model representing a convolution with given basis function.
double getNorm(const RooArgSet *nset=nullptr) const override
Return the integral of this PDF over all elements of 'nset'.
static RooFormulaVar * identity()
Return identity formula pointer.
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursive) override
Forward redirectServers call to our basis function, which is not connected to either resolution model...
const RooRealVar & basisConvVar() const
Return the convolution variable of the selection basis function.
bool _ownBasis
Flag indicating ownership of _basis.
virtual void normLeafServerList(RooArgSet &list) const
Floating point error checking and tracing for given float value.
void printMultiline(std::ostream &os, Int_t content, bool verbose=false, TString indent="") const override
Print info about this object to the specified stream.
Int_t _basisCode
Identifier code for selected basis function.
TObject * clone(const char *newname=nullptr) const override=0
RooResolutionModel()=default
RooFormulaVar * _basis
Basis function convolved with this resolution model.
const RooFormulaVar & basis() const
RooTemplateProxy< RooAbsRealLValue > x
Dependent/convolution variable.
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:173
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:227
Basic string class.
Definition TString.h:138
const char * Data() const
Definition TString.h:384
TString & Append(const char *cs)
Definition TString.h:581