// @(#)root/spectrum:$Id$
// Author: Miroslav Morhac   25/09/06

/*************************************************************************
 * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/
#ifndef ROOT_TSpectrumFit
#define ROOT_TSpectrumFit

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TSpectrumFit                                                         //
//                                                                      //
// Class for fitting 1D spectra using AWMI (algorithm without matrix    //
// inversion) and conjugate gradient algorithms for symmetrical         //
// matrices (Stiefel-Hestens method). AWMI method allows to fit         //
// simulaneously 100s up to 1000s peaks. Stiefel method is very stable, //
// it converges faster, but is more time consuming                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TNamed
#include "TNamed.h"
#endif

class TH1;

class TSpectrumFit : public TNamed {
protected:
   Int_t     fNPeaks;                    //number of peaks present in fit, input parameter, it should be > 0
   Int_t     fNumberIterations;          //number of iterations in fitting procedure, input parameter, it should be > 0
   Int_t     fXmin;                      //first fitted channel
   Int_t     fXmax;                      //last fitted channel
   Int_t     fStatisticType;             //type of statistics, possible values kFitOptimChiCounts (chi square statistics with counts as weighting coefficients), kFitOptimChiFuncValues (chi square statistics with function values as weighting coefficients),kFitOptimMaxLikelihood
   Int_t     fAlphaOptim;                //optimization of convergence algorithm, possible values kFitAlphaHalving, kFitAlphaOptimal
   Int_t     fPower;                     //possible values kFitPower2,4,6,8,10,12, for details see references. It applies only for Awmi fitting function.
   Int_t     fFitTaylor;                 //order of Taylor expansion, possible values kFitTaylorOrderFirst, kFitTaylorOrderSecond. It applies only for Awmi fitting function.
   Double_t  fAlpha;                     //convergence coefficient, input parameter, it should be positive number and <=1, for details see references
   Double_t  fChi;                       //here the fitting functions return resulting chi square
   Double_t *fPositionInit;              //[fNPeaks] array of initial values of peaks positions, input parameters
   Double_t *fPositionCalc;              //[fNPeaks] array of calculated values of fitted positions, output parameters
   Double_t *fPositionErr;               //[fNPeaks] array of position errors
   Double_t *fAmpInit;                   //[fNPeaks] array of initial values of peaks amplitudes, input parameters
   Double_t *fAmpCalc;                   //[fNPeaks] array of calculated values of fitted amplitudes, output parameters
   Double_t *fAmpErr;                    //[fNPeaks] array of amplitude errors
   Double_t *fArea;                      //[fNPeaks] array of calculated areas of peaks
   Double_t *fAreaErr;                   //[fNPeaks] array of errors of peak areas
   Double_t  fSigmaInit;                 //initial value of sigma parameter
   Double_t  fSigmaCalc;                 //calculated value of sigma parameter
   Double_t  fSigmaErr;                  //error value of sigma parameter
   Double_t  fTInit;                     //initial value of t parameter (relative amplitude of tail), for details see html manual and references
   Double_t  fTCalc;                     //calculated value of t parameter
   Double_t  fTErr;                      //error value of t parameter
   Double_t  fBInit;                     //initial value of b parameter (slope), for details see html manual and references
   Double_t  fBCalc;                     //calculated value of b parameter
   Double_t  fBErr;                      //error value of b parameter
   Double_t  fSInit;                     //initial value of s parameter (relative amplitude of step), for details see html manual and references
   Double_t  fSCalc;                     //calculated value of s parameter
   Double_t  fSErr;                      //error value of s parameter
   Double_t  fA0Init;                    //initial value of background a0 parameter(backgroud is estimated as a0+a1*x+a2*x*x)
   Double_t  fA0Calc;                    //calculated value of background a0 parameter
   Double_t  fA0Err;                     //error value of background a0 parameter
   Double_t  fA1Init;                    //initial value of background a1 parameter(backgroud is estimated as a0+a1*x+a2*x*x)
   Double_t  fA1Calc;                    //calculated value of background a1 parameter
   Double_t  fA1Err;                     //error value of background a1 parameter
   Double_t  fA2Init;                    //initial value of background a2 parameter(backgroud is estimated as a0+a1*x+a2*x*x)
   Double_t  fA2Calc;                    //calculated value of background a2 parameter
   Double_t  fA2Err;                     //error value of background a2 parameter
   Bool_t   *fFixPosition;               //[fNPeaks] array of logical values which allow to fix appropriate positions (not fit). However they are present in the estimated functional
   Bool_t   *fFixAmp;                    //[fNPeaks] array of logical values which allow to fix appropriate amplitudes (not fit). However they are present in the estimated functional
   Bool_t    fFixSigma;                  //logical value of sigma parameter, which allows to fix the parameter (not to fit).
   Bool_t    fFixT;                      //logical value of t parameter, which allows to fix the parameter (not to fit).
   Bool_t    fFixB;                      //logical value of b parameter, which allows to fix the parameter (not to fit).
   Bool_t    fFixS;                      //logical value of s parameter, which allows to fix the parameter (not to fit).
   Bool_t    fFixA0;                     //logical value of a0 parameter, which allows to fix the parameter (not to fit).
   Bool_t    fFixA1;                     //logical value of a1 parameter, which allows to fix the parameter (not to fit).
   Bool_t    fFixA2;                     //logical value of a2 parameter, which allows to fix the parameter (not to fit).

public:
   enum {
       kFitOptimChiCounts =0,
       kFitOptimChiFuncValues =1,
       kFitOptimMaxLikelihood =2,
       kFitAlphaHalving =0,
       kFitAlphaOptimal =1,
       kFitPower2 =2,
       kFitPower4 =4,
       kFitPower6 =6,
       kFitPower8 =8,
       kFitPower10 =10,
       kFitPower12 =12,
       kFitTaylorOrderFirst =0,
       kFitTaylorOrderSecond =1,
       kFitNumRegulCycles =100
   };
   TSpectrumFit(void); //default constructor
   TSpectrumFit(Int_t numberPeaks);
   virtual ~TSpectrumFit();

   //auxiliary functions for 1. parameter fit functions
protected:
   Double_t            Area(Double_t a,Double_t sigma,Double_t t,Double_t b);
   Double_t            Dera1(Double_t i);
   Double_t            Dera2(Double_t i);
   Double_t            Deramp(Double_t i,Double_t i0,Double_t sigma,Double_t t,Double_t s,Double_t b);
   Double_t            Derb(Int_t num_of_fitted_peaks,Double_t i,const Double_t* parameter,Double_t sigma,Double_t t,Double_t b);
   Double_t            Derderi0(Double_t i,Double_t amp,Double_t i0,Double_t sigma);
   Double_t            Derdersigma(Int_t num_of_fitted_peaks,Double_t i,const Double_t* parameter,Double_t sigma);
   Double_t            Derfc(Double_t x);
   Double_t            Deri0(Double_t i,Double_t amp,Double_t i0,Double_t sigma,Double_t t,Double_t s,Double_t b);
   Double_t            Derpa(Double_t sigma,Double_t t,Double_t b);
   Double_t            Derpb(Double_t a,Double_t sigma,Double_t t,Double_t b);
   Double_t            Derpsigma(Double_t a,Double_t t,Double_t b);
   Double_t            Derpt(Double_t a,Double_t sigma,Double_t b);
   Double_t            Ders(Int_t num_of_fitted_peaks,Double_t i,const Double_t* parameter,Double_t sigma);
   Double_t            Dersigma(Int_t num_of_fitted_peaks,Double_t i,const Double_t* parameter,Double_t sigma,Double_t t,Double_t s,Double_t b);
   Double_t            Dert(Int_t num_of_fitted_peaks,Double_t i,const Double_t* parameter,Double_t sigma,Double_t b);
   Double_t            Erfc(Double_t x);
   Double_t            Ourpowl(Double_t a,Int_t pw);
   Double_t            Shape(Int_t num_of_fitted_peaks,Double_t i,const Double_t *parameter,Double_t sigma,Double_t t,Double_t s,Double_t b,Double_t a0,Double_t a1,Double_t a2);
   void                StiefelInversion(Double_t **a,Int_t rozmer);

public:
   void                FitAwmi(Double_t *source);
   void                FitStiefel(Double_t *source);
   Double_t           *GetAmplitudes() const {return fAmpCalc;}
   Double_t           *GetAmplitudesErrors() const {return fAmpErr;}
   Double_t           *GetAreas() const {return fArea;}
   Double_t           *GetAreasErrors() const {return fAreaErr;}
   void                GetBackgroundParameters(Double_t &a0, Double_t &a0Err, Double_t &a1, Double_t &a1Err, Double_t &a2, Double_t &a2Err);
   Double_t            GetChi() const {return fChi;}
   Double_t           *GetPositions() const {return fPositionCalc;}
   Double_t           *GetPositionsErrors() const {return fPositionErr;}
   void                GetSigma(Double_t &sigma, Double_t &sigmaErr);
   void                GetTailParameters(Double_t &t, Double_t &tErr, Double_t &b, Double_t &bErr, Double_t &s, Double_t &sErr);
   void                SetBackgroundParameters(Double_t a0Init, Bool_t fixA0, Double_t a1Init, Bool_t fixA1, Double_t a2Init, Bool_t fixA2);
   void                SetFitParameters(Int_t xmin,Int_t xmax, Int_t numberIterations, Double_t alpha, Int_t statisticType, Int_t alphaOptim, Int_t power, Int_t fitTaylor);
   void                SetPeakParameters(Double_t sigma, Bool_t fixSigma, const Double_t *positionInit, const Bool_t *fixPosition, const Double_t *ampInit, const Bool_t *fixAmp);
   void                SetTailParameters(Double_t tInit, Bool_t fixT, Double_t bInit, Bool_t fixB, Double_t sInit, Bool_t fixS);

   ClassDef(TSpectrumFit,1)  //Spectrum Fitter using algorithm without matrix inversion and conjugate gradient method for symmetrical matrices (Stiefel-Hestens method)
};

#endif

 TSpectrumFit.h:1
 TSpectrumFit.h:2
 TSpectrumFit.h:3
 TSpectrumFit.h:4
 TSpectrumFit.h:5
 TSpectrumFit.h:6
 TSpectrumFit.h:7
 TSpectrumFit.h:8
 TSpectrumFit.h:9
 TSpectrumFit.h:10
 TSpectrumFit.h:11
 TSpectrumFit.h:12
 TSpectrumFit.h:13
 TSpectrumFit.h:14
 TSpectrumFit.h:15
 TSpectrumFit.h:16
 TSpectrumFit.h:17
 TSpectrumFit.h:18
 TSpectrumFit.h:19
 TSpectrumFit.h:20
 TSpectrumFit.h:21
 TSpectrumFit.h:22
 TSpectrumFit.h:23
 TSpectrumFit.h:24
 TSpectrumFit.h:25
 TSpectrumFit.h:26
 TSpectrumFit.h:27
 TSpectrumFit.h:28
 TSpectrumFit.h:29
 TSpectrumFit.h:30
 TSpectrumFit.h:31
 TSpectrumFit.h:32
 TSpectrumFit.h:33
 TSpectrumFit.h:34
 TSpectrumFit.h:35
 TSpectrumFit.h:36
 TSpectrumFit.h:37
 TSpectrumFit.h:38
 TSpectrumFit.h:39
 TSpectrumFit.h:40
 TSpectrumFit.h:41
 TSpectrumFit.h:42
 TSpectrumFit.h:43
 TSpectrumFit.h:44
 TSpectrumFit.h:45
 TSpectrumFit.h:46
 TSpectrumFit.h:47
 TSpectrumFit.h:48
 TSpectrumFit.h:49
 TSpectrumFit.h:50
 TSpectrumFit.h:51
 TSpectrumFit.h:52
 TSpectrumFit.h:53
 TSpectrumFit.h:54
 TSpectrumFit.h:55
 TSpectrumFit.h:56
 TSpectrumFit.h:57
 TSpectrumFit.h:58
 TSpectrumFit.h:59
 TSpectrumFit.h:60
 TSpectrumFit.h:61
 TSpectrumFit.h:62
 TSpectrumFit.h:63
 TSpectrumFit.h:64
 TSpectrumFit.h:65
 TSpectrumFit.h:66
 TSpectrumFit.h:67
 TSpectrumFit.h:68
 TSpectrumFit.h:69
 TSpectrumFit.h:70
 TSpectrumFit.h:71
 TSpectrumFit.h:72
 TSpectrumFit.h:73
 TSpectrumFit.h:74
 TSpectrumFit.h:75
 TSpectrumFit.h:76
 TSpectrumFit.h:77
 TSpectrumFit.h:78
 TSpectrumFit.h:79
 TSpectrumFit.h:80
 TSpectrumFit.h:81
 TSpectrumFit.h:82
 TSpectrumFit.h:83
 TSpectrumFit.h:84
 TSpectrumFit.h:85
 TSpectrumFit.h:86
 TSpectrumFit.h:87
 TSpectrumFit.h:88
 TSpectrumFit.h:89
 TSpectrumFit.h:90
 TSpectrumFit.h:91
 TSpectrumFit.h:92
 TSpectrumFit.h:93
 TSpectrumFit.h:94
 TSpectrumFit.h:95
 TSpectrumFit.h:96
 TSpectrumFit.h:97
 TSpectrumFit.h:98
 TSpectrumFit.h:99
 TSpectrumFit.h:100
 TSpectrumFit.h:101
 TSpectrumFit.h:102
 TSpectrumFit.h:103
 TSpectrumFit.h:104
 TSpectrumFit.h:105
 TSpectrumFit.h:106
 TSpectrumFit.h:107
 TSpectrumFit.h:108
 TSpectrumFit.h:109
 TSpectrumFit.h:110
 TSpectrumFit.h:111
 TSpectrumFit.h:112
 TSpectrumFit.h:113
 TSpectrumFit.h:114
 TSpectrumFit.h:115
 TSpectrumFit.h:116
 TSpectrumFit.h:117
 TSpectrumFit.h:118
 TSpectrumFit.h:119
 TSpectrumFit.h:120
 TSpectrumFit.h:121
 TSpectrumFit.h:122
 TSpectrumFit.h:123
 TSpectrumFit.h:124
 TSpectrumFit.h:125
 TSpectrumFit.h:126
 TSpectrumFit.h:127
 TSpectrumFit.h:128
 TSpectrumFit.h:129
 TSpectrumFit.h:130
 TSpectrumFit.h:131
 TSpectrumFit.h:132
 TSpectrumFit.h:133
 TSpectrumFit.h:134
 TSpectrumFit.h:135
 TSpectrumFit.h:136
 TSpectrumFit.h:137
 TSpectrumFit.h:138
 TSpectrumFit.h:139
 TSpectrumFit.h:140
 TSpectrumFit.h:141
 TSpectrumFit.h:142
 TSpectrumFit.h:143
 TSpectrumFit.h:144
 TSpectrumFit.h:145
 TSpectrumFit.h:146
 TSpectrumFit.h:147
 TSpectrumFit.h:148
 TSpectrumFit.h:149