36#include "irplib_flat.h"
43static double * irplib_flat_fit_proportional(
double *,
double *,
int) ;
89 double * plane_med = NULL ;
90 double * slope = NULL ;
91 cpl_image * gain = NULL ;
92 double * pgain = NULL ;
93 cpl_image * intercept = NULL ;
94 double * pintercept = NULL ;
95 cpl_image * sq_err = NULL ;
96 double * psq_err = NULL ;
97 double * timeline = NULL ;
98 float * raw_im_data = NULL ;
99 cpl_imagelist * result = NULL ;
100 const int nx = cpl_image_get_size_x(cpl_imagelist_get(raw, 0));
101 const int ny = cpl_image_get_size_y(cpl_imagelist_get(raw, 0));
102 const int ni = cpl_imagelist_get_size(raw);
106 if (raw==NULL)
return NULL ;
107 if ((mode != 0) && (mode != 1))
return NULL ;
108 if (cpl_image_get_type(cpl_imagelist_get(raw, 0)) != CPL_TYPE_FLOAT)
110 if (cpl_imagelist_get_size(raw) <= 1)
return NULL ;
113 plane_med = cpl_malloc(ni *
sizeof(
double)) ;
114 for (i=0 ; i<ni ; i++)
115 plane_med[i] = cpl_image_get_median(cpl_imagelist_get(raw, i));
118 gain = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE) ;
119 pgain = cpl_image_get_data_double(gain) ;
121 intercept = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE) ;
122 pintercept = cpl_image_get_data_double(intercept) ;
124 sq_err = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE) ;
125 psq_err = cpl_image_get_data_double(sq_err) ;
126 timeline = cpl_malloc(ni *
sizeof(
double)) ;
129 cpl_msg_info(cpl_func,
"Computing gains for all positions (long)...") ;
130 for (i=0 ; i<nx * ny ; i++) {
132 for (j=0 ; j<ni ; j++) {
133 raw_im_data = cpl_image_get_data_float(cpl_imagelist_get(raw, j)) ;
134 timeline[j] = (double)raw_im_data[i] ;
139 pintercept[i] = slope[0] ;
140 pgain[i] = slope[1] ;
141 psq_err[i] = slope[2] ;
144 slope = irplib_flat_fit_proportional(plane_med, timeline, ni) ;
146 pgain[i] = slope[0] ;
147 psq_err[i] = slope[1] ;
151 cpl_free(plane_med) ;
155 result = cpl_imagelist_new() ;
157 cpl_imagelist_set(result, gain, 0) ;
158 cpl_imagelist_set(result, intercept, 1) ;
159 cpl_imagelist_set(result, sq_err, 2) ;
161 cpl_imagelist_set(result, gain, 0) ;
162 cpl_imagelist_set(result, sq_err, 1) ;
168#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
169#define MAX_ITERATE 30
195 double aa, bb, bcomp, b1, b2, del, abdevt, f1, f2, sigb,
197 double sx, sy, sxy, sxx, chisq ;
200 double aa_ls, bb_ls ;
205 if (x==NULL || y==NULL)
return NULL ;
207 c = cpl_malloc(3 *
sizeof(
double)) ;
209 sx = sy = sxx = sxy = 0.00 ;
210 for (i=0 ; i<np ; i++) {
217 del = np * sxx - sx * sx;
218 aa_ls = aa = (sxx * sy - sx * sxy) / del;
219 bb_ls = bb = (np * sxy - sx * sy) / del;
223 double temp = y[i] - (aa+bb*x[i]) ;
228 arr = cpl_vector_new(np) ;
229 parr = cpl_vector_get_data(arr) ;
230 sigb = sqrt(chisq/del);
235 for (i=0 ; i<np ; i++) {
236 parr[i] = y[i] - bcomp * x[i];
238 aa = cpl_vector_get_median(arr);
240 for (i=0 ; i<np ; i++) {
241 d = y[i] - (bcomp * x[i] + aa);
243 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
244 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
247 b2 = bb + SIGN(3.0 * sigb, f1);
250 for (i=0 ; i<np ; i++) parr[i] = y[i] - bcomp * x[i];
251 aa = cpl_vector_get_median(arr);
253 for (i=0 ; i<np ; i++) {
254 d = y[i] - (bcomp * x[i] + aa);
256 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
257 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
261 if (fabs(b2-b1)<1e-7) {
264 c[2] = abdevt / (double)np;
265 cpl_vector_delete(arr);
270 while (f1*f2 > 0.0) {
278 for (i=0 ; i<np ; i++) parr[i] = y[i] - bcomp * x[i];
279 aa = cpl_vector_get_median(arr);
281 for (i=0 ; i<np ; i++) {
282 d = y[i] - (bcomp * x[i] + aa);
284 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
285 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
289 if (iter>=MAX_ITERATE) break ;
291 if (iter>=MAX_ITERATE) {
295 cpl_vector_delete(arr);
300 while (fabs(b2-b1) > sigb) {
302 bb = 0.5 * (b1 + b2) ;
303 if ((fabs(bb-b1)<1e-7) || (fabs(bb-b2)<1e-7))
break;
306 for (i=0 ; i<np ; i++) parr[i] = y[i] - bcomp * x[i];
307 aa = cpl_vector_get_median(arr);
309 for (i=0 ; i<np ; i++) {
310 d = y[i] - (bcomp * x[i] + aa);
312 if (fabs(y[i]) > 1e-7) d /= fabs(y[i]);
313 if (fabs(d) > 1e-7) sum += (d >= 0.0 ? x[i] : -x[i]);
325 cpl_vector_delete(arr) ;
362#define FITPROP_BIG_SLOPE 1e30
363static double * irplib_flat_fit_proportional(
368 cpl_vector * slopes ;
375 if (x==NULL || y==NULL)
return NULL ;
377 slopes = cpl_vector_new(np) ;
378 pslopes = cpl_vector_get_data(slopes) ;
379 for (i=0 ; i<np ; i++) {
380 if (fabs(x[i])>1e-30) pslopes[i] = y[i] / x[i] ;
381 else pslopes[i] = FITPROP_BIG_SLOPE ;
383 med_slope = cpl_malloc(2 *
sizeof(
double));
384 med_slope[0] = cpl_vector_get_median(slopes);
385 cpl_vector_delete(slopes);
388 for (i=0 ; i<np ; i++) {
389 double val = med_slope[0] * x[i] ;
390 sq_err += (val-y[i])*(val-y[i]) ;
392 sq_err /= (double)np ;
393 med_slope[1] = sq_err ;
396#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).