sinfo_new_cube_ops.c

00001 /*$Id: sinfo_new_cube_ops.c,v 1.45 2012/09/21 10:55:38 amodigli Exp $
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 * E.S.O. - VLT project
00021 *
00022 *
00023 *
00024 * who       when      what
00025 * --------  --------  ----------------------------------------------
00026 * schreib  17/05/00  created
00027 */
00028 /*
00029  * $Author: amodigli $
00030  * $Date: 2012/09/21 10:55:38 $
00031  * $Revision: 1.45 $
00032  * $Name: HEAD $
00033  */
00034 
00035 /************************************************************************
00036 *   NAME
00037 *       sinfo_new_cube_ops.c -
00038 *       cube arithmetic routines
00039 *
00040 *   SYNOPSIS
00041 *    #include "sinfo_new_cube_ops.h"
00042 *
00043 *
00044 *
00045 *    2) cpl_imagelist *
00046 *       sinfo_new_cube_ops( cpl_imagelist    *    cube1,
00047 *                cpl_imagelist    *    cube2,
00048 *                int        operation)
00049 *
00050 *    3) cpl_imagelist *
00051 *       sinfo_new_cube_const_ops(
00052 *                     cpl_imagelist    * cube1,
00053 *                     double    constant,
00054 *                     int        operation)
00055 *
00056 *    4) cpl_imagelist *
00057 *       sinfo_new_cube_sub(
00058 *               cpl_imagelist    *    c1,
00059 *               cpl_imagelist    *    c2 )
00060 *
00061 *    5) cpl_imagelist *
00062 *       sinfo_new_cube_add(
00063 *               cpl_imagelist    *    c1,
00064 *               cpl_imagelist    *    c2  )
00065 *    6) cpl_imagelist *
00066 *       sinfo_new_cube_mul(
00067 *               cpl_imagelist    *    c1,
00068 *               cpl_imagelist    *    c2 )
00069 *
00070 *    7) cpl_imagelist *
00071 *       sinfo_new_cube_div(
00072 *               cpl_imagelist    *    c1,
00073 *               cpl_imagelist    *    c2 )
00074 *
00075 *    8) cpl_imagelist * sinfo_new_add_image_to_cube(cpl_imagelist * cu,
00076                                                     cpl_image * im)
00077 *
00078 *    9) cpl_imagelist * sinfo_new_sub_image_from_cube (cpl_imagelist * cu,
00079                                                     cpl_image * im)
00080 *
00081 *    10) cpl_imagelist * sinfo_new_mul_image_to_cube(cpl_imagelist * cu,
00082                                                     cpl_image * im)
00083 *
00084 *    11) cpl_imagelist * sinfo_new_div_cube_by_image(cpl_imagelist * cu,
00085                                                     cpl_image * im)
00086 *
00087 *    12) cpl_imagelist * sinfo_new_add_spectrum_to_cube(cpl_imagelist *cu,
00088                                                     Vector *spec)
00089 *
00090 *    13) cpl_imagelist * sinfo_new_sub_spectrum_from_cube(cpl_imagelist *cu,
00091                                                     Vector *spec)
00092 *
00093 *    14) cpl_imagelist * sinfo_new_mul_spectrum_to_cube(cpl_imagelist *cu,
00094                                                     Vector *spec)
00095 *
00096 *    15) cpl_imagelist * sinfo_new_div_cube_by_spectrum(cpl_imagelist *cu,
00097                                                     Vector *spec)
00098 *
00099 *    16) Vector * sinfo_new_clean_mean_of_spectra(cpl_imagelist * cube,
00100 *                                    int llx,
00101 *                                    int lly,
00102 *                                    int urx,
00103 *                                    int ury,
00104 *                                    double lo_reject,
00105 *                                    double hi_reject)
00106 *
00107 *    17) cpl_image * sinfo_new_median_cube(cpl_imagelist * cube)
00108 *
00109 *    18) cpl_image * sinfo_new_average_cube_to_image(cpl_imagelist * cube)
00110 *
00111 *    19) cpl_image * sinfo_new_sum_cube_to_image(cpl_imagelist * cube)
00112 *
00113 *    20) cpl_image *
00114          sinfo_new_average_cube_to_image_between_waves (cpl_imagelist * cube,
00115 *                                                   float     dispersion,
00116 *                                                   float     centralWave,
00117 *                                                   float     initialLambda,
00118 *                                                   float     finalLambda)
00119 *
00120 *    21) cpl_image * sinfo_new_extract_image_from_cube(cpl_imagelist * cube,
00121                                                     int plane_index)
00122 *
00123 *    22) Vector * sinfo_new_extract_spectrum_from_cube( cpl_imagelist * cube,
00124                                                     int x_pos, int y_pos )
00125 *    23) cpl_imagelist *
00126          sinfo_new_combine_jittered_cubes ( cpl_imagelist ** cubes,
00127 *                                         cpl_imagelist  * mergedCube,
00128 *                                         int        n_cubes,
00129 *                                         float    * cumoffsetx,
00130 *                                         float    * cumoffsety,
00131 *                                         float    * exptimes,
00132 *                                         char     * kernel_type )
00133 *    24) cpl_imagelist * sinfo_new_interpol_cube_simple( cpl_imagelist * cube,
00134 *                                      cpl_imagelist * badcube,
00135 *                                      int       maxdist )
00136 *
00137 *
00138 *    25) cpl_imagelist * sinfo_cube_zshift(const cpl_imagelist * cube,
00139 *                                          const double shift,
00140 *                                          double* rest)
00141 *
00142 *    26) cpl_imagelist * sinfo_cube_zshift_poly(const cpl_imagelist * cube,
00143 *                                               const double shift,
00144 *                                               const int    order)
00145 *
00146 *    27) cpl_imagelist * sinfo_cube_zshift_spline3(const cpl_imagelist * cube,
00147 *                                                  const double shift)
00148 *
00149 *
00150 *
00151 *
00152 *   DESCRIPTION
00153 *    2) 4 operations between 2 cubes
00154 *    3) 4 operations between a cube and a constant
00155 *    4)    subtract one cube from another
00156 *    5) add a cube to another
00157 *    6) multiply two cubes
00158 *    7) divide two cubes
00159 *    8) add an image to all planes in the cube
00160 *    9) subtract an image from all planes in the cube
00161 *    10) multiply an image to all planes in the cube
00162 *    11) divide all planes in the cube by an image
00163 *    12) adds a spectrum (in z-direction) to all data
00164 *                        points in a cube
00165 *    13) subtracts a spectrum (in z-direction) from all
00166 *                        data points in a cube
00167 *    14) multiplies a spectrum (in z-direction) to all data
00168 *                        points in a cube
00169 *    15) divides all data points of a cube by a spectrum
00170 *                        (in z-direction)
00171 *    16) averaging routine to get a better spectral S/N, sorts
00172 *        the values of the same z-position, cuts the lowest and
00173 *        highest values according to given thresholds and then
00174 *        takes the average within the x-y plane , cannot have
00175 *        a sum of low and high rejected values greater than 90%
00176 *        of all values
00177 *    17) determines the sinfo_new_median value in every pixel position
00178 *        by considering all pixels along the third axis.
00179 *        ZERO pixels in a plane are not considered. If all
00180 *        pixels at a position are not valid the result will
00181 *        be 'ZERO'.
00182 *    18) determines the average value in every pixel position
00183 *        by considering all pixels along the third axis.
00184 *        ZERO pixels in a plane are not considered. If all
00185 *        pixels at a position are not valid the result will
00186 *        be 'ZERO'.
00187 *    19) determines the sum value in every pixel position
00188 *        by considering all pixels along the third axis.
00189 *        ZERO pixels in a plane are not considered. If all
00190 *        pixels at a position are not valid the result will
00191 *        be 'ZERO'.
00192 *    20) determines the average value in every pixel position
00193 *        by considering only the pixels along the third axis
00194 *        which lie between the given wavelength values.
00195 *        These values are first recalculated to plane indices
00196 *        by using the given dispersion and minimum wavelength in
00197 *        the cube.
00198 *        ZERO pixels in a plane are not considered. If all
00199 *        pixels at a position are not valid the result will
00200 *        be 'ZERO'.
00201 *    21) returns the wanted image plane of the cube
00202 *    22) returns the wanted single spectrum of the cube
00203 *    23) merges jittered data cubes to one bigger cube
00204 *        by averaging the overlap regions weighted by
00205 *        the integration times. The x, y size of the final data
00206 *        cube is user given, and should be between 32 and 64
00207 *        pixels, while the relative pixel-offset (sub-pixel
00208 *        accuracy) of the single cubes with respect to the
00209 *        first cube in the list is read from the SEQ CUMOFFSETX,Y
00210 *        fits header keyword.
00211 *   24)  interpolates bad pixel of an object cube if a bad pixel
00212 *        mask cube is available by using the nearest neighbors
00213 *        in 3 dimensions.
00214 *
00215 *   25)  shifts an imagelist by a given amount to integer pixel accuracy
00216 *   26)  shifts an imagelist by a given amount to sub-pixel accuracy
00217 *   27)  shifts an imagelist by a given amount to sub-pixel accuracy
00218 *   FILES
00219 *
00220 *   ENVIRONMENT
00221 *
00222 *   RETURN VALUES
00223 *
00224 *   CAUTIONS
00225 *
00226 *   EXAMPLES
00227 *
00228 *   SEE ALSO
00229 *
00230 *   BUGS
00231 *
00232 *------------------------------------------------------------------------
00233 */
00234 #ifdef HAVE_CONFIG_H
00235 #  include <config.h>
00236 #endif
00237 
00238 #include "sinfo_vltPort.h"
00239 
00240 /*
00241  * System Headers
00242  */
00243 
00244 #include <sys/types.h>
00245 #include <sys/times.h>
00246 #include <math.h>
00247 /*
00248  * Local Headers
00249  */
00250 #include "sinfo_dfs.h"
00251 #include "sinfo_new_cube_ops.h"
00252 #include "sinfo_resampling.h"
00253 #include "sinfo_function_1d.h"
00254 #include "sinfo_error.h"
00255 #include "sinfo_globals.h"
00256 #include "sinfo_utils_wrappers.h"
00257 
00258 #include <cpl_vector.h>
00259 /*----------------------------------------------------------------------------
00260  *                            Function codes
00261  *--------------------------------------------------------------------------*/
00262 
00263 
00264 static int
00265 sinfo_shift_cubes(cpl_imagelist** tmpcubes,
00266                   char* kernel_type,
00267                   const int n_cubes,
00268                   cpl_imagelist** cubes,
00269                   const int z_min,
00270                   const int z_max,
00271                   float* sub_offsetx,
00272                   float* sub_offsety,
00273                   const int mlx,
00274                   const int mly,
00275                   cpl_imagelist* mask);
00276 
00277 static int
00278 sinfo_build_mask_cube(const int z_min,
00279                       const int z_max,
00280                       const int olx,
00281                       const int oly,
00282                       const int n_cubes,
00283                       const int* llx,
00284                       const int* lly,
00285               double    * exptimes,
00286                       cpl_imagelist** cubes,
00287                       cpl_imagelist** tmpcubes,
00288                       cpl_imagelist* mask);
00289 
00290 static int
00291 sinfo_build_mask_cube_thomas(const int z_min,
00292                              const int z_max,
00293                              const int olx,
00294                              const int oly,
00295                              const int n_cubes,
00296                              const int* llx,
00297                              const int* lly,
00298                      double    * exptimes,
00299                              cpl_imagelist** cubes,
00300                              cpl_imagelist** tmpcubes,
00301                  cpl_imagelist* mask);
00302 static int
00303 sinfo_compute_weight_average(const int z_min,
00304                              const int z_max,
00305                              const int ilx,
00306                              const int ily,
00307                  const int n_cubes,
00308                              cpl_imagelist* mergedCube,
00309                              cpl_imagelist* mask,
00310                              cpl_imagelist** tmpcubes,
00311                  double* exptimes,
00312                              int* llx,
00313                              int* lly);
00314 
00315 static int
00316 sinfo_check_input(cpl_imagelist** cubes,
00317                           const int n_cubes,
00318                           float* cumoffsetx,
00319                           float* cumoffsety,
00320               double* exptimes);
00321 static int
00322 sinfo_coadd_with_ks_clip2(const int z_min,
00323             const int z_max,
00324             const int ilx,
00325             const int ily,
00326             const int n_cubes,
00327             const double kappa,
00328             int* llx,
00329             int* lly,
00330                         double* exptimes,
00331             cpl_imagelist* mask,
00332             cpl_imagelist* mergedCube,
00333                           cpl_imagelist** tmpcubes);
00334 
00335 
00336 /* temporally commented out as not yet used
00337 static int
00338 sinfo_ks_clip(
00339           const int n_cubes,
00340               const int nc,
00341           const int ilx,
00342           const int ily,
00343           const double kappa,
00344           int* llx,
00345           int* lly,
00346           double* exptimes,
00347           cpl_imagelist** tmpcubes,
00348               float* podata,
00349               float* pmdata,
00350           const int x,
00351           const int y,
00352           const int m,
00353           const int mlx,
00354           const int olx
00355           );
00356 
00357 
00358 */
00359 
00360 static int
00361 sinfo_coadd_with_ks_clip(const int z_min,
00362             const int z_max,
00363             const int ilx,
00364             const int ily,
00365             const int n_cubes,
00366             const double kappa,
00367             int* llx,
00368             int* lly,
00369                         double* exptimes,
00370             cpl_imagelist* mask,
00371             cpl_imagelist* mergedCube,
00372                         cpl_imagelist** tmpcubes);
00373 
00374 
00399 cpl_imagelist *
00400 sinfo_new_cube_ops(
00401     cpl_imagelist    *    cube1,
00402     cpl_imagelist    *    cube2,
00403     int        operation)
00404 {
00405 
00406     if (cube1==NULL || cube2==NULL)
00407     {
00408         sinfo_msg_error("null cubes");
00409         return NULL ;
00410     }
00411 
00412     switch(operation)
00413     {
00414     case '+':
00415     return sinfo_new_cube_add(cube1, cube2) ;
00416 
00417     case '-':
00418     return sinfo_new_cube_sub(cube1, cube2) ;
00419 
00420 
00421     case '*':
00422     return sinfo_new_cube_mul(cube1, cube2) ;
00423 
00424 
00425     case '/':
00426     return sinfo_new_cube_div(cube1, cube2) ;
00427 
00428 
00429     default:
00430     sinfo_msg_error("illegal requested operation: aborting cube arithmetic") ;
00431     return NULL ;
00432     }
00433 }
00434 
00435 
00436 /*----------------------------------------------------------------------------
00437    Function    :    sinfo_new_cube_const_ops()
00438    In         :    1 cube, 1 constant, operation to perform
00439    Out         :    result cube
00440    Job        :    4 operations between a cube and a constant
00441    Notice    :    possible operations are:
00442                   Addition    '+'
00443                   Subtraction     '-'
00444                   Multiplication    '*'
00445                   Division    '/'
00446                   Logarithm    'l'
00447                   Power        '^'
00448                   Exponentiation    'e'
00449 
00450  ---------------------------------------------------------------------------*/
00451 
00452 cpl_imagelist *
00453 sinfo_new_cube_const_ops(
00454     cpl_imagelist    *    c1,
00455     double        constant,
00456     int        operation)
00457 {
00458     int ilx1=0;
00459     int ily1=0;
00460     int inp1=0;
00461     cpl_imagelist* c2=NULL;
00462     cpl_image* img1=NULL;
00463 
00464 
00465 
00466     if (c1 == NULL)
00467     {
00468          sinfo_msg_error("null cube") ;
00469          return NULL ;
00470     }
00471     inp1=cpl_imagelist_get_size(c1);
00472     img1=cpl_imagelist_get(c1,0);
00473     ilx1=cpl_image_get_size_x(img1);
00474     ily1=cpl_image_get_size_y(img1);
00475 
00476 
00477 
00478 
00479 
00480     if ((constant == 0.0) && (operation == '/'))
00481     {
00482         sinfo_msg_error("division by zero requested "
00483                         "in cube/constant operation") ;
00484         return NULL ;
00485     }
00486 
00487     if ( NULL == (c2 = cpl_imagelist_new()) )
00488     {
00489         sinfo_msg_error ("cannot allocate new cube" ) ;
00490         return NULL ;
00491     }
00492 
00493     c2=cpl_imagelist_duplicate(c1);
00494     if(operation == '+') {
00495       cpl_imagelist_add_scalar(c2,constant);
00496     } else if (operation == '-') {
00497       cpl_imagelist_subtract_scalar(c2,constant);
00498     } else if (operation == '*') {
00499       cpl_imagelist_multiply_scalar(c2,constant);
00500     } else if (operation == '/') {
00501       cpl_imagelist_divide_scalar(c2,constant);
00502 
00503     } else {
00504       sinfo_msg_error("operation not supported");
00505       return NULL;
00506     }
00507     return c2 ;
00508 }
00509 
00510 
00511 /*----------------------------------------------------------------------------
00512  * Function    :    sinfo_new_cube_sub()
00513  * In         :    two cubes
00514  * Out         :    result cube
00515  * Job        :    subtract one cube from another
00516  *--------------------------------------------------------------------------*/
00517 
00518 cpl_imagelist *
00519 sinfo_new_cube_sub(
00520     cpl_imagelist    *    c1,
00521     cpl_imagelist    *    c2
00522 )
00523 {
00524     cpl_imagelist   *                 c3 ;
00525     ulong32            i ;
00526     int                     np ;
00527     int ilx1=0;
00528     int ily1=0;
00529     int inp1=0;
00530     int ilx2=0;
00531     int ily2=0;
00532     int inp2=0;
00533 
00534 
00535     cpl_image* i_img=NULL;
00536     cpl_image* img1=NULL;
00537     cpl_image* img2=NULL;
00538     cpl_image* img3=NULL;
00539     float* p1data=NULL;
00540     float* p2data=NULL;
00541     float* p3data=NULL;
00542 
00543 
00544 
00545     inp1=cpl_imagelist_get_size(c1);
00546     i_img=cpl_imagelist_get(c1,0);
00547     ilx1=cpl_image_get_size_x(i_img);
00548     ily1=cpl_image_get_size_y(i_img);
00549 
00550 
00551     inp2=cpl_imagelist_get_size(c2);
00552     i_img=cpl_imagelist_get(c2,0);
00553     ilx2=cpl_image_get_size_x(i_img);
00554     ily2=cpl_image_get_size_y(i_img);
00555 
00556     if ((ilx1 != ilx2) ||
00557     (ily1 != ily2))
00558     {
00559     sinfo_msg_error("incompatible size: cannot subtract") ;
00560     return NULL ;
00561     }
00562 
00563     if ((inp2 != inp1) &&
00564     (inp2 != 1))
00565     {
00566     sinfo_msg_error("cannot compute with these number of planes") ;
00567     return NULL ;
00568     }
00569 
00570     if ( NULL == (c3 = cpl_imagelist_new()) )
00571     {
00572         sinfo_msg_error ("cannot allocate new cube" ) ;
00573         return NULL ;
00574     }
00575 
00576     for (np=0 ; np < inp1 ; np++)
00577     {
00578       img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
00579       cpl_imagelist_set(c3,img3,np);
00580     }
00581 
00582 
00583     for (np=0 ; np < inp1 ; np++)
00584     {
00585       img1=cpl_imagelist_get(c1,np);
00586       p1data=cpl_image_get_data_float(img1);
00587       img2=cpl_imagelist_get(c2,np);
00588       p2data=cpl_image_get_data_float(img2);
00589       img3=cpl_imagelist_get(c3,np);
00590       p3data=cpl_image_get_data_float(img3);
00591 
00592         for (i=0 ; i< (ulong32)ilx1*ily1 ; i++)
00593         {
00594             p3data[i] = p1data[i] - p2data[i] ;
00595     }
00596     }
00597 
00598     return c3 ;
00599 }
00600 
00601 
00602 /*----------------------------------------------------------------------------
00603  * Function    :    sinfo_new_cube_add()
00604  * In         :    two cubes
00605  * Out         :    result cube
00606  * Job        :    add a cube to another
00607  *--------------------------------------------------------------------------*/
00608 
00609 cpl_imagelist *
00610 sinfo_new_cube_add(
00611     cpl_imagelist    *    c1,
00612     cpl_imagelist    *    c2
00613 )
00614 {
00615     cpl_imagelist  *          c3 ;
00616     ulong32        i ;
00617     int         np ;
00618     int ilx1=0;
00619     int ily1=0;
00620     int inp1=0;
00621     int ilx2=0;
00622     int ily2=0;
00623     int inp2=0;
00624 
00625 
00626     cpl_image* i_img=NULL;
00627     cpl_image* img1=NULL;
00628     cpl_image* img2=NULL;
00629     cpl_image* img3=NULL;
00630     float* p1data=NULL;
00631     float* p2data=NULL;
00632     float* p3data=NULL;
00633 
00634 
00635 
00636     inp1=cpl_imagelist_get_size(c1);
00637     i_img=cpl_imagelist_get(c1,0);
00638     ilx1=cpl_image_get_size_x(i_img);
00639     ily1=cpl_image_get_size_y(i_img);
00640 
00641 
00642     inp2=cpl_imagelist_get_size(c2);
00643     i_img=cpl_imagelist_get(c2,0);
00644     ilx2=cpl_image_get_size_x(i_img);
00645     ily2=cpl_image_get_size_y(i_img);
00646     if ((ilx1 != ilx2) || (ily1 != ily2))
00647     {
00648     sinfo_msg_error("incompatible size: cannot add") ;
00649     return NULL ;
00650     }
00651     if ((inp2 != inp1) && (inp2 != 1))
00652     {
00653     sinfo_msg_error("cannot compute with these number of planes") ;
00654     return NULL ;
00655     }
00656 
00657     if (NULL == (c3 = cpl_imagelist_new()) )
00658     {
00659         sinfo_msg_error ("cannot allocate new cube") ;
00660         return NULL ;
00661     }
00662 
00663     for (np=0 ; np < inp1 ; np++)
00664     {
00665       img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
00666       cpl_imagelist_set(c3,img3,np);
00667     }
00668 
00669     for (np=0 ; np < inp1 ; np++)
00670     {
00671       img1=cpl_imagelist_get(c1,np);
00672       p1data=cpl_image_get_data_float(img1);
00673       img2=cpl_imagelist_get(c2,np);
00674       p2data=cpl_image_get_data_float(img2);
00675       img3=cpl_imagelist_get(c3,np);
00676       p3data=cpl_image_get_data_float(img3);
00677         for (i=0 ; i< (ulong32)ilx1*ily1 ; i++)
00678         {
00679         p3data[i] = p1data[i] + p2data[i] ;
00680         }
00681     }
00682 
00683     return c3 ;
00684 }
00685 
00686 /*----------------------------------------------------------------------------
00687  * Function    :    sinfo_new_cube_mul()
00688  * In         :    two cubes
00689  * Out         :    result cube
00690  * Job        :    multiply 2 cubes
00691  *--------------------------------------------------------------------------*/
00692 
00693 cpl_imagelist *
00694 sinfo_new_cube_mul(
00695     cpl_imagelist    *    c1,
00696     cpl_imagelist    *    c2
00697 )
00698 {
00699     cpl_imagelist             *c3 ;
00700     ulong32        i ;
00701     int                np ;
00702     int ilx1=0;
00703     int ily1=0;
00704     int inp1=0;
00705     int ilx2=0;
00706     int ily2=0;
00707     int inp2=0;
00708 
00709 
00710     cpl_image* i_img=NULL;
00711     cpl_image* img1=NULL;
00712     cpl_image* img2=NULL;
00713     cpl_image* img3=NULL;
00714     float* p1data=NULL;
00715     float* p2data=NULL;
00716     float* p3data=NULL;
00717 
00718 
00719 
00720 
00721     inp1=cpl_imagelist_get_size(c1);
00722     i_img=cpl_imagelist_get(c1,0);
00723     ilx1=cpl_image_get_size_x(i_img);
00724     ily1=cpl_image_get_size_y(i_img);
00725 
00726 
00727     inp2=cpl_imagelist_get_size(c2);
00728     i_img=cpl_imagelist_get(c2,0);
00729     ilx2=cpl_image_get_size_x(i_img);
00730     ily2=cpl_image_get_size_y(i_img);
00731 
00732     if ((ilx1 != ilx2) || (ily1 != ily2))
00733     {
00734     sinfo_msg_error("incompatible size: cannot multiply") ;
00735     return NULL ;
00736     }
00737 
00738     if ((inp2 != inp1) && (inp2 != 1))
00739     {
00740     sinfo_msg_error("cannot compute with these number of planes") ;
00741     return NULL ;
00742     }
00743 
00744     if ( NULL == (c3 = cpl_imagelist_new()) )
00745     {
00746         sinfo_msg_error ("cannot allocate new cube" ) ;
00747         return NULL ;
00748     }
00749 
00750 
00751     for (np=0 ; np < inp1 ; np++)
00752     {
00753       img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
00754       cpl_imagelist_set(c3,img3,np);
00755     }
00756 
00757     for (np=0 ; np < inp1 ; np++)
00758     {
00759       img1=cpl_imagelist_get(c1,np);
00760       p1data=cpl_image_get_data_float(img1);
00761       img2=cpl_imagelist_get(c2,np);
00762       p2data=cpl_image_get_data_float(img2);
00763       img3=cpl_imagelist_get(c3,np);
00764       p3data=cpl_image_get_data_float(img3);
00765         for (i=0 ; i< (ulong32)ilx1*ilx2 ; i++)
00766         {
00767             p3data[i] = p1data[i] * p2data[i] ;
00768         }
00769     }
00770 
00771     return c3 ;
00772 }
00773 
00774 
00775 /*----------------------------------------------------------------------------
00776  * Function    :    sinfo_new_cube_div()
00777  * In         :    two cubes
00778  * Out         :    result cube
00779  * Job        :    divide 2 cubes
00780  *--------------------------------------------------------------------------*/
00781 
00782 cpl_imagelist *
00783 sinfo_new_cube_div(
00784     cpl_imagelist    *    c1,
00785     cpl_imagelist    *    c2
00786 )
00787 {
00788     cpl_imagelist *           c3 ;
00789     ulong32        i ;
00790     int         np ;
00791     int ilx1=0;
00792     int ily1=0;
00793     int inp1=0;
00794     int ilx2=0;
00795     int ily2=0;
00796     int inp2=0;
00797 
00798 
00799     cpl_image* i_img=NULL;
00800     cpl_image* img1=NULL;
00801     cpl_image* img2=NULL;
00802     cpl_image* img3=NULL;
00803     float* p1data=NULL;
00804     float* p2data=NULL;
00805     float* p3data=NULL;
00806 
00807 
00808     inp1=cpl_imagelist_get_size(c1);
00809     i_img=cpl_imagelist_get(c1,0);
00810     ilx1=cpl_image_get_size_x(i_img);
00811     ily1=cpl_image_get_size_y(i_img);
00812 
00813 
00814     inp2=cpl_imagelist_get_size(c2);
00815     i_img=cpl_imagelist_get(c2,0);
00816     ilx2=cpl_image_get_size_x(i_img);
00817     ily2=cpl_image_get_size_y(i_img);
00818 
00819     if ((ilx1 != ilx2) ||
00820     (ily1 != ily2))
00821     {
00822     sinfo_msg_error("incompatible size: cannot divide") ;
00823     return NULL ;
00824     }
00825 
00826     if ((inp2 != inp1) && (inp2 != 1))
00827     {
00828     sinfo_msg_error("cannot compute with these number of planes") ;
00829     return NULL ;
00830     }
00831 
00832     if (NULL == (c3 = cpl_imagelist_new()) )
00833     {
00834         sinfo_msg_error ("cannot allocate a new cube") ;
00835         return NULL ;
00836     }
00837 
00838     for (np=0 ; np < inp1 ; np++)
00839     {
00840       img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
00841       cpl_imagelist_set(c3,img3,np);
00842     }
00843 
00844     for (np=0 ; np < inp1 ; np++)
00845     {
00846       img1=cpl_imagelist_get(c1,np);
00847       p1data=cpl_image_get_data_float(img1);
00848       img2=cpl_imagelist_get(c2,np);
00849       p2data=cpl_image_get_data_float(img2);
00850       img3=cpl_imagelist_get(c3,np);
00851       p3data=cpl_image_get_data_float(img3);
00852 
00853 
00854         for (i=0 ; i< (ulong32) ilx1*ily1 ; i++)
00855         {
00856             if (fabs((double)p2data[i]) < 1e-10)
00857             {
00858             p3data[i] = 0.0 ;
00859             }
00860             else
00861             {
00862                 p3data[i] = p1data[i] / p2data[i] ;
00863             }
00864         }
00865     }
00866 
00867     return c3 ;
00868 }
00869 
00870 
00871 
00872 /*---------------------------------------------------------------------------
00873    Function    :    sinfo_new_add_image_to_cube()
00874    In         :    1 allocated cube, 1 allocated image
00875    Out         :    result cube
00876    Job        :    add an image to all planes in the cube
00877  ---------------------------------------------------------------------------*/
00878 
00879 cpl_imagelist *
00880 sinfo_new_add_image_to_cube(cpl_imagelist * cu, cpl_image * im)
00881 {
00882     cpl_imagelist *   cube ;
00883     int               i ;
00884     int clx=0;
00885     int cly=0;
00886     int cnp=0;
00887     int ilx=0;
00888     int ily=0;
00889 
00890 
00891     cpl_image* i_img=NULL;
00892 
00893     if (cu==NULL || im==NULL)
00894     {
00895        sinfo_msg_error ("null cube or null image") ;
00896        return NULL ;
00897     }
00898     cnp=cpl_imagelist_get_size(cu);
00899     i_img=cpl_imagelist_get(cu,0);
00900     clx=cpl_image_get_size_x(i_img);
00901     cly=cpl_image_get_size_y(i_img);
00902 
00903     ilx=cpl_image_get_size_x(im);
00904     ily=cpl_image_get_size_y(im);
00905 
00906     if ((clx != ilx) || (cly != ily))
00907     {
00908         sinfo_msg_error("incompatible size: cannot add image to cube") ;
00909     return NULL ;
00910     }
00911 
00912     cube = cpl_imagelist_duplicate (cu) ;
00913 
00914     for (i=0 ; i<cnp ; i++)
00915     {
00916       /* AMO
00917         here may be we have to use cpl_image_add_create and cpl_imagelist_set
00918        */
00919     cpl_image_add(cpl_imagelist_get(cube,i), im) ;
00920     }
00921 
00922     return cube ;
00923 }
00924 
00925 /*---------------------------------------------------------------------------
00926    Function    :    sinfo_new_sub_image_from_cube()
00927    In         :    1 allocated cube, 1 allocated image
00928    Out         :       result cube
00929    Job        :    subtract an image from all planes in the cube
00930  ---------------------------------------------------------------------------*/
00931 
00932 cpl_imagelist *
00933 sinfo_new_sub_image_from_cube (cpl_imagelist * cu, cpl_image * im)
00934 {
00935     cpl_imagelist   * cube ;
00936     int               i ;
00937     int clx=0;
00938     int cly=0;
00939     int cnp=0;
00940     int ilx=0;
00941     int ily=0;
00942 
00943 
00944     cpl_image* i_img=NULL;
00945 
00946     if (cu==NULL || im==NULL)
00947     {
00948         sinfo_msg_error ("null cube or null image") ;
00949         return NULL ;
00950     }
00951     cnp=cpl_imagelist_get_size(cu);
00952     i_img=cpl_imagelist_get(cu,0);
00953     clx=cpl_image_get_size_x(i_img);
00954     cly=cpl_image_get_size_y(i_img);
00955 
00956     ilx=cpl_image_get_size_x(im);
00957     ily=cpl_image_get_size_y(im);
00958 
00959     if ((clx != ilx) || (cly != ily))
00960     {
00961 
00962     sinfo_msg_error("incompatible size: cannot subtract image from cube") ;
00963         return NULL ;
00964     }
00965 
00966     cube = cpl_imagelist_duplicate (cu) ;
00967 
00968     for (i=0 ; i<cnp ; i++)
00969     {
00970       /* AMO
00971         here may be we have to use cpl_image_add_create and cpl_imagelist_set
00972        */
00973     cpl_image_subtract(cpl_imagelist_get(cube,i), im) ;
00974     }
00975     return cube ;
00976 }
00977 
00978 /*---------------------------------------------------------------------------
00979    Function    :    sinfo_new_mul_image_to_cube()
00980    In         :    1 allocated cube, 1 allocated image
00981    Out         :    result cube
00982    Job        :    multiply an image to all planes in the cube
00983  ---------------------------------------------------------------------------*/
00984 
00985 cpl_imagelist *
00986 sinfo_new_mul_image_to_cube(cpl_imagelist * cu, cpl_image * im)
00987 {
00988     cpl_imagelist   * cube ;
00989     int               i ;
00990     int clx=0;
00991     int cly=0;
00992     int cnp=0;
00993     int ilx=0;
00994     int ily=0;
00995 
00996 
00997     cpl_image* i_img=NULL;
00998 
00999     if (cu==NULL || im==NULL)
01000     {
01001         sinfo_msg_error("null cube or null image") ;
01002         return NULL ;
01003     }
01004     cnp=cpl_imagelist_get_size(cu);
01005     i_img=cpl_imagelist_get(cu,0);
01006     clx=cpl_image_get_size_x(i_img);
01007     cly=cpl_image_get_size_y(i_img);
01008 
01009     ilx=cpl_image_get_size_x(im);
01010     ily=cpl_image_get_size_y(im);
01011 
01012     if ((clx != ilx) || (cly != ily))
01013     {
01014     sinfo_msg_error("incompatible size: cannot multiply image by cube") ;
01015     return NULL ;
01016     }
01017 
01018     cube = cpl_imagelist_duplicate (cu) ;
01019 
01020     for (i=0 ; i<cnp ; i++)
01021     {
01022       /* AMO
01023         here may be we have to use cpl_image_add_create and cpl_imagelist_set
01024        */
01025     cpl_image_multiply(cpl_imagelist_get(cube,i), im) ;
01026     }
01027 
01028     return cube ;
01029 }
01030 
01031 /*---------------------------------------------------------------------------
01032    Function    :    sinfo_new_div_cube_by_image()
01033    In         :    1 allocated cube, 1 allocated image
01034    Out         :    result cube
01035    Job        :    divide all planes in the cube by an image
01036  ---------------------------------------------------------------------------*/
01037 
01038 cpl_imagelist *
01039 sinfo_new_div_cube_by_image(cpl_imagelist * cu, cpl_image * im)
01040 {
01041     cpl_imagelist   * cube ;
01042     int               i ;
01043     int clx=0;
01044     int cly=0;
01045     int cnp=0;
01046     int ilx=0;
01047     int ily=0;
01048 
01049 
01050     cpl_image* i_img=NULL;
01051 
01052     if (cu==NULL || im==NULL)
01053     {
01054         sinfo_msg_error ("null cube or null image") ;
01055         return NULL ;
01056     }
01057     cnp=cpl_imagelist_get_size(cu);
01058     i_img=cpl_imagelist_get(cu,0);
01059     clx=cpl_image_get_size_x(i_img);
01060     cly=cpl_image_get_size_y(i_img);
01061 
01062     ilx=cpl_image_get_size_x(im);
01063     ily=cpl_image_get_size_y(im);
01064 
01065     if ((clx != ilx) || (cly != ily))
01066     {
01067     sinfo_msg_error("incompatible size: cannot divide cube by image") ;
01068     return NULL ;
01069     }
01070 
01071     cube = cpl_imagelist_duplicate (cu) ;
01072 
01073     for (i=0 ; i<cnp ; i++)
01074     {
01075       /* AMO
01076         here may be we have to use cpl_image_add_create and cpl_imagelist_set
01077        */
01078     cpl_image_divide(cpl_imagelist_get(cube,i), im) ;
01079     }
01080 
01081     return cube ;
01082 }
01083 
01084 
01085 /*---------------------------------------------------------------------------
01086    Function    :    sinfo_new_add_spectrum_to_cube()
01087    In         :    1 allocated cube, 1 allocated spectrum sinfo_vector
01088    Out         :    result cube
01089    Job        :    adds a spectrum (in z-direction) to all data
01090                         points in a cube
01091  ---------------------------------------------------------------------------*/
01092 
01093 cpl_imagelist *
01094 sinfo_new_add_spectrum_to_cube(cpl_imagelist *cu, Vector *spec)
01095 {
01096     cpl_imagelist *   cube ;
01097     int         i ,j ;
01098     int ilx=0;
01099     int ily=0;
01100     int inp=0;
01101     float* pidata=NULL;
01102     float* podata=NULL;
01103     cpl_image* i_img=NULL;
01104     cpl_image* o_img=NULL;
01105 
01106     if (cu == NULL || spec == NULL)
01107     {
01108         sinfo_msg_error ("null cube or null spectrum") ;
01109         return NULL ;
01110     }
01111     inp=cpl_imagelist_get_size(cu);
01112     i_img=cpl_imagelist_get(cu,0);
01113     ilx=cpl_image_get_size_x(i_img);
01114     ily=cpl_image_get_size_y(i_img);
01115 
01116     if ( inp != spec -> n_elements )
01117     {
01118         sinfo_msg_error("cube length and spectrum length are not compatible") ;
01119         return NULL ;
01120     }
01121 
01122     if ( NULL == (cube = cpl_imagelist_new ()) )
01123     {
01124         sinfo_msg_error ("cannot allocate new cube" ) ;
01125         return NULL ;
01126     }
01127     for ( i = 0; i < inp; i++)
01128     {
01129       o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
01130       cpl_imagelist_set(cube,o_img,i);
01131     }
01132 
01133 
01134     for ( i = 0; i < inp; i++)
01135     {
01136       i_img=cpl_imagelist_get(cu,i);
01137       pidata=cpl_image_get_data_float(i_img);
01138       o_img=cpl_imagelist_get(cube,i);
01139       podata=cpl_image_get_data_float(o_img);
01140         for ( j = 0; j < (int) ilx*ily; j++)
01141         {
01142             podata[j] = pidata[j] + spec -> data[i] ;
01143         }
01144     }
01145 
01146     return cube ;
01147 }
01148 
01149 /*---------------------------------------------------------------------------
01150    Function    :    sinfo_new_sub_spectrum_from_cube()
01151    In         :    1 allocated cube, 1 allocated spectrum sinfo_vector
01152    Out         :    result cube
01153    Job        :    subtracts a spectrum (in z-direction) from all
01154                         data points in a cube
01155  ---------------------------------------------------------------------------*/
01156 
01157 cpl_imagelist *
01158 sinfo_new_sub_spectrum_from_cube(cpl_imagelist *cu, Vector *spec)
01159 {
01160     cpl_imagelist *   cube ;
01161     int         i ,j ;
01162     int ilx=0;
01163     int ily=0;
01164     int inp=0;
01165     float* pidata=NULL;
01166     float* podata=NULL;
01167     cpl_image* i_img=NULL;
01168     cpl_image* o_img=NULL;
01169 
01170     if (cu == NULL || spec == NULL)
01171     {
01172         sinfo_msg_error ("null cube or null spectrum") ;
01173         return NULL ;
01174     }
01175     inp=cpl_imagelist_get_size(cu);
01176     i_img=cpl_imagelist_get(cu,0);
01177     ilx=cpl_image_get_size_x(i_img);
01178     ily=cpl_image_get_size_y(i_img);
01179 
01180     if ( inp != spec -> n_elements )
01181     {
01182         sinfo_msg_error("cube length and spectrum length are not compatible") ;
01183         return NULL ;
01184     }
01185 
01186     if ( NULL == (cube = cpl_imagelist_new()) )
01187     {
01188         sinfo_msg_error ("cannot allocate new cube" ) ;
01189         return NULL ;
01190     }
01191     for ( i = 0; i < inp; i++)
01192     {
01193       o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
01194       cpl_imagelist_set(cube,o_img,i);
01195     }
01196 
01197     for ( i = 0; i < inp; i++)
01198     {
01199       i_img=cpl_imagelist_get(cu,i);
01200       pidata=cpl_image_get_data_float(i_img);
01201       o_img=cpl_imagelist_get(cube,i);
01202       podata=cpl_image_get_data_float(o_img);
01203         for ( j = 0; j < (int) ilx*ily; j++)
01204         {
01205             if ( isnan(pidata[j]) || isnan(spec -> data[i]) )
01206             {
01207                 podata[j] = ZERO ;
01208             }
01209             else
01210             {
01211                 podata[j] = pidata[j] - spec -> data[i] ;
01212             }
01213         }
01214     }
01215 
01216     return cube ;
01217 }
01218 
01219 
01220 /*---------------------------------------------------------------------------
01221    Function    :    sinfo_new_mul_spectrum_to_cube()
01222    In         :    1 allocated cube, 1 allocated spectrum sinfo_vector
01223    Out         :    result cube
01224    Job        :    multiplies a spectrum (in z-direction) to all data
01225                         points in a cube
01226  ---------------------------------------------------------------------------*/
01227 
01228 cpl_imagelist *
01229 sinfo_new_mul_spectrum_to_cube(cpl_imagelist *cu, Vector *spec)
01230 {
01231     cpl_imagelist *   cube ;
01232     int         i ,j ;
01233     int ilx=0;
01234     int ily=0;
01235     int inp=0;
01236     float* pidata=NULL;
01237     float* podata=NULL;
01238     cpl_image* i_img=NULL;
01239     cpl_image* o_img=NULL;
01240 
01241     if (cu == NULL || spec == NULL)
01242     {
01243         sinfo_msg_error ("null cube or null spectrum") ;
01244         return NULL ;
01245     }
01246     inp=cpl_imagelist_get_size(cu);
01247     i_img=cpl_imagelist_get(cu,0);
01248     ilx=cpl_image_get_size_x(i_img);
01249     ily=cpl_image_get_size_y(i_img);
01250 
01251     if ( inp != spec -> n_elements )
01252     {
01253         sinfo_msg_error("cube length and spectrum length are not compatible") ;
01254         return NULL ;
01255     }
01256 
01257     if ( NULL == (cube = cpl_imagelist_new ()) )
01258     {
01259         sinfo_msg_error ("cannot allocate new cube" ) ;
01260         return NULL ;
01261     }
01262 
01263     for ( i = 0; i < inp; i++)
01264     {
01265       o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
01266       cpl_imagelist_set(cube,o_img,i);
01267     }
01268 
01269     for ( i = 0; i < inp; i++)
01270     {
01271       i_img=cpl_imagelist_get(cu,i);
01272       pidata=cpl_image_get_data_float(i_img);
01273       o_img=cpl_imagelist_get(cube,i);
01274       podata=cpl_image_get_data_float(o_img);
01275         for ( j = 0; j < (int) ilx*ily; j++)
01276         {
01277             if ( isnan(pidata[j]) || isnan(spec->data[i]) )
01278             {
01279                 podata[j] = ZERO ;
01280             }
01281             else
01282             {
01283                 podata[j] = pidata[j] * spec -> data[i] ;
01284             }
01285         }
01286     }
01287 
01288     return cube ;
01289 }
01290 
01291 
01292 /*---------------------------------------------------------------------------
01293    Function    :    sinfo_new_div_cube_by_spectrum()
01294    In         :    1 allocated cube, 1 allocated spectrum sinfo_vector
01295    Out         :    result cube
01296    Job        :    divides all data points of a cube by a spectrum
01297                         (in z-direction)
01298  ---------------------------------------------------------------------------*/
01299 
01300 cpl_imagelist *
01301 sinfo_new_div_cube_by_spectrum(cpl_imagelist *cu, Vector *spec)
01302 {
01303     cpl_imagelist *   cube ;
01304     float       help ;
01305     int         i ,j ;
01306     int ilx=0;
01307     int ily=0;
01308     int inp=0;
01309     float* pidata=NULL;
01310     float* podata=NULL;
01311     cpl_image* i_img=NULL;
01312     cpl_image* o_img=NULL;
01313 
01314     if (cu == NULL || spec == NULL)
01315     {
01316         sinfo_msg_error ("null cube or null spectrum") ;
01317         return NULL ;
01318     }
01319     inp=cpl_imagelist_get_size(cu);
01320     i_img=cpl_imagelist_get(cu,0);
01321     ilx=cpl_image_get_size_x(i_img);
01322     ily=cpl_image_get_size_y(i_img);
01323 
01324     if ( inp != spec -> n_elements )
01325     {
01326         sinfo_msg_error("cube length and spectrum length are not compatible") ;
01327         return NULL ;
01328     }
01329 
01330     if (NULL == (cube = cpl_imagelist_new ()) )
01331     {
01332         sinfo_msg_error ("cannot allocate new cube") ;
01333         return NULL ;
01334     }
01335 
01336     for ( i = 0; i < inp; i++)
01337     {
01338       o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
01339       cpl_imagelist_set(cube,o_img,i);
01340     }
01341 
01342     for ( i = 0; i < inp; i++)
01343     {
01344 
01345       i_img=cpl_imagelist_get(cu,i);
01346       pidata=cpl_image_get_data_float(i_img);
01347       o_img=cpl_imagelist_get(cube,i);
01348       podata=cpl_image_get_data_float(o_img);
01349         for ( j = 0; j < (int) ilx*ily; j++)
01350         {
01351             if (!isnan(spec->data[i]) && spec->data[i] != 0.)
01352             {
01353                 help = 1/spec->data[i] ;
01354                 if ( help > THRESH )
01355                 {
01356                     help = 1. ;
01357                 }
01358             }
01359             else
01360             {
01361                 help = ZERO ;
01362             }
01363 
01364             if ( isnan(help) || isnan(pidata[j]) )
01365             {
01366                 podata[j] = ZERO ;
01367             }
01368             else
01369             {
01370                 podata[j] = pidata[j] * help ;
01371             }
01372         }
01373     }
01374     return cube ;
01375 }
01376 
01377 
01378 /*---------------------------------------------------------------------------
01379    Function    :    sinfo_new_clean_mean_of_spectra()
01380    In         :    1 allocated cube, position of rectangle in x-y plane ,
01381                         low and high cut threshold
01382    Out         :    result spectrum sinfo_vector
01383    Job        :    averaging routine to get a better spectral S/N, sorts
01384                         the values of the same z-position, cuts the lowest and
01385                         highest values according to given thresholds and then
01386                         takes the average within the x-y plane , cannot have
01387                         a sum of low and high rejected values greater than 90%
01388                         of all values
01389  ---------------------------------------------------------------------------*/
01390 
01391 Vector *
01392 sinfo_new_clean_mean_of_spectra(cpl_imagelist * cube,
01393                              int llx,
01394                              int lly,
01395                              int urx,
01396                              int ury,
01397                              double lo_reject,
01398                              double hi_reject)
01399 {
01400     Vector                           * mean ;
01401     pixelvalue                   *local_rectangle ;
01402     int                    i, j, k, l, m ;
01403     int             recsize, lo_n, hi_n, nv ;
01404     int ilx=0;
01405     int ily=0;
01406     int inp=0;
01407     float* pidata=NULL;
01408     cpl_image* i_img=NULL;
01409 
01410     if ( cube == NULL || cpl_imagelist_get_size(cube) < 1 )
01411     {
01412         sinfo_msg_error ("no cube to take the mean of his spectra") ;
01413         return NullVector ;
01414     }
01415     inp=cpl_imagelist_get_size(cube);
01416     i_img=cpl_imagelist_get(cube,0);
01417     ilx=cpl_image_get_size_x(i_img);
01418     ily=cpl_image_get_size_y(i_img);
01419 
01420     if ((llx<1) || (llx>ilx) ||
01421         (urx<1) || (urx>ilx) ||
01422         (lly<1) || (lly>ily) ||
01423         (ury<1) || (ury>ily) ||
01424         (llx>=urx) || (lly>=ury))
01425     {
01426         sinfo_msg_error("invalid rectangle coordinates:") ;
01427         sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
01428                         llx, lly, urx, ury) ;
01429         return NullVector ;
01430     }
01431 
01432     if ((lo_reject + hi_reject) > 0.9)
01433     {
01434         sinfo_msg_error("illegal rejection thresholds: [%f] and [%f]",
01435                         lo_reject, hi_reject) ;
01436         sinfo_msg_error("threshold sum should not be over 0.9"
01437                         " aborting average") ;
01438         return NullVector ;
01439     }
01440 
01441     /* shift from FITS coordinates to C coordinates */
01442     llx -- ;
01443     lly -- ;
01444     urx -- ;
01445     ury -- ;
01446 
01447     recsize = (urx - llx + 1) * (ury - lly + 1) ;
01448 
01449     lo_n = (int) (recsize * lo_reject + 0.5) ;
01450     hi_n = (int) (recsize * hi_reject + 0.5) ;
01451 
01452     if (lo_n + hi_n >= recsize)
01453     {
01454         sinfo_msg_error ("everything would be rejected") ;
01455         return NullVector;
01456     }
01457 
01458     /* allocate a new sinfo_vector to store the average spectral values */
01459     if (NULL == (mean = sinfo_new_vector (inp)) )
01460     {
01461         sinfo_msg_error ("cannot allocate a new sinfo_vector") ;
01462         return NullVector ;
01463     }
01464 
01465     /*------------------------------------------------------------------------
01466      *  loop through the cube planes, through the x axis and the y-axis of the
01467      *  plane rectangle and store pixel values in a buffer.
01468      */
01469     for ( i = 0 ; i < inp ; i++ )
01470     {
01471       i_img=cpl_imagelist_get(cube,i);
01472       pidata=cpl_image_get_data_float(i_img);
01473       m = 0 ;
01474       local_rectangle=(pixelvalue *)cpl_calloc(recsize, sizeof (pixelvalue*));
01475 
01476         for ( j = lly ; j <= ury ; j++ )
01477         {
01478             for ( k = llx ; k <= urx ; k++ )
01479             {
01480                 local_rectangle[m] = pidata[k + j * ilx] ;
01481                 m ++ ;
01482             }
01483         }
01484         /*sorts the pixelvalues in the buffer*/
01485         sinfo_pixel_qsort (local_rectangle, recsize) ;
01486 
01487         nv = 0 ;
01488         for ( l = lo_n ; l < (recsize - hi_n) ; l++ )
01489         {
01490             mean -> data[i] += local_rectangle[l] ;
01491             nv ++;
01492         }
01493         mean -> data[i] /= nv ;
01494 
01495         cpl_free ( local_rectangle ) ;
01496     }
01497     return mean ;
01498 }
01499 
01500 
01501 /*---------------------------------------------------------------------------
01502    Function    :sinfo_new_median_cube()
01503    In         :1 allocated cube
01504    Out         :result image
01505    Job        :determines the sinfo_new_median value in every pixel position
01506                  by considering all pixels along the third axis.
01507                  ZERO pixels in a plane are not considered. If all
01508                  pixels at a position are not valid the result will
01509                  be 'ZERO'.
01510  ---------------------------------------------------------------------------*/
01511 cpl_image *
01512 sinfo_new_median_cube(cpl_imagelist * cube)
01513 {
01514     cpl_image  *         im ;
01515     pixelvalue *    buffer ;
01516     int        i, j, k, nz ;
01517     int ilx=0;
01518     int ily=0;
01519     int inp=0;
01520     float* pidata=NULL;
01521     float* podata=NULL;
01522     cpl_image* i_img=NULL;
01523 
01524     if ( cube == NULL )
01525     {
01526         sinfo_msg_error ("null cube") ;
01527         return NULL ;
01528     }
01529     inp=cpl_imagelist_get_size(cube);
01530     i_img=cpl_imagelist_get(cube,0);
01531     ilx=cpl_image_get_size_x(i_img);
01532     ily=cpl_image_get_size_y(i_img);
01533 
01534     /* allocate memory */
01535     if (NULL == (im = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT )) )
01536     {
01537         sinfo_msg_error ("cannot allocate new image") ;
01538         return NULL ;
01539     }
01540 
01541     /*------------------------------------------------------------------------
01542      * transfer each sinfo_vector in z direction in a buffer and collect
01543        only non-blank data.
01544      */
01545 
01546     podata=cpl_image_get_data_float(im);
01547     for ( i = 0 ; i < (int) ilx*ily ; i++ )
01548     {
01549         buffer = (pixelvalue *) cpl_calloc (inp, sizeof (pixelvalue *));
01550         k = 0 ;
01551         for ( j = 0 ; j < inp ; j ++ )
01552         {
01553           i_img=cpl_imagelist_get(cube,j);
01554       pidata=cpl_image_get_data_float(i_img);
01555             if ( !isnan(pidata[i]) )
01556             {
01557                 buffer[k] = pidata[i] ;
01558                 k ++ ;
01559             }
01560         }
01561         nz = k ;
01562 
01563         /* proceed depending on the number of valid pixels */
01564         if ( nz > 2 )
01565         {
01566             podata[i] = sinfo_new_median ( buffer, nz ) ;
01567         }
01568         else if (nz == 2)
01569         {
01570             podata[i] = (buffer[0] + buffer[1]) / 2. ;
01571         }
01572         else if (nz == 1)
01573         {
01574             podata[i] = buffer[0] ;
01575         }
01576         else if (nz == 0)
01577         {
01578             podata[i] = ZERO ;
01579         }
01580 
01581         cpl_free ( buffer ) ;
01582     }
01583 
01584     return im ;
01585 }
01586 
01587 
01588 /*---------------------------------------------------------------------------
01589    Function    :    sinfo_new_average_cube_to_image()
01590    In         :    1 allocated cube
01591    Out         :    result image
01592    Job        :    determines the average value in every pixel position
01593                         by considering all pixels along the third axis.
01594                         ZERO pixels in a plane are not considered. If all
01595                         pixels at a position are not valid the result will
01596                         be 'ZERO'.
01597  ---------------------------------------------------------------------------*/
01598 cpl_image *
01599 sinfo_new_average_cube_to_image(cpl_imagelist * cube)
01600 {
01601     cpl_image  *      im ;
01602     int        i, j, nz ;
01603     int ilx=0;
01604     int ily=0;
01605     int inp=0;
01606     float* pidata=NULL;
01607     float* podata=NULL;
01608     cpl_image* i_img=NULL;
01609 
01610     if ( cube == NULL )
01611     {
01612         sinfo_msg_error ("null cube") ;
01613         return NULL ;
01614     }
01615     inp=cpl_imagelist_get_size(cube);
01616     i_img=cpl_imagelist_get(cube,0);
01617     ilx=cpl_image_get_size_x(i_img);
01618     ily=cpl_image_get_size_y(i_img);
01619 
01620     /* allocate memory */
01621     if (NULL == (im = cpl_image_new (ilx, ily,CPL_TYPE_FLOAT )) )
01622     {
01623         sinfo_msg_error ("cannot allocate new image") ;
01624         return NULL ;
01625     }
01626 
01627     /*------------------------------------------------------------------------
01628      * transfer each vector in z direction in a buffer and collect
01629        only non-blank data.
01630      */
01631 
01632     podata=cpl_image_get_data_float(im);
01633     for ( i = 0 ; i < (int) ilx*ily ; i++ )
01634     {
01635         nz = 0 ;
01636         for ( j = 0 ; j < inp ; j ++ )
01637         {
01638           i_img=cpl_imagelist_get(cube,j);
01639       pidata=cpl_image_get_data_float(i_img);
01640             if ( !isnan(pidata[i]) )
01641             {
01642                 nz ++ ;
01643                 podata[i] += pidata[i] ;
01644             }
01645         }
01646 
01647         /* proceed depending on the number of valid pixels */
01648         if ( nz >= 1 )
01649         {
01650             podata[i] /= nz ;
01651         }
01652         else if (nz == 0)
01653         {
01654             podata[i] = ZERO ;
01655         }
01656     }
01657 
01658     return im ;
01659 }
01660 
01661 /*---------------------------------------------------------------------------
01662    Function     :       sinfo_new_sum_cube_to_image()
01663    In           :       1 allocated cube
01664    Out          :       result image
01665    Job          :       determines the sum value in every pixel position
01666                         by considering all pixels along the third axis.
01667                         ZERO pixels in a plane are not considered. If all
01668                         pixels at a position are not valid the result will
01669                         be 'ZERO'.
01670  ---------------------------------------------------------------------------*/
01671 cpl_image *
01672 sinfo_new_sum_cube_to_image(cpl_imagelist * cube)
01673 {
01674     cpl_image  *      im ;
01675     int        i, j, nz ;
01676     int ilx=0;
01677     int ily=0;
01678     int inp=0;
01679     float* pidata=NULL;
01680     float* podata=NULL;
01681     cpl_image* i_img=NULL;
01682 
01683     if ( cube == NULL )
01684     {
01685         sinfo_msg_error ("null cube") ;
01686         return NULL ;
01687     }
01688     inp=cpl_imagelist_get_size(cube);
01689     i_img=cpl_imagelist_get(cube,0);
01690     ilx=cpl_image_get_size_x(i_img);
01691     ily=cpl_image_get_size_y(i_img);
01692 
01693     /* allocate memory */
01694     if (NULL == (im = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT )) )
01695     {
01696         sinfo_msg_error ("cannot allocate new image") ;
01697         return NULL ;
01698     }
01699 
01700     /*-------------------------------------------------------------------------
01701      * transfer each vector in z direction in a buffer and collect only
01702        non-blank data.
01703      */
01704 
01705     podata=cpl_image_get_data_float(im);
01706     for ( i = 0 ; i < (int) ilx*ily ; i++ )
01707     {
01708         nz = 0 ;
01709         for ( j = 0 ; j < inp ; j ++ )
01710         {
01711           i_img=cpl_imagelist_get(cube,j);
01712       pidata=cpl_image_get_data_float(i_img);
01713             if ( !isnan(pidata[i]) )
01714             {
01715                 nz++ ;
01716                 podata[i] += pidata[i] ;
01717             }
01718         }
01719 
01720         /* proceed depending on the number of valid pixels */
01721         if (nz == 0)
01722         {
01723             podata[i] = ZERO ;
01724         }
01725     }
01726 
01727     return im ;
01728 }
01729 
01730 /*---------------------------------------------------------------------------
01731    Function    sinfo_new_average_cube_to_image_between_waves()
01732    In         cube: data cube to collapse
01733                 dispersion: dispersion per pixel in microns/pixel
01734                 (derived from fits header information)
01735                 centralWave: central wavelength in the cube in microns
01736                                        (derived from fits header information)
01737                 initialLambda, finalLambda: wavelength values in microns
01738                                             within which the cube is averaged
01739    Out         :resulting averaged image
01740    Job        :determines the average value in every pixel position
01741                  by considering only the pixels along the third axis
01742                  which lie between the given wavelength values.
01743                  These values are first recalculated to plane indices
01744                  by using the given dispersion and minimum wavelength in
01745                  the cube.
01746                  ZERO pixels in a plane are not considered. If all
01747                  pixels at a position are not valid the result will
01748                  be 'ZERO'.
01749  ---------------------------------------------------------------------------*/
01750 cpl_image *
01751 sinfo_new_average_cube_to_image_between_waves (cpl_imagelist * cube,
01752                                            float     dispersion,
01753                                            float     centralWave,
01754                                            float     initialLambda,
01755                                            float     finalLambda)
01756 {
01757     cpl_image  *      im ;
01758     int        firstPlane ;
01759     int        lastPlane ;
01760     int        i, j, nz ;
01761     float      minWave ;
01762     int ilx=0;
01763     int ily=0;
01764     int inp=0;
01765     float* pidata=NULL;
01766     float* podata=NULL;
01767     cpl_image* i_img=NULL;
01768 
01769     if ( cube == NULL )
01770     {
01771         sinfo_msg_error ("null cube") ;
01772         return NULL ;
01773     }
01774     i_img=cpl_imagelist_get(cube,0);
01775     ilx=cpl_image_get_size_x(i_img);
01776     ily=cpl_image_get_size_y(i_img);
01777 
01778     inp=cpl_imagelist_get_size(cube);
01779 
01780     minWave = centralWave - (float) (inp / 2)*dispersion ;
01781 
01782     if ( dispersion <= 0. || minWave <= 0. )
01783     {
01784         sinfo_msg_error ("wrong dispersion or minimum wavelength given") ;
01785         return NULL ;
01786     }
01787 
01788     if ( initialLambda < minWave ||
01789         (initialLambda >= minWave + dispersion * inp) )
01790     {
01791         sinfo_msg_error ("wrong initial wavelength given") ;
01792         return NULL ;
01793     }
01794 
01795     if ( finalLambda <= minWave ||
01796         (finalLambda > minWave + dispersion * inp) )
01797     {
01798         sinfo_msg_error ("wrong final wavelength given") ;
01799         return NULL ;
01800     }
01801 
01802     /* allocate memory */
01803     if (NULL == (im = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT )) )
01804     {
01805         sinfo_msg_error ("cannot allocate new image") ;
01806         return NULL ;
01807     }
01808 
01809     /* transfer the wavelength range to image plane indices */
01810     firstPlane = sinfo_new_nint ((double) ((initialLambda - minWave) /
01811                                           dispersion)) ;
01812     lastPlane  = sinfo_new_nint ((double) ((finalLambda - minWave) /
01813                                           dispersion)) ;
01814 
01815     if ( firstPlane < 0 || firstPlane >= inp ||
01816          lastPlane  < 0 || lastPlane  >  inp )
01817     {
01818         sinfo_msg_error ("wrong values given!") ;
01819         return NULL ;
01820     }
01821 
01822     /*------------------------------------------------------------------------
01823      * transfer each vector in z direction in a buffer and collect only
01824        non-blank data.
01825      */
01826 
01827 
01828 
01829     podata=cpl_image_get_data_float(im);
01830     for ( i = 0 ; i < (int) ilx*ily ; i++ )
01831     {
01832         nz = 0 ;
01833 
01834         for ( j = firstPlane ; j <= lastPlane ; j ++ )
01835         {
01836           i_img=cpl_imagelist_get(cube,j);
01837       pidata=cpl_image_get_data_float(i_img);
01838             if ( !isnan(pidata[i]) )
01839             {
01840                 nz ++ ;
01841                 podata[i] += pidata[i] ;
01842             }
01843         }
01844 
01845         /* proceed depending on the number of valid pixels */
01846         if ( nz >= 1 )
01847         {
01848             podata[i] /= nz ;
01849         }
01850         else if (nz == 0)
01851         {
01852             podata[i] = ZERO ;
01853         }
01854     }
01855 
01856     return im ;
01857 }
01858 
01859 /*---------------------------------------------------------------------------
01860    Function    :    sinfo_new_extract_image_from_cube()
01861    In         :    1 allocated cube
01862                         index of cube plane
01863    Out         :    extracted image
01864    Job        :    returns the wanted image plane of the cube
01865  ---------------------------------------------------------------------------*/
01866 cpl_image *
01867 sinfo_new_extract_image_from_cube(cpl_imagelist * cube, int plane_index)
01868 {
01869     if ( cube == NULL )
01870     {
01871         sinfo_msg_error ("null cube") ;
01872         return NULL ;
01873     }
01874 
01875     if ( plane_index < 0 || plane_index >= cpl_imagelist_get_size(cube) )
01876     {
01877         sinfo_msg_error ("wrong plane index for image to be extracted") ;
01878         return NULL ;
01879     }
01880 
01881     return cpl_imagelist_get(cube,plane_index) ;
01882 }
01883 
01884 /*---------------------------------------------------------------------------
01885    Function    :sinfo_new_extract_spectrum_from_cube()
01886    In         :cube: 1 allocated cube
01887                  x_pos, y_pos: x, y pixel position of the
01888                                spectrum counted from 0
01889    Out         :extracted spectral sinfo_vector object
01890    Job        :returns the wanted single spectrum of the cube
01891  ---------------------------------------------------------------------------*/
01892 Vector *
01893 sinfo_new_extract_spectrum_from_cube(cpl_imagelist * cube,
01894                                      int x_pos, int y_pos)
01895 {
01896     Vector * returnedSpectrum ;
01897     int i ;
01898     int ilx=0;
01899     int ily=0;
01900     int inp=0;
01901     float* pidata=NULL;
01902     cpl_image* i_img=NULL;
01903 
01904     if ( cube == NULL )
01905     {
01906         sinfo_msg_error ("no cube given!") ;
01907         return NullVector ;
01908     }
01909     i_img=cpl_imagelist_get(cube,0);
01910     ilx=cpl_image_get_size_x(i_img);
01911     ily=cpl_image_get_size_y(i_img);
01912     inp=cpl_imagelist_get_size(cube);
01913 
01914     if ( x_pos < 0 || x_pos >= ilx )
01915     {
01916         sinfo_msg_error ("wrong x-positon of spectrum given!") ;
01917         return NullVector ;
01918     }
01919 
01920     if ( y_pos < 0 || y_pos >= ily )
01921     {
01922         sinfo_msg_error ("wrong y-positon of spectrum given!") ;
01923         return NullVector ;
01924     }
01925 
01926     /* allocate memory */
01927     if ( NULL == (returnedSpectrum = sinfo_new_vector ( inp )) )
01928     {
01929         sinfo_msg_error ("cannot allocate new spectrum!") ;
01930         return NullVector ;
01931     }
01932 
01933     for ( i = 0 ; i < inp ; i++ )
01934     {
01935       i_img=cpl_imagelist_get(cube,i);
01936       pidata=cpl_image_get_data_float(i_img);
01937       returnedSpectrum -> data[i] = pidata[x_pos + ilx*y_pos] ;
01938     }
01939 
01940     return returnedSpectrum ;
01941 }
01942 
01943 /*---------------------------------------------------------------------------
01944    Function     :       sinfo_new_combine_jittered_cubes()
01945    In           :       cubes: list of jittered cubes to mosaic
01946                         mergedCube: resulting merged cube containing the
01947                                       jittered cubes
01948                         n_cubes: number of cubes in the list to merge
01949                         cumoffsetx,y: array of relative x, y pixel offsets
01950                                       with respect to the first frame in the
01951                                       same sequence as the cube list.
01952                         exptimes: exposure times array giving the time
01953                                   in the same sequence as the cube list
01954                         kernel_type: the name of the interpolation kernel
01955                                      that you want to generate using the
01956                                      eclipse routine
01957                                      sinfo_generate_interpolation_kernel()
01958                                      Supported kernels are:
01959                                      NULL:      default kernel, currently tanh
01960                                      "default": dito
01961                                      "tanh":    Hyperbolic tangent
01962                                      "sinc2":   Square sinc
01963                                      "lanczos": Lanczos2 kernel
01964                                      "hamming": Hamming kernel
01965                                      "hann":    Hann kernel
01966    Out          :       mask: cube of the same size as combinedCube
01967                               containing 0 for blank (ZERO pixels) and
01968                               the summed integration times for
01969                               overlapping regions
01970                         mergedCube: final data cube containing the
01971                                     jittered cubes
01972    Job          :       merges jittered data cubes to one bigger cube
01973                         by averaging the overlap regions weighted by
01974                         the integration times. The x, y size of the final data
01975                         cube is user given, and should be between 32 and 64
01976                         pixels, while the relative pixel-offset (sub-pixel
01977                         accuracy) of the single cubes with respect to the
01978                         first cube in the list is read from the
01979                         SEQ CUMOFFSETX,Y
01980                         fits header keyword.
01981  ---------------------------------------------------------------------------*/
01982 cpl_imagelist *
01983 sinfo_new_combine_jittered_cubes ( cpl_imagelist ** cubes,
01984                                  cpl_imagelist  * mergedCube,
01985                                  int        n_cubes,
01986                                  float    * cumoffsetx,
01987                                  float    * cumoffsety,
01988                                  float    * exptimes,
01989                                  char     * kernel_type )
01990 {
01991 
01992     int i=0 ;
01993     int x=0;
01994     int y=0;
01995     int z=0;
01996     int llx0=0;
01997     int lly0=0;
01998     int posx=0;
01999     int posy=0;
02000     float weight=0;
02001     cpl_imagelist * mask=NULL;
02002     double * kernel=NULL;
02003     /*cpl_image * shiftedImage ;*/
02004 
02005     int* llx=NULL ;
02006     int* lly=NULL ;
02007 
02008     float* sub_offsetx=NULL ;
02009     float* sub_offsety=NULL ;
02010 
02011     cpl_imagelist ** tmpcubes=NULL ;
02012     pixelvalue * tmpspace=NULL;
02013 
02014 
02015   int ilx=0;
02016   int ily=0;
02017   int olx=0;
02018   int oly=0;
02019   int mlx=0;
02020   int onp=0;
02021   int inp=0;
02022 
02023 
02024 
02025   float* podata=NULL;
02026   float* pmdata=NULL;
02027   float* ptdata=NULL;
02028 
02029   cpl_image* i_img=NULL;
02030   cpl_image* o_img=NULL;
02031   cpl_image* m_img=NULL;
02032   cpl_image* t_img=NULL;
02033 
02034 
02035     if ( cubes == NULL )
02036     {
02037         sinfo_msg_error ("no cube list given!") ;
02038         return NULL ;
02039     }
02040     if ( n_cubes <= 0 )
02041     {
02042         sinfo_msg_error ("wrong number of data cubes in list!") ;
02043         return NULL ;
02044     }
02045     if ( cumoffsetx == NULL || cumoffsety == NULL )
02046     {
02047         sinfo_msg_error ("no cumoffsetx/y given!") ;
02048         return NULL ;
02049     }
02050     if ( exptimes == NULL )
02051     {
02052         sinfo_msg_error ("no exposure time array given!") ;
02053         return NULL ;
02054     }
02055 
02056     o_img=cpl_imagelist_get(mergedCube,0);
02057     olx=cpl_image_get_size_x(o_img);
02058     oly=cpl_image_get_size_y(o_img);
02059     onp=cpl_imagelist_get_size(mergedCube);
02060     if ( NULL == (mask = cpl_imagelist_new()) )
02061     {
02062         sinfo_msg_error ("could not allocate cube!") ;
02063         return NULL ;
02064     }
02065     for(i=0;i<onp;i++){
02066       o_img=cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
02067       cpl_imagelist_set(mergedCube,o_img,i);
02068     }
02069 
02070     i_img=cpl_imagelist_get(cubes[0],0);
02071     ilx=cpl_image_get_size_x(i_img);
02072     ily=cpl_image_get_size_y(i_img);
02073 
02074     inp=cpl_imagelist_get_size(cubes[0]);
02075 
02076     /*--------------------------------------------------------------------
02077      * center the cubes within the allocated big cube
02078      * that means define the (0,0) positions of the cubes in the image planes
02079      * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
02080      */
02081     /* position of first reference frame, centered in big cube */
02082     llx0 = olx/2 - ilx/2 ;
02083     lly0 = oly/2 - ily/2 ;
02084 
02085     /*--------------------------------------------------------------------
02086      * go through the frame list and determine the lower left edge position
02087      * of the shifted cubes. Additionnally, the sub-pixel offsets are
02088      * determined.
02089      */
02090 
02091     llx=cpl_calloc(n_cubes,sizeof(int)); ;
02092     lly=cpl_calloc(n_cubes,sizeof(int)) ;
02093 
02094     sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
02095     sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
02096 
02097     for ( i = 0 ; i < n_cubes ; i++ )
02098     {
02099         llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
02100         sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
02101         lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
02102         sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
02103     }
02104 
02105 
02106     /* -------------------------------------------------------------
02107      * shift the cubes according to the computed sub-pixel offsets
02108      * that means shift the single image planes of each cube
02109      * first determine an interpolation kernel
02110      */
02111     if ( NULL == (kernel = sinfo_generate_interpolation_kernel(kernel_type)))
02112     {
02113         sinfo_msg_warning ("could not generate desired interpolation kernel"
02114                            " or no kernel_typ was given, the default kernel"
02115                            " is used now!") ;
02116     }
02117     /* go through the frame list */
02118 
02119 
02120     tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
02121 
02122     for ( i = 0 ; i < n_cubes ; i++ )
02123     {
02124         tmpspace = cpl_calloc(ilx, ily*sizeof(pixelvalue)) ;
02125         tmpcubes[i] = cpl_imagelist_new();
02126 
02127         for ( z = 0 ; z < inp ; z++ )
02128         {
02129 
02130 
02131             t_img=sinfo_new_shift_image(cpl_imagelist_get(cubes[i],z),
02132                                   sub_offsetx[i], sub_offsety[i], kernel);
02133 
02134         if (t_img==NULL)
02135             {
02136                 sinfo_msg_error ("could not shift image plane no %d"
02137                                  " in cube no %d!", z, i) ;
02138                 cpl_imagelist_delete(mergedCube) ;
02139                 cpl_imagelist_delete(mask) ;
02140                 cpl_free(kernel) ;
02141                 return NULL ;
02142             }
02143             cpl_imagelist_set(tmpcubes[i],t_img,z);
02144         }
02145     cpl_free(tmpspace);
02146     }
02147 
02148     /*-------------------------------------------------------------------------
02149      * Build the mask data cube.
02150      * The mask is 0 where no data is available, otherwise the integration
02151        time of one frame, respectively the summed integration
02152      * times in the overlapping regions are inserted
02153      */
02154     /* go through the frame list */
02155     for ( i = 0 ; i < n_cubes ; i++ )
02156     {
02157 
02158         /* go through the first image plane of the big data cube */
02159         for ( y = 0 ; y < oly ; y++ )
02160         {
02161             for ( x = 0 ; x < olx ; x++ )
02162             {
02163                 /* find the position of the present cube and
02164                    go through the single spectra */
02165                 if ( y >= lly[i] && y < lly[i]+ily &&
02166                      x >= llx[i] && x < llx[i]+ilx )
02167                 {
02168                     posx = x - llx[i] ;
02169                     posy = y - lly[i] ;
02170                     for ( z = 0 ; z < onp ; z++ )
02171                     {
02172               t_img=cpl_imagelist_get(tmpcubes[i],z);
02173                       ptdata=cpl_image_get_data_float(t_img);
02174               m_img=cpl_imagelist_get(mask,z);
02175                       pmdata=cpl_image_get_data_float(m_img);
02176                         if (!isnan(ptdata[posx+posy*ilx]) &&
02177                                          ptdata[posx+posy*ilx] != 0.)
02178                         {
02179                             pmdata[x+y*mlx] += exptimes[i] ;
02180                         }
02181                     }
02182                 }
02183             }
02184         }
02185     }
02186 
02187 
02188 
02189 
02190 
02191 
02192     /* calculate a weighted average using the
02193        exposure time of the single frames
02194        of the overlapping regions of the cubes */
02195     for ( i = 0 ; i < n_cubes ; i++ )
02196     {
02197 
02198         /* go through the first image plane of the big data cube */
02199         for ( y = 0 ; y < oly ; y++ )
02200         {
02201 
02202             for ( x = 0 ; x < olx ; x++ )
02203             {
02204 
02205                 /* find the position of the present cube
02206                    and go through the single spectra */
02207                 if ( y >= lly[i] && y < lly[i]+ily &&
02208                      x >= llx[i] && x < llx[i]+ilx )
02209                 {
02210 
02211                     posx = x - llx[i] ;
02212                     posy = y - lly[i] ;
02213                     for ( z = 0 ; z < onp ; z++ )
02214                     {
02215 
02216               t_img=cpl_imagelist_get(tmpcubes[i],z);
02217                       ptdata=cpl_image_get_data_float(t_img);
02218               m_img=cpl_imagelist_get(mask,z);
02219                       pmdata=cpl_image_get_data_float(m_img);
02220                       mlx=cpl_image_get_size_x(m_img);
02221 
02222               o_img=cpl_imagelist_get(mergedCube,z);
02223                       podata=cpl_image_get_data_float(o_img);
02224                       podata[x+y*olx]=0;
02225                         if (!isnan(ptdata[posx+posy*ilx]))
02226                         {
02227                             if (pmdata[x+y*mlx] != 0.)
02228                             {
02229                 /* adjust the intensities to
02230                                    the first reference cube */
02231                                 weight = exptimes[0] / pmdata[x+y*mlx] ;
02232                             }
02233                             else
02234                             {
02235                                 weight = 0. ;
02236                             }
02237                             podata[x+y*olx] +=
02238                                weight*ptdata[posx+posy*ilx] ;
02239                         }
02240                     }
02241                 }
02242             }
02243         }
02244     }
02245 
02246 
02247 
02248 
02249     /* convert the "free space" in the cube to blank pixels */
02250     /* convert_0_to_ZERO_for_cubes(mergedCube) ; */
02251     cpl_free(kernel) ; /* originated by eclise-malloc */
02252     for( i = 0 ; i < n_cubes ; i++ )
02253     {
02254         cpl_imagelist_delete (tmpcubes[i]) ;
02255     }
02256 
02257     cpl_free(tmpcubes); ;
02258     cpl_free(llx); ;
02259     cpl_free(lly) ;
02260 
02261     cpl_free(sub_offsetx) ;
02262     cpl_free(sub_offsety) ;
02263 
02264     return mask ;
02265 }
02266 
02267 
02268 
02269 
02270 
02271 
02272 
02273 
02303 static int
02304 sinfo_build_mask_cube(const int z_min,
02305                       const int z_max,
02306                       const int olx,
02307                       const int oly,
02308                       const int n_cubes,
02309                       const int* llx,
02310                       const int* lly,
02311               double    * exptimes,
02312                       cpl_imagelist** cubes,
02313                       cpl_imagelist** tmpcubes,
02314                       cpl_imagelist* mask)
02315 {
02316 
02317   int i=0;
02318   int y=0;
02319   int z=0;
02320   int ilx=0;
02321   int ily=0;
02322   cpl_image* i_img=NULL;
02323   cpl_image* t_img=NULL;
02324   int posx=0;
02325   int posy=0;
02326   float* ptdata=NULL;
02327   float* pmdata=NULL;
02328   int m=0;
02329   int x=0;
02330   int mlx=0;
02331   cpl_image* m_img=NULL;
02332 
02333 
02334   for ( z = z_min, m=0 ; z < z_max ; z++, m++ ) {
02335 
02336     // go through the first image plane of the big data cube
02337     for ( y = 0 ; y < oly ; y++ ) {
02338       for ( x = 0 ; x < olx ; x++ ) {
02339     for ( i = 0 ; i < n_cubes ; i++ ) {
02340 
02341           i_img=cpl_imagelist_get(cubes[i],0);
02342           ilx=cpl_image_get_size_x(i_img);
02343           ily=cpl_image_get_size_y(i_img);
02344 
02345 
02346       // find the position of the present cube and go
02347           // through the single spectra */
02348           if ( y >= lly[i] && y < lly[i]+ily &&
02349                x >= llx[i] && x < llx[i]+ilx )
02350         {
02351           posx = x - llx[i] ;
02352           posy = y - lly[i] ;
02353 
02354 
02355               t_img=cpl_imagelist_get(tmpcubes[i],m);
02356               ptdata=cpl_image_get_data_float(t_img);
02357               m_img=cpl_imagelist_get(mask,z);
02358               pmdata=cpl_image_get_data_float(m_img);
02359           mlx=cpl_image_get_size_x(m_img);
02360 
02361               if (!isnan(ptdata[posx+posy*ilx]) &&
02362                          ptdata[posx+posy*ilx] != 0.)
02363         {
02364           pmdata[x+y*mlx] += (float)exptimes[i] ;
02365         } else if (isnan(ptdata[posx+posy*ilx])) {
02366         sinfo_msg_debug("ptdata %d, %d, %d is NAN\t",x,y,z);
02367           } else if (ptdata[posx+posy*ilx] == 0.) {
02368         sinfo_msg_debug("ptdata %d, %d, %d is 0\t",x,y,z);
02369           }
02370 
02371         } else {
02372         sinfo_msg_debug("point %d, %d, %d outside range\n",x,y,z);
02373       }
02374         }
02375       }
02376     }
02377   }
02378   return 0;
02379 
02380 }
02381 
02382 
02383 
02384 
02385 static int
02386 sinfo_build_mask_cube_thomas(const int z_min,
02387                       const int z_max,
02388                       const int olx,
02389                       const int oly,
02390                       const int n_cubes,
02391                       const int* llx,
02392                       const int* lly,
02393               double    * exptimes,
02394                       cpl_imagelist** cubes,
02395                       cpl_imagelist** tmpcubes,
02396                       cpl_imagelist* mask)
02397 {
02398 
02399   int i=0;
02400   int y=0;
02401   int z=0;
02402   int ilx=0;
02403   int ily=0;
02404   int inp=0;
02405   cpl_image* i_img=NULL;
02406   cpl_image* t_img=NULL;
02407   int posx=0;
02408   int posy=0;
02409   float* ptdata=NULL;
02410   float* pmdata=NULL;
02411   int m=0;
02412   int x=0;
02413   int mlx=0;
02414   cpl_image* m_img=NULL;
02415 
02416   for ( i = 0 ; i < n_cubes ; i++ ) {
02417 
02418     i_img=cpl_imagelist_get(cubes[i],0);
02419     ilx=cpl_image_get_size_x(i_img);
02420     ily=cpl_image_get_size_y(i_img);
02421     inp=cpl_imagelist_get_size(cubes[i]);
02422 
02423     //go through the first image plane of the big data cube
02424     for ( y = 0 ; y < oly ; y++ ){
02425       for ( x = 0 ; x < olx ; x++ ){
02426     // find the position of the present cube and go
02427     // through the single spectra
02428         if ( y >= lly[i] && y < lly[i]+ily &&
02429              x >= llx[i] && x < llx[i]+ilx ) {
02430       posx = x - llx[i] ;
02431           posy = y - lly[i] ;
02432 
02433       for ( z = z_min,m=0 ; z < z_max ; z++,m++ ) {
02434         t_img=cpl_imagelist_get(tmpcubes[i],m);
02435             ptdata=cpl_image_get_data_float(t_img);
02436             m_img=cpl_imagelist_get(mask,z);
02437             pmdata=cpl_image_get_data_float(m_img);
02438             mlx=cpl_image_get_size_x(m_img);
02439 
02440             if (!isnan(ptdata[posx+posy*ilx]) &&
02441         ptdata[posx+posy*ilx] != 0.) {
02442           pmdata[x+y*mlx] += (float)exptimes[i]  ;
02443         }
02444       }
02445     }
02446       }
02447     }
02448   }
02449   return 0;
02450 }
02451 
02452 
02453 
02454 
02455 
02506 int
02507 sinfo_new_combine_jittered_cubes_range ( cpl_imagelist ** cubes,
02508                                  cpl_imagelist  * mergedCube,
02509                                  cpl_imagelist  * mask,
02510                                  int        n_cubes,
02511                                  float    * cumoffsetx,
02512                                  float    * cumoffsety,
02513                                  double    * exptimes,
02514                                  char     * kernel_type,
02515                                  const int z_min, const int z_max )
02516 {
02517 
02518   int i;
02519   int llx0, lly0 ;
02520   cpl_imagelist ** tmpcubes=NULL ;
02521   int* llx=NULL ;
02522   int* lly=NULL ;
02523   float* sub_offsetx=NULL ;
02524   float* sub_offsety=NULL ;
02525 
02526   int ilx=0;
02527   int ily=0;
02528   int olx=0;
02529   int oly=0;
02530   int mlx=0;
02531   int mly=0;
02532 
02533   cpl_image* i_img=NULL;
02534   cpl_image* o_img=NULL;
02535 
02536 
02537   if(sinfo_check_input(cubes,n_cubes,cumoffsetx,cumoffsety,exptimes) == -1) {
02538     return -1;
02539   }
02540 
02541     o_img=cpl_imagelist_get(mergedCube,z_min);
02542     olx=cpl_image_get_size_x(o_img);
02543     oly=cpl_image_get_size_y(o_img);
02544     i_img=cpl_imagelist_get(cubes[0],0);
02545     ilx=cpl_image_get_size_x(i_img);
02546     ily=cpl_image_get_size_y(i_img);
02547     mlx=olx;
02548     mly=oly;
02549 
02550 
02551     /*--------------------------------------------------------------------
02552      * center the cubes within the allocated big cube
02553      * that means define the (0,0) positions of the cubes in the image planes
02554      * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
02555      */
02556     /* position of first reference frame, centered in big cube */
02557     llx0 = olx/2 - ilx/2 ;
02558     lly0 = oly/2 - ily/2 ;
02559 
02560     /*--------------------------------------------------------------------
02561      * go through the frame list and determine the lower left edge position
02562      * of the shifted cubes. Additionnally, the sub-pixel offsets are
02563      * determined.
02564      */
02565 
02566 
02567     llx=cpl_calloc(n_cubes,sizeof(int)) ;
02568     lly=cpl_calloc(n_cubes,sizeof(int)) ;
02569     sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
02570     sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
02571 
02572     for ( i = 0 ; i < n_cubes ; i++ )
02573     {
02574         llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
02575         sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
02576         lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
02577         sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
02578     }
02579 
02580     tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
02581     /* -------------------------------------------------------------
02582      * shift the cubes according to the computed sub-pixel offsets
02583      * that means shift the single image planes of each cube
02584      * first determine an interpolation kernel
02585      */
02586     if(sinfo_shift_cubes(tmpcubes,kernel_type,n_cubes,cubes,z_min, z_max,
02587              sub_offsetx,sub_offsety,mlx,mly,mask) == -1) {
02588       return -1;
02589     }
02590 
02591 
02592     /*-----------------------------------------------------------------------
02593      * Build the mask data cube.
02594      * The mask is 0 where no data is available, otherwise the
02595        integration time of
02596      * one frame, respectively the summed integration
02597      * times in the overlapping regions are inserted
02598      */
02599     /* go through the frame list */
02600     sinfo_build_mask_cube(z_min,z_max,olx,oly,n_cubes,llx,lly,exptimes,
02601                           cubes,tmpcubes,mask);
02602 
02603 
02604     /* calculate a weighted average using the exposure time of the
02605        single frames of the overlapping regions of the cubes */
02606 
02607     sinfo_compute_weight_average(z_min,z_max,ilx,ily,n_cubes,mergedCube,mask,
02608                                  tmpcubes,exptimes,llx,lly);
02609 
02610     /* convert the "free space" in the cube to blank pixels */
02611      /* convert_0_to_ZERO_for_cubes(mergedCube) ; */
02612 
02613     for( i = 0 ; i < n_cubes ; i++ )
02614     {
02615         cpl_imagelist_delete (tmpcubes[i]) ;
02616     }
02617 
02618 
02619     cpl_free(tmpcubes) ;
02620     cpl_free(llx) ;
02621     cpl_free(lly) ;
02622     cpl_free(sub_offsetx) ;
02623     cpl_free(sub_offsety) ;
02624 
02625      return 0 ;
02626 }
02627 
02645 static int
02646 sinfo_check_input(cpl_imagelist** cubes,
02647                           const int n_cubes,
02648                           float* cumoffsetx,
02649                           float* cumoffsety,
02650               double* exptimes)
02651 {
02652    if ( cubes == NULL )
02653     {
02654         sinfo_msg_error ("no cube list given!") ;
02655         return -1 ;
02656     }
02657     if ( n_cubes <= 0 )
02658     {
02659         sinfo_msg_error ("wrong number of data cubes in list!") ;
02660         return -1 ;
02661     }
02662     if ( cumoffsetx == NULL || cumoffsety == NULL )
02663     {
02664         sinfo_msg_error ("no cumoffsetx/y given!") ;
02665         return -1;
02666     }
02667     if ( exptimes == NULL )
02668     {
02669         sinfo_msg_error ("no exposure time array given!") ;
02670         return -1 ;
02671     }
02672 
02673     return 0;
02674 }
02675 
02701 static int
02702 sinfo_compute_weight_average(const int z_min,
02703                              const int z_max,
02704                              const int ilx,
02705                              const int ily,
02706                  const int n_cubes,
02707                              cpl_imagelist* mergedCube,
02708                              cpl_imagelist* mask,
02709                              cpl_imagelist** tmpcubes,
02710                  double* exptimes,
02711                              int* llx,
02712                              int* lly)
02713 {
02714 
02715   int m=0;
02716   int x=0;
02717   int y=0;
02718   int z=0;
02719   int i=0;
02720 
02721   int mlx=0;
02722   int mly=0;
02723   int olx=0;
02724   int oly=0;
02725 
02726   cpl_image* o_img=NULL;
02727   cpl_image* m_img=NULL;
02728   cpl_image* t_img=NULL;
02729 
02730   float* podata=NULL;
02731   float* pmdata=NULL;
02732   float* ptdata=NULL;
02733   double weight=0;
02734 
02735   int posx=0;
02736   int posy=0;
02737 
02738 
02739   o_img=cpl_imagelist_get(mergedCube,z_min);
02740   olx=cpl_image_get_size_x(o_img);
02741   oly=cpl_image_get_size_y(o_img);
02742   mlx=olx;
02743   mly=oly;
02744 
02745   /* calculate a weighted average using the exposure time of the
02746      single frames of the overlapping regions of the cubes */
02747   for ( z = z_min, m = 0 ; z < z_max ; z++, m++ ) {
02748     o_img=cpl_imagelist_get(mergedCube,z);
02749     podata=cpl_image_get_data_float(o_img);
02750     m_img=cpl_imagelist_get(mask,z);
02751     pmdata=cpl_image_get_data_float(m_img);
02752     mlx=cpl_image_get_size_x(m_img);
02753 
02754     /* go through the first image plane of the big data cube */
02755     for ( y = 0 ; y < oly ; y++ ) {
02756       for ( x = 0 ; x < olx ; x++ ) {
02757 
02758        /* find the position of the present cube and
02759           go through the single spectra */
02760 
02761     for ( i = 0 ; i < n_cubes ; i++ ) {
02762 
02763           if ( y >= lly[i] && y < lly[i]+ily &&
02764                x >= llx[i] && x < llx[i]+ilx ) {
02765         posx = x - llx[i] ;
02766             posy = y - lly[i] ;
02767 
02768             t_img=cpl_imagelist_get(tmpcubes[i],m);
02769             ptdata=cpl_image_get_data_float(t_img);
02770             /* To prevent black regions in peculiar batterfly cases
02771               podata[x+y*olx]=0;
02772             */
02773         if (!isnan(ptdata[posx+posy*ilx])) {
02774           if (pmdata[x+y*mlx] != 0.) {
02775                 /* adjust the intensities to the
02776                    first reference cube */
02777         weight = exptimes[0] / pmdata[x+y*mlx] ;
02778           } else {
02779         weight = 0. ;
02780           }
02781               podata[x+y*olx] += weight*ptdata[posx+posy*ilx] ;
02782 
02783         }
02784       }
02785     }
02786       }
02787     }
02788   }
02789   return 0;
02790 }
02791 
02792 
02832 static int
02833 sinfo_shift_cubes(cpl_imagelist** tmpcubes,
02834                   char* kernel_type,
02835                   const int n_cubes,
02836                   cpl_imagelist** cubes,
02837                   const int z_min,
02838                   const int z_max,
02839                   float* sub_offsetx,
02840                   float* sub_offsety,
02841                   const int mlx,
02842                   const int mly,
02843                   cpl_imagelist* mask)
02844 {
02845 
02846    double * kernel ;
02847    int i=0;
02848    cpl_image* i_img=NULL;
02849    int ilx=0;
02850    int ily=0;
02851    int inp=0;
02852    pixelvalue * tmpspace;
02853    int z=0;
02854    cpl_image* t_img=NULL;
02855    cpl_image* m_img=NULL;
02856    int m=0;
02857 
02858     /* -------------------------------------------------------------
02859      * shift the cubes according to the computed sub-pixel offsets
02860      * that means shift the single image planes of each cube
02861      * first determine an interpolation kernel
02862      */
02863 
02864    if ( NULL == (kernel = sinfo_generate_interpolation_kernel(kernel_type)) )
02865     {
02866         sinfo_msg_warning ("could not generate desired interpolation kernel"
02867                            "or no kernel_typ was given, the default kernel"
02868                            "is used now!") ;
02869     }
02870     /* go through the frame list */
02871 
02872     for ( i = 0 ; i < n_cubes ; i++ )
02873     {
02874 
02875       i_img=cpl_imagelist_get(cubes[i],0);
02876       ilx=cpl_image_get_size_x(i_img);
02877       ily=cpl_image_get_size_y(i_img);
02878       inp=cpl_imagelist_get_size(cubes[i]);
02879       tmpspace = cpl_calloc(ilx, ily*sizeof(pixelvalue)) ;
02880       tmpcubes[i]=cpl_imagelist_new();
02881 
02882         for ( z = z_min, m=0 ; z < z_max ; z++, m++ )
02883         {
02884               t_img=sinfo_new_shift_image(cpl_imagelist_get(cubes[i],z),
02885                                           sub_offsetx[i],
02886                                           sub_offsety[i],
02887                                           kernel);
02888 
02889         if (t_img==NULL)
02890             {
02891                 sinfo_msg_error("could not shift image plane no %d "
02892                                 "in cube no %d!", z, i) ;
02893                 cpl_free(kernel) ;
02894                 return -1 ;
02895             }
02896 
02897             cpl_imagelist_set(tmpcubes[i],t_img,m);
02898             m_img=cpl_image_new(mlx,mly,CPL_TYPE_FLOAT);
02899             cpl_imagelist_set(mask,m_img,z);
02900         }
02901 
02902      cpl_free(tmpspace);
02903 
02904     }
02905     if(kernel != NULL) cpl_free(kernel) ;
02906 
02907     return 0;
02908 
02909 }
02910 
02911 
02912 /* Temporally commented out as not yet used
02913 static int
02914 sinfo_ks_clip(
02915           const int n_cubes,
02916               const int nc,
02917           const int ilx,
02918           const int ily,
02919           const double kappa,
02920           int* llx,
02921           int* lly,
02922           double* exptimes,
02923           cpl_imagelist** tmpcubes,
02924               float* podata,
02925               float* pmdata,
02926           const int x,
02927           const int y,
02928           const int m,
02929           const int mlx,
02930           const int olx
02931   )
02932 {
02933 
02934 
02935   int posx=0;
02936   int posy=0;
02937   int i=0;
02938   int nclip=0;
02939   int ks=0;
02940 
02941   float sig=0;
02942   float med=0;
02943   float ovr=0;
02944   float avg=0;
02945 
02946   float* ptdata=NULL;
02947   float* pvdata=NULL;
02948 
02949   cpl_image* t_img=NULL;
02950   float  msk_sum=0;
02951   float  val_msk_sum=0;
02952   cpl_image* v_img=NULL;
02953 
02954   cpl_vector* val=NULL;
02955   cpl_vector* msk=NULL;
02956 
02957   msk=cpl_vector_new(n_cubes);
02958   for (i=0;i<n_cubes;i++) {
02959     cpl_vector_set(msk,i,1);
02960   }
02961 
02962   // k-s clipping
02963   nclip=0;
02964 
02965   for (ks=0;ks<nc;ks++) {
02966 
02967     sig=0;
02968     med=0;
02969     ovr=0;
02970     if(nc-nclip >0) {
02971       val=cpl_vector_new(nc-nclip);
02972     }
02973 
02974     // fill val
02975     for ( i = 0 ; i < n_cubes ; i++ ) {
02976       t_img=cpl_imagelist_get(tmpcubes[i],m);
02977       ptdata=cpl_image_get_data_float(t_img);
02978       if ( y >= lly[i] && y < lly[i]+ily &&
02979        x >= llx[i] && x < llx[i]+ilx ) {
02980     posx = x - llx[i] ;
02981     posy = y - lly[i] ;
02982     if (!isnan(ptdata[posx+posy*ilx]) &&
02983         ptdata[posx+posy*ilx] != 0. &&
02984         (cpl_vector_get(msk,i) != 0)) {
02985       cpl_vector_set(val,ovr,(double)ptdata[posx+posy*ilx]);
02986       ovr++;
02987     }
02988       }
02989     }
02990 
02991     // get avg, med, sig
02992     if(ovr>0) {
02993       avg=cpl_vector_get_mean(val);
02994       med=cpl_vector_get_median_const(val);
02995       if(ovr>1) {
02996     sig=cpl_vector_get_stdev(val);
02997       } else {
02998     sig=0;
02999       }
03000       cpl_vector_delete(val);
03001     }
03002 
03003     for ( i = 0 ; i < n_cubes ; i++ ) {
03004       t_img=cpl_imagelist_get(tmpcubes[i],m);
03005       ptdata=cpl_image_get_data_float(t_img);
03006       // Do k-s clipping at each pixel
03007       if ( y >= lly[i] && y < lly[i]+ily &&
03008        x >= llx[i] && x < llx[i]+ilx ) {
03009     posx = x - llx[i] ;
03010     posy = y - lly[i] ;
03011     //sinfo_msg_warning("llx[%d]=%d lly[%d],=%d",i,llx[i],i,lly[i]);
03012     //sinfo_msg_warning("posx=%d posy=%d",posx,posy);
03013     if (!isnan(ptdata[posx+posy*ilx]) &&
03014         ptdata[posx+posy*ilx] != 0. &&
03015         (cpl_vector_get(msk,i) != 0)) {
03016       if(abs((ptdata[posx+posy*ilx]-med))> kappa*sig) {
03017         ptdata[posx+posy*ilx]=0;
03018 
03019         pmdata[x+y*mlx] -= exptimes[i]  ;
03020 
03021         cpl_vector_set(msk,i,0);
03022         nclip++;
03023       }
03024     }
03025       }
03026 
03027     }
03028   }
03029 
03030   msk_sum=0;
03031   val_msk_sum=0;
03032   for ( i = 0 ; i < n_cubes ; i++ ) {
03033     v_img=cpl_imagelist_get(tmpcubes[i],m);
03034     pvdata=cpl_image_get_data_float(v_img);
03035     // computes sky at each point
03036     if ( y >= lly[i] && y < lly[i]+ily &&
03037      x >= llx[i] && x < llx[i]+ilx ) {
03038       posx = x - llx[i] ;
03039       posy = y - lly[i] ;
03040       if (!isnan(pvdata[posx+posy*ilx]) &&
03041       pvdata[posx+posy*ilx] != 0. &&
03042       (cpl_vector_get(msk,i) != 0)) {
03043 
03044     msk_sum+= pmdata[x+y*mlx];
03045 
03046     val_msk_sum+=pvdata[posx+posy*ilx]*
03047       pmdata[x+y*mlx];
03048 
03049       }
03050     }
03051   }
03052 
03053   podata[x+y*olx]=val_msk_sum/msk_sum;
03054   cpl_vector_delete(msk);
03055 
03056   return 0;
03057 
03058 }
03059 
03060 */
03061 
03111 int
03112 sinfo_new_combine_jittered_cubes_thomas_range(cpl_imagelist ** cubes,
03113                     cpl_imagelist  * mergedCube,
03114                     cpl_imagelist  * mask,
03115                     int        n_cubes,
03116                     float    * cumoffsetx,
03117                     float    * cumoffsety,
03118                     double    * exptimes,
03119                     char     * kernel_type,
03120                     const int z_min,
03121                     const int z_max,
03122                                     const double kappa )
03123 {
03124     const int VERY_BIG_INT = 268431360;
03125   int i ;
03126   int llx0, lly0 ;
03127   int* llx=NULL;
03128   int* lly=NULL ;
03129   float* sub_offsetx=NULL ;
03130   float* sub_offsety=NULL ;
03131   cpl_imagelist ** tmpcubes=NULL ;
03132   const int z_siz=z_max-z_min;
03133   int ilx=0;
03134   int ily=0;
03135   int olx=0;
03136   int oly=0;
03137   int mlx=0;
03138   int mly=0;
03139   int onp=0;
03140   cpl_image* i_img=NULL;
03141   cpl_image* o_img=NULL;
03142   int min_lx = VERY_BIG_INT;
03143   int min_ly = VERY_BIG_INT;
03144 
03145 
03146   if(sinfo_check_input(cubes,n_cubes,cumoffsetx,cumoffsety,exptimes) == -1) {
03147     return -1;
03148   }
03149 
03150   if (z_siz <= 0 ){
03151     sinfo_msg_error ("z_max <= z_min given!") ;
03152     return -1 ;
03153   }
03154 
03155   i_img=cpl_imagelist_get(cubes[0],0);
03156   o_img=cpl_imagelist_get(mergedCube,0);
03157   ilx=cpl_image_get_size_x(i_img);
03158   ily=cpl_image_get_size_y(i_img);
03159   olx=cpl_image_get_size_x(o_img);
03160   oly=cpl_image_get_size_y(o_img);
03161   mlx=olx;
03162   mly=oly;
03163 //  sinfo_msg_warning(" cube size [%d:%d] merged cube size[%d:%d]" , ilx, ily, olx, oly);
03164   /*--------------------------------------------------------------------
03165    * center the cubes within the allocated big cube
03166    * that means define the (0,0) positions of the cubes in the image planes
03167    * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
03168    */
03169   /* position of first reference frame, centered in big cube */
03170   llx0 = (1.0 * olx- 1.0 * ilx)/2.0 ;
03171   lly0 = (1.0 * oly - 1.0 * ily)/2.0 ;
03172 //  sinfo_msg_warning(" zero point [%d:%d]" , llx0, lly0);
03173   /*--------------------------------------------------------------------
03174    * go through the frame list and determine the lower left edge position
03175    * of the shifted cubes. Additionnally, the sub-pixel offsets are
03176    * determined.
03177    */
03178 
03179   llx=cpl_calloc(n_cubes,sizeof(int));
03180   lly=cpl_calloc(n_cubes,sizeof(int)) ;
03181   sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
03182   sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
03183 
03184   for ( i = 0 ; i < n_cubes ; i++ ) {
03185     llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
03186 
03187     sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
03188     lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
03189     sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
03190 /*    sinfo_msg_warning("suboff[%d]= %f %f  ll[%d:%d] cumoffset[%f:%f]" ,
03191             i,sub_offsetx[i],sub_offsety[i], llx[i], lly[i],
03192             cumoffsetx[i], cumoffsety[i]);*/
03193     if (llx[i] < min_lx)
03194     {
03195         min_lx = llx[i];
03196     }
03197     if (lly[i] < min_ly)
03198     {
03199         min_ly = lly[i];
03200     }
03201   }
03202   /***********---------
03203    * "normalize" the shift - minimum should be 0
03204    **********************************************/
03205   if (min_lx != 0)
03206   {
03207     for (i = 0 ; i < n_cubes ; i++ )
03208     {
03209         llx[i] = llx[i] - min_lx;
03210     }
03211   }
03212   if (min_ly != 0)
03213   {
03214     for (i = 0 ; i < n_cubes ; i++ )
03215     {
03216         lly[i] = lly[i] - min_ly;
03217     }
03218   }
03219 
03220   /* -------------------------------------------------------------
03221    * shift the cubes according to the computed sub-pixel offsets
03222    * that means shift the single image planes of each cube
03223    * first determine an interpolation kernel
03224    */
03225 
03226   tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
03227 
03228   if(sinfo_shift_cubes(tmpcubes,kernel_type,n_cubes,cubes,z_min, z_max,
03229                sub_offsetx,sub_offsety,mlx,mly,mask) == -1) {
03230     return -1;
03231 
03232   }
03233 
03234 
03235   /*-------------------------------------------------------------------------
03236    * Build the mask data cube.
03237    * The mask is 0 where no data is available, otherwise the integration
03238    * time of one frame, respectively the summed integration
03239    * times in the overlapping regions are inserted
03240    */
03241   /* go through the frame list */
03242 
03243 
03244   o_img=cpl_imagelist_get(mergedCube,0);
03245   olx=cpl_image_get_size_x(o_img);
03246   oly=cpl_image_get_size_y(o_img);
03247   onp=cpl_imagelist_get_size(mergedCube);
03248 
03249   if(-1 == sinfo_build_mask_cube_thomas(z_min,z_max,olx,oly,n_cubes,llx,lly,
03250                     exptimes,cubes,tmpcubes,mask) ) {
03251     return -1;
03252   }
03254 /*
03255   check_nomsg(sinfo_coadd_with_ks_clip_optimized(z_min,z_max,n_cubes,
03256                                            kappa,llx,lly,
03257                                            exptimes,mask,mergedCube,tmpcubes));
03258 */
03261   check_nomsg(sinfo_coadd_with_ks_clip2(z_min,z_max,ilx,ily,n_cubes,kappa,llx,lly,
03262                                         exptimes,mask,mergedCube,tmpcubes));
03263 
03265   /* convert the "free space" in the cube to blank pixels */
03266   /* convert_0_to_ZERO_for_cubes(mergedCube) ; */
03267   /* convert_0_to_ZERO_for_cubes(mergedSky) ; */
03268   //cpl_free(kernel) ; /* originated by eclise-malloc */
03269 
03270   cleanup:
03271 
03272   for( i = 0 ; i < n_cubes ; i++ ) {
03273     cpl_imagelist_delete (tmpcubes[i]) ;
03274   }
03275 
03276   cpl_free(tmpcubes);
03277   cpl_free(llx);
03278   cpl_free(lly) ;
03279   cpl_free(sub_offsetx) ;
03280   cpl_free(sub_offsety) ;
03281   sinfo_print_rec_status(0);
03282 
03283   return 0 ;
03284 }
03285 
03299 cpl_imagelist *
03300 sinfo_new_interpol_cube_simple( cpl_imagelist * cube,
03301                       cpl_imagelist * badcube,
03302                       int       maxdist )
03303 {
03304   cpl_imagelist * intercube ;
03305   float*     goodNeighbors=NULL ;
03306   int z, row, col ;
03307   int nx, ny, nz ;
03308   int llx, lly, llz ;
03309   int zi, coli, rowi ;
03310   int n ;
03311 
03312 
03313 
03314 
03315   int clx=0;
03316   int cly=0;
03317   int blx=0;
03318   int bly=0;
03319 
03320   int cnp=0;
03321 
03322 
03323   float* pbdata=NULL;
03324   float* pidata=NULL;
03325   float* pbzidata=NULL;
03326   float* pczidata=NULL;
03327 
03328   cpl_image* c_img=NULL;
03329   cpl_image* b_img=NULL;
03330   cpl_image* i_img=NULL;
03331 
03332   cpl_image* bzi_img=NULL;
03333   cpl_image* czi_img=NULL;
03334 
03335 
03336 
03337     if ( cube == NULL || badcube == NULL )
03338     {
03339         sinfo_msg_error("no cube given!") ;
03340         return NULL ;
03341     }
03342     if ( maxdist < 1 )
03343     {
03344         sinfo_msg_error("wrong maxrad given!") ;
03345         return NULL ;
03346     }
03347     intercube = cpl_imagelist_duplicate(cube) ;
03348 
03349     goodNeighbors=cpl_calloc((2*maxdist+1)*(2*maxdist+1)*(2*maxdist+1) -1,
03350                              sizeof(float)) ;
03351 
03352     cnp=cpl_imagelist_get_size(cube);
03353     for ( z = 0 ; z < cnp ; z++ )
03354     {
03355       b_img=cpl_imagelist_get(badcube,z);
03356       i_img=cpl_imagelist_get(intercube,z);
03357       pbdata=cpl_image_get_data_float(b_img);
03358       pidata=cpl_image_get_data_float(i_img);
03359       blx=cpl_image_get_size_x(b_img);
03360       bly=cpl_image_get_size_y(b_img);
03361 
03362       c_img=cpl_imagelist_get(cube,z);
03363       clx=cpl_image_get_size_x(c_img);
03364       cly=cpl_image_get_size_y(c_img);
03365 
03366         for ( row = 0 ; row < cly ; row++ )
03367         {
03368             for ( col = 0 ; col < clx ; col++ )
03369             {
03370                 if ( pbdata[col+row*clx] == 0 )
03371                 {
03372                     /* determine the lower left sinfo_edge of the cube */
03373                     llx = col - maxdist ;
03374                     nx = 2*maxdist +1 ;
03375                     if (llx < 0)
03376                     {
03377                        nx += llx ;
03378                        llx = 0 ;
03379                     }
03380                     if ( llx + nx > clx )
03381                     {
03382                         nx -= (llx + nx - clx) ;
03383                     }
03384 
03385                     lly = row - maxdist ;
03386                     ny = 2*maxdist +1 ;
03387                     if (lly < 0)
03388                     {
03389                        ny += lly ;
03390                        lly = 0 ;
03391                     }
03392                     if ( lly + ny > cly )
03393                     {
03394                         ny -= (lly + ny - cly) ;
03395                     }
03396 
03397                     llz = z - maxdist ;
03398                     nz = 2*maxdist +1 ;
03399                     if (llz < 0)
03400                     {
03401                        nz += llz ;
03402                        llz = 0 ;
03403                     }
03404                     if ( llz + nz > cnp )
03405                     {
03406                         nz -= (llz + nz - cnp) ;
03407                     }
03408                     n = 0 ;
03409                     for ( zi = llz ; zi < llz+nz ; zi++ )
03410                     {
03411               bzi_img=cpl_imagelist_get(badcube,zi);
03412               czi_img=cpl_imagelist_get(cube,zi);
03413                       pbzidata=cpl_image_get_data_float(bzi_img);
03414                       pczidata=cpl_image_get_data_float(czi_img);
03415 
03416                         for ( rowi = lly ; rowi < lly+ny ; rowi++ )
03417                         {
03418                             for ( coli = llx ; coli < llx+nx ; coli++ )
03419                             {
03420                                 if ( pbzidata[coli+rowi*blx] == 1 )
03421                                 {
03422                   goodNeighbors[n] = pczidata[coli+rowi*clx] ;
03423                   n++ ;
03424                                 }
03425                             }
03426                         }
03427                     }
03428                     if ( n > 0 )
03429                     {
03430                         pidata[col+row*clx]=sinfo_new_median(goodNeighbors,n);
03431                         pbdata[col+row*clx]=1 ;
03432                     }
03433                     else
03434                     {
03435                         continue ;
03436                     }
03437                 }
03438             }
03439         }
03440     }
03441     cpl_free(goodNeighbors) ;
03442     return intercube ;
03443 }
03444 
03445 
03446 
03447 
03448 
03501 cpl_imagelist *
03502 sinfo_new_combine_cubes ( cpl_imagelist ** cubes,
03503                          cpl_imagelist  * mergedCube,
03504                          int        n_cubes,
03505                          float    * cumoffsetx,
03506                          float    * cumoffsety,
03507                          float      factor,
03508                          char     * kernel_type )
03509 {
03510   int i=0 ;
03511   int x=0;
03512   int y=0;
03513   int z=0;
03514   int llx0=0;
03515   int lly0=0;
03516   int posx=0;
03517   int posy=0;
03518   cpl_imagelist * mask=NULL ;
03519   double * kernel=NULL ;
03520   cpl_image * shiftedImage=NULL ;
03521   int n=0;
03522   int ns=0;
03523   double sum=0;
03524   double sum2=0;
03525   double mean=0;
03526   double sigma=0;
03527 
03528   cpl_imagelist ** tmpcubes=NULL ;
03529 
03530   int* llx=NULL ;
03531   int* lly=NULL ;
03532 
03533   float* sub_offsetx=NULL ;
03534   float* sub_offsety=NULL ;
03535   float* cubedata=NULL ;
03536 
03537   int mlx=0;
03538   int mly=0;
03539   int clx=0;
03540   int cly=0;
03541   int mnp=0;
03542   int cnp=0;
03543 
03544 
03545   float* ptdata=NULL;
03546   float* podata=NULL;
03547   float* pmdata=NULL;
03548 
03549   cpl_image* tmp_img=NULL;
03550   cpl_image* o_img=NULL;
03551   cpl_image* m_img=NULL;
03552   cpl_image* c_img=NULL;
03553   cpl_image* t_img=NULL;
03554 
03555 
03556 
03557 
03558   if ( cubes == NULL )
03559     {
03560         sinfo_msg_error ("no cube list given!") ;
03561         return NULL ;
03562     }
03563 
03564 
03565   if ( mergedCube == NULL )
03566     {
03567         sinfo_msg_error ("no out cube  given!") ;
03568         return NULL ;
03569     }
03570 
03571 
03572     if ( n_cubes <= 0 )
03573     {
03574         sinfo_msg_error ("wrong number of data cubes in list!") ;
03575         return NULL ;
03576     }
03577     if ( cumoffsetx == NULL || cumoffsety == NULL )
03578     {
03579         sinfo_msg_error ("no cumoffsetx/y given!") ;
03580         return NULL;
03581     }
03582 
03583   if ( factor <= 0. )
03584     {
03585         sinfo_msg_error ("wrong factor given!") ;
03586         return NULL ;
03587     }
03588 
03589   m_img=cpl_imagelist_get(mergedCube,0);
03590   mlx=cpl_image_get_size_x(m_img);
03591   mly=cpl_image_get_size_y(m_img);
03592   cnp=cpl_imagelist_get_size(cubes[0]);
03593   c_img=cpl_imagelist_get(cubes[0],0);
03594   clx=cpl_image_get_size_x(c_img);
03595   cly=cpl_image_get_size_y(c_img);
03596 
03597 
03598   tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
03599 
03600         /* allocation for a cube structure without the image planes  */
03601     /*
03602    for ( i = 0 ; i < n_cubes ; i++ )
03603     {
03604          tmpcubes[i] = (cpl_imagelist*)cpl_malloc(sizeof(cpl_imagelist)) ;
03605         tmpcubes[i]->plane = (cpl_image**)cpl_calloc(cubes[0]->np ,
03606                               sizeof(cpl_image*)) ;
03607 
03608         tmpcubes[i]->lx = cubes[0]->lx ;
03609         tmpcubes[i]->ly = cubes[0]->ly ;
03610         tmpcubes[i]->np = cubes[0]->np ;
03611         tmpcubes[i]->nbpix = (ulong32)cubes[0]->lx *
03612                              (ulong32)cubes[0]->ly *
03613                              (ulong32)cubes[0]->np ;
03614         tmpcubes[i]->history = (char*)NULL ;
03615         tmpcubes[i]->n_comments = 0 ;
03616         tmpcubes[i]->orig_ptype = BPP_DEFAULT ;
03617         tmpcubes[i]->filename = NULL ;
03618     }
03619     */
03620     tmpcubes[0]=cpl_imagelist_duplicate(cubes[0]);
03621 
03622     /*--------------------------------------------------------------------
03623      * center the cubes within the allocated big cube
03624      * that means define the (0,0) positions of the cubes in the image planes
03625      * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
03626      */
03627     /* position of first reference frame, centered in big cube */
03628     llx0 = mlx/2 - clx/2 ;
03629     lly0 = mly/2 - cly/2 ;
03630 
03631     /*--------------------------------------------------------------------
03632      * go through the frame list and determine the lower left edge position
03633      * of the shifted cubes. Additionnally, the sub-pixel offsets are
03634      * determined.
03635      */
03636 
03637 
03638     llx=cpl_calloc(n_cubes,sizeof(int)) ;
03639     lly=cpl_calloc(n_cubes,sizeof(int)) ;
03640     sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
03641     sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
03642 
03643     for ( i = 0 ; i < n_cubes ; i++ )
03644     {
03645         llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
03646         sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
03647         lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
03648         sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
03649     }
03650 
03651     /* -------------------------------------------------------------
03652      * shift the cubes according to the computed sub-pixel offsets
03653      * that means shift the single image planes of each cube
03654      * first determine an interpolation kernel
03655      */
03656     if ( NULL == (kernel = sinfo_generate_interpolation_kernel(kernel_type)) )
03657     {
03658         sinfo_msg_warning ("could not generate desired interpolation kernel"
03659                            " or no kernel_typ was given, the default kernel"
03660                            " is used now!") ;
03661     }
03662     /* go through the frame list */
03663     for ( i = 0 ; i < n_cubes ; i++ )
03664     {
03665       /* go through the image planes and shift each plane by a
03666          sub-pixel value */
03667       for ( z = 0 ; z < cnp ; z++ )
03668         {
03669       tmp_img=cpl_imagelist_get(cubes[i],z);
03670       if ( NULL == (shiftedImage = sinfo_new_shift_image(tmp_img,
03671                                sub_offsetx[i],
03672                                sub_offsety[i],
03673                                kernel ) ) )
03674             {
03675           sinfo_msg_error ("could not shift image plane no %d "
03676                                "in cube no %d!", z, i) ;
03677           cpl_imagelist_delete(mergedCube) ;
03678           cpl_imagelist_delete(mask) ;
03679           cpl_free(kernel) ;
03680           return NULL ;
03681             }
03682       cpl_imagelist_set(tmpcubes[i],shiftedImage,z);
03683         }
03684     }
03685 
03686     cubedata=cpl_calloc(n_cubes,sizeof(float)) ;
03687 
03688     for ( y = 0 ; y < mly ; y++ )
03689     {
03690         for ( x = 0 ; x < mlx ; x++ )
03691         {
03692             for ( z = 0 ; z < mnp ; z++ )
03693             {
03694                 sum = 0. ;
03695                 sum2 = 0. ;
03696                 n = 0 ;
03697                 for ( i = 0 ; i < n_cubes ; i++ )
03698                 {
03699           c_img=cpl_imagelist_get(cubes[i],z);
03700 
03701           clx=cpl_image_get_size_x(c_img);
03702           cly=cpl_image_get_size_y(c_img);
03703 
03704           t_img=cpl_imagelist_get(tmpcubes[i],z);
03705                   ptdata=cpl_image_get_data_float(t_img);
03706 
03707           m_img=cpl_imagelist_get(mergedCube,z);
03708                   pmdata=cpl_image_get_data_float(m_img);
03709           o_img=cpl_imagelist_get(mask,z);
03710                   podata=cpl_image_get_data_float(o_img);
03711                   /*
03712                     find the position of the present cube and go
03713                     through the single spectra
03714                    */
03715                     if ( y >= lly[i] && y < lly[i]+cly &&
03716                          x >= llx[i] && x < llx[i]+clx )
03717                     {
03718                         posx = x - llx[i] ;
03719                         posy = y - lly[i] ;
03720                         if (!isnan(ptdata[posx+posy*clx]))
03721                         {
03722                             sum += ptdata[posx+posy*clx] ;
03723                             sum2 += (ptdata[posx+posy*clx] *
03724                                      ptdata[posx+posy*clx]) ;
03725                             cubedata[n] = ptdata[posx+posy*clx] ;
03726                             n++ ;
03727                         }
03728                     }
03729                 }
03730 
03731                 if ( n == 0 )
03732                 {
03733                     mean = 0. ;
03734                     sigma = 0. ;
03735                     pmdata[x+y*mlx] = 0. ;
03736                     podata[x+y*mlx] = 0 ;
03737                 }
03738                 else if ( n == 1 )
03739                 {
03740                     mean = sum ;
03741                     sigma = 0. ;
03742                     pmdata[x+y*mlx] = mean ;
03743                     podata[x+y*mlx] = 1 ;
03744                 }
03745                 else
03746                 {
03747                     mean = sum/(double)n ;
03748                     sigma = sqrt( (sum2 - sum*mean) / (double)(n - 1) ) ;
03749                     ns = 0 ;
03750                     for ( i = 0 ; i < n ; i++ )
03751                     {
03752                         if ( cubedata[i] > mean+factor*sigma ||
03753                              cubedata[i] < mean-factor*sigma )
03754                         {
03755                             continue ;
03756                         }
03757                         else
03758                         {
03759                             pmdata[x+y*mlx] += cubedata[i] ;
03760                             ns++ ;
03761                         }
03762                     }
03763                     if ( ns == 0 )
03764                     {
03765                         pmdata[x+y*mlx] = 0. ;
03766                     }
03767                     else
03768                     {
03769                         pmdata[x+y*mlx] /= (float)ns ;
03770                     }
03771                     podata[x+y*mlx] = (float)ns ;
03772                 }
03773             }
03774         }
03775     }
03776 
03777     for( i = 0 ; i < n_cubes ; i++ )
03778     {
03779         cpl_imagelist_delete (tmpcubes[i]) ;
03780     }
03781     cpl_free(tmpcubes);
03782     cpl_free(llx);
03783     cpl_free(lly);
03784     cpl_free(sub_offsetx);
03785     cpl_free(sub_offsety);
03786     cpl_free(cubedata);
03787 
03788     /* convert the "free space" in the cube to blank pixels */
03789     sinfo_new_convert_0_to_ZERO_for_cubes(mergedCube) ;
03790     cpl_free(kernel) ;
03791     return mask ;
03792 }
03793 
03794 cpl_imagelist *
03795 sinfo_new_bin_cube(cpl_imagelist *cu,
03796                              int xscale,
03797                              int yscale,
03798                              int xmin,
03799                              int xmax,
03800                              int ymin,
03801                              int ymax)
03802 {
03803   int i,j,k;
03804   cpl_imagelist * cube;
03805   int ilx=0;
03806   int ily=0;
03807   int olx=0;
03808   int oly=0;
03809   int inp=0;
03810 
03811   float* pidata=NULL;
03812   float* podata=NULL;
03813   cpl_image* i_img=NULL;
03814   cpl_image* o_img=NULL;
03815 
03816 
03817   /* old code
03818   if (NULL == (cube = sinfo_newCube (xmax-xmin+1,ymax-ymin+1, cu->np)) )
03819   {
03820       sinfo_msg_error ("cannot allocate new cube") ;
03821       return NULL ;
03822   }
03823   */
03824   inp=cpl_imagelist_get_size(cu);
03825   i_img=cpl_imagelist_get(cu,0);
03826   ilx=cpl_image_get_size_x(i_img);
03827   ily=cpl_image_get_size_y(i_img);
03828   olx=xmax-xmin+1;
03829   oly=ymax-ymin+1;
03830 
03831 
03832   cube=cpl_imagelist_new();
03833   for ( i = 0 ; i < inp ; i++ ) {
03834     o_img = cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
03835     cpl_imagelist_set(cube,o_img,i);
03836   }
03837 
03838 
03839   for (i=0;i<inp;i++){
03840       i_img=cpl_imagelist_get(cu,i);
03841       pidata=cpl_image_get_data_float(i_img);
03842       o_img=cpl_imagelist_get(cube,i);
03843       podata=cpl_image_get_data_float(o_img);
03844       for (j=0 ; j < olx ; j++) {
03845           for (k=0 ; k< oly ; k++) {
03846           podata[j+k*olx]=pidata[((int) (j+xmin)/xscale)+
03847                                      ((int) (k+ymin)/yscale)*ilx]/
03848                                        (xscale*yscale);
03849       }
03850       }
03851   }
03852 
03853   return cube;
03854 }
03855 
03856 
03857 cpl_imagelist *
03858 sinfo_new_scale_cube(cpl_imagelist *cu,
03859                                float xscale,
03860                                float yscale,
03861                                char * kernel_type)
03862 {
03863     cpl_imagelist    *    cube ;
03864     int             i=0, j=0, k=0, l=0 ;
03865     int             lx_out, ly_out ;
03866     double           cur ;
03867     double      *    invert_transform ;
03868     double           neighbors[16] ;
03869     double           rsc[8],
03870                     sumrs ;
03871     double        param[6];
03872     double           x, y ;
03873     int             px, py ;
03874     int             pos ;
03875     int             tabx, taby ;
03876     double      *    kernel ;
03877     int                  leaps[16] ;
03878     int                 ilx=0;
03879     int                 ily=0;
03880     int                 tlx=0;
03881     int                 tly=0;
03882     int                 inp;
03883     float*              podata=0;
03884     cpl_image*          in_img=NULL;
03885     cpl_image*          ou_img=NULL;
03886 
03887 
03888     if (cu == NULL)
03889     {
03890         sinfo_msg_error ("null cube") ;
03891         return NULL ;
03892     }
03893 
03894     param[0]=xscale;
03895     param[1]=0;
03896     param[2]=0;
03897     param[3]=0;
03898     param[4]=yscale;
03899     param[5]=0;
03900 
03901 
03902     invert_transform = sinfo_invert_linear_transform(param) ;
03903     if (invert_transform == NULL) {
03904         sinfo_msg_error("cannot compute sinfo_invert transform: "
03905                         "aborting warping") ;
03906         return NULL ;
03907     }
03908 
03909     /* Generate default interpolation kernel */
03910     kernel = sinfo_generate_interpolation_kernel(kernel_type) ;
03911     if (kernel == NULL) {
03912         sinfo_msg_error("cannot generate kernel: aborting resampling") ;
03913         return NULL ;
03914     }
03915 
03916     /* Compute new image size   */
03917     /* Compute new image size   */
03918     ilx=cpl_image_get_size_x(cpl_imagelist_get(cu,0));
03919     ily=cpl_image_get_size_y(cpl_imagelist_get(cu,0));
03920     inp=cpl_imagelist_get_size(cu);
03921 
03922     lx_out = (int) ilx*xscale ;
03923     ly_out = (int) ily*yscale ;
03924 
03925     cube=cpl_imagelist_new();
03926     for ( l = 0 ; l < inp ; l++ ) {
03927      in_img = cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
03928      cpl_imagelist_set(cube,in_img,l);
03929     }
03930 
03931     /* old code
03932     if (NULL == (cube = sinfo_newCube (lx_out, ly_out, cu->np)) )
03933     {
03934         sinfo_msg_error (" cannot allocate new cube") ;
03935         return NULL ;
03936     }
03937     */
03938 
03939     for (l=0;l<inp;l++){
03940       in_img=cpl_imagelist_get(cu,l);
03941       ou_img=cpl_imagelist_get(cube,l);
03942       tlx=cpl_image_get_size_x(in_img);
03943       tly=cpl_image_get_size_y(in_img);
03944       podata=cpl_image_get_data_float(ou_img);
03945         /* Pre compute leaps for 16 closest neighbors positions */
03946         leaps[0] = -1 - tlx ;
03947         leaps[1] =    - tlx ;
03948         leaps[2] =  1 - tlx ;
03949         leaps[3] =  2 - tlx ;
03950 
03951         leaps[4] = -1 ;
03952         leaps[5] =  0 ;
03953         leaps[6] =  1 ;
03954         leaps[7] =  2 ;
03955 
03956         leaps[8] = -1 + tlx ;
03957         leaps[9] =      tlx ;
03958         leaps[10]=  1 + tlx ;
03959         leaps[11]=  2 + tlx ;
03960 
03961         leaps[12]= -1 + 2*tlx ;
03962         leaps[13]=      2*tlx ;
03963         leaps[14]=  1 + 2*tlx ;
03964         leaps[15]=  2 + 2*tlx ;
03965 
03966         /* Double loop on the output image  */
03967         for (j=0 ; j < ly_out ; j++) {
03968             for (i=0 ; i< lx_out ; i++) {
03969                 /* Compute the original source for this pixel   */
03970 
03971                 x = invert_transform[0] * (double)i +
03972                     invert_transform[1] * (double)j +
03973                 invert_transform[2] ;
03974 
03975                 y = invert_transform[3] * (double)i +
03976                 invert_transform[4] * (double)j +
03977                 invert_transform[5] ;
03978 
03979             /* Which is the closest integer positioned neighbor?    */
03980                 px = (int)x ;
03981         py = (int)y ;
03982 
03983                 if ((px < 1) ||
03984                     (px > (tlx-2)) ||
03985                     (py < 1) ||
03986                     (py > (tly-2)))
03987                     podata[i+j*lx_out] = (pixelvalue)0.0 ;
03988                 else {
03989                     /* Now feed the positions for the closest 16 neighbors  */
03990                     pos = px + py * tlx ;
03991                     for (k=0 ; k<16 ; k++){
03992                         if(!isnan(podata[(int)(pos+leaps[k])])) neighbors[k] =
03993                          (double)(podata[(int)(pos+leaps[k])]) ;
03994                 else neighbors[k]=0;
03995             }
03996 
03997                     /* Which tabulated value index shall we use?    */
03998                     tabx = (x - (double)px) * (double)(TABSPERPIX) ;
03999                     taby = (y - (double)py) * (double)(TABSPERPIX) ;
04000 
04001                     /* Compute resampling coefficients  */
04002                     /* rsc[0..3] in x, rsc[4..7] in y   */
04003 
04004                     rsc[0] = kernel[TABSPERPIX + tabx] ;
04005                     rsc[1] = kernel[tabx] ;
04006                     rsc[2] = kernel[TABSPERPIX - tabx] ;
04007                     rsc[3] = kernel[2 * TABSPERPIX - tabx] ;
04008                     rsc[4] = kernel[TABSPERPIX + taby] ;
04009                     rsc[5] = kernel[taby] ;
04010                     rsc[6] = kernel[TABSPERPIX - taby] ;
04011                     rsc[7] = kernel[2 * TABSPERPIX - taby] ;
04012 
04013                     sumrs = (rsc[0]+rsc[1]+rsc[2]+rsc[3]) *
04014                         (rsc[4]+rsc[5]+rsc[6]+rsc[7]) ;
04015 
04016                     /* Compute interpolated pixel now   */
04017                     cur =   rsc[4] * (  rsc[0]*neighbors[0] +
04018                                     rsc[1]*neighbors[1] +
04019                                     rsc[2]*neighbors[2] +
04020                                     rsc[3]*neighbors[3] ) +
04021                         rsc[5] * (  rsc[0]*neighbors[4] +
04022                                     rsc[1]*neighbors[5] +
04023                                     rsc[2]*neighbors[6] +
04024                                     rsc[3]*neighbors[7] ) +
04025                         rsc[6] * (  rsc[0]*neighbors[8] +
04026                                     rsc[1]*neighbors[9] +
04027                                     rsc[2]*neighbors[10] +
04028                                     rsc[3]*neighbors[11] ) +
04029                         rsc[7] * (  rsc[0]*neighbors[12] +
04030                                     rsc[1]*neighbors[13] +
04031                                     rsc[2]*neighbors[14] +
04032                                     rsc[3]*neighbors[15] ) ;
04033 
04034                     /* Affect the value to the output image */
04035                     podata[i+j*lx_out] = (pixelvalue)(cur/sumrs) ;
04036                     /* done ! */
04037                 }
04038             }
04039         }
04040     }
04041     cpl_free(kernel) ;
04042     cpl_free(invert_transform) ;
04043     return cube ;
04044 }
04045 
04046 
04056 cpl_imagelist *
04057 sinfo_cube_zshift(const cpl_imagelist * cube_inp,
04058                   const double shift,
04059                   double* sub_shift)
04060 {
04061 
04062     cpl_imagelist * cube_out=NULL ;
04063     const cpl_image* img_inp=NULL;
04064     cpl_image* img_out=NULL;
04065     int        col, row,z ;
04066     int        int_shift ;
04067     int ilx=0;
04068     int ily=0;
04069     int ilz=0;
04070 
04071     int olx=0;
04072     int oly=0;
04073     int olz=0;
04074     int i=0;
04075     const float* pidata=NULL;
04076     float* podata=NULL;
04077 
04078     cknull(cube_inp,"no input cube given!") ;
04079     check_nomsg(img_inp=cpl_imagelist_get_const(cube_inp,0));
04080     check_nomsg(ilx=cpl_image_get_size_x(img_inp));
04081     check_nomsg(ily=cpl_image_get_size_y(img_inp));
04082     check_nomsg(ilz=cpl_imagelist_get_size(cube_inp));
04083 
04084     olx=ilx;
04085     oly=ily;
04086     olz=ilz;
04087 
04088     int_shift = sinfo_new_nint(shift) ;
04089     *sub_shift = shift - (double) int_shift ;
04090     if ( int_shift == 0 )
04091     {
04092         cube_out =cpl_imagelist_duplicate(cube_inp) ;
04093         return cube_out ;
04094     }
04095     else
04096     {
04097       /* allocate memory */
04098       cknull(cube_out = cpl_imagelist_new(),"could not allocate memory!") ;
04099       for ( i = 0 ; i < olz ; i++ ) {
04100         check_nomsg(img_out=cpl_image_new(olx,oly,CPL_TYPE_FLOAT));
04101         check_nomsg(cpl_imagelist_set(cube_out,img_out,i));
04102      }
04103     }
04104 
04105     for(z=0; z< ilz; z++) {
04106       if ( (z-int_shift >= 0 ) && (z - int_shift < olz) ) {
04107         check_nomsg(img_inp=cpl_imagelist_get_const(cube_inp,z));
04108         check_nomsg(img_out=cpl_imagelist_get(cube_out,z-int_shift));
04109     check_nomsg(pidata=cpl_image_get_data_float_const(img_inp));
04110     check_nomsg(podata=cpl_image_get_data_float(img_out));
04111     for ( col = 0 ; col < ilx ; col++ ) {
04112       for ( row = 0 ; row < ily ; row++ ) {
04113         podata[col+row*olx] = pidata[col+row*olx] ;
04114       }
04115     }
04116       }
04117     }
04118     return cube_out ;
04119 
04120  cleanup:
04121     sinfo_free_imagelist(&cube_out);
04122     return NULL ;
04123 }
04124 
04134 cpl_imagelist *
04135 sinfo_cube_zshift_poly(const cpl_imagelist * cube_inp,
04136                        const double sub_shift,
04137                        const int    order)
04138 {
04139   cpl_imagelist * cube_out ;
04140 
04141   float* spec=NULL ;
04142   float* corrected_spec=NULL ;
04143   float* xnum=NULL ;
04144 
04145   float sum=0;
04146   float new_sum=0 ;
04147   float eval=0 ;
04148   float * imageptr=NULL ;
04149   int row=0;
04150   int col=0 ;
04151   int firstpos=0 ;
04152   int n_points=0 ;
04153   int i=0 ;
04154   int flag=0;
04155   int ilx=0;
04156   int ily=0;
04157   int ilz=0;
04158 
04159   int olx=0;
04160   int oly=0;
04161   int olz=0;
04162   int z=0;
04163 
04164   const float* pidata=NULL;
04165   float* podata=NULL;
04166   const cpl_image* img_inp=NULL;
04167   cpl_image* img_out=NULL;
04168 
04169   if ( cube_inp == NULL ) {
04170     sinfo_msg_error("no imagelist given!") ;
04171     return NULL ;
04172   }
04173 
04174   img_inp=cpl_imagelist_get_const(cube_inp,0);
04175 
04176   ilx=cpl_image_get_size_x(img_inp);
04177   ily=cpl_image_get_size_y(img_inp);
04178   ilz=cpl_imagelist_get_size(cube_inp);
04179 
04180   if ( order <= 0 ) {
04181     sinfo_msg_error("wrong order of interpolation polynom given!") ;
04182     return NULL ;
04183   }
04184 
04185 
04186   olx=ilx;
04187   oly=ily;
04188   olz=ilz;
04189   /* allocate memory */
04190 
04191   if ( NULL == (cube_out = cpl_imagelist_new()) ) {
04192     sinfo_msg_error ("could not allocate memory!") ;
04193     return NULL ;
04194   } else {
04195     for ( i = 0 ; i < ilz ; i++ ) {
04196       img_out=cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
04197       cpl_imagelist_set(cube_out,img_out,i);
04198     }
04199   }
04200 
04201 
04202   n_points = order + 1 ;
04203   if ( n_points % 2 == 0 ) {
04204     firstpos = (int)(n_points/2) - 1 ;
04205   } else {
04206     firstpos = (int)(n_points/2) ;
04207   }
04208 
04209   spec=cpl_calloc(ilz,sizeof(float)) ;
04210   corrected_spec=cpl_calloc(ilz,sizeof(float)) ;
04211   xnum=cpl_calloc(order+1,sizeof(float)) ;
04212 
04213 
04214   /* fill the xa[] array for the polint function */
04215   for ( i = 0 ; i < n_points ; i++ ) {
04216     xnum[i] = i ;
04217   }
04218 
04219   for ( col = 0 ; col < ilx ; col++ ) {
04220     for ( row = 0 ; row < ily ; row++ ) {
04221       for( z=0; z< ilz; z++) {
04222         corrected_spec[z] = 0. ;
04223       }
04224       sum = 0. ;
04225       for ( z = 0 ; z < ilz ; z++ ) {
04226     img_inp=cpl_imagelist_get_const(cube_inp,z);
04227         pidata=cpl_image_get_data_float_const(img_inp);
04228     spec[z] = pidata[col + row*ilx] ;
04229     if (isnan(spec[z]) ) {
04230           spec[z] = 0. ;
04231 
04232       for ( i = z - firstpos ; i < z-firstpos+n_points ; i++ ) {
04233         if ( i < 0 ) continue ;
04234             if ( i >= ilz) continue  ;
04235             corrected_spec[i] = ZERO ;
04236           }
04237         }
04238         if ( z != 0 && z != ilz - 1 ) {
04239           sum += spec[z] ;
04240         }
04241 
04242       }
04243 
04244       new_sum = 0. ;
04245       for ( z = 0 ; z < ilz ; z++ ) {
04246 
04247         /* ---------------------------------------------------------------
04248          * now determine the arrays of size n_points with which the
04249          * polynom is determined and determine the position eval
04250          * where the polynom is evaluated in polynomial interpolation.
04251          * Take care of the points near the row edges!
04252          */
04253         if (isnan(corrected_spec[z])) continue ;
04254         if ( z - firstpos < 0 ) {
04255           imageptr = &spec[0] ;
04256           eval     = sub_shift + z ;
04257         } else if ( z - firstpos + n_points >= ilz ) {
04258           imageptr = &spec[ilz - n_points] ;
04259           eval     = sub_shift + z + n_points - ilz ;
04260         } else {
04261       imageptr = &spec[z-firstpos] ;
04262           eval     = sub_shift + firstpos ;
04263         }
04264 
04265         flag=0;
04266         corrected_spec[z]=sinfo_new_nev_ille(xnum,imageptr,order,eval,&flag);
04267         if ( z != 0 && z != ilz - 1 ) {
04268           new_sum += corrected_spec[z] ;
04269         }
04270       }
04271 
04272       /* fill the output spectrum */
04273       for (z = 0 ; z < ilz ; z++ )
04274       {
04275         img_out=cpl_imagelist_get(cube_out,z);
04276         podata=cpl_image_get_data_float(img_out);
04277         if ( new_sum == 0. ) {
04278           new_sum = 1. ;
04279         }
04280         if ( z == 0 ) {
04281           podata[col+row*olx] = ZERO ;
04282         } else if ( z == ilz - 1 ) {
04283           podata[col+row*olx] = ZERO ;
04284         } else if ( isnan(corrected_spec[z]) ) {
04285           podata[col+row*olx] = ZERO ;
04286         } else {
04287           corrected_spec[z] *= sum / new_sum ;
04288           podata[col+row*olx] = corrected_spec[z] ;
04289     }
04290       }
04291 
04292     }
04293   }
04294 
04295   cpl_free(spec) ;
04296   cpl_free(corrected_spec) ;
04297   cpl_free(xnum) ;
04298   return cube_out ;
04299 
04300 
04301 }
04302 
04311 cpl_imagelist *
04312 sinfo_cube_zshift_spline3(const cpl_imagelist * cube_inp,
04313                           const double sub_shift)
04314 {
04315 
04316   cpl_imagelist * cube_out=NULL ;
04317   float* spec=NULL ;
04318   float* corrected_spec=NULL ;
04319   float* xnum=NULL ;
04320   float* eval=NULL ;
04321   float sum=0;
04322   float new_sum=0 ;
04323   int row=0;
04324   int col=0;
04325   int i=0;
04326   int z=0;
04327 
04328   int ilx=0;
04329   int ily=0;
04330   int ilz=0;
04331   int olx=0;
04332   int oly=0;
04333   int olz=0;
04334 
04335   const float* pidata=NULL;
04336   float* podata=NULL;
04337   const cpl_image* img_inp=NULL;
04338   cpl_image* img_out=NULL;
04339 
04340   if ( cube_inp == NULL ) {
04341     sinfo_msg_error("no imagelist given!") ;
04342     return NULL ;
04343   }
04344 
04345   img_inp=cpl_imagelist_get_const(cube_inp,0);
04346   ilx=cpl_image_get_size_x(img_inp);
04347   ily=cpl_image_get_size_y(img_inp);
04348   ilz=cpl_imagelist_get_size(cube_inp);
04349 
04350 
04351   olx=ilx;
04352   oly=ily;
04353   olz=ilz;
04354   /* allocate memory */
04355   if ( NULL == (cube_out = cpl_imagelist_new()) ) {
04356     sinfo_msg_error ("could not allocate memory!") ;
04357     return NULL ;
04358   } else {
04359     for ( i = 0 ; i < ilz ; i++ ) {
04360       img_out=cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
04361       cpl_imagelist_set(cube_out,img_out,i);
04362     }
04363   }
04364 
04365   xnum=cpl_calloc(ilz,sizeof(float)) ;
04366   /* fill the xa[] array for the spline function */
04367   for ( i = 0 ; i < ilz ; i++ ) {
04368     xnum[i] = i ;
04369   }
04370 
04371   spec=cpl_calloc(ilz,sizeof(float)) ;
04372   corrected_spec=cpl_calloc(ilz,sizeof(float)) ;
04373   eval=cpl_calloc(ilz,sizeof(float)) ;
04374 
04375   for ( col = 0 ; col < ilx ; col++ ) {
04376     for ( row = 0 ; row < ily ; row++ ) {
04377       sum = 0. ;
04378       for ( z = 0 ; z < ilz ; z++ ) {
04379     img_inp=cpl_imagelist_get_const(cube_inp,z);
04380         pidata=cpl_image_get_data_float_const(img_inp);
04381     spec[z] = pidata[col + row*ilx] ;
04382     if (isnan(spec[z]) ) {
04383       for ( i = z-1 ; i <= z+1 ; i++ ) {
04384         if ( i < 0 ) continue ;
04385         if ( i >= ilz) continue ;
04386         corrected_spec[i] = ZERO ;
04387       }
04388       spec[z] = 0. ;
04389     }
04390     sum += spec[z] ;
04391     eval[z] = (float)sub_shift+(float)z ;
04392       }
04393       /* now we do the spline interpolation*/
04394       if ( -1 == sinfo_function1d_natural_spline( xnum, spec, ilz, eval,
04395                                               corrected_spec, ilz ) )
04396         {
04397       sinfo_msg_error("error in spline interpolation!") ;
04398       return NULL ;
04399         }
04400 
04401       new_sum = 0. ;
04402       for ( z = 0 ; z < ilz ; z++ ) {
04403     if ( isnan(corrected_spec[z]) ) {
04404       continue ;
04405     }
04406     new_sum += corrected_spec[z] ;
04407       }
04408       /* fill output imagelist */
04409       for ( z = 0 ; z < ilz ; z++ ) {
04410         img_out=cpl_imagelist_get(cube_out,z);
04411         podata=cpl_image_get_data_float(img_out);
04412     if ( new_sum == 0. ) new_sum =1. ;
04413     {
04414       if ( isnan(corrected_spec[z]) ) {
04415         podata[col+row*olx] = ZERO ;
04416       } else {
04417         corrected_spec[z] *= sum / new_sum ;
04418         podata[col+row*olx] = corrected_spec[z] ;
04419       }
04420     }
04421       }
04422     }
04423   }
04424   cpl_free(xnum);
04425   cpl_free(spec) ;
04426   cpl_free(corrected_spec) ;
04427   cpl_free(eval) ;
04428 
04429   return cube_out ;
04430 }
04431 
04433 /* The structure for stroing index data for kappa-sigma
04434  *
04435  * */
04436 struct _CubeData
04437 {
04438     int iCubeNumber;
04439     int iLocalX;
04440     int iLocalY;
04441 };
04442 typedef struct _CubeData CubeData;
04443 
04444 struct _CubeDataVector
04445 {
04446     int size;
04447     CubeData** pdata;
04448 };
04449 typedef struct _CubeDataVector CubeDataVector;
04467 static int sinfo_kappa_sigma_offset_with_mask(
04468         int z_min,
04469         int z_max,
04470         int nCubes,
04471         cpl_imagelist** inputCubes,
04472         double* exptimes,
04473         cpl_imagelist* imResult,
04474         int* offsetX,
04475         int* offsetY,
04476         cpl_imagelist* sky_mask,
04477         const double kappa
04478         );
04479 void kappa_sigma_CubeDataVector(
04480         int globalX,
04481         int globalY,
04482         CubeDataVector* pCubeDataVector,
04483         cpl_imagelist* imlistResult,
04484         cpl_imagelist** input_cubes,
04485         cpl_imagelist* sky_mask,
04486         int iPlanesNumber,
04487         int z_min,
04488         const double kappa,
04489         double* exptimes
04490         );
04491 
04492 double kappa_sigma_array_with_mask(cpl_array* parray, int szArray, const double kappa,cpl_image* imMask, double* exptimes, int x, int y, double mask_delta)
04493 {
04494     double result = 0;
04495     int nInvalidPoints = 0;
04496     const double EPS = 1E-10;
04497     //sinfo_msg("kappa_sigma_array_with_mask, x[%d] y[%d]"
04498     double mask_adjustment = mask_delta;
04499     do
04500     {
04501         double median = 0;
04502         double sig = 0;
04503         int z = 0;
04504         nInvalidPoints = 0;
04505 
04506         check_nomsg(median = cpl_array_get_median(parray));
04507         check_nomsg(sig = cpl_array_get_stdev(parray));
04508         for (z = 0; z < szArray; z++)
04509         {
04510             int isnull = 0;
04511             double value = 0;
04512             check_nomsg(value = cpl_array_get(parray, z, &isnull));
04513             if(!isnull)
04514             {
04515                 if (fabs(value - median) > (kappa * sig))
04516                 {
04517 
04518    //                       sinfo_msg("entered");
04519     //        sinfo_msg("val=%g check=%g",
04520     //              fabs(value - median),(kappa * sig));
04521 //            sinfo_msg("kappa=%f sig=%g median=%g value=%g",
04522 //                  kappa,sig,median,value);
04523 
04524                     //double msk_new_value = 0;
04525                     cpl_array_fill_window_invalid(parray, z, 1);
04526                     mask_adjustment += exptimes[z];
04527                     ++nInvalidPoints;
04528                 }
04529             }
04530         }
04531         /*if (nInvalidPoints)
04532         {
04533             sinfo_msg("nInvalidPoints %d[%d][%d] median[%f] sig[%f]", nInvalidPoints,x,y, median, sig );
04534         }*/
04535 
04536     }
04537     while (nInvalidPoints);
04538     if(imMask && fabs(mask_adjustment) > EPS)
04539     {
04540         // adjust mask image
04541         int px_rejected = 0;
04542         double msk_value = 0;
04543         check_nomsg(msk_value = cpl_image_get(imMask, x, y, &px_rejected));
04544         check_nomsg(cpl_image_set(imMask, x,y, msk_value - mask_adjustment));
04545     }
04546     // get a result value for the point
04547     check_nomsg(result = cpl_array_get_mean(parray));
04548     return result;
04549     cleanup:
04550     sinfo_msg("Error in kappa_sigma_array_with_mask");
04551     return 0;
04552 }
04553 
04554 
04555 int sinfo_coadd_with_ks_clip_optimized(
04556             const int z_min,
04557             const int z_max,
04558             const int n_cubes,
04559             const double kappa,
04560             int* llx,
04561             int* lly,
04562             double* exptimes,
04563             cpl_imagelist* sky_mask,
04564             cpl_imagelist* mergedCube,
04565             cpl_imagelist** tmpcubes
04566             )
04567 {
04568   /*
04569     sinfo_msg("sinfo_coadd_with_ks_clip_optimized() z_min[%d] z_max[%d] n_cubes[%d] kappa[%f] llx[%d] lly[%d] exptimes[%d] sky_mask[%d]",
04570             z_min, z_max, ilx, ily, n_cubes, kappa,llx, lly,exptimes,sky_mask);
04571   */
04572    int result=0;
04573    check_nomsg(result=sinfo_kappa_sigma_offset_with_mask(z_min, z_max, n_cubes, tmpcubes, exptimes, mergedCube, llx, lly, sky_mask, kappa));
04574 
04575   cleanup:
04576 
04577     return result;
04578 
04579 }
04580 
04581 static int sinfo_kappa_sigma_offset_with_mask(
04582         int z_min,
04583         int z_max,
04584         int nCubes,
04585         cpl_imagelist** inputCubes,
04586         double* exptimes,
04587         cpl_imagelist* imResult,
04588         int* global_offsetX,
04589         int* global_offsetY,
04590         cpl_imagelist* sky_mask,
04591         const double kappa
04592         )
04593 {
04594     const int BIG_ENOUGH_INT = 65535;
04595     CubeDataVector*** indexX = 0;
04596     int x = 0;
04597     int y = 0;
04598     int z = 0;
04599     int iPlanesNumber = z_max - z_min;
04600     int nIndexXbytes = 0;
04601     int globalSizeX = 0 ;
04602     int globalSizeY = 0;
04603 
04604     int xmax = -BIG_ENOUGH_INT;
04605     int ymax = -BIG_ENOUGH_INT;
04606     int xmin = BIG_ENOUGH_INT;
04607     int ymin = BIG_ENOUGH_INT;
04608     int* offsetX = 0; // local offset of the cubes, normalized
04609     int* offsetY = 0;
04610     //sinfo_msg(" starting kappa-sigma clipping for cubes[%d] planes[%d]", nCubes, z_max - z_min );
04611     // determine size of the coadded cube
04612         sinfo_check_rec_status(0);
04613     for (z = 0; z < nCubes; z++)
04614     {
04615 
04616         cpl_imagelist* pCube = inputCubes[z];
04617         cpl_image* pImage = 0;
04618         int localMaxX = 0;
04619         int localMaxY = 0;
04620         int localMinX = 0;
04621         int localMinY = 0;
04622 
04623         pImage = cpl_imagelist_get(pCube, 0);
04624 
04625         localMaxX = cpl_image_get_size_x(pImage) + global_offsetX[z];
04626         localMaxY = cpl_image_get_size_y(pImage) + global_offsetY[z];
04627         localMinX = global_offsetX[z];
04628         localMinY = global_offsetY[z];
04629 
04630         if(localMaxX > xmax) xmax = localMaxX;
04631         if(localMaxY > ymax) ymax = localMaxY;
04632 
04633         if(localMinX < xmin) xmin = localMinX;
04634         if(localMinY < ymin) ymin = localMinY;
04635     }
04636         sinfo_check_rec_status(1);
04637 
04638     // DFS09121 xmax and ymax could be more then output cube - check and adjust
04639     {
04640         int msize_x = 0;
04641         int msize_y = 0;
04642         //sinfo_msg("DFS09121 before:  xmax=%d ymax=%d", xmax, ymax);
04643         cpl_image * pmaskimage = cpl_imagelist_get(sky_mask, 0);
04644         msize_x = cpl_image_get_size_x(pmaskimage);
04645         msize_y = cpl_image_get_size_y(pmaskimage);
04646         xmax = msize_x < xmax ? msize_x : xmax;
04647         ymax = msize_y < ymax ? msize_y : ymax;
04648         //sinfo_msg("DFS09121 after:  xmax=%d ymax=%d", xmax, ymax);
04649     }
04650     // rely on the data received outside
04651     globalSizeX = xmax;// - xmin;
04652     globalSizeY = ymax;// - ymin;
04653     // calculate local offset
04654     check_nomsg(offsetX = cpl_malloc(sizeof(offsetX[0]) * nCubes));
04655     check_nomsg(offsetY = cpl_malloc(sizeof(offsetY[0]) * nCubes));
04656         sinfo_check_rec_status(2);
04657     for (z = 0; z < nCubes; z++) // use the offset from the caller
04658     {
04659         offsetX[z] = global_offsetX[z];// - xmin;
04660         offsetY[z] = global_offsetY[z];// - ymin;
04661 //      sinfo_msg("for cube [%d] offset X[%d : %d] Y[%d : %d]", z, offsetX[z], global_offsetX[z], offsetY[z], global_offsetY[z]);
04662     }
04663         sinfo_check_rec_status(3);
04664     // Because of DFS09121, the allocated size is taken +1
04665     nIndexXbytes = sizeof(CubeDataVector**) * (globalSizeX+1 );
04666 //  sinfo_msg("   kappa_sigma_offset, globalSizeX[%d] globalSizeY[%d] nIndexXbytes[%d]", globalSizeX, globalSizeY, nIndexXbytes);
04667     indexX = cpl_malloc(nIndexXbytes);
04668     memset(&indexX[0], 0, (globalSizeX+1 )* sizeof(indexX[0]));
04669     // prepare result planes and mask
04670 
04671     // 1. Fill indexes - do it only for a 0 plane in the cube
04672     for (z = 0; z < nCubes; z++)
04673     {
04674         int iCubeSizeX = 0;
04675         int iCubeSizeY = 0;
04676         int iOffsetX = 0;
04677         int iOffsetY = 0;
04678 
04679         cpl_imagelist* pCube = inputCubes[z];
04680         cpl_image* pImage = 0;
04681         pImage = cpl_imagelist_get(pCube, 0);
04682 
04683         iCubeSizeX = cpl_image_get_size_x(pImage);
04684         iCubeSizeY = cpl_image_get_size_y(pImage);
04685         iOffsetX = offsetX[z];
04686         iOffsetY = offsetY[z];
04687 //      sinfo_msg("   processing cube [%d] offsetX[%d] offsetY[%d] iCubeSizeX[%d] iCubeSizeY[%d]", z, iOffsetX, iOffsetY, iCubeSizeX, iCubeSizeY);
04688         for (x = 1; x <= iCubeSizeX; x++)
04689         {
04690             int iGlobalX = x + iOffsetX;
04691 
04692             CubeDataVector** ppVector = 0;
04693             if (indexX[iGlobalX - 1] == 0)
04694             {
04695                 // Because of DFS09121, the allocated size is taken +1
04696                 int nBytes = sizeof(CubeDataVector*) * (globalSizeY+1 );
04697                 ppVector= cpl_malloc(nBytes);
04698                 memset(&ppVector[0],0,(globalSizeY+1) * sizeof(ppVector[0]));
04699                 indexX[iGlobalX - 1] = ppVector;
04700             }
04701             else
04702             {
04703                 ppVector = indexX[iGlobalX - 1];
04704             }
04705             for (y = 1; y <=iCubeSizeY; y++)
04706             {
04707                 CubeData* pCubeData = 0;
04708                 int iGlobalY = y + iOffsetY;
04709                 CubeDataVector* pVector = ppVector[iGlobalY - 1];
04710                 if(pVector == 0)
04711                 {
04712                     int nbytes = sizeof(CubeDataVector);
04713                     check_nomsg(pVector = cpl_malloc(nbytes));
04714                     ppVector[iGlobalY - 1] = pVector;
04715                     pVector->size = 0;
04716                     nbytes = sizeof(CubeData*) * nCubes;
04717                     pVector->pdata = cpl_malloc(nbytes);
04718 //                  memset(&pVector->pdata[0], 0, nCubes * sizeof(pVector->pdata[0]));
04719                 }
04720                 pCubeData = cpl_malloc(sizeof(CubeData));
04721                 pVector->pdata[(pVector->size)++] = pCubeData;
04722                 pCubeData->iCubeNumber = z;
04723                 pCubeData->iLocalX = x;
04724                 pCubeData->iLocalY = y;
04725             }
04726         }
04727     }
04728         sinfo_check_rec_status(4);
04729 
04730     // 2. for each index value in global coordinates (x,y) call kappa-sigma
04731     for (x = 1; x <= globalSizeX; x++)
04732     {
04733         CubeDataVector** pDataX = indexX[x - 1];
04734         if (pDataX)
04735         {
04736             for (y = 1; y <= globalSizeY; y++)
04737             {
04738                 CubeDataVector* pDataY = pDataX[y - 1];
04739                 if (pDataY && pDataY->size)
04740                 {
04741                     kappa_sigma_CubeDataVector(x, y, pDataY, imResult, inputCubes, sky_mask, iPlanesNumber, z_min, kappa, exptimes);
04742                 }
04743                 if (pDataY)
04744                 {
04745                     check_nomsg(cpl_free(pDataY->pdata));
04746                     check_nomsg(cpl_free(pDataY));
04747                 }
04748             }
04749             check_nomsg(cpl_free(pDataX));
04750         }
04751     }
04752     sinfo_check_rec_status(5);
04753     cleanup:
04754     cpl_free(indexX);
04755     cpl_free(offsetX);
04756     cpl_free(offsetY);
04757     return 0;
04758 
04759 }
04760 
04761 void kappa_sigma_CubeDataVector(
04762         int globalX,
04763         int globalY,
04764         CubeDataVector* pCubeDataVector,
04765         cpl_imagelist* imlistResult,
04766         cpl_imagelist** input_cubes,
04767         cpl_imagelist* sky_mask,
04768         int iPlanesNumber,
04769         int z_min,
04770         const double kappa,
04771         double* exptimes
04772         )
04773 {
04774     int plane = 0;
04775     int z = 0;
04776 
04777     // iterate through all planes
04778     cpl_array* pArray = 0;
04779     check_nomsg(pArray = cpl_array_new(pCubeDataVector->size, CPL_TYPE_DOUBLE));
04780 
04781 
04782     for (plane = z_min; plane < z_min + iPlanesNumber; plane++)
04783     {
04784         double val_msk = 0; // value of the mask in the point
04785         int px = 0;
04786         cpl_image* imResult = 0;
04787         cpl_image* imMask = 0;
04788         double mask_adjustment = 0;
04789         int nValidPoints = 0;
04790         cpl_array_fill_window_invalid(pArray, 0, pCubeDataVector->size);
04791         check_nomsg(imMask = cpl_imagelist_get(sky_mask, plane - z_min));
04792         check_nomsg(val_msk = cpl_image_get(imMask, globalX, globalY, &px));
04793         for (z = 0; z < pCubeDataVector->size; z++) // through all cubes for that point - prepare the array
04794         {
04795 
04796             cpl_imagelist* pCube = 0;
04797             CubeData* pCubeData = pCubeDataVector->pdata[z];
04798             pCube = input_cubes[pCubeData->iCubeNumber];
04799             if (pCube)
04800             {
04801                 cpl_image* pImage = cpl_imagelist_get(pCube, plane - z_min);
04802 
04803                 if (pImage)
04804                 {
04805                     int is_rejected = 0;
04806                     double value = 0;
04807                     check_nomsg(value = cpl_image_get(pImage, pCubeData->iLocalX, pCubeData->iLocalY, &is_rejected));
04808                     if (!isnan(value))
04809                     {
04810                         check_nomsg(cpl_array_set(pArray, z, value));
04811                         ++nValidPoints;
04812                     }
04813                     else
04814                     {
04815                         mask_adjustment += exptimes[z];
04816                     }
04817                 }
04818                 else
04819                 {
04820                     sinfo_msg("kappa_sigma_CubeDataVector() - pImage is null");
04821                 }
04822             }
04823         }
04824         if(nValidPoints)
04825         {
04826            kappa_sigma_array_with_mask(pArray, pCubeDataVector->size, kappa, imMask, exptimes, globalX, globalY, mask_adjustment);
04827            check_nomsg(imResult = cpl_imagelist_get(imlistResult, plane));
04828            if (imResult)
04829            {
04830               check_nomsg(cpl_image_set(imResult, globalX, globalY, cpl_array_get_mean(pArray)));
04831            }
04832            else
04833            {
04834               sinfo_msg("kappa_sigma_CubeDataVector() - imResult is null");
04835            }
04836         } else
04837         {
04838             // adjust the mask
04839             check_nomsg(cpl_image_set(imMask, globalX,globalY, 0));
04840         }
04841     }
04842     for (z = 0; z < pCubeDataVector->size; z++) // through all cubes  - delete the data
04843     {
04844         CubeData* pCubeData = pCubeDataVector->pdata[z];
04845         cpl_free(pCubeData);
04846     }
04847     cpl_array_delete(pArray);
04848     return;
04849     cleanup:
04850 //  sinfo_msg("   -----cleanup from kappa_sigma_CubeDataVector");
04851     return;
04852 }
04853 
04854 
04855 static int
04856 sinfo_coadd_with_ks_clip(const int z_min,
04857             const int z_max,
04858             const int ilx,
04859             const int ily,
04860             const int n_cubes,
04861             const double kappa,
04862             int* llx,
04863             int* lly,
04864                         double* exptimes,
04865             cpl_imagelist* mask,
04866             cpl_imagelist* mergedCube,
04867                         cpl_imagelist** tmpcubes)
04868 
04869 {
04870 
04871   int m=0;
04872   int x=0;
04873   int y=0;
04874   int z=0;
04875 
04876   int mlx=0;
04877   int mly=0;
04878   int nc=0;
04879   int olx=0;
04880   int oly=0;
04881   int posx=0;
04882   int posy=0;
04883   int i=0;
04884   int nclip=0;
04885   int ks=0;
04886 
04887   float sig=0;
04888   float med=0;
04889   float ovr=0;
04890   float  msk_sum=0;
04891   float  val_msk_sum=0;
04892   float avg=0;
04893 
04894   float* pmdata=NULL;
04895   float* podata=NULL;
04896   float* ptdata=NULL;
04897   float* pvdata=NULL;
04898 
04899   cpl_image* m_img=NULL;
04900   cpl_image* o_img=NULL;
04901   cpl_image* t_img=NULL;
04902   cpl_image* v_img=NULL;
04903 
04904 
04905   cpl_vector* val=NULL;
04906   cpl_vector* msk=NULL;
04907 
04908 
04909   o_img=cpl_imagelist_get(mergedCube,0);
04910   olx=cpl_image_get_size_x(o_img);
04911   oly=cpl_image_get_size_y(o_img);
04912 
04913   m=0;
04914   for ( z = z_min; z < z_max ; z++ ) {
04915     m_img=cpl_imagelist_get(mask,z);
04916     pmdata=cpl_image_get_data_float(m_img);
04917     o_img=cpl_imagelist_get(mergedCube,z);
04918     podata=cpl_image_get_data_float(o_img);
04919     mlx=cpl_image_get_size_x(m_img);
04920     mly=cpl_image_get_size_y(m_img);
04921     // go through the first image plane of the big data cube 
04922     for ( y = 0 ; y < oly ; y++ ) {
04923       for ( x = 0 ; x < olx ; x++ ) {
04924     avg=0;
04925     nc=0;
04926     // computes nc 
04927     for ( i = 0 ; i < n_cubes ; i++ ) {
04928       t_img=cpl_imagelist_get(tmpcubes[i],m);
04929       ptdata=cpl_image_get_data_float(t_img);
04930           if ( y >= lly[i] && y < lly[i]+ily &&
04931                x >= llx[i] && x < llx[i]+ilx ) {
04932         posx = x - llx[i] ;
04933         posy = y - lly[i] ;
04934             if (!isnan(ptdata[posx+posy*ilx]) &&
04935                        ptdata[posx+posy*ilx] != 0.) {
04936           nc++;
04937         }
04938       }
04939     }
04940         if( nc > 0 ) {
04941 
04942       
04943       msk=cpl_vector_new(n_cubes);
04944       for (i=0;i<n_cubes;i++) {
04945         cpl_vector_set(msk,i,1);
04946       }
04947 
04948       // k-s clipping 
04949       nclip=0;
04950 
04951 
04952       for (ks=0;ks<nc;ks++) {
04953         sig=0;
04954         med=0;
04955         ovr=0;
04956         if(nc-nclip >0) {
04957           val=cpl_vector_new(nc-nclip);
04958         }
04959         // fill val 
04960         for ( i = 0 ; i < n_cubes ; i++ ) {
04961           t_img=cpl_imagelist_get(tmpcubes[i],m);
04962           ptdata=cpl_image_get_data_float(t_img);
04963               if ( y >= lly[i] && y < lly[i]+ily &&
04964                    x >= llx[i] && x < llx[i]+ilx ) {
04965         posx = x - llx[i] ;
04966         posy = y - lly[i] ;
04967                 if (!isnan(ptdata[posx+posy*ilx]) &&
04968                            ptdata[posx+posy*ilx] != 0. &&
04969             (cpl_vector_get(msk,i) != 0)) {
04970           cpl_vector_set(val,ovr,(double)ptdata[posx+posy*ilx]);
04971           ovr++;
04972         }
04973           }
04974         }
04975 
04976         // get avg, med, sig 
04977         if(ovr>0) {
04978           avg=cpl_vector_get_mean(val);
04979           med=cpl_vector_get_median_const(val);
04980           if(ovr>1) {
04981         sig=cpl_vector_get_stdev(val);
04982           } else {
04983         sig=0;
04984           }
04985           cpl_vector_delete(val);
04986         }
04987 
04988         for ( i = 0 ; i < n_cubes ; i++ ) {
04989           t_img=cpl_imagelist_get(tmpcubes[i],m);
04990           ptdata=cpl_image_get_data_float(t_img);
04991           // Do k-s clipping at each pixel 
04992               if ( y >= lly[i] && y < lly[i]+ily &&
04993                    x >= llx[i] && x < llx[i]+ilx ) {
04994         posx = x - llx[i] ;
04995         posy = y - lly[i] ;
04996                 if (!isnan(ptdata[posx+posy*ilx]) &&
04997                            ptdata[posx+posy*ilx] != 0. &&
04998             (cpl_vector_get(msk,i) != 0)) {
04999           if(abs((ptdata[posx+posy*ilx]-med))> kappa*sig) {
05000                     ptdata[posx+posy*ilx]=0;
05001             pmdata[x+y*mlx] -= exptimes[i]  ;
05002             cpl_vector_set(msk,i,0);
05003             nclip++;
05004           }
05005         }
05006           }
05007         }
05008       } // end of k-s clipping 
05009 
05010       msk_sum=0;
05011       val_msk_sum=0;
05012       for ( i = 0 ; i < n_cubes ; i++ ) {
05013         v_img=cpl_imagelist_get(tmpcubes[i],m);
05014         pvdata=cpl_image_get_data_float(v_img);
05015         // computes sky at each point 
05016             if ( y >= lly[i] && y < lly[i]+ily &&
05017                  x >= llx[i] && x < llx[i]+ilx ) {
05018           posx = x - llx[i] ;
05019           posy = y - lly[i] ;
05020               //sinfo_msg_warning("llx[%d]=%d lly[%d],=%d",i,llx[i],i,lly[i]);
05021               //sinfo_msg_warning("posx=%d posy=%d",posx,posy);
05022               if (!isnan(pvdata[posx+posy*ilx]) &&
05023                          pvdata[posx+posy*ilx] != 0. &&
05024           (cpl_vector_get(msk,i) != 0)) {
05025         msk_sum+=pmdata[x+y*mlx];
05026                 val_msk_sum+=pvdata[posx+posy*ilx]*
05027           pmdata[x+y*mlx];
05028           }
05029         }
05030       }
05031       podata[x+y*olx]=val_msk_sum/msk_sum;
05032       cpl_vector_delete(msk);
05033       /*
05034       sinfo_ks_clip(n_cubes,nc,ilx,ily,kappa,llx,lly,exptimes,
05035             tmpcubes,podata,pmdata,x,y,m,mlx,oly);
05036 
05037       */
05038 
05039     } // end check if overlap nc >0  
05040       } // end loop over x 
05041     } // end loop over y 
05042     m++;
05043   } // end loop over z 
05044 
05045   return 0;
05046 
05047 
05048 }
05049 
05050 
05051 
05052 
05053 static int
05054 sinfo_compute_contributes_at_pos(cpl_imagelist** tmpcubes, 
05055                                  int* llx, int* lly, 
05056                                  const int x, const int y,
05057                                  const int ilx, const int ily, 
05058                                  const int m,const int n_cubes)
05059 {
05060 
05061    int result=0;
05062    int i=0;
05063    int lox=0;
05064    int loy=0;
05065    int upx=0;
05066    int upy=0;
05067    int post=0;
05068    int posx=0;
05069    int posy=0;
05070 
05071    float* ptdata=NULL;
05072    cpl_image* t_img=NULL;
05073   
05074  
05075    /* computes nc the number of intensity contributes from 
05076       each overlapping cube point intensity at x,y
05077    */
05078    for ( i = 0 ; i < n_cubes ; i++ ) {
05079       t_img=cpl_imagelist_get(tmpcubes[i],m);
05080       ptdata=cpl_image_get_data_float(t_img);
05081       lox=llx[i];
05082       loy=lly[i];
05083       upx=llx[i]+ilx;
05084       upy=lly[i]+ily;
05085 
05086       if ( y >= loy && y < upy && x >= lox && x < upx ) {
05087          posx = x - lox;
05088          posy = y - loy;
05089          post = posx+posy*ilx;
05090 
05091          if (!isnan(ptdata[post]) && ptdata[post] != 0.) {
05092             result++;
05093          }
05094       }
05095    }
05096 
05097 
05098    return result;
05099 
05100 }
05101 
05102 
05103 
05104 
05105 static int
05106 sinfo_cubes_coadd_with_ks_clip(cpl_imagelist** tmpcubes, 
05107                                const int n_cubes,const int nc,
05108                                const int x, const int y, const int m,
05109                                int* llx, int* lly, 
05110                                const int ilx, const int ily,
05111                                const double kappa, 
05112                                double* exptimes, float** pmdata, 
05113                                cpl_vector** msk, const int mlx)
05114 
05115 
05116 {
05117 
05118  
05119    cpl_vector* val=NULL;
05120    cpl_image* t_img=NULL;
05121 
05122    int i=0;
05123    int nclip=0;
05124    int ks=0;
05125    
05126    int lox=0;
05127    int loy=0;
05128    int upx=0;
05129    int upy=0;
05130 
05131    int posx=0;
05132    int posy=0;
05133    int post=0;
05134 
05135    int ovr=0;
05136 
05137    float sig=0;
05138    float avg=0;
05139    float med=0;
05140 
05141    float* ptdata=NULL;
05142    
05143 
05144    // k-s clipping 
05145    nclip=0;
05146 
05147 
05148    for (ks=0;ks<nc;ks++) {
05149       sig=0;
05150       med=0;
05151       ovr=0;
05152       if(nc-nclip >0) {
05153          check_nomsg(val=cpl_vector_new(nc-nclip));
05154       }
05155       // fill val 
05156       for ( i = 0 ; i < n_cubes ; i++ ) {
05157          check_nomsg(t_img=cpl_imagelist_get(tmpcubes[i],m));
05158          check_nomsg(ptdata=cpl_image_get_data_float(t_img));
05159 
05160          lox=llx[i];
05161          loy=lly[i];
05162          upx=llx[i]+ilx;
05163          upy=lly[i]+ily;
05164 
05165          if ( y >= loy && y < upy && x >= lox && x < upx ) {
05166             posx = x - lox ;
05167             posy = y - loy ;
05168             post=posx+posy*ilx;
05169 
05170             if (!isnan(ptdata[post]) && ptdata[post] != 0. &&
05171                 (cpl_vector_get(*msk,i) != 0)) {
05172                cpl_vector_set(val,ovr,(double)ptdata[post]);
05173                ovr++;
05174             }
05175          }
05176       }
05177 
05178       // get avg, med, sig 
05179       if(ovr>0) {
05180          check_nomsg(avg=cpl_vector_get_mean(val));
05181          med=cpl_vector_get_median_const(val);
05182          if(ovr>1) {
05183             sig=cpl_vector_get_stdev(val);
05184          } else {
05185             sig=0;
05186          }
05187          cpl_vector_delete(val);
05188       }
05189 
05190       for ( i = 0 ; i < n_cubes ; i++ ) {
05191          t_img=cpl_imagelist_get(tmpcubes[i],m);
05192          ptdata=cpl_image_get_data_float(t_img);
05193 
05194          lox=llx[i];
05195          loy=lly[i];
05196          upx=llx[i]+ilx;
05197          upy=lly[i]+ily;
05198 
05199          // Do k-s clipping at each pixel 
05200          if ( y >= loy && y < upy && x >= lox && x < upx ) {
05201             posx = x - lox ;
05202             posy = y - loy ;
05203             post = posx+posy*ilx;
05204             if (!isnan(ptdata[post]) && ptdata[post] != 0. &&
05205                 (cpl_vector_get(*msk,i) != 0)) {
05206                if( abs( (ptdata[post]-med) ) > kappa*sig ) {
05207                   ptdata[post]=0;
05208                   (*pmdata)[x+y*mlx] -= exptimes[i]  ;
05209                   check_nomsg(cpl_vector_set(*msk,i,0));
05210                   nclip++;
05211                }
05212             }
05213          }
05214       }
05215    } // end of k-s clipping 
05216 
05217   cleanup:
05218    return 0;
05219 }
05220 
05243 static int
05244 sinfo_coadd_with_ks_clip2(const int z_min,
05245             const int z_max,
05246             const int ilx,
05247             const int ily,
05248             const int n_cubes,
05249             const double kappa,
05250             int* llx,
05251             int* lly,
05252                         double* exptimes,
05253             cpl_imagelist* mask,
05254             cpl_imagelist* mergedCube,
05255                         cpl_imagelist** tmpcubes)
05256 
05257 {
05258 
05259   int m=0;
05260   int x=0;
05261   int y=0;
05262   int z=0;
05263 
05264   int mlx=0;
05265   int mly=0;
05266   int nc=0;
05267   int olx=0;
05268   int oly=0;
05269   int posx=0;
05270   int posy=0;
05271   int i=0;
05272 
05273   float  msk_sum=0;
05274   float  val_msk_sum=0;
05275   float avg=0;
05276 
05277   float* pmdata=NULL;
05278   float* podata=NULL;
05279   float* pvdata=NULL;
05280 
05281   cpl_image* m_img=NULL;
05282   cpl_image* o_img=NULL;
05283   cpl_image* v_img=NULL;
05284 
05285 
05286   cpl_vector* msk=NULL;
05287 
05288 
05289   o_img=cpl_imagelist_get(mergedCube,0);
05290   olx=cpl_image_get_size_x(o_img);
05291   oly=cpl_image_get_size_y(o_img);
05292 
05293   m=0;
05294   for ( z = z_min; z < z_max ; z++ ) {
05295     m_img=cpl_imagelist_get(mask,z);
05296     pmdata=cpl_image_get_data_float(m_img);
05297     o_img=cpl_imagelist_get(mergedCube,z);
05298     podata=cpl_image_get_data_float(o_img);
05299     mlx=cpl_image_get_size_x(m_img);
05300     mly=cpl_image_get_size_y(m_img);
05301     // go through the first image plane of the big data cube 
05302     for ( y = 0 ; y < oly ; y++ ) {
05303       for ( x = 0 ; x < olx ; x++ ) {
05304     avg=0;
05305     nc=0;
05306     // computes nc 
05307 
05308         nc=sinfo_compute_contributes_at_pos(tmpcubes,llx,lly,x,y,
05309                                             ilx,ily,m,n_cubes);
05310 
05311         if( nc > 0 ) {
05312 
05313       
05314       msk=cpl_vector_new(n_cubes);
05315       for (i=0;i<n_cubes;i++) {
05316         cpl_vector_set(msk,i,1);
05317       }
05318 
05319 
05320            sinfo_cubes_coadd_with_ks_clip(tmpcubes, n_cubes,nc,x,y,m,
05321                                           llx,lly,ilx,ily,kappa, 
05322                                           exptimes,&pmdata, &msk,mlx);
05323 
05324       msk_sum=0;
05325       val_msk_sum=0;
05326       for ( i = 0 ; i < n_cubes ; i++ ) {
05327         v_img=cpl_imagelist_get(tmpcubes[i],m);
05328         pvdata=cpl_image_get_data_float(v_img);
05329         // computes sky at each point 
05330             if ( y >= lly[i] && y < lly[i]+ily &&
05331                  x >= llx[i] && x < llx[i]+ilx ) {
05332           posx = x - llx[i] ;
05333           posy = y - lly[i] ;
05334               //sinfo_msg_warning("llx[%d]=%d lly[%d],=%d",i,llx[i],i,lly[i]);
05335               //sinfo_msg_warning("posx=%d posy=%d",posx,posy);
05336               if (!isnan(pvdata[posx+posy*ilx]) &&
05337                          pvdata[posx+posy*ilx] != 0. &&
05338           (cpl_vector_get(msk,i) != 0)) {
05339         msk_sum+=pmdata[x+y*mlx];
05340                 val_msk_sum+=pvdata[posx+posy*ilx]*
05341           pmdata[x+y*mlx];
05342           }
05343         }
05344       }
05345       podata[x+y*olx]=val_msk_sum/msk_sum;
05346       cpl_vector_delete(msk);
05347       /*
05348       sinfo_ks_clip(n_cubes,nc,ilx,ily,kappa,llx,lly,exptimes,
05349             tmpcubes,podata,pmdata,x,y,m,mlx,oly);
05350 
05351       */
05352 
05353     } // end check if overlap nc >0  
05354       } // end loop over x 
05355     } // end loop over y 
05356     m++;
05357   } // end loop over z 
05358 
05359   return 0;
05360 
05361 
05362 }
05363 
05364 

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