#ifndef SINFO_NEW_CUBE_OPS_H
#define SINFO_NEW_CUBE_OPS_H
/*
 * This file is part of the ESO SINFONI Pipeline
 * Copyright (C) 2004,2005 European Southern Observatory
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
 */
/************************************************************************
* E.S.O. - VLT project
*
* who       when      what
* --------  --------  ----------------------------------------------
* schreib  18/05/00  created
*/

/************************************************************************
 * sinfo_new_cube_ops.h
 * cube arithmetic routines
 *----------------------------------------------------------------------
 */

/*
 * header files
 */

#include "sinfo_image_ops.h"
#include <cpl.h>
#include "sinfo_msg.h"


/*----------------------------------------------------------------------------
 *                        Function ANSI C prototypes
 *--------------------------------------------------------------------------*/


/**
   @name   sinfo_new_cube_ops()
   @memo   2 cubes, operation to perform
   @param  cube1 1st cube
   @param  cube2 2nd cube
   @param  operation operation to perform between cubes
   @result result cube
   @short  4 operations between 2 cubes

 */

cpl_imagelist *
sinfo_new_cube_ops(
    cpl_imagelist *  cube1,
    cpl_imagelist *   cube2,
    int         operation);


/**
   @name    sinfo_new_cube_const_ops()
   @memo    1 cube, 1 constant, operation to perform
   @param   cube1 input cube to be operated
   @param   constant value to be applied
   @param   operation operation index
   @return  result cube
   @short   4 operations between a cube and a constant
   @note    possible operations are:
                Addition        '+'
                Subtraction     '-'
                Multiplication  '*'
                Division        '/'
                Logarithm       'l'
                Power           '^'
                Exponentiation  'e'


*/

cpl_imagelist *
sinfo_new_cube_const_ops(
    cpl_imagelist *  cube1,
    double     constant,
    int        operation);


/**
   @name  sinfo_new_cube_sub()
   @memo subtract one cube from another
   @param c1  1st cube
   @param c2  2nd cube
   @result result cube
 */

cpl_imagelist *
sinfo_new_cube_sub(
    cpl_imagelist    *    c1,
    cpl_imagelist    *    c2
) ;



/**
   @name sinfo_new_cube_add()
   @memo add a cube to another
   @param c1  1st cube
   @param c2  2nd cube
   @result result cube
*/

cpl_imagelist *
sinfo_new_cube_add(
    cpl_imagelist    *    c1,
    cpl_imagelist    *    c2
) ;


/**
   @name sinfo_new_cube_mul()
   @memo multiply two cubes
   @param c1  1st cube
   @param c2  2nd cube
   @result result cube
 */

cpl_imagelist *
sinfo_new_cube_mul(
    cpl_imagelist    *    c1,
    cpl_imagelist    *    c2
) ;


/**
   @name  sinfo_new_cube_div()
   @memo  divides two cubes
   @param c1  1st cube
   @param c2  2nd cube
   @result result cube

 */

cpl_imagelist *
sinfo_new_cube_div(
    cpl_imagelist    *    c1,
    cpl_imagelist    *    c2
) ;

/**
   @name   sinfo_new_add_image_to_cube()
   @memo   add an image to all planes in the cube
   @param  cu 1 allocated cube
   @param  im 1 allocated image
   @return result cube
 */

cpl_imagelist *
sinfo_new_add_image_to_cube(cpl_imagelist * cu, cpl_image * im);

/**
   @name      sinfo_new_sub_image_from_cube()
   @memo      subtract an image from all planes in the cube
   @param cu  1 allocated cube,
   @param im  1 allocated image
   @result    result cube
 */

cpl_imagelist *
sinfo_new_sub_image_from_cube(cpl_imagelist * cu, cpl_image * im);

/**
   @name     sinfo_new_mul_image_to_cube()
   @memo multiply an image to all planes in the cube
   @param    cu   1 allocated cube,
   @param    im   1 allocated image
   @result   result cube
 */

cpl_imagelist *
sinfo_new_mul_image_to_cube(cpl_imagelist * cu, cpl_image * im);

