CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/CalibCalorimetry/EcalLaserAnalyzer/src/TFParams.cc

Go to the documentation of this file.
00001 
00013 #include <CalibCalorimetry/EcalLaserAnalyzer/interface/TFParams.h>
00014 #include <malloc.h>
00015 #include "TMatrixD.h"
00016 #include "TMath.h"
00017 
00018 #include <iostream>
00019 #include <time.h>
00020 
00021 
00022 //ClassImp(TFParams)
00023 
00024 using namespace std;
00025 
00026 TFParams::TFParams( int size, int size_sh ) {
00027 
00028   //int  sdim = size;
00029   //int plshdim = size_sh;
00030 
00031 for (int i=0 ; i<10 ; i++) {
00032   for (int j=0 ; j<10 ; j++) {
00033       weight_matrix[i][j] = 8.; 
00034     }
00035   } 
00036 
00037 }
00038 
00039 double TFParams::fitpj(double **adcval , double *parout , double **db_i, double noise_val, int debug)
00040 {
00041   
00042 #define dimn 10
00043 #define dimin 10
00044 #define plshdim 300
00045 #define nsamp 10                                            
00046 #define ntrack 500       
00047   //#define debug debug1
00048 
00049   // ******************************************************************
00050   // *  Definitions of variables used in the routine                    
00051   // ******************************************************************
00052   
00053   
00054   double a1,a2,a3,a1i,a2i,a3i,b1,b2;
00055   int iter,nevt;
00056   double errpj[dimmat][dimmat]  ;
00057   double bi[ntrack][2],dbi[ntrack][2];
00058   double zi[ntrack][2] ;
00059   double par3degre[3] ;
00060   int    ioktk[ntrack],iokchi2[ntrack],nk,nborn_min=0,nborn_max=0;
00061   double cti[ntrack][6],dm1i[ntrack][4]; 
00062   double aiter[10][3];       
00063   double par[4],tsig[1];
00064   double amp,delta[nsamp],delta2,fun;
00065   double num_fit_min[ntrack],num_fit_max[ntrack] ;
00066   int i,j,k,imax[ntrack];
00067 
00068   double noise_initialvalue,one_over_noisesq ;
00069   double ampmax[ntrack],dt,t;
00070   double chi2, chi2s, da1[nsamp], da2[nsamp], db1[nsamp], db2[nsamp] ;
00071   double chi2tot;
00072   double fact1,fact2,expo;
00073   double albet,dtsbeta,variab,alpha,beta,puiss ;
00074   double  unsurs1 ,unsurs2 ;
00075   double fit3 ;
00076   int numb_a,numb_b,numb_ab,numb_b2,numb_x,ndimi,ndimj ;
00077 
00078   fun=0; chi2s=0; chi2tot=0;
00079   matrice DA,DAT,BK,DB,DBT,C,CT,D,DM1,CDM1,CDM1CT,Z,CDM1Z,YK,Y,B,X,XINV,RES2 ;
00080   matrice A_CROISS,ZMCT ;
00081 
00082   double *amplu ;
00083   amplu = new double[nsamp] ;
00084   
00085   parout[0] = 0. ;
00086   parout[1] = 0. ;
00087   parout[2] = 0. ;
00088 
00089   //
00090   //  Define Error Matrix 
00091   //
00092 
00093   noise_initialvalue = noise_val ;
00094   one_over_noisesq=1./(noise_initialvalue * noise_initialvalue)  ;
00095   for ( i=0 ; i<dimmat ; i++ ) {
00096     for ( j=0 ; j<dimmat ; j++ ) {
00097       errpj[i][j] = 0.  ;
00098     }
00099     errpj[i][i]=one_over_noisesq  ;
00100   }
00101   
00102   //  
00103   //  Initialisation of fit parameters 
00104   //  
00105 
00106   a1 = a1ini ;
00107   a2 = a2ini ;
00108   a3 = a3ini ;
00109   if( METHODE==2) {
00110     a2 = a3ini ;   // for lastshape BETA is the third parameter ( ... ! )
00111   }
00112   a1i = a1 ;
00113   a2i = a2 ;
00114   a3i = a3 ;
00115   if (debug==1){
00116     printf(" ------> __> valeurs de a1 %f a2 %f a3 %f\n",a1,a2,a3) ;
00117   }
00118   for (i=0 ; i<ntrack ; i++) {
00119     iokchi2[i]=1 ;
00120     for (j=0 ; j<2 ; j++ ) {
00121       bi[i][j] = (double)0. ;
00122       dbi[i][j] = (double)0. ;
00123       zi[i][j]=(double)0. ;
00124       cti[i][j]=(double)0. ;
00125       dm1i[i][j]=(double)0. ;
00126     }
00127   }
00128 
00129   ndimi = 2 ;
00130   ndimj = 2 ;
00131   numb_a = 2 ;
00132 
00133 
00134   //
00135   //  Matrices initialisation
00136   //
00137 
00138   numb_x = 1 ;
00139   numb_b = 2 ;
00140   numb_ab = numb_a*numb_b ;
00141   numb_b2 = numb_b*numb_b ;
00142   DA = cree_mat(numb_a,numb_x) ;
00143   DAT = cree_mat(numb_x,numb_a) ;
00144   BK = cree_mat_prod(DA,DAT) ;
00145   DB = cree_mat(numb_b,numb_x) ;
00146   DBT = cree_mat(numb_x,numb_b) ;
00147   C = cree_mat(numb_a,numb_b) ;
00148   CT = cree_mat(numb_b,numb_a) ;
00149   D = cree_mat_prod(DB,DBT) ;
00150   DM1 = cree_mat_prod(DB,DBT) ;
00151   CDM1 = cree_mat_prod(C,DM1) ;
00152   CDM1CT = cree_mat_prod(CDM1,CT) ;
00153   Z = cree_mat(numb_b,numb_x) ;
00154   CDM1Z =cree_mat_prod(CDM1,Z) ;
00155   YK =cree_mat(numb_a,numb_x) ;
00156   Y =cree_mat(numb_a,numb_x) ;
00157   B = cree_mat_prod(DA,DAT) ;
00158   X = cree_mat_prod(DA,DAT) ;
00159   XINV = cree_mat_prod(DA,DAT) ;
00160   RES2=cree_mat(numb_a,numb_x) ;
00161   A_CROISS = cree_mat(numb_a,numb_x) ;
00162   ZMCT = cree_mat(numb_b,numb_x) ;
00163 
00164 
00166   // First Loop on iterations //                            
00168  
00169   for (iter=0 ; iter < 6 ; iter++) {
00170 
00171     chi2tot=0;
00172 
00173     //    
00174     //    Set zeros for general matrices
00175     //                                                                      
00176     
00177     if (debug==1){
00178       printf(" Debut de l'iteration numero %d \n",iter) ;
00179     }
00180     zero_mat(CDM1Z) ;
00181     zero_mat(Y) ;
00182     zero_mat(CDM1CT) ;
00183     zero_mat(B) ;
00184     zero_mat(X) ;
00185     zero_mat(CDM1) ;
00186 
00187 
00188     nk = -1 ;   
00189     aiter[iter][0] = a1 ;
00190     aiter[iter][1] = a2 ;
00191     if (debug==1){
00192       printf( " resultats injectes a iterations %d \n",iter) ;
00193       printf( " parametre a1 = %f \n",a1) ;
00194       printf( " parametre a2 = %f \n",a2) ;
00195       printf( " chi2 du fit chi2s = %f \n",chi2s) ;
00196       
00197       printf(" value de nevtmax _______________ %d \n",nevtmax) ;
00198     }
00199     
00200     
00202     //  Loop on events //
00204     
00205     for (nevt=0 ; nevt < nevtmax ; nevt++) {
00206                  
00207       //       B1 = BI[nk,1] est la normalisation du signal                    
00208       //       B2 = BI[nk,2] ewst le dephasage par rapport a une            
00209       //                 fonction centree en zero                                 
00210       //        Nous choisissons ici de demarrer avec les resultats           
00211       //            de l'ajustement parabolique mais il faudra bien             
00212       //            entendu verifier que cela ne biaise pas le resultat !      
00213       //            mise a zero des matrices utilisees dans la boucle             
00214       
00215       
00216       zero_mat(Z) ;
00217       zero_mat(YK) ;
00218       zero_mat(BK) ;
00219       zero_mat(C) ;
00220       zero_mat(D) ;
00221       
00222       nk=nevt ;  
00223       ampmax[nk] = 0. ;
00224       imax[nk] = 0 ;
00225       for ( k = 0 ; k < 10 ; k++) {     
00226         amplu[k]=adcval[nevt][k] ; 
00227         if (amplu[k] > ampmax[nk] ) {
00228           ampmax[nk] = amplu[k] ;
00229           imax[nk] = k ; 
00230         }
00231       }
00232       
00233       
00234       if( iter == 0 ) {
00235 
00236         // start with degree 3 polynomial .... 
00237         //fit3 =polfit(ns ,imax[nk] ,par3degre ,errpj ,amplu ) ;
00238         //      std::cout << "Poly Fit Param  :"<< par3degre[0] <<" "<< par3degre[1]<< std::endl; 
00239         
00240         // start with parabol
00241         //fit3 = parab(amplu,4,12,par3degre) ;
00242         fit3 = parab(amplu,2,9,par3degre) ;
00243         //std::cout << "Parab Fit Param :"<< par3degre[0] <<" "<< par3degre[1]<< std::endl; 
00244 
00245 
00246         // start with basic initial values
00247         //par3degre[0]= ampmax+ampmax/10. ;
00248         //par3degre[1]= (double)imax[nk]+0.1 ;
00249         //bi[nk][0] = ampmax[nk] ;
00250         //bi[nk][1] = (double)imax[nk] ;
00251 
00252         num_fit_min[nevt] = (double)imax[nk] - (double)nsmin ;
00253         num_fit_max[nevt] = (double)imax[nk] + (double)nsmax ;
00254         
00255         
00256         bi[nk][0] = par3degre[0] ;
00257         bi[nk][1] = par3degre[1] ;
00258         
00259         
00260         if (debug==1){
00261           printf("---------> depart ampmax[%d]=%f   maximum %f tim %f \n",
00262                  nk,ampmax[nk],bi[nk][0],bi[nk][1]);
00263         }
00264         
00265       } else {
00266         
00267         
00268         //  in other iterations  :                                              
00269         //   increment bi[][] parameters with bdi[][]                         
00270         //   calculated in previous                                           
00271         //   iteration                                                                      
00272         
00273 
00274         bi[nk][0] +=  dbi[nk][0] ;
00275         bi[nk][1] +=  dbi[nk][1] ;
00276         
00277         if (debug==1){
00278           printf("iter %d valeur de max %f et norma %f poly 3 \n",iter,bi[nk][1],bi[nk][0]) ;
00279         }       
00280       }
00281     
00282       b1 = bi[nk][0] ;
00283       b2 = bi[nk][1] ;
00284 
00285 
00287       // Loop on samples //                         
00289       
00290       chi2 = 0. ;
00291       ioktk[nk] = 0 ;
00292       ns =nborn_max-nborn_min+1 ;
00293        
00294       for (k=0 ; k < 10 ; k++){
00295         
00296         //
00297         //      calculation of fonction used to fit
00298         //       
00299         
00300         dt =(double)k - b2 ;
00301         t = (double)k ;
00302         amp = amplu[k] ;
00303         if (debug==1){
00304           printf(" CHECK sample %f ampli %f \n",t,amp) ;
00305         }
00306         //unsurs1 = 1./sig_err ;
00307         //unsurs2 = 1./(sig_err*sig_err) ;
00308         //unsurs1 = 0.1 ;
00309         //unsurs2 = 0.01 ;
00310         
00311         
00312         unsurs1=1./noise_val;
00313         unsurs2=(1./noise_val)*(1./noise_val);
00314 
00315         //                                                   
00316         // Pulse shape function used: pulseShapepj
00317         //
00318         
00319         nborn_min = (int)num_fit_min[nevt] ;
00320         nborn_max = (int)num_fit_max[nevt] ;
00321         if(k < nborn_min || k > nborn_max ) continue ;
00322         tsig[0] =(double)k  ;
00323 
00324         
00325         if(METHODE==2) {
00326         par[0]=  b1 ;
00327         par[1] = b2 ;
00328         par[2] = a1 ;
00329         par[3] = a2 ;
00330         fun = pulseShapepj( tsig , par) ;
00331         }
00332         if (debug==1){
00333           printf(" valeur ampli %f et function %f min %d max %d \n",amp,fun,nsmin,nsmax) ;
00334           printf("min %f max %f \n",num_fit_min[nevt],num_fit_max[nevt]) ;
00335         }
00336         
00337         //       we need to determine a1,a2 which are global parameters         
00338         //        and  b1, b2 which are parameters for each individual signal: 
00339         //        b1, b2 = amplitude and time event by event
00340         //        a1, a2 = alpha and beta global      
00341         //        we first begin to calculate the derivatives used in the following calculation                                              
00342         
00343         if(METHODE==2){
00344           alpha = a1 ;
00345           beta  = a2 ;
00346           albet=alpha*beta;
00347           if(dt > -albet)  { 
00348             variab = (double)1. + dt/albet ;
00349             dtsbeta = dt/beta ;
00350             expo = exp(-dtsbeta) ;       
00351             puiss = pow(variab,alpha) ;
00352             fact1 = puiss*expo ;         
00353             db1[k] = unsurs1*fun/b1 ;
00354             fact2 =  fun ;
00355             db2[k] = unsurs1*fact2*dtsbeta/(albet*variab) ;
00356             da1[k] = unsurs1*fact2*(log(variab)-dtsbeta/(alpha*variab)) ;
00357             da2[k] = unsurs1*fact2*dtsbeta*dtsbeta/(albet*variab) ;
00358           }
00359         }
00360         delta[k] = (amp - fun)*unsurs1 ;
00361         if (debug==1){
00362           printf(" ------->iter %d valeur de k %d amp %f fun %f delta %f \n",
00363                  iter,k,amp,fun,delta[k]) ;
00364           printf(" -----> valeur de k %d delta %f da1 %f da2 %f  \n",
00365                  k,delta[k],da1[k],da2[k]) ;
00366         }
00367 
00368         chi2 = chi2 + delta[k]*delta[k]     ;
00369         
00370         if (debug==1){
00371           printf(" CHECK chi2 %f deltachi2 %f sample %d iter %d \n",chi2,delta[k]*delta[k],k, iter) ;
00372         }
00373 
00374       }
00375     
00376       
00378       // End Loop on samples //                     
00380       
00381       
00382       double wk1wk2 ;
00383 
00385       // Start Loop on samples //                           
00387 
00388       for(int k1=nborn_min ; k1<nborn_max+1 ; k1++) {
00389         wk1wk2 = 1. ;
00390         int k2 = k1 ;
00391         
00392         DA.coeff[0][0] = da1[k1]*wk1wk2 ;
00393         DA.coeff[1][0] = da2[k1]*wk1wk2 ;
00394         DAT.coeff[0][0]= da1[k2] ;
00395         DAT.coeff[0][1]= da2[k2] ;
00396         DB.coeff[0][0] = db1[k1]*wk1wk2 ;
00397         DB.coeff[1][0] = db2[k1]*wk1wk2 ;
00398         DBT.coeff[0][0]= db1[k2] ;
00399         DBT.coeff[0][1]= db2[k2] ;
00400         
00401         //  Compute derivative matrix : matrix b[2][2]  
00402         
00403         produit_mat_int(DA,DAT,BK) ;
00404         
00405         //  Compute matrix c[2][2]                                  
00406         
00407         produit_mat_int(DA,DBT,C) ;
00408         
00409         //  Compute matrix d[2][2]                                   
00410         
00411         produit_mat_int(DB,DBT,D) ;
00412         
00413         //  Compute matrix y[3] and z[2] depending of delta (amp-fun)        
00414         
00415         delta2 = delta[k2] ;
00416         
00417         somme_mat_int_scale(DA,YK,delta2) ;                     
00418         somme_mat_int_scale(DB,Z,delta2) ;
00419         
00420         ioktk[nk]++ ;
00421         
00422       }
00423       
00425       // End Loop on samples //                     
00427       
00428       
00429       //  Remove events with a bad shape 
00430       
00431       if(ioktk[nk] < 4 ) {
00432         printf(" event rejected because npamp_used = %d \n",ioktk[nk]);
00433         continue ;
00434       }
00435       chi2s = chi2/(2. + (double)ns + 2.)  ;      
00436       chi2tot+=chi2s;
00437 
00438       if (debug==1){
00439         if (nevt==198 || nevt==199){
00440           std::cout << "adc123 pour l'evt " << nevt <<" = "<<adcval[nevt][nborn_min]<<" = "<<adcval[nevt][imax[nevt]]<<" = "<<adcval[nevt][nborn_max]<<std::endl;
00441           std::cout << "chi2s  pour l'evt " << nevt <<" = "<< chi2s<<" "<< chi2<<" "<< ns<<"  "<<iter<<std::endl;
00442           std::cout << "chi2tot           " << nevt <<" = "<< chi2tot<<"  "<<iter<<std::endl;
00443         }
00444       }
00445       
00446       //  Transpose matrix C ---> CT                        
00447      
00448       transpose_mat(C,CT) ;
00449       
00450       //  Calculate DM1 (inverse of D matrix 2x2)                 
00451       
00452       inverse_mat(D,DM1) ;
00453 
00454       
00455       //  Set matrix product c*d in memory in order to compute variations    
00456       //   of parameters B at the end of the iteration loop                   
00457       //   the variations of parameters b are dependant of the variations of  
00458       //   parameters da[1],da[2]                                            
00459          
00460       cti[nk][0] = CT.coeff[0][0]  ;
00461       cti[nk][1] = CT.coeff[0][1]  ;
00462       cti[nk][2] = CT.coeff[1][0]  ;
00463       cti[nk][3] = CT.coeff[1][1]  ;
00464       
00465       
00466        dm1i[nk][0] = DM1.coeff[0][0] ;
00467        dm1i[nk][1] = DM1.coeff[0][1] ;
00468        dm1i[nk][2] = DM1.coeff[1][0] ;
00469        dm1i[nk][3] = DM1.coeff[1][1] ; 
00470 
00471        zi[nk][0] = Z.coeff[0][0]  ;
00472        zi[nk][1] = Z.coeff[1][0]  ;
00473 
00474        //   Sum the matrix b and y after every event            
00475       
00476        for( k=0 ; k< numb_a ; k++) {
00477          Y.coeff[k][0] += YK.coeff[k][0] ;
00478        }
00479        somme_mat_int(BK,B) ;
00480        
00481 
00482        //   Calculate c(d-1)                                     
00483 
00484       produit_mat(C,DM1,CDM1) ;
00485 
00486       // Compute c(d-1)ct                                         
00487 
00488       produit_mat_int(CDM1,CT,CDM1CT);
00489                                                                  
00490       // Compute c(d-1)z                                          
00491       
00492       produit_mat_int(CDM1,Z,CDM1Z) ;
00493 
00494 
00495     }
00497       // End Loop on events //                      
00499     
00500     
00501     //  Compute b-cdm1ct
00502        
00503     diff_mat(B,CDM1CT,X) ;
00504     inverse_mat(X,XINV) ;
00505     diff_mat(Y,CDM1Z,RES2) ;
00506 
00507                                                                   
00508     // Calculation is now easy for da[0] da[1]                         
00509                                                                   
00510     produit_mat(XINV,RES2,A_CROISS) ;
00511 
00512     
00513     //  A la fin, on peut iterer en mesurant l'accroissement a apporter
00514     //    des parametres globaux par la formule db[i] = dm1(z-ct*da[i])  
00515          
00516     for( k=0 ; k< nk+1 ; k++) {
00517       
00518       if(METHODE ==2 ) {
00519         ZMCT.coeff[0][0] = zi[k][0] - (cti[k][0]*A_CROISS.coeff[0][0]+
00520                                        cti[k][1]*A_CROISS.coeff[1][0]) ;
00521         ZMCT.coeff[1][0] = zi[k][1] - (cti[k][2]*A_CROISS.coeff[0][0]+
00522                                        cti[k][3]*A_CROISS.coeff[1][0]) ;
00523       }
00524       
00525       dbi[k][0] = dm1i[k][0]*ZMCT.coeff[0][0] + dm1i[k][1]*ZMCT.coeff[1][0] ;
00526       dbi[k][1] = dm1i[k][2]*ZMCT.coeff[0][0] + dm1i[k][3]*ZMCT.coeff[1][0] ;
00527       if (debug==1){
00528         if( k < 100 ){
00529           printf(" variations de b1= %f et b2= %f  \n",dbi[k][0],dbi[k][1]) ;
00530         } 
00531       }
00532       db_i[k][0] = bi[k][0]+ dbi[k][0]   ;
00533       db_i[k][1] = bi[k][1]+ dbi[k][1]   ;
00534     }
00535     
00536     
00537     //   dbi[0] et dbi[1] mesurent les variations a apporter aux       
00538     //   parametres du signal                                          
00539                                                                      
00540     a1 += A_CROISS.coeff[0][0] ;
00541     a2 += A_CROISS.coeff[1][0] ;
00542     
00543 
00544     if (debug==1){
00545       printf(" CHECK croiss coef0: %f  croiss coef1: %f iter %d \n",fabs(A_CROISS.coeff[0][0]),fabs(A_CROISS.coeff[1][0]), iter);
00546     }
00547     if(fabs(A_CROISS.coeff[0][0]) < 0.001 && fabs(A_CROISS.coeff[1][0]) < 0.001)
00548       break;
00549     
00550   }
00551   
00553   //  End Loop on iterations //
00555 
00556   parout[0] = a1 ;
00557   parout[1] = a2 ;
00558   parout[2] = a3 ;
00559   if (debug==1){
00560     printf( " resultats trouves au bout de %d iterations \n",iter) ;
00561     printf( " parametre a1 = %f \n",a1) ;
00562     printf( " parametre a2 = %f \n",a2) ;
00563   }
00564 
00565   if (debug==1){
00566     std::cout << " Final chi2 / NDOF  :  "<< chi2tot/nevtmax << std::endl;
00567     std::cout << " Final (alpha,beta) : ("<< a1<<","<<a2<<")"<< std::endl;
00568   }
00569 
00570   return chi2tot/nevtmax ;
00571 
00572 }
00573 
00575 // End  Fitpj //
00577 
00578 
00579 
00580 /**************************************************************************/
00581 void TFParams::set_const( int n_samples, int sample_min, int sample_max ,
00582          double alpha ,double beta ,int nevtmaximum) {
00583 /*------------------------------------------------------------------------*/
00584   ns      = n_samples;
00585   nsmin   = sample_min ;
00586   nsmax   = sample_max ;
00587   nevtmax = nevtmaximum ;
00588   a1ini = alpha ;
00589   a2ini = 0.0 ;
00590   a3ini = beta ;
00591   step_shape = .04;
00592   METHODE = 2;
00593   if(ns > SDIM2) printf("warning: NbOfsamples exceed maximum\n");
00594 } 
00595 void TFParams::produit_mat(matrice A , matrice B , matrice M)
00596 {
00597   int i,j,k ;
00598 //  resultat du produit A*B = M 
00599   if(A.nb_colonnes != B.nb_lignes) {
00600     printf( " Erreur : produit de matrices de tailles incompatibles \n ");
00601     M.coeff = NULL ;
00602     return ;
00603   }
00604   M.nb_lignes = A.nb_lignes ;
00605   M.nb_colonnes = B.nb_colonnes ;
00606   zero_mat(M) ;
00607   for(i=0 ; i< M.nb_lignes; i++) {
00608     for(j=0 ; j< M.nb_colonnes ; j++) {
00609       for(k=0 ; k< A.nb_colonnes; k++){
00610         M.coeff[i][j] += A.coeff[i][k]*B.coeff[k][j] ;
00611       }
00612     }
00613   }
00614   return  ;
00615 }
00616 
00617 void TFParams::produit_mat_int(matrice A , matrice B, matrice M)
00618 {
00619   int i,j,k ;
00620   if(A.nb_colonnes != B.nb_lignes) {
00621     printf( " Erreur : produit de matrices de tailles incompatibles \n ");
00622     M.coeff = NULL ;
00623     return ;
00624   }
00625   M.nb_lignes = A.nb_lignes ;
00626   M.nb_colonnes = B.nb_colonnes ;
00627   for(i=0 ; i< M.nb_lignes; i++) {
00628     for(j=0 ; j< M.nb_colonnes ; j++) {
00629       for(k=0 ; k< A.nb_colonnes; k++){
00630         M.coeff[i][j] += A.coeff[i][k]*B.coeff[k][j] ;
00631       }
00632     }
00633   }
00634   return  ;
00635 }
00636 void TFParams::diff_mat(matrice A , matrice B , matrice M)
00637 {
00638   int i,j ;
00639 //resultat de la difference A-B = M 
00640   if(A.nb_lignes != B.nb_lignes) {
00641     printf( " Erreur : difference de matrices de tailles incompatibles \n ");
00642     M.coeff = NULL ;
00643     return ;
00644   }
00645   M.nb_lignes = A.nb_lignes ;
00646   M.nb_colonnes = A.nb_colonnes ;
00647   for(i=0 ; i< M.nb_lignes; i++) {
00648     for(j=0 ; j < M.nb_colonnes ; j++) {
00649       M.coeff[i][j] = A.coeff[i][j] - B.coeff[i][j] ;
00650     }
00651   }
00652   return  ;
00653   
00654 }
00655 void TFParams::copie_colonne_mat(matrice A , matrice M , int nk)
00656 {
00657   int i,j ;
00658   int k ;
00659  /* resultat de la copie de A dans un vecteur colonne M */
00660   k = 0 ;
00661   for(i=0 ; i< A.nb_lignes; i++) {
00662     for(j=0 ; j < A.nb_colonnes ; j++) {
00663       M.coeff[nk][k] = A.coeff[i][j] ;
00664    printf(" copie nk %d  i %d j %d k %d A %e M %e \n ",nk,i,j,k,A.coeff[i][j],
00665           M.coeff[nk][k]);      
00666       k++ ;
00667     }
00668   }
00669   return  ;
00670 }
00671 
00672 void TFParams::somme_mat_int(matrice A , matrice M)
00673 {
00674   int i,j;
00675  /* resultat de la somme integree M += A */
00676   if(A.nb_lignes != M.nb_lignes) {
00677     printf( " Erreur : somme de matrices de tailles incompatibles \n ");
00678     M.coeff = NULL ;
00679     return ;
00680   }
00681   M.nb_lignes = A.nb_lignes ;
00682   M.nb_colonnes = A.nb_colonnes ;
00683   for(i=0 ; i< M.nb_lignes; i++) {
00684     for(j=0 ; j< M.nb_colonnes ; j++) 
00685       M.coeff[i][j] += A.coeff[i][j] ;
00686   }
00687   return  ;
00688 }
00689 void TFParams::somme_mat_int_scale(matrice A , matrice M , double delta)
00690 {
00691   int i,j ;
00692   M.nb_lignes = A.nb_lignes ;
00693   M.nb_colonnes = A.nb_colonnes ;
00694   for(i=0 ; i< M.nb_lignes; i++) {
00695     for(j=0 ; j< M.nb_colonnes ; j++) M.coeff[i][j] += A.coeff[i][j]*delta ;
00696     }
00697   return  ;
00698 }
00699 void TFParams::transpose_mat(matrice A , matrice M)
00700 {
00701   int i,j;
00702 // resultat de la transposition = matrice M 
00703   for(i=0 ; i< A.nb_lignes; i++) {
00704     for(j=0 ; j< A.nb_colonnes ; j++) {
00705         M.coeff[j][i] = A.coeff[i][j]  ;
00706     }
00707   }
00708   return  ;
00709 }
00710 matrice cree_mat_prod(matrice A , matrice B)
00711 {
00712   int i,j;
00713   matrice M ; /* resultat de la creation */
00714  
00715   M.nb_lignes = A.nb_lignes ;
00716   M.nb_colonnes = B.nb_colonnes ;
00717   M.coeff = (double**)malloc(M.nb_lignes*sizeof(double*)) ;
00718   for(i=0 ; i< M.nb_lignes; i++) 
00719     M.coeff[i]=(double*)calloc(M.nb_colonnes,sizeof(double));
00720   for(i=0 ; i< M.nb_lignes; i++) {
00721 
00722     for(j=0 ; j< M.nb_colonnes ; j++) {
00723         M.coeff[i][j] = 0.  ;
00724     }
00725   }
00726   //printf(" creation de matrice ---->  nlignes %d ncolonnes %d  \n",
00727 //       M.nb_lignes,M.nb_colonnes) ;
00728   return (M) ;
00729 }
00730 matrice cree_mat(int n_lignes,int n_colonnes)
00731 {
00732   int i,j;
00733   matrice M ; /* resultat de la creation */
00734  
00735   M.nb_lignes = n_lignes ;
00736   M.nb_colonnes = n_colonnes ;
00737   M.coeff = (double**)malloc(M.nb_lignes*sizeof(double*)) ;
00738   for(i=0 ; i< M.nb_lignes; i++) 
00739     M.coeff[i]=(double*)calloc(M.nb_colonnes,sizeof(double));
00740   for(i=0 ; i< M.nb_lignes; i++) {
00741     for(j=0 ; j< M.nb_colonnes ; j++) {
00742         M.coeff[i][j] = 0.  ;
00743     }
00744   }
00745   //printf(" creation de matrice --->  nlignes %d ncolonnes %d  \n",
00746         // M.nb_lignes,M.nb_colonnes) ;
00747   return (M) ;
00748 }
00749 
00750 void fill_mat( matrice A , matrice M)
00751 {
00752   int i,j;
00753   /* on remplit la matrice M avec la matrice A */
00754  
00755   M.nb_lignes = A.nb_lignes ;
00756   M.nb_colonnes = A.nb_colonnes ;
00757   for(i=0 ; i< M.nb_lignes; i++) {
00758     for(j=0 ; j< M.nb_colonnes ; j++) {
00759         M.coeff[i][j] = A.coeff[i][j]  ;
00760         printf("matrice remplie %e \n",M.coeff[i][j]) ;
00761     }
00762   } 
00763   return ;
00764 }
00765 void TFParams::print_mat(matrice M)
00766 {
00767   int i,j ;
00768   if( M.coeff == NULL) 
00769     printf(" erreur : affichage d'une matrice vide \n") ;
00770   printf(" m_nli %d M_ncol %d \n",M.nb_lignes,M.nb_colonnes) ;
00771   for(i=0 ; i< M.nb_lignes; i++) {
00772     for(j=0 ; j< M.nb_colonnes ; j++) 
00773       printf(" MATRICE i= %d j= %d ---> %e \n",i,j,M.coeff[i][j]) ;
00774   }
00775   //printf(" apres passage d'impression \n") ;
00776   return ;
00777 }
00778 void TFParams::zero_mat(matrice M)
00779 {
00780   int i,j ;
00781   for(i=0 ; i< M.nb_lignes; i++) {
00782     for(j=0 ; j< M.nb_colonnes ; j++) M.coeff[i][j]=0. ; 
00783   }
00784   return ;
00785 }
00786 void TFParams::zero_mat_nk(matrice M,int nk)
00787 {
00788   int j ;
00789     for(j=0 ; j< M.nb_colonnes ; j++) M.coeff[nk][j]=0. ;
00790   return ;
00791 }
00792 void TFParams::print_mat_nk(matrice M,int nk)
00793 {
00794   int j ;
00795   if( M.coeff == NULL)
00796     printf(" erreur : affichage d'une matrice vide \n") ;
00797   printf(" nk = %d m_nli %d M_ncol %d \n",nk,M.nb_lignes,M.nb_colonnes) ;
00798     for(j=0 ; j< M.nb_colonnes ; j++) 
00799       printf(" MATRICE nk= %d j= %d  ---> %e \n",nk,j,M.coeff[nk][j]) ;    
00800   printf(" apres passage d'impression \n") ;
00801   return ;
00802 }
00803 void TFParams::inverse_mat( matrice A , matrice M )
00804 {
00805 /*   A[ligne][colonne]   B[ligne][colonne]   */
00806 int i , j   ;
00807 double  deter=0.  ;
00808 /*  M est la matrice inverse de A */
00809  
00810  if(A.nb_lignes != A.nb_colonnes) {
00811    printf( " attention matrice non inversible !!!! %d lignes %d colonnes \n",
00812            A.nb_lignes,A.nb_colonnes) ;
00813    return ;
00814  }
00815   zero_mat(M) ;
00816   if(A.nb_lignes == 2) {
00817     deter = A.coeff[0][0]*A.coeff[1][1] - A.coeff[0][1]*A.coeff[1][0] ;
00818     M.coeff[0][0] = A.coeff[1][1]/deter ;
00819     M.coeff[0][1] = -A.coeff[0][1]/deter ;
00820     M.coeff[1][0] = -A.coeff[1][0]/deter ;
00821     M.coeff[1][1] = A.coeff[0][0]/deter ;
00822   }
00823  else if(A.nb_lignes == 3) {
00824       M.coeff[0][0]=A.coeff[1][1]*A.coeff[2][2]-A.coeff[2][1]*A.coeff[1][2] ;
00825       M.coeff[1][1]=A.coeff[0][0]*A.coeff[2][2]-A.coeff[2][0]*A.coeff[0][2] ;
00826 
00827       M.coeff[2][2]=A.coeff[0][0]*A.coeff[1][1]-A.coeff[0][1]*A.coeff[1][0] ;
00828       M.coeff[0][1]=A.coeff[2][1]*A.coeff[0][2]-A.coeff[0][1]*A.coeff[2][2] ;
00829       M.coeff[0][2]=A.coeff[0][1]*A.coeff[1][2]-A.coeff[1][1]*A.coeff[0][2] ;
00830       M.coeff[1][0]=A.coeff[1][2]*A.coeff[2][0]-A.coeff[1][0]*A.coeff[2][2] ;
00831       M.coeff[1][2]=A.coeff[1][0]*A.coeff[0][2]-A.coeff[0][0]*A.coeff[1][2] ;
00832       M.coeff[2][0]=A.coeff[1][0]*A.coeff[2][1]-A.coeff[1][1]*A.coeff[2][0] ;
00833       M.coeff[2][1]=A.coeff[0][1]*A.coeff[2][0]-A.coeff[0][0]*A.coeff[2][1] ;
00834       deter=A.coeff[0][0]*M.coeff[0][0]+A.coeff[1][0]*M.coeff[0][1]
00835         +A.coeff[2][0]*M.coeff[0][2] ;
00836       for ( i=0 ; i<3 ; i++ ) {
00837         for ( j=0 ; j<3 ; j++ ) M.coeff[i][j] = M.coeff[i][j]/deter  ;
00838       }
00839  }
00840  else {
00841  printf(" Attention , on ne peut inverser la MATRICE %d \n",A.nb_lignes) ;
00842  return ;
00843  }
00844   
00845  return ;
00846 }
00847 Double_t TFParams::polfit(Int_t ns ,Int_t imax , Double_t par3d[dimout] , 
00848                  Double_t errpj[dimmat][dimmat] ,double *adcpj )
00849  {
00850   double val , val2 , val3 , adfmx[dimmat] , parfp3[dimout]  ;
00851   double ius[dimmat], maskp3[dimmat] ;
00852   double deglib,fit3,tm,h,xki2 ;
00853   int i ,nus ,ilow,isup ;
00854   val=adcpj[imax] ;
00855   val2=val/2.  ;
00856   val3=val/3.  ;
00857   ilow=0       ;
00858   isup=ns    ;
00859   deglib=-4.  ;
00860   for (i=0 ; i<ns ; i++ ){
00861     deglib=deglib+1.  ;
00862     ius[i] = 1. ;
00863     if((adcpj[i] < val3) && (i<imax) ){
00864       ilow=i  ;
00865     }
00866     if(adcpj[i] > val2 ){
00867       isup=i  ;
00868     }
00869   }
00870   ilow=ilow+1   ;
00871   if(ilow == imax )ilow=ilow-1 ;
00872   if(isup-ilow < 3) isup=ilow+3 ;
00873   nus=0  ;
00874   for(i=ilow ; i<=isup ; i++){
00875     
00876     adfmx[nus]=adcpj[i]  ;
00877     maskp3[nus] =0. ;
00878     if(ius[i] == 1) {
00879       maskp3[nus]=1. ;
00880       nus=nus+1    ;
00881     }
00882   }
00883   if(nus < 4) return 10000. ;
00884   xki2 =  f3deg (  nus , parfp3 ,  maskp3 , adfmx ,  errpj ) ;
00885   tm= parfp3[4]  ;
00886   h=parfp3[5] ;
00887   tm=tm+(double)ilow  ;
00888   par3d[0] = h ;
00889   par3d[1] = tm ;
00890   fit3 = xki2 ;
00891   return fit3 ;
00892 }
00893 double TFParams::f3deg (  int nmxu ,  double parom[dimout] , double mask[dimmat] , double adcpj[dimmat] , double errpj[dimmat][dimmat] ) {
00894 /*                                                                   */
00895 /*  fit   3rd degree polynomial                                      */
00896 /*  nmxu = nb of samples in sample data array adcpj[]
00897     parom   values of parameters
00898     errpj  inverse of the error matrix
00899     fplo3dg uses only the diagonal terms of errpj[][]
00900 */
00901   int i , k , l , iworst ;
00902   double  h , t2 , tm , delta , tmp ;
00903   double xki2 , dif , difmx , deglib   ;
00904   double t[dimmat] ,  f[dimmat][4]   ;
00905   double cov[dimmat][dimmat] , bv[4] , invcov[dimmat][dimmat] , s , deter  ;
00906   
00907   deglib=(double)nmxu - 4.  ;
00908   for ( i=0 ; i<nmxu ; i++ ) {
00909     t[i]=i ;
00910     f[i][0]=1. ;
00911     f[i][1]=t[i]  ;
00912     f[i][2]=t[i]*t[i]  ;
00913     f[i][3]=f[i][2]*t[i] ;
00914   }
00915 /*   computation of covariance matrix     */
00916   for ( k=0 ; k<4 ; k++ ) {
00917     for ( l=0 ; l<4 ; l++ ) {
00918       s=0.   ;
00919       for (i=0 ; i<nmxu ; i++ ) {
00920         s=s+f[i][k]*f[i][l]*errpj[i][i]*mask[i]   ;
00921       }
00922       cov[k][l]=s  ;
00923     }
00924     s=0.    ;
00925     for (i=0 ; i<nmxu ; i++ ) {
00926         s=s+f[i][k]*adcpj[i]*errpj[i][i]*mask[i]   ;
00927     }
00928       bv[k]=s  ;
00929   }
00930 /*     parameters                          */
00931   deter = inverpj ( 4 , cov , invcov );
00932   for ( k=0 ; k<4 ; k++ ) {
00933     s=0.  ;
00934     for ( l=0 ; l<4 ; l++ ) {
00935       s=s+bv[l]*invcov[l][k]   ;
00936     }
00937     parom[k]=s  ;
00938   }
00939 
00940   if( parom[3] == 0. ){
00941     parom[4] = -1000.;
00942     parom[5] = -1000.;
00943     parom[6] = -1000.;
00944     return 1000000.;
00945   }
00946 /*    worst hit and ki2                    */
00947   xki2=0.    ;
00948   difmx=0.   ;
00949     for (i=0 ; i<nmxu ; i++ ){
00950       t2=t[i]*t[i]  ;
00951       h= parom[0]+parom[1]*t[i]+parom[2]*t2+parom[3]*t2*t[i] ;
00952       dif=(adcpj[i]-h)*mask[i]     ;
00953         if(dif > difmx) {
00954           iworst=i  ;
00955           difmx=dif ;
00956         }
00957     }
00958     if(deglib > 0.5) xki2=xki2/deglib ;
00959 /*     amplitude and maximum position                    */
00960   delta=parom[2]*parom[2]-3.*parom[3]*parom[1]  ;
00961   if(delta > 0.){
00962     delta=sqrt(delta)  ;
00963     tm=-(delta+parom[2])/(3.*parom[3])  ;
00964     tmp=(delta-parom[2])/(3.*parom[3])  ;
00965   }
00966   else{
00967     parom[4] = -1000.;
00968     parom[5] = -1000.;
00969     parom[6] = -1000.;
00970     return xki2  ;
00971   }
00972   parom[4]= tm  ;
00973   parom[5]= parom[0]+parom[1]*tm+parom[2]*tm*tm+parom[3]*tm*tm*tm ;
00974   parom[6]= tmp ;
00975   // printf("par --------> %f %f %f %f \n",parom[3],parom[2],parom[1],parom[0]);
00976   
00977    return xki2  ;
00978 }
00979 /*------------------------------------------------------------------*/
00980 
00981 double TFParams::inverpj(int n,double g[dimmat][dimmat],double ginv[dimmat][dimmat] )
00982 {
00983 /*                                                                   */
00984 /*  inversion d une matrice symetrique definie positive de taille n  */
00985 /*  J.P. Pansart   Novembre 99                                       */
00986 /*                                                                   */
00987 int i , j , k , jj  ;
00988 double r ,  s  ;
00989 double deter=0  ;
00990 double al[dimmat][dimmat] , be[dimmat][dimmat]  ;
00991 /*   initialisation                                                  */
00992  for( i=0 ; i<n ; i++ ) {
00993    for ( j=0 ; j<n ; j++ ) {
00994     al[i][j] = 0.  ;
00995     be[i][j] = 0.  ;
00996    }
00997  }
00998 /*  decomposition en vecteurs sur une base orthonormee               */
00999  al[0][0] =  sqrt( g[0][0] )  ;
01000  for ( i=1 ; i<n ; i++ ) {
01001  al[i][0] = g[0][i] / al[0][0]  ;
01002    for ( j=1 ; j<=i ; j++ ) {
01003     s=0.   ;
01004     for ( k=0 ; k<=j-1 ; k++ ) {
01005      s=s+ al[i][k] * al[j][k]  ;
01006     }
01007     r= g[i][j] - s   ;
01008    if( j < i ) al[i][j] = r/al[j][j]  ;
01009    if( j == i ) al[i][j] =  sqrt ( r)  ;
01010    }
01011  }
01012 /*  inversion de la matrice al                                       */
01013  be[0][0] = 1./al[0][0]  ;
01014  for ( i=1 ; i<n ; i++ ) {
01015  be[i][i] = 1. / al[i][i]  ;
01016    for ( j=0 ; j<i ; j++ ) {
01017     jj=i-j-1  ;
01018     s=0.   ;
01019     for ( k=jj+1 ; k<=i ; k++ ) {
01020      s=s+ be[i][k] * al[k][jj]  ;
01021     }
01022     be[i][jj]=-s/al[jj][jj]  ;
01023    }
01024  }
01025 /*   calcul de la matrice ginv                                       */
01026  for ( i=0 ; i<n ; i++ ) {
01027    for ( j=0 ; j<n ; j++ ) {
01028     s=0.   ;
01029     for ( k=0 ; k<n ; k++ ) {
01030      s=s+ be[k][i] * be[k][j]  ;
01031     }
01032     ginv[i][j]=s  ;
01033     //    if (debug==1){
01034     //printf("valeur de la matrice %d %d %f \n",i,j,ginv[i][j]) ;
01035     //}
01036    }
01037  }
01038   return deter ;
01039 }
01040 /*                                                                   */
01041 /*  inversion d une matrice 3x3                                      */
01042 /*                                                                   */
01043 double TFParams::inv3x3(double a[3][3] , double b[3][3] )
01044 {
01045 /*   a[ligne][colonne]   b[ligne][colonne]   */
01046 int i , j   ;
01047 double  deter=0.  ;
01048       b[0][0]=a[1][1]*a[2][2]-a[2][1]*a[1][2] ;
01049       b[1][1]=a[0][0]*a[2][2]-a[2][0]*a[0][2] ;
01050       b[2][2]=a[0][0]*a[1][1]-a[0][1]*a[1][0] ;
01051       printf("a[x][x] %e %e %e %e %e %e %e \n",a[0][0],a[1][1],a[0][1],a[1][0],
01052              a[0][0]*a[1][1],a[0][1]*a[1][0],b[2][2]);
01053       b[0][1]=a[2][1]*a[0][2]-a[0][1]*a[2][2] ;
01054       b[0][2]=a[0][1]*a[1][2]-a[1][1]*a[0][2] ;
01055       b[1][0]=a[1][2]*a[2][0]-a[1][0]*a[2][2] ;
01056       b[1][2]=a[1][0]*a[0][2]-a[0][0]*a[1][2] ;
01057       b[2][0]=a[1][0]*a[2][1]-a[1][1]*a[2][0] ;
01058       b[2][1]=a[0][1]*a[2][0]-a[0][0]*a[2][1] ;
01059       deter=a[0][0]*b[0][0] + a[1][0]*b[0][1] + a[2][0]*b[0][2] ;
01060       printf(" deter = %e \n",deter) ;
01061  for ( i=0 ; i<3 ; i++ ) {
01062    for ( j=0 ; j<3 ; j++ ) {
01063      printf(" avant division a[3][3] %d %d  %e \n",i,j,a[i][j]) ;
01064      printf(" avant division b[3][3] %d %d  %e %e \n",i,j,b[i][j],deter) ;
01065      b[i][j] = b[i][j]/deter  ;
01066      printf(" valeur de b[3][3] apres division %d %d  %e %e \n",i,j,b[i][j],deter) ;
01067    }
01068  }
01069   return deter ;
01070 }
01071 
01072 double TFParams::pulseShapepj( Double_t *x, Double_t *par )
01073 {
01074 
01075   Double_t fitfun;
01076   Double_t ped, h, tm, alpha, beta;
01077   Double_t  dt, dtsbeta, albet, variab, puiss ;
01078   Double_t b1,b2,a1,a2 ;
01079   b1 = par[0] ;
01080   b2 = par[1] ;
01081   a1 = par[2] ;
01082   a2 = par[3] ;
01083 
01084   ped   =  0. ;
01085   h     =  b1 ;
01086   tm    =  b2 ;
01087   alpha =  a1 ;
01088   beta  =  a2 ;
01089   dt= x[0] - tm  ;
01090   //printf(" par %f %f %f %f dt = %f albet = %f",b1,b2,a1,a2,dt,albet) ;
01091   albet = alpha*beta ;
01092   if( albet <= 0 )return( (Double_t)0. );
01093 
01094   if(dt > -albet)  {
01095     dtsbeta=dt/beta ;
01096     variab=1.+dt/albet ;
01097     puiss=pow(variab,alpha);
01098     fitfun=h*puiss*exp(-dtsbeta) + ped;
01099     //printf(" dt = %f h = %f puiss = %f exp(-dtsbeta) %f \n",dt,h,puiss,
01100     // exp(-dtsbeta)) ;
01101      }
01102   else {
01103       fitfun = ped;
01104      }
01105 
01106   return fitfun;
01107 }
01108 
01109 double TFParams::lastShape( Double_t *x, Double_t *par )
01110 {
01111 
01112   Double_t fitfun;
01113   Double_t alpha, beta;
01114   Double_t dt,alphadt,exponent ;
01115   Double_t b1,b2 ;
01116   b1 = par[0] ;
01117   b2 = par[1] ;
01118   alpha = par[2] ;
01119   beta  = par[3] ;
01120   dt= x[0] - b2  ;
01121   alphadt = alpha*dt ;
01122   exponent = -(alphadt+(exp(-alphadt)-1.))/beta ; 
01123   fitfun = b1*exp(exponent) ; 
01124   return fitfun;
01125 }
01126 double TFParams::lastShape2( Double_t *x, Double_t *par )
01127 {
01128 
01129   Double_t fitfun;
01130   Double_t alpha, beta;
01131   Double_t dt,expo1,dt2,exponent ;
01132   Double_t b1,b2 ;
01133   b1 = par[0] ;
01134   b2 = par[1] ;
01135   alpha = par[2] ;
01136   beta  = par[3] ;
01137   dt= x[0] - b2  ;
01138   expo1 = exp(-beta*dt) ;
01139   dt2 = dt*dt ;
01140   exponent = -(alpha*dt2+(expo1-1.)) ;
01141   fitfun = b1*exp(exponent) ; 
01142   return fitfun;
01143 }
01144 
01145 Double_t TFParams::pulseShapepj2( Double_t *x, Double_t *par )
01146 {
01147 
01148   Double_t fitfun;
01149   Double_t ped, h, tm, alpha, beta;
01150   Double_t  dt, dtsbeta, albet, variab, puiss;
01151   Double_t b1,b2,a1,a2 ;
01152   b1 = par[0] ;
01153   b2 = par[1] ;
01154   a1 = par[2] ;
01155   a2 = par[3] ;
01156   ped   =  0. ;
01157   h     =  b1 ;
01158   tm    =  b2 ;
01159   alpha =  a1 ;
01160   beta  =  a2 ;
01161   dt= x[0]  ;
01162   albet = alpha*beta ;
01163   if( albet <= 0 )return( (Double_t)0. );
01164 
01165   if(dt > -albet)  {
01166     dtsbeta=dt/beta ;
01167     variab=1.+dt/albet ;
01168     puiss=pow(variab,alpha);
01169     fitfun=h*puiss*exp(-dtsbeta) + ped;
01170   }
01171   else {
01172     fitfun = ped;
01173   }
01174 
01175   /*  printf( "fitfun %f %f %f %f, %f %f %f\n", ped, h, tm, alpha, beta, *x, fitfun );  */
01176 
01177   return fitfun;
01178 }
01179 
01180 double TFParams::parab(Double_t ampl[nsamp],Int_t nmin,Int_t nmax,Double_t parout[3])
01181 {
01182 /* Now we calculate the parabolic adjustement in order to get        */
01183 /*    maximum and time max                                           */
01184   
01185   double denom,dt,amp1,amp2,amp3 ; 
01186   double ampmax = 0. ;                          
01187   int imax = 0 ;
01188   int k ;
01189 /*
01190                                                                    */     
01191   for ( k = nmin ; k < nmax ; k++) {
01192     if (ampl[k] > ampmax ) {
01193       ampmax = ampl[k] ;
01194       imax = k ;
01195     }
01196   }
01197         amp1 = ampl[imax-1] ;
01198         amp2 = ampl[imax] ;
01199         amp3 = ampl[imax+1] ;
01200         denom=2.*amp2-amp1-amp3  ;
01201 /*                                                                   */       
01202         if(denom>0.){
01203           dt =0.5*(amp3-amp1)/denom  ;
01204         }
01205         else {
01206           //printf("denom =%f\n",denom)  ;
01207           dt=0.5  ;
01208         }
01209 /*                                                                   */        
01210 /* ampmax correspond au maximum d'amplitude parabolique et dt        */
01211 /* decalage en temps par rapport au sample maximum soit k + dt       */
01212                 
01213         parout[0] =amp2+(amp3-amp1)*dt*0.25 ;
01214         parout[1] = (double)imax + dt ;
01215         parout[2] = (double)imax ;
01216 return denom ;
01217 }
01218 
01219 double TFParams::mixShape( Double_t *x, Double_t *par )
01220 {
01221   Double_t fitval0,fitval;
01222   Double_t alpha,beta,fact,puiss;
01223   Double_t dt,alpha2dt,exponent ;
01224   Double_t b1,b2,alpha2,t ;
01225   b1 = par[0] ;
01226   b2 = par[1] ;
01227   alpha  = par[2] ;
01228   alpha2 = par[3] ;
01229   beta   = par[4] ;
01230 //
01231   t = x[0] ;
01232   dt= x[0]-b2  ;
01233 //
01234   if(t>0.) {
01235   fact = t/b2 ;
01236   puiss = pow(fact,alpha) ;
01237   fitval0 = puiss*exp(-alpha*dt/b2) ;
01238   }
01239   else
01240   {
01241   fitval0=1. ;
01242   }
01243   dt = x[0] - b2 ;
01244   alpha2dt = dt*alpha2 ;
01245   exponent = -(alpha2dt+(exp(-alpha2dt)-1.))/beta ;
01246   fitval = b1*fitval0*exp(exponent) ;  
01247   return fitval;
01248 }
01249 //=========================
01250 // Method computePulseWidth
01251 //=========================
01252 double TFParams::computePulseWidth( int methode , double alpha_here , double beta_here){ 
01253 
01254 // level of amplitude where we calculate the width ( level = 0.5 if at 50 % )
01255 //   (level = 0.3 if at 30 % )
01256   double level = 0.30 ;
01257 // fixed parameters
01258   double amplitude   = 1.00 ;
01259   double offset      = 7.00;  
01260   double amp_max     = amplitude;
01261 
01262 // steps in time
01263   double t_min       =  offset-4.50;
01264   double t_max       =  offset+12.50;
01265 
01266   int    t_step_max  = 3000;
01267   double delta_t     =  (double)((t_max-t_min)/t_step_max);
01268       
01269 // Loop over time ( Loop 2  --> get width )
01270   int    t_amp_half_flag =    0;
01271   double t_amp_half_min  =  999.; 
01272   double t_amp_half_max  = -999.; 
01273 
01274   for (int t_step=0; t_step<t_step_max; t_step++){
01275 
01276        double t_val = t_min + (double)t_step*delta_t;
01277        double albet = alpha_here*beta_here ;
01278        double dt = t_val-offset ;
01279        double amp =0;
01280 
01281        if( methode == 2 ) { // electronic function
01282           if( (t_val-offset) > -albet) {
01283 
01284             amp =  amplitude*TMath::Power( ( 1 + ( dt / (alpha_here*beta_here) ) ) , alpha_here ) * TMath::Exp(-1.0*(dt/beta_here));
01285           } else {
01286             
01287             amp = 1. ;
01288           }
01289        } 
01290 
01291        if( amp > (amp_max*level) && t_amp_half_flag == 0) {
01292            t_amp_half_flag = 1;
01293            t_amp_half_min = t_val;
01294        }
01295 
01296        if( amp < (amp_max*level) && t_amp_half_flag == 1) {
01297            t_amp_half_flag = 2;
01298            t_amp_half_max = t_val;
01299        }          
01300 
01301    }
01302     
01303 // Compute Width
01304   double width = (t_amp_half_max - t_amp_half_min);
01305 
01306   return width;
01307 }
01308 
01309