irplib_flat.c

00001 /* $Id: irplib_flat.c,v 1.15 2007/08/07 12:15:41 llundin Exp $
00002  *
00003  * This file is part of the irplib package
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2007/08/07 12:15:41 $
00024  * $Revision: 1.15 $
00025  * $Name: HEAD $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                    Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <math.h>
00037 #include <cpl.h>
00038 
00039 #include "irplib_flat.h"
00040 
00041 /*-----------------------------------------------------------------------------
00042                             Functions prototypes
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     /* Check entries */
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     /* Compute median for all planes */
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     /* Create result images */
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     /* Loop on all pixel positions */
00131     cpl_msg_info(cpl_func, "Computing gains for all positions (long)...") ;
00132     for (i=0 ; i<nx * ny ; i++) {
00133         /* extract time line */
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         /* Fit slope to this time line */
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             /* Set results in output images */
00145         } else {
00146             slope = irplib_flat_fit_proportional(plane_med, timeline, ni) ;
00147             /* Set results in output images */
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     /* Return */
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 /* @cond */
00170 #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
00171 #define MAX_ITERATE     30
00172 /* @endcond */
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     /* Check entries */
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); /* arr permuted */
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);  /* arr permuted */
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); /* arr permuted */
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); /* arr permuted */
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     /* Check entries */
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); /* slopes permuted */
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 

Generated on 1 Mar 2011 for DETMON Pipeline Reference Manual by  doxygen 1.6.1