/**
   @name    sinfo_new_div_cube_by_image ()
   @memo    divide all planes in the cube by an image
   @param   cu     1 allocated cube,
   @param   im     1 allocated image
   @return  result cube
*/

cpl_imagelist *
sinfo_new_div_cube_by_image(cpl_imagelist * cu, cpl_image * im);


/**
   @name    sinfo_new_add_spectrum_to_cube()
   @memo   adds a spectrum (in z-direction) from all data points in a cube
   @param   cu       1 allocated cube,
   @parm    spec       1 allocated spectrum sinfo_vector
   @return       result cube
 */

cpl_imagelist *
sinfo_new_add_spectrum_to_cube(cpl_imagelist *cu, Vector *spec);


/**
   @name     sinfo_new_sub_spectrum_from_cube()
   @memo  subtracts a spectrum (in z-direction) from all data points in a cube
   @param    cu       1 allocated cube,
   @param    im       1 allocated spectrum sinfo_vector
   @return  result cube
 */

cpl_imagelist *
sinfo_new_sub_spectrum_from_cube(cpl_imagelist *cu, Vector *spec);


/**
   @name     sinfo_new_mul_spectrum_to_cube()
   @memo multiplies a spectrum (in z-direction) to all data points in a cube
   @param    cu     1 allocated cube,
   @param    spec   1 allocated spectrum sinfo_vector
   @result   result cube
*/

cpl_imagelist *
sinfo_new_mul_spectrum_to_cube(cpl_imagelist *cu, Vector *spec);


/**
   @name sinfo_new_div_cube_by_spectrum()
   @param cu  1 allocated cube,
   @param spec  1 allocated spectrum sinfo_vector
   @result  result cube
   @memo divides all data points of a cube by a spectrum (in z-direction)
 */

cpl_imagelist *
sinfo_new_div_cube_by_spectrum(cpl_imagelist *cu, Vector *spec);

/**
   @name  sinfo_new_clean_mean_of_spectra()
   @memo  clean mean of a cube in a rectangle
   @param cu  1 allocated cube,
   @param llx lower left x position of rectangle in x-y plane ,
   @param lly lower left y position of rectangle in x-y plane ,
   @param urx upper right x position of rectangle in x-y plane ,
   @param ury upper right y position of rectangle in x-y plane ,
   @param lo_reject lower cut intensity threshold
   @param hi_reject upper cut intensity threshold
   @return result spectrum vector
   @doc  averaging routine to get a better spectral S/N, sorts
         the values of the same z-position, cuts the lowest and
         highest values according to given thresholds and then
         takes the average within the x-y plane , cannot have
         a sum of low and high rejected values greater than 90%
         of all values
 */

Vector *
sinfo_new_clean_mean_of_spectra(cpl_imagelist * cube,
                             int llx,
                             int lly,
                             int urx,
                             int ury,
                             double lo_reject,
                             double hi_reject);

/**
   @name   sinfo_new_median_cube()
   @memo clean (remove 'BLANK' pixels) median of a cube along z axis
   @param  cube       1 allocated cube
   @result result image
   @doc    determines the median value in every pixel position
           by considering all pixels along the third axis.
           BLANK pixels in a plane are not considered. If all
           pixels at a position are not valid the result will
           be 'BLANK'.
*/
cpl_image *
sinfo_new_median_cube(cpl_imagelist * cube) ;

/**
   @name sinfo_new_average_cube_to_image()
   @memo clean (remove 'ZERO' pixels) average of a cube along z axis
   @param cube       1 allocated cube
   @result  result image
   @doc  determines the average value in every pixel position
         by considering all pixels along the third axis.
         ZERO pixels in a plane are not considered. If all
         pixels at a position are not valid the result will
         be 'ZERO'.
 */
cpl_image *
sinfo_new_average_cube_to_image(cpl_imagelist * cube) ;

