/*----------------------------------------------------------------------------
 
   File name    :       sinfo_new_slit_pos.c
   Author       :    A. Modigliani
   Created on   :    Sep 17, 2003
   Description  : 

 ---------------------------------------------------------------------------*/
/*
 * 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
 */
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

/*----------------------------------------------------------------------------
                                Includes
 ---------------------------------------------------------------------------*/
#include "sinfo_new_slit_pos.h"
#include "sinfo_pro_save.h"
#include "sinfo_pro_types.h"
#include "sinfo_wavecal_ini_by_cpl.h"
#include "sinfo_wcal_functions.h"
#include "sinfo_wave_calibration.h"
#include "sinfo_utilities.h"
#include "sinfo_utils_wrappers.h"
#include "sinfo_hidden.h"
#include "sinfo_error.h"
#include "sinfo_globals.h"

/*----------------------------------------------------------------------------
                                Defines
 ---------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
                             Function Definitions
 ---------------------------------------------------------------------------*/
/**@{*/
/**
 * @defgroup sinfo_new_slit_pos Slitlets position determination
 *
 * TBD
 */

/*----------------------------------------------------------------------------
   Function     :       sinfo_new_slit_pos()
   In           :       ini_file: file name of according .ini file
   Out          :       integer (0 if it worked, -1 if it doesn't) 
   Job          :


  Normal method:

  does the wavelength calibration and the fitting of the slitlet sinfo_edge 
  positions (ASCII file 32 x 2 values) if wished
  produces an array of the bcoefs and of the fit parameters if wished and a 
  wavelength calibration map input is an emission line frame and a line list


  o searching for lines by cross sinfo_correlation with a line list
  o Gaussian fitting of emission lines in each column->positions of the lines->
    resulting fit parameters can be stored in an ASCII file
  o Fitting of a polynomial to the line positions for each column
  o Smoothing: fitting of each polynomial coefficient by another polynomial
    across the whole frame -> resulting polynomial coefficients can be stored 
    in an ASCII file.
  o Wavelength calibration map (micron value for each frame pixel) can be
    produced by using these coefficients and a cross sinfo_correlation to the
    original frame

  o The slitlet sinfo_edge positions can be fitted:
    1) Automatically (not really stable) or by using guess sinfo_edge positions
    2) By using a Boltzmann or a linear slope function

  Slit method:

  does the wavelength calibration and the fitting of the slitlet sinfo_edge 
  positions (ASCII file 32 x 2 values) if wished produces a list of the fit 
  parameters and of the smoothed coefficients if wished and a wavelength 
  calibration map input is an emission line frame and a line list

  o Does the same as other method but smoothes the found polynomial 
    coefficients within each slitlet and not over the whole frame.

  o Produces always a wavelength calibration map and does not crosscorrelate.

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



int sinfo_new_slit_pos (cpl_parameterlist* config, cpl_frameset* sof)
{
    wave_config * cfg =NULL;
    int check = 0;
    int lx = 0;
    /* int ly = 0; */
    int n_lines=0;
    int i = 0;
    int j = 0;
    int n = 0;

    int sum=0;

    int* n_found_lines=NULL;
    int* sum_pointer=NULL;
    int** row_clean=NULL;

    float a=0;
    float shift=0;
    float* wave=NULL;
    float* intens=NULL;

    float** acoefs=NULL;
    float** wavelength_clean=NULL;

    float** sinfo_slit_pos=NULL;
 
    cpl_image *  map=NULL ;
    cpl_image * im=NULL ;

    FitParams** par=NULL;

    cpl_table* tbl_wcal=NULL;
    cpl_table* tbl_spos=NULL;

    char* col_name=NULL;
    char* tbl_name=NULL;

    char* tbl_line_list_name=NULL;
    cpl_table* tbl_line_list = NULL;
    int* status=NULL;
 
    cpl_frameset* raw=NULL;


    cpl_table * tbl_fp =NULL;
    char* col=NULL;
    cpl_table* qclog_tbl=NULL;
    char* key_name=NULL;
    double fwhm_med=0;
    double fwhm_avg=0;
    double coef_med=0;
    double coef_avg=0;
    /* int trow=0; */
    qc_wcal* qc=sinfo_qc_wcal_new();
    /*        -----------------------------------------------------------------
       1) parse the file names and parameters to the ns_config data 
          structure cfg
       -----------------------------------------------------------------
     */

    sinfo_msg("Parsing cpl input");
    cfg = sinfo_parse_cpl_input_wave(config,sof,&raw) ;
    
    if(cfg!=NULL) {
       cfg->nslitlets=32;
       cfg->calibIndicator=1;
       cfg->wavemapInd=0;
       cfg->slitposIndicator=1;
    }
    if(cpl_error_get_code() != CPL_ERROR_NONE) {
      sinfo_msg_error("%s", (char* ) cpl_error_get_message());
      sinfo_qc_wcal_delete(&qc);
      return -1;
    }
   
    if (cfg == NULL)
    {
        sinfo_msg_error("could not parse cpl input!\n") ;
        sinfo_qc_wcal_delete(&qc);
        return -1 ;
    }
    if(sinfo_is_fits_file(cfg->inFrame) != 1) {
      sinfo_msg_error("Input file %s is not FITS",cfg->inFrame);
      sinfo_qc_wcal_delete(&qc);
      return -1;
    }


    if (cfg->slitposIndicator == 1 && cfg->estimateIndicator == 1) {
      if (sinfo_is_fits_file(cfg->slitposGuessName) != 1) {
        sinfo_msg_error("slitlet position guess list not given!");
        sinfo_qc_wcal_delete(&qc);
        return -1;
      }
    }

    if (cfg->calibIndicator == 0 && cfg->wavemapInd == 1) {
      if (sinfo_is_fits_file(cfg->coeffsName) != 1) {
        sinfo_msg_error("coefficients list not given!");
        sinfo_qc_wcal_delete(&qc);
        return -1;
      }
    }


    if (cfg->slitposIndicator == 1) {
      if (cfg->calibIndicator != 1 && cfg->estimateIndicator != 1) {
       
        if (sinfo_is_fits_file(cfg->paramsList) != 1) {
      sinfo_msg_error("parameter list not given!");
          sinfo_qc_wcal_delete(&qc);
      return -1;
    }
    
      }
    }

