39 #include "irplib_flat.h"
45 static double * irplib_flat_fit_proportional(
double *,
double *,
int) ;
91 double * plane_med = NULL ;
92 double * slope = NULL ;
93 cpl_image * gain = NULL ;
94 double * pgain = NULL ;
95 cpl_image * intercept = NULL ;
96 double * pintercept = NULL ;
97 cpl_image * sq_err = NULL ;
98 double * psq_err = NULL ;
99 double * timeline = NULL ;
100 float * raw_im_data = NULL ;
101 cpl_imagelist * result = NULL ;
102 const int nx = cpl_image_get_size_x(cpl_imagelist_get(raw, 0));
103 const int ny = cpl_image_get_size_y(cpl_imagelist_get(raw, 0));
104 const int ni = cpl_imagelist_get_size(raw);
108 if (raw==NULL)
return NULL ;
109 if ((mode != 0) && (mode != 1))
return NULL ;
110 if (cpl_image_get_type(cpl_imagelist_get(raw, 0)) != CPL_TYPE_FLOAT)
112 if (cpl_imagelist_get_size(raw) <= 1)
return NULL ;
115 plane_med = cpl_malloc(ni *
sizeof(
double)) ;
116 for (i=0 ; i<ni ; i++)
117 plane_med[i] = cpl_image_get_median(cpl_imagelist_get(raw, i));
120 gain = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE) ;
121 pgain = cpl_image_get_data_double(gain) ;
123 intercept = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE) ;
124 pintercept = cpl_image_get_data_double(intercept) ;
126 sq_err = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE) ;
127 psq_err = cpl_image_get_data_double(sq_err) ;
128 timeline = cpl_malloc(ni *
sizeof(
double)) ;
131 cpl_msg_info(cpl_func,
"Computing gains for all positions (long)...") ;
132 for (i=0 ; i<nx * ny ; i++) {
134 for (j=0 ; j<ni ; j++) {
135 raw_im_data = cpl_image_get_data_float(cpl_imagelist_get(raw, j)) ;
136 timeline[j] = (double)raw_im_data[i] ;
141 pintercept[i] = slope[0] ;
142 pgain[i] = slope[1] ;
143 psq_err[i] = slope[2] ;
146 slope = irplib_flat_fit_proportional(plane_med, timeline, ni) ;
148 pgain[i] = slope[0] ;
149 psq_err[i] = slope[1] ;
153 cpl_free(plane_med) ;
157 result = cpl_imagelist_new() ;
159 cpl_imagelist_set(result, gain, 0) ;
160 cpl_imagelist_set(result, intercept, 1) ;
161 cpl_imagelist_set(result, sq_err, 2) ;
163 cpl_imagelist_set(result, gain, 0) ;
164 cpl_imagelist_set(result, sq_err, 1) ;
170 #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
171 #define MAX_ITERATE 30
197 double aa, bb, bcomp, b1, b2, del, abdevt, f, f1, f2, sigb, temp,
199 double sx, sy, sxy, sxx, chisq ;
202 double aa_ls, bb_ls ;
207 if (x==NULL || y==NULL)
return NULL ;
209 c = cpl_malloc(3 *
sizeof(
double)) ;
211 sx = sy = sxx = sxy = 0.00 ;
212 for (i=0 ; i<np ; i++) {
219 del = np * sxx - sx * sx;
220 aa_ls = aa = (sxx * sy - sx * sxy) / del;
221 bb_ls = bb = (np * sxy - sx * sy) / del;
225 temp = y[i] - (aa+bb*x[i]) ;
230 arr = cpl_vector_new(np) ;
231 parr = cpl_vector_get_data(arr) ;
232 sigb = sqrt(chisq/del);
237 for (i=0 ; i<np ; i++) {
238 parr[i] = y[i] - bcomp * x[i];
240 aa = cpl_vector_get_median(arr);
242 for (i=0 ; i<np ; i++) {
243 d = y[i] - (bcomp * x[i] + aa);
245 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
246 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
249 b2 = bb + SIGN(3.0 * sigb, f1);
252 for (i=0 ; i<np ; i++) parr[i] = y[i] - bcomp * x[i];
253 aa = cpl_vector_get_median(arr);
255 for (i=0 ; i<np ; i++) {
256 d = y[i] - (bcomp * x[i] + aa);
258 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
259 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
263 if (fabs(b2-b1)<1e-7) {
266 c[2] = abdevt / (double)np;
267 cpl_vector_delete(arr);
272 while (f1*f2 > 0.0) {
280 for (i=0 ; i<np ; i++) parr[i] = y[i] - bcomp * x[i];
281 aa = cpl_vector_get_median(arr);
283 for (i=0 ; i<np ; i++) {
284 d = y[i] - (bcomp * x[i] + aa);
286 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
287 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
291 if (iter>=MAX_ITERATE) break ;
293 if (iter>=MAX_ITERATE) {
297 cpl_vector_delete(arr);
302 while (fabs(b2-b1) > sigb) {
303 bb = 0.5 * (b1 + b2) ;
304 if ((fabs(bb-b1)<1e-7) || (fabs(bb-b2)<1e-7))
break;
307 for (i=0 ; i<np ; i++) parr[i] = y[i] - bcomp * x[i];
308 aa = cpl_vector_get_median(arr);
310 for (i=0 ; i<np ; i++) {
311 d = y[i] - (bcomp * x[i] + aa);
313 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
314 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
326 cpl_vector_delete(arr) ;
363 #define FITPROP_BIG_SLOPE 1e30
364 static double * irplib_flat_fit_proportional(
369 cpl_vector * slopes ;
377 if (x==NULL || y==NULL)
return NULL ;
379 slopes = cpl_vector_new(np) ;
380 pslopes = cpl_vector_get_data(slopes) ;
381 for (i=0 ; i<np ; i++) {
382 if (fabs(x[i])>1e-30) pslopes[i] = y[i] / x[i] ;
383 else pslopes[i] = FITPROP_BIG_SLOPE ;
385 med_slope = cpl_malloc(2 *
sizeof(
double));
386 med_slope[0] = cpl_vector_get_median(slopes);
387 cpl_vector_delete(slopes);
390 for (i=0 ; i<np ; i++) {
391 val = med_slope[0] * x[i] ;
392 sq_err += (val-y[i])*(val-y[i]) ;
394 sq_err /= (double)np ;
395 med_slope[1] = sq_err ;
398 #undef FITPROP_BIG_SLOPE
cpl_imagelist * irplib_flat_fit_set(cpl_imagelist *raw, int mode)
Compute a flat-field out of a set of exposures.
double * irplib_flat_fit_slope_robust(double *x, double *y, int np)
Fit a slope to a list of points (robust fit).