/**
   @name  sinfo_new_sum_cube_to_image()
   @param cube       1 allocated cube
   @result result image
   @doc  determines the sum value in every pixel position
         by considering all pixels along the third axis.
         ZERO pixels in a plane are not considered. If all
         pixels at a position are not valid the result will
         be 'ZERO'.
 */
cpl_image *
sinfo_new_sum_cube_to_image(cpl_imagelist * cube) ;

/**
   @name                sinfo_new_average_cube_to_image_between_waves()
   @memo  clean average of a cube within a given wavelength range
   @param               cube: data cube to collapse
   @param               dispersion: dispersion per pixel in microns/pixel
                                    (derived from fits header information)
   @param               centralWave: central wavelength in the cube in microns
                                       (derived from fits header information)
   @param               initialLambda start wavelength values in microns
   @param               finalLambda: end   wavelength values in microns
                                    within which the cube is averaged
   @result              resulting averaged image
   @doc                 determines the average value in every pixel position
                        by considering only the pixels along the third axis
                        which lie between the given wavelength values.
                        These values are first recalculated to plane indices
                        by using the given dispersion and minimum wavelength in
                        the cube.
                        ZERO pixels in a plane are not considered. If all
                        pixels at a position are not valid the result will
                        be 'ZERO'.
 */
cpl_image *
sinfo_new_average_cube_to_image_between_waves (cpl_imagelist * cube,
                                           float     dispersion,
                                           float     centralWave,
                                           float     initialLambda,
                                           float     finalLambda) ;

/**
   @name     sinfo_new_extract_image_from_cube()
   @memo     returns the wanted image plane of the cube
   @param    cube      1 allocated cube
   @param    index of cube plane
   @result   extracted image
*/
cpl_image *
sinfo_new_extract_image_from_cube(cpl_imagelist * cube, int plane_index) ;

/**
   @name     sinfo_new_extract_spectrum_from_cube()
   @param    cube: 1 allocated cube
   @param    x_pos x pixel position of the spectrum counted from 0
   @param    y_pos y pixel position of the spectrum counted from 0
   @result   extracted spectral sinfo_vector object
   @memo     returns the wanted single spectrum of the cube
*/
Vector *
sinfo_new_extract_spectrum_from_cube(cpl_imagelist * cube,
                                     int x_pos,
                                     int y_pos ) ;

/**
   @name         sinfo_new_combine_jittered_cubes()
   @name         cubes: list of jittered cubes to mosaic
   @param        mergedCube: resulting merged cube containing the
                                    jittered cubes
   @param        n_cubes: number of cubes in the list to merge
   @param        cumoffsetx: array of relative x pixel offset
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        cumoffsety: array of relative y pixel offsets
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        exptimes:   exposure times array giving the time
                             in the same sequence as the cube list
   @param        kernel_type: the name of the interpolation kernel
                              that you want to generate using the eclipse
                              routine sinfo_generate_interpolation_kernel()
                              Supported kernels are:
                                     NULL:      default kernel, currently tanh
                                     "default": dito
                                     "tanh":    Hyperbolic tangent
                                     "sinc2":   Square sinc
                                     "lanczos": Lanczos2 kernel
                                     "hamming": Hamming kernel
                                     "hann":    Hann kernel
   @result       mask: cube of the same size as combinedCube
                       containing 0 for blank (ZERO pixels) and
                       the summed integration times for overlapping regions
   @doc                merges jittered data cubes to one bigger cube
                       by averaging the overlap regions weighted by
                       the integration times. The x, y size of the final data
                       cube is user given, and should be between 32 and 64
                       pixels, while the relative pixel-offset (sub-pixel
                       accuracy) of the single cubes with respect to the
                       first cube in the list is read from the SEQ CUMOFFSETX,Y
                       fits header keyword.
 */



cpl_imagelist *
sinfo_new_combine_jittered_cubes ( cpl_imagelist ** cubes,
                                 cpl_imagelist  * mergedCube,
                                 int        n_cubes,
                                 float    * cumoffsetx,
                                 float    * cumoffsety,
                                 float    * exptimes,
                   char     * kernel_type );