/*---load the emission line frame---*/
    im = cpl_image_load(cfg->inFrame,CPL_TYPE_FLOAT,0,0);
    if (im == NULL) {
      sinfo_msg_error("could not load image\n");
      sinfo_qc_wcal_delete(&qc);
      return -1;
    }


    lx = cpl_image_get_size_x(im);
    /* ly = cpl_image_get_size_y(im); */



if (cfg->calibIndicator == 1 || cfg->wavemapInd == 1) {
    /*---open the line list and read the number of lines---*/

    if(cpl_error_get_code() != CPL_ERROR_NONE) {
      sinfo_msg_error("%s", (char* ) cpl_error_get_message());
      sinfo_qc_wcal_delete(&qc);
      cpl_image_delete(im);
      return -1;
    }

    tbl_line_list_name=cfg->lineList;
    tbl_line_list = cpl_table_load(tbl_line_list_name,1,0);
    if(cpl_error_get_code() != CPL_ERROR_NONE) {
      sinfo_msg_error("%s", (char* ) cpl_error_get_message());
      sinfo_qc_wcal_delete(&qc);
      return -1;
    }
    n = cpl_table_get_nrow(tbl_line_list);
    n_lines = n;
    if(cpl_error_get_code() != CPL_ERROR_NONE) {
      sinfo_msg_error("%s", (char* ) cpl_error_get_message());
      sinfo_qc_wcal_delete(&qc);
      cpl_image_delete(im);
      return -1;
    }

    /* THIS ORIGINATES A MEMORY LEAK 
    wave   = sinfo_new_floatarray (n);
    intens = sinfo_new_floatarray (n);
    if (wave == NULL || intens == NULL) {
      sinfo_msg_error("could not allocate memory for the line list values\n" );
      sinfo_qc_wcal_delete(&qc);
      return -1;
    }
    */

    wave   = cpl_table_get_data_float(tbl_line_list,"wave");
    if(cpl_error_get_code() != CPL_ERROR_NONE) {
      sinfo_msg_error("%s", (char* ) cpl_error_get_message());
      sinfo_qc_wcal_delete(&qc);
      cpl_image_delete(im);
      return -1;
    }

    intens = cpl_table_get_data_float(tbl_line_list,"int");
    if(cpl_error_get_code() != CPL_ERROR_NONE) {
      sinfo_msg_error("%s", (char* ) cpl_error_get_message());
      sinfo_qc_wcal_delete(&qc);
      cpl_image_delete(im);
      return -1;
    }
    
}



