sinfo_image_ops.c

00001 /*
00002  * This file is part of the ESO SINFONI Pipeline
00003  * Copyright (C) 2004,2005 European Southern Observatory
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00018  */
00019 /*************************************************************************
00020 * M.P.E. - SPIFFI project
00021 *
00022 *
00023 *
00024 * who       when      what
00025 * --------  --------  ----------------------------------------------
00026 * rabuter 2004-12-03 support one dimensional image in sinfo_shiftImage
00027 * schreib  23/05/00  created
00028 */
00029 
00030 /************************************************************************
00031 *   NAME
00032 *        sinfo_image_ops.c -
00033 *        image arithmetic routines
00034 *
00035 *   SYNOPSIS
00036 *   #include "sinfo_image_ops.h"
00037 *
00038 *   1) Vector * sinfo_new_mean_of_columns( cpl_image *im )
00039 *   2) Vector * sinfo_new_clean_mean_of_columns( cpl_image *im,
00040 *                                   double lo_reject,
00041 *                                   double hi_reject)
00042 *   3) cpl_image * sinfo_new_div_image_by_row( cpl_image *im, Vector *row )
00043 *   4) cpl_image * sinfo_new_mult_row_to_image( cpl_image *im, Vector *row )
00044 *   5) cpl_image * sinfo_new_col_tilt ( cpl_image * image, float sigmaFactor )
00045 *   6) cpl_image * sinfo_new_median_image( cpl_image * im, float fmedian )
00046 *   7) cpl_image * sinfo_new_compare_images( cpl_image * im1,
00047                                              cpl_image * im2,
00048                                              cpl_image * origim )
00049 *   8) cpl_image * sinfo_new_thresh_image ( cpl_image * im,
00050                                             float lo_cut, float hi_cut )
00051 *   9) pixel_map * sinfo_new_promote_image_to_pixelmap ( cpl_image * im )
00052 *  10) cpl_image * sinfo_new_promote_image_to_mask ( cpl_image * im,
00053                                                      int * n_badpixels )
00054 *  11) cpl_image * sinfo_new_mult_image_by_mask ( cpl_image * im,
00055                                                   cpl_image * mask )
00056 *  12) cpl_image * sinfo_new_interpol_image ( cpl_image * im,
00057 *                                 cpl_image * mask,
00058 *                                 int        max_radius,
00059 *                                 int        n_pixels )
00060 *  13) cpl_image * sinfo_interpol_source_image ( cpl_image * im,
00061 *                                       cpl_image * mask,
00062 *                                       int        max_rad,
00063 *                                       float   ** slit_edges )
00064 *  14) cpl_image * sinfo_new_stack_row_to_image ( Vector * row, int ly )
00065 *  15) Stats * sinfo_new_image_stats_on_rectangle ( cpl_image * im,
00066 *                                      float      loReject,
00067 *                                      float      hiReject,
00068 *                                      int        llx,
00069 *                                      int        lly,
00070 *                                      int        urx,
00071 *                                      int        ury )
00072 *  16) cpl_image * sinfo_new_normalize_to_central_pixel ( cpl_image * image )
00073 *  17) cpl_image *
00074 *      sinfo_new_shift_image(
00075 *            cpl_image    *    image_in,
00076 *            double           shift_x,
00077 *            double           shift_y,
00078 *            double       *   interp_kernel)
00079 *  18) cpl_image * sinfo_new_combine_masks ( cpl_image * firstMask,
00080                                              cpl_image * secondMask )
00081 *  19) cpl_image * sinfo_new_slice_cube (cpl_imagelist * cube, int x, int y )
00082 *  20) cpl_image * sinfo_new_div_images_robust ( cpl_image * im1,
00083                                                  cpl_image * im2 )
00084 *
00085 *
00086 *   DESCRIPTION
00087 *   1) takes the average of each image column
00088 *   2) takes the average of each image column by sorting the
00089 *      column values and rejecting the given percentage of
00090 *      the highest and lowest values  [0...1]
00091 *   3) divides each image column by a row value
00092 *   4) multiplies each image column with a row value
00093 *   5) first calculates statistics for each column of an image.
00094 *      sinfo_median value and standard deviation of columns are de-
00095 *      termined, blank values are excluded. Fits a straight
00096 *      line through the pixel values of each column and subtracts
00097 *      the fit in order to remove the tilt of each column.
00098 *      Only those pixels are used for the fit that are within
00099 *      a defined factor of sigma noise limit. The noise is
00100 *      calculated from pixels between the 10percentil and
00101 *      90percentil points.
00102 *      if the straight line could not be determined, the sinfo_median
00103 *      of the column is subtracted from the column
00104 *   6) sinfo_median filter, calculates the sinfo_median for an image
00105 *      by using the 8 closest pixels to each pixel.
00106 *      The values in the output image are determined according
00107 *      to the values of the input parameter.
00108 *      If fmedian = 0: always replace by sinfo_median
00109 *      if fmedian < 0: replace by sinfo_median if |pixel - sinfo_median| >
00110 *                      -fmedian
00111 *      if fmedian > 0: replace by sinfo_median (fmedian as a factor of
00112 *                      the square root of the sinfo_median itself)
00113 *                      if |pixel - median| >= fmedian * sqrt ( median )
00114 *                      This can be used to consider photon noise.
00115 *                      This considers a dependence of the differences on the
00116 *                      pixel values themselves.
00117 *   7) if a pixel value of one image (im1) equals
00118 *      the pixel value of the other image keep the
00119 *      pixel value of the original image otherwise replace
00120 *      it with ZEROs
00121 *   8) simple search for static bad pixels for a flat field
00122 *      or sinfo_dark frame, values below and above the threshold
00123 *      values are set to ZERO.
00124 *   9) changes an image with ZERO indicated bad pixels to
00125 *      a bad pixel map.
00126 *  10) changes an image with ZERO indicated bad pixels to
00127 *      a bad pixel mask image, that means the returned
00128 *      image has values 1 at positions of good pixels and
00129 *      ZEROs at positions of bad pixels.
00130 *  11) changes an image to an image that has ZERO indicated
00131 *      static bad pixels
00132 *  12) interpolates all bad pixels indicated by the bad pixel mask.
00133 *      Therefore, the mean of at least 2 valid values of
00134 *      the nearest 8 neighbors is taken. If too much
00135 *      neighbors are also bad pixels
00136 *      the neighbor radius is increased to a maximum of
00137 *      max_radius until n_pixels valid pixels are found.
00138 *      The valid neighbors are searched by going through
00139 *      the columns and rows around the central square that
00140 *      was already searched.
00141 *      The bad pixel is interpolated by the mean of these
00142 *      valid pixels (less than 9) or by the sinfo_median of them
00143 *      (more than 8).
00144 *  13) interpolates all bad pixels indicated by the bad pixel mask.
00145 *      Therefore, the mean of the nearest 4 neighbors is taken,
00146 *      two in spectral direction and 2 in spatial direction.
00147 *      The routine cares about the image and slitlet edges.
00148 *      If there are no good pixel found within the nearest neighbors,
00149 *      the next 4 nearest neighbors in spatial and spectral direction
00150 *      are searched for valid pixels until a limit of max_rad.
00151 *      A maximum of 4 valid pixels are used for interpolation by their mean.
00152 *  14) stack a given image row to build a whole image
00153 *  15) computes the mean and standard deviation of
00154 *      a given rectangle on an image by leaving the extreme
00155 *      intensity values.
00156 *  16) normalizes a raw flatfield image by dividing by the median of the
00157        central spectral pixels to produce a master flatfield
00158 *  17) This function is a conversion to CPL of the ECLIPSE function
00159        shift_image()
00160 *      but slightly changed. If a blank (ZERO) pixel appears the blank pixel
00161 *      is shifted but preserved as blank.
00162 *      If a blank (ZERO) pixel appears within the
00163 *      interpolation kernel the blank pixel is set to 0.
00164 *
00165 *      This function shifts an image by a non-integer offset, using
00166 *      interpolation. You can either generate an interpolation kernel once and
00167 *      pass it to this function, or let it generate a default kernel. In the
00168 *      former case, use sinfo_generate_interpolation_kernel() to generate an
00169 *      appropriate kernel. In the latter case, pass NULL as last argument. A
00170 *      default interpolation kernel is then generated then discarded
00171        before this function returns.
00172 *
00173 *      The returned image is a newly allocated object, it must be deallocated
00174 *      using cpl_image_delete().
00175 *  18) combines two bad pixel mask to one using an or relation
00176 *  19) slices a data cube in x or y direction
00177 *  20) divides two images by considering blanks and
00178 *      calculating first 1/im2 by
00179 *      cutting the very high values and setting to 1,
00180 *      then multiplying im1 * 1/im2.
00181 *
00182 *   FILES
00183 *
00184 *   ENVIRONMENT
00185 *
00186 *   RETURN VALUES
00187 *
00188 *   CAUTIONS
00189 *
00190 *   EXAMPLES
00191 *
00192 *   SEE ALSO
00193 *
00194 *   BUGS
00195 *
00196 *------------------------------------------------------------------------
00197 */
00198 
00199 #ifdef HAVE_CONFIG_H
00200 #  include <config.h>
00201 #endif
00202 #include "sinfo_vltPort.h"
00203 
00204 /*
00205  * System Headers
00206  */
00207 #include <errno.h>
00208 /*
00209  * Local Headers
00210  */
00211 
00212 #include "sinfo_image_ops.h"
00213 #include "sinfo_error.h"
00214 #include "sinfo_resampling.h"
00215 #include "sinfo_local_types.h"
00216 #include "sinfo_utils_wrappers.h"
00225 static cpl_image *
00226 sinfo_gen_lowpass(const int xs,
00227                   const int ys,
00228                   const double sigma_x,
00229                   const double sigma_y);
00230 
00231 
00232 static void quicksort_int(int* data, int left, int right);
00235 /*----------------------------------------------------------------------------
00236  *                            Function codes
00237  *--------------------------------------------------------------------------*/
00238 
00239 
00240 
00252 cpl_error_code
00253 sinfo_image_line_corr(const int width,
00254                 const int filt_rad,
00255                 const int kappa,
00256                 cpl_image* ima_in,
00257                 cpl_image** ima_out)
00258 {
00259 
00260   cpl_image* mask=NULL;
00261 
00262   cpl_image* ima_backpix=NULL;
00263   cpl_image* ima_backpos=NULL;
00264   cpl_image* ima_ybackpix=NULL;
00265   cpl_image* ima_diffbackpix=NULL;
00266   cpl_image* ima_filt=NULL;
00267   cpl_image* ima = NULL;
00268 
00269   cpl_matrix* filter=NULL;
00270   //cpl_mask* bpm_good=NULL; //Is this really useful?
00271   cpl_mask* bpm_bad=NULL;
00272 
00273   int sx=0;
00274   int sy=0;
00275   int i=0;
00276   int j=0;
00277   int k=0;
00278   double med_back=0;
00279   double sigma_back=0;
00280   double medvalue=0;
00281 
00282   float* pima=NULL;
00283   float* ppix=NULL;
00284   float* pmsk=NULL;
00285   int* ppos=NULL;
00286   int* pbackpix=NULL;
00287   cpl_binary* pbin=NULL;
00288   double tot=0;
00289   double mean=0;
00290   int* ybad=NULL;
00291 
00292   int nrow=0;
00293   int nbad=0;
00294   int yval=0;
00295   int yprev=0;
00296 
00297 
00298   check_nomsg(sx=cpl_image_get_size_x(ima_in));
00299   check_nomsg(sy=cpl_image_get_size_y(ima_in));
00300   check_nomsg(*ima_out=cpl_image_duplicate(ima_in));
00301 
00302   check_nomsg(mask=cpl_image_new(sx,sy,CPL_TYPE_FLOAT));
00303   check_nomsg(pmsk=cpl_image_get_data_float(mask));
00304 
00305   for(i=0;i<width;i++) {
00306     for(j=width;j<sy-width;j++) {
00307       pmsk[j*sx+i]=1;
00308     }
00309   }
00310 
00311   for(i=sx-width;i<sx;i++) {
00312     for(j=width;j<sy-width;j++) {
00313       pmsk[j*sx+i]=1;
00314     }
00315   }
00316   sinfo_free_image(&mask); //is mask needed?
00317 
00318 
00319   nrow=2*width*(sy-2*width);
00320   check_nomsg(ima_backpix=cpl_image_new(nrow,1,CPL_TYPE_FLOAT));
00321   check_nomsg(ima_backpos=cpl_image_new(nrow,1,CPL_TYPE_INT));
00322 
00323   check_nomsg(pima=cpl_image_get_data_float(ima_in));
00324   check_nomsg(ppix=cpl_image_get_data_float(ima_backpix));
00325   check_nomsg(ppos=cpl_image_get_data_int(ima_backpos));
00326 
00327   k=0;
00328   for(i=0;i<width;i++) {
00329     for(j=width;j<sy-width;j++) {
00330       ppix[k]=pima[j*sx+i];
00331       ppos[k]=j*sx+i;
00332       k++;
00333     }
00334   }
00335 
00336   for(i=sx-width;i<sx;i++) {
00337     for(j=width;j<sy-width;j++) {
00338       ppix[k]=pima[j*sx+i];
00339       ppos[k]=j*sx+i;
00340       k++;
00341     }
00342   }
00343 
00344   check_nomsg(ima_ybackpix=cpl_image_duplicate(ima_backpos));
00345   sinfo_free_image(&ima_backpos);
00346 
00347   check_nomsg(pbackpix=cpl_image_get_data_int(ima_ybackpix));
00348 
00349   check_nomsg(cpl_image_divide_scalar(ima_ybackpix,sx));
00350   check_nomsg(pbackpix=cpl_image_get_data_int(ima_ybackpix));
00351 
00352 
00353   check_nomsg(med_back=cpl_image_get_median(ima_backpix));
00354   check_nomsg(ima_diffbackpix=cpl_image_duplicate(ima_backpix));
00355   //sinfo_msg("med_back=%g",med_back);
00356   check_nomsg(cpl_image_subtract_scalar(ima_diffbackpix,med_back));
00357   //check_nomsg(cpl_image_save(ima_diffbackpix,"ima_diff.fits",
00358   //                           CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT));
00359 
00360   check_nomsg(filter=cpl_matrix_new(1,filt_rad));
00361   check_nomsg(cpl_matrix_fill(filter,1.));
00362   check_nomsg(ima_filt=sinfo_image_filter_median(ima_diffbackpix,filter));
00363   sinfoni_free_matrix(&filter);
00364   //check_nomsg(cpl_image_save(ima_filt,"ima_filt.fits",CPL_BPP_IEEE_FLOAT,
00365   //             NULL,CPL_IO_DEFAULT));
00366 
00367   
00368   check_nomsg(sigma_back=cpl_image_get_stdev(ima_filt));
00369   sinfo_free_image(&ima_filt);
00370 
00371   check_nomsg(ima=cpl_image_duplicate(ima_diffbackpix));
00372   sinfo_free_image(&ima_diffbackpix);
00373 
00374   check_nomsg(cpl_image_abs(ima));
00375   //sinfo_msg("sigma_back=%g",sigma_back);
00376 
00377   //find good pixels
00378   check_nomsg(bpm_bad=cpl_mask_threshold_image_create(ima,kappa*sigma_back,
00379                               SINFO_DBL_MAX));
00380   /*check_nomsg(bpm_good=cpl_mask_threshold_image_create(ima,SINFO_DBL_MIN,
00381                                kappa*sigma_back));
00382   sinfo_free_mask(&bpm_good);
00383 */
00384   check_nomsg(cpl_image_reject_from_mask(ima_backpix,bpm_bad));
00385   check_nomsg(medvalue=cpl_image_get_median(ima_backpix));
00386   //sinfo_msg("medvalue=%g",sigma_back);
00387   check_nomsg(nbad=cpl_mask_count(bpm_bad));
00388   //sinfo_msg("nbad=%d",nbad);
00389   check_nomsg(cpl_image_reject_from_mask(ima_backpix,bpm_bad));
00390   sinfo_free_image(&ima_backpix);
00391 
00392   yprev=-1;
00393 
00394   check_nomsg(pbin=cpl_mask_get_data(bpm_bad));
00395   check_nomsg(pbackpix=cpl_image_get_data_int(ima_ybackpix));
00396   cpl_msg_debug(cpl_func, "%d lines detected", nbad);
00397   if(nbad)
00398   {
00399 
00400       ybad = cpl_calloc(nbad,sizeof(int));
00401       k=0;
00402 
00403       for(i=0;i<nrow;i++) {
00404         if(pbin[i] == CPL_BINARY_1) {
00405            ybad[k]=pbackpix[i] + 1;
00406            k++;
00407         }
00408       }
00409       sinfo_free_mask(&bpm_bad);
00410       sinfo_free_image(&ima_ybackpix);
00411 
00412       quicksort_int(&(ybad[0]), 0, nbad-1);
00413       yprev=-1;
00414       for(k=0;k<nbad;k++) {
00415         yval=ybad[k];
00416         if(yval == yprev) {
00417           sinfo_msg_debug("skyp %d",yval);
00418         }
00419         else {
00420           yprev=yval;
00421           sinfo_msg_debug("correct raw %d",yval);
00422           check_nomsg(tot=cpl_image_get_flux_window(ima_in,1,yval,width,yval));
00423           check_nomsg(tot+=cpl_image_get_flux_window(ima_in,sx-width+1,
00424                             yval,sx,yval));
00425           mean=tot/(2. * width);
00426           check_nomsg(pima=cpl_image_get_data_float(*ima_out));
00427           for(i=width;i<sx-width;i++) {
00428         pima[i+(yval-1)*sx]+=(float)(mean-medvalue);
00429           }
00430 
00431         }
00432       }
00433   }
00434 
00435 
00436  cleanup:
00437 
00438   sinfo_free_image(&mask); //is mask needed?
00439   sinfo_free_image(&ima_backpos);
00440   sinfoni_free_matrix(&filter);
00441   sinfo_free_image(&ima_filt);
00442   sinfo_free_image(&ima_diffbackpix);
00443 //  sinfo_free_mask(&bpm_good);
00444   sinfo_free_image(&ima_backpix);
00445   sinfo_free_mask(&bpm_bad);
00446   sinfo_free_image(&ima_ybackpix);
00447   cpl_image_delete(ima);
00448   cpl_free(ybad);
00449   return cpl_error_get_code();
00450 
00451 }
00452 
00453 
00462 double sinfo_new_my_median_image(cpl_image* im)
00463 {
00464   double m=0;
00465   register int i=0;
00466   int n=0;
00467   pixelvalue* pv=0;
00468   int ilx=0;
00469   int ily=0;
00470   float* pidata=NULL;
00471 
00472 
00473   if(im==NULL) sinfo_msg_error("Null Image");
00474   ilx=cpl_image_get_size_x(im);
00475   ily=cpl_image_get_size_y(im);
00476   pidata=cpl_image_get_data_float(im);
00477 
00478    for ( i = 0 ; i < (int) ilx*ily ; i++ )
00479     {
00480       if ( isnan(pidata[i]) )
00481         {
00482 
00483     } else {
00484       n++;
00485     }
00486     }
00487    pv = cpl_calloc(n,sizeof(pixelvalue));
00488    n=0;
00489    for ( i = 0 ; i < (int) ilx*ily ; i++ )
00490     {
00491       if ( isnan(pidata[i]) )
00492         {
00493 
00494     } else {
00495       pv[n]=pidata[i];
00496           n++;
00497     }
00498     }
00499    if(pv == NULL || n == 0) {
00500      m=0;
00501    } else {
00502      m=sinfo_new_median(pv,n);
00503    }
00504    cpl_free(pv);
00505    if(isnan(m)){
00506      m=0;
00507    }
00508   return m;
00509 }
00510 
00519 Vector * sinfo_new_mean_of_columns( cpl_image *im )
00520 {
00521     Vector * row=NULL ;
00522     int i=0;
00523     int j=0;
00524     int ilx=0;
00525     int ily=0;
00526     float* pidata=NULL;
00527 
00528     if ( im == NULL )
00529     {
00530         sinfo_msg_error ("null image") ;
00531         return NullVector ;
00532     }
00533     ilx=cpl_image_get_size_x(im);
00534     ily=cpl_image_get_size_y(im);
00535     pidata=cpl_image_get_data_float(im);
00536 
00537     /* allocate memory for a row with the length of the image x-axis */
00538     if ( NULL == (row = sinfo_new_vector (ilx)) )
00539     {
00540         sinfo_msg_error ("not able to allocate a sinfo_vector" ) ;
00541         return NullVector ;
00542     }
00543 
00544     for ( i = 0 ; i < ilx ; i++ )
00545     {
00546         for ( j = 0 ; j < ily ; j++ )
00547         {
00548             if (!isnan(pidata[i+j*ilx]))
00549             {
00550                 row->data[i] += pidata[i + j*(ilx)] ;
00551             }
00552         }
00553 
00554         row->data[i] /= ily ;
00555     }
00556     return row ;
00557 }
00569 cpl_image * sinfo_new_clean_mean_of_columns( cpl_image *im,
00570                              float lo_reject,
00571                              float hi_reject)
00572 {
00573     cpl_image     * row=NULL ;
00574     pixelvalue*   buffer=NULL ;
00575     int          i=0;
00576     int          j=0;
00577     int          k=0;
00578     int          nv=0;
00579     int          lo_n=0;
00580     int          hi_n=0;
00581     int ilx=0;
00582     int ily=0;
00583     float* pidata=NULL;
00584     float* podata=NULL;
00585 
00586     if ( im == NULL )
00587     {
00588         sinfo_msg_error ("null image") ;
00589         return NULL ;
00590     }
00591     ilx=cpl_image_get_size_x(im);
00592     ily=cpl_image_get_size_y(im);
00593     pidata=cpl_image_get_data_float(im);
00594 
00595     if ((lo_reject + hi_reject) > 0.9)
00596     {
00597         sinfo_msg_error("illegal rejection thresholds: [%f] and [%f]",
00598                         lo_reject, hi_reject) ;
00599         sinfo_msg_error("threshold sum should not be over "
00600                         "0.90 aborting average") ;
00601         return NULL ;
00602     }
00603 
00604     lo_n = (int) (ily * lo_reject + 0.5) ;
00605     hi_n = (int) (ily * hi_reject + 0.5) ;
00606     if (lo_n + hi_n >= ily)
00607     {
00608         sinfo_msg_error ("everything would be rejected") ;
00609         return NULL ;
00610     }
00611 
00612     /* allocate memory for a row with the length of the image x-axis */
00613     if ( NULL == (row = cpl_image_new (ilx, 1,CPL_TYPE_FLOAT)) )
00614     {
00615         sinfo_msg_error ("cannot allocate new image") ;
00616         return NULL ;
00617     }
00618     podata=cpl_image_get_data_float(row);
00619 
00620     buffer=(pixelvalue*) cpl_calloc(ily,sizeof(pixelvalue)) ;
00621 
00622     for ( i = 0 ; i < ilx ; i++ )
00623     {
00624         for ( j = 0 ; j < ily ; j++ )
00625         {
00626             buffer[j] = pidata[i + j*(ilx)] ;
00627         }
00628         sinfo_pixel_qsort (buffer, ily) ;
00629 
00630         nv = 0 ;
00631         for (k = lo_n ; k < ily - hi_n ; k ++)
00632         {
00633             if ( !isnan(buffer[k]) )
00634             {
00635                 podata[i] += buffer[k] ;
00636                 nv ++ ;
00637             }
00638         }
00639         podata[i] /= nv ;
00640 
00641     }
00642     cpl_free(buffer);
00643     return row ;
00644 }
00645 
00646 
00656 cpl_image * sinfo_new_div_image_by_row( cpl_image *im, Vector *row )
00657 {
00658     cpl_image *image=NULL ;
00659     int         i=0;
00660     int         j=0;
00661     int ilx=0;
00662     int ily=0;
00663     float* pidata=NULL;
00664     float* podata=NULL;
00665 
00666     if ( im == NULL || row == NULL )
00667     {
00668         sinfo_msg_error ("null image or null row") ;
00669         return NULL ;
00670     }
00671     ilx=cpl_image_get_size_x(im);
00672     ily=cpl_image_get_size_y(im);
00673     pidata=cpl_image_get_data_float(im);
00674 
00675     if ( ilx != row -> n_elements )
00676     {
00677         sinfo_msg_error("image and row size not compatible") ;
00678         return NULL ;
00679     }
00680 
00681     if ( NULL == (image = cpl_image_duplicate (im)) )
00682     {
00683         sinfo_msg_error ("cannot copy image") ;
00684         return NULL ;
00685     }
00686     podata=cpl_image_get_data_float(image);
00687 
00688     for (i = 0 ; i < ilx ; i++ )
00689     {
00690         for (j = 0 ; j < ily ; j++)
00691         {
00692             if ( !isnan(pidata[i + j*(ilx)]) )
00693             {
00694                 podata[i + j*(ilx)] = pidata[i + j*(ilx)] / row -> data[i] ;
00695             }
00696         }
00697     }
00698     return image ;
00699 }
00700 
00701 
00711 cpl_image * sinfo_new_mult_row_to_image( cpl_image *im, Vector *row )
00712 {
00713     cpl_image *image=NULL;
00714     int         i=0;
00715     int         j=0;
00716     int ilx=0;
00717     int ily=0;
00718     float* pidata=NULL;
00719     float* podata=NULL;
00720 
00721 
00722 
00723 
00724     if ( im == NULL || row == NULL )
00725     {
00726         sinfo_msg_error ("null image or null row") ;
00727         return NULL ;
00728     }
00729     ilx=cpl_image_get_size_x(im);
00730     ily=cpl_image_get_size_y(im);
00731     pidata=cpl_image_get_data_float(im);
00732 
00733     if ( ilx != row -> n_elements )
00734     {
00735         sinfo_msg_error("image and row size not compatible") ;
00736         return NULL ;
00737     }
00738 
00739     if ( NULL == (image = cpl_image_duplicate (im)) )
00740     {
00741         sinfo_msg_error ("cannot copy image") ;
00742         return NULL ;
00743     }
00744     podata=cpl_image_get_data_float(image);
00745 
00746     for (i = 0 ; i < ilx ; i++ )
00747     {
00748         for (j = 0 ; j < ily ; j++)
00749         {
00750             if ( !isnan(pidata[i + j*(ilx)]) )
00751             {
00752                 podata[i + j*(ilx)] = pidata[i + j*(ilx)] * row -> data[i] ;
00753             }
00754         }
00755     }
00756     return image ;
00757 }
00758 
00759 
00760 
00761 
00762 
00763 
00787 cpl_image * sinfo_new_col_tilt ( cpl_image * image, float sigmaFactor )
00788 {
00789     cpl_image   * im=NULL;
00790     float      * column=NULL ;
00791     double       sum=0;
00792     double  sum2=0;
00793     double  mean=0;
00794     float   sinfo_median=0;
00795     float   noise=0 ;
00796     float      * sig=NULL;
00797     float    * dat=NULL;
00798     float        a=0;
00799     float        b=0;
00800     float        siga=0;
00801     float        sigb=0;
00802     float        chi2=0;
00803     float        q=0;
00804     int          i=0;
00805     int          j=0;
00806     int          colnum=0;
00807     int         npix=0;
00808     int         mwt=0 ;
00809     int lx=0;
00810     int ly=0;
00811     float* p_in_data=NULL;
00812     float* p_ou_data=NULL;
00813 
00814 
00815     if ( image == NULL )
00816     {
00817         sinfo_msg_error ("no image given" ) ;
00818         return NULL ;
00819     }
00820 
00821     if ( sigmaFactor <= 0. )
00822     {
00823         sinfo_msg_error ("no or negative sigma factor") ;
00824         return NULL ;
00825     }
00826     lx = cpl_image_get_size_x(image);
00827     ly = cpl_image_get_size_y(image);
00828 
00829 
00830     /* allocate memory */
00831     if ( NULL == (im = cpl_image_new (lx,ly,CPL_TYPE_FLOAT )) )
00832     {
00833         sinfo_msg_error ("cannot allocate new image" ) ;
00834         return NULL ;
00835     }
00836 
00837     /* go through the columns */
00838     p_in_data = cpl_image_get_data_float(image);
00839     p_ou_data = cpl_image_get_data_float(im);
00840     for ( i = 0 ; i < lx ; i ++ )
00841     {
00842         /* initialize the buffer variables for each column */
00843         colnum = 0 ;
00844         column = (float *) cpl_calloc ( ly , sizeof (float *) ) ;
00845         sig    = (float *) cpl_calloc ( ly , sizeof (float *) ) ;
00846         dat    = (float *) cpl_calloc ( ly , sizeof (float *) ) ;
00847 
00848         /*select only non-ZERO values of one column*/
00849         for ( j = 0 ; j < ly ; j++ )
00850         {
00851             if ( !isnan(p_in_data[i + j*lx]) )
00852             {
00853                 column[j] = p_in_data[i + j*lx] ;
00854                 colnum ++ ;
00855             }
00856         }
00857         if ( colnum < 10 )
00858         {
00859             /*sinfo_msg_warning ("sinfo_new_col_tilt:",
00860           "column %d has almost only blank pixels and is set to blank", i+1) ;*/
00861             for ( j = 0 ; j < ly ; j++ )
00862             {
00863                 p_ou_data[i + j*lx] = ZERO;
00864             }
00865             /*
00866             cpl_free (column) ;
00867             cpl_free (sig);
00868             cpl_free (dat) ;
00869             continue ;
00870             */
00871         }
00872 
00873         /*-------------------------------------------------------------------
00874          * sort the data, clip off the extremes, determine the noise
00875          * and get the range for the valid data. It is assumed here
00876          * that most pixels are o.k.
00877          */
00878 
00879         sinfo_pixel_qsort (column, colnum) ;
00880 
00881         sum   = 0. ;
00882         sum2  = 0. ;
00883         npix  = 0  ;
00884 
00885         for ( j = 0.1*colnum + 1 ; j <= 0.9*colnum ; j++ )
00886         {
00887             sum  += column[j] ;
00888             sum2 += column[j] * column[j] ;
00889             npix ++ ;
00890         }
00891 
00892         if (npix <= 1)
00893         {
00894             noise = sigmaFactor * 1000.;
00895         }
00896         else
00897         {
00898             mean   = sum/(float)npix ;
00899             noise  = sqrt( (sum2 - sum*mean)/(double)(npix -1) ) ;
00900             noise *= sigmaFactor ;
00901         }
00902 
00903         /* -------------------------------------------------------------
00904          * determine sinfo_median if colnum is odd, sinfo_median will be the
00905            colnum/2 th value, otherwise
00906          * sinfo_median is the mean of colnum/2-1 th and colnum/2 th value.
00907          */
00908 
00909         if ( colnum % 2 == 1 )
00910         {
00911             sinfo_median = column[colnum/2] ;
00912         }
00913         else
00914         {
00915             sinfo_median = (column[colnum/2 - 1] + column[colnum/2])/2. ;
00916         }
00917 
00918         /* now select the pixels for the tilt calculation */
00919 
00920         colnum = 0 ;
00921         for ( j = 0; j < ly ; j ++ )
00922         {
00923             if ( !isnan(p_in_data[i+j*lx]) &&
00924                  fabs ( (p_in_data[i+j*lx]) - sinfo_median) <= noise )
00925             {
00926                 column[colnum] = p_in_data[i+j*lx] ;
00927                 dat[colnum] = (float) j ;
00928                 sig[colnum] = 1. ;
00929                 colnum ++ ;
00930             }
00931         }
00932 
00933         if ( colnum == 0 )
00934         {
00935             /*for ( j = 0; j < ly; j++ )
00936             {
00937                 p_ou_data[i+j*lx] -= sinfo_median ;
00938             }
00939             cpl_free (column) ;
00940             cpl_free (sig)    ;
00941             cpl_free (dat)    ;
00942             continue ;*/
00943         a=0./0.;
00944         b=0./0.;
00945         }
00946     else
00947     {
00948         mwt = 0 ;
00949         sinfo_my_fit ( dat, column, colnum, sig, mwt, &a,
00950                        &b, &siga, &sigb, &chi2, &q ) ;
00951     }
00952         if ( fabs(b) >= SLOPE || fabs(a) >= SATURATION  ||
00953              isnan(b) || isnan(a))
00954         {
00955             sinfo_msg_warning ("linear fit: slope is greater than limit: %f"
00956                                " saturation level is reached: %f in column"
00957                                " number %d ", b, a , i+1) ;
00958         }
00959 
00960         /* subtract fit or sinfo_median from data */
00961         for ( j = 0; j < ly; j++ )
00962         {
00963             if ( !isnan(p_in_data[i+j*lx]) &&
00964                  fabs(b) < SLOPE && fabs(a) < SATURATION )
00965             {
00966                 p_ou_data[i+j*lx] = p_in_data[i+j*lx] - (a + b * (float)j) ;
00967             }
00968             else if ( isnan(p_in_data[i+j*lx]) )
00969             {
00970                 p_ou_data[i+j*lx] = ZERO ;
00971             }
00972             else if ( (fabs(b) >= SLOPE ||
00973                        fabs(a) >= SATURATION || isnan(a) || isnan(b)) &&
00974                       !isnan(p_in_data[i+j*lx]) )
00975             {
00976                 p_ou_data[i+j*lx] -= sinfo_median ;
00977             }
00978             else
00979             {
00980                 sinfo_msg_error (" case is not possible! %f %f", b,a) ;
00981                 /*cpl_free (column) ;
00982                 cpl_free (sig)    ;
00983                 cpl_free (dat)    ;
00984                 cpl_image_delete(im) ;
00985                 return NULL ;*/
00986             }
00987         }
00988         cpl_free (column) ;
00989         cpl_free (sig)    ;
00990         cpl_free (dat)    ;
00991     }
00992 
00993     return im     ;
00994 }
00995 
00996 
00997 
00998 
00999 
01023 cpl_image * sinfo_new_median_image( cpl_image * im, float fmedian )
01024 {
01025     cpl_image *   image=NULL       ;
01026     pixelvalue * value=NULL       ;
01027     pixelvalue   sinfo_median=0      ;
01028     int        * position=NULL    ;
01029     int          nposition=0   ;
01030     int          n=0;
01031     int          i=0;
01032     int          j=0;
01033     int lx=0;
01034     int ly=0;
01035     float* p_in_data=NULL;
01036     float* p_ou_data=NULL;
01037     int im_size=0;
01038     if ( im == NULL )
01039     {
01040         sinfo_msg_error ("no image input") ;
01041         return NULL ;
01042     }
01043 
01044     image = cpl_image_duplicate ( im ) ;
01045     lx=cpl_image_get_size_x(im);
01046     ly=cpl_image_get_size_y(im);
01047     im_size=lx*ly;
01048     p_in_data=cpl_image_get_data_float(im);
01049     p_ou_data=cpl_image_get_data_float(image);
01050 
01051     /*----------------------------------------------------------------------
01052      * go through all pixels
01053      */
01054 
01055     for ( i = 0 ; i < im_size ; i++ )
01056     {
01057         /* blank pixels are not replaced */
01058         if ( isnan(p_in_data[i]) )
01059         {
01060             continue ;
01061         }
01062 
01063         /* initialize the buffer variables for the 8 nearest neighbors */
01064         value = (pixelvalue * )cpl_calloc ( 8, sizeof ( pixelvalue * ) ) ;
01065         position = ( int * ) cpl_calloc ( 8, sizeof ( int * ) ) ;
01066 
01067         /*--------------------------------------------------------------------
01068          * determine the pixel position of the 8 nearest neighbors
01069          */
01070 
01071         position[0] = i + lx - 1 ; /* upper left  */
01072         position[1] = i + lx     ; /* upper       */
01073         position[2] = i + lx + 1 ; /* upper right */
01074         position[3] = i + 1      ; /* right       */
01075         position[4] = i - lx + 1 ; /* lower right */
01076         position[5] = i - lx     ; /* lower       */
01077         position[6] = i - lx - 1 ; /* lower left  */
01078         position[7] = i - 1      ; /* left        */
01079 
01080         /*-------------------------------------------------------------------
01081          * determine the positions of the image margins, top positions are
01082            changed to low positions and vice versa. Right positions are
01083            changed to left positions and vice versa.
01084          */
01085 
01086         if ( i >= 0 && i < lx )    /* bottom line */
01087         {
01088             position[4] += 2 * lx ;
01089             position[5] += 2 * lx ;
01090             position[6] += 2 * lx ;
01091         }
01092         else if ( i >= ((int) lx*ly - lx ) && i < (int) lx*ly ) /* top line */
01093         {
01094             position[0] -= 2 * lx ;
01095             position[1] -= 2 * lx ;
01096             position[2] -= 2 * lx ;
01097         }
01098         else if ( i % lx == 0 )    /* left side */
01099         {
01100             position[0] += 2 ;
01101             position[6] += 2 ;
01102             position[7] += 2 ;
01103         }
01104         else if ( i % lx == lx - 1 )    /* right side */
01105         {
01106             position[2] -= 2 ;
01107             position[3] -= 2 ;
01108             position[4] -= 2 ;
01109         }
01110 
01111         /* --------------------------------------------------------------------
01112          * read the pixel values of the neighboring pixels,
01113          * blanks are not considered
01114          */
01115 
01116         nposition = 8 ;
01117         n = 0 ;
01118         for ( j = 0 ; j < nposition ; j ++ )
01119         {
01120            if((position[j] >-1 ) && (position[j]<im_size)) {
01121               if ( !isnan(p_in_data[position[j]]) )
01122               {
01123                 value[n] = p_in_data[position[j]] ;
01124                 n ++ ;
01125               }
01126            }
01127         }
01128         nposition = n ;
01129 
01130         if ( nposition <= 1 )  /* almost all neighbors are blank */
01131         {
01132             p_ou_data[i] = ZERO ;
01133             cpl_free(value) ;
01134             cpl_free(position) ;
01135             continue ;
01136         }
01137 
01138         /* sort the values and determine the sinfo_median */
01139 
01140         sinfo_pixel_qsort ( value, nposition ) ;
01141         if ( nposition % 2 == 1 )
01142         {
01143             sinfo_median = value [ nposition/2 ] ;
01144         }
01145         else
01146         {
01147             sinfo_median = ( value [nposition/2 - 1] +
01148                              value [nposition/2] ) / 2. ;
01149         }
01150 
01151         /* -----------------------------------------------------------------
01152          * replace the pixel value by the sinfo_median on conditions:
01153          * fmedian = 0: always replace with sinfo_median.
01154          * fmedian < 0: interpret as absolute condition:
01155          *              if |pixel - sinfo_median| > -fmedian
01156          *              replace with sinfo_median.
01157          * fmedian > 0: replace by sinfo_median (fmedian as a factor of
01158          *              the square root of the sinfo_median itself)
01159          *              if |pixel - sinfo_median| >= fmedian *
01160                                                      sqrt ( sinfo_median )
01161          *              considers a dependence on the pixel value.
01162          *              This can be used to consider photon noise.
01163          */
01164 
01165         if ( fmedian == 0 )
01166         {
01167             p_ou_data[i] = sinfo_median ;
01168         }
01169         else if ( fmedian < 0 &&
01170                   fabs ( sinfo_median - p_in_data[i] ) >= -fmedian )
01171         {
01172             p_ou_data[i] = sinfo_median ;
01173         }
01174         else if ( fmedian > 0 &&
01175                   fabs ( sinfo_median - p_in_data[i] ) >= fmedian *
01176                                                       sqrt(fabs(sinfo_median)) )
01177         {
01178             p_ou_data[i] = sinfo_median ;
01179         }
01180         else
01181         {
01182             cpl_free (value) ;
01183             cpl_free (position) ;
01184             continue ;
01185         }
01186 
01187         cpl_free (value) ;
01188         cpl_free (position) ;
01189     }
01190     return image ;
01191 }
01192 
01193 
01194 
01195 
01206 cpl_image *
01207 sinfo_new_compare_images(cpl_image * im1,cpl_image * im2,cpl_image * origim )
01208 {
01209     cpl_image * image=NULL ;
01210     int            i=0 ;
01211     int lx1=0;
01212     int ly1=0;
01213     int lx2=0;
01214     int ly2=0;
01215     float* p_in1_data=NULL;
01216     float* p_in2_data=NULL;
01217     float* p_ou_data=NULL;
01218     float* p_org_data=NULL;
01219 
01220 
01221     if ( im1 == NULL || im2 == NULL || origim == NULL )
01222     {
01223         sinfo_msg_error ("Null images as input" ) ;
01224         return NULL ;
01225     }
01226     lx1=cpl_image_get_size_x(im1);
01227     ly1=cpl_image_get_size_y(im1);
01228 
01229     lx2=cpl_image_get_size_x(im2);
01230     ly2=cpl_image_get_size_y(im2);
01231 
01232     p_in1_data=cpl_image_get_data_float(im1);
01233     p_in2_data=cpl_image_get_data_float(im2);
01234     p_org_data=cpl_image_get_data_float(origim);
01235     if ( lx1 != lx2 || ly1 != ly2 )
01236     {
01237         sinfo_msg_error ("incompatible image sizes" ) ;
01238         return NULL ;
01239     }
01240 
01241     /* allocate memory */
01242     if ( NULL == (image = cpl_image_new ( lx1, ly1, CPL_TYPE_FLOAT )) )
01243     {
01244         sinfo_msg_error ("cannot allocate new image" ) ;
01245         return NULL ;
01246     }
01247     p_ou_data=cpl_image_get_data_float(image);
01248     for ( i = 0 ; i < (int) lx1*ly1 ; i ++ )
01249     {
01250         if ( isnan(p_in1_data[i]) && isnan(p_in2_data[i]) )
01251         {
01252             p_ou_data[i] = ZERO ;
01253         }
01254         else
01255         {
01256             if ( p_in1_data[i] == p_in2_data[i] )
01257             {
01258                 p_ou_data[i] = p_org_data[i] ;
01259             }
01260             else
01261             {
01262                 p_ou_data[i] = ZERO ;
01263             }
01264         }
01265     }
01266     return image ;
01267 }
01268 
01269 
01270 
01282 cpl_image *
01283 sinfo_new_promote_image_to_mask (cpl_image * im, int * n_badpixels )
01284 {
01285     cpl_image * reImage=NULL ;
01286     int        i=0 ;
01287     int lx=0;
01288     int ly=0;
01289     float* p_in_data=NULL;
01290     float* p_ou_data=NULL;
01291 
01292     if ( NULL == im )
01293     {
01294         sinfo_msg_error("no input image given!") ;
01295         return NULL ;
01296     }
01297     lx=cpl_image_get_size_x(im);
01298     ly=cpl_image_get_size_y(im);
01299     p_in_data=cpl_image_get_data_float(im);
01300 
01301     /* allocate memory for the returned image */
01302     if ( NULL == (reImage = cpl_image_new (lx,ly,CPL_TYPE_FLOAT )) )
01303     {
01304         sinfo_msg_error ("cannot allocate new image!") ;
01305         return NULL ;
01306     }
01307     p_ou_data=cpl_image_get_data_float(reImage);
01308 
01309     *n_badpixels = 0 ;
01310     for ( i = 0 ; i < (int) lx*ly ; i ++ )
01311     {
01312         if ( isnan(p_in_data[i]) )
01313         {
01314             p_ou_data[i] = 0. ;
01315             (*n_badpixels)++ ;
01316         }
01317         else
01318         {
01319             p_ou_data[i] = 1. ;
01320         }
01321     }
01322     return reImage ;
01323 }
01324 
01325 
01336 cpl_image * sinfo_new_mult_image_by_mask (cpl_image * im,cpl_image * mask )
01337 {
01338     cpl_image * reImage=NULL ;
01339     int        i=0 ;
01340     int ix=0;
01341     int iy=0;
01342     int mx=0;
01343     int my=0;
01344 
01345 
01346     float* pmdata=NULL;
01347     float* podata=NULL;
01348 
01349     if ( NULL == im )
01350     {
01351         sinfo_msg_error("no input image given!") ;
01352         return NULL ;
01353     }
01354     if ( NULL == mask )
01355     {
01356         sinfo_msg_error("no mask image given!") ;
01357         return NULL ;
01358     }
01359     ix=cpl_image_get_size_x(im);
01360     iy=cpl_image_get_size_y(im);
01361     mx=cpl_image_get_size_x(mask);
01362     my=cpl_image_get_size_y(mask);
01363 
01364     if ( ix != mx || iy != my)
01365     {
01366         sinfo_msg_error("image sizes are not correspondent!") ;
01367         return NULL ;
01368     }
01369 
01370     reImage = cpl_image_duplicate( im ) ;
01371     podata=cpl_image_get_data_float(reImage);
01372     pmdata=cpl_image_get_data_float(mask);
01373 
01374     for ( i = 0 ; i < (int) ix*iy ; i ++ )
01375     {
01376         if ( pmdata[i] == 0. )
01377         {
01378             podata[i] = ZERO ;
01379         }
01380     }
01381 
01382     return reImage ;
01383 }
01384 
01385 
01386 
01396 cpl_image *
01397 sinfo_new_thresh_image (cpl_image * im, float lo_cut, float hi_cut )
01398 {
01399     cpl_image * image=NULL ;
01400     float* p_inp_data=NULL;
01401     float* p_out_data=NULL;
01402     int lx=0;
01403     int ly=0;
01404 
01405     int            i=0 ;
01406 
01407     if (im == NULL)
01408     {
01409         sinfo_msg_error ("null image given") ;
01410         return NULL ;
01411     }
01412     lx=cpl_image_get_size_x(im);
01413     ly=cpl_image_get_size_y(im);
01414 
01415     image = cpl_image_duplicate(im) ;
01416     p_inp_data=cpl_image_get_data(im);
01417     p_out_data=cpl_image_get_data(image);
01418     for ( i = 0 ; i < (int) lx*ly ; i ++ )
01419     {
01420         if ( p_inp_data[i] > (pixelvalue) hi_cut ||
01421              p_inp_data[i] < (pixelvalue) lo_cut )
01422         {
01423              p_out_data[i] = ZERO ;
01424         }
01425     }
01426     return image ;
01427 }
01428 
01429 
01430 
01431 
01456 cpl_image * sinfo_new_interpol_image ( cpl_image * im,
01457                            cpl_image * mask,
01458                            int        max_radius,
01459                            int        n_pixels )
01460 {
01461     cpl_image * returnImage=NULL ;
01462     float* neighbors=NULL ;
01463     float sum=0;
01464     float mean=0;
01465     int i=0;
01466     int j=0;
01467     int k=0;
01468     int row=0;
01469     int col=0;
01470     int n_valid=0;
01471     int agreed=0;
01472 
01473     int ilx=0;
01474     int ily=0;
01475     int mlx=0;
01476     int mly=0;
01477     float* pidata=NULL;
01478     float* podata=NULL;
01479     float* pmdata=NULL;
01480 
01481     if ( NULL == im )
01482     {
01483         sinfo_msg_error("sorry, no input image given!") ;
01484         return NULL ;
01485     }
01486     ilx=cpl_image_get_size_x(im);
01487     ily=cpl_image_get_size_y(im);
01488     pidata=cpl_image_get_data_float(im);
01489 
01490     if ( NULL == mask )
01491     {
01492         sinfo_msg_error("sorry, no mask image given!") ;
01493         return NULL ;
01494     }
01495 
01496     mlx=cpl_image_get_size_x(mask);
01497     mly=cpl_image_get_size_y(mask);
01498     pmdata=cpl_image_get_data_float(mask);
01499 
01500     if ( mlx != ilx || mly != ily )
01501     {
01502         sinfo_msg_error("images not compatible !") ;
01503         return NULL ;
01504     }
01505 
01506     if ( max_radius <= 0 )
01507     {
01508         sinfo_msg_error("wrong number of pixels for maximal "
01509                         "search radius given!") ;
01510         return NULL ;
01511     }
01512 
01513     if ( n_pixels <= 2 )
01514     {
01515         sinfo_msg_error("wrong number of pixels used "
01516                         "for interpolation given!") ;
01517         return NULL ;
01518     }
01519 
01520     returnImage = cpl_image_duplicate ( im ) ;
01521     podata=cpl_image_get_data_float(returnImage);
01522 
01523     /* go through the columns and rows of the input and mask image */
01524     neighbors=cpl_calloc(4*max_radius*max_radius,sizeof(float)) ;
01525 
01526     for ( col = 0 ; col < ilx ; col++ )
01527     {
01528         for ( row = 0 ; row < ily ; row++ )
01529         {
01530             /* look for the ZEROS that means the detected bad pixels */
01531             if ( isnan(pmdata[col+row*ilx]) || pmdata[col+row*ilx] == 0. )
01532             {
01533                 /* now the neighbors must be considered */
01534                 n_valid = 0 ;
01535                 agreed  = 0 ;
01536                 for ( j = 1 ; j <= max_radius ; j++ )
01537                 {
01538 
01539                     /* go through the left column */
01540                     for ( k = -j ; k < j ; k++ )
01541                     {
01542                         if ( col-j >= 0 && row+k < ily && row+k >= 0 )
01543                         {
01544                             if ( !isnan(pmdata[col-j+(row+k)*mlx]) ||
01545                                  pmdata[col-j+(row+k)*mlx] != 0 )
01546                             {
01547                                 neighbors[n_valid]=pidata[col-j+(row+k)*ilx] ;
01548                                 n_valid++ ;
01549                             }
01550                         }
01551                     }
01552 
01553                     /* go through the upper row */
01554                     for ( k = -j ; k < j ; k++ )
01555                     {
01556                         if ( col+k < ilx && col+k >= 0 && row+j < ily )
01557                         {
01558                             if ( !isnan(pmdata[col+k+(row+j)*mlx]) ||
01559                                  pmdata[col+k+(row+j)*mlx] != 0. )
01560                             {
01561                                 neighbors[n_valid]=pidata[col+k+(row+j)*ilx] ;
01562                                 n_valid++ ;
01563                             }
01564                         }
01565                     }
01566 
01567                     /* go through the right column */
01568                     for ( k = -j ; k < j ; k++ )
01569                     {
01570                         if ( col+j < ilx  && row-k >= 0 && row-k < ily )
01571                         {
01572                             if ( !isnan(pmdata[col+j+(row-k)*mlx]) ||
01573                                  pmdata[col+j+(row-k)*mlx] != 0. )
01574                             {
01575                                 neighbors[n_valid]=pidata[col+j+(row-k)*ilx] ;
01576                                 n_valid++ ;
01577                             }
01578                         }
01579                     }
01580 
01581                     /* go through the lower row */
01582                     for ( k = -j ; k < j ; k++ )
01583                     {
01584                         if ( col-k >= 0 && col-k < ilx && row-j < ily )
01585                         {
01586                             if ( !isnan(pmdata[col-k+(row-j)*mlx]) ||
01587                                  pmdata[col-k+(row-j)*mlx] != 0. )
01588                             {
01589                                 neighbors[n_valid]=pidata[col-k+(row-j)*ilx] ;
01590                                 n_valid++ ;
01591                             }
01592                         }
01593                     }
01594 
01595                     /* control if the breaking criteria is fullfilled */
01596                     if ( n_valid >= n_pixels )
01597                     {
01598                         agreed = 1 ;
01599                         break ;
01600                     }
01601                     /* do a break if more than 2 nearest neighbors are found */
01602                     if ( j == 1 && n_valid >= 2 )
01603                     {
01604                         agreed = 1 ;
01605                         break ;
01606                     }
01607                 }
01608                 if ( n_valid < n_pixels && agreed == 0 )
01609                 {
01610                     sinfo_msg_error("not enough valid neighbors found to "
01611                                     "interpolate bad pixel in col: "
01612                                     "%d, row: %d", col, row ) ;
01613                     return NULL ;
01614                 }
01615                 else
01616                 {
01617                     /* ------------------------------------------------------
01618                      * take the mean of the valid neighboring pixels if less
01619                      * than 9 valid pixels are available else take the
01620                        sinfo_median.
01621                      */
01622                     if ( n_valid <= 8 )
01623                     {
01624                         sum = 0. ;
01625 
01626                         for ( i = 0 ; i < n_valid ; i++ )
01627                         {
01628                             sum += neighbors[i] ;
01629                         }
01630                         mean = sum / n_valid ;
01631 
01632                         podata[col+row*ilx] = mean ;
01633                     }
01634                     else
01635                     {
01636                        podata[col+row*ilx]=sinfo_new_median(neighbors,n_valid);
01637                     }
01638                 }
01639             }
01640         }
01641     }
01642     cpl_free(neighbors);
01643     return returnImage ;
01644 }
01645 
01646 
01669 cpl_image * sinfo_interpol_source_image ( cpl_image * im,
01670                                  cpl_image * mask,
01671                                  int        max_rad,
01672                                  float   ** slit_edges )
01673 {
01674     cpl_image * returnImage=NULL ;
01675     float validpixel[6] ;
01676     float sum=0 ;
01677     int n=0;
01678     int row=0;
01679     int col=0;
01680     int i=0;
01681     int k=0;
01682     int slitlet=0;
01683     int n_slitlets=0;
01684     int ilx=0;
01685     int ily=0;
01686     int mlx=0;
01687     int mly=0;
01688 
01689     float* pidata=NULL;
01690     float* podata=NULL;
01691     float* pmdata=NULL;
01692 
01693 
01694     if ( NULL == im )
01695     {
01696         sinfo_msg_error("sorry, no input image given!") ;
01697         return NULL ;
01698     }
01699     ilx=cpl_image_get_size_x(im);
01700     ily=cpl_image_get_size_y(im);
01701     pidata=cpl_image_get_data_float(im);
01702 
01703     if ( NULL == mask )
01704     {
01705         sinfo_msg_error("sorry, no bad pixel mask image given!") ;
01706         return NULL ;
01707     }
01708     mlx=cpl_image_get_size_x(mask);
01709     mly=cpl_image_get_size_y(mask);
01710     pmdata=cpl_image_get_data_float(mask);
01711 
01712     if ( mlx != ilx || mly != ily )
01713     {
01714         sinfo_msg_error("images not compatible in size!") ;
01715         return NULL ;
01716     }
01717 
01718     if ( max_rad < 1 )
01719     {
01720         sinfo_msg_error("sorry, wrong maximum distance given!") ;
01721         return NULL ;
01722     }
01723 
01724     if ( slit_edges == NULL )
01725     {
01726         sinfo_msg_error("sorry, array slit_edges is empty!") ;
01727         return NULL ;
01728     }
01729 
01730     /* determine the number of slitlets */
01731     n_slitlets = N_SLITLETS ;
01732 
01733     /* copy the original image in the image that will be returned */
01734     returnImage = cpl_image_duplicate( im ) ;
01735     podata=cpl_image_get_data_float(returnImage);
01736 
01737     /* go through the rows and columns of the image and search for
01738       the bad pixels */
01739     for ( row = 0 ; row < ily ; row++ )
01740     {
01741         for ( col = 0 ; col < ilx ; col++ )
01742         {
01743             n = 0 ;
01744             if ( isnan(pmdata[col + row*mlx]) ||
01745                  pmdata[col + row*mlx] == 0. ||
01746                  isnan(pidata[col + row*mlx]) )
01747             {
01748                 /* look for the slitlet where the bad pixel is found */
01749                 slitlet = -1000 ;
01750                 for ( k = 0 ; k < n_slitlets ; k++ )
01751                 {
01752                     if ( sinfo_new_nint(slit_edges[k][0]) <= col &&
01753                          sinfo_new_nint(slit_edges[k][1]) >= col )
01754                     {
01755                         slitlet = k ;
01756                     }
01757 /* The following else statement is wrong, because in the
01758      end slitlet will always be -1000
01759             else
01760                     {
01761                         slitlet = -1000 ;
01762                     }
01763 */
01764                 }
01765                 for ( i = 0 ; i < 6 ; i++ )
01766                 {
01767                     validpixel[i] = 0. ;
01768                 }
01769                 /* look for the valid nearest neighbors
01770                    and collect them but only a maximum of 4 */
01771                 for ( i = 1 ; i <= max_rad ; i++ )
01772                 {
01773                     if ( row + i < ily)
01774                     {
01775                         if ( !isnan(pmdata[col + (row+i) * mlx])
01776                              && pmdata[col + (row+i) * mlx] != 0. &&
01777                                 !isnan(pidata[col + (row+i) * ilx]) )
01778                         {
01779                             validpixel[n] = pidata[col + (row+i) * ilx] ;
01780                             n++ ;
01781                         }
01782                     }
01783                     if ( row - i >= 0 )
01784                     {
01785                         if ( !isnan(pmdata[col + (row-i) * mlx])
01786                              && pmdata[col + (row-i) * mlx] != 0. &&
01787                                 !isnan(pidata[col + (row-i) * ilx]) )
01788                         {
01789                             validpixel[n] = pidata[col + (row-i) * ilx] ;
01790                             n++ ;
01791                         }
01792                     }
01793 
01794                     /* be aware of the slitlet edges in the
01795                        spatial direction */
01796                     if ( col + i < ilx )
01797                     {
01798                       if (  slitlet != -1000 )
01799                       {
01800                          if (col+i <= sinfo_new_nint(slit_edges[slitlet][1]) &&
01801                              !isnan(pmdata[col + i + row * mlx]) &&
01802                              pmdata[col + i + row * mlx] != 0. &&
01803                              !isnan(pidata[col + i + row * ilx]) )
01804                          {
01805                              validpixel[n] = pidata[col + i + row * ilx] ;
01806                              n++ ;
01807                          }
01808                       }
01809                     }
01810                     if ( col - i >= 0 )
01811                     {
01812                       if ( slitlet != -1000 )
01813                       {
01814                          if (col-i >= sinfo_new_nint(slit_edges[slitlet][0]) &&
01815                              !isnan(pmdata[col - i + row * mlx]) &&
01816                              pmdata[col - i + row * mlx] != 0. &&
01817                              !isnan(pidata[col - i + row * ilx]) )
01818                          {
01819                              validpixel[n] = pidata[col - i + row * ilx] ;
01820                              n++ ;
01821                          }
01822                       }
01823                     }
01824 
01825                     if ( i == 1 && n > 1 )
01826                     {
01827                         break ;
01828                     }
01829                     if ( n > 2 )
01830                     {
01831                         break ;
01832                     }
01833                 }
01834 
01835                 if ( n == 0 )
01836                 {
01837                     podata[col + row*ilx] = ZERO ;
01838             /*sinfo_msg_warning("sinfo_interpolSourceImage:",
01839                                         "bad pixel in column: %d and row: %d"
01840                                         " could not be interpolated!",col,row);
01841                              */
01842                 }
01843                 else
01844                 {
01845                     /* now compute the mean and replace
01846                        the bad pixel value by the mean */
01847                     sum = 0. ;
01848                     for ( i = 0 ; i < n ; i++ )
01849                     {
01850                         sum += validpixel[i] ;
01851                     }
01852                     podata[col + row*ilx] = sum/n ;
01853                 }
01854             }
01855         }
01856     }
01857 
01858     return returnImage ;
01859 }
01860 
01870 cpl_image * sinfo_new_stack_row_to_image ( Vector * row, int ly )
01871 {
01872     cpl_image * image=NULL;
01873     int        col=0;
01874     int        ro=0;
01875     float* podata=NULL;
01876 
01877     if ( row == NullVector )
01878     {
01879         sinfo_msg_error ("Null sinfo_vector as input" ) ;
01880         return NULL ;
01881     }
01882     if ( ly <= 1 )
01883     {
01884         sinfo_msg_error ("wrong image length given" ) ;
01885         return NULL ;
01886     }
01887 
01888     /* allocate memory */
01889     if (NULL == (image = cpl_image_new(row->n_elements ,ly,CPL_TYPE_FLOAT )) )
01890     {
01891         sinfo_msg_error ("cannot allocate new image" ) ;
01892         return NULL ;
01893     }
01894     podata=cpl_image_get_data_float(image);
01895 
01896     for ( col = 0 ; col < row -> n_elements ; col++ )
01897     {
01898         for ( ro = 0 ; ro < ly ; ro++ )
01899         {
01900             podata[col + ro*ly] = row -> data[col] ;
01901         }
01902     }
01903     return image ;
01904 }
01905 
01921 Stats * sinfo_new_image_stats_on_rectangle ( cpl_image * im,
01922                                 float      loReject,
01923                                 float      hiReject,
01924                                 int        llx,
01925                                 int        lly,
01926                                 int        urx,
01927                                 int        ury )
01928 {
01929     Stats * retstats=NULL;
01930     int i=0 ;
01931     int row=0;
01932     int col=0;
01933     int n=0;
01934     int npix=0;
01935     int lo_n=0;
01936     int hi_n=0;
01937     double pix_sum=0;
01938     double sqr_sum=0;
01939     float * pix_array=NULL;
01940     int im_lx=0;
01941     int im_ly=0;
01942     float* pim=NULL;
01943 
01944     if ( NULL == im )
01945     {
01946         sinfo_msg_error("sorry, no input image given!") ;
01947         return NULL ;
01948     }
01949     if ( loReject+hiReject >= 100. )
01950     {
01951         sinfo_msg_error("sorry, too much pixels rejected!") ;
01952         return NULL ;
01953     }
01954     if ( loReject < 0. || loReject >= 100. ||
01955          hiReject < 0. || hiReject >= 100. )
01956     {
01957         sinfo_msg_error("sorry, negative reject values!") ;
01958         return NULL ;
01959     }
01960 
01961     im_lx=cpl_image_get_size_x(im);
01962     im_ly=cpl_image_get_size_y(im);
01963 
01964     if ( llx < 0 || lly < 0 || urx < 0 || ury < 0 ||
01965          llx >= im_lx || lly >= im_ly || urx >= im_lx ||
01966          ury >= im_ly || ury <= lly || urx <= llx )
01967     {
01968         sinfo_msg_error("sorry, wrong pixel coordinates of rectangle!") ;
01969         return NULL ;
01970     }
01971 
01972      /* allocate memory */
01973     retstats = (Stats*) cpl_calloc(1, sizeof(Stats)) ;
01974     npix = (urx - llx + 1) * (ury - lly + 1) ;
01975     pix_array = (float*) cpl_calloc ( npix, sizeof(float) ) ;
01976 
01977     /*-------------------------------------------------------------------------
01978      * go through the rectangle and copy the pixel values into an array.
01979      */
01980     n = 0 ;
01981     pim = cpl_image_get_data_float(im);
01982     for ( row = lly ; row <= ury ; row++ )
01983     {
01984         for ( col = llx ; col <= urx ; col++ )
01985         {
01986             if ( !isnan(pim[col + row*im_lx]) )
01987             {
01988                 pix_array[n] = pim[col + row*im_lx] ;
01989                 n++ ;
01990             }
01991     }
01992     }
01993 
01994     npix = n;
01995     /*if (n != npix)
01996     {
01997         sinfo_msg_error("the computed number of pixel equals "
01998                         "not the counted number, impossible!") ;
01999         cpl_free(retstats) ;
02000         cpl_free(pix_array) ;
02001         return NULL ;
02002     }*/
02003 
02004     /* determining the clean mean is already done in the recipes */
02005     if ( FLT_MAX == (retstats->cleanmean = sinfo_new_clean_mean(pix_array,
02006                                            npix, loReject, hiReject)) )
02007     {
02008         sinfo_msg_error("sinfo_new_clean_mean() did not work!") ;
02009         cpl_free(retstats) ;
02010         cpl_free(pix_array) ;
02011         return NULL ;
02012     }
02013 
02014     /* now the clean standard deviation must be calculated */
02015     /* initialize sums */
02016     lo_n = (int) (loReject / 100. * (float)npix) ;
02017     hi_n = (int) (hiReject / 100. * (float)npix) ;
02018     pix_sum = 0. ;
02019     sqr_sum = 0. ;
02020     n = 0 ;
02021     for ( i = lo_n ; i <= npix - hi_n ; i++ )
02022     {
02023         pix_sum += (double)pix_array[i] ;
02024         sqr_sum += ((double)pix_array[i] * (double)pix_array[i]) ;
02025         n++ ;
02026     }
02027 
02028     if ( n == 0 )
02029     {
02030         sinfo_msg_error("number of clean pixels is zero!") ;
02031         cpl_free(retstats) ;
02032         cpl_free(pix_array) ;
02033         return NULL ;
02034     }
02035     retstats -> npix = n ;
02036     pix_sum /= (double) n ;
02037     sqr_sum /= (double) n ;
02038     retstats -> cleanstdev = (float)sqrt(sqr_sum - pix_sum * pix_sum) ;
02039     cpl_free (pix_array) ;
02040     return retstats ;
02041 }
02042 
02043 
02044 
02053 cpl_image * sinfo_new_normalize_to_central_pixel ( cpl_image * image )
02054 {
02055     int col=0;
02056     int row=0;
02057     int i=0;
02058     int n=0;
02059     float* array=NULL ;
02060     float divisor=0;
02061     cpl_image * retImage=NULL;
02062     int ilx=0;
02063     int ily=0;
02064     float* pidata=NULL;
02065     float* podata=NULL;
02066 
02067     if ( image == NULL )
02068     {
02069         sinfo_msg_error("no image given!") ;
02070         return NULL ;
02071     }
02072     ilx=cpl_image_get_size_x(image);
02073     ily=cpl_image_get_size_y(image);
02074     pidata=cpl_image_get_data_float(image);
02075 
02076     retImage = cpl_image_duplicate(image) ;
02077     podata=cpl_image_get_data_float(retImage);
02078 
02079     n = 0 ;
02080     /* go through the central two image rows and store
02081        the values in an array */
02082     array=cpl_calloc(2*ilx,sizeof(float)) ;
02083 
02084     for ( row = ily/2 ; row < ily/2+1 ; row++ )
02085     {
02086         for ( col = 0 ; col < ilx ; col++ )
02087         {
02088             if ( !isnan(pidata[col+ilx*row]) )
02089             {
02090                 array[n] = pidata[col+ilx*row] ;
02091                 n++ ;
02092             }
02093         }
02094     }
02095     /* compute the sinfo_median of the central 2 spectral
02096        values of all spatial pixels*/
02097     if ( isnan(divisor = sinfo_new_median(array, n) ) )
02098     {
02099         sinfo_msg_error("no sinfo_median possible!") ;
02100         return NULL ;
02101     }
02102     if ( 0 == divisor )
02103     {
02104         sinfo_msg_error("cannot divide by 0") ;
02105         return NULL ;
02106     }
02107 
02108     for ( i = 0 ; i < (int) ilx*ily ; i++ )
02109     {
02110         if ( isnan(pidata[i]) )
02111         {
02112             podata[i] = ZERO ;
02113         }
02114         else
02115         {
02116             podata[i] = pidata[i]/divisor ;
02117         }
02118     }
02119     cpl_free(array);
02120     return retImage ;
02121 }
02122 
02123 /*-------------------------------------------------------------------------*/
02152 /*--------------------------------------------------------------------------*/
02153 
02154 cpl_image *
02155 sinfo_new_mpe_shift_image(
02156     cpl_image    *    image_in,
02157     double           shift_x,
02158     double           shift_y,
02159     double       *   interp_kernel)
02160 {
02161     cpl_image    *       shifted=NULL ;
02162     pixelvalue  *       first_pass=NULL ;
02163     pixelvalue  *       second_pass=NULL ;
02164     int             samples = KERNEL_SAMPLES ;
02165     int          i=0, j=0 ;
02166     double           fx=0, fy=0 ;
02167     double           rx=0, ry=0 ;
02168     int             px=0, py=0 ;
02169     int             tabx=0, taby=0 ;
02170     double           value=0 ;
02171     size_t          pos ;
02172     register pixelvalue     *   pix ;
02173     register pixelvalue     *   pixint ;
02174     int             mid=0;
02175     double          norm=0 ;
02176     double       *      ker=NULL ;
02177     int                         freeKernel = 1 ;
02178 
02179     int ilx=0;
02180     int ily=0;
02181     float* pidata=NULL;
02182     float* psdata=NULL;
02183 
02184 
02185     /* error handling: test entries */
02186     if (image_in==NULL) return NULL ;
02187 
02188     /* Shifting by a zero offset returns a copy of the input image */
02189     if ((fabs(shift_x)<1e-2) && (fabs(shift_y)<1e-2))
02190       return cpl_image_duplicate(image_in) ;
02191     ilx=cpl_image_get_size_x(image_in);
02192     ily=cpl_image_get_size_y(image_in);
02193     pidata=cpl_image_get_data_float(image_in);
02194 
02195 
02196         /* See if a kernel needs to be generated */
02197     if (interp_kernel == NULL) {
02198         ker = sinfo_generate_interpolation_kernel("default") ;
02199         if (ker == NULL) {
02200             sinfo_msg_error("kernel generation failure:aborting resampling") ;
02201             return NULL ;
02202         }
02203     } else {
02204         ker = interp_kernel ;
02205         freeKernel = 0 ;
02206     }
02207 
02208     mid = (int)samples/(int)2 ;
02209     first_pass = cpl_calloc(ilx, ily*sizeof(pixelvalue)) ;
02210     shifted = cpl_image_new(ilx, ily,CPL_TYPE_FLOAT) ;
02211     psdata=cpl_image_get_data_float(shifted);
02212 
02213     second_pass = psdata ;
02214 
02215     pix = pidata ;
02216     if ( ilx != 1 )
02217     {
02218     for (j=0 ; j<ily ; j++)
02219         {
02220          for (i=0 ; i<ilx ; i++) {
02221            fx = (double)i-shift_x ;
02222            px = (int)fx ;
02223            rx = fx - (double)px ;
02224            pos = px + j * ilx ;
02225 
02226            if ((px>1) && (px<(ilx-2)))
02227            {
02228            tabx = (int)(fabs((double)mid * rx)) ;
02229            /* exclude blank (ZERO) pixels from interpolation */
02230            if (isnan(pix[pos]))
02231                {
02232                value = ZERO ;
02233                }
02234            else
02235                {
02236                if (isnan(pix[pos-1]))
02237                {
02238                pix[pos-1] = 0. ;
02239                }
02240                if (isnan(pix[pos+1]))
02241                {
02242                pix[pos+1] = 0. ;
02243                }
02244                if (isnan(pix[pos+2]))
02245                {
02246                pix[pos+2] = 0. ;
02247                }
02248 
02249                /*
02250             * Sum up over 4 closest pixel values,
02251             * weighted by interpolation kernel values
02252             */
02253                value =     (double)pix[pos-1] * ker[mid+tabx] +
02254                (double)pix[pos] * ker[tabx] +
02255                (double)pix[pos+1] * ker[mid-tabx] +
02256                (double)pix[pos+2] * ker[samples-tabx-1] ;
02257                /*
02258             * Also sum up interpolation kernel coefficients
02259             * for further normalization
02260             */
02261                norm =      (double)ker[mid+tabx] +
02262                (double)ker[tabx] +
02263                (double)ker[mid-tabx] +
02264                (double)ker[samples-tabx-1] ;
02265                if (fabs(norm) > 1e-4) {
02266                value /= norm ;
02267                }
02268                }
02269            } else {
02270            value = ZERO ;
02271            }
02272            /*
02273         * There may be a problem of rounding here if pixelvalue
02274         * has not enough bits to sustain the accuracy.
02275         */
02276            if ( isnan(value) )
02277            {
02278            first_pass[i+j*ilx] = ZERO ;
02279            }
02280            else
02281            {
02282            first_pass[i+j*ilx] = (pixelvalue)value ;
02283            }
02284          }
02285         }
02286     }
02287     else
02288     {
02289     memcpy(first_pass,pix,ily*sizeof(pixelvalue));
02290     }
02291 
02292     pixint = first_pass ;
02293     for (i=0 ; i<ilx ; i++) {
02294         for (j=0 ; j<ily ; j++) {
02295             fy = (double)j - shift_y ;
02296             py = (int)fy ;
02297             ry = fy - (double)py ;
02298             pos = i + py * ilx ;
02299 
02300             taby = (int)(fabs((double)mid * ry)) ;
02301 
02302             if ((py>(int)1) && (py<(ily-2))) {
02303                 /* exclude blank (ZERO) pixels from interpolation */
02304                 if (isnan(pixint[pos]) && ilx != 1 )
02305                 {
02306                     value = ZERO ;
02307                 }
02308                 else
02309                 {
02310                     if (isnan(pixint[pos-ilx]))
02311                     {
02312                         pixint[pos-ilx] = 0. ;
02313                     }
02314                     if (isnan(pixint[pos+ilx]))
02315                     {
02316                         pixint[pos+ilx] = 0. ;
02317                     }
02318                     if (isnan(pixint[pos+2*ilx]))
02319                     {
02320                         pixint[pos+2*ilx] = 0. ;
02321                     }
02322                     /*
02323                      * Sum up over 4 closest pixel values,
02324                      * weighted by interpolation kernel values
02325                      */
02326                     value = (double)pixint[pos-ilx] * ker[mid+taby] +
02327                             (double)pixint[pos] * ker[taby] +
02328                             (double)pixint[pos+ilx] * ker[mid-taby] +
02329                             (double)pixint[pos+2*ilx]*ker[samples-taby-1];
02330                     /*
02331                      * Also sum up interpolation kernel coefficients
02332                      * for further normalization
02333                      */
02334                     norm =      (double)ker[mid+taby] +
02335                                 (double)ker[taby] +
02336                                 (double)ker[mid-taby] +
02337                                 (double)ker[samples-taby-1] ;
02338 
02339                     if (fabs(norm) > 1e-4) {
02340                         value /= norm ;
02341                     }
02342                 }
02343             } else {
02344                 value = ZERO ;
02345             }
02346             if (isnan(value))
02347             {
02348                 second_pass[i+j*ilx] = ZERO ;
02349             }
02350             else
02351             {
02352                 second_pass[i+j*ilx] = (pixelvalue)value ;
02353             }
02354         }
02355     }
02356 
02357     cpl_free(first_pass) ;
02358     if (freeKernel)
02359         cpl_free(ker) ;
02360     return shifted ;
02361 }
02362 
02363 
02364 /*-------------------------------------------------------------------------*/
02395 /*--------------------------------------------------------------------------*/
02396 
02397 void
02398 sinfo_new_shift_image_in_cube(
02399     cpl_image     *   image_in,
02400     double           shift_x,
02401     double           shift_y,
02402     double       *   interp_kernel,
02403     cpl_image     *   shifted,
02404     pixelvalue   *   first_pass)
02405 {
02406     pixelvalue  *       second_pass=NULL ;
02407     int             samples = KERNEL_SAMPLES ;
02408     int          i=0, j=0 ;
02409     double           fx=0, fy=0 ;
02410     double           rx=0, ry=0 ;
02411     int             px=0, py=0 ;
02412     int             tabx=0, taby=0 ;
02413     double           value=0 ;
02414     size_t          pos ;
02415     register pixelvalue     *   pix ;
02416     register pixelvalue     *   pixint ;
02417     int             mid=0;
02418     double          norm=0 ;
02419     double       *      ker=NULL ;
02420     int                         freeKernel = 1 ;
02421 
02422     int ilx=0;
02423     int ily=0;
02424     int slx=0;
02425     int sly=0;
02426     float* pidata=NULL;
02427     float* psdata=NULL;
02428 
02429     /* error handling: test entries */
02430         if (image_in==NULL) shifted = NULL ;
02431         pidata=cpl_image_get_data_float(image_in);
02432         ilx=cpl_image_get_size_x(image_in);
02433         ily=cpl_image_get_size_y(image_in);
02434 
02435         shifted=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
02436         slx=ilx;
02437         sly=ily;
02438 
02439         psdata=cpl_image_get_data_float(shifted);
02440 
02441         /* Shifting by a zero offset returns a copy of the input image */
02442         if ((fabs(shift_x)<1e-2) && (fabs(shift_y)<1e-2))
02443                 memcpy(psdata,pidata, (size_t) slx*sly * sizeof(pixelvalue)) ;
02444 
02445         /* See if a kernel needs to be generated */
02446     if (interp_kernel == NULL) {
02447         ker = sinfo_generate_interpolation_kernel("default") ;
02448         if (ker == NULL) {
02449             sinfo_msg_error("kernel generation failure:aborting resampling") ;
02450             shifted = NULL ;
02451         }
02452     } else {
02453         ker = interp_kernel ;
02454         freeKernel = 0 ;
02455     }
02456 
02457     mid = (int)samples/(int)2 ;
02458     second_pass = psdata ;
02459 
02460     pix = pidata ;
02461     for (j=0 ; j<ily ; j++) {
02462         for (i=1 ; i<ilx-2 ; i++) {
02463             fx = (double)i-shift_x ;
02464             px = (int)fx ;
02465             rx = fx - (double)px ;
02466 
02467             pos = px + j * ilx ;
02468 
02469             if ((px>1) && (px<(ilx-2))) {
02470                 tabx = (int)(fabs((double)mid * rx)) ;
02471                 /* exclude blank (ZERO) pixels from interpolation */
02472                 if (isnan(pix[pos]))
02473                 {
02474                     value = ZERO ;
02475                 }
02476                 else
02477                 {
02478                     if (isnan(pix[pos-1]))
02479                     {
02480                         pix[pos-1] = 0. ;
02481                     }
02482                     if (isnan(pix[pos+1]))
02483                     {
02484                         pix[pos+1] = 0. ;
02485                     }
02486                     if (isnan(pix[pos+2]))
02487                     {
02488                         pix[pos+2] = 0. ;
02489                     }
02490 
02491                     /*
02492                      * Sum up over 4 closest pixel values,
02493                      * weighted by interpolation kernel values
02494                      */
02495                     value =     (double)pix[pos-1] * ker[mid+tabx] +
02496                                 (double)pix[pos] * ker[tabx] +
02497                                 (double)pix[pos+1] * ker[mid-tabx] +
02498                                 (double)pix[pos+2] * ker[samples-tabx-1] ;
02499                     /*
02500                      * Also sum up interpolation kernel coefficients
02501                      * for further normalization
02502                      */
02503                     norm =      (double)ker[mid+tabx] +
02504                                 (double)ker[tabx] +
02505                                 (double)ker[mid-tabx] +
02506                                 (double)ker[samples-tabx-1] ;
02507                     if (fabs(norm) > 1e-4) {
02508                         value /= norm ;
02509                     }
02510                 }
02511             } else {
02512                 value = 0.0 ;
02513             }
02514             /*
02515              * There may be a problem of rounding here if pixelvalue
02516              * has not enough bits to sustain the accuracy.
02517              */
02518             if ( isnan(value) )
02519             {
02520                 first_pass[i+j*ilx] = ZERO ;
02521             }
02522             else
02523             {
02524                 first_pass[i+j*ilx] = (pixelvalue)value ;
02525             }
02526         }
02527     }
02528     pixint = first_pass ;
02529     for (i=0 ; i< ilx ; i++) {
02530         for (j=1 ; j< ily-2 ; j++) {
02531             fy = (double)j - shift_y ;
02532             py = (int)fy ;
02533             ry = fy - (double)py ;
02534             pos = i + py * ilx ;
02535 
02536             taby = (int)(fabs((double)mid * ry)) ;
02537 
02538             if ((py>(int)1) && (py<(ily-2))) {
02539                 /* exclude blank (ZERO) pixels from interpolation */
02540                 if (isnan(pixint[pos]))
02541                 {
02542                     value = ZERO ;
02543                 }
02544                 else
02545                 {
02546                     if (isnan(pixint[pos-ilx]))
02547                     {
02548                         pixint[pos-ilx] = 0. ;
02549                     }
02550                     if (isnan(pixint[pos+ilx]))
02551                     {
02552                         pixint[pos+ilx] = 0. ;
02553                     }
02554                     if (isnan(pixint[pos+2*ilx]))
02555                     {
02556                         pixint[pos+2*ilx] = 0. ;
02557                     }
02558                     /*
02559                      * Sum up over 4 closest pixel values,
02560                      * weighted by interpolation kernel values
02561                      */
02562                     value = (double)pixint[pos-ilx] * ker[mid+taby] +
02563                             (double)pixint[pos] * ker[taby] +
02564                             (double)pixint[pos+ilx] * ker[mid-taby] +
02565                             (double)pixint[pos+2*ilx]*ker[samples-taby-1];
02566                     /*
02567                      * Also sum up interpolation kernel coefficients
02568                      * for further normalization
02569                      */
02570                     norm =      (double)ker[mid+taby] +
02571                                 (double)ker[taby] +
02572                                 (double)ker[mid-taby] +
02573                                 (double)ker[samples-taby-1] ;
02574 
02575                     if (fabs(norm) > 1e-4) {
02576                         value /= norm ;
02577                     }
02578                 }
02579             } else {
02580           /* value = 0.0 ; AMo: This affect slitlet #1 */
02581             }
02582             if (isnan(value))
02583             {
02584                 second_pass[i+j*ilx] = ZERO ;
02585             }
02586             else
02587             {
02588                 second_pass[i+j*ilx] = (pixelvalue)value ;
02589             }
02590         }
02591     }
02592 
02593     if (freeKernel)
02594         cpl_free(ker) ;
02595 }
02596 
02597 /* function to delete the image statistics within python */
02598 void sinfo_new_del_Stats( Stats * st)
02599 {
02600     cpl_free (st) ;
02601 }
02602 
02609 cpl_image *
02610 sinfo_new_combine_masks ( cpl_image * firstMask, cpl_image * secondMask )
02611 {
02612     cpl_image * retMask=NULL ;
02613     int n=0 ;
02614     int olx=0;
02615     int oly=0;
02616     float* podata=NULL;
02617     float* pm1data=NULL;
02618     float* pm2data=NULL;
02619 
02620     if ( firstMask == NULL || secondMask == NULL )
02621     {
02622         sinfo_msg_error ("no input mask image given!") ;
02623         return NULL ;
02624     }
02625     retMask = cpl_image_duplicate (firstMask) ;
02626     podata = cpl_image_get_data_float(retMask);
02627     pm1data = cpl_image_get_data_float(firstMask);
02628     pm2data = cpl_image_get_data_float(secondMask);
02629     olx=cpl_image_get_size_x(retMask);
02630     oly=cpl_image_get_size_y(retMask);
02631 
02632     for ( n = 0 ; n < (int) olx*oly ; n++ )
02633     {
02634        if ( podata[n] == 0. || pm2data[n] == 0. )
02635        {
02636            podata[n] = 0. ;
02637        }
02638        else
02639        {
02640            podata[n] = 1. ;
02641        }
02642     }
02643     return retMask ;
02644 }
02645 
02654 cpl_image * sinfo_new_slice_cube (cpl_imagelist * cube, int x, int y )
02655 {
02656     cpl_image * retImage=NULL ;
02657     int col=0, row=0, z=0 ;
02658     int inp=0;
02659     int ilx=0;
02660     int ily=0;
02661     cpl_image* img=NULL;
02662     float* podata=NULL;
02663     float* pidata=NULL;
02664 
02665     if ( cube == NULL )
02666     {
02667         sinfo_msg_error("no cube given!") ;
02668         return NULL ;
02669     }
02670     if ( x > 31 || y > 31 )
02671     {
02672         sinfo_msg_warning("wrong x or y values!") ;
02673     }
02674 
02675     img=cpl_imagelist_get(cube,0);
02676     ilx=cpl_image_get_size_x(img);
02677     ily=cpl_image_get_size_y(img);
02678     inp=cpl_imagelist_get_size(cube);
02679     if ( x < 0 )
02680     {
02681         /* allocate memory */
02682         if ( NULL == (retImage = cpl_image_new(ilx, inp, CPL_TYPE_FLOAT)) )
02683         {
02684             sinfo_msg_error("could not allocate memory!") ;
02685             return NULL ;
02686         }
02687         podata=cpl_image_get_data_float(retImage);
02688         for ( z = 0 ; z < inp ; z++ )
02689         {
02690 
02691             pidata=cpl_image_get_data_float(cpl_imagelist_get(cube,z));
02692             for ( col = 0 ; col < ilx ; col++ )
02693             {
02694                 podata[col+z*ilx] = pidata[col+y*ilx] ;
02695             }
02696         }
02697     }
02698     else if ( y < 0 )
02699     {
02700         /* allocate memory */
02701         if ( NULL == (retImage = cpl_image_new(ily, inp,CPL_TYPE_FLOAT)) )
02702         {
02703             sinfo_msg_error("could not allocate memory!") ;
02704             return NULL ;
02705         }
02706         podata=cpl_image_get_data_float(retImage);
02707 
02708         for ( z = 0 ; z < inp ; z++ )
02709         {
02710             pidata=cpl_image_get_data_float(cpl_imagelist_get(cube,z));
02711             for ( row = 0 ; row < ily ; row++ )
02712             {
02713                 podata[row+z*ily] = pidata[x+row*ily] ;
02714             }
02715         }
02716     }
02717     else
02718     {
02719         sinfo_msg_error("wrong input!") ;
02720         return NULL ;
02721     }
02722     return retImage ;
02723 }
02724 
02736 cpl_image * sinfo_new_div_images_robust ( cpl_image * im1, cpl_image * im2 )
02737 {
02738     cpl_image * retIm=NULL ;
02739     float help=0 ;
02740     int i=0 ;
02741     int lx1=0;
02742     int ly1=0;
02743     int lx2=0;
02744     int ly2=0;
02745 
02746     float* p1data=NULL;
02747     float* p2data=NULL;
02748     float* podata=NULL;
02749 
02750     if ( im1 == NULL || im2 == NULL )
02751     {
02752         sinfo_msg_error("no input images given!") ;
02753         return NULL ;
02754     }
02755     lx1=cpl_image_get_size_x(im1);
02756     ly1=cpl_image_get_size_y(im1);
02757     lx2=cpl_image_get_size_x(im2);
02758     ly2=cpl_image_get_size_y(im2);
02759     p1data=cpl_image_get_data_float(im1);
02760     p2data=cpl_image_get_data_float(im2);
02761 
02762     if ( lx1 != lx2 || ly1 != ly2 )
02763     {
02764         sinfo_msg_error("images not compatible!") ;
02765         return NULL ;
02766     }
02767     if ( NULL == (retIm = cpl_image_new(lx1, ly1, CPL_TYPE_FLOAT)) )
02768     {
02769         sinfo_msg_error("could not allocate memory!") ;
02770         return NULL ;
02771     }
02772     podata=cpl_image_get_data_float(retIm);
02773 
02774     for ( i = 0 ; i < (int) lx2*ly2 ; i++ )
02775     {
02776         if ( !isnan(p2data[i]) )
02777         {
02778             help = 1./p2data[i] ;
02779             if (fabs( help )> THRESH )
02780             {
02781                help = 1. ;
02782             }
02783         }
02784         else
02785         {
02786             help = ZERO ;
02787         }
02788         if ( isnan(help) || isnan(p1data[i]) )
02789         {
02790             podata[i] = ZERO ;
02791         }
02792         else
02793         {
02794             podata[i] = p1data[i] * help ;
02795         }
02796     }
02797     return retIm ;
02798 }
02799 
02800 cpl_image * sinfo_new_null_edges ( cpl_image * image)
02801 {
02802     cpl_image * new=NULL ;
02803     int i=0,j=0 ;
02804     int ilx=0;
02805     int ily=0;
02806     int olx=0;
02807     int oly=0;
02808 
02809     float* pidata=NULL;
02810     float* podata=NULL;
02811 
02812     if ( image == NULL )
02813     {
02814         sinfo_msg_error ("no input image given!\n") ;
02815         return NULL ;
02816     }
02817 
02818 
02819     new = cpl_image_duplicate (image) ;
02820     ilx=cpl_image_get_size_x(image);
02821     ily=cpl_image_get_size_y(image);
02822     olx=cpl_image_get_size_x(new);
02823     oly=cpl_image_get_size_y(new);
02824     pidata=cpl_image_get_data_float(image);
02825     podata=cpl_image_get_data_float(new);
02826 
02827     for ( i = 0 ; i < olx ; i++ )
02828     {
02829         for ( j = 0 ; j < 4 ; j++)
02830     {
02831         podata[i+j*olx]=0;
02832         podata[i+(oly-j-1)*olx]=0;
02833     }
02834     }
02835     for ( i = 0 ; i < oly ; i++ )
02836     {
02837         for ( j = 0 ; j < 4 ; j++)
02838     {
02839         podata[j+i*olx]=0;
02840         podata[(olx-j-1)+i*olx]=0;
02841     }
02842     }
02843     return new ;
02844 }
02845 
02846 
02847 void sinfo_new_used_cor_map( cpl_image *im, cpl_image *map)
02848 {
02849     int i=0,j=0,loc_index=0;
02850     float temp_array[2048];
02851     int lx=cpl_image_get_size_x(im);
02852     int ly=cpl_image_get_size_y(im);
02853     float* pidata=cpl_image_get_data_float(im);
02854     float* pmdata=cpl_image_get_data_float(map);
02855 
02856     for( j=0; j<ly; j++)
02857     {
02858     for( i=0;i<lx;i++)
02859         {
02860           loc_index = (int)pmdata[i+j*lx];
02861            temp_array[i] = pidata[loc_index+j*lx];
02862         }
02863     for( i=0;i<lx;i++)
02864         {
02865           pidata[i+j*lx]= temp_array[i];
02866         }
02867     }
02868 }
02869 
02870 
02871 
02872 
02873 /*-------------------------------------------------------------------------*/
02896 /*--------------------------------------------------------------------------*/
02897 
02898 cpl_image *
02899 sinfo_new_shift_image(
02900     cpl_image    *    image_in,
02901     double           shift_x,
02902     double           shift_y,
02903     double       *    interp_kernel)
02904 {
02905     cpl_image    *    shifted=NULL ;
02906     float  *    first_pass=NULL ;
02907     float  *    second_pass=NULL ;
02908     int             samples = KERNEL_SAMPLES ;
02909     int          i=0, j=0 ;
02910     double           fx=0, fy=0 ;
02911     double           rx=0, ry=0 ;
02912     int             px=0, py=0 ;
02913     int             tabx=0, taby=0 ;
02914     double           value=0 ;
02915     size_t          pos ;
02916     register float     *    pix=NULL ;
02917     register float     *    pixint=NULL ;
02918     int             mid=0;
02919     double          norm=0 ;
02920     double       *    ker=NULL ;
02921     int                freeKernel = 1 ;
02922     int ilx=0;
02923     int ily=0;
02924 
02925     /* error handling: test entries */
02926     if (image_in==NULL) return NULL ;
02927 
02928     /* Shifting by a zero offset returns a copy of the input image */
02929     if ((fabs(shift_x)<1e-2) && (fabs(shift_y)<1e-2))
02930         return cpl_image_duplicate(image_in) ;
02931 
02932     /* See if a kernel needs to be generated */
02933     if (interp_kernel == NULL) {
02934         ker = sinfo_generate_interpolation_kernel("default") ;
02935         if (ker == NULL) {
02936             sinfo_msg_error("kernel generation failure: aborting resampling") ;
02937             return NULL ;
02938         }
02939     } else {
02940         ker = interp_kernel ;
02941         freeKernel = 0 ;
02942     }
02943 
02944     ilx=cpl_image_get_size_x(image_in);
02945     ily=cpl_image_get_size_y(image_in);
02946 
02947 
02948     pix = cpl_image_get_data_float(image_in);
02949     if (pix)
02950     {
02951         mid = (int)samples/(int)2 ;
02952         first_pass = cpl_calloc(ilx, ily*sizeof(float)) ;
02953         shifted = cpl_image_new(ilx, ily,CPL_TYPE_FLOAT) ;
02954         second_pass = cpl_image_get_data_float(shifted);
02955         for (j=0 ; j<ily ; j++) {
02956             for (i=1 ; i<ilx-2 ; i++) {
02957                 fx = (double)i-shift_x ;
02958                 px = (int)fx ;
02959                 rx = fx - (double)px ;
02960 
02961                 pos = px + j * ilx ;
02962 
02963                 if ((px>1) && (px<(ilx-3))) {
02964                     tabx = (int)(fabs((double)mid * rx)) ;
02965                     /*
02966                      * Sum up over 4 closest pixel values,
02967                      * weighted by interpolation kernel values
02968                      */
02969                     value =     (double)pix[pos-1] * ker[mid+tabx] +
02970                                 (double)pix[pos] * ker[tabx] +
02971                                 (double)pix[pos+1] * ker[mid-tabx] +
02972                                 (double)pix[pos+2] * ker[samples-tabx-1] ;
02973                     /*
02974                      * Also sum up interpolation kernel coefficients
02975                      * for further normalization
02976                      */
02977                     norm =      (double)ker[mid+tabx] +
02978                                 (double)ker[tabx] +
02979                                 (double)ker[mid-tabx] +
02980                                 (double)ker[samples-tabx-1] ;
02981                     if (fabs(norm) > 1e-4) {
02982                         value /= norm ;
02983                     }
02984                 } else {
02985                     value = 0.0 ;
02986                 }
02987                 /*
02988                  * There may be a problem of rounding here if pixelvalue
02989                  * has not enough bits to sustain the accuracy.
02990                  */
02991                 first_pass[i+j*ilx] = (float)value ;
02992             }
02993         }
02994         pixint = first_pass ;
02995         for (i=0 ; i<ilx ; i++) {
02996             for (j=1 ; j<ily-3 ; j++) {
02997                 fy = (double)j - shift_y ;
02998                 py = (int)fy ;
02999                 ry = fy - (double)py ;
03000                 pos = i + py * ilx ;
03001 
03002                 taby = (int)(fabs((double)mid * ry)) ;
03003 
03004                 if ((py>(int)1) && (py<(ily-2))) {
03005                     /*
03006                      * Sum up over 4 closest pixel values,
03007                      * weighted by interpolation kernel values
03008                      */
03009                     value = (double)pixint[pos-ilx] * ker[mid+taby] +
03010                             (double)pixint[pos] * ker[taby] +
03011                             (double)pixint[pos+ilx] * ker[mid-taby] +
03012                             (double)pixint[pos+2*ilx]*ker[samples-taby-1];
03013                     /*
03014                      * Also sum up interpolation kernel coefficients
03015                      * for further normalization
03016                      */
03017                     norm =      (double)ker[mid+taby] +
03018                                 (double)ker[taby] +
03019                                 (double)ker[mid-taby] +
03020                                 (double)ker[samples-taby-1] ;
03021 
03022                     if (fabs(norm) > 1e-4) {
03023                         value /= norm ;
03024                     }
03025                 } else {
03026                     value = 0.0 ;
03027                 }
03028                 second_pass[i+j*ilx] = (float)value ;
03029             }
03030         }
03031     }
03032     else
03033     {
03034         cpl_msg_warning(cpl_func, "cannot get a data from an image");
03035     }
03036     cpl_free(first_pass) ;
03037     if (freeKernel)
03038         cpl_free(ker) ;
03039     return shifted ;
03040 }
03041 
03042 
03043 /*-------------------------------------------------------------------------*/
03057 /*--------------------------------------------------------------------------*/
03058 
03059 cpl_image *
03060 sinfo_image_hermite_interpol(cpl_image * inp)
03061 {
03062 
03063   /*
03064    @param xp     x-value to interpolate
03065    @param x      x-values
03066    @param y      y-values
03067    @param n      array length
03068    @param istart    (input/output) initial row (set to 0 to search all row)
03069 
03070   sinfo_spline_hermite( double xp, const double *x,
03071                         const double *y, int n, int *istart );
03072 
03073   */
03074   float* pinp=NULL;
03075   float* pout=NULL;
03076   int sx=0;
03077   int sy=0;
03078   int i=0;
03079   int j=0;
03080   int r=5;
03081   int k=0;
03082 
03083   cpl_image* out=NULL;
03084 
03085   cknull(inp,"Null in put image, exit");
03086   check_nomsg(out=cpl_image_duplicate(inp));
03087   check_nomsg(sx=cpl_image_get_size_x(inp));
03088   check_nomsg(sy=cpl_image_get_size_y(inp));
03089   check_nomsg(pinp=cpl_image_get_data_float(inp));
03090   check_nomsg(pout=cpl_image_get_data_float(out));
03091   for(j=r;j<sy-r;j++) {
03092     for(i=0;i<sx;i++) {
03093       for(k=-r;k<r;k++) {
03094     pout[j*sx+i]+=pinp[(j+k)*sx+i];
03095       }
03096       pout[j*sx+i]/=2*r;
03097     }
03098   }
03099 
03100  cleanup:
03101 
03102   if(cpl_error_get_code() != CPL_ERROR_NONE) {
03103     return NULL;
03104   } else {
03105     return out;
03106 
03107   }
03108 
03109 }
03110 
03111 
03112 
03113 /*-------------------------------------------------------------------------*/
03127 /*--------------------------------------------------------------------------*/
03128 
03129 cpl_image *
03130 sinfo_image_smooth_y(cpl_image * inp, const int r)
03131 {
03132 
03133   /*
03134    @param xp     x-value to interpolate
03135    @param x      x-values
03136    @param y      y-values
03137    @param n      array length
03138    @param istart    (input/output) initial row (set to 0 to search all row)
03139 
03140   */
03141   float* pinp=NULL;
03142   float* pout=NULL;
03143   int sx=0;
03144   int sy=0;
03145   int i=0;
03146   int j=0;
03147   int k=0;
03148 
03149   cpl_image* out=NULL;
03150 
03151   cknull(inp,"Null in put image, exit");
03152   check_nomsg(out=cpl_image_duplicate(inp));
03153   check_nomsg(sx=cpl_image_get_size_x(inp));
03154   check_nomsg(sy=cpl_image_get_size_y(inp));
03155   check_nomsg(pinp=cpl_image_get_data_float(inp));
03156   check_nomsg(pout=cpl_image_get_data_float(out));
03157   for(j=r;j<sy-r;j++) {
03158     for(i=0;i<sx;i++) {
03159       for(k=-r;k<r;k++) {
03160     pout[j*sx+i]+=pinp[(j+k)*sx+i];
03161       }
03162       pout[j*sx+i]/=2*r;
03163     }
03164   }
03165 
03166  cleanup:
03167 
03168   if(cpl_error_get_code() != CPL_ERROR_NONE) {
03169     return NULL;
03170   } else {
03171     return out;
03172 
03173   }
03174 
03175 }
03176 
03177 
03178 /*-------------------------------------------------------------------------*/
03192 /*--------------------------------------------------------------------------*/
03193 
03194 cpl_image *
03195 sinfo_image_smooth_mean_y(cpl_image * inp, const int r)
03196 {
03197 
03198   /*
03199    @param xp     x-value to interpolate
03200    @param x      x-values
03201    @param y      y-values
03202    @param n      array length
03203    @param istart    (input/output) initial row (set to 0 to search all row)
03204 
03205   */
03206   float* pinp=NULL;
03207   float* pout=NULL;
03208   int sx=0;
03209   int sy=0;
03210   int i=0;
03211   int j=0;
03212   int k=0;
03213 
03214   cpl_image* out=NULL;
03215 
03216   cknull(inp,"Null in put image, exit");
03217   check_nomsg(out=cpl_image_duplicate(inp));
03218   check_nomsg(sx=cpl_image_get_size_x(inp));
03219   check_nomsg(sy=cpl_image_get_size_y(inp));
03220   check_nomsg(pinp=cpl_image_get_data_float(inp));
03221   check_nomsg(pout=cpl_image_get_data_float(out));
03222   for(j=r;j<sy-r;j++) {
03223     for(i=0;i<sx;i++) {
03224       for(k=-r;k<r;k++) {
03225     pout[j*sx+i]+=pinp[(j+k)*sx+i];
03226       }
03227       pout[j*sx+i]/=2*r;
03228     }
03229   }
03230 
03231  cleanup:
03232 
03233   if(cpl_error_get_code() != CPL_ERROR_NONE) {
03234     return NULL;
03235   } else {
03236     return out;
03237 
03238   }
03239 
03240 }
03241 
03242 
03243 /*-------------------------------------------------------------------------*/
03257 /*--------------------------------------------------------------------------*/
03258 
03259 cpl_image *
03260 sinfo_image_smooth_median_y(cpl_image * inp, const int r)
03261 {
03262 
03263   /*
03264    @param xp     x-value to interpolate
03265    @param x      x-values
03266    @param y      y-values
03267    @param n      array length
03268    @param istart    (input/output) initial row (set to 0 to search all row)
03269 
03270   */
03271   float* pout=NULL;
03272   int sx=0;
03273   int sy=0;
03274   int i=0;
03275   int j=0;
03276 
03277   cpl_image* out=NULL;
03278 
03279 
03280   cknull(inp,"Null in put image, exit");
03281   check_nomsg(out=cpl_image_duplicate(inp));
03282   check_nomsg(sx=cpl_image_get_size_x(inp));
03283   check_nomsg(sy=cpl_image_get_size_y(inp));
03284   check_nomsg(pout=cpl_image_get_data_float(out));
03285 
03286   for(j=r+1;j<sy-r;j++) {
03287     for(i=1;i<sx;i++) {
03288       pout[j*sx+i]=(float)cpl_image_get_median_window(inp,i,j,i,j+r);
03289     }
03290   }
03291 
03292  cleanup:
03293 
03294   if(cpl_error_get_code() != CPL_ERROR_NONE) {
03295     return NULL;
03296   } else {
03297     return out;
03298 
03299   }
03300 
03301 }
03302 
03303 /*-------------------------------------------------------------------------*/
03316 /*--------------------------------------------------------------------------*/
03317 
03318 cpl_image *
03319 sinfo_image_smooth_fft(cpl_image * inp, const int fy)
03320 {
03321 
03322   int sx=0;
03323   int sy=0;
03324 
03325   cpl_image* out=NULL;
03326   cpl_image* im_re=NULL;
03327   cpl_image* im_im=NULL;
03328   cpl_image* ifft_re=NULL;
03329   cpl_image* ifft_im=NULL;
03330   cpl_image* filter=NULL;
03331 
03332   int sigma_x=0;
03333   int sigma_y=fy;
03334 
03335   cknull(inp,"Null in put image, exit");
03336   check_nomsg(im_re = cpl_image_cast(inp, CPL_TYPE_DOUBLE));
03337   check_nomsg(im_im = cpl_image_cast(inp, CPL_TYPE_DOUBLE));
03338 
03339   // Compute FFT
03340   check_nomsg(cpl_image_fft(im_re,im_im,CPL_FFT_DEFAULT));
03341 
03342   check_nomsg(sx=cpl_image_get_size_x(inp));
03343   check_nomsg(sy=cpl_image_get_size_y(inp));
03344   sigma_x=sx;
03345 
03346   //Generates filter image
03347   check_nomsg(filter = sinfo_gen_lowpass(sx,sy,sigma_x,sigma_y));
03348 
03349   //Apply filter
03350   cpl_image_multiply(im_re,filter);
03351   cpl_image_multiply(im_im,filter);
03352 
03353   sinfo_free_image(&filter);
03354 
03355   check_nomsg(ifft_re = cpl_image_duplicate(im_re));
03356   check_nomsg(ifft_im = cpl_image_duplicate(im_im));
03357 
03358   sinfo_free_image(&im_re);
03359   sinfo_free_image(&im_im);
03360 
03361   //Computes FFT-INVERSE
03362   check_nomsg(cpl_image_fft(ifft_re,ifft_im,CPL_FFT_INVERSE));
03363   check_nomsg(out = cpl_image_cast(ifft_re, CPL_TYPE_FLOAT));
03364 
03365  cleanup:
03366 
03367   sinfo_free_image(&ifft_re);
03368   sinfo_free_image(&ifft_im);
03369   sinfo_free_image(&filter);
03370   sinfo_free_image(&im_re);
03371   sinfo_free_image(&im_im);
03372 
03373   if(cpl_error_get_code() != CPL_ERROR_NONE) {
03374     return NULL;
03375   } else {
03376     return out;
03377   }
03378 
03379 }
03380 
03381 
03382 
03383 /*-------------------------------------------------------------------------*/
03399 /*--------------------------------------------------------------------------*/
03400 static cpl_image *
03401 sinfo_gen_lowpass(const int xs,
03402                   const int ys,
03403                   const double sigma_x,
03404                   const double sigma_y)
03405 {
03406 
03407     int i= 0.0;
03408     int j= 0.0;
03409     int hlx= 0.0;
03410     int hly = 0.0;
03411     double x= 0.0;
03412     double y= 0.0;
03413     double gaussval= 0.0;
03414     double inv_sigma_x=1./sigma_x;
03415     double inv_sigma_y=1./sigma_y;
03416 
03417     float *data;
03418 
03419     cpl_image   *lowpass_image=NULL;
03420 
03421 
03422     lowpass_image = cpl_image_new (xs, ys, CPL_TYPE_FLOAT);
03423     if (lowpass_image == NULL) {
03424         sinfo_msg_error("Cannot generate lowpass filter <%s>",
03425                         cpl_error_get_message());
03426         return NULL;
03427     }
03428 
03429     hlx = xs/2;
03430     hly = ys/2;
03431 
03432     data = cpl_image_get_data_float(lowpass_image);
03433 
03434 /* Given an image with pixels 0<=i<N, 0<=j<M then the convolution image
03435    has the following properties:
03436 
03437    ima[0][0] = 1
03438    ima[i][0] = ima[N-i][0] = exp (-0.5 * (i/sig_i)^2)   1<=i<N/2
03439    ima[0][j] = ima[0][M-j] = exp (-0.5 * (j/sig_j)^2)   1<=j<M/2
03440    ima[i][j] = ima[N-i][j] = ima[i][M-j] = ima[N-i][M-j]
03441              = exp (-0.5 * ((i/sig_i)^2 + (j/sig_j)^2))
03442 */
03443 
03444     data[0] = 1.0;
03445 
03446     /* first row */
03447     for (i=1 ; i<=hlx ; i++) {
03448         x = i * inv_sigma_x;
03449         gaussval = exp(-0.5*x*x);
03450         data[i] = gaussval;
03451         data[xs-i] = gaussval;
03452     }
03453 
03454     for (j=1; j<=hly ; j++) {
03455         y = j * inv_sigma_y;
03456       /* first column */
03457         data[j*xs] = exp(-0.5*y*y);
03458         data[(ys-j)*xs] = exp(-0.5*y*y);
03459 
03460         for (i=1 ; i<=hlx ; i++) {
03461     /* Use internal symetries */
03462             x = i * inv_sigma_x;
03463             gaussval = exp (-0.5*(x*x+y*y));
03464             data[j*xs+i] = gaussval;
03465             data[(j+1)*xs-i] = gaussval;
03466             data[(ys-j)*xs+i] = gaussval;
03467             data[(ys+1-j)*xs-i] = gaussval;
03468 
03469         }
03470     }
03471 
03472     /* FIXME: for the moment, reset errno which is coming from exp()
03473             in first for-loop at i=348. This is causing cfitsio to
03474             fail when loading an extension image (bug in cfitsio too).
03475     */
03476     if(errno != 0)
03477         errno = 0;
03478 
03479     return lowpass_image;
03480 }
03481 
03482 static void quicksort_int(int* data, int left, int right)
03483 {
03484     int i = left;
03485     int j = right;
03486     int pivot = (i + j) / 2;
03487     double index_value = data[pivot];
03488     do
03489     {
03490         while(data[i] < index_value) i++;
03491         while(data[j] > index_value) j--;
03492         if (i <= j)
03493         {
03494             if(i < j)
03495             {
03496                 int tmp = data[i];
03497                 data[i]=data[j];
03498                 data[j]=tmp;
03499             }
03500             i++;
03501             j--;
03502         }
03503     } while (i <= j);
03504 
03505     if (i < right)
03506     {
03507         quicksort_int(data, i, right);
03508     }
03509     if (left < j)
03510     {
03511         quicksort_int(data, left, j);
03512     }
03513 }
03514 
03515 /*--------------------------------------------------------------------------*/

Generated on 3 Mar 2013 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1