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 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <math.h>
00037 #include <cpl.h>
00038
00039 #include "irplib_flat.h"
00040
00041
00042
00043
00044
00045 static double * irplib_flat_fit_proportional(double *, double *, int) ;
00046
00047
00051
00052
00055
00086
00087 cpl_imagelist * irplib_flat_fit_set(
00088 cpl_imagelist * raw,
00089 int mode)
00090 {
00091 double * plane_med = NULL ;
00092 double * slope = NULL ;
00093 cpl_image * gain = NULL ;
00094 double * pgain = NULL ;
00095 cpl_image * intercept = NULL ;
00096 double * pintercept = NULL ;
00097 cpl_image * sq_err = NULL ;
00098 double * psq_err = NULL ;
00099 double * timeline = NULL ;
00100 float * raw_im_data = NULL ;
00101 cpl_imagelist * result = NULL ;
00102 const int nx = cpl_image_get_size_x(cpl_imagelist_get(raw, 0));
00103 const int ny = cpl_image_get_size_y(cpl_imagelist_get(raw, 0));
00104 const int ni = cpl_imagelist_get_size(raw);
00105 int i, j ;
00106
00107
00108 if (raw==NULL) return NULL ;
00109 if ((mode != 0) && (mode != 1)) return NULL ;
00110 if (cpl_image_get_type(cpl_imagelist_get(raw, 0)) != CPL_TYPE_FLOAT)
00111 return NULL ;
00112 if (cpl_imagelist_get_size(raw) <= 1) return NULL ;
00113
00114
00115 plane_med = cpl_malloc(ni * sizeof(double)) ;
00116 for (i=0 ; i<ni ; i++)
00117 plane_med[i] = cpl_image_get_median(cpl_imagelist_get(raw, i));
00118
00119
00120 gain = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE) ;
00121 pgain = cpl_image_get_data_double(gain) ;
00122 if (mode == 1) {
00123 intercept = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE) ;
00124 pintercept = cpl_image_get_data_double(intercept) ;
00125 }
00126 sq_err = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE) ;
00127 psq_err = cpl_image_get_data_double(sq_err) ;
00128 timeline = cpl_malloc(ni * sizeof(double)) ;
00129
00130
00131 cpl_msg_info(cpl_func, "Computing gains for all positions (long)...") ;
00132 for (i=0 ; i<nx * ny ; i++) {
00133
00134 for (j=0 ; j<ni ; j++) {
00135 raw_im_data = cpl_image_get_data_float(cpl_imagelist_get(raw, j)) ;
00136 timeline[j] = (double)raw_im_data[i] ;
00137 }
00138
00139 if (mode == 1) {
00140 slope = irplib_flat_fit_slope_robust(plane_med, timeline, ni) ;
00141 pintercept[i] = slope[0] ;
00142 pgain[i] = slope[1] ;
00143 psq_err[i] = slope[2] ;
00144
00145 } else {
00146 slope = irplib_flat_fit_proportional(plane_med, timeline, ni) ;
00147
00148 pgain[i] = slope[0] ;
00149 psq_err[i] = slope[1] ;
00150 }
00151 cpl_free(slope);
00152 }
00153 cpl_free(plane_med) ;
00154 cpl_free(timeline) ;
00155
00156
00157 result = cpl_imagelist_new() ;
00158 if (mode == 1) {
00159 cpl_imagelist_set(result, gain, 0) ;
00160 cpl_imagelist_set(result, intercept, 1) ;
00161 cpl_imagelist_set(result, sq_err, 2) ;
00162 } else {
00163 cpl_imagelist_set(result, gain, 0) ;
00164 cpl_imagelist_set(result, sq_err, 1) ;
00165 }
00166 return result ;
00167 }
00168
00169
00170 #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
00171 #define MAX_ITERATE 30
00172
00173
00190
00191 double * irplib_flat_fit_slope_robust(
00192 double * x,
00193 double * y,
00194 int np)
00195 {
00196 double * c ;
00197 double aa, bb, bcomp, b1, b2, del, abdevt, f, f1, f2, sigb, temp,
00198 d, sum ;
00199 double sx, sy, sxy, sxx, chisq ;
00200 cpl_vector * arr ;
00201 double * parr ;
00202 double aa_ls, bb_ls ;
00203 int iter ;
00204 int i ;
00205
00206
00207 if (x==NULL || y==NULL) return NULL ;
00208
00209 c = cpl_malloc(3 * sizeof(double)) ;
00210
00211 sx = sy = sxx = sxy = 0.00 ;
00212 for (i=0 ; i<np ; i++) {
00213 sx += x[i];
00214 sy += y[i];
00215 sxy += x[i] * y[i];
00216 sxx += x[i] * x[i];
00217 }
00218
00219 del = np * sxx - sx * sx;
00220 aa_ls = aa = (sxx * sy - sx * sxy) / del;
00221 bb_ls = bb = (np * sxy - sx * sy) / del;
00222
00223 chisq = 0.00 ;
00224 for (i=0;i<np;i++) {
00225 temp = y[i] - (aa+bb*x[i]) ;
00226 temp *= temp ;
00227 chisq += temp ;
00228 }
00229
00230 arr = cpl_vector_new(np) ;
00231 parr = cpl_vector_get_data(arr) ;
00232 sigb = sqrt(chisq/del);
00233 b1 = bb ;
00234
00235 bcomp = b1 ;
00236 sum = 0.00 ;
00237 for (i=0 ; i<np ; i++) {
00238 parr[i] = y[i] - bcomp * x[i];
00239 }
00240 aa = cpl_vector_get_median(arr);
00241 abdevt = 0.0;
00242 for (i=0 ; i<np ; i++) {
00243 d = y[i] - (bcomp * x[i] + aa);
00244 abdevt += fabs(d);
00245 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
00246 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
00247 }
00248 f1 = sum ;
00249 b2 = bb + SIGN(3.0 * sigb, f1);
00250 bcomp = b2 ;
00251 sum = 0.00 ;
00252 for (i=0 ; i<np ; i++) parr[i] = y[i] - bcomp * x[i];
00253 aa = cpl_vector_get_median(arr);
00254 abdevt = 0.0;
00255 for (i=0 ; i<np ; i++) {
00256 d = y[i] - (bcomp * x[i] + aa);
00257 abdevt += fabs(d);
00258 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
00259 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
00260 }
00261 f2 = sum ;
00262
00263 if (fabs(b2-b1)<1e-7) {
00264 c[0] = aa ;
00265 c[1] = bb ;
00266 c[2] = abdevt / (double)np;
00267 cpl_vector_delete(arr);
00268 return c ;
00269 }
00270
00271 iter = 0 ;
00272 while (f1*f2 > 0.0) {
00273 bb = 2.0*b2-b1;
00274 b1 = b2;
00275 f1 = f2;
00276 b2 = bb;
00277
00278 bcomp = b2 ;
00279 sum = 0.00 ;
00280 for (i=0 ; i<np ; i++) parr[i] = y[i] - bcomp * x[i];
00281 aa = cpl_vector_get_median(arr);
00282 abdevt = 0.0;
00283 for (i=0 ; i<np ; i++) {
00284 d = y[i] - (bcomp * x[i] + aa);
00285 abdevt += fabs(d);
00286 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
00287 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
00288 }
00289 f2 = sum ;
00290 iter++;
00291 if (iter>=MAX_ITERATE) break ;
00292 }
00293 if (iter>=MAX_ITERATE) {
00294 c[0] = aa_ls ;
00295 c[1] = bb_ls ;
00296 c[2] = -1.0 ;
00297 cpl_vector_delete(arr);
00298 return c ;
00299 }
00300
00301 sigb = 0.01 * sigb;
00302 while (fabs(b2-b1) > sigb) {
00303 bb = 0.5 * (b1 + b2) ;
00304 if ((fabs(bb-b1)<1e-7) || (fabs(bb-b2)<1e-7)) break;
00305 bcomp = bb ;
00306 sum = 0.00 ;
00307 for (i=0 ; i<np ; i++) parr[i] = y[i] - bcomp * x[i];
00308 aa = cpl_vector_get_median(arr);
00309 abdevt = 0.0;
00310 for (i=0 ; i<np ; i++) {
00311 d = y[i] - (bcomp * x[i] + aa);
00312 abdevt += fabs(d);
00313 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
00314 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
00315 }
00316 f = sum ;
00317
00318 if (f*f1 >= 0.0) {
00319 f1=f;
00320 b1=bb;
00321 } else {
00322 f2=f;
00323 b2=bb;
00324 }
00325 }
00326 cpl_vector_delete(arr) ;
00327 c[0]=aa;
00328 c[1]=bb;
00329 c[2]=abdevt/np;
00330 return c ;
00331 }
00332 #undef MAX_ITERATE
00333 #undef SIGN
00334
00335
00338
00362
00363 #define FITPROP_BIG_SLOPE 1e30
00364 static double * irplib_flat_fit_proportional(
00365 double * x,
00366 double * y,
00367 int np)
00368 {
00369 cpl_vector * slopes ;
00370 double * pslopes ;
00371 double * med_slope ;
00372 double val ;
00373 double sq_err ;
00374 int i ;
00375
00376
00377 if (x==NULL || y==NULL) return NULL ;
00378
00379 slopes = cpl_vector_new(np) ;
00380 pslopes = cpl_vector_get_data(slopes) ;
00381 for (i=0 ; i<np ; i++) {
00382 if (fabs(x[i])>1e-30) pslopes[i] = y[i] / x[i] ;
00383 else pslopes[i] = FITPROP_BIG_SLOPE ;
00384 }
00385 med_slope = cpl_malloc(2 * sizeof(double));
00386 med_slope[0] = cpl_vector_get_median(slopes);
00387 cpl_vector_delete(slopes);
00388
00389 sq_err = 0.00 ;
00390 for (i=0 ; i<np ; i++) {
00391 val = med_slope[0] * x[i] ;
00392 sq_err += (val-y[i])*(val-y[i]) ;
00393 }
00394 sq_err /= (double)np ;
00395 med_slope[1] = sq_err ;
00396
00397 return med_slope ;
00398 #undef FITPROP_BIG_SLOPE
00399 }
00400
00401
00402