sinfo_new_cube_ops.c

00001 /*$Id: sinfo_new_cube_ops.c,v 1.42 2010/07/26 13:44:08 kmirny 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: kmirny $
00030  * $Date: 2010/07/26 13:44:08 $
00031  * $Revision: 1.42 $
00032  * $Name: sinfo-2_2_5 $
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 
00322 
00323 /* temporally commented out as not yet used
00324 static int
00325 sinfo_ks_clip(
00326           const int n_cubes,
00327               const int nc,
00328           const int ilx,
00329           const int ily,
00330           const double kappa,
00331           int* llx,
00332           int* lly,
00333           double* exptimes,
00334           cpl_imagelist** tmpcubes,
00335               float* podata,
00336               float* pmdata,
00337           const int x,
00338           const int y,
00339           const int m,
00340           const int mlx,
00341           const int olx
00342           );
00343 
00344 
00345 */
00346 
00370 cpl_imagelist *
00371 sinfo_new_cube_ops(
00372     cpl_imagelist    *    cube1,
00373     cpl_imagelist    *    cube2,
00374     int        operation)
00375 {
00376 
00377     if (cube1==NULL || cube2==NULL)
00378     {
00379         sinfo_msg_error("null cubes");
00380         return NULL ;
00381     }
00382 
00383     switch(operation)
00384     {
00385     case '+':
00386     return sinfo_new_cube_add(cube1, cube2) ;
00387     break ;
00388     case '-':
00389     return sinfo_new_cube_sub(cube1, cube2) ;
00390     break ;
00391 
00392     case '*':
00393     return sinfo_new_cube_mul(cube1, cube2) ;
00394     break ;
00395 
00396     case '/':
00397     return sinfo_new_cube_div(cube1, cube2) ;
00398     break ;
00399 
00400     default:
00401     sinfo_msg_error("illegal requested operation: aborting cube arithmetic") ;
00402     return NULL ;
00403     }
00404 }
00405 
00406 
00407 /*----------------------------------------------------------------------------
00408    Function    :    sinfo_new_cube_const_ops()
00409    In         :    1 cube, 1 constant, operation to perform
00410    Out         :    result cube
00411    Job        :    4 operations between a cube and a constant
00412    Notice    :    possible operations are:
00413                   Addition    '+'
00414                   Subtraction     '-'
00415                   Multiplication    '*'
00416                   Division    '/'
00417                   Logarithm    'l'
00418                   Power        '^'
00419                   Exponentiation    'e'
00420 
00421  ---------------------------------------------------------------------------*/
00422 
00423 cpl_imagelist *
00424 sinfo_new_cube_const_ops(
00425     cpl_imagelist    *    c1,
00426     double        constant,
00427     int        operation)
00428 {
00429     int ilx1=0;
00430     int ily1=0;
00431     int inp1=0;
00432     cpl_imagelist* c2=NULL;
00433     cpl_image* img1=NULL;
00434 
00435 
00436 
00437     if (c1 == NULL)
00438     {
00439          sinfo_msg_error("null cube") ;
00440          return NULL ;
00441     }
00442     inp1=cpl_imagelist_get_size(c1);
00443     img1=cpl_imagelist_get(c1,0);
00444     ilx1=cpl_image_get_size_x(img1);
00445     ily1=cpl_image_get_size_y(img1);
00446 
00447 
00448 
00449 
00450 
00451     if ((constant == 0.0) && (operation == '/'))
00452     {
00453         sinfo_msg_error("division by zero requested "
00454                         "in cube/constant operation") ;
00455         return NULL ;
00456     }
00457 
00458     if ( NULL == (c2 = cpl_imagelist_new()) )
00459     {
00460         sinfo_msg_error ("cannot allocate new cube" ) ;
00461         return NULL ;
00462     }
00463 
00464     c2=cpl_imagelist_duplicate(c1);
00465     if(operation == '+') {
00466       cpl_imagelist_add_scalar(c2,constant);
00467     } else if (operation == '-') {
00468       cpl_imagelist_subtract_scalar(c2,constant);
00469     } else if (operation == '*') {
00470       cpl_imagelist_multiply_scalar(c2,constant);
00471     } else if (operation == '/') {
00472       cpl_imagelist_divide_scalar(c2,constant);
00473 
00474     } else {
00475       sinfo_msg_error("operation not supported");
00476       return NULL;
00477     }
00478     return c2 ;
00479 }
00480 
00481 
00482 /*----------------------------------------------------------------------------
00483  * Function    :    sinfo_new_cube_sub()
00484  * In         :    two cubes
00485  * Out         :    result cube
00486  * Job        :    subtract one cube from another
00487  *--------------------------------------------------------------------------*/
00488 
00489 cpl_imagelist *
00490 sinfo_new_cube_sub(
00491     cpl_imagelist    *    c1,
00492     cpl_imagelist    *    c2
00493 )
00494 {
00495     cpl_imagelist   *                 c3 ;
00496     ulong32            i ;
00497     int                     np ;
00498     int ilx1=0;
00499     int ily1=0;
00500     int inp1=0;
00501     int ilx2=0;
00502     int ily2=0;
00503     int inp2=0;
00504 
00505 
00506     cpl_image* i_img=NULL;
00507     cpl_image* img1=NULL;
00508     cpl_image* img2=NULL;
00509     cpl_image* img3=NULL;
00510     float* p1data=NULL;
00511     float* p2data=NULL;
00512     float* p3data=NULL;
00513 
00514 
00515 
00516     inp1=cpl_imagelist_get_size(c1);
00517     i_img=cpl_imagelist_get(c1,0);
00518     ilx1=cpl_image_get_size_x(i_img);
00519     ily1=cpl_image_get_size_y(i_img);
00520 
00521 
00522     inp2=cpl_imagelist_get_size(c2);
00523     i_img=cpl_imagelist_get(c2,0);
00524     ilx2=cpl_image_get_size_x(i_img);
00525     ily2=cpl_image_get_size_y(i_img);
00526 
00527     if ((ilx1 != ilx2) ||
00528     (ily1 != ily2))
00529     {
00530     sinfo_msg_error("incompatible size: cannot subtract") ;
00531     return NULL ;
00532     }
00533 
00534     if ((inp2 != inp1) &&
00535     (inp2 != 1))
00536     {
00537     sinfo_msg_error("cannot compute with these number of planes") ;
00538     return NULL ;
00539     }
00540 
00541     if ( NULL == (c3 = cpl_imagelist_new()) )
00542     {
00543         sinfo_msg_error ("cannot allocate new cube" ) ;
00544         return NULL ;
00545     }
00546 
00547     for (np=0 ; np < inp1 ; np++)
00548     {
00549       img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
00550       cpl_imagelist_set(c3,img3,np);
00551     }
00552 
00553 
00554     for (np=0 ; np < inp1 ; np++)
00555     {
00556       img1=cpl_imagelist_get(c1,np);
00557       p1data=cpl_image_get_data_float(img1);
00558       img2=cpl_imagelist_get(c2,np);
00559       p2data=cpl_image_get_data_float(img2);
00560       img3=cpl_imagelist_get(c3,np);
00561       p3data=cpl_image_get_data_float(img3);
00562 
00563         for (i=0 ; i< (ulong32)ilx1*ily1 ; i++)
00564         {
00565             p3data[i] = p1data[i] - p2data[i] ;
00566     }
00567     }
00568 
00569     return c3 ;
00570 }
00571 
00572 
00573 /*----------------------------------------------------------------------------
00574  * Function    :    sinfo_new_cube_add()
00575  * In         :    two cubes
00576  * Out         :    result cube
00577  * Job        :    add a cube to another
00578  *--------------------------------------------------------------------------*/
00579 
00580 cpl_imagelist *
00581 sinfo_new_cube_add(
00582     cpl_imagelist    *    c1,
00583     cpl_imagelist    *    c2
00584 )
00585 {
00586     cpl_imagelist  *          c3 ;
00587     ulong32        i ;
00588     int         np ;
00589     int ilx1=0;
00590     int ily1=0;
00591     int inp1=0;
00592     int ilx2=0;
00593     int ily2=0;
00594     int inp2=0;
00595 
00596 
00597     cpl_image* i_img=NULL;
00598     cpl_image* img1=NULL;
00599     cpl_image* img2=NULL;
00600     cpl_image* img3=NULL;
00601     float* p1data=NULL;
00602     float* p2data=NULL;
00603     float* p3data=NULL;
00604 
00605 
00606 
00607     inp1=cpl_imagelist_get_size(c1);
00608     i_img=cpl_imagelist_get(c1,0);
00609     ilx1=cpl_image_get_size_x(i_img);
00610     ily1=cpl_image_get_size_y(i_img);
00611 
00612 
00613     inp2=cpl_imagelist_get_size(c2);
00614     i_img=cpl_imagelist_get(c2,0);
00615     ilx2=cpl_image_get_size_x(i_img);
00616     ily2=cpl_image_get_size_y(i_img);
00617     if ((ilx1 != ilx2) || (ily1 != ily2))
00618     {
00619     sinfo_msg_error("incompatible size: cannot add") ;
00620     return NULL ;
00621     }
00622     if ((inp2 != inp1) && (inp2 != 1))
00623     {
00624     sinfo_msg_error("cannot compute with these number of planes") ;
00625     return NULL ;
00626     }
00627 
00628     if (NULL == (c3 = cpl_imagelist_new()) )
00629     {
00630         sinfo_msg_error ("cannot allocate new cube") ;
00631         return NULL ;
00632     }
00633 
00634     for (np=0 ; np < inp1 ; np++)
00635     {
00636       img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
00637       cpl_imagelist_set(c3,img3,np);
00638     }
00639 
00640     for (np=0 ; np < inp1 ; np++)
00641     {
00642       img1=cpl_imagelist_get(c1,np);
00643       p1data=cpl_image_get_data_float(img1);
00644       img2=cpl_imagelist_get(c2,np);
00645       p2data=cpl_image_get_data_float(img2);
00646       img3=cpl_imagelist_get(c3,np);
00647       p3data=cpl_image_get_data_float(img3);
00648         for (i=0 ; i< (ulong32)ilx1*ily1 ; i++)
00649         {
00650         p3data[i] = p1data[i] + p2data[i] ;
00651         }
00652     }
00653 
00654     return c3 ;
00655 }
00656 
00657 /*----------------------------------------------------------------------------
00658  * Function    :    sinfo_new_cube_mul()
00659  * In         :    two cubes
00660  * Out         :    result cube
00661  * Job        :    multiply 2 cubes
00662  *--------------------------------------------------------------------------*/
00663 
00664 cpl_imagelist *
00665 sinfo_new_cube_mul(
00666     cpl_imagelist    *    c1,
00667     cpl_imagelist    *    c2
00668 )
00669 {
00670     cpl_imagelist             *c3 ;
00671     ulong32        i ;
00672     int                np ;
00673     int ilx1=0;
00674     int ily1=0;
00675     int inp1=0;
00676     int ilx2=0;
00677     int ily2=0;
00678     int inp2=0;
00679 
00680 
00681     cpl_image* i_img=NULL;
00682     cpl_image* img1=NULL;
00683     cpl_image* img2=NULL;
00684     cpl_image* img3=NULL;
00685     float* p1data=NULL;
00686     float* p2data=NULL;
00687     float* p3data=NULL;
00688 
00689 
00690 
00691 
00692     inp1=cpl_imagelist_get_size(c1);
00693     i_img=cpl_imagelist_get(c1,0);
00694     ilx1=cpl_image_get_size_x(i_img);
00695     ily1=cpl_image_get_size_y(i_img);
00696 
00697 
00698     inp2=cpl_imagelist_get_size(c2);
00699     i_img=cpl_imagelist_get(c2,0);
00700     ilx2=cpl_image_get_size_x(i_img);
00701     ily2=cpl_image_get_size_y(i_img);
00702 
00703     if ((ilx1 != ilx2) || (ily1 != ily2))
00704     {
00705     sinfo_msg_error("incompatible size: cannot multiply") ;
00706     return NULL ;
00707     }
00708 
00709     if ((inp2 != inp1) && (inp2 != 1))
00710     {
00711     sinfo_msg_error("cannot compute with these number of planes") ;
00712     return NULL ;
00713     }
00714 
00715     if ( NULL == (c3 = cpl_imagelist_new()) )
00716     {
00717         sinfo_msg_error ("cannot allocate new cube" ) ;
00718         return NULL ;
00719     }
00720 
00721 
00722     for (np=0 ; np < inp1 ; np++)
00723     {
00724       img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
00725       cpl_imagelist_set(c3,img3,np);
00726     }
00727 
00728     for (np=0 ; np < inp1 ; np++)
00729     {
00730       img1=cpl_imagelist_get(c1,np);
00731       p1data=cpl_image_get_data_float(img1);
00732       img2=cpl_imagelist_get(c2,np);
00733       p2data=cpl_image_get_data_float(img2);
00734       img3=cpl_imagelist_get(c3,np);
00735       p3data=cpl_image_get_data_float(img3);
00736         for (i=0 ; i< (ulong32)ilx1*ilx2 ; i++)
00737         {
00738             p3data[i] = p1data[i] * p2data[i] ;
00739         }
00740     }
00741 
00742     return c3 ;
00743 }
00744 
00745 
00746 /*----------------------------------------------------------------------------
00747  * Function    :    sinfo_new_cube_div()
00748  * In         :    two cubes
00749  * Out         :    result cube
00750  * Job        :    divide 2 cubes
00751  *--------------------------------------------------------------------------*/
00752 
00753 cpl_imagelist *
00754 sinfo_new_cube_div(
00755     cpl_imagelist    *    c1,
00756     cpl_imagelist    *    c2
00757 )
00758 {
00759     cpl_imagelist *           c3 ;
00760     ulong32        i ;
00761     int         np ;
00762     int ilx1=0;
00763     int ily1=0;
00764     int inp1=0;
00765     int ilx2=0;
00766     int ily2=0;
00767     int inp2=0;
00768 
00769 
00770     cpl_image* i_img=NULL;
00771     cpl_image* img1=NULL;
00772     cpl_image* img2=NULL;
00773     cpl_image* img3=NULL;
00774     float* p1data=NULL;
00775     float* p2data=NULL;
00776     float* p3data=NULL;
00777 
00778 
00779     inp1=cpl_imagelist_get_size(c1);
00780     i_img=cpl_imagelist_get(c1,0);
00781     ilx1=cpl_image_get_size_x(i_img);
00782     ily1=cpl_image_get_size_y(i_img);
00783 
00784 
00785     inp2=cpl_imagelist_get_size(c2);
00786     i_img=cpl_imagelist_get(c2,0);
00787     ilx2=cpl_image_get_size_x(i_img);
00788     ily2=cpl_image_get_size_y(i_img);
00789 
00790     if ((ilx1 != ilx2) ||
00791     (ily1 != ily2))
00792     {
00793     sinfo_msg_error("incompatible size: cannot divide") ;
00794     return NULL ;
00795     }
00796 
00797     if ((inp2 != inp1) && (inp2 != 1))
00798     {
00799     sinfo_msg_error("cannot compute with these number of planes") ;
00800     return NULL ;
00801     }
00802 
00803     if (NULL == (c3 = cpl_imagelist_new()) )
00804     {
00805         sinfo_msg_error ("cannot allocate a new cube") ;
00806         return NULL ;
00807     }
00808 
00809     for (np=0 ; np < inp1 ; np++)
00810     {
00811       img3=cpl_image_new(ilx1,ily1,CPL_TYPE_FLOAT);
00812       cpl_imagelist_set(c3,img3,np);
00813     }
00814 
00815     for (np=0 ; np < inp1 ; np++)
00816     {
00817       img1=cpl_imagelist_get(c1,np);
00818       p1data=cpl_image_get_data_float(img1);
00819       img2=cpl_imagelist_get(c2,np);
00820       p2data=cpl_image_get_data_float(img2);
00821       img3=cpl_imagelist_get(c3,np);
00822       p3data=cpl_image_get_data_float(img3);
00823 
00824 
00825         for (i=0 ; i< (ulong32) ilx1*ily1 ; i++)
00826         {
00827             if (fabs((double)p2data[i]) < 1e-10)
00828             {
00829             p3data[i] = 0.0 ;
00830             }
00831             else
00832             {
00833                 p3data[i] = p1data[i] / p2data[i] ;
00834             }
00835         }
00836     }
00837 
00838     return c3 ;
00839 }
00840 
00841 
00842 
00843 /*---------------------------------------------------------------------------
00844    Function    :    sinfo_new_add_image_to_cube()
00845    In         :    1 allocated cube, 1 allocated image
00846    Out         :    result cube
00847    Job        :    add an image to all planes in the cube
00848  ---------------------------------------------------------------------------*/
00849 
00850 cpl_imagelist *
00851 sinfo_new_add_image_to_cube(cpl_imagelist * cu, cpl_image * im)
00852 {
00853     cpl_imagelist *   cube ;
00854     int               i ;
00855     int clx=0;
00856     int cly=0;
00857     int cnp=0;
00858     int ilx=0;
00859     int ily=0;
00860 
00861 
00862     cpl_image* i_img=NULL;
00863 
00864     if (cu==NULL || im==NULL)
00865     {
00866        sinfo_msg_error ("null cube or null image") ;
00867        return NULL ;
00868     }
00869     cnp=cpl_imagelist_get_size(cu);
00870     i_img=cpl_imagelist_get(cu,0);
00871     clx=cpl_image_get_size_x(i_img);
00872     cly=cpl_image_get_size_y(i_img);
00873 
00874     ilx=cpl_image_get_size_x(im);
00875     ily=cpl_image_get_size_y(im);
00876 
00877     if ((clx != ilx) || (cly != ily))
00878     {
00879         sinfo_msg_error("incompatible size: cannot add image to cube") ;
00880     return NULL ;
00881     }
00882 
00883     cube = cpl_imagelist_duplicate (cu) ;
00884 
00885     for (i=0 ; i<cnp ; i++)
00886     {
00887       /* AMO
00888         here may be we have to use cpl_image_add_create and cpl_imagelist_set
00889        */
00890     cpl_image_add(cpl_imagelist_get(cube,i), im) ;
00891     }
00892 
00893     return cube ;
00894 }
00895 
00896 /*---------------------------------------------------------------------------
00897    Function    :    sinfo_new_sub_image_from_cube()
00898    In         :    1 allocated cube, 1 allocated image
00899    Out         :       result cube
00900    Job        :    subtract an image from all planes in the cube
00901  ---------------------------------------------------------------------------*/
00902 
00903 cpl_imagelist *
00904 sinfo_new_sub_image_from_cube (cpl_imagelist * cu, cpl_image * im)
00905 {
00906     cpl_imagelist   * cube ;
00907     int               i ;
00908     int clx=0;
00909     int cly=0;
00910     int cnp=0;
00911     int ilx=0;
00912     int ily=0;
00913 
00914 
00915     cpl_image* i_img=NULL;
00916 
00917     if (cu==NULL || im==NULL)
00918     {
00919         sinfo_msg_error ("null cube or null image") ;
00920         return NULL ;
00921     }
00922     cnp=cpl_imagelist_get_size(cu);
00923     i_img=cpl_imagelist_get(cu,0);
00924     clx=cpl_image_get_size_x(i_img);
00925     cly=cpl_image_get_size_y(i_img);
00926 
00927     ilx=cpl_image_get_size_x(im);
00928     ily=cpl_image_get_size_y(im);
00929 
00930     if ((clx != ilx) || (cly != ily))
00931     {
00932 
00933     sinfo_msg_error("incompatible size: cannot subtract image from cube") ;
00934         return NULL ;
00935     }
00936 
00937     cube = cpl_imagelist_duplicate (cu) ;
00938 
00939     for (i=0 ; i<cnp ; i++)
00940     {
00941       /* AMO
00942         here may be we have to use cpl_image_add_create and cpl_imagelist_set
00943        */
00944     cpl_image_subtract(cpl_imagelist_get(cube,i), im) ;
00945     }
00946     return cube ;
00947 }
00948 
00949 /*---------------------------------------------------------------------------
00950    Function    :    sinfo_new_mul_image_to_cube()
00951    In         :    1 allocated cube, 1 allocated image
00952    Out         :    result cube
00953    Job        :    multiply an image to all planes in the cube
00954  ---------------------------------------------------------------------------*/
00955 
00956 cpl_imagelist *
00957 sinfo_new_mul_image_to_cube(cpl_imagelist * cu, cpl_image * im)
00958 {
00959     cpl_imagelist   * cube ;
00960     int               i ;
00961     int clx=0;
00962     int cly=0;
00963     int cnp=0;
00964     int ilx=0;
00965     int ily=0;
00966 
00967 
00968     cpl_image* i_img=NULL;
00969 
00970     if (cu==NULL || im==NULL)
00971     {
00972         sinfo_msg_error("null cube or null image") ;
00973         return NULL ;
00974     }
00975     cnp=cpl_imagelist_get_size(cu);
00976     i_img=cpl_imagelist_get(cu,0);
00977     clx=cpl_image_get_size_x(i_img);
00978     cly=cpl_image_get_size_y(i_img);
00979 
00980     ilx=cpl_image_get_size_x(im);
00981     ily=cpl_image_get_size_y(im);
00982 
00983     if ((clx != ilx) || (cly != ily))
00984     {
00985     sinfo_msg_error("incompatible size: cannot multiply image by cube") ;
00986     return NULL ;
00987     }
00988 
00989     cube = cpl_imagelist_duplicate (cu) ;
00990 
00991     for (i=0 ; i<cnp ; i++)
00992     {
00993       /* AMO
00994         here may be we have to use cpl_image_add_create and cpl_imagelist_set
00995        */
00996     cpl_image_multiply(cpl_imagelist_get(cube,i), im) ;
00997     }
00998 
00999     return cube ;
01000 }
01001 
01002 /*---------------------------------------------------------------------------
01003    Function    :    sinfo_new_div_cube_by_image()
01004    In         :    1 allocated cube, 1 allocated image
01005    Out         :    result cube
01006    Job        :    divide all planes in the cube by an image
01007  ---------------------------------------------------------------------------*/
01008 
01009 cpl_imagelist *
01010 sinfo_new_div_cube_by_image(cpl_imagelist * cu, cpl_image * im)
01011 {
01012     cpl_imagelist   * cube ;
01013     int               i ;
01014     int clx=0;
01015     int cly=0;
01016     int cnp=0;
01017     int ilx=0;
01018     int ily=0;
01019 
01020 
01021     cpl_image* i_img=NULL;
01022 
01023     if (cu==NULL || im==NULL)
01024     {
01025         sinfo_msg_error ("null cube or null image") ;
01026         return NULL ;
01027     }
01028     cnp=cpl_imagelist_get_size(cu);
01029     i_img=cpl_imagelist_get(cu,0);
01030     clx=cpl_image_get_size_x(i_img);
01031     cly=cpl_image_get_size_y(i_img);
01032 
01033     ilx=cpl_image_get_size_x(im);
01034     ily=cpl_image_get_size_y(im);
01035 
01036     if ((clx != ilx) || (cly != ily))
01037     {
01038     sinfo_msg_error("incompatible size: cannot divide cube by image") ;
01039     return NULL ;
01040     }
01041 
01042     cube = cpl_imagelist_duplicate (cu) ;
01043 
01044     for (i=0 ; i<cnp ; i++)
01045     {
01046       /* AMO
01047         here may be we have to use cpl_image_add_create and cpl_imagelist_set
01048        */
01049     cpl_image_divide(cpl_imagelist_get(cube,i), im) ;
01050     }
01051 
01052     return cube ;
01053 }
01054 
01055 
01056 /*---------------------------------------------------------------------------
01057    Function    :    sinfo_new_add_spectrum_to_cube()
01058    In         :    1 allocated cube, 1 allocated spectrum sinfo_vector
01059    Out         :    result cube
01060    Job        :    adds a spectrum (in z-direction) to all data
01061                         points in a cube
01062  ---------------------------------------------------------------------------*/
01063 
01064 cpl_imagelist *
01065 sinfo_new_add_spectrum_to_cube(cpl_imagelist *cu, Vector *spec)
01066 {
01067     cpl_imagelist *   cube ;
01068     int         i ,j ;
01069     int ilx=0;
01070     int ily=0;
01071     int inp=0;
01072     float* pidata=NULL;
01073     float* podata=NULL;
01074     cpl_image* i_img=NULL;
01075     cpl_image* o_img=NULL;
01076 
01077     if (cu == NULL || spec == NULL)
01078     {
01079         sinfo_msg_error ("null cube or null spectrum") ;
01080         return NULL ;
01081     }
01082     inp=cpl_imagelist_get_size(cu);
01083     i_img=cpl_imagelist_get(cu,0);
01084     ilx=cpl_image_get_size_x(i_img);
01085     ily=cpl_image_get_size_y(i_img);
01086 
01087     if ( inp != spec -> n_elements )
01088     {
01089         sinfo_msg_error("cube length and spectrum length are not compatible") ;
01090         return NULL ;
01091     }
01092 
01093     if ( NULL == (cube = cpl_imagelist_new ()) )
01094     {
01095         sinfo_msg_error ("cannot allocate new cube" ) ;
01096         return NULL ;
01097     }
01098     for ( i = 0; i < inp; i++)
01099     {
01100       o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
01101       cpl_imagelist_set(cube,o_img,i);
01102     }
01103 
01104 
01105     for ( i = 0; i < inp; i++)
01106     {
01107       i_img=cpl_imagelist_get(cu,i);
01108       pidata=cpl_image_get_data_float(i_img);
01109       o_img=cpl_imagelist_get(cube,i);
01110       podata=cpl_image_get_data_float(o_img);
01111         for ( j = 0; j < (int) ilx*ily; j++)
01112         {
01113             podata[j] = pidata[j] + spec -> data[i] ;
01114         }
01115     }
01116 
01117     return cube ;
01118 }
01119 
01120 /*---------------------------------------------------------------------------
01121    Function    :    sinfo_new_sub_spectrum_from_cube()
01122    In         :    1 allocated cube, 1 allocated spectrum sinfo_vector
01123    Out         :    result cube
01124    Job        :    subtracts a spectrum (in z-direction) from all
01125                         data points in a cube
01126  ---------------------------------------------------------------------------*/
01127 
01128 cpl_imagelist *
01129 sinfo_new_sub_spectrum_from_cube(cpl_imagelist *cu, Vector *spec)
01130 {
01131     cpl_imagelist *   cube ;
01132     int         i ,j ;
01133     int ilx=0;
01134     int ily=0;
01135     int inp=0;
01136     float* pidata=NULL;
01137     float* podata=NULL;
01138     cpl_image* i_img=NULL;
01139     cpl_image* o_img=NULL;
01140 
01141     if (cu == NULL || spec == NULL)
01142     {
01143         sinfo_msg_error ("null cube or null spectrum") ;
01144         return NULL ;
01145     }
01146     inp=cpl_imagelist_get_size(cu);
01147     i_img=cpl_imagelist_get(cu,0);
01148     ilx=cpl_image_get_size_x(i_img);
01149     ily=cpl_image_get_size_y(i_img);
01150 
01151     if ( inp != spec -> n_elements )
01152     {
01153         sinfo_msg_error("cube length and spectrum length are not compatible") ;
01154         return NULL ;
01155     }
01156 
01157     if ( NULL == (cube = cpl_imagelist_new()) )
01158     {
01159         sinfo_msg_error ("cannot allocate new cube" ) ;
01160         return NULL ;
01161     }
01162     for ( i = 0; i < inp; i++)
01163     {
01164       o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
01165       cpl_imagelist_set(cube,o_img,i);
01166     }
01167 
01168     for ( i = 0; i < inp; i++)
01169     {
01170       i_img=cpl_imagelist_get(cu,i);
01171       pidata=cpl_image_get_data_float(i_img);
01172       o_img=cpl_imagelist_get(cube,i);
01173       podata=cpl_image_get_data_float(o_img);
01174         for ( j = 0; j < (int) ilx*ily; j++)
01175         {
01176             if ( isnan(pidata[j]) || isnan(spec -> data[i]) )
01177             {
01178                 podata[j] = ZERO ;
01179             }
01180             else
01181             {
01182                 podata[j] = pidata[j] - spec -> data[i] ;
01183             }
01184         }
01185     }
01186 
01187     return cube ;
01188 }
01189 
01190 
01191 /*---------------------------------------------------------------------------
01192    Function    :    sinfo_new_mul_spectrum_to_cube()
01193    In         :    1 allocated cube, 1 allocated spectrum sinfo_vector
01194    Out         :    result cube
01195    Job        :    multiplies a spectrum (in z-direction) to all data
01196                         points in a cube
01197  ---------------------------------------------------------------------------*/
01198 
01199 cpl_imagelist *
01200 sinfo_new_mul_spectrum_to_cube(cpl_imagelist *cu, Vector *spec)
01201 {
01202     cpl_imagelist *   cube ;
01203     int         i ,j ;
01204     int ilx=0;
01205     int ily=0;
01206     int inp=0;
01207     float* pidata=NULL;
01208     float* podata=NULL;
01209     cpl_image* i_img=NULL;
01210     cpl_image* o_img=NULL;
01211 
01212     if (cu == NULL || spec == NULL)
01213     {
01214         sinfo_msg_error ("null cube or null spectrum") ;
01215         return NULL ;
01216     }
01217     inp=cpl_imagelist_get_size(cu);
01218     i_img=cpl_imagelist_get(cu,0);
01219     ilx=cpl_image_get_size_x(i_img);
01220     ily=cpl_image_get_size_y(i_img);
01221 
01222     if ( inp != spec -> n_elements )
01223     {
01224         sinfo_msg_error("cube length and spectrum length are not compatible") ;
01225         return NULL ;
01226     }
01227 
01228     if ( NULL == (cube = cpl_imagelist_new ()) )
01229     {
01230         sinfo_msg_error ("cannot allocate new cube" ) ;
01231         return NULL ;
01232     }
01233 
01234     for ( i = 0; i < inp; i++)
01235     {
01236       o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
01237       cpl_imagelist_set(cube,o_img,i);
01238     }
01239 
01240     for ( i = 0; i < inp; i++)
01241     {
01242       i_img=cpl_imagelist_get(cu,i);
01243       pidata=cpl_image_get_data_float(i_img);
01244       o_img=cpl_imagelist_get(cube,i);
01245       podata=cpl_image_get_data_float(o_img);
01246         for ( j = 0; j < (int) ilx*ily; j++)
01247         {
01248             if ( isnan(pidata[j]) || isnan(spec->data[i]) )
01249             {
01250                 podata[j] = ZERO ;
01251             }
01252             else
01253             {
01254                 podata[j] = pidata[j] * spec -> data[i] ;
01255             }
01256         }
01257     }
01258 
01259     return cube ;
01260 }
01261 
01262 
01263 /*---------------------------------------------------------------------------
01264    Function    :    sinfo_new_div_cube_by_spectrum()
01265    In         :    1 allocated cube, 1 allocated spectrum sinfo_vector
01266    Out         :    result cube
01267    Job        :    divides all data points of a cube by a spectrum
01268                         (in z-direction)
01269  ---------------------------------------------------------------------------*/
01270 
01271 cpl_imagelist *
01272 sinfo_new_div_cube_by_spectrum(cpl_imagelist *cu, Vector *spec)
01273 {
01274     cpl_imagelist *   cube ;
01275     float       help ;
01276     int         i ,j ;
01277     int ilx=0;
01278     int ily=0;
01279     int inp=0;
01280     float* pidata=NULL;
01281     float* podata=NULL;
01282     cpl_image* i_img=NULL;
01283     cpl_image* o_img=NULL;
01284 
01285     if (cu == NULL || spec == NULL)
01286     {
01287         sinfo_msg_error ("null cube or null spectrum") ;
01288         return NULL ;
01289     }
01290     inp=cpl_imagelist_get_size(cu);
01291     i_img=cpl_imagelist_get(cu,0);
01292     ilx=cpl_image_get_size_x(i_img);
01293     ily=cpl_image_get_size_y(i_img);
01294 
01295     if ( inp != spec -> n_elements )
01296     {
01297         sinfo_msg_error("cube length and spectrum length are not compatible") ;
01298         return NULL ;
01299     }
01300 
01301     if (NULL == (cube = cpl_imagelist_new ()) )
01302     {
01303         sinfo_msg_error ("cannot allocate new cube") ;
01304         return NULL ;
01305     }
01306 
01307     for ( i = 0; i < inp; i++)
01308     {
01309       o_img=cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
01310       cpl_imagelist_set(cube,o_img,i);
01311     }
01312 
01313     for ( i = 0; i < inp; i++)
01314     {
01315 
01316       i_img=cpl_imagelist_get(cu,i);
01317       pidata=cpl_image_get_data_float(i_img);
01318       o_img=cpl_imagelist_get(cube,i);
01319       podata=cpl_image_get_data_float(o_img);
01320         for ( j = 0; j < (int) ilx*ily; j++)
01321         {
01322             if (!isnan(spec->data[i]) && spec->data[i] != 0.)
01323             {
01324                 help = 1/spec->data[i] ;
01325                 if ( help > THRESH )
01326                 {
01327                     help = 1. ;
01328                 }
01329             }
01330             else
01331             {
01332                 help = ZERO ;
01333             }
01334 
01335             if ( isnan(help) || isnan(pidata[j]) )
01336             {
01337                 podata[j] = ZERO ;
01338             }
01339             else
01340             {
01341                 podata[j] = pidata[j] * help ;
01342             }
01343         }
01344     }
01345     return cube ;
01346 }
01347 
01348 
01349 /*---------------------------------------------------------------------------
01350    Function    :    sinfo_new_clean_mean_of_spectra()
01351    In         :    1 allocated cube, position of rectangle in x-y plane ,
01352                         low and high cut threshold
01353    Out         :    result spectrum sinfo_vector
01354    Job        :    averaging routine to get a better spectral S/N, sorts
01355                         the values of the same z-position, cuts the lowest and
01356                         highest values according to given thresholds and then
01357                         takes the average within the x-y plane , cannot have
01358                         a sum of low and high rejected values greater than 90%
01359                         of all values
01360  ---------------------------------------------------------------------------*/
01361 
01362 Vector *
01363 sinfo_new_clean_mean_of_spectra(cpl_imagelist * cube,
01364                              int llx,
01365                              int lly,
01366                              int urx,
01367                              int ury,
01368                              double lo_reject,
01369                              double hi_reject)
01370 {
01371     Vector                           * mean ;
01372     pixelvalue                   *local_rectangle ;
01373     int                    i, j, k, l, m ;
01374     int             recsize, lo_n, hi_n, nv ;
01375     int ilx=0;
01376     int ily=0;
01377     int inp=0;
01378     float* pidata=NULL;
01379     cpl_image* i_img=NULL;
01380 
01381     if ( cube == NULL || cpl_imagelist_get_size(cube) < 1 )
01382     {
01383         sinfo_msg_error ("no cube to take the mean of his spectra") ;
01384         return NullVector ;
01385     }
01386     inp=cpl_imagelist_get_size(cube);
01387     i_img=cpl_imagelist_get(cube,0);
01388     ilx=cpl_image_get_size_x(i_img);
01389     ily=cpl_image_get_size_y(i_img);
01390 
01391     if ((llx<1) || (llx>ilx) ||
01392         (urx<1) || (urx>ilx) ||
01393         (lly<1) || (lly>ily) ||
01394         (ury<1) || (ury>ily) ||
01395         (llx>=urx) || (lly>=ury))
01396     {
01397         sinfo_msg_error("invalid rectangle coordinates:") ;
01398         sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
01399                         llx, lly, urx, ury) ;
01400         return NullVector ;
01401     }
01402 
01403     if ((lo_reject + hi_reject) > 0.9)
01404     {
01405         sinfo_msg_error("illegal rejection thresholds: [%f] and [%f]",
01406                         lo_reject, hi_reject) ;
01407         sinfo_msg_error("threshold sum should not be over 0.9"
01408                         " aborting average") ;
01409         return NullVector ;
01410     }
01411 
01412     /* shift from FITS coordinates to C coordinates */
01413     llx -- ;
01414     lly -- ;
01415     urx -- ;
01416     ury -- ;
01417 
01418     recsize = (urx - llx + 1) * (ury - lly + 1) ;
01419 
01420     lo_n = (int) (recsize * lo_reject + 0.5) ;
01421     hi_n = (int) (recsize * hi_reject + 0.5) ;
01422 
01423     if (lo_n + hi_n >= recsize)
01424     {
01425         sinfo_msg_error ("everything would be rejected") ;
01426         return NullVector;
01427     }
01428 
01429     /* allocate a new sinfo_vector to store the average spectral values */
01430     if (NULL == (mean = sinfo_new_vector (inp)) )
01431     {
01432         sinfo_msg_error ("cannot allocate a new sinfo_vector") ;
01433         return NullVector ;
01434     }
01435 
01436     /*------------------------------------------------------------------------
01437      *  loop through the cube planes, through the x axis and the y-axis of the
01438      *  plane rectangle and store pixel values in a buffer.
01439      */
01440     for ( i = 0 ; i < inp ; i++ )
01441     {
01442       i_img=cpl_imagelist_get(cube,i);
01443       pidata=cpl_image_get_data_float(i_img);
01444       m = 0 ;
01445       local_rectangle=(pixelvalue *)cpl_calloc(recsize, sizeof (pixelvalue*));
01446 
01447         for ( j = lly ; j <= ury ; j++ )
01448         {
01449             for ( k = llx ; k <= urx ; k++ )
01450             {
01451                 local_rectangle[m] = pidata[k + j * ilx] ;
01452                 m ++ ;
01453             }
01454         }
01455         /*sorts the pixelvalues in the buffer*/
01456         sinfo_pixel_qsort (local_rectangle, recsize) ;
01457 
01458         nv = 0 ;
01459         for ( l = lo_n ; l < (recsize - hi_n) ; l++ )
01460         {
01461             mean -> data[i] += local_rectangle[l] ;
01462             nv ++;
01463         }
01464         mean -> data[i] /= nv ;
01465 
01466         cpl_free ( local_rectangle ) ;
01467     }
01468     return mean ;
01469 }
01470 
01471 
01472 /*---------------------------------------------------------------------------
01473    Function    :sinfo_new_median_cube()
01474    In         :1 allocated cube
01475    Out         :result image
01476    Job        :determines the sinfo_new_median value in every pixel position
01477                  by considering all pixels along the third axis.
01478                  ZERO pixels in a plane are not considered. If all
01479                  pixels at a position are not valid the result will
01480                  be 'ZERO'.
01481  ---------------------------------------------------------------------------*/
01482 cpl_image *
01483 sinfo_new_median_cube(cpl_imagelist * cube)
01484 {
01485     cpl_image  *         im ;
01486     pixelvalue *    buffer ;
01487     int        i, j, k, nz ;
01488     int ilx=0;
01489     int ily=0;
01490     int inp=0;
01491     float* pidata=NULL;
01492     float* podata=NULL;
01493     cpl_image* i_img=NULL;
01494 
01495     if ( cube == NULL )
01496     {
01497         sinfo_msg_error ("null cube") ;
01498         return NULL ;
01499     }
01500     inp=cpl_imagelist_get_size(cube);
01501     i_img=cpl_imagelist_get(cube,0);
01502     ilx=cpl_image_get_size_x(i_img);
01503     ily=cpl_image_get_size_y(i_img);
01504 
01505     /* allocate memory */
01506     if (NULL == (im = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT )) )
01507     {
01508         sinfo_msg_error ("cannot allocate new image") ;
01509         return NULL ;
01510     }
01511 
01512     /*------------------------------------------------------------------------
01513      * transfer each sinfo_vector in z direction in a buffer and collect
01514        only non-blank data.
01515      */
01516 
01517     podata=cpl_image_get_data_float(im);
01518     for ( i = 0 ; i < (int) ilx*ily ; i++ )
01519     {
01520         buffer = (pixelvalue *) cpl_calloc (inp, sizeof (pixelvalue *));
01521         k = 0 ;
01522         for ( j = 0 ; j < inp ; j ++ )
01523         {
01524           i_img=cpl_imagelist_get(cube,j);
01525       pidata=cpl_image_get_data_float(i_img);
01526             if ( !isnan(pidata[i]) )
01527             {
01528                 buffer[k] = pidata[i] ;
01529                 k ++ ;
01530             }
01531         }
01532         nz = k ;
01533 
01534         /* proceed depending on the number of valid pixels */
01535         if ( nz > 2 )
01536         {
01537             podata[i] = sinfo_new_median ( buffer, nz ) ;
01538         }
01539         else if (nz == 2)
01540         {
01541             podata[i] = (buffer[0] + buffer[1]) / 2. ;
01542         }
01543         else if (nz == 1)
01544         {
01545             podata[i] = buffer[0] ;
01546         }
01547         else if (nz == 0)
01548         {
01549             podata[i] = ZERO ;
01550         }
01551 
01552         cpl_free ( buffer ) ;
01553     }
01554 
01555     return im ;
01556 }
01557 
01558 
01559 /*---------------------------------------------------------------------------
01560    Function    :    sinfo_new_average_cube_to_image()
01561    In         :    1 allocated cube
01562    Out         :    result image
01563    Job        :    determines the average value in every pixel position
01564                         by considering all pixels along the third axis.
01565                         ZERO pixels in a plane are not considered. If all
01566                         pixels at a position are not valid the result will
01567                         be 'ZERO'.
01568  ---------------------------------------------------------------------------*/
01569 cpl_image *
01570 sinfo_new_average_cube_to_image(cpl_imagelist * cube)
01571 {
01572     cpl_image  *      im ;
01573     int        i, j, nz ;
01574     int ilx=0;
01575     int ily=0;
01576     int inp=0;
01577     float* pidata=NULL;
01578     float* podata=NULL;
01579     cpl_image* i_img=NULL;
01580 
01581     if ( cube == NULL )
01582     {
01583         sinfo_msg_error ("null cube") ;
01584         return NULL ;
01585     }
01586     inp=cpl_imagelist_get_size(cube);
01587     i_img=cpl_imagelist_get(cube,0);
01588     ilx=cpl_image_get_size_x(i_img);
01589     ily=cpl_image_get_size_y(i_img);
01590 
01591     /* allocate memory */
01592     if (NULL == (im = cpl_image_new (ilx, ily,CPL_TYPE_FLOAT )) )
01593     {
01594         sinfo_msg_error ("cannot allocate new image") ;
01595         return NULL ;
01596     }
01597 
01598     /*------------------------------------------------------------------------
01599      * transfer each vector in z direction in a buffer and collect
01600        only non-blank data.
01601      */
01602 
01603     podata=cpl_image_get_data_float(im);
01604     for ( i = 0 ; i < (int) ilx*ily ; i++ )
01605     {
01606         nz = 0 ;
01607         for ( j = 0 ; j < inp ; j ++ )
01608         {
01609           i_img=cpl_imagelist_get(cube,j);
01610       pidata=cpl_image_get_data_float(i_img);
01611             if ( !isnan(pidata[i]) )
01612             {
01613                 nz ++ ;
01614                 podata[i] += pidata[i] ;
01615             }
01616         }
01617 
01618         /* proceed depending on the number of valid pixels */
01619         if ( nz >= 1 )
01620         {
01621             podata[i] /= nz ;
01622         }
01623         else if (nz == 0)
01624         {
01625             podata[i] = ZERO ;
01626         }
01627     }
01628 
01629     return im ;
01630 }
01631 
01632 /*---------------------------------------------------------------------------
01633    Function     :       sinfo_new_sum_cube_to_image()
01634    In           :       1 allocated cube
01635    Out          :       result image
01636    Job          :       determines the sum value in every pixel position
01637                         by considering all pixels along the third axis.
01638                         ZERO pixels in a plane are not considered. If all
01639                         pixels at a position are not valid the result will
01640                         be 'ZERO'.
01641  ---------------------------------------------------------------------------*/
01642 cpl_image *
01643 sinfo_new_sum_cube_to_image(cpl_imagelist * cube)
01644 {
01645     cpl_image  *      im ;
01646     int        i, j, nz ;
01647     int ilx=0;
01648     int ily=0;
01649     int inp=0;
01650     float* pidata=NULL;
01651     float* podata=NULL;
01652     cpl_image* i_img=NULL;
01653 
01654     if ( cube == NULL )
01655     {
01656         sinfo_msg_error ("null cube") ;
01657         return NULL ;
01658     }
01659     inp=cpl_imagelist_get_size(cube);
01660     i_img=cpl_imagelist_get(cube,0);
01661     ilx=cpl_image_get_size_x(i_img);
01662     ily=cpl_image_get_size_y(i_img);
01663 
01664     /* allocate memory */
01665     if (NULL == (im = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT )) )
01666     {
01667         sinfo_msg_error ("cannot allocate new image") ;
01668         return NULL ;
01669     }
01670 
01671     /*-------------------------------------------------------------------------
01672      * transfer each vector in z direction in a buffer and collect only
01673        non-blank data.
01674      */
01675 
01676     podata=cpl_image_get_data_float(im);
01677     for ( i = 0 ; i < (int) ilx*ily ; i++ )
01678     {
01679         nz = 0 ;
01680         for ( j = 0 ; j < inp ; j ++ )
01681         {
01682           i_img=cpl_imagelist_get(cube,j);
01683       pidata=cpl_image_get_data_float(i_img);
01684             if ( !isnan(pidata[i]) )
01685             {
01686                 nz++ ;
01687                 podata[i] += pidata[i] ;
01688             }
01689         }
01690 
01691         /* proceed depending on the number of valid pixels */
01692         if (nz == 0)
01693         {
01694             podata[i] = ZERO ;
01695         }
01696     }
01697 
01698     return im ;
01699 }
01700 
01701 /*---------------------------------------------------------------------------
01702    Function    sinfo_new_average_cube_to_image_between_waves()
01703    In         cube: data cube to collapse
01704                 dispersion: dispersion per pixel in microns/pixel
01705                 (derived from fits header information)
01706                 centralWave: central wavelength in the cube in microns
01707                                        (derived from fits header information)
01708                 initialLambda, finalLambda: wavelength values in microns
01709                                             within which the cube is averaged
01710    Out         :resulting averaged image
01711    Job        :determines the average value in every pixel position
01712                  by considering only the pixels along the third axis
01713                  which lie between the given wavelength values.
01714                  These values are first recalculated to plane indices
01715                  by using the given dispersion and minimum wavelength in
01716                  the cube.
01717                  ZERO pixels in a plane are not considered. If all
01718                  pixels at a position are not valid the result will
01719                  be 'ZERO'.
01720  ---------------------------------------------------------------------------*/
01721 cpl_image *
01722 sinfo_new_average_cube_to_image_between_waves (cpl_imagelist * cube,
01723                                            float     dispersion,
01724                                            float     centralWave,
01725                                            float     initialLambda,
01726                                            float     finalLambda)
01727 {
01728     cpl_image  *      im ;
01729     int        firstPlane ;
01730     int        lastPlane ;
01731     int        i, j, nz ;
01732     float      minWave ;
01733     int ilx=0;
01734     int ily=0;
01735     int inp=0;
01736     float* pidata=NULL;
01737     float* podata=NULL;
01738     cpl_image* i_img=NULL;
01739 
01740     if ( cube == NULL )
01741     {
01742         sinfo_msg_error ("null cube") ;
01743         return NULL ;
01744     }
01745     i_img=cpl_imagelist_get(cube,0);
01746     ilx=cpl_image_get_size_x(i_img);
01747     ily=cpl_image_get_size_y(i_img);
01748 
01749     inp=cpl_imagelist_get_size(cube);
01750 
01751     minWave = centralWave - (float) (inp / 2)*dispersion ;
01752 
01753     if ( dispersion <= 0. || minWave <= 0. )
01754     {
01755         sinfo_msg_error ("wrong dispersion or minimum wavelength given") ;
01756         return NULL ;
01757     }
01758 
01759     if ( initialLambda < minWave ||
01760         (initialLambda >= minWave + dispersion * inp) )
01761     {
01762         sinfo_msg_error ("wrong initial wavelength given") ;
01763         return NULL ;
01764     }
01765 
01766     if ( finalLambda <= minWave ||
01767         (finalLambda > minWave + dispersion * inp) )
01768     {
01769         sinfo_msg_error ("wrong final wavelength given") ;
01770         return NULL ;
01771     }
01772 
01773     /* allocate memory */
01774     if (NULL == (im = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT )) )
01775     {
01776         sinfo_msg_error ("cannot allocate new image") ;
01777         return NULL ;
01778     }
01779 
01780     /* transfer the wavelength range to image plane indices */
01781     firstPlane = sinfo_new_nint ((double) ((initialLambda - minWave) /
01782                                           dispersion)) ;
01783     lastPlane  = sinfo_new_nint ((double) ((finalLambda - minWave) /
01784                                           dispersion)) ;
01785 
01786     if ( firstPlane < 0 || firstPlane >= inp ||
01787          lastPlane  < 0 || lastPlane  >  inp )
01788     {
01789         sinfo_msg_error ("wrong values given!") ;
01790         return NULL ;
01791     }
01792 
01793     /*------------------------------------------------------------------------
01794      * transfer each vector in z direction in a buffer and collect only
01795        non-blank data.
01796      */
01797 
01798 
01799 
01800     podata=cpl_image_get_data_float(im);
01801     for ( i = 0 ; i < (int) ilx*ily ; i++ )
01802     {
01803         nz = 0 ;
01804 
01805         for ( j = firstPlane ; j <= lastPlane ; j ++ )
01806         {
01807           i_img=cpl_imagelist_get(cube,j);
01808       pidata=cpl_image_get_data_float(i_img);
01809             if ( !isnan(pidata[i]) )
01810             {
01811                 nz ++ ;
01812                 podata[i] += pidata[i] ;
01813             }
01814         }
01815 
01816         /* proceed depending on the number of valid pixels */
01817         if ( nz >= 1 )
01818         {
01819             podata[i] /= nz ;
01820         }
01821         else if (nz == 0)
01822         {
01823             podata[i] = ZERO ;
01824         }
01825     }
01826 
01827     return im ;
01828 }
01829 
01830 /*---------------------------------------------------------------------------
01831    Function    :    sinfo_new_extract_image_from_cube()
01832    In         :    1 allocated cube
01833                         index of cube plane
01834    Out         :    extracted image
01835    Job        :    returns the wanted image plane of the cube
01836  ---------------------------------------------------------------------------*/
01837 cpl_image *
01838 sinfo_new_extract_image_from_cube(cpl_imagelist * cube, int plane_index)
01839 {
01840     if ( cube == NULL )
01841     {
01842         sinfo_msg_error ("null cube") ;
01843         return NULL ;
01844     }
01845 
01846     if ( plane_index < 0 || plane_index >= cpl_imagelist_get_size(cube) )
01847     {
01848         sinfo_msg_error ("wrong plane index for image to be extracted") ;
01849         return NULL ;
01850     }
01851 
01852     return cpl_imagelist_get(cube,plane_index) ;
01853 }
01854 
01855 /*---------------------------------------------------------------------------
01856    Function    :sinfo_new_extract_spectrum_from_cube()
01857    In         :cube: 1 allocated cube
01858                  x_pos, y_pos: x, y pixel position of the
01859                                spectrum counted from 0
01860    Out         :extracted spectral sinfo_vector object
01861    Job        :returns the wanted single spectrum of the cube
01862  ---------------------------------------------------------------------------*/
01863 Vector *
01864 sinfo_new_extract_spectrum_from_cube(cpl_imagelist * cube,
01865                                      int x_pos, int y_pos)
01866 {
01867     Vector * returnedSpectrum ;
01868     int i ;
01869     int ilx=0;
01870     int ily=0;
01871     int inp=0;
01872     float* pidata=NULL;
01873     cpl_image* i_img=NULL;
01874 
01875     if ( cube == NULL )
01876     {
01877         sinfo_msg_error ("no cube given!") ;
01878         return NullVector ;
01879     }
01880     i_img=cpl_imagelist_get(cube,0);
01881     ilx=cpl_image_get_size_x(i_img);
01882     ily=cpl_image_get_size_y(i_img);
01883     inp=cpl_imagelist_get_size(cube);
01884 
01885     if ( x_pos < 0 || x_pos >= ilx )
01886     {
01887         sinfo_msg_error ("wrong x-positon of spectrum given!") ;
01888         return NullVector ;
01889     }
01890 
01891     if ( y_pos < 0 || y_pos >= ily )
01892     {
01893         sinfo_msg_error ("wrong y-positon of spectrum given!") ;
01894         return NullVector ;
01895     }
01896 
01897     /* allocate memory */
01898     if ( NULL == (returnedSpectrum = sinfo_new_vector ( inp )) )
01899     {
01900         sinfo_msg_error ("cannot allocate new spectrum!") ;
01901         return NullVector ;
01902     }
01903 
01904     for ( i = 0 ; i < inp ; i++ )
01905     {
01906       i_img=cpl_imagelist_get(cube,i);
01907       pidata=cpl_image_get_data_float(i_img);
01908       returnedSpectrum -> data[i] = pidata[x_pos + ilx*y_pos] ;
01909     }
01910 
01911     return returnedSpectrum ;
01912 }
01913 
01914 /*---------------------------------------------------------------------------
01915    Function     :       sinfo_new_combine_jittered_cubes()
01916    In           :       cubes: list of jittered cubes to mosaic
01917                         mergedCube: resulting merged cube containing the
01918                                       jittered cubes
01919                         n_cubes: number of cubes in the list to merge
01920                         cumoffsetx,y: array of relative x, y pixel offsets
01921                                       with respect to the first frame in the
01922                                       same sequence as the cube list.
01923                         exptimes: exposure times array giving the time
01924                                   in the same sequence as the cube list
01925                         kernel_type: the name of the interpolation kernel
01926                                      that you want to generate using the
01927                                      eclipse routine
01928                                      sinfo_generate_interpolation_kernel()
01929                                      Supported kernels are:
01930                                      NULL:      default kernel, currently tanh
01931                                      "default": dito
01932                                      "tanh":    Hyperbolic tangent
01933                                      "sinc2":   Square sinc
01934                                      "lanczos": Lanczos2 kernel
01935                                      "hamming": Hamming kernel
01936                                      "hann":    Hann kernel
01937    Out          :       mask: cube of the same size as combinedCube
01938                               containing 0 for blank (ZERO pixels) and
01939                               the summed integration times for
01940                               overlapping regions
01941                         mergedCube: final data cube containing the
01942                                     jittered cubes
01943    Job          :       merges jittered data cubes to one bigger cube
01944                         by averaging the overlap regions weighted by
01945                         the integration times. The x, y size of the final data
01946                         cube is user given, and should be between 32 and 64
01947                         pixels, while the relative pixel-offset (sub-pixel
01948                         accuracy) of the single cubes with respect to the
01949                         first cube in the list is read from the
01950                         SEQ CUMOFFSETX,Y
01951                         fits header keyword.
01952  ---------------------------------------------------------------------------*/
01953 cpl_imagelist *
01954 sinfo_new_combine_jittered_cubes ( cpl_imagelist ** cubes,
01955                                  cpl_imagelist  * mergedCube,
01956                                  int        n_cubes,
01957                                  float    * cumoffsetx,
01958                                  float    * cumoffsety,
01959                                  float    * exptimes,
01960                                  char     * kernel_type )
01961 {
01962 
01963     int i=0 ;
01964     int x=0;
01965     int y=0;
01966     int z=0;
01967     int llx0=0;
01968     int lly0=0;
01969     int posx=0;
01970     int posy=0;
01971     float weight=0;
01972     cpl_imagelist * mask=NULL;
01973     double * kernel=NULL;
01974     /*cpl_image * shiftedImage ;*/
01975 
01976     int* llx=NULL ;
01977     int* lly=NULL ;
01978 
01979     float* sub_offsetx=NULL ;
01980     float* sub_offsety=NULL ;
01981 
01982     cpl_imagelist ** tmpcubes=NULL ;
01983     pixelvalue * tmpspace=NULL;
01984 
01985 
01986   int ilx=0;
01987   int ily=0;
01988   int olx=0;
01989   int oly=0;
01990   int mlx=0;
01991   int onp=0;
01992   int inp=0;
01993 
01994 
01995 
01996   float* podata=NULL;
01997   float* pmdata=NULL;
01998   float* ptdata=NULL;
01999 
02000   cpl_image* i_img=NULL;
02001   cpl_image* o_img=NULL;
02002   cpl_image* m_img=NULL;
02003   cpl_image* t_img=NULL;
02004 
02005 
02006     if ( cubes == NULL )
02007     {
02008         sinfo_msg_error ("no cube list given!") ;
02009         return NULL ;
02010     }
02011     if ( n_cubes <= 0 )
02012     {
02013         sinfo_msg_error ("wrong number of data cubes in list!") ;
02014         return NULL ;
02015     }
02016     if ( cumoffsetx == NULL || cumoffsety == NULL )
02017     {
02018         sinfo_msg_error ("no cumoffsetx/y given!") ;
02019         return NULL ;
02020     }
02021     if ( exptimes == NULL )
02022     {
02023         sinfo_msg_error ("no exposure time array given!") ;
02024         return NULL ;
02025     }
02026 
02027     o_img=cpl_imagelist_get(mergedCube,0);
02028     olx=cpl_image_get_size_x(o_img);
02029     oly=cpl_image_get_size_y(o_img);
02030     onp=cpl_imagelist_get_size(mergedCube);
02031     if ( NULL == (mask = cpl_imagelist_new()) )
02032     {
02033         sinfo_msg_error ("could not allocate cube!") ;
02034         return NULL ;
02035     }
02036     for(i=0;i<onp;i++){
02037       o_img=cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
02038       cpl_imagelist_set(mergedCube,o_img,i);
02039     }
02040 
02041     i_img=cpl_imagelist_get(cubes[0],0);
02042     ilx=cpl_image_get_size_x(i_img);
02043     ily=cpl_image_get_size_y(i_img);
02044 
02045     inp=cpl_imagelist_get_size(cubes[0]);
02046 
02047     /*--------------------------------------------------------------------
02048      * center the cubes within the allocated big cube
02049      * that means define the (0,0) positions of the cubes in the image planes
02050      * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
02051      */
02052     /* position of first reference frame, centered in big cube */
02053     llx0 = olx/2 - ilx/2 ;
02054     lly0 = oly/2 - ily/2 ;
02055 
02056     /*--------------------------------------------------------------------
02057      * go through the frame list and determine the lower left edge position
02058      * of the shifted cubes. Additionnally, the sub-pixel offsets are
02059      * determined.
02060      */
02061 
02062     llx=cpl_calloc(n_cubes,sizeof(int)); ;
02063     lly=cpl_calloc(n_cubes,sizeof(int)) ;
02064 
02065     sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
02066     sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
02067 
02068     for ( i = 0 ; i < n_cubes ; i++ )
02069     {
02070         llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
02071         sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
02072         lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
02073         sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
02074     }
02075 
02076 
02077     /* -------------------------------------------------------------
02078      * shift the cubes according to the computed sub-pixel offsets
02079      * that means shift the single image planes of each cube
02080      * first determine an interpolation kernel
02081      */
02082     if ( NULL == (kernel = sinfo_generate_interpolation_kernel(kernel_type)))
02083     {
02084         sinfo_msg_warning ("could not generate desired interpolation kernel"
02085                            " or no kernel_typ was given, the default kernel"
02086                            " is used now!") ;
02087     }
02088     /* go through the frame list */
02089 
02090 
02091     tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
02092 
02093     for ( i = 0 ; i < n_cubes ; i++ )
02094     {
02095         tmpspace = cpl_calloc(ilx, ily*sizeof(pixelvalue)) ;
02096         tmpcubes[i] = cpl_imagelist_new();
02097 
02098         for ( z = 0 ; z < inp ; z++ )
02099         {
02100 
02101 
02102             t_img=sinfo_new_shift_image(cpl_imagelist_get(cubes[i],z),
02103                                   sub_offsetx[i], sub_offsety[i], kernel);
02104 
02105         if (t_img==NULL)
02106             {
02107                 sinfo_msg_error ("could not shift image plane no %d"
02108                                  " in cube no %d!", z, i) ;
02109                 cpl_imagelist_delete(mergedCube) ;
02110                 cpl_imagelist_delete(mask) ;
02111                 cpl_free(kernel) ;
02112                 return NULL ;
02113             }
02114             cpl_imagelist_set(tmpcubes[i],t_img,z);
02115         }
02116     cpl_free(tmpspace);
02117     }
02118 
02119     /*-------------------------------------------------------------------------
02120      * Build the mask data cube.
02121      * The mask is 0 where no data is available, otherwise the integration
02122        time of one frame, respectively the summed integration
02123      * times in the overlapping regions are inserted
02124      */
02125     /* go through the frame list */
02126     for ( i = 0 ; i < n_cubes ; i++ )
02127     {
02128 
02129         /* go through the first image plane of the big data cube */
02130         for ( y = 0 ; y < oly ; y++ )
02131         {
02132             for ( x = 0 ; x < olx ; x++ )
02133             {
02134                 /* find the position of the present cube and
02135                    go through the single spectra */
02136                 if ( y >= lly[i] && y < lly[i]+ily &&
02137                      x >= llx[i] && x < llx[i]+ilx )
02138                 {
02139                     posx = x - llx[i] ;
02140                     posy = y - lly[i] ;
02141                     for ( z = 0 ; z < onp ; z++ )
02142                     {
02143               t_img=cpl_imagelist_get(tmpcubes[i],z);
02144                       ptdata=cpl_image_get_data_float(t_img);
02145               m_img=cpl_imagelist_get(mask,z);
02146                       pmdata=cpl_image_get_data_float(m_img);
02147                         if (!isnan(ptdata[posx+posy*ilx]) &&
02148                                          ptdata[posx+posy*ilx] != 0.)
02149                         {
02150                             pmdata[x+y*mlx] += exptimes[i] ;
02151                         }
02152                     }
02153                 }
02154             }
02155         }
02156     }
02157 
02158 
02159 
02160 
02161 
02162 
02163     /* calculate a weighted average using the
02164        exposure time of the single frames
02165        of the overlapping regions of the cubes */
02166     for ( i = 0 ; i < n_cubes ; i++ )
02167     {
02168 
02169         /* go through the first image plane of the big data cube */
02170         for ( y = 0 ; y < oly ; y++ )
02171         {
02172 
02173             for ( x = 0 ; x < olx ; x++ )
02174             {
02175 
02176                 /* find the position of the present cube
02177                    and go through the single spectra */
02178                 if ( y >= lly[i] && y < lly[i]+ily &&
02179                      x >= llx[i] && x < llx[i]+ilx )
02180                 {
02181 
02182                     posx = x - llx[i] ;
02183                     posy = y - lly[i] ;
02184                     for ( z = 0 ; z < onp ; z++ )
02185                     {
02186 
02187               t_img=cpl_imagelist_get(tmpcubes[i],z);
02188                       ptdata=cpl_image_get_data_float(t_img);
02189               m_img=cpl_imagelist_get(mask,z);
02190                       pmdata=cpl_image_get_data_float(m_img);
02191                       mlx=cpl_image_get_size_x(m_img);
02192 
02193               o_img=cpl_imagelist_get(mergedCube,z);
02194                       podata=cpl_image_get_data_float(o_img);
02195                       podata[x+y*olx]=0;
02196                         if (!isnan(ptdata[posx+posy*ilx]))
02197                         {
02198                             if (pmdata[x+y*mlx] != 0.)
02199                             {
02200                 /* adjust the intensities to
02201                                    the first reference cube */
02202                                 weight = exptimes[0] / pmdata[x+y*mlx] ;
02203                             }
02204                             else
02205                             {
02206                                 weight = 0. ;
02207                             }
02208                             podata[x+y*olx] +=
02209                                weight*ptdata[posx+posy*ilx] ;
02210                         }
02211                     }
02212                 }
02213             }
02214         }
02215     }
02216 
02217 
02218 
02219 
02220     /* convert the "free space" in the cube to blank pixels */
02221     /* convert_0_to_ZERO_for_cubes(mergedCube) ; */
02222     cpl_free(kernel) ; /* originated by eclise-malloc */
02223     for( i = 0 ; i < n_cubes ; i++ )
02224     {
02225         cpl_imagelist_delete (tmpcubes[i]) ;
02226     }
02227 
02228     cpl_free(tmpcubes); ;
02229     cpl_free(llx); ;
02230     cpl_free(lly) ;
02231 
02232     cpl_free(sub_offsetx) ;
02233     cpl_free(sub_offsety) ;
02234 
02235     return mask ;
02236 }
02237 
02238 
02239 
02240 
02241 
02242 
02243 
02244 
02274 static int
02275 sinfo_build_mask_cube(const int z_min,
02276                       const int z_max,
02277                       const int olx,
02278                       const int oly,
02279                       const int n_cubes,
02280                       const int* llx,
02281                       const int* lly,
02282               double    * exptimes,
02283                       cpl_imagelist** cubes,
02284                       cpl_imagelist** tmpcubes,
02285                       cpl_imagelist* mask)
02286 {
02287 
02288   int i=0;
02289   int y=0;
02290   int z=0;
02291   int ilx=0;
02292   int ily=0;
02293   cpl_image* i_img=NULL;
02294   cpl_image* t_img=NULL;
02295   int posx=0;
02296   int posy=0;
02297   float* ptdata=NULL;
02298   float* pmdata=NULL;
02299   int m=0;
02300   int x=0;
02301   int mlx=0;
02302   cpl_image* m_img=NULL;
02303 
02304 
02305   for ( z = z_min, m=0 ; z < z_max ; z++, m++ ) {
02306 
02307     // go through the first image plane of the big data cube
02308     for ( y = 0 ; y < oly ; y++ ) {
02309       for ( x = 0 ; x < olx ; x++ ) {
02310     for ( i = 0 ; i < n_cubes ; i++ ) {
02311 
02312           i_img=cpl_imagelist_get(cubes[i],0);
02313           ilx=cpl_image_get_size_x(i_img);
02314           ily=cpl_image_get_size_y(i_img);
02315 
02316 
02317       // find the position of the present cube and go
02318           // through the single spectra */
02319           if ( y >= lly[i] && y < lly[i]+ily &&
02320                x >= llx[i] && x < llx[i]+ilx )
02321         {
02322           posx = x - llx[i] ;
02323           posy = y - lly[i] ;
02324 
02325 
02326               t_img=cpl_imagelist_get(tmpcubes[i],m);
02327               ptdata=cpl_image_get_data_float(t_img);
02328               m_img=cpl_imagelist_get(mask,z);
02329               pmdata=cpl_image_get_data_float(m_img);
02330           mlx=cpl_image_get_size_x(m_img);
02331 
02332               if (!isnan(ptdata[posx+posy*ilx]) &&
02333                          ptdata[posx+posy*ilx] != 0.)
02334         {
02335           pmdata[x+y*mlx] += (float)exptimes[i] ;
02336         } else if (isnan(ptdata[posx+posy*ilx])) {
02337         sinfo_msg_debug("ptdata %d, %d, %d is NAN\t",x,y,z);
02338           } else if (ptdata[posx+posy*ilx] == 0.) {
02339         sinfo_msg_debug("ptdata %d, %d, %d is 0\t",x,y,z);
02340           }
02341 
02342         } else {
02343         sinfo_msg_debug("point %d, %d, %d outside range\n",x,y,z);
02344       }
02345         }
02346       }
02347     }
02348   }
02349   return 0;
02350 
02351 }
02352 
02353 
02354 
02355 
02356 static int
02357 sinfo_build_mask_cube_thomas(const int z_min,
02358                       const int z_max,
02359                       const int olx,
02360                       const int oly,
02361                       const int n_cubes,
02362                       const int* llx,
02363                       const int* lly,
02364               double    * exptimes,
02365                       cpl_imagelist** cubes,
02366                       cpl_imagelist** tmpcubes,
02367                       cpl_imagelist* mask)
02368 {
02369 
02370   int i=0;
02371   int y=0;
02372   int z=0;
02373   int ilx=0;
02374   int ily=0;
02375   int inp=0;
02376   cpl_image* i_img=NULL;
02377   cpl_image* t_img=NULL;
02378   int posx=0;
02379   int posy=0;
02380   float* ptdata=NULL;
02381   float* pmdata=NULL;
02382   int m=0;
02383   int x=0;
02384   int mlx=0;
02385   cpl_image* m_img=NULL;
02386 
02387   for ( i = 0 ; i < n_cubes ; i++ ) {
02388 
02389     i_img=cpl_imagelist_get(cubes[i],0);
02390     ilx=cpl_image_get_size_x(i_img);
02391     ily=cpl_image_get_size_y(i_img);
02392     inp=cpl_imagelist_get_size(cubes[i]);
02393 
02394     //go through the first image plane of the big data cube
02395     for ( y = 0 ; y < oly ; y++ ){
02396       for ( x = 0 ; x < olx ; x++ ){
02397     // find the position of the present cube and go
02398     // through the single spectra
02399         if ( y >= lly[i] && y < lly[i]+ily &&
02400              x >= llx[i] && x < llx[i]+ilx ) {
02401       posx = x - llx[i] ;
02402           posy = y - lly[i] ;
02403 
02404       for ( z = z_min,m=0 ; z < z_max ; z++,m++ ) {
02405         t_img=cpl_imagelist_get(tmpcubes[i],m);
02406             ptdata=cpl_image_get_data_float(t_img);
02407             m_img=cpl_imagelist_get(mask,z);
02408             pmdata=cpl_image_get_data_float(m_img);
02409             mlx=cpl_image_get_size_x(m_img);
02410 
02411             if (!isnan(ptdata[posx+posy*ilx]) &&
02412         ptdata[posx+posy*ilx] != 0.) {
02413           pmdata[x+y*mlx] += (float)exptimes[i]  ;
02414         }
02415       }
02416     }
02417       }
02418     }
02419   }
02420   return 0;
02421 }
02422 
02423 
02424 
02425 
02426 
02477 int
02478 sinfo_new_combine_jittered_cubes_range ( cpl_imagelist ** cubes,
02479                                  cpl_imagelist  * mergedCube,
02480                                  cpl_imagelist  * mask,
02481                                  int        n_cubes,
02482                                  float    * cumoffsetx,
02483                                  float    * cumoffsety,
02484                                  double    * exptimes,
02485                                  char     * kernel_type,
02486                                  const int z_min, const int z_max )
02487 {
02488 
02489   int i;
02490   int llx0, lly0 ;
02491   cpl_imagelist ** tmpcubes=NULL ;
02492   int* llx=NULL ;
02493   int* lly=NULL ;
02494   float* sub_offsetx=NULL ;
02495   float* sub_offsety=NULL ;
02496 
02497   int ilx=0;
02498   int ily=0;
02499   int olx=0;
02500   int oly=0;
02501   int mlx=0;
02502   int mly=0;
02503 
02504   cpl_image* i_img=NULL;
02505   cpl_image* o_img=NULL;
02506 
02507 
02508   if(sinfo_check_input(cubes,n_cubes,cumoffsetx,cumoffsety,exptimes) == -1) {
02509     return -1;
02510   }
02511 
02512     o_img=cpl_imagelist_get(mergedCube,z_min);
02513     olx=cpl_image_get_size_x(o_img);
02514     oly=cpl_image_get_size_y(o_img);
02515     i_img=cpl_imagelist_get(cubes[0],0);
02516     ilx=cpl_image_get_size_x(i_img);
02517     ily=cpl_image_get_size_y(i_img);
02518     mlx=olx;
02519     mly=oly;
02520 
02521 
02522     /*--------------------------------------------------------------------
02523      * center the cubes within the allocated big cube
02524      * that means define the (0,0) positions of the cubes in the image planes
02525      * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
02526      */
02527     /* position of first reference frame, centered in big cube */
02528     llx0 = olx/2 - ilx/2 ;
02529     lly0 = oly/2 - ily/2 ;
02530 
02531     /*--------------------------------------------------------------------
02532      * go through the frame list and determine the lower left edge position
02533      * of the shifted cubes. Additionnally, the sub-pixel offsets are
02534      * determined.
02535      */
02536 
02537 
02538     llx=cpl_calloc(n_cubes,sizeof(int)) ;
02539     lly=cpl_calloc(n_cubes,sizeof(int)) ;
02540     sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
02541     sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
02542 
02543     for ( i = 0 ; i < n_cubes ; i++ )
02544     {
02545         llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
02546         sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
02547         lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
02548         sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
02549     }
02550 
02551     tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
02552     /* -------------------------------------------------------------
02553      * shift the cubes according to the computed sub-pixel offsets
02554      * that means shift the single image planes of each cube
02555      * first determine an interpolation kernel
02556      */
02557     if(sinfo_shift_cubes(tmpcubes,kernel_type,n_cubes,cubes,z_min, z_max,
02558              sub_offsetx,sub_offsety,mlx,mly,mask) == -1) {
02559       return -1;
02560     }
02561 
02562 
02563     /*-----------------------------------------------------------------------
02564      * Build the mask data cube.
02565      * The mask is 0 where no data is available, otherwise the
02566        integration time of
02567      * one frame, respectively the summed integration
02568      * times in the overlapping regions are inserted
02569      */
02570     /* go through the frame list */
02571     sinfo_build_mask_cube(z_min,z_max,olx,oly,n_cubes,llx,lly,exptimes,
02572                           cubes,tmpcubes,mask);
02573 
02574 
02575     /* calculate a weighted average using the exposure time of the
02576        single frames of the overlapping regions of the cubes */
02577 
02578     sinfo_compute_weight_average(z_min,z_max,ilx,ily,n_cubes,mergedCube,mask,
02579                                  tmpcubes,exptimes,llx,lly);
02580 
02581     /* convert the "free space" in the cube to blank pixels */
02582      /* convert_0_to_ZERO_for_cubes(mergedCube) ; */
02583 
02584     for( i = 0 ; i < n_cubes ; i++ )
02585     {
02586         cpl_imagelist_delete (tmpcubes[i]) ;
02587     }
02588 
02589 
02590     cpl_free(tmpcubes) ;
02591     cpl_free(llx) ;
02592     cpl_free(lly) ;
02593     cpl_free(sub_offsetx) ;
02594     cpl_free(sub_offsety) ;
02595 
02596      return 0 ;
02597 }
02598 
02616 static int
02617 sinfo_check_input(cpl_imagelist** cubes,
02618                           const int n_cubes,
02619                           float* cumoffsetx,
02620                           float* cumoffsety,
02621               double* exptimes)
02622 {
02623    if ( cubes == NULL )
02624     {
02625         sinfo_msg_error ("no cube list given!") ;
02626         return -1 ;
02627     }
02628     if ( n_cubes <= 0 )
02629     {
02630         sinfo_msg_error ("wrong number of data cubes in list!") ;
02631         return -1 ;
02632     }
02633     if ( cumoffsetx == NULL || cumoffsety == NULL )
02634     {
02635         sinfo_msg_error ("no cumoffsetx/y given!") ;
02636         return -1;
02637     }
02638     if ( exptimes == NULL )
02639     {
02640         sinfo_msg_error ("no exposure time array given!") ;
02641         return -1 ;
02642     }
02643 
02644     return 0;
02645 }
02646 
02672 static int
02673 sinfo_compute_weight_average(const int z_min,
02674                              const int z_max,
02675                              const int ilx,
02676                              const int ily,
02677                  const int n_cubes,
02678                              cpl_imagelist* mergedCube,
02679                              cpl_imagelist* mask,
02680                              cpl_imagelist** tmpcubes,
02681                  double* exptimes,
02682                              int* llx,
02683                              int* lly)
02684 {
02685 
02686   int m=0;
02687   int x=0;
02688   int y=0;
02689   int z=0;
02690   int i=0;
02691 
02692   int mlx=0;
02693   int mly=0;
02694   int olx=0;
02695   int oly=0;
02696 
02697   cpl_image* o_img=NULL;
02698   cpl_image* m_img=NULL;
02699   cpl_image* t_img=NULL;
02700 
02701   float* podata=NULL;
02702   float* pmdata=NULL;
02703   float* ptdata=NULL;
02704   double weight=0;
02705 
02706   int posx=0;
02707   int posy=0;
02708 
02709 
02710   o_img=cpl_imagelist_get(mergedCube,z_min);
02711   olx=cpl_image_get_size_x(o_img);
02712   oly=cpl_image_get_size_y(o_img);
02713   mlx=olx;
02714   mly=oly;
02715 
02716   /* calculate a weighted average using the exposure time of the
02717      single frames of the overlapping regions of the cubes */
02718   for ( z = z_min, m = 0 ; z < z_max ; z++, m++ ) {
02719     o_img=cpl_imagelist_get(mergedCube,z);
02720     podata=cpl_image_get_data_float(o_img);
02721     m_img=cpl_imagelist_get(mask,z);
02722     pmdata=cpl_image_get_data_float(m_img);
02723     mlx=cpl_image_get_size_x(m_img);
02724 
02725     /* go through the first image plane of the big data cube */
02726     for ( y = 0 ; y < oly ; y++ ) {
02727       for ( x = 0 ; x < olx ; x++ ) {
02728 
02729        /* find the position of the present cube and
02730           go through the single spectra */
02731 
02732     for ( i = 0 ; i < n_cubes ; i++ ) {
02733 
02734           if ( y >= lly[i] && y < lly[i]+ily &&
02735                x >= llx[i] && x < llx[i]+ilx ) {
02736         posx = x - llx[i] ;
02737             posy = y - lly[i] ;
02738 
02739             t_img=cpl_imagelist_get(tmpcubes[i],m);
02740             ptdata=cpl_image_get_data_float(t_img);
02741             /* To prevent black regions in peculiar batterfly cases
02742               podata[x+y*olx]=0;
02743             */
02744         if (!isnan(ptdata[posx+posy*ilx])) {
02745           if (pmdata[x+y*mlx] != 0.) {
02746                 /* adjust the intensities to the
02747                    first reference cube */
02748         weight = exptimes[0] / pmdata[x+y*mlx] ;
02749           } else {
02750         weight = 0. ;
02751           }
02752               podata[x+y*olx] += weight*ptdata[posx+posy*ilx] ;
02753 
02754         }
02755       }
02756     }
02757       }
02758     }
02759   }
02760   return 0;
02761 }
02762 
02763 
02803 static int
02804 sinfo_shift_cubes(cpl_imagelist** tmpcubes,
02805                   char* kernel_type,
02806                   const int n_cubes,
02807                   cpl_imagelist** cubes,
02808                   const int z_min,
02809                   const int z_max,
02810                   float* sub_offsetx,
02811                   float* sub_offsety,
02812                   const int mlx,
02813                   const int mly,
02814                   cpl_imagelist* mask)
02815 {
02816 
02817    double * kernel ;
02818    int i=0;
02819    cpl_image* i_img=NULL;
02820    int ilx=0;
02821    int ily=0;
02822    int inp=0;
02823    pixelvalue * tmpspace;
02824    int z=0;
02825    cpl_image* t_img=NULL;
02826    cpl_image* m_img=NULL;
02827    int m=0;
02828 
02829     /* -------------------------------------------------------------
02830      * shift the cubes according to the computed sub-pixel offsets
02831      * that means shift the single image planes of each cube
02832      * first determine an interpolation kernel
02833      */
02834 
02835    if ( NULL == (kernel = sinfo_generate_interpolation_kernel(kernel_type)) )
02836     {
02837         sinfo_msg_warning ("could not generate desired interpolation kernel"
02838                            "or no kernel_typ was given, the default kernel"
02839                            "is used now!") ;
02840     }
02841     /* go through the frame list */
02842 
02843     for ( i = 0 ; i < n_cubes ; i++ )
02844     {
02845 
02846       i_img=cpl_imagelist_get(cubes[i],0);
02847       ilx=cpl_image_get_size_x(i_img);
02848       ily=cpl_image_get_size_y(i_img);
02849       inp=cpl_imagelist_get_size(cubes[i]);
02850       tmpspace = cpl_calloc(ilx, ily*sizeof(pixelvalue)) ;
02851       tmpcubes[i]=cpl_imagelist_new();
02852 
02853         for ( z = z_min, m=0 ; z < z_max ; z++, m++ )
02854         {
02855               t_img=sinfo_new_shift_image(cpl_imagelist_get(cubes[i],z),
02856                                           sub_offsetx[i],
02857                                           sub_offsety[i],
02858                                           kernel);
02859 
02860         if (t_img==NULL)
02861             {
02862                 sinfo_msg_error("could not shift image plane no %d "
02863                                 "in cube no %d!", z, i) ;
02864                 cpl_free(kernel) ;
02865                 return -1 ;
02866             }
02867 
02868             cpl_imagelist_set(tmpcubes[i],t_img,m);
02869             m_img=cpl_image_new(mlx,mly,CPL_TYPE_FLOAT);
02870             cpl_imagelist_set(mask,m_img,z);
02871         }
02872 
02873      cpl_free(tmpspace);
02874 
02875     }
02876     if(kernel != NULL) cpl_free(kernel) ;
02877 
02878     return 0;
02879 
02880 }
02881 
02882 
02883 /* Temporally commented out as not yet used
02884 static int
02885 sinfo_ks_clip(
02886           const int n_cubes,
02887               const int nc,
02888           const int ilx,
02889           const int ily,
02890           const double kappa,
02891           int* llx,
02892           int* lly,
02893           double* exptimes,
02894           cpl_imagelist** tmpcubes,
02895               float* podata,
02896               float* pmdata,
02897           const int x,
02898           const int y,
02899           const int m,
02900           const int mlx,
02901           const int olx
02902   )
02903 {
02904 
02905 
02906   int posx=0;
02907   int posy=0;
02908   int i=0;
02909   int nclip=0;
02910   int ks=0;
02911 
02912   float sig=0;
02913   float med=0;
02914   float ovr=0;
02915   float avg=0;
02916 
02917   float* ptdata=NULL;
02918   float* pvdata=NULL;
02919 
02920   cpl_image* t_img=NULL;
02921   float  msk_sum=0;
02922   float  val_msk_sum=0;
02923   cpl_image* v_img=NULL;
02924 
02925   cpl_vector* val=NULL;
02926   cpl_vector* msk=NULL;
02927 
02928   msk=cpl_vector_new(n_cubes);
02929   for (i=0;i<n_cubes;i++) {
02930     cpl_vector_set(msk,i,1);
02931   }
02932 
02933   // k-s clipping
02934   nclip=0;
02935 
02936   for (ks=0;ks<nc;ks++) {
02937 
02938     sig=0;
02939     med=0;
02940     ovr=0;
02941     if(nc-nclip >0) {
02942       val=cpl_vector_new(nc-nclip);
02943     }
02944 
02945     // fill val
02946     for ( i = 0 ; i < n_cubes ; i++ ) {
02947       t_img=cpl_imagelist_get(tmpcubes[i],m);
02948       ptdata=cpl_image_get_data_float(t_img);
02949       if ( y >= lly[i] && y < lly[i]+ily &&
02950        x >= llx[i] && x < llx[i]+ilx ) {
02951     posx = x - llx[i] ;
02952     posy = y - lly[i] ;
02953     if (!isnan(ptdata[posx+posy*ilx]) &&
02954         ptdata[posx+posy*ilx] != 0. &&
02955         (cpl_vector_get(msk,i) != 0)) {
02956       cpl_vector_set(val,ovr,(double)ptdata[posx+posy*ilx]);
02957       ovr++;
02958     }
02959       }
02960     }
02961 
02962     // get avg, med, sig
02963     if(ovr>0) {
02964       avg=cpl_vector_get_mean(val);
02965       med=cpl_vector_get_median_const(val);
02966       if(ovr>1) {
02967     sig=cpl_vector_get_stdev(val);
02968       } else {
02969     sig=0;
02970       }
02971       cpl_vector_delete(val);
02972     }
02973 
02974     for ( i = 0 ; i < n_cubes ; i++ ) {
02975       t_img=cpl_imagelist_get(tmpcubes[i],m);
02976       ptdata=cpl_image_get_data_float(t_img);
02977       // Do k-s clipping at each pixel
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     //sinfo_msg_warning("llx[%d]=%d lly[%d],=%d",i,llx[i],i,lly[i]);
02983     //sinfo_msg_warning("posx=%d posy=%d",posx,posy);
02984     if (!isnan(ptdata[posx+posy*ilx]) &&
02985         ptdata[posx+posy*ilx] != 0. &&
02986         (cpl_vector_get(msk,i) != 0)) {
02987       if(abs((ptdata[posx+posy*ilx]-med))> kappa*sig) {
02988         ptdata[posx+posy*ilx]=0;
02989 
02990         pmdata[x+y*mlx] -= exptimes[i]  ;
02991 
02992         cpl_vector_set(msk,i,0);
02993         nclip++;
02994       }
02995     }
02996       }
02997 
02998     }
02999   }
03000 
03001   msk_sum=0;
03002   val_msk_sum=0;
03003   for ( i = 0 ; i < n_cubes ; i++ ) {
03004     v_img=cpl_imagelist_get(tmpcubes[i],m);
03005     pvdata=cpl_image_get_data_float(v_img);
03006     // computes sky at each point
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       if (!isnan(pvdata[posx+posy*ilx]) &&
03012       pvdata[posx+posy*ilx] != 0. &&
03013       (cpl_vector_get(msk,i) != 0)) {
03014 
03015     msk_sum+= pmdata[x+y*mlx];
03016 
03017     val_msk_sum+=pvdata[posx+posy*ilx]*
03018       pmdata[x+y*mlx];
03019 
03020       }
03021     }
03022   }
03023 
03024   podata[x+y*olx]=val_msk_sum/msk_sum;
03025   cpl_vector_delete(msk);
03026 
03027   return 0;
03028 
03029 }
03030 
03031 */
03032 
03082 int
03083 sinfo_new_combine_jittered_cubes_thomas_range(cpl_imagelist ** cubes,
03084                     cpl_imagelist  * mergedCube,
03085                     cpl_imagelist  * mask,
03086                     int        n_cubes,
03087                     float    * cumoffsetx,
03088                     float    * cumoffsety,
03089                     double    * exptimes,
03090                     char     * kernel_type,
03091                     const int z_min,
03092                     const int z_max,
03093                                     const double kappa )
03094 {
03095     const int VERY_BIG_INT = 268431360;
03096   int i ;
03097   int llx0, lly0 ;
03098   int* llx=NULL;
03099   int* lly=NULL ;
03100   float* sub_offsetx=NULL ;
03101   float* sub_offsety=NULL ;
03102   cpl_imagelist ** tmpcubes=NULL ;
03103   const int z_siz=z_max-z_min;
03104   int ilx=0;
03105   int ily=0;
03106   int olx=0;
03107   int oly=0;
03108   int mlx=0;
03109   int mly=0;
03110   int onp=0;
03111   cpl_image* i_img=NULL;
03112   cpl_image* o_img=NULL;
03113   int min_lx = VERY_BIG_INT;
03114   int min_ly = VERY_BIG_INT;
03115 
03116 
03117   if(sinfo_check_input(cubes,n_cubes,cumoffsetx,cumoffsety,exptimes) == -1) {
03118     return -1;
03119   }
03120 
03121   if (z_siz <= 0 ){
03122     sinfo_msg_error ("z_max <= z_min given!") ;
03123     return -1 ;
03124   }
03125 
03126   i_img=cpl_imagelist_get(cubes[0],0);
03127   o_img=cpl_imagelist_get(mergedCube,0);
03128   ilx=cpl_image_get_size_x(i_img);
03129   ily=cpl_image_get_size_y(i_img);
03130   olx=cpl_image_get_size_x(o_img);
03131   oly=cpl_image_get_size_y(o_img);
03132   mlx=olx;
03133   mly=oly;
03134 //  sinfo_msg_warning(" cube size [%d:%d] merged cube size[%d:%d]" , ilx, ily, olx, oly);
03135   /*--------------------------------------------------------------------
03136    * center the cubes within the allocated big cube
03137    * that means define the (0,0) positions of the cubes in the image planes
03138    * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
03139    */
03140   /* position of first reference frame, centered in big cube */
03141   llx0 = (1.0 * olx- 1.0 * ilx)/2.0 ;
03142   lly0 = (1.0 * oly - 1.0 * ily)/2.0 ;
03143 //  sinfo_msg_warning(" zero point [%d:%d]" , llx0, lly0);
03144   /*--------------------------------------------------------------------
03145    * go through the frame list and determine the lower left edge position
03146    * of the shifted cubes. Additionnally, the sub-pixel offsets are
03147    * determined.
03148    */
03149 
03150   llx=cpl_calloc(n_cubes,sizeof(int));
03151   lly=cpl_calloc(n_cubes,sizeof(int)) ;
03152   sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
03153   sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
03154 
03155   for ( i = 0 ; i < n_cubes ; i++ ) {
03156     llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
03157 
03158     sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
03159     lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
03160     sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
03161 /*    sinfo_msg_warning("suboff[%d]= %f %f  ll[%d:%d] cumoffset[%f:%f]" ,
03162             i,sub_offsetx[i],sub_offsety[i], llx[i], lly[i],
03163             cumoffsetx[i], cumoffsety[i]);*/
03164     if (llx[i] < min_lx)
03165     {
03166         min_lx = llx[i];
03167     }
03168     if (lly[i] < min_ly)
03169     {
03170         min_ly = lly[i];
03171     }
03172   }
03173   /***********---------
03174    * "normalize" the shift - minimum should be 0
03175    **********************************************/
03176   if (min_lx != 0)
03177   {
03178     for (i = 0 ; i < n_cubes ; i++ )
03179     {
03180         llx[i] = llx[i] - min_lx;
03181     }
03182   }
03183   if (min_ly != 0)
03184   {
03185     for (i = 0 ; i < n_cubes ; i++ )
03186     {
03187         lly[i] = lly[i] - min_ly;
03188     }
03189   }
03190 
03191   /* -------------------------------------------------------------
03192    * shift the cubes according to the computed sub-pixel offsets
03193    * that means shift the single image planes of each cube
03194    * first determine an interpolation kernel
03195    */
03196 
03197   tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
03198 
03199   if(sinfo_shift_cubes(tmpcubes,kernel_type,n_cubes,cubes,z_min, z_max,
03200                sub_offsetx,sub_offsety,mlx,mly,mask) == -1) {
03201     return -1;
03202 
03203   }
03204 
03205 
03206   /*-------------------------------------------------------------------------
03207    * Build the mask data cube.
03208    * The mask is 0 where no data is available, otherwise the integration
03209    * time of one frame, respectively the summed integration
03210    * times in the overlapping regions are inserted
03211    */
03212   /* go through the frame list */
03213 
03214 
03215   o_img=cpl_imagelist_get(mergedCube,0);
03216   olx=cpl_image_get_size_x(o_img);
03217   oly=cpl_image_get_size_y(o_img);
03218   onp=cpl_imagelist_get_size(mergedCube);
03219 
03220   if(-1 == sinfo_build_mask_cube_thomas(z_min,z_max,olx,oly,n_cubes,llx,lly,
03221                     exptimes,cubes,tmpcubes,mask) ) {
03222     return -1;
03223   }
03225   check_nomsg(sinfo_coadd_with_ks_clip_optimized(z_min,z_max,n_cubes,
03226                                            kappa,llx,lly,
03227                                            exptimes,mask,mergedCube,tmpcubes));
03230 //    sinfo_coadd_with_ks_clip(z_min,z_max,ilx,ily,n_cubes,kappa,llx,lly,
03231 //                 exptimes,mask,mergedCube,tmpcubes);
03233   /* convert the "free space" in the cube to blank pixels */
03234   /* convert_0_to_ZERO_for_cubes(mergedCube) ; */
03235   /* convert_0_to_ZERO_for_cubes(mergedSky) ; */
03236   //cpl_free(kernel) ; /* originated by eclise-malloc */
03237   cleanup:
03238 
03239   for( i = 0 ; i < n_cubes ; i++ ) {
03240     cpl_imagelist_delete (tmpcubes[i]) ;
03241   }
03242 
03243   cpl_free(tmpcubes);
03244   cpl_free(llx);
03245   cpl_free(lly) ;
03246   cpl_free(sub_offsetx) ;
03247   cpl_free(sub_offsety) ;
03248   sinfo_print_rec_status(0);
03249 
03250   return 0 ;
03251 }
03252 
03266 cpl_imagelist *
03267 sinfo_new_interpol_cube_simple( cpl_imagelist * cube,
03268                       cpl_imagelist * badcube,
03269                       int       maxdist )
03270 {
03271   cpl_imagelist * intercube ;
03272   float*     goodNeighbors=NULL ;
03273   int z, row, col ;
03274   int nx, ny, nz ;
03275   int llx, lly, llz ;
03276   int zi, coli, rowi ;
03277   int n ;
03278 
03279 
03280 
03281 
03282   int clx=0;
03283   int cly=0;
03284   int blx=0;
03285   int bly=0;
03286 
03287   int cnp=0;
03288 
03289 
03290   float* pbdata=NULL;
03291   float* pidata=NULL;
03292   float* pbzidata=NULL;
03293   float* pczidata=NULL;
03294 
03295   cpl_image* c_img=NULL;
03296   cpl_image* b_img=NULL;
03297   cpl_image* i_img=NULL;
03298 
03299   cpl_image* bzi_img=NULL;
03300   cpl_image* czi_img=NULL;
03301 
03302 
03303 
03304     if ( cube == NULL || badcube == NULL )
03305     {
03306         sinfo_msg_error("no cube given!") ;
03307         return NULL ;
03308     }
03309     if ( maxdist < 1 )
03310     {
03311         sinfo_msg_error("wrong maxrad given!") ;
03312         return NULL ;
03313     }
03314     intercube = cpl_imagelist_duplicate(cube) ;
03315 
03316     goodNeighbors=cpl_calloc((2*maxdist+1)*(2*maxdist+1)*(2*maxdist+1) -1,
03317                              sizeof(float)) ;
03318 
03319     cnp=cpl_imagelist_get_size(cube);
03320     for ( z = 0 ; z < cnp ; z++ )
03321     {
03322       b_img=cpl_imagelist_get(badcube,z);
03323       i_img=cpl_imagelist_get(intercube,z);
03324       pbdata=cpl_image_get_data_float(b_img);
03325       pidata=cpl_image_get_data_float(i_img);
03326       blx=cpl_image_get_size_x(b_img);
03327       bly=cpl_image_get_size_y(b_img);
03328 
03329       c_img=cpl_imagelist_get(cube,z);
03330       clx=cpl_image_get_size_x(c_img);
03331       cly=cpl_image_get_size_y(c_img);
03332 
03333         for ( row = 0 ; row < cly ; row++ )
03334         {
03335             for ( col = 0 ; col < clx ; col++ )
03336             {
03337                 if ( pbdata[col+row*clx] == 0 )
03338                 {
03339                     /* determine the lower left sinfo_edge of the cube */
03340                     llx = col - maxdist ;
03341                     nx = 2*maxdist +1 ;
03342                     if (llx < 0)
03343                     {
03344                        nx += llx ;
03345                        llx = 0 ;
03346                     }
03347                     if ( llx + nx > clx )
03348                     {
03349                         nx -= (llx + nx - clx) ;
03350                     }
03351 
03352                     lly = row - maxdist ;
03353                     ny = 2*maxdist +1 ;
03354                     if (lly < 0)
03355                     {
03356                        ny += lly ;
03357                        lly = 0 ;
03358                     }
03359                     if ( lly + ny > cly )
03360                     {
03361                         ny -= (lly + ny - cly) ;
03362                     }
03363 
03364                     llz = z - maxdist ;
03365                     nz = 2*maxdist +1 ;
03366                     if (llz < 0)
03367                     {
03368                        nz += llz ;
03369                        llz = 0 ;
03370                     }
03371                     if ( llz + nz > cnp )
03372                     {
03373                         nz -= (llz + nz - cnp) ;
03374                     }
03375                     n = 0 ;
03376                     for ( zi = llz ; zi < llz+nz ; zi++ )
03377                     {
03378               bzi_img=cpl_imagelist_get(badcube,zi);
03379               czi_img=cpl_imagelist_get(cube,zi);
03380                       pbzidata=cpl_image_get_data_float(bzi_img);
03381                       pczidata=cpl_image_get_data_float(czi_img);
03382 
03383                         for ( rowi = lly ; rowi < lly+ny ; rowi++ )
03384                         {
03385                             for ( coli = llx ; coli < llx+nx ; coli++ )
03386                             {
03387                                 if ( pbzidata[coli+rowi*blx] == 1 )
03388                                 {
03389                   goodNeighbors[n] = pczidata[coli+rowi*clx] ;
03390                   n++ ;
03391                                 }
03392                             }
03393                         }
03394                     }
03395                     if ( n > 0 )
03396                     {
03397                         pidata[col+row*clx]=sinfo_new_median(goodNeighbors,n);
03398                         pbdata[col+row*clx]=1 ;
03399                     }
03400                     else
03401                     {
03402                         continue ;
03403                     }
03404                 }
03405             }
03406         }
03407     }
03408     cpl_free(goodNeighbors) ;
03409     return intercube ;
03410 }
03411 
03412 
03413 
03414 
03415 
03468 cpl_imagelist *
03469 sinfo_new_combine_cubes ( cpl_imagelist ** cubes,
03470                          cpl_imagelist  * mergedCube,
03471                          int        n_cubes,
03472                          float    * cumoffsetx,
03473                          float    * cumoffsety,
03474                          float      factor,
03475                          char     * kernel_type )
03476 {
03477   int i=0 ;
03478   int x=0;
03479   int y=0;
03480   int z=0;
03481   int llx0=0;
03482   int lly0=0;
03483   int posx=0;
03484   int posy=0;
03485   cpl_imagelist * mask=NULL ;
03486   double * kernel=NULL ;
03487   cpl_image * shiftedImage=NULL ;
03488   int n=0;
03489   int ns=0;
03490   double sum=0;
03491   double sum2=0;
03492   double mean=0;
03493   double sigma=0;
03494 
03495   cpl_imagelist ** tmpcubes=NULL ;
03496 
03497   int* llx=NULL ;
03498   int* lly=NULL ;
03499 
03500   float* sub_offsetx=NULL ;
03501   float* sub_offsety=NULL ;
03502   float* cubedata=NULL ;
03503 
03504   int mlx=0;
03505   int mly=0;
03506   int clx=0;
03507   int cly=0;
03508   int mnp=0;
03509   int cnp=0;
03510 
03511 
03512   float* ptdata=NULL;
03513   float* podata=NULL;
03514   float* pmdata=NULL;
03515 
03516   cpl_image* tmp_img=NULL;
03517   cpl_image* o_img=NULL;
03518   cpl_image* m_img=NULL;
03519   cpl_image* c_img=NULL;
03520   cpl_image* t_img=NULL;
03521 
03522 
03523 
03524 
03525   if ( cubes == NULL )
03526     {
03527         sinfo_msg_error ("no cube list given!") ;
03528         return NULL ;
03529     }
03530 
03531 
03532   if ( mergedCube == NULL )
03533     {
03534         sinfo_msg_error ("no out cube  given!") ;
03535         return NULL ;
03536     }
03537 
03538 
03539     if ( n_cubes <= 0 )
03540     {
03541         sinfo_msg_error ("wrong number of data cubes in list!") ;
03542         return NULL ;
03543     }
03544     if ( cumoffsetx == NULL || cumoffsety == NULL )
03545     {
03546         sinfo_msg_error ("no cumoffsetx/y given!") ;
03547         return NULL;
03548     }
03549 
03550   if ( factor <= 0. )
03551     {
03552         sinfo_msg_error ("wrong factor given!") ;
03553         return NULL ;
03554     }
03555 
03556   m_img=cpl_imagelist_get(mergedCube,0);
03557   mlx=cpl_image_get_size_x(m_img);
03558   mly=cpl_image_get_size_y(m_img);
03559   cnp=cpl_imagelist_get_size(cubes[0]);
03560   c_img=cpl_imagelist_get(cubes[0],0);
03561   clx=cpl_image_get_size_x(c_img);
03562   cly=cpl_image_get_size_y(c_img);
03563 
03564 
03565   tmpcubes=(cpl_imagelist**)cpl_calloc(n_cubes,sizeof(cpl_imagelist*)) ;
03566 
03567         /* allocation for a cube structure without the image planes  */
03568     /*
03569    for ( i = 0 ; i < n_cubes ; i++ )
03570     {
03571          tmpcubes[i] = (cpl_imagelist*)cpl_malloc(sizeof(cpl_imagelist)) ;
03572         tmpcubes[i]->plane = (cpl_image**)cpl_calloc(cubes[0]->np ,
03573                               sizeof(cpl_image*)) ;
03574 
03575         tmpcubes[i]->lx = cubes[0]->lx ;
03576         tmpcubes[i]->ly = cubes[0]->ly ;
03577         tmpcubes[i]->np = cubes[0]->np ;
03578         tmpcubes[i]->nbpix = (ulong32)cubes[0]->lx *
03579                              (ulong32)cubes[0]->ly *
03580                              (ulong32)cubes[0]->np ;
03581         tmpcubes[i]->history = (char*)NULL ;
03582         tmpcubes[i]->n_comments = 0 ;
03583         tmpcubes[i]->orig_ptype = BPP_DEFAULT ;
03584         tmpcubes[i]->filename = NULL ;
03585     }
03586     */
03587     tmpcubes[0]=cpl_imagelist_duplicate(cubes[0]);
03588 
03589     /*--------------------------------------------------------------------
03590      * center the cubes within the allocated big cube
03591      * that means define the (0,0) positions of the cubes in the image planes
03592      * to sub-pixel accuracy by using cumoffsetx,y and the reference cube
03593      */
03594     /* position of first reference frame, centered in big cube */
03595     llx0 = mlx/2 - clx/2 ;
03596     lly0 = mly/2 - cly/2 ;
03597 
03598     /*--------------------------------------------------------------------
03599      * go through the frame list and determine the lower left edge position
03600      * of the shifted cubes. Additionnally, the sub-pixel offsets are
03601      * determined.
03602      */
03603 
03604 
03605     llx=cpl_calloc(n_cubes,sizeof(int)) ;
03606     lly=cpl_calloc(n_cubes,sizeof(int)) ;
03607     sub_offsetx=cpl_calloc(n_cubes,sizeof(float)) ;
03608     sub_offsety=cpl_calloc(n_cubes,sizeof(float)) ;
03609 
03610     for ( i = 0 ; i < n_cubes ; i++ )
03611     {
03612         llx[i] = llx0 - sinfo_new_nint(cumoffsetx[i]) ;
03613         sub_offsetx[i] = (float)sinfo_new_nint(cumoffsetx[i]) - cumoffsetx[i] ;
03614         lly[i] = lly0 - sinfo_new_nint(cumoffsety[i]) ;
03615         sub_offsety[i] = (float)sinfo_new_nint(cumoffsety[i]) - cumoffsety[i] ;
03616     }
03617 
03618     /* -------------------------------------------------------------
03619      * shift the cubes according to the computed sub-pixel offsets
03620      * that means shift the single image planes of each cube
03621      * first determine an interpolation kernel
03622      */
03623     if ( NULL == (kernel = sinfo_generate_interpolation_kernel(kernel_type)) )
03624     {
03625         sinfo_msg_warning ("could not generate desired interpolation kernel"
03626                            " or no kernel_typ was given, the default kernel"
03627                            " is used now!") ;
03628     }
03629     /* go through the frame list */
03630     for ( i = 0 ; i < n_cubes ; i++ )
03631     {
03632       /* go through the image planes and shift each plane by a
03633          sub-pixel value */
03634       for ( z = 0 ; z < cnp ; z++ )
03635         {
03636       tmp_img=cpl_imagelist_get(cubes[i],z);
03637       if ( NULL == (shiftedImage = sinfo_new_shift_image(tmp_img,
03638                                sub_offsetx[i],
03639                                sub_offsety[i],
03640                                kernel ) ) )
03641             {
03642           sinfo_msg_error ("could not shift image plane no %d "
03643                                "in cube no %d!", z, i) ;
03644           cpl_imagelist_delete(mergedCube) ;
03645           cpl_imagelist_delete(mask) ;
03646           cpl_free(kernel) ;
03647           return NULL ;
03648             }
03649       cpl_imagelist_set(tmpcubes[i],shiftedImage,z);
03650         }
03651     }
03652 
03653     cubedata=cpl_calloc(n_cubes,sizeof(float)) ;
03654 
03655     for ( y = 0 ; y < mly ; y++ )
03656     {
03657         for ( x = 0 ; x < mlx ; x++ )
03658         {
03659             for ( z = 0 ; z < mnp ; z++ )
03660             {
03661                 sum = 0. ;
03662                 sum2 = 0. ;
03663                 n = 0 ;
03664                 for ( i = 0 ; i < n_cubes ; i++ )
03665                 {
03666           c_img=cpl_imagelist_get(cubes[i],z);
03667 
03668           clx=cpl_image_get_size_x(c_img);
03669           cly=cpl_image_get_size_y(c_img);
03670 
03671           t_img=cpl_imagelist_get(tmpcubes[i],z);
03672                   ptdata=cpl_image_get_data_float(t_img);
03673 
03674           m_img=cpl_imagelist_get(mergedCube,z);
03675                   pmdata=cpl_image_get_data_float(m_img);
03676           o_img=cpl_imagelist_get(mask,z);
03677                   podata=cpl_image_get_data_float(o_img);
03678                   /*
03679                     find the position of the present cube and go
03680                     through the single spectra
03681                    */
03682                     if ( y >= lly[i] && y < lly[i]+cly &&
03683                          x >= llx[i] && x < llx[i]+clx )
03684                     {
03685                         posx = x - llx[i] ;
03686                         posy = y - lly[i] ;
03687                         if (!isnan(ptdata[posx+posy*clx]))
03688                         {
03689                             sum += ptdata[posx+posy*clx] ;
03690                             sum2 += (ptdata[posx+posy*clx] *
03691                                      ptdata[posx+posy*clx]) ;
03692                             cubedata[n] = ptdata[posx+posy*clx] ;
03693                             n++ ;
03694                         }
03695                     }
03696                 }
03697 
03698                 if ( n == 0 )
03699                 {
03700                     mean = 0. ;
03701                     sigma = 0. ;
03702                     pmdata[x+y*mlx] = 0. ;
03703                     podata[x+y*mlx] = 0 ;
03704                 }
03705                 else if ( n == 1 )
03706                 {
03707                     mean = sum ;
03708                     sigma = 0. ;
03709                     pmdata[x+y*mlx] = mean ;
03710                     podata[x+y*mlx] = 1 ;
03711                 }
03712                 else
03713                 {
03714                     mean = sum/(double)n ;
03715                     sigma = sqrt( (sum2 - sum*mean) / (double)(n - 1) ) ;
03716                     ns = 0 ;
03717                     for ( i = 0 ; i < n ; i++ )
03718                     {
03719                         if ( cubedata[i] > mean+factor*sigma ||
03720                              cubedata[i] < mean-factor*sigma )
03721                         {
03722                             continue ;
03723                         }
03724                         else
03725                         {
03726                             pmdata[x+y*mlx] += cubedata[i] ;
03727                             ns++ ;
03728                         }
03729                     }
03730                     if ( ns == 0 )
03731                     {
03732                         pmdata[x+y*mlx] = 0. ;
03733                     }
03734                     else
03735                     {
03736                         pmdata[x+y*mlx] /= (float)ns ;
03737                     }
03738                     podata[x+y*mlx] = (float)ns ;
03739                 }
03740             }
03741         }
03742     }
03743 
03744     for( i = 0 ; i < n_cubes ; i++ )
03745     {
03746         cpl_imagelist_delete (tmpcubes[i]) ;
03747     }
03748     cpl_free(tmpcubes);
03749     cpl_free(llx);
03750     cpl_free(lly);
03751     cpl_free(sub_offsetx);
03752     cpl_free(sub_offsety);
03753     cpl_free(cubedata);
03754 
03755     /* convert the "free space" in the cube to blank pixels */
03756     sinfo_new_convert_0_to_ZERO_for_cubes(mergedCube) ;
03757     cpl_free(kernel) ;
03758     return mask ;
03759 }
03760 
03761 cpl_imagelist *
03762 sinfo_new_bin_cube(cpl_imagelist *cu,
03763                              int xscale,
03764                              int yscale,
03765                              int xmin,
03766                              int xmax,
03767                              int ymin,
03768                              int ymax)
03769 {
03770   int i,j,k;
03771   cpl_imagelist * cube;
03772   int ilx=0;
03773   int ily=0;
03774   int olx=0;
03775   int oly=0;
03776   int inp=0;
03777 
03778   float* pidata=NULL;
03779   float* podata=NULL;
03780   cpl_image* i_img=NULL;
03781   cpl_image* o_img=NULL;
03782 
03783 
03784   /* old code
03785   if (NULL == (cube = sinfo_newCube (xmax-xmin+1,ymax-ymin+1, cu->np)) )
03786   {
03787       sinfo_msg_error ("cannot allocate new cube") ;
03788       return NULL ;
03789   }
03790   */
03791   inp=cpl_imagelist_get_size(cu);
03792   i_img=cpl_imagelist_get(cu,0);
03793   ilx=cpl_image_get_size_x(i_img);
03794   ily=cpl_image_get_size_y(i_img);
03795   olx=xmax-xmin+1;
03796   oly=ymax-ymin+1;
03797 
03798 
03799   cube=cpl_imagelist_new();
03800   for ( i = 0 ; i < inp ; i++ ) {
03801     o_img = cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
03802     cpl_imagelist_set(cube,o_img,i);
03803   }
03804 
03805 
03806   for (i=0;i<inp;i++){
03807       i_img=cpl_imagelist_get(cu,i);
03808       pidata=cpl_image_get_data_float(i_img);
03809       o_img=cpl_imagelist_get(cube,i);
03810       podata=cpl_image_get_data_float(o_img);
03811       for (j=0 ; j < olx ; j++) {
03812           for (k=0 ; k< oly ; k++) {
03813           podata[j+k*olx]=pidata[((int) (j+xmin)/xscale)+
03814                                      ((int) (k+ymin)/yscale)*ilx]/
03815                                        (xscale*yscale);
03816       }
03817       }
03818   }
03819 
03820   return cube;
03821 }
03822 
03823 
03824 cpl_imagelist *
03825 sinfo_new_scale_cube(cpl_imagelist *cu,
03826                                float xscale,
03827                                float yscale,
03828                                char * kernel_type)
03829 {
03830     cpl_imagelist    *    cube ;
03831     int             i, j, k, l ;
03832     int             lx_out, ly_out ;
03833     double           cur ;
03834     double      *    invert_transform ;
03835     double           neighbors[16] ;
03836     double           rsc[8],
03837                     sumrs ;
03838     double        param[6];
03839     double           x, y ;
03840     int             px, py ;
03841     int             pos ;
03842     int             tabx, taby ;
03843     double      *    kernel ;
03844     int                  leaps[16] ;
03845     int                 ilx=0;
03846     int                 ily=0;
03847     int                 tlx=0;
03848     int                 tly=0;
03849     int                 inp;
03850     float*              podata=0;
03851     cpl_image*          in_img=NULL;
03852     cpl_image*          ou_img=NULL;
03853 
03854 
03855     if (cu == NULL)
03856     {
03857         sinfo_msg_error ("null cube") ;
03858         return NULL ;
03859     }
03860 
03861     param[0]=xscale;
03862     param[1]=0;
03863     param[2]=0;
03864     param[3]=0;
03865     param[4]=yscale;
03866     param[5]=0;
03867 
03868 
03869     invert_transform = sinfo_invert_linear_transform(param) ;
03870     if (invert_transform == NULL) {
03871         sinfo_msg_error("cannot compute sinfo_invert transform: "
03872                         "aborting warping") ;
03873         return NULL ;
03874     }
03875 
03876     /* Generate default interpolation kernel */
03877     kernel = sinfo_generate_interpolation_kernel(kernel_type) ;
03878     if (kernel == NULL) {
03879         sinfo_msg_error("cannot generate kernel: aborting resampling") ;
03880         return NULL ;
03881     }
03882 
03883     /* Compute new image size   */
03884     /* Compute new image size   */
03885     ilx=cpl_image_get_size_x(cpl_imagelist_get(cu,0));
03886     ily=cpl_image_get_size_y(cpl_imagelist_get(cu,0));
03887     inp=cpl_imagelist_get_size(cu);
03888 
03889     lx_out = (int) ilx*xscale ;
03890     ly_out = (int) ily*yscale ;
03891 
03892     cube=cpl_imagelist_new();
03893     for ( l = 0 ; l < inp ; i++ ) {
03894      in_img = cpl_image_new(ilx,ily,CPL_TYPE_FLOAT);
03895      cpl_imagelist_set(cube,in_img,l);
03896     }
03897 
03898     /* old code
03899     if (NULL == (cube = sinfo_newCube (lx_out, ly_out, cu->np)) )
03900     {
03901         sinfo_msg_error (" cannot allocate new cube") ;
03902         return NULL ;
03903     }
03904     */
03905 
03906     for (l=0;l<inp;l++){
03907       in_img=cpl_imagelist_get(cu,l);
03908       ou_img=cpl_imagelist_get(cube,l);
03909       tlx=cpl_image_get_size_x(in_img);
03910       tly=cpl_image_get_size_y(in_img);
03911       podata=cpl_image_get_data_float(ou_img);
03912         /* Pre compute leaps for 16 closest neighbors positions */
03913         leaps[0] = -1 - tlx ;
03914         leaps[1] =    - tlx ;
03915         leaps[2] =  1 - tlx ;
03916         leaps[3] =  2 - tlx ;
03917 
03918         leaps[4] = -1 ;
03919         leaps[5] =  0 ;
03920         leaps[6] =  1 ;
03921         leaps[7] =  2 ;
03922 
03923         leaps[8] = -1 + tlx ;
03924         leaps[9] =      tlx ;
03925         leaps[10]=  1 + tlx ;
03926         leaps[11]=  2 + tlx ;
03927 
03928         leaps[12]= -1 + 2*tlx ;
03929         leaps[13]=      2*tlx ;
03930         leaps[14]=  1 + 2*tlx ;
03931         leaps[15]=  2 + 2*tlx ;
03932 
03933         /* Double loop on the output image  */
03934         for (j=0 ; j < ly_out ; j++) {
03935             for (i=0 ; i< lx_out ; i++) {
03936                 /* Compute the original source for this pixel   */
03937 
03938                 x = invert_transform[0] * (double)i +
03939                     invert_transform[1] * (double)j +
03940                 invert_transform[2] ;
03941 
03942                 y = invert_transform[3] * (double)i +
03943                 invert_transform[4] * (double)j +
03944                 invert_transform[5] ;
03945 
03946             /* Which is the closest integer positioned neighbor?    */
03947                 px = (int)x ;
03948         py = (int)y ;
03949 
03950                 if ((px < 1) ||
03951                     (px > (tlx-2)) ||
03952                     (py < 1) ||
03953                     (py > (tly-2)))
03954                     podata[i+j*lx_out] = (pixelvalue)0.0 ;
03955                 else {
03956                     /* Now feed the positions for the closest 16 neighbors  */
03957                     pos = px + py * tlx ;
03958                     for (k=0 ; k<16 ; k++){
03959                         if(!isnan(podata[(int)(pos+leaps[k])])) neighbors[k] =
03960                          (double)(podata[(int)(pos+leaps[k])]) ;
03961                 else neighbors[k]=0;
03962             }
03963 
03964                     /* Which tabulated value index shall we use?    */
03965                     tabx = (x - (double)px) * (double)(TABSPERPIX) ;
03966                     taby = (y - (double)py) * (double)(TABSPERPIX) ;
03967 
03968                     /* Compute resampling coefficients  */
03969                     /* rsc[0..3] in x, rsc[4..7] in y   */
03970 
03971                     rsc[0] = kernel[TABSPERPIX + tabx] ;
03972                     rsc[1] = kernel[tabx] ;
03973                     rsc[2] = kernel[TABSPERPIX - tabx] ;
03974                     rsc[3] = kernel[2 * TABSPERPIX - tabx] ;
03975                     rsc[4] = kernel[TABSPERPIX + taby] ;
03976                     rsc[5] = kernel[taby] ;
03977                     rsc[6] = kernel[TABSPERPIX - taby] ;
03978                     rsc[7] = kernel[2 * TABSPERPIX - taby] ;
03979 
03980                     sumrs = (rsc[0]+rsc[1]+rsc[2]+rsc[3]) *
03981                         (rsc[4]+rsc[5]+rsc[6]+rsc[7]) ;
03982 
03983                     /* Compute interpolated pixel now   */
03984                     cur =   rsc[4] * (  rsc[0]*neighbors[0] +
03985                                     rsc[1]*neighbors[1] +
03986                                     rsc[2]*neighbors[2] +
03987                                     rsc[3]*neighbors[3] ) +
03988                         rsc[5] * (  rsc[0]*neighbors[4] +
03989                                     rsc[1]*neighbors[5] +
03990                                     rsc[2]*neighbors[6] +
03991                                     rsc[3]*neighbors[7] ) +
03992                         rsc[6] * (  rsc[0]*neighbors[8] +
03993                                     rsc[1]*neighbors[9] +
03994                                     rsc[2]*neighbors[10] +
03995                                     rsc[3]*neighbors[11] ) +
03996                         rsc[7] * (  rsc[0]*neighbors[12] +
03997                                     rsc[1]*neighbors[13] +
03998                                     rsc[2]*neighbors[14] +
03999                                     rsc[3]*neighbors[15] ) ;
04000 
04001                     /* Affect the value to the output image */
04002                     podata[i+j*lx_out] = (pixelvalue)(cur/sumrs) ;
04003                     /* done ! */
04004                 }
04005             }
04006         }
04007     }
04008     cpl_free(kernel) ;
04009     cpl_free(invert_transform) ;
04010     return cube ;
04011 }
04012 
04013 
04023 cpl_imagelist *
04024 sinfo_cube_zshift(const cpl_imagelist * cube_inp,
04025                   const double shift,
04026                   double* sub_shift)
04027 {
04028 
04029     cpl_imagelist * cube_out=NULL ;
04030     const cpl_image* img_inp=NULL;
04031     cpl_image* img_out=NULL;
04032     int        col, row,z ;
04033     int        int_shift ;
04034     int ilx=0;
04035     int ily=0;
04036     int ilz=0;
04037 
04038     int olx=0;
04039     int oly=0;
04040     int olz=0;
04041     int i=0;
04042     const float* pidata=NULL;
04043     float* podata=NULL;
04044 
04045     cknull(cube_inp,"no input cube given!") ;
04046     check_nomsg(img_inp=cpl_imagelist_get_const(cube_inp,0));
04047     check_nomsg(ilx=cpl_image_get_size_x(img_inp));
04048     check_nomsg(ily=cpl_image_get_size_y(img_inp));
04049     check_nomsg(ilz=cpl_imagelist_get_size(cube_inp));
04050 
04051     olx=ilx;
04052     oly=ily;
04053     olz=ilz;
04054 
04055     int_shift = sinfo_new_nint(shift) ;
04056     *sub_shift = shift - (double) int_shift ;
04057     if ( int_shift == 0 )
04058     {
04059         cube_out =cpl_imagelist_duplicate(cube_inp) ;
04060         return cube_out ;
04061     }
04062     else
04063     {
04064       /* allocate memory */
04065       cknull(cube_out = cpl_imagelist_new(),"could not allocate memory!") ;
04066       for ( i = 0 ; i < olz ; i++ ) {
04067         check_nomsg(img_out=cpl_image_new(olx,oly,CPL_TYPE_FLOAT));
04068         check_nomsg(cpl_imagelist_set(cube_out,img_out,i));
04069      }
04070     }
04071 
04072     for(z=0; z< ilz; z++) {
04073       if ( (z-int_shift >= 0 ) && (z - int_shift < olz) ) {
04074         check_nomsg(img_inp=cpl_imagelist_get_const(cube_inp,z));
04075         check_nomsg(img_out=cpl_imagelist_get(cube_out,z-int_shift));
04076     check_nomsg(pidata=cpl_image_get_data_float_const(img_inp));
04077     check_nomsg(podata=cpl_image_get_data_float(img_out));
04078     for ( col = 0 ; col < ilx ; col++ ) {
04079       for ( row = 0 ; row < ily ; row++ ) {
04080         podata[col+row*olx] = pidata[col+row*olx] ;
04081       }
04082     }
04083       }
04084     }
04085     return cube_out ;
04086 
04087  cleanup:
04088     sinfo_free_imagelist(&cube_out);
04089     return NULL ;
04090 }
04091 
04101 cpl_imagelist *
04102 sinfo_cube_zshift_poly(const cpl_imagelist * cube_inp,
04103                        const double sub_shift,
04104                        const int    order)
04105 {
04106   cpl_imagelist * cube_out ;
04107 
04108   float* spec=NULL ;
04109   float* corrected_spec=NULL ;
04110   float* xnum=NULL ;
04111 
04112   float sum=0;
04113   float new_sum=0 ;
04114   float eval=0 ;
04115   float * imageptr=NULL ;
04116   int row=0;
04117   int col=0 ;
04118   int firstpos=0 ;
04119   int n_points=0 ;
04120   int i=0 ;
04121   int flag=0;
04122   int ilx=0;
04123   int ily=0;
04124   int ilz=0;
04125 
04126   int olx=0;
04127   int oly=0;
04128   int olz=0;
04129   int z=0;
04130 
04131   const float* pidata=NULL;
04132   float* podata=NULL;
04133   const cpl_image* img_inp=NULL;
04134   cpl_image* img_out=NULL;
04135 
04136   if ( cube_inp == NULL ) {
04137     sinfo_msg_error("no imagelist given!") ;
04138     return NULL ;
04139   }
04140 
04141   img_inp=cpl_imagelist_get_const(cube_inp,0);
04142 
04143   ilx=cpl_image_get_size_x(img_inp);
04144   ily=cpl_image_get_size_y(img_inp);
04145   ilz=cpl_imagelist_get_size(cube_inp);
04146 
04147   if ( order <= 0 ) {
04148     sinfo_msg_error("wrong order of interpolation polynom given!") ;
04149     return NULL ;
04150   }
04151 
04152 
04153   olx=ilx;
04154   oly=ily;
04155   olz=ilz;
04156   /* allocate memory */
04157 
04158   if ( NULL == (cube_out = cpl_imagelist_new()) ) {
04159     sinfo_msg_error ("could not allocate memory!") ;
04160     return NULL ;
04161   } else {
04162     for ( i = 0 ; i < ilz ; i++ ) {
04163       img_out=cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
04164       cpl_imagelist_set(cube_out,img_out,i);
04165     }
04166   }
04167 
04168 
04169   n_points = order + 1 ;
04170   if ( n_points % 2 == 0 ) {
04171     firstpos = (int)(n_points/2) - 1 ;
04172   } else {
04173     firstpos = (int)(n_points/2) ;
04174   }
04175 
04176   spec=cpl_calloc(ilz,sizeof(float)) ;
04177   corrected_spec=cpl_calloc(ilz,sizeof(float)) ;
04178   xnum=cpl_calloc(order+1,sizeof(float)) ;
04179 
04180 
04181   /* fill the xa[] array for the polint function */
04182   for ( i = 0 ; i < n_points ; i++ ) {
04183     xnum[i] = i ;
04184   }
04185 
04186   for ( col = 0 ; col < ilx ; col++ ) {
04187     for ( row = 0 ; row < ily ; row++ ) {
04188       for( z=0; z< ilz; z++) {
04189         corrected_spec[z] = 0. ;
04190       }
04191       sum = 0. ;
04192       for ( z = 0 ; z < ilz ; z++ ) {
04193     img_inp=cpl_imagelist_get_const(cube_inp,z);
04194         pidata=cpl_image_get_data_float_const(img_inp);
04195     spec[z] = pidata[col + row*ilx] ;
04196     if (isnan(spec[z]) ) {
04197           spec[z] = 0. ;
04198 
04199       for ( i = z - firstpos ; i < z-firstpos+n_points ; i++ ) {
04200         if ( i < 0 ) continue ;
04201             if ( i >= ilz) continue  ;
04202             corrected_spec[i] = ZERO ;
04203           }
04204         }
04205         if ( z != 0 && z != ilz - 1 ) {
04206           sum += spec[z] ;
04207         }
04208 
04209       }
04210 
04211       new_sum = 0. ;
04212       for ( z = 0 ; z < ilz ; z++ ) {
04213 
04214         /* ---------------------------------------------------------------
04215          * now determine the arrays of size n_points with which the
04216          * polynom is determined and determine the position eval
04217          * where the polynom is evaluated in polynomial interpolation.
04218          * Take care of the points near the row edges!
04219          */
04220         if (isnan(corrected_spec[z])) continue ;
04221         if ( z - firstpos < 0 ) {
04222           imageptr = &spec[0] ;
04223           eval     = sub_shift + z ;
04224         } else if ( z - firstpos + n_points >= ilz ) {
04225           imageptr = &spec[ilz - n_points] ;
04226           eval     = sub_shift + z + n_points - ilz ;
04227         } else {
04228       imageptr = &spec[z-firstpos] ;
04229           eval     = sub_shift + firstpos ;
04230         }
04231 
04232         flag=0;
04233         corrected_spec[z]=sinfo_new_nev_ille(xnum,imageptr,order,eval,&flag);
04234         if ( z != 0 && z != ilz - 1 ) {
04235           new_sum += corrected_spec[z] ;
04236         }
04237       }
04238 
04239       /* fill the output spectrum */
04240       for (z = 0 ; z < ilz ; z++ )
04241       {
04242         img_out=cpl_imagelist_get(cube_out,z);
04243         podata=cpl_image_get_data_float(img_out);
04244         if ( new_sum == 0. ) {
04245           new_sum = 1. ;
04246         }
04247         if ( z == 0 ) {
04248           podata[col+row*olx] = ZERO ;
04249         } else if ( z == ilz - 1 ) {
04250           podata[col+row*olx] = ZERO ;
04251         } else if ( isnan(corrected_spec[z]) ) {
04252           podata[col+row*olx] = ZERO ;
04253         } else {
04254           corrected_spec[z] *= sum / new_sum ;
04255           podata[col+row*olx] = corrected_spec[z] ;
04256     }
04257       }
04258 
04259     }
04260   }
04261 
04262   cpl_free(spec) ;
04263   cpl_free(corrected_spec) ;
04264   cpl_free(xnum) ;
04265   return cube_out ;
04266 
04267 
04268 }
04269 
04278 cpl_imagelist *
04279 sinfo_cube_zshift_spline3(const cpl_imagelist * cube_inp,
04280                           const double sub_shift)
04281 {
04282 
04283   cpl_imagelist * cube_out=NULL ;
04284   float* spec=NULL ;
04285   float* corrected_spec=NULL ;
04286   float* xnum=NULL ;
04287   float* eval=NULL ;
04288   float sum=0;
04289   float new_sum=0 ;
04290   int row=0;
04291   int col=0;
04292   int i=0;
04293   int z=0;
04294 
04295   int ilx=0;
04296   int ily=0;
04297   int ilz=0;
04298   int olx=0;
04299   int oly=0;
04300   int olz=0;
04301 
04302   const float* pidata=NULL;
04303   float* podata=NULL;
04304   const cpl_image* img_inp=NULL;
04305   cpl_image* img_out=NULL;
04306 
04307   if ( cube_inp == NULL ) {
04308     sinfo_msg_error("no imagelist given!") ;
04309     return NULL ;
04310   }
04311 
04312   img_inp=cpl_imagelist_get_const(cube_inp,0);
04313   ilx=cpl_image_get_size_x(img_inp);
04314   ily=cpl_image_get_size_y(img_inp);
04315   ilz=cpl_imagelist_get_size(cube_inp);
04316 
04317 
04318   olx=ilx;
04319   oly=ily;
04320   olz=ilz;
04321   /* allocate memory */
04322   if ( NULL == (cube_out = cpl_imagelist_new()) ) {
04323     sinfo_msg_error ("could not allocate memory!") ;
04324     return NULL ;
04325   } else {
04326     for ( i = 0 ; i < ilz ; i++ ) {
04327       img_out=cpl_image_new(olx,oly,CPL_TYPE_FLOAT);
04328       cpl_imagelist_set(cube_out,img_out,i);
04329     }
04330   }
04331 
04332   xnum=cpl_calloc(ilz,sizeof(float)) ;
04333   /* fill the xa[] array for the spline function */
04334   for ( i = 0 ; i < ilz ; i++ ) {
04335     xnum[i] = i ;
04336   }
04337 
04338   spec=cpl_calloc(ilz,sizeof(float)) ;
04339   corrected_spec=cpl_calloc(ilz,sizeof(float)) ;
04340   eval=cpl_calloc(ilz,sizeof(float)) ;
04341 
04342   for ( col = 0 ; col < ilx ; col++ ) {
04343     for ( row = 0 ; row < ily ; row++ ) {
04344       sum = 0. ;
04345       for ( z = 0 ; z < ilz ; z++ ) {
04346     img_inp=cpl_imagelist_get_const(cube_inp,z);
04347         pidata=cpl_image_get_data_float_const(img_inp);
04348     spec[z] = pidata[col + row*ilx] ;
04349     if (isnan(spec[z]) ) {
04350       for ( i = z-1 ; i <= z+1 ; i++ ) {
04351         if ( i < 0 ) continue ;
04352         if ( i >= ilz) continue ;
04353         corrected_spec[i] = ZERO ;
04354       }
04355       spec[z] = 0. ;
04356     }
04357     sum += spec[z] ;
04358     eval[z] = (float)sub_shift+(float)z ;
04359       }
04360       /* now we do the spline interpolation*/
04361       if ( -1 == sinfo_function1d_natural_spline( xnum, spec, ilz, eval,
04362                                               corrected_spec, ilz ) )
04363         {
04364       sinfo_msg_error("error in spline interpolation!") ;
04365       return NULL ;
04366         }
04367 
04368       new_sum = 0. ;
04369       for ( z = 0 ; z < ilz ; z++ ) {
04370     if ( isnan(corrected_spec[z]) ) {
04371       continue ;
04372     }
04373     new_sum += corrected_spec[z] ;
04374       }
04375       /* fill output imagelist */
04376       for ( z = 0 ; z < ilz ; z++ ) {
04377         img_out=cpl_imagelist_get(cube_out,z);
04378         podata=cpl_image_get_data_float(img_out);
04379     if ( new_sum == 0. ) new_sum =1. ;
04380     {
04381       if ( isnan(corrected_spec[z]) ) {
04382         podata[col+row*olx] = ZERO ;
04383       } else {
04384         corrected_spec[z] *= sum / new_sum ;
04385         podata[col+row*olx] = corrected_spec[z] ;
04386       }
04387     }
04388       }
04389     }
04390   }
04391   cpl_free(xnum);
04392   cpl_free(spec) ;
04393   cpl_free(corrected_spec) ;
04394   cpl_free(eval) ;
04395 
04396   return cube_out ;
04397 }
04398 
04400 /* The structure for stroing index data for kappa-sigma
04401  *
04402  * */
04403 struct _CubeData
04404 {
04405     int iCubeNumber;
04406     int iLocalX;
04407     int iLocalY;
04408 };
04409 typedef struct _CubeData CubeData;
04410 
04411 struct _CubeDataVector
04412 {
04413     int size;
04414     CubeData** pdata;
04415 };
04416 typedef struct _CubeDataVector CubeDataVector;
04434 static int sinfo_kappa_sigma_offset_with_mask(
04435         int z_min,
04436         int z_max,
04437         int nCubes,
04438         cpl_imagelist** inputCubes,
04439         double* exptimes,
04440         cpl_imagelist* imResult,
04441         int* offsetX,
04442         int* offsetY,
04443         cpl_imagelist* sky_mask,
04444         const double kappa
04445         );
04446 void kappa_sigma_CubeDataVector(
04447         int globalX,
04448         int globalY,
04449         CubeDataVector* pCubeDataVector,
04450         cpl_imagelist* imlistResult,
04451         cpl_imagelist** input_cubes,
04452         cpl_imagelist* sky_mask,
04453         int iPlanesNumber,
04454         int z_min,
04455         const double kappa,
04456         double* exptimes
04457         );
04458 
04459 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)
04460 {
04461     double result = 0;
04462     int nInvalidPoints = 0;
04463     const double EPS = 1E-10;
04464     //sinfo_msg("kappa_sigma_array_with_mask, x[%d] y[%d]"
04465     double mask_adjustment = mask_delta;
04466     do
04467     {
04468         double median = 0;
04469         double sig = 0;
04470         int z = 0;
04471         nInvalidPoints = 0;
04472 
04473         check_nomsg(median = cpl_array_get_median(parray));
04474         check_nomsg(sig = cpl_array_get_stdev(parray));
04475         for (z = 0; z < szArray; z++)
04476         {
04477             int isnull = 0;
04478             double value = 0;
04479             check_nomsg(value = cpl_array_get(parray, z, &isnull));
04480             if(!isnull)
04481             {
04482                 if (fabs(value - median) > (kappa * sig))
04483                 {
04484 
04485    //                       sinfo_msg("entered");
04486     //        sinfo_msg("val=%g check=%g",
04487     //              fabs(value - median),(kappa * sig));
04488 //            sinfo_msg("kappa=%f sig=%g median=%g value=%g",
04489 //                  kappa,sig,median,value);
04490 
04491                     //double msk_new_value = 0;
04492                     cpl_array_fill_window_invalid(parray, z, 1);
04493                     mask_adjustment += exptimes[z];
04494                     ++nInvalidPoints;
04495                 }
04496             }
04497         }
04498         /*if (nInvalidPoints)
04499         {
04500             sinfo_msg("nInvalidPoints %d[%d][%d] median[%f] sig[%f]", nInvalidPoints,x,y, median, sig );
04501         }*/
04502 
04503     }
04504     while (nInvalidPoints);
04505     if(imMask && fabs(mask_adjustment) > EPS)
04506     {
04507         // adjust mask image
04508         int px_rejected = 0;
04509         double msk_value = 0;
04510         check_nomsg(msk_value = cpl_image_get(imMask, x, y, &px_rejected));
04511         check_nomsg(cpl_image_set(imMask, x,y, msk_value - mask_adjustment));
04512     }
04513     // get a result value for the point
04514     check_nomsg(result = cpl_array_get_mean(parray));
04515     return result;
04516     cleanup:
04517     sinfo_msg("Error in kappa_sigma_array_with_mask");
04518     return 0;
04519 }
04520 int sinfo_coadd_with_ks_clip_optimized(
04521             const int z_min,
04522             const int z_max,
04523             const int n_cubes,
04524             const double kappa,
04525             int* llx,
04526             int* lly,
04527             double* exptimes,
04528             cpl_imagelist* sky_mask,
04529             cpl_imagelist* mergedCube,
04530             cpl_imagelist** tmpcubes
04531             )
04532 {
04533   /*
04534     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]",
04535             z_min, z_max, ilx, ily, n_cubes, kappa,llx, lly,exptimes,sky_mask);
04536   */
04537    int result=0;
04538    check_nomsg(result=sinfo_kappa_sigma_offset_with_mask(z_min, z_max, n_cubes, tmpcubes, exptimes, mergedCube, llx, lly, sky_mask, kappa));
04539 
04540   cleanup:
04541 
04542     return result;
04543 
04544 }
04545 
04546 static int sinfo_kappa_sigma_offset_with_mask(
04547         int z_min,
04548         int z_max,
04549         int nCubes,
04550         cpl_imagelist** inputCubes,
04551         double* exptimes,
04552         cpl_imagelist* imResult,
04553         int* global_offsetX,
04554         int* global_offsetY,
04555         cpl_imagelist* sky_mask,
04556         const double kappa
04557         )
04558 {
04559     const int BIG_ENOUGH_INT = 65535;
04560     CubeDataVector*** indexX = 0;
04561     int x = 0;
04562     int y = 0;
04563     int z = 0;
04564     int iPlanesNumber = z_max - z_min;
04565     int nIndexXbytes = 0;
04566     int globalSizeX = 0 ;
04567     int globalSizeY = 0;
04568 
04569     int xmax = -BIG_ENOUGH_INT;
04570     int ymax = -BIG_ENOUGH_INT;
04571     int xmin = BIG_ENOUGH_INT;
04572     int ymin = BIG_ENOUGH_INT;
04573     int* offsetX = 0; // local offset of the cubes, normalized
04574     int* offsetY = 0;
04575     //sinfo_msg(" starting kappa-sigma clipping for cubes[%d] planes[%d]", nCubes, z_max - z_min );
04576     // determine size of the coadded cube
04577         sinfo_check_rec_status(0);
04578     for (z = 0; z < nCubes; z++)
04579     {
04580 
04581         cpl_imagelist* pCube = inputCubes[z];
04582         cpl_image* pImage = 0;
04583         int localMaxX = 0;
04584         int localMaxY = 0;
04585         int localMinX = 0;
04586         int localMinY = 0;
04587 
04588         pImage = cpl_imagelist_get(pCube, 0);
04589 
04590         localMaxX = cpl_image_get_size_x(pImage) + global_offsetX[z];
04591         localMaxY = cpl_image_get_size_y(pImage) + global_offsetY[z];
04592         localMinX = global_offsetX[z];
04593         localMinY = global_offsetY[z];
04594 
04595         if(localMaxX > xmax) xmax = localMaxX;
04596         if(localMaxY > ymax) ymax = localMaxY;
04597 
04598         if(localMinX < xmin) xmin = localMinX;
04599         if(localMinY < ymin) ymin = localMinY;
04600     }
04601         sinfo_check_rec_status(1);
04602 
04603     // DFS09121 xmax and ymax could be more then output cube - check and adjust
04604     {
04605         int msize_x = 0;
04606         int msize_y = 0;
04607         //sinfo_msg("DFS09121 before:  xmax=%d ymax=%d", xmax, ymax);
04608         cpl_image * pmaskimage = cpl_imagelist_get(sky_mask, 0);
04609         msize_x = cpl_image_get_size_x(pmaskimage);
04610         msize_y = cpl_image_get_size_y(pmaskimage);
04611         xmax = msize_x < xmax ? msize_x : xmax;
04612         ymax = msize_y < ymax ? msize_y : ymax;
04613         //sinfo_msg("DFS09121 after:  xmax=%d ymax=%d", xmax, ymax);
04614     }
04615     // rely on the data received outside
04616     globalSizeX = xmax;// - xmin;
04617     globalSizeY = ymax;// - ymin;
04618     // calculate local offset
04619     check_nomsg(offsetX = cpl_malloc(sizeof(offsetX[0]) * nCubes));
04620     check_nomsg(offsetY = cpl_malloc(sizeof(offsetY[0]) * nCubes));
04621         sinfo_check_rec_status(2);
04622     for (z = 0; z < nCubes; z++) // use the offset from the caller
04623     {
04624         offsetX[z] = global_offsetX[z];// - xmin;
04625         offsetY[z] = global_offsetY[z];// - ymin;
04626 //      sinfo_msg("for cube [%d] offset X[%d : %d] Y[%d : %d]", z, offsetX[z], global_offsetX[z], offsetY[z], global_offsetY[z]);
04627     }
04628         sinfo_check_rec_status(3);
04629     // Because of DFS09121, the allocated size is taken +1
04630     nIndexXbytes = sizeof(CubeDataVector**) * (globalSizeX+1 );
04631 //  sinfo_msg("   kappa_sigma_offset, globalSizeX[%d] globalSizeY[%d] nIndexXbytes[%d]", globalSizeX, globalSizeY, nIndexXbytes);
04632     indexX = cpl_malloc(nIndexXbytes);
04633     memset(&indexX[0], 0, (globalSizeX+1 )* sizeof(indexX[0]));
04634     // prepare result planes and mask
04635 
04636     // 1. Fill indexes - do it only for a 0 plane in the cube
04637     for (z = 0; z < nCubes; z++)
04638     {
04639         int iCubeSizeX = 0;
04640         int iCubeSizeY = 0;
04641         int iOffsetX = 0;
04642         int iOffsetY = 0;
04643 
04644         cpl_imagelist* pCube = inputCubes[z];
04645         cpl_image* pImage = 0;
04646         pImage = cpl_imagelist_get(pCube, 0);
04647 
04648         iCubeSizeX = cpl_image_get_size_x(pImage);
04649         iCubeSizeY = cpl_image_get_size_y(pImage);
04650         iOffsetX = offsetX[z];
04651         iOffsetY = offsetY[z];
04652 //      sinfo_msg("   processing cube [%d] offsetX[%d] offsetY[%d] iCubeSizeX[%d] iCubeSizeY[%d]", z, iOffsetX, iOffsetY, iCubeSizeX, iCubeSizeY);
04653         for (x = 1; x <= iCubeSizeX; x++)
04654         {
04655             int iGlobalX = x + iOffsetX;
04656 
04657             CubeDataVector** ppVector = 0;
04658             if (indexX[iGlobalX - 1] == 0)
04659             {
04660                 // Because of DFS09121, the allocated size is taken +1
04661                 int nBytes = sizeof(CubeDataVector*) * (globalSizeY+1 );
04662                 ppVector= cpl_malloc(nBytes);
04663                 memset(&ppVector[0],0,(globalSizeY+1) * sizeof(ppVector[0]));
04664                 indexX[iGlobalX - 1] = ppVector;
04665             }
04666             else
04667             {
04668                 ppVector = indexX[iGlobalX - 1];
04669             }
04670             for (y = 1; y <=iCubeSizeY; y++)
04671             {
04672                 CubeData* pCubeData = 0;
04673                 int iGlobalY = y + iOffsetY;
04674                 CubeDataVector* pVector = ppVector[iGlobalY - 1];
04675                 if(pVector == 0)
04676                 {
04677                     int nbytes = sizeof(CubeDataVector);
04678                     check_nomsg(pVector = cpl_malloc(nbytes));
04679                     ppVector[iGlobalY - 1] = pVector;
04680                     pVector->size = 0;
04681                     nbytes = sizeof(CubeData*) * nCubes;
04682                     pVector->pdata = cpl_malloc(nbytes);
04683 //                  memset(&pVector->pdata[0], 0, nCubes * sizeof(pVector->pdata[0]));
04684                 }
04685                 pCubeData = cpl_malloc(sizeof(CubeData));
04686                 pVector->pdata[(pVector->size)++] = pCubeData;
04687                 pCubeData->iCubeNumber = z;
04688                 pCubeData->iLocalX = x;
04689                 pCubeData->iLocalY = y;
04690             }
04691         }
04692     }
04693         sinfo_check_rec_status(4);
04694 
04695     // 2. for each index value in global coordinates (x,y) call kappa-sigma
04696     for (x = 1; x <= globalSizeX; x++)
04697     {
04698         CubeDataVector** pDataX = indexX[x - 1];
04699         if (pDataX)
04700         {
04701             for (y = 1; y <= globalSizeY; y++)
04702             {
04703                 CubeDataVector* pDataY = pDataX[y - 1];
04704                 if (pDataY && pDataY->size)
04705                 {
04706                     kappa_sigma_CubeDataVector(x, y, pDataY, imResult, inputCubes, sky_mask, iPlanesNumber, z_min, kappa, exptimes);
04707                 }
04708                 if (pDataY)
04709                 {
04710                     check_nomsg(cpl_free(pDataY->pdata));
04711                     check_nomsg(cpl_free(pDataY));
04712                 }
04713             }
04714             check_nomsg(cpl_free(pDataX));
04715         }
04716     }
04717     sinfo_check_rec_status(5);
04718     cleanup:
04719     cpl_free(indexX);
04720     cpl_free(offsetX);
04721     cpl_free(offsetY);
04722     return 0;
04723 
04724 }
04725 
04726 void kappa_sigma_CubeDataVector(
04727         int globalX,
04728         int globalY,
04729         CubeDataVector* pCubeDataVector,
04730         cpl_imagelist* imlistResult,
04731         cpl_imagelist** input_cubes,
04732         cpl_imagelist* sky_mask,
04733         int iPlanesNumber,
04734         int z_min,
04735         const double kappa,
04736         double* exptimes
04737         )
04738 {
04739     int plane = 0;
04740     int z = 0;
04741 
04742     // iterate through all planes
04743     cpl_array* pArray = 0;
04744     check_nomsg(pArray = cpl_array_new(pCubeDataVector->size, CPL_TYPE_DOUBLE));
04745 
04746 
04747     for (plane = z_min; plane < z_min + iPlanesNumber; plane++)
04748     {
04749         double val_msk = 0; // value of the mask in the point
04750         int px = 0;
04751         cpl_image* imResult = 0;
04752         cpl_image* imMask = 0;
04753         double mask_adjustment = 0;
04754         int nValidPoints = 0;
04755         cpl_array_fill_window_invalid(pArray, 0, pCubeDataVector->size);
04756         check_nomsg(imMask = cpl_imagelist_get(sky_mask, plane - z_min));
04757         check_nomsg(val_msk = cpl_image_get(imMask, globalX, globalY, &px));
04758         for (z = 0; z < pCubeDataVector->size; z++) // through all cubes for that point - prepare the array
04759         {
04760 
04761             cpl_imagelist* pCube = 0;
04762             CubeData* pCubeData = pCubeDataVector->pdata[z];
04763             pCube = input_cubes[pCubeData->iCubeNumber];
04764             if (pCube)
04765             {
04766                 cpl_image* pImage = cpl_imagelist_get(pCube, plane - z_min);
04767 
04768                 if (pImage)
04769                 {
04770                     int is_rejected = 0;
04771                     double value = 0;
04772                     check_nomsg(value = cpl_image_get(pImage, pCubeData->iLocalX, pCubeData->iLocalY, &is_rejected));
04773                     if (!isnan(value))
04774                     {
04775                         check_nomsg(cpl_array_set(pArray, z, value));
04776                         ++nValidPoints;
04777                     }
04778                     else
04779                     {
04780                         mask_adjustment += exptimes[z];
04781                     }
04782                 }
04783                 else
04784                 {
04785                     sinfo_msg("kappa_sigma_CubeDataVector() - pImage is null");
04786                 }
04787             }
04788         }
04789         if(nValidPoints)
04790         {
04791            kappa_sigma_array_with_mask(pArray, pCubeDataVector->size, kappa, imMask, exptimes, globalX, globalY, mask_adjustment);
04792            check_nomsg(imResult = cpl_imagelist_get(imlistResult, plane));
04793            if (imResult)
04794            {
04795               check_nomsg(cpl_image_set(imResult, globalX, globalY, cpl_array_get_mean(pArray)));
04796            }
04797            else
04798            {
04799               sinfo_msg("kappa_sigma_CubeDataVector() - imResult is null");
04800            }
04801         } else
04802         {
04803             // adjust the mask
04804             check_nomsg(cpl_image_set(imMask, globalX,globalY, 0));
04805         }
04806     }
04807     for (z = 0; z < pCubeDataVector->size; z++) // through all cubes  - delete the data
04808     {
04809         CubeData* pCubeData = pCubeDataVector->pdata[z];
04810         cpl_free(pCubeData);
04811     }
04812     cpl_array_delete(pArray);
04813     return;
04814     cleanup:
04815 //  sinfo_msg("   -----cleanup from kappa_sigma_CubeDataVector");
04816     return;
04817 }
04818 
04819 

Generated on 8 Mar 2011 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1