/**
   @name         sinfo_new_combine_jittered_cubes()
   @name         cubes: list of jittered cubes to mosaic
   @param        mergedCube: resulting merged cube containing the
                                    jittered cubes
   @param        n_cubes: number of cubes in the list to merge
   @param        cumoffsetx: array of relative x pixel offset
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        cumoffsety: array of relative y pixel offsets
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        exptimes:   exposure times array giving the time
                             in the same sequence as the cube list
   @param        kernel_type: the name of the interpolation kernel
                              that you want to generate using the eclipse
                              routine sinfo_generate_interpolation_kernel()
                              Supported kernels are:
                                     NULL:      default kernel, currently tanh
                                     "default": dito
                                     "tanh":    Hyperbolic tangent
                                     "sinc2":   Square sinc
                                     "lanczos": Lanczos2 kernel
                                     "hamming": Hamming kernel
                                     "hann":    Hann kernel

   @param        z     plane at which the cube is combined.
   @result       mask: cube of the same size as combinedCube
                       containing 0 for blank (ZERO pixels) and
                       the summed integration times for overlapping regions
   @doc                merges jittered data cubes to one bigger cube
                       by averaging the overlap regions weighted by
                       the integration times. The x, y size of the final data
                       cube is user given, and should be between 32 and 64
                       pixels, while the relative pixel-offset (sub-pixel
                       accuracy) of the single cubes with respect to the
                       first cube in the list is read from the SEQ CUMOFFSETX,Y
                       fits header keyword.
 */


cpl_imagelist *
new_combine_jittered_cubes_it ( cpl_imagelist ** cubes,
                                 cpl_imagelist *  mergedCube,
                                 cpl_imagelist *  mask,
                                 int        n_cubes,
                                 float    * cumoffsetx,
                                 float    * cumoffsety,
                                 float    * exptimes,
                                 char     * kernel_type,
                                 const int z) ;


/**
   @name         sinfo_new_combine_jittered_cubes_thomas_range()
   @name         cubes: list of jittered cubes to mosaic
   @param        mergedCube: resulting merged cube containing the
                                    jittered cubes
   @param        n_cubes: number of cubes in the list to merge
   @param        cumoffsetx: array of relative x pixel offset
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        cumoffsety: array of relative y pixel offsets
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        exptimes:   exposure times array giving the time
                             in the same sequence as the cube list
   @param        kernel_type: the name of the interpolation kernel
                              that you want to generate using the eclipse
                              routine sinfo_generate_interpolation_kernel()
                              Supported kernels are:
                                     NULL:      default kernel, currently tanh
                                     "default": dito
                                     "tanh":    Hyperbolic tangent
                                     "sinc2":   Square sinc
                                     "lanczos": Lanczos2 kernel
                                     "hamming": Hamming kernel
                                     "hann":    Hann kernel
   @param       z_min         min z of plane  to be combined
   @param       z_max         max z of plane  to be combined
   @param       kappa         kappa of kappa-sigma clipping algorithm
   @result       mask: cube of the same size as combinedCube
                       containing 0 for blank (ZERO pixels) and
                       the summed integration times for overlapping regions
   @doc                merges jittered data cubes to one bigger cube
                       by averaging the overlap regions weighted by
                       the integration times. The x, y size of the final data
                       cube is user given, and should be between 32 and 64
                       pixels, while the relative pixel-offset (sub-pixel
                       accuracy) of the single cubes with respect to the
                       first cube in the list is read from the SEQ CUMOFFSETX,Y
                       fits header keyword.
 */

int
sinfo_new_combine_jittered_cubes_thomas_range(cpl_imagelist ** cubes,
                    cpl_imagelist  * mergedCube,
                    cpl_imagelist  * mask,
                    int        n_cubes,
                    float    * cumoffsetx,
                    float    * cumoffsety,
                    double    * exptimes,
                    char     * kernel_type,
                    const int z_min,
                    const int z_max,
                                    const double kappa );