/*
 ----------------------------------------------------------------------
 ---------------------------FINDLINES----------------------------------
 ----------------------------------------------------------------------
 */


/*if not yet done:
  do the wavelength calibration, that means: 
  find the dispersion relation and parameterize its coefficients
 */
/*
 sinfo_msg("guessBeginWave=%g",cfg->guessBeginWavelength);
 sinfo_msg("guessDisp1=%g",cfg->guessDispersion1);
 sinfo_msg("guessDisp2=%g",cfg->guessDispersion2);
*/
if (cfg->calibIndicator == 1 && cfg->wavemapInd == 0) {
   sinfo_msg("Findlines");
   acoefs  = sinfo_new_2Dfloatarray(cfg->nrDispCoefficients, lx);
   /*allocate memory*/
   n_found_lines    = sinfo_new_intarray(lx); 
   row_clean        = sinfo_new_2Dintarray(lx, n_lines);
   wavelength_clean = sinfo_new_2Dfloatarray(lx, n_lines);
   sum_pointer      = sinfo_new_intarray(1) ;
   /*find the emission lines in each image column*/
   sinfo_new_intarray_set_value(sum_pointer, 0, 0);
   check = sinfo_new_find_lines(im, wave, intens, n_lines, row_clean, 
                      wavelength_clean, cfg->guessBeginWavelength, 
             cfg->guessDispersion1, cfg->guessDispersion2,
                      cfg->mindiff, cfg->halfWidth, 
                      n_found_lines, cfg->sigma, sum_pointer );
   if (-1 == check) {
           sinfo_msg_error("sinfo_findLines failed!\n");
           sinfo_qc_wcal_delete(&qc);
           return -1;
   }
      

/*---------------------------------------------------------------------
 *-----------------------WAVE_CALIB-------------------------------------
 *---------------------------------------------------------------------
 */

     
   sinfo_msg("Wave Calibration");
   sum = sinfo_new_intarray_get_value(sum_pointer,0);
   /* allocate memory for the fit parameters */
   par = sinfo_new_fit_params( sum );
   if (par == NULL) {
        sinfo_msg_error("sinfo_newFitParams failed!\n");
        sinfo_qc_wcal_delete(&qc);
        return -1;
   }

  /*
   fit each line, make a polynomial fit and fit the resulting fit 
   coefficients across the columns of the slitlet
   */
   sinfo_slit_pos = sinfo_new_2Dfloatarray(32,2);

   map = sinfo_new_spred_wave_cal(im, 
                 par, 
                 acoefs, 
                 cfg->nslitlets, 
                 row_clean, 
                 wavelength_clean, 
                 n_found_lines, 
                 cfg->guessDispersion1, 
                 cfg->halfWidth, 
                 cfg->minAmplitude, 
                 cfg->maxResidual, 
                 cfg->fwhm, 
                 cfg->nrDispCoefficients, 
                 cfg->nrCoefCoefficients, 
                 cfg->sigmaFactor, 
                 cfg->pixeldist, 
                 cfg->pixel_tolerance,
                 sinfo_slit_pos);

 
   if (map == NULL ) { 
          sinfo_msg_error("sinfo_wave_cal failed!\n");
          sinfo_qc_wcal_delete(&qc);
      return -1;
   }
   sinfo_msg("Check line positions");
  
   shift = sinfo_new_check_line_positions (im, acoefs, 
                                          cfg->nrDispCoefficients,
                                          cfg->guessDispersion1, par);
   if (FLAG == shift){ 
      sinfo_msg_error("checkForLinePositions failed!\n");
   }


    sinfo_det_ncounts(raw, cfg->qc_thresh_max,qc);
    qclog_tbl = sinfo_qclog_init();
    ck0_nomsg(sinfo_qclog_add_int(qclog_tbl,"QC WAVE ALL",
                  n_lines,"Number of found lines","%d"));

    ck0_nomsg(sinfo_qclog_add_int(qclog_tbl,"QC WAVE NPIXSAT",
                  qc->nsat,"Number of saturated pixels","%d"));

    ck0_nomsg(sinfo_qclog_add_int(qclog_tbl,"QC WAVE MAXFLUX",
                qc->max_di,"Max int off-lamp subracted frm","%g"));

   if(-1 == sinfo_pro_save_ima(map,raw,sof,cfg->outName,
         PRO_WAVE_MAP,qclog_tbl,cpl_func,config)) {
         sinfo_msg_error("cannot save ima %s", cfg->outName);
    }
   sinfo_free_table(&qclog_tbl);
 
 
   /*
    #store the resulting polynomial fit coefficients in an 
     ASCII file if wished
    */

   if (cfg->writeCoeffsInd == 1) {
         col_name = (char*) cpl_calloc(MAX_NAME_SIZE,sizeof(char*));
         tbl_name = (char*) cpl_calloc(MAX_NAME_SIZE,sizeof(char*));
         tbl_wcal = cpl_table_new(lx);
         for (i=0; i< cfg->nrDispCoefficients; i++) {
             snprintf(col_name,MAX_NAME_SIZE-1,"%s%d","coeff",i);
             cpl_table_new_column(tbl_wcal,col_name, CPL_TYPE_DOUBLE);
     }


         qclog_tbl = sinfo_qclog_init();
         key_name  = cpl_calloc(FILE_NAME_SZ,sizeof(char));
         ck0_nomsg(sinfo_qclog_add_int(qclog_tbl,"QC WAVE ALL",
               n_lines,"Number of found lines","%d"));



         for (j=0; j< lx; j++) { 
        for (i=0; i< cfg->nrDispCoefficients; i++) {
                snprintf(col_name,MAX_NAME_SIZE-1,"%s%d","coeff",i);
            a = sinfo_new_array2D_get_value(acoefs, i, j);
        /* fprintf(acoefs_file, "%15.13g ", a) ; */
                cpl_table_set_double(tbl_wcal,col_name,j,a);
        }


     }


     for (i=0; i< cfg->nrDispCoefficients; i++) {
            snprintf(col_name,MAX_NAME_SIZE-1,"%s%d","coeff",i);
            coef_avg=cpl_table_get_column_mean(tbl_wcal,col_name);
            coef_med=cpl_table_get_column_median(tbl_wcal,col_name);

            //trow=1+i;
            snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%s","QC COEF",i," AVG");
            ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,coef_avg,
                         "Average wavecal Coef","%g"));

            //trow=1+i+cfg->nrDispCoefficients;
            snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%s","QC COEF",i," MED");
            ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,coef_med,
                         "Median wavecal Coef","%g"));

     }

     /*
         fclose(acoefs_file);
     */
         strcpy(tbl_name,cfg->coeffsName);

         if(-1 == sinfo_pro_save_tbl(tbl_wcal,raw,sof,tbl_name,
             PRO_WAVE_COEF_SLIT,qclog_tbl,cpl_func,config)) {
         sinfo_msg_error("cannot save tbl %s", tbl_name);
         }
         sinfo_free_table(&tbl_wcal);
         sinfo_free_table(&qclog_tbl);
         cpl_free(key_name);

         cpl_free(col_name);
         cpl_free(tbl_name);

   }


   /*
    #store the resulting Gaussian fit parameters in an ASCII file if wished
   */
   if (cfg->writeParInd == 1) {


      sinfo_new_dump_fit_params_to_ascii(par,WAVECAL_FIT_PARAMS_OUT_FILEASCII);
 
      if ( NULL == par )
      {
         sinfo_msg_error ("no fit parameters available!") ;
         sinfo_qc_wcal_delete(&qc);
         return -1;
      }

      if ( NULL == cfg->paramsList )
      {
         sinfo_msg_error ("no filename available!") ;
         sinfo_qc_wcal_delete(&qc);
         return -1;
      }

      tbl_fp = cpl_table_new(par[0] -> n_params);
      cpl_table_new_column(tbl_fp,"n_params", CPL_TYPE_INT);
      cpl_table_new_column(tbl_fp,"column", CPL_TYPE_INT);
      cpl_table_new_column(tbl_fp,"line", CPL_TYPE_INT);
      col = (char*) cpl_calloc(MAX_NAME_SIZE,sizeof(char*));

      for(j=0;j<4;j++) {
         snprintf(col,MAX_NAME_SIZE-1,"%s%d","fpar",j);
         cpl_table_new_column(tbl_fp,col, CPL_TYPE_DOUBLE);
         snprintf(col,MAX_NAME_SIZE-1,"%s%d","dpar",j);
         cpl_table_new_column(tbl_fp,col, CPL_TYPE_DOUBLE);
      }



    qclog_tbl = sinfo_qclog_init();
    ck0_nomsg(sinfo_qclog_add_int(qclog_tbl,"QC NLINES",n_lines,
                  "Number of Found lines","%d"));

      for ( i = 0 ; i < par[0] -> n_params ; i++ )
      {
         cpl_table_set_int(tbl_fp,"n_params",i,par[i]->n_params);
         cpl_table_set_int(tbl_fp,"column",i,par[i]->column);
         cpl_table_set_int(tbl_fp,"line",i,par[i]->line);


         for(j=0;j<4;j++) {
        snprintf(col,MAX_NAME_SIZE-1,"%s%d","fpar",j);
            cpl_table_set_double(tbl_fp,col,i,par[i]->fit_par[j]);
        snprintf(col,MAX_NAME_SIZE-1,"%s%d","dpar",j);
            cpl_table_set_double(tbl_fp,col,i,par[i]->derv_par[j]);
     }
      }

      fwhm_avg = cpl_table_get_column_mean(tbl_fp,"fpar1");
      fwhm_med = cpl_table_get_column_median(tbl_fp,"fpar1");
      ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC FWHM MED",fwhm_med,
                       "Median FWHM of found lines","%f"));

      ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC FWHM AVG",fwhm_avg,
                       "Average FWHM of found lines","%f"));


      if(-1 == sinfo_pro_save_tbl(tbl_fp,raw,sof,cfg->paramsList,
         PRO_WAVE_PAR_LIST,qclog_tbl,cpl_func,config)) {
         sinfo_msg_error("cannot save tbl %s", cfg->paramsList);
      }
      sinfo_free_table(&qclog_tbl);

      sinfo_free_table(&tbl_fp) ;
      cpl_free(col);

   }
   /* free memory */
   sinfo_new_destroy_2Dfloatarray ( &wavelength_clean, lx );
   sinfo_new_destroy_2Dintarray (&row_clean, lx);
   sinfo_new_destroy_intarray(&n_found_lines );
   sinfo_new_destroy_intarray(&sum_pointer );
   sinfo_new_destroy_2Dfloatarray ( &acoefs, cfg->nrDispCoefficients );

