/*
 * 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_absolute.h,v 1.3 2007-08-20 10:01:05 amodigli Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* schreib  14/11/00  created
*/
#ifndef SINFO_ABSOLUTE_H
#define SINFO_ABSOLUTE_H
/**
 * @addtogroup sinfo_absolute
 *
 */
/*----------------------------------------------------------------------------*/


/************************************************************************
 * absolute.h
 * routines to determine the absolute positions of the slitlets out of 
 * an emission line frame
 *----------------------------------------------------------------------
 */

/*
 * header files
 */

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

/**
   @name sinfo_new_edge()
   input: position array xdat, parameter list parlist, number of
                        parameters in the list npar
   @param ndat number of data elements
   The parameters are:
   @param  parlist(0) pos1
   @param  parlist(1) pos2
   @param  parlist(2) intensity left
   @param  parlist(3) intensity right
   @return function value of a linear slope function that means a function 
           with a constant intensity value for xdat values smaller than 
           pos1, linear increasing between pos1 and pos2, constant intensity 
           value for xdat values greater than pos2
   @memo  calculates the value of a slope function with parameters
          parlist at the position xdat
 */

float 
sinfo_new_edge(float * xdat, float * parlist/*, int * npar, int * ndat */) ;

/**
   @name  sinfo_new_boltz()
   In: position array xdat, parameter list parlist. The parameters are:
   @param parlist(0) background1
   @param parlist(1) background2
   @param parlist(2) central position
   @param parlist(3) width
   @return function value of a Boltzmann function that is
   y = (parlist(0)-parlist(1))/(1+exp((x-parlist(2))/parlist(3))) + parlist(1)
   @memo calculates the value of a Boltzmann function with parameters parlist 
         at the position xdat
*/

float 
sinfo_new_boltz ( float * xdat, float * parlist ) ;

/**
   @name sinfo_new_edge_deriv()
   In : position array xdat, parameter list parlist, number of parameters in 
        the list npar. The parameters are:
   @param parlist(0) pos1
   @param parlist(1) pos2
   @param parlist(2) intensity left
   @param parlist(3) intensity right
   derivative value of a hat function at position xdat: dervs
   @param dervs[0] partial derivative by pos1
   @param dervs[1] partial derivative by pos2
   @param dervs[2] partial derivative by intensity left
   @param dervs[3] partial derivative by intensity right
   @return void
   @memo calculates the partial derivatives for a slope function with
         parameters parlist at position xdat
*/

void 
sinfo_new_edge_deriv(float * xdat, 
                     float * parlist, float * dervs/*, int * npar */) ;

/**
   @name sinfo_new_boltz_deriv()
   In : position array xdat, parameter list parlist. The parameters are:
   @param parlist(0) background1
   @param parlist(1) background2
   @param parlist(2) central position
   @param parlist(3) width
   derivative value of a Boltzmann function at position xdat: dervs
   @param dervs[0] partial derivative by background1
   @param dervs[1] partial derivative by background2
   @param dervs[2] partial derivative by central position
   @param dervs[3] partial derivative by the width
   @return void
   @memo calculates the partial derivatives for a Boltzmann function with
         parameters parlist at position xdat
*/

void 
sinfo_new_boltz_deriv( float * xdat, float * parlist, float * dervs ) ;

/**
   @name sinfo_new_lsqfit()
   @param xdat  position, coordinates of data points.
   @param xdat is 2 dimensional: XDAT ( XDIM, NDAT )
   @param xdim  dimension of fit
   @param ydat  data points
   @param wdat  weights for data points
   @param ndat  number of data points
   @param fpar  on input contains initial estimates of the
                parameters for non-linear fits, on output the
                fitted parameters.
   @param epar  contains estimates of the errors in fitted parameters
   @param mpar  logical mask telling which parameters are free (non-zero)
                and which parameters are fixed (0)
   @param npar  number of function parameters ( free + fixed )
   @param tol   relative tolerance. lsqfit stops when successive iterations
                fail to produce a decrement in reduced chi-squared less
                than tol. If tol is less than the minimum tolerance
                possible, tol will be set to this value. This means
                that maximum accuracy can be obtained by setting
                tol = 0.0.
   @param its   maximum number of iterations
   @param lab   mixing parameter, lab determines the initial weight
                of steepest descent method relative to the Taylor method
                lab should be a small value (i.e. 0.01). lab can only
                be zero when the partial derivatives are independent
                of the parameters. In fact in this case lab should be
                exactly equal to zero.
   @return number of iterations needed to achieve convergence
           according to tol. When this number is negative, the fitting
           was not continued because a fatal error occurred:
           #             -1 too many free parameters, maximum is 32
           #             -2 no free parameters
           #             -3 not enough degrees of freedom
           #             -4 maximum number of iterations too small to obtain
                           a solution which satisfies tol.
           #             -5 diagonal of sinfo_matrix contains elements 
                            which are zero
           #             -6 determinant of the coefficient sinfo_matrix is zero
           #             -7 square root of a negative number
   @doc this is a routine for making a least-squares fit of a
        function to a set of data points. The method used is
        described in: Marquardt, J.Soc.Ind.Appl.Math. 11. 431 (1963).
        This method is a mixture of the steepest descent method
        and the Taylor method.
 */

