Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <CalibCalorimetry/EcalLaserAnalyzer/interface/PulseFitWithShape.h>
00012
00013 #include <iostream>
00014 #include "TMath.h"
00015 #include <cmath>
00016
00017
00018
00019
00020
00021 PulseFitWithShape::PulseFitWithShape()
00022 {
00023
00024 fNsamples = 0;
00025 fNsamplesShape = 0;
00026 fNum_samp_bef_max = 0;
00027 fNum_samp_after_max = 0;
00028 fNoise = 0.0;
00029 }
00030
00031
00032 PulseFitWithShape::~PulseFitWithShape()
00033 {
00034 }
00035
00036
00037
00038 void PulseFitWithShape::init(int n_samples,int samplb,int sampla,int niter,int n_samplesShape, const std::vector<double>& shape, double nois)
00039 {
00040
00041 fNsamples = n_samples ;
00042 fNsamplesShape = n_samplesShape ;
00043 fNb_iter = niter ;
00044 fNum_samp_bef_max = samplb ;
00045 fNum_samp_after_max = sampla ;
00046
00047
00048 if( fNsamplesShape < fNum_samp_bef_max+fNum_samp_after_max+1){
00049 std::cout<<"PulseFitWithShape::init: Error! Configuration samples in fit greater than total number of samples!" << std::endl;
00050 }
00051
00052 for(int i=0;i<fNsamplesShape;i++){
00053 pshape.push_back(shape[i]);
00054 dshape.push_back(0.0);
00055 }
00056
00057 fNoise=nois;
00058 return ;
00059 }
00060
00061
00062
00063 double PulseFitWithShape::doFit(double *adc, double *cova)
00064 {
00065
00066
00067
00068
00069
00070
00071 bool useCova=true;
00072 if(cova==0) useCova=false;
00073
00074 double xpar[3];
00075 double chi2;
00076
00077 fAmp_fitted_max = 0. ;
00078 fTim_fitted_max = 0. ;
00079
00080
00081
00082 xpar[1]=0.0;
00083
00084
00085
00086 double noise=fNoise;
00087
00088
00089 xpar[0]=0.;
00090 xpar[2]=0.;
00091
00092
00093
00094
00095 int imax=0;
00096 double amax=0.0;
00097 for(int i=0; i<fNsamples; i++){
00098 if (adc[i]>amax){
00099 amax=adc[i];
00100 imax=i;
00101 }
00102 }
00103
00104
00105
00106 double qms=0.;
00107 int ims=0;
00108
00109
00110
00111 for(int is=0; is<fNsamplesShape; is++){
00112 if(pshape[is] > qms){
00113 qms=pshape[is];
00114 ims=is;
00115 }
00116
00117
00118
00119 if(is < fNsamplesShape-2)
00120 dshape[is]= (pshape[is+2]-pshape[is])*12.5;
00121 else
00122 dshape[is]=dshape[is-1];
00123 }
00124
00125
00126
00127 double sq1=pshape[ims-1];
00128 double sq2=pshape[ims];
00129 double sq3=pshape[ims+1];
00130
00131 double a2=(sq3+sq1)/2.0-sq2;
00132 double a1=sq2-sq1+a2*(1-2*ims);
00133
00134
00135 double t_ims=0;
00136 if(a2!=0) t_ims=-a1/(2.0*a2);
00137
00138
00139
00140
00141
00142 double qm=0.;
00143 int im=0;
00144
00145 int nsamplef=fNum_samp_bef_max + fNum_samp_after_max +1 ;
00146 int nsampleo=imax-fNum_samp_bef_max;
00147
00148 for(int is=0; is<nsamplef; is++){
00149
00150 if(adc[is+nsampleo] > qm){
00151 qm=adc[is+nsampleo];
00152 im=nsampleo+is;
00153 }
00154 }
00155
00156 double tm;
00157 if(qm > 5.*noise){
00158 if(im >= nsamplef+nsampleo) im=nsampleo+nsamplef-1;
00159 double q1=adc[im-1];
00160 double q2=adc[im];
00161 double q3=adc[im+1];
00162 double y2=(q1+q3)/2.-q2;
00163 double y1=q2-q1+y2*(1-2*im);
00164 double y0=q2-y1*(double)im-y2*(double)(im*im);
00165 tm=-y1/2./y2;
00166 xpar[0]=y0+y1*tm+y2*tm*tm;
00167 xpar[2]=(double)ims/25.-tm;
00168 }
00169
00170 double chi2old=999999.;
00171 chi2=99999.;
00172 int nsfit=nsamplef;
00173 int iloop=0;
00174 int nloop=fNb_iter;
00175 if(qm <= 5*noise)nloop=1;
00176
00177 double *resi;
00178 resi= new double[fNsamples];
00179 for (int j=0;j<fNsamples;j++) resi[j]=0;
00180
00181 while(std::fabs(chi2old-chi2) > 0.1 && iloop < nloop)
00182 {
00183 iloop++;
00184 chi2old=chi2;
00185
00186 double c=0.;
00187 double y1=0.;
00188 double s1=0.;
00189 double s2=0.;
00190 double ys1=0.;
00191 double sp1=0.;
00192 double sp2=0.;
00193 double ssp=0.;
00194 double ysp=0.;
00195
00196 for(int is=0; is<nsfit; is++)
00197 {
00198 int iis=is;
00199 iis=is+nsampleo;
00200
00201 double t1=(double)iis+xpar[2];
00202 double xbin=t1*25.;
00203 int ibin1=(int)xbin;
00204
00205 if(ibin1 < 0) ibin1=0;
00206
00207 double amp1,amp11,amp12,der1,der11,der12;
00208
00209 if(ibin1 <= fNsamplesShape-2){
00210
00211 int ibin2=ibin1+1;
00212 double xfrac=xbin-ibin1;
00213 amp11=pshape[ibin1];
00214 amp12=pshape[ibin2];
00215 amp1=(1.-xfrac)*amp11+xfrac*amp12;
00216 der11=dshape[ibin1];
00217 der12=dshape[ibin2];
00218 der1=(1.-xfrac)*der11+xfrac*der12;
00219
00220 }else{
00221
00222 amp1=pshape[fNsamplesShape-1]+dshape[fNsamplesShape-1]*
00223 (xbin-double(fNsamplesShape-1))/25.;
00224 der1=dshape[fNsamplesShape-1];
00225 }
00226
00227 if( useCova ){
00228 for(int js=0; js<nsfit; js++)
00229 {
00230 int jjs=js;
00231 jjs+=nsampleo;
00232
00233 t1=(double)jjs+xpar[2];
00234 xbin=t1*25.;
00235 ibin1=(int)xbin;
00236 if(ibin1 < 0) ibin1=0;
00237 if(ibin1 > fNsamplesShape-2)ibin1=fNsamplesShape-2;
00238 int ibin2=ibin1+1;
00239 double xfrac=xbin-ibin1;
00240 amp11=pshape[ibin1];
00241 amp12=pshape[ibin2];
00242 double amp2=(1.-xfrac)*amp11+xfrac*amp12;
00243 der11=dshape[ibin1];
00244 der12=dshape[ibin2];
00245 double der2=(1.-xfrac)*der11+xfrac*der12;
00246 c=c+cova[js*fNsamples+is];
00247 y1=y1+adc[iis]*cova[js*fNsamples+is];
00248 s1=s1+amp1*cova[js*fNsamples+is];
00249 s2=s2+amp1*amp2*cova[js*fNsamples+is];
00250 ys1=ys1+adc[iis]*amp2*cova[js*fNsamples+is];
00251 sp1=sp1+der1*cova[is*fNsamples+js];
00252 sp2=sp2+der1*der2*cova[js*fNsamples+is];
00253 ssp=ssp+amp1*der2*cova[js*fNsamples+is];
00254 ysp=ysp+adc[iis]*der2*cova[js*fNsamples+is];
00255 }
00256 }else {
00257 c++;
00258 y1=y1+adc[iis];
00259 s1=s1+amp1;
00260 s2=s2+amp1*amp1;
00261 ys1=ys1+amp1*adc[iis];
00262 sp1=sp1+der1;
00263 sp2=sp2+der1*der1;
00264 ssp=ssp+der1*amp1;
00265 ysp=ysp+der1*adc[iis];
00266 }
00267 }
00268 xpar[0]=(ysp*ssp-ys1*sp2)/(ssp*ssp-s2*sp2);
00269 xpar[2]+=(ysp/xpar[0]/sp2-ssp/sp2);
00270
00271 for(int is=0; is<nsfit; is++){
00272 int iis=is;
00273 iis=is+nsampleo;
00274
00275 double t1=(double)iis+xpar[2];
00276 double xbin=t1*25.;
00277 int ibin1=(int)xbin;
00278 if(ibin1 < 0) ibin1=0;
00279
00280 if(ibin1 < 0) ibin1=0;
00281 if(ibin1 > fNsamplesShape-2)ibin1=fNsamplesShape-2;
00282 int ibin2=ibin1+1;
00283 double xfrac=xbin-ibin1;
00284 double amp11=xpar[0]*pshape[ibin1];
00285 double amp12=xpar[0]*pshape[ibin2];
00286 double amp1=xpar[1]+(1.-xfrac)*amp11+xfrac*amp12;
00287 resi[iis]=adc[iis]-amp1;
00288 }
00289
00290 chi2=0.;
00291 for(int is=0; is<nsfit; is++){
00292 int iis=is;
00293 iis+=nsampleo;
00294
00295 if( useCova ){
00296 for(int js=0; js<nsfit; js++){
00297 int jjs=js;
00298 jjs+=nsampleo;
00299 chi2+=resi[iis]*resi[jjs]*cova[js*fNsamples+is];
00300 }
00301
00302 }else chi2+=resi[iis]*resi[iis];
00303 }
00304 }
00305
00306 fAmp_fitted_max = xpar[0];
00307 fTim_fitted_max = (double)t_ims/25.-xpar[2];
00308
00309 return chi2 ;
00310
00311 }
00312