#ifndef SINFO_WAVECAL_H
#define SINFO_WAVECAL_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_wavecal.h,v 1.5 2007/06/06 07:10:46 amodigli Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* schreib  13/07/00  created
*/

/************************************************************************
 * sinfo_wavecal.h
 * routines needed for wavelength calibration
 *----------------------------------------------------------------------
 */

/*
 * header files
 */
#include <cpl.h>
#include "sinfo_spectrum_ops.h"

/*
 * function prototypes
 */

/**
   @name    sinfo_new_wave_map_slit()
   @param   acoefs fit coefficient sinfo_matrix: output of 
            sinfo_coeffsCrossSlitFit()
   @param  n_acoefs number of acoefs, polynomial order + 1
   @param  n_rows number of final image rows
   @param  n_columns number of final image columns
   @return wavemap calibration map image
*/

cpl_image * 
sinfo_new_wave_map_slit ( float ** acoefs,
                         int      n_acoefs,
                         int      n_rows,
                         int      n_columns ) ;

/**
   @name       sinfo_new_wave_cal()
   @param      par array of the resulting FitParams data structure
   @param      abuf array of smoothed coefficients of the polynomial fit 
               along the columns abuf[index][column].
   @param      image        merged image from a calibration emission lamp,
   @param      par          fit parameters data structure storage
   @param      abuf         buffer array for fit coefficients 
                            abuf[index][column]
   @param      row_clean resulting list of the row indices but without the
                         lines that are too close to each other for the fit
                         output of sinfo_findLines()
   @param      wavelength_clean corrected wavelength list corresponding to
                                the row_clean array
                                output of sinfo_findLines()
   @param      n_found_lines output of sinfo_findLines(): 
                             total number of found emission lines
   @param      dispersion   dispersion of spectrum: micron per pixel
   @param      halfWidth    half width of the box where the line must sit
   @param      minAmplitude minimum amplitude of the Gaussian to do the fit
   @param      max_residual maximum residual value, beyond that value
                            the polynomial lambda-position fit is rejected.
   @param      fwhm         first guess for the full width of half maximum
                            of the sinfo_gaussian line fit
   @param      n_a_fitcoefs number of fit coefficients for the single
                            column fits: lambda-position
   @param      n_b_fitcoefs number of fit coefficients for the fits of
                            the single a coefficients across the columns
   @param      sigmaFactor  factor of the standard deviation of the determined
                            polynomial coefficients of the columns beyond
                            which these coefficients are not used to carry out
                            the polynomial fit across the columns.
   @param      pixel_dist   estimate of minimal pixel distance in spectral 
                            direction between slitlets
   @param      pixel_tolerance maximum tolerated difference between estimated
                   and fitted line positions.
   @return     wavelength map image.
   @doc   this routine takes an image from a calibration emission lamp and 
          delivers the smoothed fit coefficients of a polynomial fit along 
          the columns of the line positions as output. This routine expects 
          Nyquist sampled spectra (either an interleaved image or an image 
          convolved with an appropriate function in spectral direction)
*/

cpl_image * 
sinfo_new_wave_cal(cpl_image   * image,
                    FitParams ** par ,
                    float     ** abuf,
                    int          n_slitlets,
                    int       ** row_clean,
                    float     ** wavelength_clean,
                    int        * n_found_lines,
                    float        dispersion,
                    int          halfWidth,
                    float        minAmplitude,
                    float        max_residual,
                    float        fwhm,
                    int          n_a_fitcoefs,
                    int          n_b_fitcoefs,
                    float        sigmaFactor,
                    float        pixel_dist,
            float        pixel_tolerance ) ;