int sinfo_new_lsqfit ( float * xdat,
             int   * xdim,
             float * ydat,
             float * wdat,
             int   * ndat,
             float * fpar,
             float * epar,
             int   * mpar,
             int   * npar,
             float * tol ,
             int   * its ,
             float * lab  ) ;

/**
   @name    sinfo_new_lsqfit_edge()
   @param   xdat  position, coordinates of data points.
                              xdat is 2 dimensional: XDAT ( XDIM, NDAT )
   @param   xdim  dimension of fit
   @param   ydat  data points
   @param   wdat  weights for data points
   @param   ndat  number of data points
   @param   fpar  on input contains initial estimates of the parameters for 
                  non-linear fits, on output the fitted parameters.
   @param   epar  contains estimates of the errors in fitted parameters
   @param   mpar  logical mask telling which parameters are free (non-zero)
                              and which parameters are fixed (0)
   @param   npar  number of function parameters ( free + fixed )
   @param   tol   relative tolerance. sinfo_lsqfit stops when successive 
                  iterations fail to produce a decrement in reduced chi-squared
                  less than tol. If tol is less than the minimum tolerance
                  possible, tol will be set to this value. This means that 
                  maximum accuracy can be obtained by setting tol = 0.0.
   @param   its   maximum number of iterations
   @param   lab   mixing parameter, lab determines the initial weight
                  of steepest descent method relative to the Taylor method
                  lab should be a small value (i.e. 0.01). lab can only
                  be zero when the partial derivatives are independent
                  of the parameters. In fact in this case lab should be
                  exactly equal to zero.
   @return number of iterations needed to achieve convergence according to tol.
                  When this number is negative, the fitting
                  was not continued because a fatal error occurred:
                  #      -1 too many free parameters, maximum is 32
                  #      -2 no free parameters
                  #      -3 not enough degrees of freedom
                  #      -4 maximum number of iterations too small to obtain
                           a solution which satisfies tol.
                  #      -5 diagonal of sinfo_matrix contains elements 
                            which are zero
                  #      -6 determinant of the coefficient sinfo_matrix is zero
                  #      -7 square root of a negative number
   @doc this is a routine for making a least-squares fit of a function to a 
        set of data points. The method used is described in: 
        Marquardt, J.Soc.Ind.Appl.Math. 11. 431 (1963).
        This method is a mixture of the steepest descent method
        and the Taylor method.
 */

int 
sinfo_new_lsqfit_edge ( float * xdat,
                  int   * xdim,
                  float * ydat,
                  float * wdat,
                  int   * ndat,
                  float * fpar,
                  float * epar,
                  int   * mpar,
                  int   * npar,
                  float * tol ,
                  int   * its ,
                  float * lab  ) ;

/**
   @name  sinfo_new_fit_slits_edge()
   @param lineImage  emission line frame
   @param par        fit parameter data structure of fitted lines
   @param sinfo_slit_pos   allocated dummy array for the slitlet 
                           positions [32][4]
   @param box_length pixel length of the row box within the fit is done
   @param y_box      small box in spectral direction within the slitlet may 
                      lie.
   @param diff_tol   maximum tolerable difference of the resulting fit position
                     with respect to the expected position. If difference is
                     greater the expected position is taken.
   @return sinfo_slit_pos  beginning and end position of the slitlets to
                            sub-pixel accuracy
                     #    0  if it worked,
                     #   -1  if there was no line image given,
                     #   -2  if there were no line fit parameters given,
                     #   -3  if there was no dummy array for the slit positions
                            allocated
                     #   -4  if the given box length is impossible
                     #   -5  if the given y box length is impossible
                     #   -6  if the given difference tolerance is too small
                     #   -7  if there were no emission lines found in the first
                             image columns
                     #   -8  if not all slitlets could be found
   @doc fits the beginning and end position of the slitlets by using non-linear
        least square fitting of a hat function fits a step function to the 
        slitlet edges exposed and indicated by the brightest emission lines. 
        To achieve this, the fit parameters are used to find the brightest 
        emission line and to get its position for each column.
        The least squares fit is done by using a box smaller than the size of 
        two slitlets 
 */

int 
sinfo_new_fit_slits_edge( cpl_image   * lineImage,
                  FitParams ** par,
                  float     ** sinfo_slit_pos,
                  int          box_length,
                  float        y_box,
                  float        diff_tol ) ;

