#ifndef SINFO_RECIPES_H
#define SINFO_RECIPES_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_recipes.h,v 1.7 2008-02-12 13:29:09 amodigli Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* schreib  05/06/00  created
*/

/************************************************************************
 * recipes.h
 * some numerical recipes
 *----------------------------------------------------------------------
 */

/*
 * header files
 */

#include <cpl.h>
#include <inttypes.h>
#include <float.h>
#include <math.h>
#include "sinfo_pixel_handling.h"
#include "sinfo_msg.h"


/*----------------------------------------------------------------------------
 *                        defines
 *--------------------------------------------------------------------------*/
/* definitions of initial values for sinfo_lsqfit_c in sinfo_linefit() 
   (wave_calibration) */
#define XDIM         1         /* dimension of the x values */
#define TOL          0.001     /* fitting tolerance */
#define LAB          0.1       /* labda parameter */
#define ITS          200       /* maximum number of iterations */
#define MAXPAR       4         /* number of free parameters */
#define LABFAC       10.0      /* labda step factor */
#define LABMAX       1.0e+10   /* maximum value for labda */
#define LABMIN       1.0e-10   /* minimum value for labda */

/*----------------------------------------------------------------------------
 *                        Function ANSI C prototypes
 *--------------------------------------------------------------------------*/
double sinfo_nev_ille(double x[], double f[], int n, double z, int* flag);

float 
sinfo_new_f_median(float * array, int n);

float 
sinfo_new_clean_mean( float * array,
                  int     n_elements,
                  float   throwaway_low,
                  float   throwaway_high ) ;


/**
   @name  sinfo_new_median()
   @param  array  array of pixelvalues starting at index 0,
                  number of array elements
   @result      median of pixelvalues
   @memo sorts an array into ascending numerical order by using 
         sinfo_pixel_qsort(), and derives the median depending on an 
         odd or even number of array elements
*/

pixelvalue 
sinfo_new_median(pixelvalue * array, int n) ;
/**
   @name   sinfo_new_lsqfit_c()
   @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. The 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.
  @result       returns 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 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_c ( 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_my_fit()
   @memo fits a straight line to a set of x, y data points by
         minimizing chi-square. Numeric. Rec. page 665
   @param x     set of data points, 
   @param y     set of data points,
   @param ndata number of input data 
   @param sig   individual standard deviations,
   @param mwt   weights
   @param a     parameters of a straight line, 
   @param b     parameters of a straight line, 
   @param chi2  chi-square, 
   @param q     goodness-of-fit probability
   @return     void
*/

void 
sinfo_my_fit (float x[], float y[], int ndata, float sig[], int mwt, float *a,
           float *b, float *siga, float *sigb, float *chi2, float *q) ;

/**
   @name      sinfo_new_nint()
   @memo this routine determines the nearest integer to a specified real value
   @param     x : specified real value
   @return      nearest integer to specified real value
*/

int 
sinfo_new_nint ( double x ) ;

/**
   @name  sinfo_new_correlation()
   @param data1 first data array
   @param data2 second data array
   @param ndata number of data elements in the arrays, both arrays must have 
                the same number of elements.
   @return integer shift of the second array with respect to the first array.
                        2^32/2 if something went wrong.
   @memo this routine computes the cross sinfo_correlation between two data 
         arrays of the same size and returns the integer shift between both 
         arrays
*/

int 
sinfo_new_correlation ( float * data1, float * data2, int ndata ) ;

/**
   @name    sinfo_new_convert_ZEROs_to_0_for_images()
   @memo    this function converts any ZEROs in an image to 0
   @param   im    input image
   @return  nothing
*/

void 
sinfo_new_convert_ZEROs_to_0_for_images(cpl_image * im) ;

/**
   @name  sinfo_new_convert_ZEROs_to_0_for_cubes_range()
   @memo  this function converts any ZEROs in a cube to 0
   @param input cube
   @return nothing
*/

void 
sinfo_new_convert_ZEROs_to_0_for_cubes_range(cpl_imagelist * cube,
                                             const int z_min,
                                             const int z_max);

/**
   @name  new_convert_0_to_ZEROs_for_cubes()
   @memo   this function converts any 0 in a cube to ZERO
   @param cube  input cube
   @param z_min  min z to be considered
   @param z_max  max z to be considered
   @return nothing
*/

void 
sinfo_new_convert_0_to_ZERO_for_cubes_range(cpl_imagelist * cube,
                                            const int z_min,
                                            const int z_max);
/**
   @name  sinfo_new_convert_ZEROs_to_0_for_cubes()
   @memo   this function converts any ZEROs in a cube to 0
   @param cube  input cube
   @return nothing
*/

void 
sinfo_new_convert_ZEROs_to_0_for_cubes(cpl_imagelist * cube) ;


/**
   @name sinfo_new_convert_0_to_ZEROs_for_images()
   @param im   input image
   @result    nothing
   @memo  this function converts any 0 in an image to ZEROs
*/

void 
sinfo_new_convert_0_to_ZEROs_for_images(cpl_image * im) ;

/**
   @name   new_convert_0_to_ZEROs_for_cubes()
   @memo  this function converts any 0 in a cube to ZERO
   @param  cube    input cube
   @result nothing
*/

void 
sinfo_new_convert_0_to_ZERO_for_cubes(cpl_imagelist * cube) ;

/**
   @name  new_invert_image()
   @memo  this function multiplies each image value by -1.
   @param im     input image
   @result inverted input image (overwritten)
*/

void sinfo_new_invert(cpl_image * im) ;


/**
   @name      sinfo_new_xcorrel ()
   @memo   simple cross-sinfo_correlation of two 1d-signals without FFT
   @param  line_i      the reference signal
   @param  width_i     number of samples in reference signal
   @param  line_t      candidate signal to compare
   @param  width_t     number of samples in candidate signal
   @param  half_search half-size of the search domain
   @param  delta       output sinfo_correlation offset.
   @param  maxpos      position index of the maximum of the output array
   @param  xcorr_max   maximum value of the output array
   @result sinfo_correlation function, must be freed.
*/

double * 
sinfo_new_xcorrel(
    float      *    line_i,
    int             width_i,
    float      *    line_t,
    int             width_t,
    int             half_search,
    int     *       delta,
    int        *    maxpos,
    double     *    xcorr_max

) ;

float 
sinfo_new_nev_ille(float [], float [], int, float, int *);


#endif /*!SINFO_RECIPES_H*/

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

