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