/*----------------------------------------------------------------------
 *-------------------WAVEMAP--------------------------------------------
 *----------------------------------------------------------------------
 */

/*
#---now do the cross sinfo_correlation and produce a wavelength map---
 */
} else if (cfg->wavemapInd == 1 && cfg->calibIndicator == 0) { 
  sinfo_msg("Wavemap");
  acoefs = sinfo_new_2Dfloatarray ( cfg->nrDispCoefficients, lx);
   /* #read the parameterized dispersion relation */

   tbl_name = (char*) cpl_calloc(MAX_NAME_SIZE,sizeof(char*));
   col_name = (char*) cpl_calloc(MAX_NAME_SIZE,sizeof(char*));
   strcpy(tbl_name,cfg->coeffsName);
   tbl_wcal = cpl_table_load(tbl_name,1,0);
    if(cpl_error_get_code() != CPL_ERROR_NONE) {
      sinfo_msg("cannot load table %s",tbl_name);
      sinfo_msg_error("%s", (char* ) cpl_error_get_message());
      sinfo_qc_wcal_delete(&qc);
      cpl_image_delete(im);
      cpl_free(col_name);
      return -1;
    }
   for (i =0; i < lx; i++) {
      for (j = 0; j< cfg->nrDispCoefficients; j++) {
            snprintf(col_name,MAX_NAME_SIZE-1,"%s%d","coeff",j);
            acoefs[j][i]=cpl_table_get_double(tbl_wcal,col_name,i,status);
      }
   }
    if(cpl_error_get_code() != CPL_ERROR_NONE) {
      sinfo_msg("cannot read table %s",tbl_name);
      sinfo_msg_error("%s", (char* ) cpl_error_get_message());
      sinfo_qc_wcal_delete(&qc);
      return -1;
    }
    cpl_free(col_name);
    cpl_free(tbl_name);
    sinfo_free_table(&tbl_wcal);

    map = sinfo_new_create_shifted_slit_wavemap2 ( im, 
                                          acoefs, 
                                          cfg->nrDispCoefficients,
                                          wave, 
                                          intens, 
                                          n_lines, 
                                          cfg->magFactor, 
                      cfg->guessDispersion1, 
                                          cfg->pixeldist );
   if (map == NULL) {
           sinfo_msg_error("sinfo_createShiftedSlitWavemap2 failed!\n");
           sinfo_qc_wcal_delete(&qc);
           return -1;
   }

   par = sinfo_new_fit_params(15*n_lines);
   sinfo_msg("Check shifts");

   shift = sinfo_new_check_correlated_line_positions ( im, acoefs, 
                                           cfg->nrDispCoefficients, 
                                           wave, 
                                           intens, 
                                           n_lines, 
                                           cfg->fwhm, 
                                           cfg->halfWidth, 
                                           cfg->minAmplitude, 
                                           cfg->guessDispersion1, 
                                           par );


   if (FLAG == shift){
      sinfo_msg_error("sinfo_checkCorrelatedLinePositions failed!\n");
   }


    sinfo_det_ncounts(raw, cfg->qc_thresh_max,qc);
    qclog_tbl = sinfo_qclog_init();
    ck0_nomsg(sinfo_qclog_add_int(qclog_tbl,"QC NLINES",n_lines,
                  "Number of found lines","%d"));



    fwhm_avg = cpl_table_get_column_mean(tbl_fp,"fpar1");
    fwhm_med = cpl_table_get_column_median(tbl_fp,"fpar1");

    ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC FWHM MED",fwhm_med,
                     "Median FWHM of found lines","%f"));
    ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC FWHM AVG",fwhm_avg,
                     "Average FWHM of found lines","%f"));


    if(-1 == sinfo_pro_save_ima(map,raw,sof,cfg->outName,
         PRO_WAVE_MAP,qclog_tbl,cpl_func,config)) {
         sinfo_msg_error("cannot save ima %s", cfg->outName);
    }
    sinfo_free_table(&qclog_tbl);


   /* # ---free memory--- */
   sinfo_new_destroy_2Dfloatarray ( &acoefs, cfg->nrDispCoefficients );
   /* To fix a memory bug we comment the following. But check! */

} else if (cfg->wavemapInd == 1 && cfg->calibIndicator == 1) {
   sinfo_msg_error("give either wavemapIndicator = yes and calibIndicator = no \
                or wavemapIndicator = no and calibIndicator = yes") ;
   sinfo_qc_wcal_delete(&qc);
   return -1;
}


