44 class TF1Convolution_EvalWrapper
46 std::unique_ptr<TF1> fFunction1;
47 std::unique_ptr<TF1> fFunction2;
51 TF1Convolution_EvalWrapper(std::unique_ptr<TF1> &
f1, std::unique_ptr<TF1> &f2,
Double_t t) : fT0(t)
53 fFunction1 = std::unique_ptr<TF1>((
TF1 *)f1->
Clone());
54 fFunction2 = std::unique_ptr<TF1>((
TF1 *)f2->
Clone());
62 return fFunction1->
EvalPar(xx,
nullptr) * fFunction2->
EvalPar(xx+1,
nullptr);
72 TF1 * fnew1 = (
TF1*) function1->IsA()->New();
73 function1->
Copy(*fnew1);
74 fFunction1 = std::unique_ptr<TF1>(fnew1);
77 TF1 * fnew2 = (
TF1*) function2->IsA()->New();
78 function2->
Copy(*fnew2);
79 fFunction2 = std::unique_ptr<TF1>(fnew2);
81 if (fFunction1.get() ==
nullptr|| fFunction2.get() ==
nullptr)
82 Fatal(
"InitializeDataMembers",
"Invalid functions - Abort");
93 fNofParams1 = fFunction1->
GetNpar();
94 fNofParams2 = fFunction2->
GetNpar();
95 fParams1 = std::vector<Double_t>(fNofParams1);
96 fParams2 = std::vector<Double_t>(fNofParams2);
104 fParNames.reserve( fNofParams1 + fNofParams2);
105 for (
int i=0; i<fNofParams1; i++)
107 fParams1[i] = fFunction1 -> GetParameter(i);
108 fParNames.push_back(fFunction1 -> GetParName(i) );
110 for (
int i=0; i<fNofParams2; i++)
112 fParams2[i] = fFunction2 -> GetParameter(i);
113 if (i != fCstIndex) fParNames.push_back(fFunction2 -> GetParName(i) );
117 fFunction2 -> FixParameter(fCstIndex,1.);
118 fNofParams2 = fNofParams2-1;
119 fParams2.erase(fParams2.begin()+fCstIndex);
136 InitializeDataMembers(function1,function2, useFFT);
144 InitializeDataMembers(function1, function2,useFFT);
149 Info(
"TF1Convolution",
"Using default range [-inf, inf] for TF1Convolution");
162 std::vector < TString > stringarray(2);
163 std::vector < TF1* > funcarray(2);
164 for (
int i=0; i<2; i++)
166 stringarray[i] = ((
TObjString*)((*objarray)[i])) -> GetString();
167 stringarray[i].ReplaceAll(
" ",
"");
168 funcarray[i] = (
TF1*)(
gROOT -> GetListOfFunctions() -> FindObject(stringarray[i]));
170 if (funcarray[i] ==
nullptr) {
173 Error(
"TF1Convolution",
"Invalid formula : %s",stringarray[i].Data() );
175 fFunction1 = std::unique_ptr<TF1>(
f);
177 fFunction2 = std::unique_ptr<TF1>(
f);
180 InitializeDataMembers(funcarray[0], funcarray[1],useFFT);
185 Info(
"TF1Convolution",
"Using default range [-inf, inf] for TF1Convolution");
201 TF1*
f1 = (
TF1*)(
gROOT -> GetListOfFunctions() -> FindObject(formula1));
202 TF1* f2 = (
TF1*)(
gROOT -> GetListOfFunctions() -> FindObject(formula2));
205 fFunction1 = std::unique_ptr<TF1>(
new TF1(
"f_conv_1", formula1));
207 Error(
"TF1Convolution",
"Invalid formula for : %s",formula1.
Data() );
210 fFunction2 = std::unique_ptr<TF1>(
new TF1(
"f_conv_1", formula2));
212 Error(
"TF1Convolution",
"Invalid formula for : %s",formula2.
Data() );
215 InitializeDataMembers(f1, f2,useFFT);
220 Info(
"TF1Convolution",
"Using default range [-inf, inf] for TF1Convolution");
249 Info(
"MakeFFTConv",
"Making FFT convolution using %d points in range [%g,%g]",fNofPoints,fXmin,fXmax);
251 std::vector < Double_t >
x (fNofPoints);
252 std::vector < Double_t > in1(fNofPoints);
253 std::vector < Double_t > in2(fNofPoints);
257 if (fft1 ==
nullptr || fft2 ==
nullptr) {
258 Warning(
"MakeFFTConv",
"Cannot use FFT, probably FFTW package is not available. Switch to numerical convolution");
264 Double_t shift2 = 0.5*(fXmin+fXmax);
266 for (
int i=0; i<fNofPoints; i++)
268 x[i] = fXmin + (fXmax-fXmin)/(fNofPoints-1)*i;
270 in1[i] = fFunction1 -> EvalPar( &x[i],
nullptr);
271 in2[i] = fFunction2 -> EvalPar( &x2,
nullptr);
272 fft1 -> SetPoint(i, in1[i]);
273 fft2 -> SetPoint(i, in2[i]);
281 Double_t re1, re2, im1, im2, out_re, out_im;
283 for (
int i=0;i<=fNofPoints/2.;i++)
285 fft1 -> GetPointComplex(i,re1,im1);
286 fft2 -> GetPointComplex(i,re2,im2);
287 out_re = re1*re2 - im1*im2;
288 out_im = re1*im2 + re2*im1;
289 fftinverse -> SetPoint(i, out_re, out_im);
291 fftinverse -> Transform();
295 fGraphConv = std::unique_ptr<TGraph>(
new TGraph(fNofPoints));
297 for (
int i=0;i<fNofPoints;i++)
300 int j = i + fNofPoints/2;
301 if (j >= fNofPoints) j -= fNofPoints;
303 fGraphConv->SetPoint(i, x[i], fftinverse->
GetPointReal(j)*(fXmax-fXmin)/(fNofPoints*fNofPoints) );
318 if (!fFlagGraph) MakeFFTConv();
321 return fGraphConv ->
Eval(t);
324 return EvalNumConv(t);
333 TF1Convolution_EvalWrapper fconv( fFunction1, fFunction2, t);
338 result = integrator.
Integral(fXmin, fXmax);
358 result = EvalFFTConv(x[0]);
360 result = EvalNumConv(x[0]);
370 if (fGraphConv) fGraphConv -> Set(fNofPoints);
378 bool equalParams =
true;
379 for (
int i=0; i<fNofParams1; i++) {
381 equalParams &= (fParams1[i] == params[i]);
382 fParams1[i] = params[i];
387 if (fCstIndex!=-1) offset = 1;
388 Int_t totalnofparams = fNofParams1+fNofParams2+offset;
389 for (
int i=fNofParams1; i<totalnofparams; i++) {
397 equalParams &= (fParams2[k - offset2] == params[i - offset2]);
398 fParams2[k - offset2] = params[i - offset2];
402 if (!equalParams) fFlagGraph =
false;
418 if (percentage<0)
return;
419 double range = fXmax = fXmin;
420 fXmin -= percentage * range;
421 fXmax += percentage * range;
430 Warning(
"SetRange",
"Invalid range: %f >= %f", a, b);
438 Warning(
"TF1Convolution::SetRange()",
"In FFT mode, range can not be infinite. Infinity has been replaced by range of first function plus a bufferzone to avoid spillover.");
virtual TFormula * GetFormula()
static double p3(double t, double a, double b, double c, double d)
virtual void Copy(TObject &f1) const
Copy this F1 to a new F1.
void Update()
Update the two component functions of the convolution.
void Fatal(const char *location, const char *msgfmt,...)
Collectable string class.
TString & ReplaceAll(const TString &s1, const TString &s2)
TF1Convolution()
constructor without arguments
Double_t operator()(const Double_t *x, const Double_t *p)
Used in TF1 when doing the fit, will be evaluated at each point.
TF1Convolution & operator=(const TF1Convolution &rhs)
Operator =.
TRObject operator()(const T1 &t1) const
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Class wrapping convolution of two functions.
static const double x2[5]
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
static double p2(double t, double a, double b, double c)
void MakeFFTConv()
Perform the FFT of the two functions.
void Info(const char *location, const char *msgfmt,...)
void InitializeDataMembers(TF1 *function1, TF1 *function2, Bool_t useFFT)
Use copy instead of Clone.
static IntegrationOneDim::Type DefaultIntegratorType()
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
void Error(const char *location, const char *msgfmt,...)
double IntegralLow(const IGenFunction &f, double b)
evaluate the Integral of a function f over the over the semi-infinite interval (-inf,b)
double Integral(Function &f, double a, double b)
evaluate the Integral of a function f over the defined interval (a,b)
void SetRange(Double_t a, Double_t b)
double IntegralUp(const IGenFunction &f, double a)
evaluate the Integral of a function f over the semi-infinite interval (a,+inf)
virtual Double_t GetPointReal(Int_t ipoint, Bool_t fromInput=kFALSE) const =0
static TVirtualFFT * FFT(Int_t ndim, Int_t *n, Option_t *option)
Returns a pointer to the FFT of requested size and type.
Double_t EvalNumConv(Double_t t)
Perform numerical convolution.
void SetNofPointsFFT(Int_t n)
User Class for performing numerical integration of a function in one dimension.
static void InitStandardFunctions()
Create the basic function objects.
static double p1(double t, double a, double b)
virtual void Update()
Called by functions such as SetRange, SetNpx, SetParameters to force the deletion of the associated h...
void Warning(const char *location, const char *msgfmt,...)
TVirtualFFT is an interface class for Fast Fourier Transforms.
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
graph is sorted in X points
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Double_t EvalFFTConv(Double_t t)
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Mother of all ROOT objects.
virtual Int_t GetNpar() const
void Copy(TObject &obj) const
Copy this to obj.
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
A Graph is a graphics object made of two arrays X and Y with npoints each.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
virtual void SetParameter(Int_t param, Double_t value)
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0)
Evaluate function with given coordinates and parameters.
void GetRange(Double_t &a, Double_t &b) const
virtual Int_t GetParNumber(const char *name) const
void SetExtraRange(Double_t percentage)
const char * Data() const
void SetParameters(const Double_t *params)