/**
   @name       sinfo_new_spred_wave_cal()
   @param      par array of the resulting FitParams data structure
   @param      abuf array of smoothed coefficients of the polynomial fit 
               along the columns abuf[index][column].
   @param      image        merged image from a calibration emission lamp,
   @param      par          fit parameters data structure storage
   @param      abuf         buffer array for fit coefficients 
                            abuf[index][column]
   @param      row_clean resulting list of the row indices but without the
                         lines that are too close to each other for the fit
                         output of sinfo_findLines()
   @param      wavelength_clean corrected wavelength list corresponding to
                                the row_clean array
                                output of sinfo_findLines()
   @param      n_found_lines output of sinfo_findLines(): 
                             total number of found emission lines
   @param      dispersion   dispersion of spectrum: micron per pixel
   @param      halfWidth    half width of the box where the line must sit
   @param      minAmplitude minimum amplitude of the Gaussian to do the fit
   @param      max_residual maximum residual value, beyond that value
                            the polynomial lambda-position fit is rejected.
   @param      fwhm         first guess for the full width of half maximum
                            of the sinfo_gaussian line fit
   @param      n_a_fitcoefs number of fit coefficients for the single
                            column fits: lambda-position
   @param      n_b_fitcoefs number of fit coefficients for the fits of
                            the single a coefficients across the columns
   @param      sigmaFactor  factor of the standard deviation of the determined
                            polynomial coefficients of the columns beyond
                            which these coefficients are not used to carry out
                            the polynomial fit across the columns.
   @param      pixel_dist   estimate of minimal pixel distance in 
                            spectral direction between slitlets
   @param      pixel_tolerance maximum tolerated difference between estimated
                   and fitted line positions.
   @return     wavelength map image.
   @doc   this routine takes an image from a calibration emission lamp and 
          delivers the smoothed fit coefficients of a polynomial fit along 
          the columns of the line positions as output. This routine expects 
          Nyquist sampled spectra (either an interleaved image or an image 
          convolved with an appropriate function in spectral direction)
*/
 cpl_image * sinfo_new_spred_wave_cal(cpl_image   * image,
                     FitParams ** par ,
                     float     ** abuf,
                     int          n_slitlets,
                     int       ** row_clean,
                     float     ** wavelength_clean,
                     int        * n_found_lines,
                     float        dispersion,
                     int          halfWidth,
                     float        minAmplitude,
                     float        max_residual,
                     float        fwhm,
                     int          n_a_fitcoefs,
                     int          n_b_fitcoefs,
                     float        sigmaFactor,
                     float        pixel_dist,
                     float        pixel_tolerance,
                     float **sinfo_slit_pos ) ;


/**
   @name   sinfo_new_check_for_fake_lines()
   @param  par array of the fit parameter data structure FitParams
   @param  dispersion estimated dispersion
   @param  wavelength_clean: corrected wavelength list
   @param  row_clean corrected row list corresponding to the wavelength list
   @param  n_found_lines array of numbers of found lines of each column
   @param  n_columns total number of image columns
   @param  pixel_tolerance maximum tolerated difference between estimated
               and fitted line positions.
   @return par corrected FitParams 0 in case of success -1 in case of error
   @doc this routine searches for successfully fitted fake lines like
    bad pixels by comparing the found line positons with estimated 
        template positions. This routine should be inserted in the wavelength 
        calibration routine just after the sinfo_fitLines() routine.
*/

int 
sinfo_new_check_for_fake_lines ( FitParams ** par,
                       float        dispersion,
                        float     ** wavelength_clean,
            int       ** row_clean,
            int        * n_found_lines,
            int          n_columns,
            float        pixel_tolerance ) ;


/**
   @name   sinfo_new_create_shifted_slit_wavemap()
   @param  lineIm  new shifted emission line frame
   @param  coeffs  calculated polynomial coefficients,
                   output of sinfo_coeffsCrossSlitFit()
   @param  n_fitcoeffs  number of polynomial coefficients, order + 1
   @param  wavelength   wavelength list from line list
   @param  intensity    corresponding line intensity from line list
   @param  n_lines      number of lines in the list
   @param  magFactor    magnification factor for help arrays
   @return wavelength map
   @doc This routine cross-correlates a shifted emission line frames
        and determines the shift to the old one which is given by
        its polynomial coefficients. Then the a0 coefficients is recalculated 
        and afterwards a new wavelength calibration map is generated using the
        already calculated smoothed polynomial coefficients.
*/

cpl_image * 
sinfo_new_create_shifted_slit_wavemap (cpl_image * lineIm,
                                      float    ** coeffs,
                                      int      n_fitcoeffs,
                                      float  * wavelength,
                                      float  * intensity,
                                      int      n_lines,
                                      int      magFactor ) ;
/**
   @name  sinfo_new_create_shifted_slit_wavemap2()
   @param lineIm       new shifted emission line frame
   @param coeffs       calculated polynomial coefficients,
                       output of sinfo_coeffsCrossSlitFit()
   @param n_fitcoeffs  number of polynomial coefficients, order + 1
   @param wavelength   wavelength list from line list
   @param intensity    corresponding line intensity from line list
   @param n_lines      number of lines in the list
   @param magFactor    magnification factor for help arrays
   @param dispersion   estimate of the dispersion
   @param pixel_dist   estimate of minimal pixel distance in spectral 
                       direction between slitlets
   @return wavelength map
   @doc This routine cross-correlates a shifted emission line frames
        and determines the shift to the old one which is given by
        its polynomial coefficients.
        Then the a0 coefficients is recalculated and afterwards
        a new wavelength calibration map is generated using the
        already calculated smoothed polynomial coefficients.
*/