/**
   @name sinfo_new_fit_slits_boltz()
   @param lineImage  emission line frame
   @param par        fit parameter data structure of fitted lines
   @param sinfo_slit_pos   allocated dummy array for the slitlet 
                           positions [32][2]
   @param box_length pixel length of the row box within the fit is done
   @param y_box      small box in spectral direction within the slitlet may lie.
   @param diff_tol   maximum tolerable difference of the resulting fit position
                     with respect to the expected position. If difference is
                     greater the expected position is taken.
   @return  sinfo_slit_pos  beginning and end position of the slitlets to
                             sub-pixel accuracy
                     #    0  if it worked,
                     #   -1  if there was no line image given,
                     #   -2  if there were no line fit parameters given,
                     #   -3  if there was no dummy array for the slit positions
                            allocated
                     #   -4  if the given box length is impossible
                     #   -5  if the given y box length is impossible
                     #   -6  if the given difference tolerance is too small
                     #   -7  if there were no emission lines found in the 
                             first image columns
                     #   -8  if not all slitlets could be found
   @doc  fits the beginning and end position of the slitlets by using 
         non-linear least square fitting of a Boltzmann function fits a 
         Boltzmann function to the slitlet edges exposed and indicated
         by the brightest emission lines. To achieve this, the fit
         parameters are used to find the brightest emission line
         and to get its position for each column. The least squares fit is 
         done by using a box smaller than the size of two slitlets 
 */

int 
sinfo_new_fit_slits_boltz( cpl_image   * lineImage,
                   FitParams ** par,
                   float     ** sinfo_slit_pos,
                   int          box_length,
                   float        y_box,
                   float        diff_tol ) ;

/**
   @name  sinfo_new_fit_slits_boltz_single_line()
   @param lineImage  emission line frame
   @param sinfo_slit_pos   allocated dummy array for the slitlet 
                           positions [32][2]
   @param box_length  pixel length of the row box within the fit is done
   @param y_box       small box in spectral direction within the slitlet
                      may lie
   @param low_pos
   @param high_pos pixel positions in spectral direction between which the line
                   should be located.
   @return   sinfo_slit_pos  beginning and end position of the slitlets to
                          sub-pixel accuracy 0  if it worked, -1  if it failed,
   @doc  fits the beginning and end position of the slitlets by using 
         non-linear least square fitting of a Boltzmann function fits a 
         Boltzmann function to the slitlet edges exposed and indicated by the 
         brightest emission lines. The slitlet is searched within user given 
         positions. The least squares fit is done by using a box smaller than
         the size of two slitlets
*/

int 
sinfo_new_fit_slits_boltz_single_line ( cpl_image   * lineImage,
                  float     ** sinfo_slit_pos,
                  int          box_length,
                  float        y_box,
                  int          low_pos,
                  int          high_pos ) ;


/**
   @name  sinfo_new_fit_slits_boltz_with_estimate()
   @param lineImage  emission line frame
   @param sinfo_slit_pos  estimation array for the slitlet positions [min32][2]
   @param box_length  pixel length of the row box within the fit is done
   @param y_box       small box in spectral direction within the slitlet
                      may lie.
   @param low_pos
   @param high_pos    pixel positions in spectral direction between which the 
                      line should be located.
   @return sinfo_slit_pos  beginning and end position of the slitlets to
                           sub-pixel accuracy 0  if it worked, -1  if it failed,
   @doc  fits the beginning and end position of the slitlets by using 
         non-linear least square fitting of a Boltzmann function fits a 
         Boltzmann function to the slitlet edges exposed and indicated by the 
         brightest emission lines. The slitlet is searched within user given 
         positions. The least squares fit is done by using a box smaller than
         the size of two slitlets 
 */


int 
sinfo_new_fit_slits_boltz_with_estimate ( cpl_image   * lineImage,
                                float     ** sinfo_slit_pos,
                                int          box_length,
                                float        y_box,
                                float        diff_tol,
                                int          low_pos,
                                int          high_pos ) ;


/**
   @name  sinfo_new_fit_slits_edge_with_estimate()
   @param lineImage  emission line frame
   @param sinfo_slit_pos  estimation array for the slitlet positions [min32][2]
   @param box_length pixel length of the row box within the fit is done
   @param y_box      small box in spectral direction within the slitlet
                     may lie.
   @param low_pos
   @param high_pos   pixel positions in spectral direction between which the 
                     line should be located.
   @doc   sinfo_slit_pos  beginning and end position of the slitlets to
                           sub-pixel accuracy  0  if it worked,
                             -1  if it failed,
   @doc   fits the beginning and end position of the slitlets by using 
          non-linear least square fitting of an sinfo_edge  function fits a 
          linear sinfo_edge function to the slitlet edges exposed and indicated
          by the brightest emission lines. The slitlet is searched within
          user given positions.
          The least squares fit is done by using a box smaller than
          the size of two slitlets 
 */

int 
sinfo_new_fit_slits_edge_with_estimate ( cpl_image   * lineImage,
                                float    ** sinfo_slit_pos,
                                int         box_length,
                                float       y_box,
                                float       diff_tol,
                                int         low_pos,
                                int         high_pos ) ;



#endif /*!SINFO_ABSOLUTE_H*/
/**@}*/