/**
   @name         sinfo_new_combine_jittered_cubes_sky_range()
   @name         cubes: list of jittered cubes to mosaic
   @param        mergedCube: resulting merged cube containing the
                                    jittered cubes
   @param        n_cubes: number of cubes in the list to merge
   @param        cumoffsetx: array of relative x pixel offset
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        cumoffsety: array of relative y pixel offsets
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        exptimes:   exposure times array giving the time
                             in the same sequence as the cube list
   @param        kernel_type: the name of the interpolation kernel
                              that you want to generate using the eclipse
                              routine sinfo_generate_interpolation_kernel()
                              Supported kernels are:
                                     NULL:      default kernel, currently tanh
                                     "default": dito
                                     "tanh":    Hyperbolic tangent
                                     "sinc2":   Square sinc
                                     "lanczos": Lanczos2 kernel
                                     "hamming": Hamming kernel
                                     "hann":    Hann kernel
   @param       z_min         min z of plane  to be combined
   @param       z_max         max z of plane  to be combined
   @result       mask: cube of the same size as combinedCube
                       containing 0 for blank (ZERO pixels) and
                       the summed integration times for overlapping regions
   @doc                merges jittered data cubes to one bigger cube
                       by averaging the overlap regions weighted by
                       the integration times. The x, y size of the final data
                       cube is user given, and should be between 32 and 64
                       pixels, while the relative pixel-offset (sub-pixel
                       accuracy) of the single cubes with respect to the
                       first cube in the list is read from the SEQ CUMOFFSETX,Y
                       fits header keyword.
 */

int
new_combine_jittered_cubes_sky_range (cpl_imagelist ** cubes,
                   cpl_imagelist  * mergedCube,
                   cpl_imagelist  * mask,
                   cpl_imagelist  * mergedSky,
                   cpl_imagelist  * mergedMsk,
                   cpl_imagelist  * mergeMed,
                   cpl_imagelist  * mergeAvg,
                   cpl_imagelist  * mergeStd,
                   cpl_imagelist  * mergeNc,
                   int        n_cubes,
                   float    * cumoffsetx,
                   float    * cumoffsety,
                   float    * exptimes,
                   char     * kernel_type,
                   const int z_min,
                   const int z_max);

/**
   @name         sinfo_new_combine_jittered_cubes_range()
   @name         cubes: list of jittered cubes to mosaic
   @param        mergedCube: resulting merged cube containing the
                                    jittered cubes
   @param        n_cubes: number of cubes in the list to merge
   @param        cumoffsetx: array of relative x pixel offset
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        cumoffsety: array of relative y pixel offsets
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        exptimes:   exposure times array giving the time
                             in the same sequence as the cube list
   @param        kernel_type: the name of the interpolation kernel
                              that you want to generate using the eclipse
                              routine sinfo_generate_interpolation_kernel()
                              Supported kernels are:
                                     NULL:      default kernel, currently tanh
                                     "default": dito
                                     "tanh":    Hyperbolic tangent
                                     "sinc2":   Square sinc
                                     "lanczos": Lanczos2 kernel
                                     "hamming": Hamming kernel
                                     "hann":    Hann kernel
   @param       z_min         min z of plane  to be combined
   @param       z_max         max z of plane  to be combined
   @result       mask: cube of the same size as combinedCube
                       containing 0 for blank (ZERO pixels) and
                       the summed integration times for overlapping regions
   @doc                merges jittered data cubes to one bigger cube
                       by averaging the overlap regions weighted by
                       the integration times. The x, y size of the final data
                       cube is user given, and should be between 32 and 64
                       pixels, while the relative pixel-offset (sub-pixel
                       accuracy) of the single cubes with respect to the
                       first cube in the list is read from the SEQ CUMOFFSETX,Y
                       fits header keyword.
 */
int
sinfo_new_combine_jittered_cubes_range ( cpl_imagelist ** cubes,
                                 cpl_imagelist  * mergedCube,
                                 cpl_imagelist  * mask,
                                 int        n_cubes,
                                 float    * cumoffsetx,
                                 float    * cumoffsety,
                                 double    * exptimes,
                                 char     * kernel_type,
                                 const int z_min, const int z_max );

