// @(#)root/hist:$Id$
// Author: L. Moneta May 2015

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2015  ROOT  Team, CERN/PH-SFT                        *
 *                                                                    *
 *                                                                    *
 **********************************************************************/
//
//
//  TF1Convolution.h
//
//  Created by Aurélie Flandi on 27.08.14.
//
//

#ifndef ROOT_TF1Convolution__
#define ROOT_TF1Convolution__

#include <iostream>
#include "TF1.h"
#include "TGraph.h"
#include <memory>

class TF1Convolution
{
   std::shared_ptr <TF1>      fFunction1;
   std::shared_ptr <TF1>      fFunction2;
   std::shared_ptr <TGraph>   fGraphConv;
   
   std::vector < Double_t >   fParams1;
   std::vector < Double_t >   fParams2;

   std::vector< TString >    fParNames;      // parameter names 
   
   Double_t fXmin;            //minimal bound of the range of the convolution
   Double_t fXmax;            //maximal bound of the range of the convolution
   Int_t    fNofParams1;
   Int_t    fNofParams2;
   Int_t    fCstIndex;        //index of the constant parameter f the first function
   Int_t    fNofPoints;       //number of point for FFT array
   Bool_t   fFlagFFT;         //choose fft or numerical convolution
   Bool_t   fFlagGraph; //tells if the graph is already done or not
   
   
   Double_t EvalNumConv(Double_t t);
   Double_t EvalFFTConv(Double_t t);
   void     InitializeDataMembers(TF1* function1, TF1* function2, Bool_t useFFT);
   void     MakeFFTConv();
   
   public:
   
   TF1Convolution(TF1* function1, TF1* function2, Bool_t useFFT = true);
   TF1Convolution(TF1* function1, TF1* function2, Double_t xmin, Double_t xmax, Bool_t useFFT = true);
   TF1Convolution(TString formula, Double_t xmin = 1., Double_t xmax = 0., Bool_t useFFT = true);
   TF1Convolution(TString formula1, TString formula2, Double_t xmin = 1., Double_t xmax = 0., Bool_t useFFT = true);
   
   void     SetParameters(Double_t* p);
   void     SetParameters(Double_t p0,    Double_t p1,    Double_t p2=0., Double_t p3=0.,
                          Double_t p4=0., Double_t p5=0., Double_t p6=0., Double_t p7=0.);
   void     SetRange(Double_t a, Double_t b);
   void     SetExtraRange(Double_t percentage);
   void     SetNofPointsFFT(Int_t n);
   void     SetNumConv(Bool_t flag = true){fFlagFFT=!flag;}
   
   Int_t    GetNpar() const {return (fNofParams1+fNofParams2);}
   Double_t GetXmin() const {return fXmin;}
   Double_t GetXmax() const {return fXmax;}
   const char *    GetParName(Int_t ipar) const { return fParNames.at(ipar).Data(); }
   
   Double_t operator()(Double_t* t, Double_t* p);
};


#endif
 TF1Convolution.h:1
 TF1Convolution.h:2
 TF1Convolution.h:3
 TF1Convolution.h:4
 TF1Convolution.h:5
 TF1Convolution.h:6
 TF1Convolution.h:7
 TF1Convolution.h:8
 TF1Convolution.h:9
 TF1Convolution.h:10
 TF1Convolution.h:11
 TF1Convolution.h:12
 TF1Convolution.h:13
 TF1Convolution.h:14
 TF1Convolution.h:15
 TF1Convolution.h:16
 TF1Convolution.h:17
 TF1Convolution.h:18
 TF1Convolution.h:19
 TF1Convolution.h:20
 TF1Convolution.h:21
 TF1Convolution.h:22
 TF1Convolution.h:23
 TF1Convolution.h:24
 TF1Convolution.h:25
 TF1Convolution.h:26
 TF1Convolution.h:27
 TF1Convolution.h:28
 TF1Convolution.h:29
 TF1Convolution.h:30
 TF1Convolution.h:31
 TF1Convolution.h:32
 TF1Convolution.h:33
 TF1Convolution.h:34
 TF1Convolution.h:35
 TF1Convolution.h:36
 TF1Convolution.h:37
 TF1Convolution.h:38
 TF1Convolution.h:39
 TF1Convolution.h:40
 TF1Convolution.h:41
 TF1Convolution.h:42
 TF1Convolution.h:43
 TF1Convolution.h:44
 TF1Convolution.h:45
 TF1Convolution.h:46
 TF1Convolution.h:47
 TF1Convolution.h:48
 TF1Convolution.h:49
 TF1Convolution.h:50
 TF1Convolution.h:51
 TF1Convolution.h:52
 TF1Convolution.h:53
 TF1Convolution.h:54
 TF1Convolution.h:55
 TF1Convolution.h:56
 TF1Convolution.h:57
 TF1Convolution.h:58
 TF1Convolution.h:59
 TF1Convolution.h:60
 TF1Convolution.h:61
 TF1Convolution.h:62
 TF1Convolution.h:63
 TF1Convolution.h:64
 TF1Convolution.h:65
 TF1Convolution.h:66
 TF1Convolution.h:67
 TF1Convolution.h:68
 TF1Convolution.h:69
 TF1Convolution.h:70
 TF1Convolution.h:71
 TF1Convolution.h:72
 TF1Convolution.h:73
 TF1Convolution.h:74
 TF1Convolution.h:75
 TF1Convolution.h:76