cpl_image * 
sinfo_new_create_shifted_slit_wavemap2 (cpl_image * lineIm,
                                      float    ** coeffs,
                                      int      n_fitcoeffs,
                                      float  * wavelength,
                                      float  * intensity,
                                      int      n_lines,
                                      int      magFactor,
                                      float    dispersion,
                                      float    pixel_dist ) ;


/**
   @name    sinfo_new_create_shifted_slit_wavemap3()
   @param   lineIm       new shifted emission line frame
   @param   coeffs       calculated polynomial coefficients,
                         output of sinfo_coeffsCrossSlitFit()
   @param   n_fitcoeffs  number of polynomial coefficients, order + 1
   @param   wavelength   wavelength list from line list
   @param   intensity    corresponding line intensity from line list
   @param   n_lines      number of lines in the list
   @param   magFactor    magnification factor for help arrays
   @result  wavelength map
   @doc     This routine cross-correlates a shifted emission line frames
            and determines the shift to the old one which is given by
            its polynomial coefficients.
            Then the a0 coefficients is recalculated by using a clean mean
            of the determined offset (shift) over the whole frame
            and afterwards a new wavelength calibration map is generated using 
            the already calculated smoothed polynomial coefficients.
*/


cpl_image * 
sinfo_new_create_shifted_slit_wavemap3 (cpl_image * lineIm,
                                      float    ** coeffs,
                                      int      n_fitcoeffs,
                                      float  * wavelength,
                                      float  * intensity,
                                      int      n_lines,
                                      int      magFactor ) ;


/**
   @name    sinfo_new_check_line_positions()
   @param   lineIm       new shifted emission line frame
   @param   coeffs       calculated polynomial coefficients,
                         output of sinfo_coeffsCrossSlitFit()
   @param   n_fitcoeffs  number of polynomial coefficients, order + 1
   @param   guess_disp1  guess dispersion (to have positioning error in pix)
   @param   par          fit parameters
   @doc     clean averaged position error (shift) of the brightest lines in 
            the emission line image with respect to the expected positions 
            from the wavelength calibration (error in the wavelength regime 
            (microns)).
   @doc     This routine determines the clean averaged error (shift) of the 
            brightest lines in the emission line image with respect to the 
            expected positions from the wavelength calibration. The error is 
            given in the wavelength regime (microns).
            It should give the user an impression for the quality
            of the wavelength calibration.
*/

float sinfo_new_check_line_positions ( cpl_image     * lineIm,
                       float       ** coeffs,
                       int            n_fitcoeffs,
                       float           guess_disp1,
                       FitParams   ** par );

/**
   @name   sinfo_new_check_correlated_line_positions()
   @param  lineIm       new shifted emission line frame
   @param  coeffs       calculated polynomial coefficients,
                        output of sinfo_coeffsCrossSlitFit()
   @param  n_fitcoeffs  number of polynomial coefficients, order + 1
   @param  wavelength   wavelength list from line list
   @param  intensity    corresponding line intensity from line list
   @param  n_lines      number of lines in list
   @param  fwhm         guess value for full width of half maximum of Gaussian
   @param  width        half width of the box where the line must sit
   @param  min_amplitude minimum line amplitude with respect to the background
                         to do the fit
   @param  par           fit parameters
   @return clean averaged position error (shift) of the brightest lines in the
           emission line image with respect to the expected positions from the 
           wavelength calibration (error in the wavelength regime (microns)).
   @doc    This routine determines the clean averaged error (shift) of the 
           brightest lines in the emission line image with respect to the 
           expected positions from the wavelength calibration. The error is 
           given in the wavelength regime (microns).
           It should give the user an impression of the quality
           of the wavelength calibration.
*/

float 
sinfo_new_check_correlated_line_positions (cpl_image     * lineIm,
                                     float       ** coeffs,
                                     int            n_fitcoeffs,
                                     float        * wavelength,
                                     float        * intensity,
                                     int            n_lines,
                                     float          fwhm,
                                     float          width,
                                     float          min_amplitude,
                                     float          dispersion,
                                     FitParams   ** par ) ;



#endif /*!SINFO_WAVECAL_H*/