/**
   @name         sinfo_new_combine_jittered_cubes_sky_range2()
   @name         cubes: list of jittered cubes to mosaic
   @param        mergedCube: resulting merged cube containing the
                                    jittered cubes
   @param        n_cubes: number of cubes in the list to merge
   @param        cumoffsetx: array of relative x pixel offset
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        cumoffsety: array of relative y pixel offsets
                             with respect to the first frame in the
                             same sequence as the cube list.
   @param        exptimes:   exposure times array giving the time
                             in the same sequence as the cube list
   @param        kernel_type: the name of the interpolation kernel
                              that you want to generate using the eclipse
                              routine sinfo_generate_interpolation_kernel()
                              Supported kernels are:
                                     NULL:      default kernel, currently tanh
                                     "default": dito
                                     "tanh":    Hyperbolic tangent
                                     "sinc2":   Square sinc
                                     "lanczos": Lanczos2 kernel
                                     "hamming": Hamming kernel
                                     "hann":    Hann kernel
   @param       z_min         min z of plane  to be combined
   @param       z_max         max z of plane  to be combined
   @result       mask: cube of the same size as combinedCube
                       containing 0 for blank (ZERO pixels) and
                       the summed integration times for overlapping regions
   @doc                merges jittered data cubes to one bigger cube
                       by averaging the overlap regions weighted by
                       the integration times. The x, y size of the final data
                       cube is user given, and should be between 32 and 64
                       pixels, while the relative pixel-offset (sub-pixel
                       accuracy) of the single cubes with respect to the
                       first cube in the list is read from the SEQ CUMOFFSETX,Y
                       fits header keyword.
 */

int
new_combine_jittered_cubes_sky_range2 (cpl_imagelist ** cubes,
                   cpl_imagelist  * mergedCube,
                   cpl_imagelist  * mask,
                   cpl_imagelist  * mergedSky,
                   cpl_imagelist  * mergedMsk,
                   cpl_imagelist  * mergeMed,
                   cpl_imagelist  * mergeAvg,
                   cpl_imagelist  * mergeStd,
                   cpl_imagelist  * mergeNc,
                   int        n_cubes,
                   float    * cumoffsetx,
                   float    * cumoffsety,
                   double    * exptimes,
                   char     * kernel_type,
                   const int z_min,
                   const int z_max);


/**
   @name     sinfo_new_interpol_cube_simple()
   @param    cube: 1 allocated cube
   @param    badcube: bad pixel mask cube (0: bad, 1: good pixel)
   @param    maxdist: maximal pixel distance from bad pixel
                      to search for good pixels, don't make this
                      value too big!
   @return   interpolated cube, and corrected bad pixel mask cube
   @doc      interpolates bad pixel of an object cube if a bad pixel
             mask cube is available by using the nearest neighbors
             in 3 dimensions.
 */
cpl_imagelist *
sinfo_new_interpol_cube_simple( cpl_imagelist * cube,
                              cpl_imagelist * badcube,
                              int       maxdist ) ;

/**
   @name     sinfo_new_combine_cubes()
   @param    cubes: list of jittered cubes to mosaic
   @param    mergedCube: resulting merged cube containing the
                                      jittered cubes
   @param    n_cubes: number of cubes in the list to merge
   @param    cumoffsetx: array of relative x pixel offsets with respect to
                         the first frame in the same sequence as the cube list.
   @param    cumoffsety: array of relative y pixel offsets with respect to
                         the first frame in the same sequence as the cube list.
   @param    factor:     sigma factor beyond which pixels are thrown away.
   @param    kernel_type: the name of the interpolation kernel that you want
                          to generate using the routine
                          sinfo_generate_interpolation_kernel()
                          Supported kernels are:
                                     NULL:      default kernel, currently tanh
                                     "default": dito
                                     "tanh":    Hyperbolic tangent
                                     "sinc2":   Square sinc
                                     "lanczos": Lanczos2 kernel
                                     "hamming": Hamming kernel
                                     "hann":    Hann kernel
   @return mask: cube of the same size as combinedCube
                              containing 0 for blank (ZERO pixels) and
                              n used pixels for overlapping regions
   @doc             merges jittered data cubes to one bigger cube
                    by taking the sinfo_median in each pixel and throw away the
                    high deviation pixels (bigger than factor * sigma)
                    The x, y size of the final data
                    cube is user given, and should be between 32 and 64
                    pixels, while the relative pixel-offset (sub-pixel
                    accuracy) of the single cubes with respect to the
                    first cube in the list is read from the SEQ CUMOFFSETX,Y
                    fits header keyword.
 */

