#ifndef SINFO_SPECTRUM_OPS_H
#define SINFO_SPECTRUM_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
*
* "@(#) $Id: sinfo_spectrum_ops.h,v 1.4 2007-06-06 07:10:45 amodigli Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* schreib  25/05/00  created
*/

/************************************************************************
 * sinfo_spectrum_ops.h
 * spectral sinfo_vector routines
 *----------------------------------------------------------------------
 */

#define  SPEED_OF_LIGHT 2.99792458e8
#define  PLANCK            6.62606876e-34
#define  BOLTZMANN      1.3806503e-23

/*
 * header files
 */

#include <cpl.h>
#include "sinfo_focus.h"
#include "sinfo_recipes.h"
#include "sinfo_new_cube_ops.h"
#include "sinfo_msg.h"
/*----------------------------------------------------------------------------
 *                        Function ANSI C prototypes
 *--------------------------------------------------------------------------*/


/**
@brief convert an image in a table spectrum 
@param spc       input image spectrum
@param filename  input filename
@param tbl       output table
*/
int 
sinfo_stectrum_ima2table(
                 const cpl_image* spc,
                 const char* filename,
                 cpl_table** tbl);

/**
@brief clean averaging routine for a reduced data to get a 
       better spectral S/N only for a rectangular aperture.
@name sinfo_new_cleanmean_rectangle_of_cube_spectra()
@param cube: 1 allocated cube, 
@param llx, 
@param lly, 
@param urx, 
@param ury: lower left and upper right position of rectangle in x-y plane ,
            image coordinates 0...
@return result spectrum sinfo_vector 
*/

Vector * 
sinfo_new_cleanmean_rectangle_of_cube_spectra( cpl_imagelist * cube,
                                          int llx,
                                          int lly,
                                          int urx,
                                          int ury,
                                          float lo_reject,
                            float hi_reject );
/**
@brief clean averaging routine for a reduced data to get 
       a better spectral S/N only for a circular aperture.
@name sinfo_new_cleanmean_circle_of_cube_spectra()
@param cube: 1 allocated cube, 
@param centerx, 
@param centery: center pixel of circular aperture in image coordinates
@param radius: integer radius of circular aperture
@return result spectrum sinfo_vector 
*/

Vector * 
sinfo_new_cleanmean_circle_of_cube_spectra( cpl_imagelist * cube,
                                  int       centerx,
                                  int       centery,
                                  int       radius,
                                  float     lo_reject,
                             float     hi_reject );
/**
   @name sinfo_new_div_image_by_spectrum()
   @param  image resampled image
   @param  spectrum resampled spectrum in image format
   @result resulting image
   @memo   divides a resampled image with a resampled spectrum in the same 
           spectral range that means all image columns are multiplied with 
           the same spectrum
*/

cpl_image * 
sinfo_new_div_image_by_spectrum( cpl_image * image, cpl_image * spectrum ) ;

/**
@brief frees memory of a sinfo_vector
@name sinfo_free_svector()
@param sinfo_vector to destroy
@return nothing 
*/

void 
sinfo_free_svector( Vector **svector );

/**
   @name     sinfo_new_vector()
   @memo allocates memory for a new sinfo_vector
   @param    number of sinfo_vector elements
   @result     sinfo_vector
*/

Vector * 
sinfo_new_vector( ulong32 n_elements ) ;


/**
   @name   sinfo_new_destroy_vector()
   @param  sinfo_vector to destroy
   @result nothing
   @memo frees memory of a sinfo_vector
*/

void 
sinfo_new_destroy_vector( Vector *sinfo_vector ) ;

/**
   @name   sinfo_new_vector_to_image()
   @param spectrum spectral vector that should be converted to a fits image
   @result mage with lx = 1 and ly = length of sinfo_vector
   @doc   converts a spectral vector to a fits image
   @note the sinfo_vector object spectrum is destroyed
*/


cpl_image * 
sinfo_new_vector_to_image( Vector * spectrum ) ;

/**
   @name  sinfo_imageToVector()
   @memo converts a fits image to a spectral sinfo_vector
   @param spectrum   1-D Fits image that should be converted to a 
                     spectral vector
   @result  spectral sinfo_vector with length ly
   @note input image is destroyed
*/

Vector * 
sinfo_new_image_to_vector( cpl_image * spectrum ) ;


/**
   @name sinfo_new_extract_spectrum_from_resampled_flat()
   @memo   builds one spectrum in a fits image out of a resampled
           flatfield frame by taking a clean mean along the spatial pixels
   @param resflat: resampled halogen lamp frame, bad pixel corrected
   @param loreject
   @param hireject percentage of extreme low and high intensity values
                   to be rejected from averaging
   @result fits image that contains the final halogen lamp spectrum
*/

