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