cpl_imagelist *
sinfo_new_combine_cubes ( cpl_imagelist ** cubes,
                         cpl_imagelist  * mergedCube,
                         int        n_cubes,
                         float    * cumoffsetx,
                         float    * cumoffsety,
                         float      factor,
                         char     * kernel_type ) ;

/**
@name sinfo_new_bin_cube
@param cu input cube
@param xscale scale on X axis
@param yscale scale on Y axis
@param xmin   minimum X
@param xmax   maximum X
@param ymin   minimum Y
@param ymax   maximum Y

*/
cpl_imagelist *
sinfo_new_bin_cube(cpl_imagelist *cu,
                   int xscale,
                   int yscale,
                   int xmin,
                   int xmax,
                   int ymin,
                   int ymax);

/**
@name sinfo_new_scale_cube
@param cu input cube
@param xscale scale on X axis
@param yscale scale on Y axis
@param    kernel_type: the name of the interpolation kernel that you want
                          to generate using the routine
                          sinfo_generate_interpolation_kernel()
                          Supported kernels are:
                                     NULL:      default kernel, currently tanh
                                     "default": dito
                                     "tanh":    Hyperbolic tangent
                                     "sinc2":   Square sinc
                                     "lanczos": Lanczos2 kernel
                                     "hamming": Hamming kernel
                                     "hann":    Hann kernel

*/

cpl_imagelist *
sinfo_new_scale_cube(cpl_imagelist *cu,
                     float xscale,
                     float yscale,
                     char * kernel_type);


/**
 @short shifts an imagelist by a given amount to integer pixel accuracy
 @name sinfo_cube_zshift
 @param cube  input cube to be shifted
 @param shift amount of z shift to be applied
 @param rest  amout of fractional shift remaining (<1)

*/

cpl_imagelist *
sinfo_cube_zshift(const cpl_imagelist * cube,
                  const double shift,
                  double* rest);

/**
 @short shifts an imagelist by a given amount to sub-pixel accuracy
 @name sinfo_cube_zshift
 @param cube  input cube to be shifted
 @param shift amount of z shift to be applied
 @param order polynomial order

*/

cpl_imagelist *
sinfo_cube_zshift_poly(const cpl_imagelist * cube,
                       const double shift,
                       const int    order);

/**
 @short shifts an imagelist by a given amount to sub-pixel accuracy
 @name sinfo_cube_zshift
 @param cube  input cube to be shifted
 @param shift amount of z shift to be applied

*/

cpl_imagelist *
sinfo_cube_zshift_spline3(const cpl_imagelist * cube,
                          const double shift);


int
sinfo_coadd_with_ks_clip_optimized(const int z_min,
			const int z_max,
			const int n_cubes,
			const double kappa,
			int* llx,
			int* lly,
                        double* exptimes,
			cpl_imagelist* mask,
			cpl_imagelist* mergedCube,
                        cpl_imagelist** tmpcubes);

double sinfo_kappa_sigma_array_with_mask(
		cpl_array* parray,
		int szArray,
		const double kappa,
		cpl_image* imMask,
		const double* exptimes,
		int x, int y, double mas_adjustment
		/*, double* val_msk_sum*/);

cpl_error_code
sinfo_imagelist_reject_value(cpl_imagelist* iml,cpl_value value);

#endif /*!SINFO_NEW_CUBE_OPS_H*/



/*--------------------------------------------------------------------------*/