cpl_image * 
sinfo_new_extract_spectrum_from_resampled_flat( cpl_image * resflat,
                                             float      loreject,
                                             float      hireject ) ;

/**
   @name  sinfo_new_multiply_image_with_spectrum()
   @param  image: resampled image
   @param  spectrum: resampled spectrum in image format
   @result resulting image
   @doc    multiplys a resampled image with a resampled spectrum
           (calibrated halogen lamp spectrum) in the same spectral range
           that means all image columns are multiplied with the same spectrum
*/

cpl_image * 
sinfo_new_multiply_image_with_spectrum(cpl_image * image,
                                       cpl_image * spectrum ) ;

/**
   @name   sinfo_new_optimal_extraction_from_cube()
   @param  cube: input data cube
   @param  llx lower left edge x point of 2d Gaussian fitting box.
   @param  lly lower left edge y point of 2d Gaussian fitting box.
   @param  halfbox_x half width of a box inside which
                                              a 2D-Gaussian fit is carried out
   @param  halfbox_y half width of a box inside which
                                              a 2D-Gaussian fit is carried out
   @param  fwhm_factor factor applied to the found fwhms of a 2D-Gaussian
                       fit, defines the radius of the aperture inside which the
                       spectral extraction is carried out (default: 0.6).
   @param  backvariance (readnoise^2 + dark current variance) needed to 
                        determine the noise variance of the background. 
                        Must be given in counts/sec.
   @param  sky          estimated sky variance in counts/sec
   @param  gain         conversion factor electrons/count
   @param  exptime     total exposure time
   @result  resulting spectrum stored in a 1D-image
   @doc     does the optimal extraction of a standard star spectrum
            according to the equation:
            S = sum { (P^2 / V) * (I - B) / P } / sum{ P^2 / V }
            S: spectral flux at a particular wavelength
            P: normalized PSF (determined by a 2D-Gaussian fit)
            I: pixel value
            B: background pixel value determined by the 
               background parameter of the 2D-Gaussian fit
            V: estimated variance of a pixel: 
            V = [R^2 + D + sky + I,c/exptime]/gain
            where R is the read noise, and D the sinfo_dark current variance.
            backvariance is R^2 + D in counts/sec. 
            I,c is the source intensity in counts
            Remember: 
            sigma,e[e-] = gain[e/count] * sigma,c [counts] 
                        = sqrt(I,e) = sqrt(gain*I,c)
                      => V,c = sigma,c^2 = sigma,e^2/gain^2
                      => sigma,c = sqrt(I,c/gain) => V,c = I,c/gain
*/


cpl_image * 
sinfo_new_optimal_extraction_from_cube( cpl_imagelist * cube,
                                      int llx,
                                      int lly,
                                      int halfbox_x,
                                      int halfbox_y,
                                      float fwhm_factor,
                                      float backvariance,
                                      float sky,
                                      float gain,
                                      float exptime,
                                      const char* name,
                                      cpl_table** spectrum,
                                      int qc_info,
                                      int* check2) ;

/**
   @name       sinfo_new_extract_sky_from_cube()
   @param      cube reduced cube from sky spider observation
   @param      loReject
   @param      hiReject: fraction (percentage) of the extreme high and low
                         sky spectrum values that are rejected before
                         averaging the found sky spectra.
   @param      position: end pixel positions of the straight line in the image
                         dividing the sky from the object pixels.
   @param      tolerance: pixel tolerance which are not considered and 
                          subtracted from the diagonal line to be sure to get 
                          a clean sky, default: 2
   @param      posindicator: indicates in which sinfo_edge of the field of 
                             view the sky is projected. output of 
                             spiffi_get_spiderposindex() in fitshead.c
   @result resulting averaged sky spectrum
   @doc    extracts a sky spectrum from a reduced sky spider observation, that
           means from a data cube. Therefore, the position of the sky within 
           the field of view must be first read from the fits header. A pixel 
           tolerance is subtracted. The found sky spectra are averaged by 
           rejecting the extreme high and low values.
*/

Vector * 
sinfo_new_extract_sky_from_cube( cpl_imagelist * cube,
                             float     loReject,
                             float     hiReject,
                             int     * position,
                             int       tolerance,
                             int       posindicator ) ;

/**
   @name    sinfo_new_sum_rectangle_of_cube_spectra()
   @memo averaging routine for a reduced data to get a better spectral S/N
         only for a rectangular aperture.
   @param   cube: 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 
                                       of rectangle in x-y plane ,
                                         
   @result spectrum vector
*/

Vector * 
sinfo_new_sum_rectangle_of_cube_spectra( cpl_imagelist * cube,
                                     int llx,
                                     int lly,
                                     int urx,
                                     int ury ) ;

