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