/*-------------------------------------------------------------------
 *-------------------SLITFITS----------------------------------------
 *-------------------------------------------------------------------
 #--fit the slitlet sinfo_edge positions if desired--
 */
if (cfg->slitposIndicator == 1) {
  sinfo_msg("fit the slitlet sinfo_edge positions");


    /* #store the resulting sitlet positions in an TFITS table */
   tbl_name = (char*) cpl_calloc(MAX_NAME_SIZE,sizeof(char*));
   tbl_spos = cpl_table_new(32);
   cpl_table_new_column(tbl_spos,"pos1", CPL_TYPE_DOUBLE);
   cpl_table_new_column(tbl_spos,"pos2", CPL_TYPE_DOUBLE);
   cpl_table_set_column_format(tbl_spos,"pos1", "15.9f");
   cpl_table_set_column_format(tbl_spos,"pos2", "15.9f");

    for (i =0; i< 32; i++) {
     /*
     fprintf( slitpos_file, "%15.9f %15.9f \n",
      sinfo_new_array2D_get_value(sinfo_slit_pos,i,0),
                        sinfo_new_array2D_get_value(sinfo_slit_pos,i,1));
     */
      cpl_table_set_double(tbl_spos,"pos1",i,
                           sinfo_new_array2D_get_value(sinfo_slit_pos,i,0));
      cpl_table_set_double(tbl_spos,"pos2",i,
                           sinfo_new_array2D_get_value(sinfo_slit_pos,i,1));
     
   }
    /* strcpy(tbl_name,cfg->slitposName); */
    strcpy(tbl_name,"out_guess_slit_pos.fits");
    if(-1 == sinfo_pro_save_tbl(tbl_spos,raw,sof,tbl_name,
         PRO_SLIT_POS,NULL,cpl_func,config)) {
         sinfo_msg_error("cannot save tbl %s", tbl_name);
    }
    sinfo_free_table(&tbl_spos);
    cpl_free(tbl_name);
   /*# free memory*/
   sinfo_new_destroy_2Dfloatarray ( &sinfo_slit_pos, 32 );
   
   
}

/* #-----free the rest memory--*/
if ( (cfg->slitposIndicator == 1 && cfg->estimateIndicator != 1) || 
     (cfg->calibIndicator == 1)  || (cfg->wavemapInd == 1) ){
     sinfo_new_destroy_fit_params(&par);
}
sinfo_free_image( &im );
sinfo_free_image( &map );
sinfo_wavecal_free(&cfg);
sinfo_qc_wcal_delete(&qc);

 return 0;

 cleanup:
 return -1;



}

/**@}*/

