Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <CalibCalorimetry/EcalLaserAnalyzer/interface/PulseFitWithFunction.h>
00021
00022 #include <iostream>
00023 #include "TMath.h"
00024
00025
00026
00027
00028
00029 PulseFitWithFunction::PulseFitWithFunction()
00030 {
00031
00032 fNsamples = 0;
00033 fNum_samp_bef_max = 0;
00034 fNum_samp_after_max = 0;
00035 }
00036
00037
00038 PulseFitWithFunction::~PulseFitWithFunction()
00039 {
00040 }
00041
00042
00043
00044 void PulseFitWithFunction::init(int n_samples,int samplb,int sampla,int niter,double alfa,double beta)
00045 {
00046
00047
00048
00049
00050
00051
00052
00053 fNsamples = n_samples ;
00054 fAlpha_laser = alfa;
00055 fBeta_laser = beta ;
00056 fAlpha_beam = 0.98 ;
00057 fBeta_beam = 2.04 ;
00058 fNb_iter = niter ;
00059 fNum_samp_bef_max = samplb ;
00060 fNum_samp_after_max = sampla ;
00061
00062
00063
00064
00065 return ;
00066 }
00067
00068
00069 double PulseFitWithFunction::doFit(double *adc)
00070 {
00071 double parout[4];
00072
00073 double chi2;
00074
00075
00076
00077 Fit_parab(&adc[0],3,fNsamples,parout) ;
00078 amp_parab = parout[0] ;
00079 tim_parab = parout[1] ;
00080 imax = (int)parout[2] ;
00081 amp_max = parout[3] ;
00082
00083 fNumber_samp_max=imax ;
00084
00085
00086 if(amp_parab < 1.) {
00087 tim_parab = (double)imax ;
00088 amp_parab = amp_max ;
00089 }
00090
00091 fValue_tim_max= tim_parab ;
00092 fFunc_max= amp_parab ;
00093 fTim_max=tim_parab ;
00094
00095
00096
00097 chi2 = Fit_electronic(0,&adc[0],8.) ;
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 return chi2 ;
00110
00111 }
00112
00113
00114
00115
00116
00117 double PulseFitWithFunction::Fit_electronic(int data , double* adc_to_fit , double sigmas_sample) {
00118
00119
00120
00121
00122
00123 double chi2=0;
00124 double d_alpha, d_beta ;
00125
00126 fAlpha = fAlpha_laser ;
00127 fBeta = fBeta_laser ;
00128 if(data == 1) {
00129 fAlpha = fAlpha_beam ;
00130 fBeta = fBeta_beam ;
00131 }
00132
00133 fAmp_fitted_max = 0. ;
00134 fTim_fitted_max = 0. ;
00135 double un_sur_sigma = 1./fSigma_ped ;
00136 double variation_func_max = 0. ;
00137 double variation_tim_max = 0. ;
00138
00139 if(fValue_tim_max > 20. || fValue_tim_max < 3.) {
00140 fValue_tim_max = fNumber_samp_max ;
00141 }
00142 int num_fit_min =(int)(fValue_tim_max - fNum_samp_bef_max) ;
00143 int num_fit_max =(int)(fValue_tim_max + fNum_samp_after_max) ;
00144
00145
00146 if( sigmas_sample > 0. ) un_sur_sigma = 1./sigmas_sample;
00147 else un_sur_sigma = 1.;
00148
00149 double func,delta ;
00150
00151 for (int iter=0 ; iter < fNb_iter ; iter ++) {
00152
00153
00154 chi2 = 0. ;
00155 double d11 = 0. ;
00156 double d12 = 0. ;
00157 double d22 = 0. ;
00158 double z1 = 0. ;
00159 double z2 = 0. ;
00160 fFunc_max += variation_func_max ;
00161 fTim_max += variation_tim_max ;
00162 int nsamp_used = 0 ;
00163
00164
00165
00166
00167
00168 for( int i = num_fit_min ; i < num_fit_max+1 ; i++) {
00169
00170
00171 func = Electronic_shape( (double)i ) ;
00172
00173
00174 double dt =(double)i - fTim_max ;
00175 double alpha_beta = fAlpha*fBeta ;
00176
00177 if(dt > -alpha_beta) {
00178 double dt_sur_beta = dt/fBeta ;
00179
00180 double variable = (double)1. + dt/alpha_beta ;
00181 double expo = TMath::Exp(-dt_sur_beta) ;
00182
00183 double puissance = TMath::Power(variable,fAlpha) ;
00184 d_alpha=un_sur_sigma*puissance*expo ;
00185 d_beta=fFunc_max*d_alpha*dt_sur_beta/(alpha_beta*variable) ;
00186 }
00187 else {
00188 continue ;
00189 }
00190
00191 nsamp_used ++ ;
00192
00193 d11 += d_alpha*d_alpha ;
00194 d12 += d_alpha*d_beta ;
00195 d22 += d_beta*d_beta ;
00196
00197 delta = (adc_to_fit[i]-func)*un_sur_sigma ;
00198
00199 z1 += delta*d_alpha ;
00200 z2 += delta*d_beta ;
00201 chi2 += delta * delta ;
00202 }
00203 double denom = d11*d22-d12*d12 ;
00204 if(denom == 0.) {
00205
00206 return 101 ;
00207 }
00208 if(nsamp_used < 3) {
00209
00210 return 102 ;
00211 }
00212
00213 variation_func_max = (z1*d22-z2*d12)/denom ;
00214 variation_tim_max = (-z1*d12+z2*d11)/denom ;
00215 chi2 = chi2/((double)nsamp_used - 2.) ;
00216 }
00217
00218 fAmp_fitted_max = fFunc_max + variation_func_max ;
00219 fTim_fitted_max = fTim_max + variation_tim_max ;
00220
00221 return chi2 ;
00222 }
00223
00224
00225
00226
00227 double PulseFitWithFunction::Electronic_shape(double tim)
00228 {
00229
00230 double func_electronic,dtsbeta,variable,puiss;
00231 double albet = fAlpha*fBeta ;
00232 if( albet <= 0 ) return( (Double_t)0. );
00233 double dt = tim-fTim_max ;
00234 if(dt > -albet) {
00235 dtsbeta=dt/fBeta ;
00236 variable=1.+dt/albet ;
00237 puiss=TMath::Power(variable,fAlpha);
00238 func_electronic=fFunc_max*puiss*TMath::Exp(-dtsbeta);
00239 }
00240 else func_electronic = 0. ;
00241
00242 return func_electronic ;
00243 }
00244 void PulseFitWithFunction::Fit_parab(Double_t *ampl,Int_t nmin,Int_t nmax,Double_t *parout)
00245 {
00246
00247
00248
00249 double denom,dt,amp1,amp2,amp3 ;
00250 double ampmax = 0. ;
00251 int imax = 0 ;
00252 int k ;
00253
00254
00255 for ( k = nmin ; k < nmax ; k++) {
00256
00257 if (ampl[k] > ampmax ) {
00258 ampmax = ampl[k] ;
00259 imax = k ;
00260 }
00261 }
00262 amp1 = ampl[imax-1] ;
00263 amp2 = ampl[imax] ;
00264 amp3 = ampl[imax+1] ;
00265 denom=2.*amp2-amp1-amp3 ;
00266
00267 if(denom>0.){
00268 dt =0.5*(amp3-amp1)/denom ;
00269 }
00270 else {
00271
00272 dt=0.5 ;
00273 }
00274
00275
00276
00277
00278 parout[0] =amp2+(amp3-amp1)*dt*0.25 ;
00279 parout[1] = (double)imax + dt ;
00280 parout[2] = (double)imax ;
00281 parout[3] = ampmax ;
00282 return ;
00283 }