/**
   @name   sinfo_new_sum_circle_of_cube_spectra()
   @memo averaging routine for a reduced data to get a better spectral S/N
         only for a circular aperture.
   @param  cube: 1 allocated cube,
   @param  centerx x center pixel of circular aperture in image coordinates
   @param  centery y center pixel of circular aperture in image coordinates
   @param  radius integer radius of circular aperture
   @result spectrum sinfo_vector
*/

Vector * 
sinfo_new_sum_circle_of_cube_spectra( cpl_imagelist * cube,
                                  int       centerx,
                                  int       centery,
                                  int       radius ) ;


/**
   @name sinfo_new_mean_rectangle_of_cube_spectra()
   @memo averaging routine for a reduced data to get a better spectral S/N
         only for a rectangular aperture.
   @param  cube: 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 
                                       of rectangle in x-y plane ,
   @return  result spectrum vector
*/

Vector * 
sinfo_new_mean_rectangle_of_cube_spectra( cpl_imagelist * cube,
                                     int llx,
                                     int lly,
                                     int urx,
                                     int ury ) ;

/**
   @name   sinfo_new_mean_circle_of_cube_spectra()
   @memo averaging routine for a reduced data to get a better spectral S/N
         only for a circular aperture.
   @param  cube: 1 allocated cube
   @param  centerx center pixel of circular aperture in image coordinates
   @param  centery center pixel of circular aperture in image coordinates
   @param  radius integer radius of circular aperture
   @result result spectrum vector
*/

Vector * 
sinfo_new_mean_circle_of_cube_spectra( cpl_imagelist * cube,
                                  int       centerx,
                                  int       centery,
                                  int       radius ) ;

/**
   @name   sinfo_new_blackbody_spectrum()
   @memo   computes a blackbody spectral intensity distribution
           (W/(m^2 lambda ster))
   @param  templateSpec spectrum of a standard star
                        (1-d image with fits header)
   @param  temp blackbody temperature in Kelvin (standard Star temp),
   @return resulting spectrum sinfo_vector
*/

Vector * 
sinfo_new_blackbody_spectrum( char * templateSpec, double temp ) ;

/**
   @name    sinfo_new_median_rectangle_of_cube_spectra()
   @memo averaging routine for a reduced data to get a better spectral S/N
         only for a rectangular aperture.
   @param   cube: 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 
                                       of rectangle in x-y plane ,
   @result  result spectrum vector
*/

Vector * 
sinfo_new_median_rectangle_of_cube_spectra( cpl_imagelist * cube,
                                             int llx,
                                             int lly,
                                             int urx,
                                             int ury ) ;

/**
   @name  sinfo_new_median_circle_of_cube_spectra()
   @memo averaging routine for a reduced data to get a better spectral S/N
         only for a circular aperture.
   @param cube: 1 allocated cube,
   @param  centerx center pixel of circular aperture in image coordinates
   @param  centery center pixel of circular aperture in image coordinates
   @param  radius integer radius of circular aperture
   @result result spectrum vector
*/

Vector * 
sinfo_new_median_circle_of_cube_spectra( cpl_imagelist * cube,
                                  int       centerx,
                                  int       centery,
                                  int       radius ) ;


/**
   @name   sinfo_new_clean_mean_rectangle_of_cube_spectra()
   @memo averaging routine for a reduced data to get a better spectral S/N
         only for a rectangular aperture.
   @param  cube: 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 
                                       of rectangle in x-y plane ,
   @result  result spectrum vector
*/

Vector * 
sinfo_new_clean_mean_rectangle_of_cube_spectra( cpl_imagelist * cube,
                                             int llx,
                                             int lly,
                                             int urx,
                                             int ury,
                                             float lo_reject,
                                             float hi_reject ) ;

/**
   @name    sinfo_new_clean_mean_circle_of_cube_spectra()
   @memo averaging routine for a reduced data to get a better spectral S/N
         only for a circular aperture.
   @param       cube: 1 allocated cube,
   @param  centerx center pixel of circular aperture in image coordinates
   @param  centery center pixel of circular aperture in image coordinates
   @param  radius integer radius of circular aperture
   @result result spectrum vector
 ---------------------------------------------------------------------------*/

Vector * 
sinfo_new_clean_mean_circle_of_cube_spectra( cpl_imagelist * cube,
                                  int       centerx,
                                  int       centery,
                                  int       radius,
                                  float     lo_reject,
                                  float     hi_reject ) ;

/**
   @name sinfo_new_shift_array()
   @memo   shifts an array by a sub-pixel shift value using a tanh
           interpolation kernel
   @param  input input array,
   @param  n_elements number of elements in input array
   @param  shift sub-pixel shift value (must be < 1.)
   @param  ker    interpolation kernel
   @result resulting float array
*/

float * 
sinfo_new_shift_array(float * input,int n_elements,float shift,double * ker ) ;

#endif /*!SINFO_SPECTRUM_OPS_H*/

