00001 #include "ctypes_def.h"
00002
00003 #if TYPE == FLOAT
00004 #define DETREND sdetrend
00005 #define DETREND_DISCONTIG sdetrend_discontig
00006 #define LEGENDRE_POLY slegendre_poly
00007 #define ORTHO_POLY sortho_poly
00008 #elif TYPE == DOUBLE
00009 #define DETREND ddetrend
00010 #define DETREND_DISCONTIG ddetrend_discontig
00011 #define LEGENDRE_POLY dlegendre_poly
00012 #define ORTHO_POLY dortho_poly
00013 #endif
00014
00015
00016
00017
00018 static void LEGENDRE_POLY(int degree, int length, RTYPE **poly);
00019 static void ORTHO_POLY(int degree, int length, RTYPE **poly, int *isgood);
00020
00021
00022 void DETREND_DISCONTIG( int n, RTYPE *data, int *isgood, int degree,
00023 int length, int skip, int m, int *sect)
00024 {
00025 #ifndef NDEBUG
00026 int verbose=1;
00027 #else
00028 int verbose=0;
00029 #endif
00030 int i,first,last;
00031
00032
00033
00034
00035
00036
00037 if (m==0)
00038 DETREND(n,data,isgood,degree,length,skip);
00039 else
00040 {
00041 for (i=0; i<m; i++)
00042 {
00043 first = sect[2*i];
00044 last = sect[2*i+1];
00045
00046 printf("Detrending [%d:%d]\n",first,last);
00047 DETREND(last-first+1,&data[first],&isgood[first],degree,length,skip);
00048 }
00049 }
00050 }
00051
00052
00053
00054 void DETREND( int n, RTYPE *data, int *isgood, int degree,
00055 int length, int skip)
00056 {
00057 #ifndef NDEBUG
00058 int verbose=1;
00059 #else
00060 int verbose=0;
00061 #endif
00062 int first,i,d, overlap, start,end;
00063 RTYPE **legendre_poly, **gap_poly, *fit, gamma, *apodizer;
00064 #ifdef DEBUG
00065 char name[20];
00066 static int count=0;
00067 FILE *fh;
00068 #endif
00069
00070 if (verbose)
00071 printf("%s: n=%d, length=%d, skip=%d, degree=%d\n",
00072 __func__,n,length,skip,degree);
00073
00074 fit = (RTYPE *)calloc(n,sizeof(RTYPE));
00075
00076 legendre_poly = (RTYPE **)malloc((degree+1)*sizeof(RTYPE *));
00077 gap_poly = (RTYPE **)malloc((degree+1)*sizeof(RTYPE *));
00078 for (i=0; i<=degree; i++)
00079 {
00080 legendre_poly[i] = (RTYPE *)malloc(2*length*sizeof(RTYPE));
00081 gap_poly[i] = (RTYPE *)malloc(2*length*sizeof(RTYPE));
00082 }
00083 LEGENDRE_POLY(degree,length, legendre_poly);
00084
00085
00086 overlap = length-skip;
00087 apodizer = (RTYPE *)malloc(overlap*sizeof(RTYPE));
00088 for (i=0;i<overlap;i++)
00089 {
00090 apodizer[i] = cos(M_PI/2*((RTYPE) i+1)/(overlap+1));
00091 apodizer[i] *= apodizer[i];
00092 }
00093
00094 for (first=0; first<=n-length; first+=skip)
00095 {
00096
00097 if (first+2*length>n )
00098 {
00099 length = n-first;
00100 LEGENDRE_POLY(degree, length, legendre_poly);
00101 }
00102
00103 start = first;
00104 while (start<first+length && !isgood[start])
00105 start++;
00106 if (start==first+length)
00107 {
00108
00109 for (i=first; i<first+length; i++)
00110 fit[i] = 0;
00111 continue;
00112 }
00113
00114 end = first+length-1;
00115 while (end>start && !isgood[end])
00116 end--;
00117 end++;
00118
00119
00120 if ((end-start) < length/2)
00121 {
00122 if (verbose)
00123 printf("special treatment of [%d:%d], length = %d\n",start,end,length);
00124 LEGENDRE_POLY(degree, (end-start), legendre_poly);
00125
00126
00127 for (i=0; i<=degree; i++)
00128 memcpy(gap_poly[i],legendre_poly[i],(end-start)*sizeof(RTYPE));
00129 ORTHO_POLY(degree,(end-start), gap_poly, &isgood[start]);
00130 for (i=start; i<end; i++)
00131 fit[i] = 0;
00132 for (d=0;d<=degree;d++)
00133 {
00134 gamma = 0;
00135 for (i=start; i<end; i++)
00136 if (isgood[i])
00137 gamma += gap_poly[d][i-start]*data[i];
00138 for (i=start; i<end; i++)
00139 fit[i] += gamma*gap_poly[d][i-start];
00140 }
00141 LEGENDRE_POLY(degree, length, legendre_poly);
00142 }
00143 else
00144 {
00145 if (verbose)
00146 printf("normal treatment [%d:%d]\n",first,first+length-1);
00147
00148
00149 for (i=0; i<=degree; i++)
00150 memcpy(gap_poly[i],legendre_poly[i],length*sizeof(RTYPE));
00151 ORTHO_POLY(degree,length, gap_poly, &isgood[first]);
00152
00153
00154 if (first!=0)
00155 {
00156 for (i=first; i<first+overlap; i++)
00157 {
00158 RTYPE alpha = apodizer[i-first];
00159 fit[i] = alpha*fit[i];
00160 }
00161 }
00162 for (d=0;d<=degree;d++)
00163 {
00164 gamma = 0;
00165 for (i=first; i<first+length; i++)
00166 if (isgood[i])
00167 gamma += gap_poly[d][i-first]*data[i];
00168 if (first!=0)
00169 for (i=first; i<first+overlap; i++)
00170 {
00171 RTYPE alpha = apodizer[i-first];
00172 fit[i] += (1-alpha)*gamma*gap_poly[d][i-first];
00173 }
00174 else
00175 i=first;
00176 for (; i<first+length; i++)
00177 fit[i] += gamma*gap_poly[d][i-first];
00178 }
00179 }
00180 }
00181
00182 for (i=0; i<n; i++)
00183 if (!isgood[i])
00184 fit[i] = 0;
00185
00186 for (i=0; i<n; i++)
00187 if (isgood[i])
00188 data[i] -= fit[i];
00189 else
00190 data[i] = 0;
00191
00192 #ifdef DEBUG
00193 printf("writing debug file #%d\n",count);
00194 sprintf(name,"detrend_debug_%d.out",count++);
00195 fh = fopen(name,"w");
00196 assert(fh);
00197 for (i=0; i<n; i++)
00198 fprintf(fh,"%e %e\n",fit[i],data[i]);
00199 fclose(fh);
00200 #endif
00201
00202 for (i=0; i<=degree; i++)
00203 {
00204 free(legendre_poly[i]);
00205 free(gap_poly[i]);
00206 }
00207 free(legendre_poly);
00208 free(gap_poly);
00209 free(fit);
00210 free(apodizer);
00211 }
00212
00213
00214 static void LEGENDRE_POLY(int degree, int length, RTYPE **poly)
00215 {
00216 int d,i;
00217
00218
00219 for (i=0;i<(length+1)/2; i++)
00220 {
00221 poly[0][i] = 1.0;
00222 poly[1][i] = -1.0+(2.0*(i+1))/(length+1);
00223 }
00224 for (d=1; d<degree; d++)
00225 for (i=0; i<(length+1)/2; i++)
00226 poly[d+1][i] = ((2*d+1)*poly[1][i]*poly[d][i]-d*poly[d-1][i])/(d+1);
00227
00228
00229 for (d=1; d<=degree; d+=2)
00230 for (i=0; i<length/2; i++)
00231 poly[d][length-i-1] = -poly[d][i];
00232 for (d=0; d<=degree; d+=2)
00233 for (i=0; i<length/2; i++)
00234 poly[d][length-i-1] = poly[d][i];
00235 }
00236
00237
00238 static void ORTHO_POLY(int degree, int length, RTYPE **poly, int *isgood)
00239 {
00240 int d,i,j;
00241 RTYPE norm;
00242
00243
00244 for (d=0; d<=degree; d++)
00245 {
00246 norm = 0.0;
00247 for (i=0; i<length; i++)
00248 if (isgood[i])
00249 norm += poly[d][i]*poly[d][i];
00250 norm = sqrt(norm);
00251 for (i=0; i<length; i++)
00252 poly[d][i] /= norm;
00253 }
00254
00255
00256 for (d=0; d<=degree; d++)
00257 for (j=d-1; j>=0; j--)
00258 {
00259 norm = 0;
00260 for (i=0; i<length; i++)
00261 if (isgood[i])
00262 norm += poly[j][i]*poly[d][i];
00263 for (i=0; i<length; i++)
00264 poly[d][i] -= norm*poly[j][i];
00265 }
00266
00267
00268 for (d=0; d<=degree; d++)
00269 {
00270 norm = 0.0;
00271 for (i=0; i<length; i++)
00272 if (isgood[i])
00273 norm += poly[d][i]*poly[d][i];
00274 norm = sqrt(norm);
00275 for (i=0; i<length; i++)
00276 poly[d][i] /= norm;
00277 }
00278
00279 }
00280
00281
00282 #undef DETREND
00283 #undef DETREND_DISCONTIG
00284 #undef LEGENDRE_POLY
00285 #undef ORTHO_POLY
00286 #include "ctypes_undef.h"