00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <math.h>
00045
00046 #define UP 1
00047 #define DOWN -1
00048 #define HORI 0
00049 #define PRINT 0
00050 #include "f_find_peaks.h"
00051
00052 void f_find_peaks(
00053 void *pfData,
00054 int lType,
00055 int lFirstChan,
00056 int lPoints,
00057 int lAver,
00058 double dDeltaFact,
00059 double dDeltaMin,
00060 double *dNoise,
00061 int lPeaksMax,
00062 int *plPeaks,
00063 int *plMinima,
00064 double *pdMinima,
00065 int *plMaxima,
00066 int *plWidth,
00067 double *pdIntegral)
00068 {
00069 short *pw;
00070 int lMaxIndex,lMinIndex,lIndexMax,lDirection,lIndex,lLastUp,lLastDown,ii,i,
00071 *plMinimaL,*plMaximaL,*plMinimaR,*plMaximaR,lPrint,*pl;
00072 float *pf;
00073 double dValue,dLow,dHigh,dDelta,dAver,*pdData,*pdNoise,dMax,dMin,dPos,dSig,dSum,*pd;
00074
00075 *plPeaks=0;
00076 pdNoise=NULL;
00077 pdData = (double *)malloc(lPoints*8);
00078 pdNoise = (double *)malloc(lPoints*8);
00079 memset(pdData,0,lPoints*8);
00080 memset(pdNoise,0,lPoints*8);
00081 lPrint=PRINT;
00082 dMax=0.;
00083 dMin=1e20;
00084 pw = ((short *)pfData) + lFirstChan;
00085 pl = ((int *)pfData) + lFirstChan;
00086 pf = ((float *)pfData) + lFirstChan;
00087 pd = ((double *)pfData) + lFirstChan;
00088 if(lAver == 0)lAver=1;
00089 lPoints=lPoints/lAver;
00090 dAver = (double) lAver;
00091
00092 switch(lType)
00093 {
00094 case TYPE__SHORT: for(ii=0;ii<lPoints;ii++)
00095 { *(pdData+ii) = (double)*(pw+lAver*ii);
00096 for(i=1;i<lAver;i++)*(pdData+ii) += (double)*(pw+lAver*ii+i);
00097 *(pdData+ii) = *(pdData+ii)/dAver;
00098 if(*(pdData+ii) > dMax) dMax=*(pdData+ii);
00099 if(*(pdData+ii) < dMin) dMin=*(pdData+ii);} break;
00100 case TYPE__INT: for(ii=0;ii<lPoints;ii++)
00101 { *(pdData+ii) = (double)*(pl+lAver*ii);
00102 for(i=1;i<lAver;i++)*(pdData+ii) += (double)*(pl+lAver*ii+i);
00103 *(pdData+ii) = *(pdData+ii)/dAver;
00104 if(*(pdData+ii) > dMax) dMax=*(pdData+ii);
00105 if(*(pdData+ii) < dMin) dMin=*(pdData+ii);} break;
00106 case TYPE__FLOAT: for(ii=0;ii<lPoints;ii++)
00107 { *(pdData+ii) = (double)*(pf+lAver*ii);
00108 for(i=1;i<lAver;i++)*(pdData+ii) += (double)*(pf+lAver*ii+i);
00109 *(pdData+ii) = *(pdData+ii)/dAver;
00110 if(*(pdData+ii) > dMax) dMax=*(pdData+ii);
00111 if(*(pdData+ii) < dMin) dMin=*(pdData+ii);} break;
00112 case TYPE__DOUBLE: for(ii=0;ii<lPoints;ii++)
00113 { *(pdData+ii) = (double)*(pd+lAver*ii);
00114 for(i=1;i<lAver;i++)*(pdData+ii) += (double)*(pd+lAver*ii+i);
00115 *(pdData+ii) = *(pdData+ii)/dAver;
00116 if(*(pdData+ii) > dMax) dMax=*(pdData+ii);
00117 if(*(pdData+ii) < dMin) dMin=*(pdData+ii);} break;
00118 default: printf("Data type %d not supported!\n",lType);
00119 printf("Type 0: short, 1: int, 2: float, 3: double\n");
00120 free(pdData);
00121 free(pdNoise);
00122 return;
00123 }
00124 if(dNoise == NULL)
00125 {
00126 for(ii=0;ii<lPoints;ii++)
00127 {
00128 if(*(pdData+ii) == 0.0) *(pdNoise+ii) = dDeltaFact;
00129 else *(pdNoise+ii) = sqrt(*(pdData+ii)) * dDeltaFact;
00130 if(dDeltaMin > *(pdNoise+ii)) *(pdNoise+ii)=dDeltaMin;
00131 }
00132 }else {
00133 for(ii=0;ii<lPoints;ii++)
00134 { *(pdNoise+ii) = *(dNoise+lFirstChan+lAver*ii);
00135 for(i=1;i<lAver;i++)*(pdNoise+ii) += *(dNoise+lFirstChan+lAver*ii+i);
00136 *(pdNoise+ii) = *(pdNoise+ii)/dAver;
00137 }
00138 }
00139 lMaxIndex=0;
00140 lMinIndex=0;
00141 lIndexMax=lPoints-1;
00142 plMinimaL = (int *)malloc(lPeaksMax*16);
00143 plMaximaL = (int *)(plMinimaL+lPeaksMax);
00144 plMinimaR = (int *)(plMinimaL+2*lPeaksMax);
00145 plMaximaR = (int *)(plMinimaL+3*lPeaksMax);
00146 memset(plMinimaL,0,lPeaksMax*16);
00147
00148 dDelta= *pdNoise;
00149 dHigh = *pdData + dDelta;
00150 dLow = *pdData - dDelta;
00151
00152
00153 lDirection=HORI;
00154 lIndex=0;
00155 lLastDown=0;
00156 lLastUp=0;
00157 while ((lIndex <= lIndexMax) & (lMaxIndex < lPeaksMax-2))
00158 {
00159 dValue = *(pdData+lIndex);
00160 if(dValue > dHigh)
00161 {
00162 if (lDirection != UP)
00163 {
00164 if(lPrint)printf("%5d - %5d - %5d d %8.1f\n",
00165 lMinIndex,
00166 lLastDown,
00167 lIndex,
00168 dDelta);
00169 *(plMinimaR+lMinIndex)=lIndex;
00170 *(plMinimaL+lMinIndex)=lLastDown;
00171 lMinIndex++;
00172 }
00173 lLastUp=lIndex;
00174 lDirection=UP;
00175 }
00176 if(dValue < dLow)
00177 {
00178 if (lDirection == UP)
00179 {
00180 if(lPrint)printf("%5d + %5d - %5d d %8.1f\n",
00181 lMaxIndex,
00182 lLastUp,
00183 lIndex,
00184 dDelta);
00185 *(plMaximaR+lMaxIndex)=lIndex;
00186 *(plMaximaL+lMaxIndex)=lLastUp;
00187 lMaxIndex++;
00188 }
00189 lLastDown=lIndex;
00190 lDirection=DOWN;
00191 }
00192
00193 if((dValue < dLow)|(dValue > dHigh))
00194 {
00195 dDelta= *(pdNoise+lIndex);
00196 dHigh = dValue + dDelta;
00197 dLow = dValue - dDelta;
00198 }
00199 lIndex++;
00200 }
00201 if(lDirection == DOWN)
00202 {
00203 *(plMinimaL+lMinIndex)=lLastDown;
00204 *(plMinimaR+lMinIndex)=lIndexMax;
00205 if(lPrint)printf("%5d - %5d - %5d\n",
00206 lMinIndex,
00207 lLastDown,
00208 lIndexMax);
00209 lMinIndex++;
00210 }
00211
00212 if(lPrint)printf("-------------------------\n");
00213 if(lPrint)printf("Minima %d Maxima %d \n",lMinIndex,lMaxIndex);
00214
00215 if(lMinIndex != (lMaxIndex+1))
00216 {
00217 free(plMinimaL);
00218 free(pdData);
00219 free(pdNoise);
00220 printf("Error, wrong minima\n");
00221 return;
00222 }
00223
00224
00225 if(lPrint)printf(" [ Left Right ] \n");
00226 *plMinima = (*plMinimaL + *plMinimaR)/2;
00227 *plMinima = (int)((double)(*plMinima)*dAver + dAver/2.)+lFirstChan;
00228 *pdMinima=0.;
00229 for(ii = *plMinimaL;ii <= *plMinimaR;ii++) *pdMinima += *(pdData+ii);
00230 *pdMinima = *pdMinima/(double)(*plMinimaR - *plMinimaL + 1);
00231 if(lPrint)printf("- [%6d %6d] %6d %6.1f\n",
00232 *plMinimaL,
00233 *plMinimaR,
00234 *plMinima,
00235 *pdMinima);
00236 for(lIndex=0;lIndex < lMaxIndex;lIndex++)
00237 {
00238
00239 *(plMaxima+lIndex)=(*(plMaximaL+lIndex)+*(plMaximaR+lIndex))/2;
00240 if(lPrint)printf("+ [%6d %6d] %6d\n",
00241 *(plMaximaL+lIndex),
00242 *(plMaximaR+lIndex),
00243 *(plMaxima+lIndex));
00244
00245 *(plMinima+lIndex+1) = (*(plMinimaL+lIndex+1) + *(plMinimaR+lIndex+1))/2;
00246 *(plMinima+lIndex+1) = (int)((double)(*(plMinima+lIndex+1))*dAver + dAver/2.)+lFirstChan;
00247 *(pdMinima+lIndex+1)=0.;
00248 for(ii = *(plMinimaL+lIndex+1);ii <= *(plMinimaR+lIndex+1);ii++)
00249 *(pdMinima+lIndex+1) += *(pdData+ii);
00250 *(pdMinima+lIndex+1) = *(pdMinima+lIndex+1)/
00251 (double)(*(plMinimaR+lIndex+1) - *(plMinimaL+lIndex+1)+1);
00252 if(lPrint)printf("- [%6d %6d] %6d %6.1f\n",
00253 *(plMinimaL+lIndex+1),
00254 *(plMinimaR+lIndex+1),
00255 *(plMinima+lIndex+1),
00256 *(pdMinima+lIndex+1));
00257
00258 ii = *(plMinimaL+lIndex+1) - *(plMinimaR+lIndex) + 1;
00259 if(ii > 1)
00260 {
00261 f_position(ii,pdData + *(plMinimaR+lIndex),&dPos,&dSig,&dSum);
00262
00263 *(plMaxima+*plPeaks)=(int)((dPos+(double)(*(plMinimaR+lIndex)))*dAver)+lFirstChan;
00264 *(plWidth+*plPeaks) =(int)(dSig*dAver + 0.5);
00265 if(*(pdMinima+lIndex) < *(pdMinima+lIndex+1))
00266 dSum=dSum-((double)ii * *(pdMinima+lIndex)+ (double)ii * (*(pdMinima+lIndex+1)-*(pdMinima+lIndex))/2.);
00267 else
00268 dSum=dSum-((double)ii * *(pdMinima+lIndex)- (double)ii * (*(pdMinima+lIndex)-*(pdMinima+lIndex+1))/2.);
00269 *(pdIntegral+*plPeaks) = dSum*dAver;
00270 (*plPeaks)++;
00271 }
00272 else
00273 {
00274 free(plMinimaL);
00275 free(pdData);
00276 free(pdNoise);
00277 printf("Error, negative interval\n");
00278 return;
00279 }
00280 }
00281 if(lPrint)printf("peaks found %d\n",*plPeaks);
00282
00283 free(plMinimaL);
00284 free(pdData);
00285 free(pdNoise);
00286 }
00287
00288 int f_position(int l_len,double *pa_data,double *pr_pos,double *pr_sig, double *pr_sum)
00289 {
00290
00291 #define LOW 2
00292 #define WIDTH 8
00293
00294 double r_sig_f ;
00295 int I,J,K,L ;
00296 double d_sum_prod ;
00297 double l_max_chan ;
00298 double *pl_data,d_max ;
00299
00300 ;
00301 r_sig_f = 55.4518;
00302 r_sig_f = 2.;
00303 *pr_sum = 0;
00304 d_sum_prod = 0;
00305 *pr_sig = 0.;
00306 *pr_pos = 0.;
00307 d_max=0.0;
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 pl_data = pa_data;
00323 for(J = 1; J <= l_len; J++)
00324 {
00325 *pr_sum = *pr_sum + *pl_data;
00326 d_sum_prod = d_sum_prod + J * *pl_data;
00327 pl_data++;
00328 }
00329
00330 if(*pr_sum > 0)
00331 {
00332 *pr_pos = (d_sum_prod/ *pr_sum + 0.5);
00333 pl_data = pa_data;
00334 for(J = 1; J <= l_len; J++)
00335 {
00336 *pr_sig = *pr_sig + ((double)J - *pr_pos) * ((double)J - *pr_pos) * *pl_data;
00337 pl_data++;
00338 }
00339 *pr_sig = r_sig_f * sqrt(*pr_sig/ *pr_sum);
00340 }
00341 else return(1);
00342 *pr_pos = *pr_pos -1.0;
00343 return(0);
00344 }