```/*****************************************************************************
* Project: RooFit                                                           *
* Package: RooFitCore                                                       *
* @(#)root/roofitcore:\$Id\$
* Authors:                                                                  *
*   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
*   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
*                                                                           *
* Copyright (c) 2000-2005, Regents of the University of California          *
*                                                                           *
* Redistribution and use in source and binary forms,                        *
* with or without modification, are permitted according to the terms        *
*****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
//
// BEGIN_HTML
// Numeric 1-dimensional convolution operator PDF. This class can convolve any PDF
// with any other PDF using a straightforward numeric calculation of the
// convolution integral
// <p>
// This class should be used as last resort as numeric convolution calculated
// this way is computationally intensive and prone to stability fitting problems.
// <b>The preferred way to compute numeric convolutions is RooFFTConvPdf</b>,
// which calculates convolutions using Fourier Transforms (requires external free
// FFTW3 package)
// <p>
// RooNumConvPdf implements reasonable defaults that should convolve most
// functions reasonably well, but results strongly depend on the shape of your
// input PDFS so always check your result.
// <p>
// The default integration engine for the numeric convolution is the
// adaptive Gauss-Kronrod method, which empirically seems the most robust
// for this task. You can override the convolution integration settings via
// the RooNumIntConfig object reference returned by the convIntConfig() member
// function
// <p>
// By default the numeric convolution is integrated from -infinity to
// +infinity through a <pre>x -> 1/x</pre> coordinate transformation of the
// tails. For convolution with a very small bandwidth it may be
// advantageous (for both CPU consumption and stability) if the
// integration domain is limited to a finite range. The function
// setConvolutionWindow(mean,width,scale) allows to set a sliding
// window around the x value to be calculated taking a RooAbsReal
// expression for an offset and a width to be taken around the x
// value. These input expression can be RooFormulaVars or other
// function objects although the 3d 'scale' argument 'scale'
// multiplies the width RooAbsReal expression given in the 2nd
// argument, allowing for an appropriate window definition for most
// cases without need for a RooFormulaVar object: e.g. a Gaussian
// resolution PDF do setConvolutionWindow(gaussMean,gaussSigma,5)
// Note that for a 'wide' Gaussian the -inf to +inf integration
// may converge more quickly than that over a finite range!
// <p>
// The default numeric precision is 1e-7, i.e. the global default for
// numeric integration but you should experiment with this value to
// see if it is sufficient for example by studying the number of function
// calls that MINUIT needs to fit your function as function of the
// convolution precision.
// END_HTML
//

#include "RooFit.h"

#include "Riostream.h"
#include "Riostream.h"
#include "TH2F.h"
#include "RooNumConvPdf.h"
#include "RooArgList.h"
#include "RooRealVar.h"
#include "RooFormulaVar.h"
#include "RooCustomizer.h"
#include "RooConvIntegrandBinding.h"
#include "RooNumIntFactory.h"
#include "RooGenContext.h"
#include "RooConvGenContext.h"

using namespace std;

ClassImp(RooNumConvPdf)
;

//_____________________________________________________________________________
RooNumConvPdf::RooNumConvPdf() :
_init(kFALSE),
_conv(0)
{
}

//_____________________________________________________________________________R
RooNumConvPdf::RooNumConvPdf(const char *name, const char *title, RooRealVar& convVar, RooAbsPdf& inPdf, RooAbsPdf& resmodel) :
RooAbsPdf(name,title),
_init(kFALSE),
_conv(0),
_origVar("!origVar","Original Convolution variable",this,convVar),
_origPdf("!origPdf","Original Input PDF",this,inPdf),
_origModel("!origModel","Original Resolution model",this,resmodel)
{
// Constructor of convolution operator PDF
//
// convVar  :  convolution variable (on which both pdf and resmodel should depend)
// pdf      :  input 'physics' pdf
// resmodel :  input 'resultion' pdf
//
// output is pdf(x) (X) resmodel(x) = Int [ pdf(x') resmodel (x-x') ] dx'
//
}

//_____________________________________________________________________________
RooNumConvPdf::RooNumConvPdf(const RooNumConvPdf& other, const char* name) :
RooAbsPdf(other,name),
_init(kFALSE),
_origVar("!origVar",this,other._origVar),
_origPdf("!origPdf",this,other._origPdf),
_origModel("!origModel",this,other._origModel)
{
// Copy constructor

// Make temporary clone of original convolution to preserve configuration information
// This information will be propagated to a newly create convolution in a subsequent
// call to initialize()
if (other._conv) {
_conv = new RooNumConvolution(*other._conv,Form("%s_CONV",name?name:GetName())) ;
} else {
_conv = 0 ;
}
}

//_____________________________________________________________________________
RooNumConvPdf::~RooNumConvPdf()
{
// Destructor
if (_init) {
delete _conv ;
}
}

//_____________________________________________________________________________
Double_t RooNumConvPdf::evaluate() const
{
// Calculate and return value of p.d.f

if (!_init) initialize() ;

return _conv->evaluate() ;
}

//_____________________________________________________________________________
void RooNumConvPdf::initialize() const
{
// One-time initialization of object

// Save pointer to any prototype convolution object (only present if this object is made through
// a copy constructor)
RooNumConvolution* protoConv = _conv ;

// Optionally pass along configuration data from prototype object
_conv = new RooNumConvolution(Form("%s_CONV",GetName()),GetTitle(),var(),pdf(),model(),protoConv) ;

// Delete prototype object now
if (protoConv) {
delete protoConv ;
}

_init = kTRUE ;
}

//_____________________________________________________________________________
RooAbsGenContext* RooNumConvPdf::genContext(const RooArgSet &vars, const RooDataSet *prototype,
const RooArgSet* auxProto, Bool_t verbose) const
{
// Return appropriate generator context for this convolved p.d.f. If both pdf and resolution
// model support internal generation return and optimization convolution generation context
// that uses a smearing algorithm. Otherwise return a standard accept/reject sampling
// context on the convoluted shape.

if (!_init) initialize() ;

// Check if physics PDF and resolution model can both directly generate the convolution variable
RooArgSet* modelDep = _conv->model().getObservables(&vars) ;
modelDep->remove(_conv->var(),kTRUE,kTRUE) ;
delete modelDep ;

RooArgSet dummy ;
Bool_t pdfCanDir = (((RooAbsPdf&)_conv->pdf()).getGenerator(_conv->var(),dummy) != 0 && \
((RooAbsPdf&)_conv->pdf()).isDirectGenSafe(_conv->var())) ;
Bool_t resCanDir = (((RooAbsPdf&)_conv->model()).getGenerator(_conv->var(),dummy) !=0  &&
((RooAbsPdf&)_conv->model()).isDirectGenSafe(_conv->var())) ;

if (numAddDep>0 || !pdfCanDir || !resCanDir) {
// Any resolution model with more dependents than the convolution variable
// or pdf or resmodel do not support direct generation
return new RooGenContext(*this,vars,prototype,auxProto,verbose) ;
}

// Any other resolution model: use specialized generator context
return new RooConvGenContext(*this,vars,prototype,auxProto,verbose) ;
}

//_____________________________________________________________________________
void RooNumConvPdf::printMetaArgs(ostream& os) const
{
// Customized printing of arguments of a RooNumConvPdf to more intuitively reflect the contents of the
// product operator construction

os << _origPdf.arg().GetName() << "(" << _origVar.arg().GetName() << ") (*) " << _origModel.arg().GetName() << "(" << _origVar.arg().GetName() << ") " ;
}
```
RooNumConvPdf.cxx:1
RooNumConvPdf.cxx:2
RooNumConvPdf.cxx:3
RooNumConvPdf.cxx:4
RooNumConvPdf.cxx:5
RooNumConvPdf.cxx:6
RooNumConvPdf.cxx:7
RooNumConvPdf.cxx:8
RooNumConvPdf.cxx:9
RooNumConvPdf.cxx:10
RooNumConvPdf.cxx:11
RooNumConvPdf.cxx:12
RooNumConvPdf.cxx:13
RooNumConvPdf.cxx:14
RooNumConvPdf.cxx:15
RooNumConvPdf.cxx:16
RooNumConvPdf.cxx:17
RooNumConvPdf.cxx:18
RooNumConvPdf.cxx:19
RooNumConvPdf.cxx:20
RooNumConvPdf.cxx:21
RooNumConvPdf.cxx:22
RooNumConvPdf.cxx:23
RooNumConvPdf.cxx:24
RooNumConvPdf.cxx:25
RooNumConvPdf.cxx:26
RooNumConvPdf.cxx:27
RooNumConvPdf.cxx:28
RooNumConvPdf.cxx:29
RooNumConvPdf.cxx:30
RooNumConvPdf.cxx:31
RooNumConvPdf.cxx:32
RooNumConvPdf.cxx:33
RooNumConvPdf.cxx:34
RooNumConvPdf.cxx:35
RooNumConvPdf.cxx:36
RooNumConvPdf.cxx:37
RooNumConvPdf.cxx:38
RooNumConvPdf.cxx:39
RooNumConvPdf.cxx:40
RooNumConvPdf.cxx:41
RooNumConvPdf.cxx:42
RooNumConvPdf.cxx:43
RooNumConvPdf.cxx:44
RooNumConvPdf.cxx:45
RooNumConvPdf.cxx:46
RooNumConvPdf.cxx:47
RooNumConvPdf.cxx:48
RooNumConvPdf.cxx:49
RooNumConvPdf.cxx:50
RooNumConvPdf.cxx:51
RooNumConvPdf.cxx:52
RooNumConvPdf.cxx:53
RooNumConvPdf.cxx:54
RooNumConvPdf.cxx:55
RooNumConvPdf.cxx:56
RooNumConvPdf.cxx:57
RooNumConvPdf.cxx:58
RooNumConvPdf.cxx:59
RooNumConvPdf.cxx:60
RooNumConvPdf.cxx:61
RooNumConvPdf.cxx:62
RooNumConvPdf.cxx:63
RooNumConvPdf.cxx:64
RooNumConvPdf.cxx:65
RooNumConvPdf.cxx:66
RooNumConvPdf.cxx:67
RooNumConvPdf.cxx:68
RooNumConvPdf.cxx:69
RooNumConvPdf.cxx:70
RooNumConvPdf.cxx:71
RooNumConvPdf.cxx:72
RooNumConvPdf.cxx:73
RooNumConvPdf.cxx:74
RooNumConvPdf.cxx:75
RooNumConvPdf.cxx:76
RooNumConvPdf.cxx:77
RooNumConvPdf.cxx:78
RooNumConvPdf.cxx:79
RooNumConvPdf.cxx:80
RooNumConvPdf.cxx:81
RooNumConvPdf.cxx:82
RooNumConvPdf.cxx:83
RooNumConvPdf.cxx:84
RooNumConvPdf.cxx:85
RooNumConvPdf.cxx:86
RooNumConvPdf.cxx:87
RooNumConvPdf.cxx:88
RooNumConvPdf.cxx:89
RooNumConvPdf.cxx:90
RooNumConvPdf.cxx:91
RooNumConvPdf.cxx:92
RooNumConvPdf.cxx:93
RooNumConvPdf.cxx:94
RooNumConvPdf.cxx:95
RooNumConvPdf.cxx:96
RooNumConvPdf.cxx:97
RooNumConvPdf.cxx:98
RooNumConvPdf.cxx:99
RooNumConvPdf.cxx:100
RooNumConvPdf.cxx:101
RooNumConvPdf.cxx:102
RooNumConvPdf.cxx:103
RooNumConvPdf.cxx:104
RooNumConvPdf.cxx:105
RooNumConvPdf.cxx:106
RooNumConvPdf.cxx:107
RooNumConvPdf.cxx:108
RooNumConvPdf.cxx:109
RooNumConvPdf.cxx:110
RooNumConvPdf.cxx:111
RooNumConvPdf.cxx:112
RooNumConvPdf.cxx:113
RooNumConvPdf.cxx:114
RooNumConvPdf.cxx:115
RooNumConvPdf.cxx:116
RooNumConvPdf.cxx:117
RooNumConvPdf.cxx:118
RooNumConvPdf.cxx:119
RooNumConvPdf.cxx:120
RooNumConvPdf.cxx:121
RooNumConvPdf.cxx:122
RooNumConvPdf.cxx:123
RooNumConvPdf.cxx:124
RooNumConvPdf.cxx:125
RooNumConvPdf.cxx:126
RooNumConvPdf.cxx:127
RooNumConvPdf.cxx:128
RooNumConvPdf.cxx:129
RooNumConvPdf.cxx:130
RooNumConvPdf.cxx:131
RooNumConvPdf.cxx:132
RooNumConvPdf.cxx:133
RooNumConvPdf.cxx:134
RooNumConvPdf.cxx:135
RooNumConvPdf.cxx:136
RooNumConvPdf.cxx:137
RooNumConvPdf.cxx:138
RooNumConvPdf.cxx:139
RooNumConvPdf.cxx:140
RooNumConvPdf.cxx:141
RooNumConvPdf.cxx:142
RooNumConvPdf.cxx:143
RooNumConvPdf.cxx:144
RooNumConvPdf.cxx:145
RooNumConvPdf.cxx:146
RooNumConvPdf.cxx:147
RooNumConvPdf.cxx:148
RooNumConvPdf.cxx:149
RooNumConvPdf.cxx:150
RooNumConvPdf.cxx:151
RooNumConvPdf.cxx:152
RooNumConvPdf.cxx:153
RooNumConvPdf.cxx:154
RooNumConvPdf.cxx:155
RooNumConvPdf.cxx:156
RooNumConvPdf.cxx:157
RooNumConvPdf.cxx:158
RooNumConvPdf.cxx:159
RooNumConvPdf.cxx:160
RooNumConvPdf.cxx:161
RooNumConvPdf.cxx:162
RooNumConvPdf.cxx:163
RooNumConvPdf.cxx:164
RooNumConvPdf.cxx:165
RooNumConvPdf.cxx:166
RooNumConvPdf.cxx:167
RooNumConvPdf.cxx:168
RooNumConvPdf.cxx:169
RooNumConvPdf.cxx:170
RooNumConvPdf.cxx:171
RooNumConvPdf.cxx:172
RooNumConvPdf.cxx:173
RooNumConvPdf.cxx:174
RooNumConvPdf.cxx:175
RooNumConvPdf.cxx:176
RooNumConvPdf.cxx:177
RooNumConvPdf.cxx:178
RooNumConvPdf.cxx:179
RooNumConvPdf.cxx:180
RooNumConvPdf.cxx:181
RooNumConvPdf.cxx:182
RooNumConvPdf.cxx:183
RooNumConvPdf.cxx:184
RooNumConvPdf.cxx:185
RooNumConvPdf.cxx:186
RooNumConvPdf.cxx:187
RooNumConvPdf.cxx:188
RooNumConvPdf.cxx:189
RooNumConvPdf.cxx:190
RooNumConvPdf.cxx:191
RooNumConvPdf.cxx:192
RooNumConvPdf.cxx:193
RooNumConvPdf.cxx:194
RooNumConvPdf.cxx:195
RooNumConvPdf.cxx:196
RooNumConvPdf.cxx:197
RooNumConvPdf.cxx:198
RooNumConvPdf.cxx:199
RooNumConvPdf.cxx:200
RooNumConvPdf.cxx:201
RooNumConvPdf.cxx:202
RooNumConvPdf.cxx:203
RooNumConvPdf.cxx:204
RooNumConvPdf.cxx:205
RooNumConvPdf.cxx:206
RooNumConvPdf.cxx:207
RooNumConvPdf.cxx:208
RooNumConvPdf.cxx:209
RooNumConvPdf.cxx:210
RooNumConvPdf.cxx:211
RooNumConvPdf.cxx:212
RooNumConvPdf.cxx:213
RooNumConvPdf.cxx:214
RooNumConvPdf.cxx:215
RooNumConvPdf.cxx:216
RooNumConvPdf.cxx:217
RooNumConvPdf.cxx:218
RooNumConvPdf.cxx:219
RooNumConvPdf.cxx:220
RooNumConvPdf.cxx:221
RooNumConvPdf.cxx:222
RooNumConvPdf.cxx:223
RooNumConvPdf.cxx:224
RooNumConvPdf.cxx:225
RooNumConvPdf.cxx:226
RooNumConvPdf.cxx:227
RooNumConvPdf.cxx:228
RooNumConvPdf.cxx:229