/*                                                                            *
 *   This file is part of the ESO UVES Pipeline                               *
 *   Copyright (C) 2004,2005 European Southern Observatory                    *
 *                                                                            *
 *   This library 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     *
 *                                                                           */
 
/*
 * $Author: amodigli $
 * $Date: 2013-09-08 10:40:36 $
 * $Revision: 1.136 $
 * $Name: not supported by cvs2svn $
 *
 */
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif


/*----------------------------------------------------------------------------*/
/**
 * @defgroup flames_obs_scired  Recipe: science reduction
 *
 * This recipe reduce science frames
 * See man-page for details.
 */
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
                                Includes
 ----------------------------------------------------------------------------*/


#include <flames_midas_def.h>

#include <flames_create_backtable.h>
#include <flames_crea_bp_ima.h>
#include <flames_add_extra_des.h>
#include <flames_preppa_impl.h>
#include <flames_uves.h>
#include <flames_dfs.h>
#include <flames_utils.h>
#include <flames_utils_science.h>
#include <flames_def_drs_par.h>
#include <flames.h>
#include <flames_mainopt.h>
#include <flames_mainoptquick.h>
#include <flames_mainoptfast.h>
#include <flames_mainstand.h>
#include <flames_mainstandquick.h>
#include <flames_mainstandfast.h>
#include <flames_corvel.h>
#include <flames_cveltab.h>

#include <uves_corrbadpix.h>
#include <uves_rebin.h>
#include <uves_merge.h>
#include <uves_globals.h>
#include <uves.h>
#include <uves_dfs.h>
#include <uves_pfits.h>
#include <uves_recipe.h>
#include <uves_qclog.h>
#include <uves_parameters.h>
#include <uves_dump.h>
#include <uves_utils.h>
#include <uves_error.h>
#include <uves_baryvel.h>
#include <uves_utils_wrappers.h>

#include <cpl.h>

#include <ctype.h>
#include <math.h>
#include <time.h>
#include <string.h>
/*-----------------------------------------------------------------------------
                            Functions prototypes
 -----------------------------------------------------------------------------*/
//static char* 
//(tag)(const int i, enum uves_chip chip);


static int
flames_reduce_proclass(const cpl_frame* ifrm, 
                       const cpl_frame* ordef, 
                       cpl_frameset* frames,
		       enum uves_chip chip,
                       const cpl_table* xtab,
		       const cpl_parameterlist *parameters, 
		       polynomial *order_locations,
                       const char* drs_base_name,
                       const char* start_time,
                       cpl_table** qclog);


static int
flames_rebin_frame(const cpl_parameterlist *parameters, 
                   const char* filename,
                   const cpl_table* lin_tab,  
                   const polynomial  *disp_rel,
                   const int omin,
                   const int omax,
                   cpl_image** wimg, 
                   uves_propertylist** wheader);



static int
flames_set_delta(const int wlen, 
		 enum uves_chip chip,
                 double* delta1, 
                 double* delta2);

static int
flames_extract_frame(const cpl_frame* sci,
                     const cpl_frame* ordtab,
                     const cpl_frame* bkg_frm,
                     const cpl_frameset* slitff_set,
                     const cpl_frameset* fibreff_set,
                     const char* prefid,
                     const char* base_name,
                     const double drs_k_s_thresh,
                     const char* method,
                     const char* drs_cor_max_fnd,
                     const float drs_cor_def_rng,
                     const int drs_cor_def_pnt,
                     const float drs_cor_def_off,
             const double drs_maxyshift,
                     const double drs_ext_w_siz);

static int
flames_reduce(const cpl_parameterlist* parameters,
                    cpl_frameset* frames,
              const cpl_frame *sci,
              const cpl_frame *master_bias,
              const cpl_frame *ordef,
              const cpl_frame *cvel_tab,
	            polynomial *order_locations,
              enum uves_chip chip,
              const int binx,
              const int biny,
              const char *ext_method,
              merge_method m_method,
             const char *starttime,
                    time_t t_start,
              char bias_method,
               int bias_value,
              cpl_table** ext,
              int* fibres_mask,
              double* fibres_pos,
              int* pixel_thresh_min,
              int* pixel_thresh_max,
              const char *filt_sw,
              const double drs_k_s_thre,
              const char* drs_base_name,
              const char* drs_cor_max_fnd,
              const float drs_cor_def_rng,
              const int drs_cor_def_pnt,
              const float drs_cor_def_off,
              const int drs_corvel_iter,
              const double drs_maxyshift,
              const double drs_ext_w_siz);



static cpl_frame*
flames_reduce_bias_subtract(const cpl_frame* sci_frm, 
                            const cpl_frame* mbia_frm,
                            const char bias_method,
                            const double bias_value,
                            int* pixel_thresh_max);

static int
flames_obs_scired_define_parameters(cpl_parameterlist *parameters);

static cpl_table*
flames_reduce_xtab_merge(
          int* fibres_mask,
          double* fibres_pos,
	  cpl_table** ext,
          enum uves_chip chip);


static cpl_frameset*
flames_reduce_prep_slitff(cpl_frameset* frames, 
                          enum uves_chip chip,
			   const char* prefid);


static cpl_frameset*
flames_reduce_prep_fibff(cpl_frameset* frames, 
                         enum uves_chip chip,
                         const char* prefid);


static int
flames_reduce_extract(const cpl_frame* sci, 
                      const cpl_frame* ordpos, 
                      const cpl_frame* bkg_frm, 
                      const cpl_frameset* slitff_set,
                      const cpl_frameset* fibff_set,
                      const char* prefid,
                      const char* method,
                      const double drs_k_s_thre,
                      const char* base_name,
                      const char*  drs_cor_max_fnd,
                      const float drs_cor_def_rng,
                      const int    drs_cor_def_pnt,
                      const float drs_cor_def_off,
                      const double drs_maxyshift,
                      const double drs_ext_w_siz,
                         enum uves_chip chip,
              double* t_extract);


static int
flames_reduce_rebmerge(const cpl_frame* ifrm, 
                       const cpl_frame* ordef, 
                       cpl_frameset* frames,
		       enum uves_chip chip,
                       cpl_table* xtab,
                       const cpl_table* ozpoz,
		       const cpl_parameterlist *parameters, 
		       polynomial *order_locations,
                       const char* drs_base_name,
                       const char* start_time, 
		       merge_method m_method);





/*
static int
flames_reduce_compeff(void);
static int
flames_reduce_qclog(void);
*/


/**@{*/
/*-----------------------------------------------------------------------------
                            Recipe standard code
 -----------------------------------------------------------------------------*/

#define cpl_plugin_get_info flames_obs_scired_get_info
UVES_RECIPE_DEFINE(
    FLAMES_OBS_SCIRED_ID, FLAMES_OBS_SCIRED_DOM, flames_obs_scired_define_parameters,
    "Andrea Modigliani", "cpl@eso.org",
    "Reduces a FLAMES science image",
   "Fibre & order position determination procedure:\n"
   "You should feed the recipe with:\n"
   "- science fibre images (" 
   FLAMES_SCI_RED ", " FLAMES_SCI_SIM_RED ", " FLAMES_SCI_SIM_RED ")\n"
   "- single fibre images, FIB_ORDEF_(REDL|REDU)\n"
   "- master bias frames, MASTER_BIAS_(REDL|REDU)\n"
   "- 3 master slit flatfield frames, MASTER_SFLAT_(REDL|REDU)\n"
   "- Fibre order table, FIB_ORDEF_TABLE_(REDL|REDU)\n" 
   "- Slit flatfield common, SLIT_FF_COM_(REDL|REDU)\n" 
   "- Slit flatfield norm, SLIT_FF_NOR_(REDL|REDU)\n" 
   "- Slit flatfield data, SLIT_FF_DTC_(REDL|REDU)\n" 
   "- Slit flatfield sigma, SLIT_FF_SGC_(REDL|REDU)\n" 
   "- Slit flatfield bad pixel, SLIT_FF_BPC_(REDL|REDU)\n" 
   "- Slit flatfield boundary, SLIT_FF_BNC_(REDL|REDU)\n" 
   "- Fibre flatfield common, FIB_FF_COM_(REDL|REDU)\n" 
   "- Fibre flatfield norm, FIB_FF_NOR_(REDL|REDU)\n" 
   "- Fibre flatfield norm sigma, FIB_FF_NSG_(REDL|REDU)\n" 
   "- Slit flatfield data, SLIT_FF_DTC_(REDL|REDU)\n" 
   "- Slit flatfield sigma, SLIT_FF_SGC_(REDL|REDU)\n" 
   "- Slit flatfield bad pixel, SLIT_FF_BPC_(REDL|REDU)\n"
   "\n"
   "Products are:\n"
   "- Science fibre info table (FIB_SCI_INFO_TAB)\n" 
   "-   XB_SCI_RAW_(REDL|REDU)\n"
   "-   ERR_XB_SCI_RAW_(REDL|REDU)\n"
   "-   WXB_SCI_RAW_(REDL|REDU)\n"
   "-   ERR_WXB_SCI_RAW_(REDL|REDU)\n"
   "-   MWXB_SCI_RAW_(REDL|REDU)\n"
   "-   ERR_MWXB_SCI_RAW_(REDL|REDU)\n"
   "-   XB_SCI_(REDL|REDU)\n"
   "-   ERR_XB_SCI_(REDL|REDU)\n"
   "-   WXB_SCI_(REDL|REDU)\n"
   "-   ERR_WXB_SCI_(REDL|REDU)\n"
   "-   MWXB_SCI_(REDL|REDU)\n"
   "-   ERR_MWXB_SCI_(REDL|REDU)\n"
    );
/*-----------------------------------------------------------------------------
                              Functions code
 -----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/**
  @brief    Setup the recipe options    
  @param    parameters   the parameterlist to fill
  @return   0 if everything is ok
 */
/*----------------------------------------------------------------------------*/
static int
flames_obs_scired_define_parameters(cpl_parameterlist *parameters)
{
  const char *name = "";
  const char *subcontext = NULL;
  const char *recipe_id = make_str(FLAMES_OBS_SCIRED_ID);

  /*****************
   *    General    *
   *****************/

  if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
  {
    return -1;
  }

  uves_par_new_enum("ext_method",
		    CPL_TYPE_STRING,
		    "Extraction method",
		    DRS_EXT_MTD,
		    4,
		    // "std", "opt", "fst", "fop", "qst", "qop");
  "std", "opt", "fst", "fop");


    
  uves_par_new_enum("cor_max_fnd",
		    CPL_TYPE_STRING,
		    "Find correlation maximum?",
		    DRS_COR_MAX_FND,
		    2,
		    "N", "Y");

  uves_par_new_value("cor_def_rng",
		     CPL_TYPE_DOUBLE,
		     "Correlation range size?",
		     DRS_COR_DEF_RNG);


   
  uves_par_new_range("cor_def_pnt",
		     CPL_TYPE_INT,
		     "Correlation sampling points?",
		     DRS_COR_DEF_PNT,5,100);



 
  uves_par_new_value("cor_def_off",
		     CPL_TYPE_DOUBLE,
		     "Correlation center offset?",
		     DRS_COR_DEF_OFF);

  uves_par_new_value("corvel_iter",
		     CPL_TYPE_INT,
		     "Velocity correlation iteration number (SimCal)",
		     1);


  uves_par_new_enum("bias_method",
		    CPL_TYPE_STRING,
		    "Bias subtraction method",
		    DRS_BIAS_MTD,
		    3,
		    "M", "V", "N");

   
  /* How to set a given value in a string parameter? */

  uves_par_new_value("bias_value",
		     CPL_TYPE_INT,
		     "Bias value (only if bias_method = V)",
		     200);

    
  uves_par_new_enum("cubify_sw",
		    CPL_TYPE_STRING,
		    "Cubify switch",
		    DRS_CUBIFY,
		    2,
		    "Y", "N");

 uves_par_new_enum("filt_sw",
		    CPL_TYPE_STRING,
		    "Filter switch",
		    DRS_FILT_SW,
		    2,
		    "none", "median");


  uves_par_new_value("bkg_max_io_win",
		     CPL_TYPE_INT,
		     "Background window number in each full inter order",
		     BKG_MAX_IO_WIN);

  uves_par_new_value("bkg_xy_win_sz_x",
		     CPL_TYPE_INT,
		     "x maximum size of each background window: ",
		     (int)BKG_XY_WIN_SZ[0]);

  uves_par_new_value("bkg_xy_win_sz_y",
		     CPL_TYPE_INT,
		     "y maximum size of each background window: ",
		     (int)BKG_XY_WIN_SZ[1]);


  uves_par_new_value("pixel_thresh_max",
		     CPL_TYPE_INT,
		     "Pixel saturation threshold max",
		     DRS_PTHRE_MAX);

  uves_par_new_value("pixel_thresh_min",
		     CPL_TYPE_INT,
		     "Pixel saturation threshold min",
		     DRS_PTHRE_MIN);

  /*
  uves_par_new_value("input_fmt_cube",
		     CPL_TYPE_BOOL,
		     "Input data format",
		     TRUE);


  uves_par_new_value("output_fmt_cube",
		     CPL_TYPE_BOOL,
		     "Output data format",
		     FALSE);
  */
  uves_par_new_value("drs_k_s_thre",
		     CPL_TYPE_DOUBLE,
		     "Kappa sigma threshold",
		     DRS_K_S_THRE);

  uves_par_new_value("drs_base_name",
		     CPL_TYPE_STRING,
		     "Base name for science products",
		     DRS_BASE_NAME);

 
  uves_par_new_value("drs_maxyshift",
		     CPL_TYPE_DOUBLE,
                     "Half width of the interval to scan for correlation, "
		     "when determining y shift",
		     MAXYSHIFT);


  uves_par_new_value("drs_ext_w_siz",
		     CPL_TYPE_DOUBLE,
                     "Integration window size good: "
                     "10 (if fibre deconvolution works fine)",
		     DRS_EXT_W_SIZ);
    
    /*****************
     *  Rebinning    *
     *****************/
  
    if (cpl_error_get_code() == CPL_ERROR_NONE)
    {
        uves_propagate_parameters_step(UVES_REBIN_ID, parameters, 
				       make_str(FLAMES_OBS_SCIRED_ID), NULL);
    }
  

    /*****************
     *   Merging     *
     *****************/
    
    if (cpl_error_get_code() == CPL_ERROR_NONE)
    {
	cpl_parameter *p;
	char *full_name = NULL;
        name = "merge";

        full_name = uves_sprintf("%s.%s",make_str(FLAMES_OBS_SCIRED_ID),name);
        
        uves_parameter_new_enum(p, full_name,
                       CPL_TYPE_STRING,
                       "Order merging method. If 'optimal', the "
                       "flux in the overlapping region is set "
                       "to the (optimally computed, using the "
                       "uncertainties) average of single order "
                       "spectra. If 'sum', the flux in the "
                       "overlapping region is computed as the "
                       "sum of the single order spectra. If "
                       "flat-fielding is done, method 'optimal' "
                       "is recommended, otherwise 'sum'.",
				make_str(FLAMES_OBS_SCIRED_ID),
                       "optimal",
                       2, 
                       "optimal", "sum");
        
        cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
        cpl_parameterlist_append(parameters, p);
        cpl_free(full_name);


	name = "merge_delt1";
	full_name = uves_sprintf("%s.%s",make_str(FLAMES_OBS_SCIRED_ID), name);
    
	uves_parameter_new_range(p, full_name,
				 CPL_TYPE_DOUBLE,
				 "Order merging left hand (short wavelength) "
				 "cut. To reduce the amount of order "
				 "overlapping regions we allow to cut short and "
				 "long wavelength ranges. "
				 "This may reduce the ripple possibly "
				 "introduced by the order merging. "
				 "Suggested values are: "
				 "10 (W<=390), 12 (390<W<=437, 520<W<=564), "
				 "14 (437<W<=520, 564<W<860), 4 (W>=860) ",
				 make_str(FLAMES_OBS_SCIRED_ID),
				 -1.,-1.,100.);
        
	cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
	cpl_parameterlist_append(parameters, p);
	cpl_free(full_name);


	name = "merge_delt2";
	full_name = uves_sprintf("%s.%s",make_str(FLAMES_OBS_SCIRED_ID), name);
        
	uves_parameter_new_range(p, full_name,
				 CPL_TYPE_DOUBLE,
				 "Order merging right hand (long wavelength) "
				 "cut. To reduce the amount of order "
				 "overlapping regions we allow to cut short and "
				 "long wavelength ranges. "
				 "This may reduce the ripple possibly "
				 "introduced by the order merging. "
				 "Suggested values is 4 for W<860, else 0",
				 make_str(FLAMES_OBS_SCIRED_ID),
				 -1.,-1.,100.);
        
	cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
	cpl_parameterlist_append(parameters, p);
	cpl_free(full_name);


	uves_par_new_value("clean_tmp_products",
	         CPL_TYPE_BOOL,
	         "Input data format",
	         FALSE);







    }

    


  return (cpl_error_get_code() != CPL_ERROR_NONE);

}


/*----------------------------------------------------------------------------*/
/**
  @brief reduce data
  @param  parameters   recipe parameters
  @param  frames       set of frames
  @param  sci          science frame
  @param  master_bias  master bias frame
  @param  ordef        order definition frame
  @param  order_locations   polynomial coefficients describing orders
  @param  chip         CCD chip
  @param  binx         X bin size
  @param  biny         Y bin size
  @param  ext_method       extraction method
  @param  starttime    start time
  @param  t_start      start time
  @param  bias_method  bias subtraction method
  @param  bias_value   level of bias
  @param  ext          extention tables
  @param  fibres_mask  FIBREMASK array
  @param  fibres_pos   FIBREPOS array
  @param  pixel_thresh_min minimum allowed intensity for a pixel
  @param  pixel_thresh_max maximum allowed intensity for a pixel
  @param  filt_sw      filter switch
  @param  drs_k_s_thre      kappa-sigma threshold
  @param  drs_base_name     product file base name
  @param  drs_cor_max_fnd   run correlation?
  @param  drs_cor_def_rng   correlation range
  @param  drs_cor_def_pnt   correlation npoint
  @param  drs_cor_def_off   correlation offset
  @param  drs_maxyshift     max xy shift
  @param  drs_ext_w_siz     extraction window size
  @return reduced science 
**/
/*----------------------------------------------------------------------------*/
static int
flames_reduce(const cpl_parameterlist* parameters,
	      cpl_frameset* frames,
              const cpl_frame *sci,
              const cpl_frame *master_bias,
              const cpl_frame *ordef,
              const cpl_frame *cvel_tab,
	      polynomial *order_locations,
              enum uves_chip chip,
              const int binx,
              const int biny,
              const char *ext_method,
              merge_method m_method,
              const char *starttime,
	      time_t t_start,
              char bias_method,
	      int bias_value,
              cpl_table** ext_sci,
              int* fibres_mask,
              double* fibres_pos,
              int* pixel_thresh_min,
              int* pixel_thresh_max,
              const char *filt_sw,
              const double drs_k_s_thre,
              const char* drs_base_name,
              const char* drs_cor_max_fnd,
              const float drs_cor_def_rng,
              const int drs_cor_def_pnt,
              const float drs_cor_def_off,
              const int drs_corvel_iter,
              const double drs_maxyshift,
              const double drs_ext_w_siz)

{




  //define/local ord_max/i/1/1 0
  //define/local zp/d/1/1 0 


  //FixMe
  const char* dpr_type=NULL;
  const char *bp_sci    = NULL;
  const char* prefid=NULL;
  const char* instid=NULL;

  char bkg_name[80];
  const char* info_tbl_name=NULL;
  int wc=0;


  double t_extract=0;

  cpl_frame* bkg_frm=NULL;
  cpl_frameset* slitff_cat=NULL;
  cpl_frameset* fibff_cat=NULL;
  cpl_frame* b_sci    = NULL;
  cpl_table* info_tbl=NULL;
  cpl_image* b_sci_ima=NULL;

  uves_propertylist* header=NULL;
  cpl_vector* vec=NULL;
  cpl_table        *qclog[1] = {NULL};
  const char *recipe_id = make_str(FLAMES_OBS_SCIRED_ID);
  bool red_ccd_is_new=false;

  //XTABMERGE/FLAMES {parSci} {parFibOrdTab} xt_sci_{prefid}.tbl

  //@p flames_reduce,PREPGRAP              !a) set any graphyc requirenment
  //@p flames_reduce,BIASUBTR {parSci}     !b) subtract bias
  //@p flames_reduce,PREPPA   {parSci}     !c) get frm's sigma & bad pix mask

  //To remove some compilation warnings: FIXME. There should be real code
  cknull_nomsg(sci);
  if(bias_method == 'M' ) {
    cknull(master_bias,"Null input bias");
  }
  //cknull_nomsg(ordef);
  uves_msg_debug("TODO: make work flames_reduce_xtab_merge()");
  uves_free_propertylist(&header);
  check_nomsg(header = uves_propertylist_load(cpl_frame_get_filename(ordef),0));
  check_nomsg(red_ccd_is_new=uves_ccd_is_new(header));

  
  //This leak 1 block
  cknull_nomsg(info_tbl=flames_reduce_xtab_merge(fibres_mask,fibres_pos,ext_sci,chip));
  uves_free_propertylist(&header);

  info_tbl_name=uves_sprintf("bin_table_info_%s.fits",
			     uves_chip_tostring_lower(chip));
       
  check_nomsg(cpl_table_save(info_tbl,NULL,NULL,info_tbl_name,CPL_IO_DEFAULT));
 
  //flames_reduce_prepgrap();        
  uves_msg("flames_reduce_bias_subtract");   

  cknull(b_sci=flames_reduce_bias_subtract(sci,master_bias,bias_method,
					   bias_value,pixel_thresh_max),
	 "Error subtraction bias");

 
  bp_sci    = uves_sprintf("%s%s", "bp_", cpl_frame_get_filename(b_sci));
  uves_msg("flames_crea_bp_ima");   
  check( flames_crea_bp_ima(b_sci, bp_sci,*pixel_thresh_max, chip, binx, biny,ext_sci[0]),
	 "Error creating even frame bad pixel map");


  uves_msg("flames_preppa_process");
  //AMo this changes value of NAXIS1-2 in b_sci   
  check( flames_preppa_process(b_sci,bp_sci,filt_sw,
			       DRS_PTHRE_MIN, DRS_PTHRE_MAX),
	 "Error preparing bias subtracted even frame");
  //cpl_free(bp_sci);

 

  //if "{ext_method(1:1)}" .ne. "q" then
  // @p flames_reduce,PRESLFF            !c) set Slit FF frame names to DRS std
  //endif

  check_nomsg(instid=flames_get_frmid(sci,chip,&wc));
  if(strstr(instid,"re") != NULL) {
    prefid="l";
  } else {
    prefid="u";
  }
  //uves_free(instid);

  if((strcmp(ext_method,"qst") != 0) ||
     (strcmp(ext_method,"qop") != 0) ) {
    uves_msg("flames_reduce_prep_slitff()");
    cknull_nomsg(slitff_cat=flames_reduce_prep_slitff(frames,chip,prefid));
  }
  

  //@p flames_reduce,PREFIBFF              !d) set Fibre FF frame names to DRS std
  //@p flames_reduce,PREBKG                !e) generate a bkg table  





  uves_msg("flames_reduce_prep_fibff()");
  cknull_nomsg(fibff_cat=flames_reduce_prep_fibff(frames,chip,prefid));

  uves_msg("Implement flames_reduce_prep_bkg()");
  sprintf(bkg_name,"%s%s%s","bkg_",prefid,".fits");

  check( flames_create_backtable(cpl_frame_get_filename(ordef),
                                 bkg_name,
                                 &BKG_MAX_IO_WIN,
                                 BKG_XY_WIN_SZ),
         "Failed to create background table");
 
 

  check_nomsg(header=uves_propertylist_load(cpl_frame_get_filename(b_sci),0));
  dpr_type=uves_pfits_get_dpr_type(header);

  bkg_frm=cpl_frame_new();
  cpl_frame_set_group(bkg_frm,CPL_FRAME_GROUP_PRODUCT);
  cpl_frame_set_type(bkg_frm,CPL_FRAME_TYPE_TABLE);
  cpl_frame_set_level(bkg_frm,CPL_FRAME_LEVEL_INTERMEDIATE);
  cpl_frame_set_filename(bkg_frm,bkg_name);
  //bkg_tbl=cpl_table_load(bkg_name,0,0);
  check_nomsg(b_sci_ima=cpl_image_load(cpl_frame_get_filename(b_sci),CPL_TYPE_FLOAT,0,0));

  uves_msg("DPR TYPE: %s",dpr_type);

  //if m$index(dpr_type,"SimCal") .gt. 0 then
  //  FIND/TPIX {parSci} bp.tbl {PATHID}
  //  CORRECT/TPIX {parSci} bp.tbl A
  //endif
  if(strstr(dpr_type,"SimCal") != NULL) {
     uves_correct_badpix_all(b_sci_ima,header,chip,binx,biny,TRUE,red_ccd_is_new);

  }




  
  check( flames_frameset_insert(
				frames,
				CPL_FRAME_GROUP_PRODUCT,
				CPL_FRAME_TYPE_TABLE,
				CPL_FRAME_LEVEL_INTERMEDIATE,
				info_tbl_name,
				FLAMES_INFO_TABLE(chip),
				header,
				parameters,
				recipe_id,
				PACKAGE "/" PACKAGE_VERSION,
				NULL, starttime, true, 0),
	 "Could not add order table %s (%s) to frameset",
	 info_tbl_name, FLAMES_INFO_TABLE(chip));
  //cpl_free(info_tbl_name);
   
  //  cpl_image_save(b_sci_ima, cpl_frame_get_filename(b_sci), 
  //	   CPL_BPP_IEEE_FLOAT,header,CPL_IO_DEFAULT);

  uves_free_image(&b_sci_ima);

  //@p flames_reduce,EXTRACT {parSci} fxb_ !f) extract the science frame

  flames_reduce_extract(b_sci,ordef,bkg_frm,slitff_cat,fibff_cat,prefid,
                        ext_method,drs_k_s_thre,
                        drs_base_name,drs_cor_max_fnd,drs_cor_def_rng,
                        drs_cor_def_pnt,drs_cor_def_off,drs_maxyshift,
                        drs_ext_w_siz,chip,&t_extract);

  //uves_free_frameset(&fibff_cat);
  //uves_free_frame(&bkg_frm);
  //!Here SimCal option may be to be commented out
  //if m$index(dpr_type,"SimCal") .gt. 0 then
  //  @p flames_reduce,REBMER  {parSci} fxb_
  //  if "{DRS_CVEL_SWITCH}" .eq. "Y" then 
  //     define/local OLD_CVEL_MAX/d/1/1 {DRS_CVEL_MAX}
  //     define/local OLD_CVEL_MIN/d/1/1 {DRS_CVEL_MIN}
  //     ord_max = {"wfxb_{prefid}_0001.bdf",NPIX(2)}
  //     w/o {parLinTab}
  //     if m$existd(parLinTab,"ESO.QC.CCF.POSMAX") .eq. 1 then
  //        zp = {{parLinTab},ESO.QC.CCF.POSMAX}
  //     endif
  //     DRS_CVEL_MAX = DRS_CVEL_MAX 
  //     DRS_CVEL_MIN = DRS_CVEL_MIN 


  //     @p flames_reduce,VCORREL fxb_ cvel1 {prefid} {ord_max} {parCorVelTab} _raw0000 _raw0001 {zp}
  //     DRS_CVEL_MAX = DRS_CVEL_MAX + {q1}
  //     DRS_CVEL_MIN = DRS_CVEL_MIN + {q1}

  //     @p flames_reduce,VCORREL fxb_ cvel2 {prefid} {ord_max} {parCorVelTab} _raw0000 _raw0001 {zp}
  //     DRS_CVEL_MAX = OLD_CVEL_MAX
  //     DRS_CVEL_MIN = OLD_CVEL_MIN
  //  endif
  //else
  // @p flames_reduce,REBMER  {parSci} fxb_ !g) rebin and merge it
  //endif



  ck0(flames_reduce_rebmerge(b_sci,ordef,frames,chip,info_tbl,ext_sci[0],parameters,
			     order_locations,drs_base_name,starttime,m_method),
      "failed reb-merging");


  if(strstr(dpr_type,"SimCal") != NULL) {

    if(strcmp(drs_cor_max_fnd,"Y") == 0) {
      if(cvel_tab == NULL) {
	uves_msg_warning("You have data in SimCal mode. ");
	uves_msg_warning("To get corvel QC log You must provide an input CORVEL_MASK");
      } else {


	uves_msg("Computes velocity correction");
	double old_cvel_max=0;
	double old_cvel_min=0;
	double drs_cvel_max=0;
	double drs_cvel_min=0;
	double cvel_max=0;
	//double cvel_min=0;
	double cvel_sig=0;

	int ord_min=0;
	int ord_max=0;
	int nord=0;
        int j=0;
	double ccf_posmax_zero_point=0;
	double ccf_posmax_zero_point_iter0=0;

	char wname[80];
	char mname[80];
	uves_propertylist* whead=NULL;
	uves_propertylist* mhead=NULL;
	cpl_image* img=NULL;
	cpl_table* order_tbl=NULL;
 
	old_cvel_max = DRS_CVEL_MAX;
	old_cvel_min = DRS_CVEL_MIN;
	drs_cvel_max = DRS_CVEL_MAX;
	drs_cvel_min = DRS_CVEL_MIN;
	ord_max=1;
	ccf_posmax_zero_point=0;
      
 
	//Add extra WSTART descriptors to merged FF to 
	//be used to compute vcorrel
	sprintf(wname,"%s%s%s","w",drs_base_name,"_raw0001.fits");
	sprintf(mname,"%s%s%s","mw",drs_base_name,"_raw0001.fits");
	check_nomsg(whead=uves_propertylist_load(wname,0));
	check_nomsg(mhead=uves_propertylist_load(mname,0));
	check_nomsg(vec=cpl_vector_load(mname,0));
	check_nomsg(img=uves_vector_to_image(vec,CPL_TYPE_FLOAT));
	uves_free_vector(&vec);
	check_nomsg(order_tbl=cpl_table_load(cpl_frame_get_filename(ordef),1,0));
	check_nomsg(ord_min=cpl_table_get_column_min(order_tbl,"Order"));
	check_nomsg(ord_max=cpl_table_get_column_max(order_tbl,"Order"));
	uves_free_table(&order_tbl);
	nord=ord_max-ord_min+1;
	ck0_nomsg(flames_reduce_add_wstart(whead,&mhead,nord));
	check_nomsg(uves_save_image(img,mname,mhead,true,true));
	uves_free_image(&img);
     
	check_nomsg(qclog[0] = uves_qclog_init(header,chip));
	uves_msg("cvel max:%g %g",DRS_CVEL_MAX,DRS_CVEL_MIN);



        for(j=0;j<drs_corvel_iter;j++) {
	  check_nomsg(flames_reduce_vcorrel(drs_base_name,
					    "cvel2", 
					    prefid,
					    ord_max,
					    cvel_tab, 
					    "_raw0001", 
					    "_raw0001", 
					    drs_cvel_min,
					    drs_cvel_max,
					    &ccf_posmax_zero_point,
					    &cvel_max,
					    &cvel_sig,
					    qclog[0]));


	  drs_cvel_max +=cvel_max;
	  drs_cvel_min +=cvel_max;
	  if(j==0) {
	    ccf_posmax_zero_point_iter0=cvel_max;;
	  }
	  uves_msg("iter %d cvel max:%g %g",j,drs_cvel_max,drs_cvel_min);
	}

	/*
	check_nomsg(flames_reduce_vcorrel(drs_base_name,
					  "cvel2", 
					  prefid,
					  ord_max,
					  cvel_tab, 
					  "_raw0001", 
					  "_raw0001", 
					  drs_cvel_min,
					  drs_cvel_max,
					  &ccf_posmax_zero_point,
					  &cvel_max,
					  &cvel_sig,
					  qclog[0]));

	drs_cvel_max +=cvel_max;
	drs_cvel_min +=cvel_max;
	*/
	ccf_posmax_zero_point =ccf_posmax_zero_point_iter0;

        ck0_nomsg(uves_qclog_add_double(qclog[0],
				   "QC CCF POSOFF",
				   ccf_posmax_zero_point,
				   "CCF pos avg from ThAr calibration",
				   "%f"));

	uves_msg("cvel max:%g min: %g zp: %g",
		 drs_cvel_max,drs_cvel_min,ccf_posmax_zero_point);


	//DRS_CVEL_MAX=old_cvel_max;
	//DRS_CVEL_MIN=old_cvel_min;

	uves_msg("cvel max:%g %g",DRS_CVEL_MAX,DRS_CVEL_MIN);

      }
    }
  }



  check_nomsg(flames_reduce_proclass(b_sci,ordef,frames,chip,
                                     info_tbl,parameters,order_locations,
				     drs_base_name,starttime,qclog));
  uves_qclog_delete(&qclog[0]);


  //if "{DRS_BLAZE_SW}" .eq. "Y" then
  // @p flames_reduce,COMPEFF xt_sci_{prefid}.tbl fxb_
  //endif
  //uves_msg("flames_reduce_compeff()");
  //if(DRS_BLAZE_SW) {
  //flames_reduce_compeff();
  //}


  //uves_msg("flames_reduce_qclog()");
  //@p flames_reduce,QC  {parSci} fxb_         !h) Dump QC-LOG
  //flames_reduce_qclog();

  uves_msg("end flames_reduce()");

 cleanup:
  uves_qclog_delete(&qclog[0]);
  uves_free_frame(&b_sci);
  uves_free_table(&info_tbl);
  uves_free_propertylist(&header);
  uves_free_vector(&vec);

  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    uves_msg("flames_reduce error");
    return -1;
  } else {
    uves_msg("flames_reduce success");
    return 0;
  }

}


/*---------------------------------------------------------------------------*/
/**
  @brief    Get the command line options and execute the data reduction
  @param    frames      the frames list
  @param    parameters  the parameters list
  @param    starttime   the recipe starting time 
  @return   CPL_ERROR_NONE if everything is ok
 */
/*---------------------------------------------------------------------------*/
static void
flames_obs_scired_exe(cpl_frameset *frames, 
                      const cpl_parameterlist *parameters,
                      const char *starttime)
{


  double* fibres_pos=NULL;

  /* Input images */
  uves_propertylist *rot_header_sci[]  = {NULL, NULL};
 
 
  /* input images */
  cpl_image        *raw_image_sci[]   = {NULL, NULL};
  uves_propertylist *raw_header_sci[]  = {NULL, NULL};
  cpl_frame        *sci               = NULL;    
  cpl_table        *ext_sci[]         = {NULL, NULL};

  /* Calibration */
  cpl_image* master_bias_image = NULL;
  uves_propertylist* master_bias_header = NULL;
  cpl_frame *master_bias = NULL;

  cpl_image *ordef_image = NULL;
  cpl_table *ordef_table = NULL;
  uves_propertylist *ordef_header = NULL;
  uves_propertylist *ordef_xheader = NULL;
  cpl_frame *ordef = NULL;
  uves_propertylist *primary_header = NULL;
  uves_propertylist *table_header = NULL;
  polynomial*   order_locations=NULL;
  cpl_table* order_traces=NULL;
  double tab_in_out_yshift=0;
  int tab_in_out_oshift=0;
  bool guess_table=0;



  /* QC */
  cpl_table *qclog[2] = {NULL, NULL};


  const char *raw_filename_sci = "";


  /* other stuff */
  bool flames = true; /* FLAMES only */
  bool blue = false; /* only RED arm data */
  enum uves_chip chip;
  const char *product_filename = NULL;  
    
  //Really needed?
  time_t t_start;
  int bias_value=0; 
  int binx,biny;

  const char *bias_method_string=NULL;
  char bias_method;
  const char *pid = make_str(FLAMES_OBS_SCIRED_ID);

  const char *recipe_id = pid;

   
  /* the following variables are indeed used in flames_reduce() */
  const char *red_method = NULL;
  const char *drs_cor_max_fnd = NULL;
  int     drs_cor_def_pnt =25;
  float  drs_cor_def_rng = 6.;
  float  drs_cor_def_off = 0.;
  double  dbl_cor_def_rng = 6.;
  double  dbl_cor_def_off = 0.;

  int    drs_corvel_iter = 0;
  int bkg_max_io_win=BKG_MAX_IO_WIN;

  const char *filt_sw=NULL; /* this is used only in flames_preppa() */
  int pixel_thresh_min=0; /* this is used only in flames_creamask() */
  int pixel_thresh_max=0; /* this is used only in flames_creamask() */

  double drs_k_s_thre=0;
  char* drs_base_name=NULL;
  double drs_maxyshift=0;
  double drs_ext_w_siz=DRS_EXT_W_SIZ;
   
  //int input_cubify_switch = 0;
  //int output_cubify_switch = 0;
  int wc=0;

  const char* frmid=NULL;

  cpl_frame* cvel_tab=NULL;

  const char *chip_name = "";
  const char *master_bias_filename = "";
  const char *ordef_filename = "";
  int raw_index = 0;
  int* fibres_mask=NULL;

  merge_method m_method;
  const char *context = NULL;
  char ordef_name[MIN_NAME_SIZE];
  char sci_name[MIN_NAME_SIZE];
  char mbias_name[MIN_NAME_SIZE];
  char prefix[MIN_NAME_SIZE];
  const char* PROCESS_CHIP=NULL;
  int clean_tmp_products=0;


  /* FLAMES specific */

  assure(!cpl_frameset_is_empty(frames), CPL_ERROR_DATA_NOT_FOUND,
       "No input frames...");


  starttime = starttime;
  parameters = parameters;

  


    /*
!@p flames_def_useful_frm_var

define/local BKGFITMETHOD/c/1/80 " " ? +lower_levels
write/key BKGFITMETHOD "median" 

define/local mid2fits/c/1/80 {DRS_MIDAS2FITS} ? +lower_levels
mid2fits = m$upper(mid2fits(1:1))

!procedure id
define/local pid/c/1/80 flames_reduce ? +lower_levels

define/local icat/c/1/80 {p1} ? +lower_levels
define/local ocat/c/1/80 {p2} ? +lower_levels
define/local rcat/c/1/80 {p3} ? +lower_levels

    */
    //Why not read from parameters?
    /*

define/local stdstar/c/1/25 " " ALL +lower_levels
define/local refc/c/1/100 " " ALL +lower_levels
define/local extinc/c/1/100 " " ALL +lower_levels
define/local eff/c/1/100 " " ALL +lower_levels
define/local modext/c/1/25 " " ALL +lower_levels

    */

 
  t_start=time(NULL);
    /* The following parameters should be read in the flames_reduce 

define/local kk/i/1/1 0

kk = m$parse(P4,"par")
if kk .eq. 1 then
   define/local red_method/c/1/10      {par01}           ? +lower_levels
   define/local cor_max_fnd/c/1/1  {DRS_COR_MAX_FND} ? +lower_levels
   define/local cor_def_rng/r/1/1  {DRS_COR_DEF_RNG} ? +lower_levels
   define/local cor_def_pnt/i/1/1  {DRS_COR_DEF_PNT} ? +lower_levels
   define/local cor_def_off/r/1/1  {DRS_COR_DEF_OFF} ? +lower_levels
else if  kk .eq. 2 then
   define/local red_method/c/1/10      {par01}           ? +lower_levels
   define/local cor_max_fnd/c/1/1  {par02}           ? +lower_levels
   define/local cor_def_rng/r/1/1  {DRS_COR_DEF_RNG} ? +lower_levels
   define/local cor_def_pnt/i/1/1  {DRS_COR_DEF_PNT} ? +lower_levels
   define/local cor_def_off/r/1/1  {DRS_COR_DEF_OFF} ? +lower_levels
else if  kk .eq. 3 then
   define/local red_method/c/1/10      {par01}           ? +lower_levels
   define/local cor_max_fnd/c/1/1  {par02}           ? +lower_levels
   define/local cor_def_rng/r/1/1  {par03}           ? +lower_levels
   define/local cor_def_pnt/i/1/1  {DRS_COR_DEF_PNT} ? +lower_levels
   define/local cor_def_off/r/1/1  {DRS_COR_DEF_OFF} ? +lower_levels
else if  kk .eq. 4 then
   define/local red_method/c/1/10      {par01}           ? +lower_levels
   define/local cor_max_fnd/c/1/1  {par02}           ? +lower_levels
   define/local cor_def_rng/r/1/1  {par03}           ? +lower_levels
   define/local cor_def_pnt/i/1/1  {par04}           ? +lower_levels
   define/local cor_def_off/r/1/1  {DRS_COR_DEF_OFF} ? +lower_levels
else if  kk .eq. 5 then
   define/local red_method/c/1/10      {par01}           ? +lower_levels
   define/local cor_max_fnd/c/1/1  {par02}           ? +lower_levels
   define/local cor_def_rng/r/1/1  {par03}           ? +lower_levels
   define/local cor_def_pnt/i/1/1  {par04}           ? +lower_levels
   define/local cor_def_off/r/1/1  {par05}           ? +lower_levels
else
   mess/out 1 {pid} "Wrong number of parameters for p4, max is 4: method, correlation search,range,points,offset"
   return -1
endif 


red_method = m$lower(red_method(1:3))
cor_max_fnd = m$upper(cor_max_fnd(1:1))

*/


  check( uves_get_parameter(parameters, NULL, recipe_id, "ext_method",
                  CPL_TYPE_STRING, &red_method), 
                             "Could not read parameter");


  assure( strlen(red_method) == 3 &&
        red_method[0] == tolower(red_method[0]) &&
        red_method[1] == tolower(red_method[1]) &&
        red_method[2] == tolower(red_method[2]), 
            CPL_ERROR_ILLEGAL_INPUT,
        "Extraction method must be 3 letters, lowercase");


  check( uves_get_parameter(parameters, NULL, recipe_id, "cor_max_fnd",
                  CPL_TYPE_STRING, &drs_cor_max_fnd), 
                             "Could not read parameter");

  assure( strlen(drs_cor_max_fnd) == 1 &&
      drs_cor_max_fnd[0] == toupper(drs_cor_max_fnd[0]),
            CPL_ERROR_ILLEGAL_INPUT,
        "Extraction method must be 1 letter, uppercase");

  check( uves_get_parameter(parameters, NULL, recipe_id, "cor_def_rng",
                  CPL_TYPE_DOUBLE, &dbl_cor_def_rng), 
                             "Could not read parameter");

 
  check( uves_get_parameter(parameters, NULL, recipe_id, "cor_def_pnt",
                  CPL_TYPE_INT, &drs_cor_def_pnt), 
                             "Could not read parameter");

  check( uves_get_parameter(parameters, NULL, recipe_id, "cor_def_off",
                  CPL_TYPE_DOUBLE, &dbl_cor_def_off), 
                             "Could not read parameter");
  drs_cor_def_off=dbl_cor_def_off;
  drs_cor_def_rng=dbl_cor_def_rng;

  check( uves_get_parameter(parameters, NULL, recipe_id, "corvel_iter",
                  CPL_TYPE_INT, &drs_corvel_iter), 
                             "Could not read parameter");
 

 

  check( uves_get_parameter(parameters, NULL, recipe_id, "bkg_max_io_win",
                  CPL_TYPE_INT, &bkg_max_io_win), 
                             "Could not read parameter");
 
    
  {
    int i;
    check( uves_get_parameter(parameters, NULL, recipe_id, "bkg_xy_win_sz_x",
                  CPL_TYPE_INT, &i),"Could not read parameter");
        
    BKG_XY_WIN_SZ[0] = i;
 
    check( uves_get_parameter(parameters, NULL, recipe_id, "bkg_xy_win_sz_y",
                  CPL_TYPE_INT, &i),"Could not read parameter");
    BKG_XY_WIN_SZ[1] = i;
  }


  check( uves_get_parameter(parameters, NULL, recipe_id, "filt_sw",
                CPL_TYPE_STRING, &filt_sw),
                            "Could not read parameter");


  check( uves_get_parameter(parameters, NULL, recipe_id, "pixel_thresh_min",
                CPL_TYPE_INT, &pixel_thresh_min), 
                            "Could not read parameter");

  check( uves_get_parameter(parameters, NULL, recipe_id, "pixel_thresh_max",
                CPL_TYPE_INT, &pixel_thresh_max), 
                            "Could not read parameter");

  check( uves_get_parameter(parameters, NULL, recipe_id, "drs_k_s_thre",
                CPL_TYPE_DOUBLE, &drs_k_s_thre), 
                            "Could not read parameter");
 

  check( uves_get_parameter(parameters, NULL, recipe_id, "drs_base_name",
                CPL_TYPE_STRING, &drs_base_name), 
                            "Could not read parameter");

  check( uves_get_parameter(parameters, NULL, recipe_id, "drs_maxyshift",
                CPL_TYPE_DOUBLE, &drs_maxyshift), 
                            "Could not read parameter");

  check( uves_get_parameter(parameters, NULL, recipe_id, "drs_ext_w_siz",
                CPL_TYPE_DOUBLE, &drs_ext_w_siz), 
                            "Could not read parameter");


    /*
define/local filt_sw/c/1/80 {p6} ? +lower_levels
filt_sw = m$upper(filt_sw)
define/local sat_thr/r/1/1  {p7} ? +lower_levels
define/local cubify_sw/c/1/1  " " ? +lower_levels
define/local sci_csw/c/1/1 " " 
define/local dpr_type/c/1/80 " " all +lower_levels
    */
  check( uves_get_parameter(parameters, NULL, recipe_id,"clean_tmp_products",
                 CPL_TYPE_BOOL, &clean_tmp_products),
                             "Could not read parameter");

/*
  check( uves_get_parameter(parameters, NULL, recipe_id,"input_fmt_cube",
                CPL_TYPE_BOOL, &input_cubify_switch), 
                            "Could not read parameter");

  check( uves_get_parameter(parameters, NULL, recipe_id,"output_fmt_cube",
                CPL_TYPE_BOOL, &output_cubify_switch), 
                            "Could not read parameter");
*/
  check( uves_get_parameter(parameters, NULL, recipe_id, "bias_method",
                CPL_TYPE_STRING, &bias_method_string), 
                        "Could not read parameter");
  
  assure( strlen(bias_method_string) == 1 &&
      bias_method_string[0] == toupper(bias_method_string[0]),
      CPL_ERROR_ILLEGAL_INPUT,
      "Bias method is '%s', should be 1 uppercase character",
      bias_method_string);

  bias_method = bias_method_string[0];


  if (bias_method == 'V')
    {
      check( uves_get_parameter(parameters, NULL, recipe_id, "bias_value",
                CPL_TYPE_INT, &bias_value), 
         "Could not read parameter");
    }

 
  check( m_method = uves_get_merge_method(parameters, context,recipe_id),
           "Could not get merging method");
  m_method = MERGE_FLAMES;
 

    /* The following are not necessary in CPl as anyway are 
       retrieved as parameters

kk = m$parse(P8,"par")
     if kk .eq. 0 then
   sci_csw   = {DRS_SCI_CUBE}
   cubify_sw = {DRS_CUBIFY}
else if kk .eq. 1 then
   sci_csw   = par01
   cubify_sw = {DRS_CUBIFY}
else if  kk .eq. 2 then
   sci_csw   = par01
   cubify_sw = par02
else
   mess/out 1 {pid} "Max subparameters for p8, is 2: DRS_SCI_CUBE,DRS_CUBIFY"
endif

    */



    /* FIXME Here makes sense only if it would be possible to pass a 
       constant in a string parameter 
if m$tstno(p5) .eq. 0 then
   define/local bias_method/c/1/1 m$upper(p5(1:1))  ? +lower_levels
else
   define/local bias_method/r/1/1 {p5}  ? +lower_levels
endif
    */

    /*
  This is useless: provided by EsoRex

t_start = m$secs(); 
    */

                        /*
mess/out 3 {pid} "FLAMES-UVES SCIENCE Reduction Procedure"
mess/out 3 {pid} "At runtime you should be ready to feed the procedure with: "
mess/out 3 {pid} " - an input frame or catalog with splitted raw frame(s)"
mess/out 3 {pid} " - an output product catalogue"
mess/out 3 {pid} " - a reference frame catalogue"
mess/out 3 {pid} " - the extraction method "

                        */

  uves_msg("FLAMES-UVES SCIENCE Reduction Procedure");
  uves_msg("At runtime you should be ready to feed the procedure with: ");
  uves_msg(" - an input frame or catalog with splitted raw frame(s)");
  uves_msg(" - an output product catalogue");
  uves_msg(" - a reference frame catalogue");
  uves_msg(" - the extraction method ");

  //check there is at least one science frame
  assure(
	 cpl_frameset_find(frames, FLAMES_SCI_RED)     != NULL ||
         cpl_frameset_find(frames, FLAMES_SCI_SIM_RED) != NULL ||
         cpl_frameset_find(frames, FLAMES_SCI_COM_RED) != NULL,
         CPL_ERROR_DATA_NOT_FOUND, "No %s or %s or %s in frame set",
         FLAMES_SCI_RED,
         FLAMES_SCI_SIM_RED,
         FLAMES_SCI_COM_RED);  



  /* load input frames */
  if(cpl_frameset_find(frames, FLAMES_SCI_RED)    != NULL) {
    check(flames_load_frame(frames, 
			    &raw_filename_sci,
			    raw_image_sci,
			    raw_header_sci,
			    rot_header_sci,
			    ext_sci,
			    FLAMES_SCI_RED),
	  "No %s in frame set", FLAMES_SCI_RED);

     }


  if(cpl_frameset_find(frames, FLAMES_SCI_COM_RED)    != NULL) {
    check(flames_load_frame(frames, 
			    &raw_filename_sci,
			    raw_image_sci,
			    raw_header_sci,
			    rot_header_sci,
			    ext_sci,
			    FLAMES_SCI_COM_RED),
	  "No %s in frame set", FLAMES_SCI_COM_RED);

     }


  if(cpl_frameset_find(frames, FLAMES_SCI_SIM_RED)    != NULL) {
    check(flames_load_frame(frames, 
			    &raw_filename_sci,
			    raw_image_sci,
			    raw_header_sci,
			    rot_header_sci,
			    ext_sci,
			    FLAMES_SCI_SIM_RED),
	  "No %s in frame set", FLAMES_SCI_SIM_RED);

     }



  check_nomsg(cpl_table_save(ext_sci[0], NULL, NULL, "ext1.fits", 
			     CPL_IO_DEFAULT));
  check_nomsg(cpl_table_save(ext_sci[1], NULL, NULL, "ext2.fits", 
			     CPL_IO_DEFAULT));


  check( binx = uves_pfits_get_binx(raw_header_sci[0]), 
     "Could not read x binning factor from input header");
  check( biny = uves_pfits_get_biny(raw_header_sci[0]), 
     "Could not read y binning factor from input header");





  if( (cvel_tab=cpl_frameset_find(frames, FLAMES_CORVEL_MASK))    != NULL) {
    cvel_tab=cpl_frameset_find(frames, FLAMES_CORVEL_MASK);
     }


    /*


define/local badpxframe/c/1/80 "" all +lower_levels

define/local ifrm/c/1/100 " " all 
define/local ext/c/1/4 " " all
define/local num/i/1/1 0
define/local catal/i/1/1 0
define/local main_prod/c/1/25 " " all 
define/local fid/c/1/80 " " all +lower_levels
define/local prefid/c/1/80 " " all +lower_levels
define/local wlen/i/1/1 0 ? +lower_levels


    */

    /* The following is MIDAS specific 
parse/path {p1}                    !Get file extension.
ext = m$upper(q3)
if ext(1:4) .eq. ".CAT" then            !Check if we got a catalog.
  show/icat {p1} >Null
  num = outputi(1)                !Check number of entries.
  if num .lt. 1 goto ERR1            !No entries in the catalog.
  goto CATALOG
else if ext(1:4) .eq. ".BDF" then
  ifrm = p1
  goto SINGLE
else
  goto ERR2                    !Bad P1 specification
endif


set/format I1                    !Now loop through all
CATALOG:                    !input files.
  store/frame ifrm {p1} 1 FINI
SINGLE:
  mess/out {DRS_MES_LEV} {pid} "Do the SCIENCE reduction for {ifrm}..."
    */

    /*
config/instr {ifrm}
  modext = q2
parSci = ifrm

@p flames_get_frmid {parSci}
fid = q1
prefid = fid
prefid = chip({PATHID})
WLEN = wcenter/10.

if m$existd(parSci,h_dprtype) .gt. 0 then
   dpr_type = "{{parSci},{h_dprtype}}"
endif
if m$index(dpr_type,"SimCal") .gt. 0 then
   DRS_SCI_RAW = "Y"
else
   DRS_SCI_RAW = "N"
endif
    */
    check( uves_get_parameter(parameters, NULL, "uves", 
            "process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
               "Could not read parameter");

  uves_free_double(&fibres_pos);

  /* Loop over two chips */
  for (chip = uves_chip_get_first(blue); 
       chip != UVES_CHIP_INVALID;
       chip = uves_chip_get_next(chip))
    {



      if(strcmp(PROCESS_CHIP,"redu") == 0) {
	chip = uves_chip_get_next(chip);
      }

      //chip = uves_chip_get_next(chip);

      raw_index = uves_chip_get_index(chip);
      sprintf(prefix,"%s%s%c",drs_base_name,"_",uves_chip_tochar(chip));
      sprintf(ordef_name,"%s%c%s","ordef_",uves_chip_tochar(chip),".fits");

      uves_msg("Processing %s chip in '%s'",
           uves_chip_tostring_upper(chip), raw_filename_sci);
      
      check_nomsg( chip_name = uves_pfits_get_chipid(raw_header_sci[raw_index],
                             chip));

    /* load calib input frames

        FIB_LINE_TABLE_x
        FIB_ORDEF_TABLE_x
        MASTER_BIAS_x
        SLIT_FF_DT1_x
        SLIT_FF_DT2_x
        SLIT_FF_BP1_x
        SLIT_FF_BP2_x 
        SLIT_FF_BN1_x
        SLIT_FF_BN2_x
        SLIT_FF_SG1_x
        SLIT_FF_SG2_x
        SLIT_FF_COM_x
        SLIT_FF_NOR_x
        FIB_FF_DT1_x
        FIB_FF_DT2_x
        FIB_FF_BP1_x
        FIB_FF_BP2_x
        FIB_FF_SG1_x
        FIB_FF_SG2_x
        FIB_FF_COM_x
        FIB_FF_NOR_x
        FIB_FF_NSG_x

     */

    if (strcmp(bias_method_string,"M") == 0 ) {
      uves_free_image(&master_bias_image);
      uves_free_propertylist(&master_bias_header);
      check( uves_load_mbias(frames, chip_name,
                 &master_bias_filename,
                 &master_bias_image, 
                                 &master_bias_header,
                 chip),
         "Error loading master bias");
          
      uves_msg_low("Using master bias %s", master_bias_filename);
    } else {
          uves_msg_warning("NULL master bias");
      master_bias = NULL;
    }


    uves_free_double(&fibres_pos);
    uves_free_propertylist(&ordef_header);
    uves_free_propertylist(&ordef_xheader);
    //This generates a leak of 12 blocks
    check( uves_load_ordertable(frames, 
                    flames,
                    chip_name,
                    &ordef_filename,
                    &ordef_table,
                    &ordef_header,
                    &ordef_xheader,
                    &order_locations,
                    &order_traces,
                    &tab_in_out_oshift,
                    &tab_in_out_yshift,
                    &fibres_mask,&fibres_pos,
                    chip, 
                    guess_table),
           "Error loading order definition table");



    uves_msg_low("Using order definition table %s", ordef_filename);
    cknull_nomsg(ordef_table);


    /* Save to local directory */
    uves_free_frame(&ordef);
  
    check_nomsg(ordef= flames_new_frame_table(ordef_name, 
					      ordef_table, 
					      ordef_header,ordef_xheader));



    uves_free_propertylist(&ordef_header);
    uves_free_propertylist(&ordef_xheader);


       /* Save to local directory */
      uves_free_frame(&sci);
      uves_free_frame(&master_bias);
      sprintf(sci_name,"%s%c%s","sci_",uves_chip_tochar(chip),".fits");
      sprintf(mbias_name,"%s%c%s","mbias_",uves_chip_tochar(chip),".fits");

             check_nomsg(sci= flames_new_frame(sci_name, 
                                            raw_image_sci[raw_index], 
                        raw_header_sci[raw_index]));

     if (bias_method == 'M' ) {
       check(master_bias = flames_new_frame(mbias_name,
                        master_bias_image,
                        master_bias_header),
         "Error saving master bias");
     }

     frmid=flames_get_frmid(sci,chip,&wc);
 
     ck0_nomsg(flames_reduce(parameters,
			     frames,
                             sci,
                             master_bias,
                             ordef,
		             cvel_tab,
		             order_locations,
                             chip,
                             binx,
                             biny,
                             red_method,
			     m_method,
			     starttime,
                             t_start,
                             bias_method,
                             bias_value,
                             ext_sci,
                             fibres_mask,
                             fibres_pos,
                             &pixel_thresh_min,
                             &pixel_thresh_max,
                             filt_sw,
                             drs_k_s_thre,
                             prefix,
                             drs_cor_max_fnd,
                             drs_cor_def_rng,
                             drs_cor_def_pnt,
                             drs_cor_def_off,
                             drs_corvel_iter,
                             drs_maxyshift,
                             drs_ext_w_siz));
 
     // if(frmid!= NULL) uves_free(frmid);

      //The following lines need to be verified if necessary.
      uves_free_string_const(&product_filename);
      product_filename = uves_sprintf("fixme");
      
      uves_free_propertylist(&primary_header);
      primary_header = uves_propertylist_new();

      uves_free_propertylist(&table_header);
      table_header = uves_propertylist_new();
      
      uves_qclog_delete(&qclog[raw_index]); 
      qclog[raw_index] = uves_qclog_init(raw_header_sci[raw_index], chip);
      /* fixme: */
     /*
      check( calc_qc(ordef_table,
             0,
             0,
             qclog[raw_index]),
         "Could not compute QC parameters");
     */

     uves_qclog_delete(&qclog[raw_index]); 

      if(strcmp(PROCESS_CHIP,"redl") == 0) {
	chip = uves_chip_get_next(chip);
      }


    } // end loop over chips


  const char* cubify_sw = NULL;
  int cubify_products = 0;
  check(
      uves_get_parameter(parameters, NULL, recipe_id, "cubify_sw", CPL_TYPE_STRING, &cubify_sw),
      "Could not read parameter");

  if (strcmp(cubify_sw, "N") == 0) {
    cubify_products = 0;
  } else {
    cubify_products = 1;
  }

  if (clean_tmp_products) {
    /* Loop over two chips */
    for (chip = uves_chip_get_first(blue); chip != UVES_CHIP_INVALID; chip =
        uves_chip_get_next(chip)) {

      if (strcmp(PROCESS_CHIP, "redu") == 0) {
        chip = uves_chip_get_next(chip);
      }
      flames_clean_tmp_products_sci(chip, cubify_products);
      if (strcmp(PROCESS_CHIP, "redl") == 0) {
        chip = uves_chip_get_next(chip);
      }
    }
  }
    //TODO: get dpr_type

    //reads input data using their DO_CLASSIFICATION
    /*
@p flames_reduce,CONFIG {p3}  
if {q1} .eq. -1 return -1
@p flames_reduce,REDUCE  

if "{sci_csw}" .eq. "Y" then
   @p flames_reduce,FRM_PACK fxb_ pack
endif
@p flames_reduce,PROCLASS {p2} {sci_csw} {parSci} fxb_
main_prod = "{q2}"

if "{mid2fits(1:1)}" .eq. "Y" then
   @p flames_midas2fits {p2}              !extra: simulated MIDAS-FITS conv
endif

    */

    //flames_proclass();



    /* This is useful only in MIDAS 

t_res_tuto = t_all - t_preppa1 
t_drs = t_all - t_res_tuto

mess/out {DRS_MES_LEV} {pid} "Time preppa1    [s]: {t_preppa1}"
mess/out {DRS_MES_LEV} {pid} "Time DRS        [s]: {t_drs}"
mess/out {DRS_MES_LEV} {pid} "residuals       [s]: {t_res_tuto}"
t_all = m$secs()-t_start; mess/out {DRS_MES_LEV} {pid} "Total Time      [s]: {t_all}"



CHECK:
  DRS_CVEL_SWITCH = "Y"
  if ext(1:4) .eq. ".BDF" goto FINI        !single frame -> finished.
  goto CATALOG



FINI:
DRS_BLAZE_SW = "Y"
return 0 {main_prod}

ERR1:
  mess/out 1 {pid} "Empty input catalog !"
  return -1
ERR2:
  mess/out 1 {pid} "You have to specify full name of input frame (.cat, .bdf)!"
  return -1


    */


    //uves_print_cpl_frameset(frames);
 cleanup:

    uves_free_double(&fibres_pos);
    uves_free_int(&fibres_mask);    
    uves_free_propertylist(&ordef_header);
    uves_free_propertylist(&ordef_xheader);
    uves_free_propertylist(&rot_header_sci[0]);
    uves_free_propertylist(&rot_header_sci[1]);
    uves_qclog_delete(&qclog[0]); 
    uves_qclog_delete(&qclog[1]);

    /* input images */
    uves_free_image(&raw_image_sci[0]);
    uves_free_image(&raw_image_sci[1]);
    uves_free_propertylist(&raw_header_sci[0]);
    uves_free_propertylist(&raw_header_sci[1]);
    uves_free_frame(&sci);    
    uves_free_table(&ext_sci[0]);
    uves_free_table(&ext_sci[1]);

    /* Calibration */
    uves_free_image(&master_bias_image); 
    uves_free_propertylist(&master_bias_header);
    uves_free_frame(&master_bias);
    uves_free_image(&ordef_image);
    uves_free_table(&ordef_table);
    uves_free_frame(&ordef);
    uves_free_propertylist(&primary_header);
    uves_free_propertylist(&table_header);
    //uves_free_polynomial(&order_locations);
    uves_free_table(&order_traces);
    if(frmid!= NULL) uves_free(frmid);

  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    //uves_free_imagelist(&obj_cor);
     uves_msg("flames_obs_scired_exe error");
    return;

  } else {
     uves_msg("flames_obs_scired_exe success");
    return;
  }

}


/*---------------------------------------------------------------------------*/
/**
  @brief    Merge extention tables (only UVES part)
  @param    fib_msk     fibres mask
  @param    fib_pos     fibres positions
  @param    ext         input extention tables 
  @return   merged table if everything is ok
 */
/*---------------------------------------------------------------------------*/
static cpl_table*
flames_reduce_xtab_merge(
          int* fib_msk,
          double* fib_pos,
	  cpl_table** ext_sci,
          enum uves_chip chip)
{
  cpl_table* m_tbl=NULL;
  int i=0;
  int status=0;
  cpl_table* x1=NULL;
  cpl_table* x2=NULL;
  cpl_table* tmp=NULL;
  int fib_ord[N_FIBRES_MAX];
  int nmaxfib=0;
  int it=0;
  int ref_button[]={0,3,135,37,169,69,201,103,235};
  //const char** object=NULL;
  double ra[N_FIBRES_MAX];
  double dec[N_FIBRES_MAX];
  double r[N_FIBRES_MAX];
  double r_error[N_FIBRES_MAX];
  double theta[N_FIBRES_MAX];
  double theta_error[N_FIBRES_MAX];

  int button[N_FIBRES_MAX];
  int priority[N_FIBRES_MAX];
  double orient[N_FIBRES_MAX];
  double magnitude[N_FIBRES_MAX];
  //const char** in_tol=NULL;
  int mag_col=1;
  int com_col=1;
  int sel_no=0;
  int sel_raw=0;
  char null_string[10];
  int count=N_FIBRES_MAX;
  char file[80];

  strcpy(null_string," ");
  cknull(ext_sci,"Null input extention tables");
//crossref in_ima in_tab out_tab
//define/parameter p1 ? ima "Enter input fibre mode frame in MIDAS format"
//define/parameter p2 ? tbl "Enter fibre-order table"
//define/parameter p3 ? tbl "Enter output table info"

//define/local in_ima/c/1/80 {p1}
//define/local in_ima_x1/c/1/80 " " all
//define/local in_ima_x2/c/1/80 " " all
//define/local in_tab/c/1/80 {p2}
//define/local out_tab/c/1/80 {p3}

//define/local len/i/1/1 0
//len = m$len(in_ima)
//len = len-6

//in_ima_x1 = "{in_ima(1:{len})}.tbl"
//in_ima_x2 = "{in_ima(1:{len})}a.tbl"


  for(i=0;i<N_FIBRES_MAX;i++) {
    fib_ord[i]=0;
  }

  /*
DONE BEFORE WHEN ORDTAB IS READ
copy/dkey {in_tab} FIBREPOS fib_pos
copy/dkey {in_ima} FIBREMASK fib_msk
  */

  //crea/col {out_tab} FIBREPOS "Pix"   G15.13 R*8
  //crea/col {out_tab} FIBREMASK "None" I10 I*1
  //crea/col {out_tab} FIBREORD  "None" I10 I*1

  m_tbl=cpl_table_new(N_FIBRES_MAX);

  cpl_table_new_column(m_tbl,"FIBREPOS",CPL_TYPE_DOUBLE);
  cpl_table_set_column_unit(m_tbl,"FIBREPOS","Pix");
  cpl_table_set_column_format(m_tbl,"FIBREPOS","% 15.13g");
  cpl_table_fill_column_window_double(m_tbl,"FIBREPOS",0,count,-999.);

  cpl_table_new_column(m_tbl,"FIBREMASK",CPL_TYPE_INT);
  cpl_table_set_column_unit(m_tbl,"FIBREMASK","None");
  cpl_table_set_column_format(m_tbl,"FIBREMASK","% 10d");
  cpl_table_fill_column_window_int(m_tbl,"FIBREMASK",0,count,-999);

  cpl_table_new_column(m_tbl,"FIBREORD",CPL_TYPE_INT);
  cpl_table_set_column_unit(m_tbl,"FIBREORD","None");
  cpl_table_set_column_format(m_tbl,"FIBREORD","% 10d");
  cpl_table_fill_column_window_int(m_tbl,"FIBREORD",0,count,-999);

  for (i = 0; i < N_FIBRES_MAX; i++) {
      if (fib_msk[i] == 1) {
    nmaxfib += 1;
    fib_ord[i]=nmaxfib;
      }
  }
 
  for(it=0;it<N_FIBRES_MAX; it++) {
    if ((fabs(fib_pos[it]) <= 1e-5) && it <= 2) { 
      cpl_table_set(m_tbl,"FIBREPOS",it,-200);
      cpl_table_set(m_tbl,"FIBREMASK",it,fib_msk[it]);
      cpl_table_set(m_tbl,"FIBREORD",it,it);
    } else if ((fabs(fib_pos[it]) <= 1e-5) && it >= 7) {
      cpl_table_set(m_tbl,"FIBREPOS",it,200);
      cpl_table_set(m_tbl,"FIBREMASK",it,fib_msk[it]);
      cpl_table_set(m_tbl,"FIBREORD",it,it);
    } else {
      cpl_table_set(m_tbl,"FIBREPOS",it,fib_pos[it]);
      cpl_table_set(m_tbl,"FIBREMASK",it,fib_msk[it]);
      cpl_table_set(m_tbl,"FIBREORD",it,it);
   }
  }            
   

  for(i=0;i<N_FIBRES_MAX;i++) {
    ra[i]=0;
    dec[i]=0;
    r[i]=0;
    r_error[i]=0;
    theta[i]=0;
    theta_error[i]=0;
    button[i]=0;
    priority[i]=0;
    orient[i]=0;
    magnitude[i]=0;
  }




  /*
crea/col {out_tab} :OBJECT      "None"    A30 C*30
crea/col {out_tab} :RA          "degrees" E15.5 R*8
crea/col {out_tab} :DEC         "degrees" E15.5 R*8
crea/col {out_tab} :R           "microns" E15.5 R*8
crea/col {out_tab} :R_ERROR     "microns" E15.5 R*8
crea/col {out_tab} :THETA       "radians" E15.5 R*8
crea/col {out_tab} :THETA_ERROR "microns" E15.5 R*8
crea/col {out_tab} :TYPE        "None"    A20   C*20
crea/col {out_tab} :BUTTON      "None"    I11   I*2
crea/col {out_tab} :PRIORITY    "None"    I10   I*2
crea/col {out_tab} :ORIENT      "radians" E15.5 R*8
crea/col {out_tab} :IN_TOL      "None"    A9    C*1
  */

 
  check_nomsg(cpl_table_new_column(m_tbl,"OBJECT",CPL_TYPE_STRING));
  cpl_table_set_column_unit(m_tbl,"OBJECT","None");
  cpl_table_set_column_format(m_tbl,"OBJECT","%%30s");
  cpl_table_fill_column_window_string(m_tbl,"OBJECT",0,count,null_string);

  cpl_table_new_column(m_tbl,"RA",CPL_TYPE_DOUBLE);
  cpl_table_set_column_unit(m_tbl,"RA","degrees");
  cpl_table_set_column_format(m_tbl,"RA","% 15.5g");
  cpl_table_fill_column_window_double(m_tbl,"RA",0,count,-999.);

  cpl_table_new_column(m_tbl,"DEC",CPL_TYPE_DOUBLE);
  cpl_table_set_column_unit(m_tbl,"DEC","degrees");
  cpl_table_set_column_format(m_tbl,"DEC","% 15.5g");
  cpl_table_fill_column_window_double(m_tbl,"DEC",0,count,-999.);

  cpl_table_new_column(m_tbl,"R",CPL_TYPE_DOUBLE);
  cpl_table_set_column_unit(m_tbl,"R","microns");
  cpl_table_set_column_format(m_tbl,"R","% 15.5g");
  cpl_table_fill_column_window_double(m_tbl,"R",0,count,-999.);

  cpl_table_new_column(m_tbl,"R_ERROR",CPL_TYPE_DOUBLE);
  cpl_table_set_column_unit(m_tbl,"R_ERROR","microns");
  cpl_table_set_column_format(m_tbl,"R_ERROR","% 15.5g");
  cpl_table_fill_column_window_double(m_tbl,"R_ERROR",0,count,-999.);

  cpl_table_new_column(m_tbl,"THETA",CPL_TYPE_DOUBLE);
  cpl_table_set_column_unit(m_tbl,"THETA","radians");
  cpl_table_set_column_format(m_tbl,"THETA","% 15.5g");
  cpl_table_fill_column_window_double(m_tbl,"THETA",0,count,-999.);

  cpl_table_new_column(m_tbl,"THETA_ERROR",CPL_TYPE_DOUBLE);
  cpl_table_set_column_unit(m_tbl,"THETA_ERROR","radians");
  cpl_table_set_column_format(m_tbl,"THETA_ERROR","% 15.5g");
  cpl_table_fill_column_window_double(m_tbl,"THETA_ERROR",0,count,-999.);

  cpl_table_new_column(m_tbl,"TYPE",CPL_TYPE_STRING);
  cpl_table_set_column_unit(m_tbl,"TYPE","None");
  cpl_table_set_column_format(m_tbl,"TYPE","%%20s");
  cpl_table_fill_column_window_string(m_tbl,"TYPE",0,count,null_string);

  cpl_table_new_column(m_tbl,"BUTTON",CPL_TYPE_INT);
  cpl_table_set_column_unit(m_tbl,"BUTTON","None");
  cpl_table_set_column_format(m_tbl,"BUTTON","% 11d");
  cpl_table_fill_column_window_int(m_tbl,"BUTTON",0,count,-999);

  cpl_table_new_column(m_tbl,"PRIORITY",CPL_TYPE_INT);
  cpl_table_set_column_unit(m_tbl,"PRIORITY","None");
  cpl_table_set_column_format(m_tbl,"PRIORITY","% 10d");
  cpl_table_fill_column_window_int(m_tbl,"PRIORITY",0,count,-999);

  cpl_table_new_column(m_tbl,"ORIENT",CPL_TYPE_DOUBLE);
  cpl_table_set_column_unit(m_tbl,"ORIENT","radians");
  cpl_table_set_column_format(m_tbl,"ORIENT","% 15.5g");
  cpl_table_fill_column_window_double(m_tbl,"ORIENT",0,count,-999.);

  cpl_table_new_column(m_tbl,"IN_TOL",CPL_TYPE_STRING);
  cpl_table_set_column_unit(m_tbl,"IN_TOL","None");
  cpl_table_set_column_format(m_tbl,"IN_TOL","%%9s");
  cpl_table_fill_column_window_string(m_tbl,"IN_TOL",0,count,null_string);


/* TODO
if m$existc("{in_ima_x1}","MAGNITUDE") .gt. 0 then
   crea/col {out_tab} :MAGNITUDE   "None"    E15.5 R*8
   mag_col = 0
endif
if m$existc("{in_ima_x1}","COMMENTS") .gt. 0 then
   crea/col {out_tab} :COMMENTS    "None"    A256  C*256
   com_col = 0
endif
*/


  check_nomsg(x1=cpl_table_duplicate(ext_sci[0]));



  for (i = 0; i< N_FIBRES_MAX; i++) {
    check_nomsg(sel_no=cpl_table_and_selected_int(x1,"BUTTON",CPL_EQUAL_TO,ref_button[i]));
    if(sel_no>0) {
      tmp=cpl_table_extract_selected(x1);


      check_nomsg(cpl_table_set_string(m_tbl,"OBJECT",i,
                  cpl_table_get_string(tmp,"OBJECT",0)));
      check_nomsg(cpl_table_set_double(m_tbl,"RA",i,
                  cpl_table_get_double(tmp,"RA",0,&status)));
      check_nomsg(cpl_table_set_double(m_tbl,"DEC",i,
                  cpl_table_get_double(tmp,"DEC",0,&status)));
      check_nomsg(cpl_table_set_double(m_tbl,"R",i,
                  cpl_table_get_double(tmp,"R",0,&status)));
      check_nomsg(cpl_table_set_double(m_tbl,"R_ERROR",i,
                  cpl_table_get_double(tmp,"R_ERROR",0,&status)));
      check_nomsg(cpl_table_set_double(m_tbl,"THETA",i,
                  cpl_table_get_double(tmp,"THETA",0,&status)));
      check_nomsg(cpl_table_set_double(m_tbl,"THETA_ERROR",i,
                  cpl_table_get_double(tmp,"THETA_ERROR",0,&status)));
      check_nomsg(cpl_table_set_string(m_tbl,"TYPE",i,
                  cpl_table_get_string(tmp,"TYPE",0)));
      check_nomsg(cpl_table_set_int(m_tbl,"BUTTON",i,
                  cpl_table_get_int(tmp,"BUTTON",0,&status)));
      check_nomsg(cpl_table_set_int(m_tbl,"PRIORITY",i,
                  cpl_table_get_int(tmp,"PRIORITY",0,&status)));

      check_nomsg(cpl_table_set_double(m_tbl,"ORIENT",i,
                  cpl_table_get_double(tmp,"ORIENT",0,&status)));
      check_nomsg(cpl_table_set_string(m_tbl,"IN_TOL",i,
                  cpl_table_get_string(tmp,"IN_TOL",0)));
     
      if (mag_col == 0) {
         check_nomsg(cpl_table_set_string(m_tbl,"MAGNITUDE",i,
             cpl_table_get_string(x1,"MAGNITUDE",sel_raw)));
      }
      if (com_col == 0) {
         check_nomsg(cpl_table_set_string(m_tbl,"COMMENTS",i,
             cpl_table_get_string(x1,"COMMENTS",sel_raw)));
      }
      uves_free_table(&tmp);
    } 
     cpl_table_select_all(x1);

 }

   /*
   define/local ii/i/1/1 0
   crea/col {out_tab} :Slit_pt{ii}      "None"    A20   C*16
   crea/col {out_tab} :FPS_pt{ii}       "None"    A8    C*4
   !crea/col {out_tab} :SSN_pt{ii}       "None"    A8    C*4
   !crea/col {out_tab} :PSSN_pt{ii}      "None"    A8    C*4
   crea/col {out_tab} :Retractor_pt{ii} "None"    A20   C*16
   crea/col {out_tab} :BN_pt{ii}        "None"    A8    C*4
   crea/col {out_tab} :FBN_pt{ii}       "None"    A20   C*16
   crea/col {out_tab} :RP_pt{ii}        "None"    A8    C*4
   !crea/col {out_tab} :_370_pt{ii}      "None"    A8    C*4
   crea/col {out_tab} :_400_pt{ii}      "None"    A8    C*4
   crea/col {out_tab} :_420_pt{ii}      "None"    A8    C*4
   !crea/col {out_tab} :_450_pt{ii}      "None"    A8    C*4
   crea/col {out_tab} :_500_pt{ii}      "None"    A8    C*4
   !crea/col {out_tab} :_600_pt{ii}      "None"    A8    C*4
   crea/col {out_tab} :_700_pt{ii}      "None"    A8    C*4
   !crea/col {out_tab} :_870_pt{ii}      "None"    A8    C*4
    */
    

  
/*
define/local ref_rp/c*3/1/{tot_fib} 0 all
define/local match/c/1/3
*/


  /* TODO
  strcpy(ref_rp[0],"   ");
  strcpy(ref_rp[1],"3  ");
  strcpy(ref_rp[2],"135");
  strcpy(ref_rp[3],"169");
  strcpy(ref_rp[4],"69 ");
  strcpy(ref_rp[5],"201");
  strcpy(ref_rp[6],"201");
  strcpy(ref_rp[7],"103");
  strcpy(ref_rp[8],"235");
  */

  /*
define/local raw/i/1/1 0
select/table {in_ima_x2} :Slit.eq."*Uv*" {SESSOUTV}
merge/table {in_ima_x2} &t
crea/col &t :RPN "None" I3  I*2
compute/table &t :RPN = :RP
  */

  //PROBLEMS in cpl_table_duplicate_column
  uves_free_table(&tmp);
  tmp=cpl_table_duplicate(ext_sci[1]);
  cpl_table_select_all(tmp);
  sel_no=cpl_table_and_selected_string(tmp,"Slit",CPL_EQUAL_TO,"Uves1");
  x2=cpl_table_extract_selected(tmp);
  check_nomsg(cpl_table_duplicate_column(m_tbl,"Slit_pt1",x2,"Slit"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"FPS_pt1",x2,"FPS"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"Retractor_pt1",x2,"Retractor"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"BN_pt1",x2,"BN"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"FBN_pt1",x2,"FBN"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"RP_pt1",x2,"RP"));

  check_nomsg(cpl_table_duplicate_column(m_tbl,"_400_pt1",x2,"400"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"_420_pt1",x2,"420"));

  check_nomsg(cpl_table_duplicate_column(m_tbl,"_500_pt1",x2,"500"));

  check_nomsg(cpl_table_duplicate_column(m_tbl,"_700_pt1",x2,"700"));



  uves_free_table(&tmp);
  tmp=cpl_table_duplicate(ext_sci[1]);
  sel_no=cpl_table_and_selected_string(tmp,"Slit",CPL_EQUAL_TO,"Uves2");
  uves_free_table(&x2);
  x2=cpl_table_extract_selected(tmp);


  check_nomsg(cpl_table_duplicate_column(m_tbl,"Slit_pt2",x2,"Slit"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"FPS_pt2",x2,"FPS"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"Retractor_pt2",x2,"Retractor"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"BN_pt2",x2,"BN"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"FBN_pt2",x2,"FBN"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"RP_pt2",x2,"RP"));


  check_nomsg(cpl_table_duplicate_column(m_tbl,"_400_pt2",x2,"400"));
  check_nomsg(cpl_table_duplicate_column(m_tbl,"_420_pt2",x2,"420"));

  check_nomsg(cpl_table_duplicate_column(m_tbl,"_500_pt2",x2,"500"));

  check_nomsg(cpl_table_duplicate_column(m_tbl,"_700_pt2",x2,"700"));


  //cpl_table_insert(x2,cpl_table_extract_selected(tmp),cpl_table_get_nrow(x2));

  //TODO at what raw should we merge ?
  //cpl_table_duplicate_column(x2,"RPN",x2,"RP");
  //check_nomsg(cpl_table_save(x2, NULL, NULL, "x2.fits", CPL_IO_DEFAULT));



/*
do it = 1 {tot_fib}
   select/table &t :RPN.eq.{ref_rp({it})} {SESSOUTV}
   sel_no = outputi(1)
   if {sel_no} .eq. 2 then
      do ii = 1 2         raw = ({ii}-1)*{tot_fib}+{it}
         {out_tab},:Slit_pt{ii},@{it}      = {&t,:Slit,@{raw}}
         {out_tab},:FPS_pt{ii},@{it}       = {&t,:FPS,@{raw}}
         !{out_tab},:SSN_pt{ii},@{it}       = {&t,:SSN,@{raw}}
         !{out_tab},:PSSN_pt{ii},@{it}      = {&t,:SSN,@{raw}}
         {out_tab},:Retractor_pt{ii},@{it} = {&t,:Retractor,@{raw}}
         {out_tab},:BN_pt{ii},@{it}        = {&t,:BN,@{raw}}
         {out_tab},:FBN_pt{ii},@{it}       = {&t,:FBN,@{raw}}
         {out_tab},:RP_pt{ii},@{it}        = {&t,:RP,@{raw}}
         !{out_tab},:_370_pt{ii},@{it}      = {&t,:_370,@{raw}}
         {out_tab},:_400_pt{ii},@{it}      = {&t,:_400,@{raw}}
         {out_tab},:_420_pt{ii},@{it}      = {&t,:_420,@{raw}}
         !{out_tab},:_450_pt{ii},@{it}      = {&t,:_450,@{raw}}
         {out_tab},:_500_pt{ii},@{it}      = {&t,:_500,@{raw}}
         !{out_tab},:_600_pt{ii},@{it}      = {&t,:_600,@{raw}}
         {out_tab},:_700_pt{ii},@{it}      = {&t,:_700,@{raw}}
         !{out_tab},:_870_pt{ii},@{it}      = {&t,:_870,@{raw}}
      enddo
   endif
enddo
*/
  //cpl_table_dum(x2,0,9,stdout);
  strcpy(file,uves_sprintf("m_tbl_%s.fits",uves_chip_tostring_lower(chip)));
  check_nomsg(cpl_table_save(m_tbl, NULL, NULL,file,CPL_IO_DEFAULT));
  //cpl_free(file);

  //cpl_table_dump(m_tbl,0,9,stdout);


/*
select/tab &t all {SESSOUTV}
do ii = 1 2
   select/tab &t :Retractor .eq. "*Calibration*".and.:Slit.eq."*Uves{ii}*" {SESSOUTV}
   raw = {&t.tbl,SELIDX(2)}
   {out_tab},:Slit_pt{ii},@1 = {&t,:Slit,@{raw}}
   {out_tab},:Retractor_pt{ii},@1 = {&t,:Retractor,@{raw}}
   {out_tab},:FPS_pt{ii},@1 = {&t,:FPS,@{raw}}
enddo
select/tab &t all {SESSOUTV}
*/


/*
  check_nomsg(cpl_table_select_all(x2));

  for(ii = 0; ii< 2;ii++) {
    cpl_table_and_selected(x2,"Retractor",CPL_EQUAL_TO,"Calibration");
    cpl_table_and_selected(x2,"Slit",CPL_EQUAL_TO,"Uves");
      //TODO
      //raw = {&t.tbl,SELIDX(2)}

       sprintf(column,"%s%d","Slit_pt",ii);
       cpl_table_set(m_tbl,column,1,cpl_table_get(tmp,"Slit",raw,&status));

       sprintf(column,"%s%d","Retractor",ii);
       cpl_table_set(m_tbl,column,1,cpl_table_get(tmp,"Retractor",raw,&status));

       sprintf(column,"%s%d","FPS_pt",ii);
       check_nomsg(cpl_table_set(m_tbl,column,1,cpl_table_get(tmp,"FPS",raw,&status)));
  }

*/
  /*
!this set of line was were now is the !pippo comment 
!and should fix the xt table order info
  */
  //TODO
  //sort/tab {out_tab} :FIBREPOS 
  //cpl_table_sort(m_tbl,"FIBREPOS",0);

              /*
!merge/tab {out_tab} tmp_{out_tab}
!compute/tab tmp_{out_tab} :FIBREORD = SEQ
!-copy tmp_{out_tab} {out_tab}
              */
 
              //compute/tab {out_tab} :FIBREORD = SEQ
  //TODO
  //check_nomsg(cpl_table_duplicate_column(m_tbl,"FIBREORD",m_tbl,"SEQ"));


  //set/format



  
  
 cleanup:
  uves_free_table(&x1);
  uves_free_table(&x2);
  uves_free_table(&tmp);
  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    //uves_free_imagelist(&obj_cor);
    return NULL;
  } else {
    return m_tbl;
  }
  
}



/*---------------------------------------------------------------------------*/
/**
  @brief    Subtract bias level 
  @param    sci_frm     science frame
  @param    mbia_frm    master bias frame
  @param    bias_method bias subtraction method
  @param    bias_value  bias value
  @param    pixel_thresh_max  maximum intensity value for a pixel
  @return   bias subtracted frame if everything is ok
 */
/*---------------------------------------------------------------------------*/

static cpl_frame*
flames_reduce_bias_subtract(const cpl_frame* sci_frm, 
                            const cpl_frame* mbia_frm,
                            const char bias_method,
                            const double bias_value,
                            int* pixel_thresh_max){

  cpl_frame* b_sci_frm=NULL;
  const char* filename=NULL;
  cpl_image* mbia_ima=NULL;


  cknull(sci_frm,"Null input image");
  if( bias_method == 'M') {
    cknull(mbia_frm,"Null input bias");
  }


  /*
   if "{bias_method}" .eq. "N" then 
       $ln -sf {ifrm} b_{ifrm}  
   else if m$tstno(bias_method) .eq. 1 then
      if m$existd("b_{ifrm}","BIAS_SUBTR") .ne. 0 then
         mess/out 3 {pid} "Bias already subtracted !"
      else
         mess/out 3 {pid} "Subtract bias ..."
         compute/ima b_{ifrm}  = {ifrm} - {bias_method}
         @p flames_add_extra_des {ifrm} b_{ifrm}
         sat_thr = sat_thr - outputr(8)
      endif
   else if "{bias_method}" .eq. "M" then
      if "{parBias}" .eq. "-1" then
          compute/ima b_{ifrm} = {ifrm}
          @p flames_add_extra_des {ifrm} b_{ifrm}
      else
          if m$existd("b_{ifrm}","BIAS_SUBTR") .ne. 0 then
                 mess/out 3 {pid} "Bias already subtracted !"
          else
             mess/out 3 {pid} "Subtract bias ..."
             compute/ima b_{ifrm}  = {ifrm} - {parBias}
             @p flames_add_extra_des {ifrm} b_{ifrm}
             statistic/image {parBias} >Null
             sat_thr = sat_thr - outputr(8)
          endif
      endif
   else 
     mess/out {pid} 1 "Bias subtraction method {bias_method} not supported"
   endif

  */


  if ( bias_method == 'N' ) {   
    uves_msg("No bias subtraction");
    b_sci_frm=cpl_frame_duplicate(sci_frm);
  } else if ( bias_method == 'V' ) {

    /* TODO
      if m$existd("b_{ifrm}","BIAS_SUBTR") .ne. 0 then
         mess/out 3 {pid} "Bias already subtracted !"
      else
    */
    uves_msg("Subtract bias ... value=%f",bias_value);
    b_sci_frm = flames_image_subtract_scalar_create("b_", sci_frm, bias_value);
    //TODO
    //flames_add_extra_des(sci_frm,b_sci_frm);
    //sat_thr = sat_thr - outputr(8)
  } else if ( bias_method == 'M' ) {

    if (mbia_frm == NULL) {
      b_sci_frm=cpl_frame_duplicate(sci_frm);
      flames_add_extra_des(sci_frm, b_sci_frm);
    } else {
      /* TODO
          if m$existd("b_{ifrm}","BIAS_SUBTR") .ne. 0 then
                 mess/out 3 {pid} "Bias already subtracted !"
          else
      */
      //TODO : get sat_thr
      uves_msg("Subtract master bias ...");
      b_sci_frm  = flames_image_subtract_create("b_", sci_frm, mbia_frm);
      filename=cpl_frame_get_filename(b_sci_frm);
      mbia_ima=cpl_image_load(filename,CPL_TYPE_FLOAT,0,0);
      
      //cpl_image_save(mbia_ima,"b_sci.fits", CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
      //flames_add_extra_des(sci_frm, b_sci_frm);
      *pixel_thresh_max -= cpl_image_get_median(mbia_ima);
      uves_free_image(&mbia_ima);
      uves_msg_debug("Updating threshold to=%d",*pixel_thresh_max);
    }
  } else { 
    uves_msg_error("Bias subtraction method %c not supported",bias_method);
  }

 cleanup:
  uves_free_image(&mbia_ima);
  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    uves_check_rec_status(0);
    return NULL;
  } else {

return b_sci_frm;
  }


}

 
/*---------------------------------------------------------------------------*/
/**
  @brief    set slit FF names to DRS standard
  @param    b_frm      bias subtracted frame
  @return   0 if everything is ok
  @doc this is hard coded, due to the fact that DRS uses hardcoded values.
  DRS should sobstitute such hardcoded values from generic keywords
  in which is written the actual name of the frame.
  It is a good idea to use different names for upper an lower chip data
  as the pipe and the user may like to have access to them at any moment

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

static cpl_frameset*
flames_reduce_prep_slitff(cpl_frameset* frames, 
                          enum uves_chip chip,
                          const char* prefid)
{
  const char* src_name=NULL;
  uves_propertylist* head_ref=NULL;
  uves_propertylist* head_out=NULL;
  cpl_frame* frame=NULL;
  cpl_frameset* set_slitff=NULL;
  const int size=80;
  char new_name[size];
  char prefix[size];
  char suffix[size];
  char tag[size];
  int nflats=0;
  int i=0;
  int k=0;





  //get nflats
  check_nomsg(frame=cpl_frameset_find(frames,FLAMES_SLIT_FF_COM(chip)));
  check_nomsg(src_name=cpl_frame_get_filename(frame));
  check_nomsg(head_ref=uves_propertylist_load(src_name,0));
  check_nomsg(nflats=uves_flames_pfits_get_nflats(head_ref));
  uves_free_propertylist(&head_ref);

  snprintf(prefix,size,"%s%s","slitff_",prefid);
  //replicate SLITFF_COMMON
  check_nomsg(set_slitff=cpl_frameset_new());
  sprintf(new_name,"%s%s",prefix,"_common.fits");
  ck0_nomsg(flames_replicate_frame(frames,FLAMES_SLIT_FF_COM(chip),
				   new_name,&set_slitff));
 
  //replicate SLITFF_NORM
  snprintf(new_name,size,"%s%s",prefix,"_norm.fits");
  ck0_nomsg(flames_replicate_frame(frames,FLAMES_SLIT_FF_NOR(chip),
				   new_name,&set_slitff));

 

  //Check if input is in cubes or not
  if(cpl_frameset_find(frames, FLAMES_SLIT_FF_DTC(chip)) != NULL ) {
    uves_msg("decubify");
    ck0_nomsg(flames_my_decubify(frames,chip,1,&set_slitff));
 
  

    /*
    for(i=0;i<nflats;i++) {
      k=i+1;

      strcpy(tag,FLAMES_SLIT_FF_DT(k,chip));
      frame=cpl_frame_new();
      snprintf(new_name,size,"%s%s%s%2.2d%s","slitff_",prefid,"_data",k,".fits");
      check_nomsg(cpl_frame_set_filename(frame,new_name));
      check_nomsg(cpl_frame_set_tag(frame,tag));
      check_nomsg(cpl_frameset_insert(set_slitff,frame));
      uves_frameset_dump(set_slitff);

      strcpy(tag,FLAMES_SLIT_FF_BP(k,chip));
      frame=cpl_frame_new();
      snprintf(new_name,size,"%s%s%s%2.2d%s","slitff_",prefid,"_badpixel",k,".fits");
      check_nomsg(cpl_frame_set_filename(frame,new_name));
      check_nomsg(cpl_frame_set_tag(frame,tag));
      check_nomsg(cpl_frameset_insert(set_slitff,frame));

      strcpy(tag,FLAMES_SLIT_FF_SG(k,chip));
      frame=cpl_frame_new();
      snprintf(new_name,size,"%s%s%s%2.2d%s","slitff_",prefid,"_sigma",k,".fits");
      check_nomsg(cpl_frame_set_filename(frame,new_name));
      check_nomsg(cpl_frame_set_tag(frame,tag));
      check_nomsg(cpl_frameset_insert(set_slitff,frame));

      strcpy(tag,FLAMES_SLIT_FF_BN(k,chip));
      frame=cpl_frame_new();
      snprintf(new_name,size,"%s%s%s%2.2d%s","slitff_",prefid,"_bound",k,".fits");
      check_nomsg(cpl_frame_set_filename(frame,new_name));
      check_nomsg(cpl_frame_set_tag(frame,tag));
      check_nomsg(cpl_frameset_insert(set_slitff,frame));

    }
    */

    
  } else {
    uves_msg("not decubify");
    //replicate data frame i
    for(i=0;i<nflats;i++) {
      k=i+1;
      snprintf(suffix,size,"%2.2d%s",k,".fits");

      strcpy(tag,FLAMES_SLIT_FF_DT(k,chip));
      snprintf(new_name,size,"%s%s%s",prefix,"_data",suffix);
      ck0_nomsg(flames_replicate_frame(frames,tag,new_name,&set_slitff));

      strcpy(tag,FLAMES_SLIT_FF_SG(k,chip));
      snprintf(new_name,size,"%s%s%s",prefix,"_sigma",suffix);
      ck0_nomsg(flames_replicate_frame(frames,tag,new_name,&set_slitff));

      strcpy(tag,FLAMES_SLIT_FF_BP(k,chip));
      snprintf(new_name,size,"%s%s%s",prefix,"_badpixel",suffix);
      ck0_nomsg(flames_replicate_frame(frames,tag,new_name,&set_slitff));

      strcpy(tag,FLAMES_SLIT_FF_BN(k,chip));
      snprintf(new_name,size,"%s%s%s",prefix,"_bound",suffix);
      ck0_nomsg(flames_replicate_frame(frames,tag,new_name,&set_slitff));

    }

  }
    uves_msg("end check");

  /*

define/local nflats/i/1/1 0
define/local it/i/1/1 0

nflats = {{parSlitFFC},NFLATS}

set/formmat i1
if "{parSlitFFN}"  .ne. "-1" then
    $ln -sf {parSlitFFN}  slitff_{prefid}_norm.bdf
endif
if "{parSlitFFC}"  .ne. "-1" then
   $ln -sf {parSlitFFC}  slitff_{prefid}_common.bdf
endif
if "{cubify_sw(1:1)}" .eq. "N" then
   do it = 1 nflats
      if "{parSlitS0{it}}"  .ne. "-1" then
         $ln -sf {parSlitS0{it}}  slitff_{prefid}_sigma0{it}.bdf
      endif
      if "{parSlitBP{it}}"  .ne. "-1" then
         $ln -sf {parSlitBP{it}}  slitff_{prefid}_badpixel0{it}.bdf
      endif
      if "{parSlitBND{it}}" .ne. "-1" then
         $ln -sf {parSlitBND{it}} slitff_{prefid}_bound0{it}.bdf
      endif
      if "{parSlitFF{it}}"  .ne. "-1" then
         $ln -sf {parSlitFF{it}}  slitff_{prefid}_data0{it}.bdf
      endif
   enddo
else
   $ln -sf {parSlitFFcube} slitff_{prefid}_dtc.bdf
   $ln -sf {parSlitSGcube} slitff_{prefid}_sgc.bdf
   $ln -sf {parSlitBPcube} slitff_{prefid}_bpc.bdf
   $ln -sf {parSlitBNcube} slitff_{prefid}_bnc.bdf
   @p flames_my_decubify slitff_{prefid} 1 {parSlitFFC}

   do it = 1 nflats
      parSlitFF{it}  = "slitff_{prefid}_data0{it}.bdf"
      parSlitS0{it}  = "slitff_{prefid}_sigma0{it}.bdf"
      parSlitBP{it}  = "slitff_{prefid}_badpixel0{it}.bdf"
      parSlitBND{it} = "slitff_{prefid}_bound0{it}.bdf"
   enddo
endif
crea/icat outslitff_{prefid}.cat null  {SESSOUTV} 
do it = 1 nflats
   add/icat outslitff_{prefid}.cat slitff_{prefid}_data0{it}.bdf {SESSOUTV}
enddo

add/icat outslitff_{prefid}.cat slitff_{prefid}_norm.bdf  {SESSOUTV}
add/icat outslitff_{prefid}.cat slitff_{prefid}_common.bdf  {SESSOUTV}
  */


 cleanup:
  uves_free_propertylist(&head_ref);
  uves_free_propertylist(&head_out);
    

  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    uves_free_frameset(&set_slitff);
    return NULL;
  } else {
    return set_slitff;
  }

}
 
/*---------------------------------------------------------------------------*/
/**
  @brief    to set fibre FF names to DRS standard
  @param    frames     set of frames
  @param    chip       detector chip
  @param    prefid     frame prefix
  @return   0 if everything is ok

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

static cpl_frameset*
flames_reduce_prep_fibff(cpl_frameset* frames, 
                         enum uves_chip chip,
                         const char* prefid){

  char new_name[80];

  char tag[80];
  uves_propertylist* head_ref=NULL;
  uves_propertylist* head_out=NULL;
  cpl_frame* frame=NULL;
  cpl_frameset* set_fibff=NULL;
  //TODO: nflats should be determined on the fly
  int nflats=2;
  int i=0;
  int k=0;


  
  //FIB_FF_COMMON
  check_nomsg(set_fibff=cpl_frameset_new());
  sprintf(new_name,"%s%s%s","fibreff_",prefid,"_common.fits");
  ck0_nomsg(flames_replicate_frame(frames,FLAMES_FIB_FF_COM(chip),new_name,&set_fibff));
  check_nomsg(frame=cpl_frameset_find(frames,FLAMES_FIB_FF_COM(chip)));
  check_nomsg(head_ref=uves_propertylist_load(cpl_frame_get_filename(frame),0));
  check_nomsg(nflats=uves_flames_pfits_get_nflats(head_ref));
  uves_free_propertylist(&head_ref);

  //FIB_FF_NORM
  sprintf(new_name,"%s%s%s","fibreff_",prefid,"_norm.fits");
  ck0_nomsg(flames_replicate_frame(frames,FLAMES_FIB_FF_NOR(chip),new_name,&set_fibff));

  //FIB_FF_NSIGMA
  sprintf(new_name,"%s%s%s","fibreff_",prefid,"_nsigma.fits");
  ck0_nomsg(flames_replicate_frame(frames,FLAMES_FIB_FF_NSG(chip),new_name,&set_fibff));

  
  if(cpl_frameset_find(frames, FLAMES_FIB_FF_DTC(chip)) != NULL ) {


    ck0_nomsg(flames_my_decubify(frames,chip,2,&set_fibff));

    /*
    for(i=0;i<nflats;i++) {
      k=i+1;

      strcpy(tag,FLAMES_FIB_FF_DT(k,chip));
      frame=cpl_frame_new();
      sprintf(new_name,"%s%s%s%2.2d%s","fibreff_",prefid,"_data",k,".fits");
      check_nomsg(cpl_frame_set_filename(frame,new_name));
      check_nomsg(cpl_frame_set_tag(frame,tag));
      check_nomsg(cpl_frameset_insert(set_fibff,frame));

      strcpy(tag,FLAMES_FIB_FF_BP(k,chip));
      frame=cpl_frame_new();
      sprintf(new_name,"%s%s%s%2.2d%s","fibreff_",prefid,"_badpixel",k,".fits");
      check_nomsg(cpl_frame_set_filename(frame,new_name));
      check_nomsg(cpl_frame_set_tag(frame,tag));
      check_nomsg(cpl_frameset_insert(set_fibff,frame));

      strcpy(tag,FLAMES_FIB_FF_SG(k,chip));
      frame=cpl_frame_new();
      sprintf(new_name,"%s%s%s%2.2d%s","fibreff_",prefid,"_sigma",k,".fits");
      check_nomsg(cpl_frame_set_filename(frame,new_name));
      check_nomsg(cpl_frame_set_tag(frame,tag));
      check_nomsg(cpl_frameset_insert(set_fibff,frame));

    }
    */


  } else {

    for(i=0;i<nflats;i++) {
      k=i+1;
      strcpy(tag,FLAMES_FIB_FF_DT(k,chip));
      sprintf(new_name,"%s%s%s%d%d%s","fibreff_",prefid,"_data",0,k,".fits");
      ck0_nomsg(flames_replicate_frame(frames,tag,new_name,&set_fibff));

      strcpy(tag,FLAMES_FIB_FF_BP(k,chip));
      sprintf(new_name,"%s%s%s%d%d%s","fibreff_",prefid,"_badpixel",0,k,".fits");
      ck0_nomsg(flames_replicate_frame(frames,tag,new_name,&set_fibff));

      strcpy(tag,FLAMES_FIB_FF_SG(k,chip));
      sprintf(new_name,"%s%s%s%d%d%s","fibreff_",prefid,"_sigma",0,k,".fits");
      ck0_nomsg(flames_replicate_frame(frames,tag,new_name,&set_fibff));


    }
  }
  

 cleanup:
  uves_free_propertylist(&head_ref);
  uves_free_propertylist(&head_out);

  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    uves_free_frameset(&set_fibff);
    return NULL;
  } else {
    return set_fibff;
  }

}



/*---------------------------------------------------------------------------*/
/**
  @brief This extract the science frame
  @param  sci               science frame
  @param  ordpos            orderposition frame
  @param  bkg_frm           background frame
  @param  slitff_frm        slit flat field set of frames 
  @param  fibff_frm         fiber flat field set of frames
  @param  prefid            prefix id
  @param  method            extraction method
  @param  drs_k_s_thre      kappa-sigma threshold
  @param  drs_base_name     product file base name
  @param  drs_cor_max_fnd   run correlation?
  @param  drs_cor_def_rng   correlation range
  @param  drs_cor_def_pnt   correlation npoint
  @param  drs_cor_def_off   correlation offset
  @param  drs_maxyshift     max xy shift
  @param  drs_ext_w_siz     extraction window size
  @param  chip              detector chip
  @param  t_extract         extraction time
  @return   0 if everything is ok

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

static int
flames_reduce_extract(const cpl_frame* sci, 
                      const cpl_frame* ordpos, 
                      const cpl_frame* bkg_frm, 
                      const cpl_frameset* slitff_set,
                      const cpl_frameset* fibff_set,
                      const char* prefid,
                      const char* method,
                      const double drs_k_s_thre,
                      const char* drs_base_name,
                      const char*  drs_cor_max_fnd,
                      const float drs_cor_def_rng,
                      const int    drs_cor_def_pnt,
              const float drs_cor_def_off,
                      const double drs_maxyshift,
                      const double drs_ext_w_siz,
                      enum uves_chip chip,
              double* t_extract) 
{


  uves_propertylist* plist=NULL;
  cpl_image* img=NULL;
  *t_extract = time(NULL);

 
  /*
!This entry extracts the fibres
define/parameter p1 ? ima "Enter input frame"
define/parameter p2 ? c   "Enter extracted spectra prefix"

define/local ifrm/c/1/80 {p1}
define/local opfx/c/1/80 {p2}
  */

  //AMo: To be able to use old CDB with new DRS we check a 
  //few descriptors and eventually add them with proper value.
  
  /*
if m$existd("fibreff_{prefid}_common.bdf","SHIFTABLE") .eq. 0 then
   mess/out 2 {pid} "adding SHIFTABLE and NORMALISED descriptors"
   write/descriptor fibreff_{prefid}_common.bdf SHIFTABLE/c/1/1 y
   write/descriptor fibreff_{prefid}_common.bdf NORMALISED/c/1/1 y
endif
  */
    
  //check_nomsg(frm=cpl_frameset_find(fibff_set,FLAMES_FIB_FF_COM(chip)));
  //sprintf(name,"%s%s%s","fibreff_",prefid,"_common.fits");
  //sprintf(name,cpl_frame_get_filename(frm));
  //check_nomsg(plist=uves_propertylist_load(name,0));


  //uves_msg("ex0 name=%s",name);
  /*
  if(CPL_ERROR_NONE != uves_propertylist_get_string(plist,"SHIFTABLE")) {
  check_nomsg(img=cpl_image_load(name,CPL_TYPE_FLOAT,0,0));
     uves_propertylist_append_string(plist,"SHIFTABLE","y");
     uves_propertylist_append_string(plist,"NORMALISED","y");
     uves_image_save(img, name, CPL_BPP_IEEE_FLOAT,plist,CPL_IO_DEFAULT);
     uves_free_image(&img);
     uves_free_propertylist(&plist);
    } else {
    cpl_error_reset();
  }
  */

  /*
t_ext = m$secs();
  */

 
  ck0_nomsg(flames_extract_frame(sci,ordpos,bkg_frm,
                                 slitff_set,fibff_set,prefid,
                                 drs_base_name,drs_k_s_thre,
                                 method,drs_cor_max_fnd,drs_cor_def_rng,
                                 drs_cor_def_pnt,drs_cor_def_off,drs_maxyshift,
                                 drs_ext_w_siz));

 

  /*
if OUTPUTI(2) .ne. 0 then
   DRS_CHI2_RED = OUTPUTI(1)/OUTPUTI(2)
endif
DRS_BKG_PIX = OUTPUTI(3)
if m$existd("middumma.tbl","DRS_Y_SHIFT") .gt. 0 then
   DRS_Y_SHIFT = {middumma.tbl,DRS_Y_SHIFT}
endif


t_ext = m$secs()-t_ext; 
mess/out {DRS_MES_LEV} {pid} "Time EXT        [s]: {t_ext}"

  */


  *t_extract = difftime(time(NULL), *t_extract);
  uves_msg("extract = %.2f s", *t_extract);


 cleanup:
    uves_free_image(&img);
    uves_free_propertylist(&plist);

  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    return -1;
  } else {
    return 0;
  }


}



/*---------------------------------------------------------------------------*/
/**
  @brief This extract the science frame
  @param  sci               science frame
  @param  ordpos            orderposition frame
  @param  bkg_frm           background frame
  @param  slitff_frm        slit flat field set of frames 
  @param  fibff_frm         fiber flat field set of frames
  @param  prefid            prefix id
  @param  base_name         product file name
  @param  drs_k_s_thre      kappa-sigma threshold
  @param  method            extraction method
  @param  drs_cor_max_fnd   run correlation?
  @param  drs_cor_def_rng   correlation range
  @param  drs_cor_def_pnt   correlation npoint
  @param  drs_cor_def_off   correlation offset
  @param  drs_maxyshift     max xy shift
  @param  drs_ext_w_siz     extraction window size
  @return   0 if everything is ok

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

static int
flames_extract_frame(const cpl_frame* sci,
                     const cpl_frame* ordtab,
                     const cpl_frame* bkg_frm,
                     const cpl_frameset* slitff_set,
                     const cpl_frameset* fibff_set,
                     const char*  prefid,
                     const char*  base_name,
                     const double drs_k_s_thre,
                     const char*  method,
                     const char*  drs_cor_max_fnd,
                     const float drs_cor_def_rng,
                     const int    drs_cor_def_pnt,
                     const float drs_cor_def_off,
             const double drs_maxyshift,
                     const double drs_ext_w_siz)
{


  /*
DEFINE/PARAMETER P1 ? IMA "Enter frame whose spectrum is to be extracted: "
DEFINE/PARAMETER P2 ? c "Enter fibre FF catalog, slit FF catalog: "
DEFINE/PARAMETER P3 ? c "Enter inter/order table, order/fibre table: "
DEFINE/PARAMETER P4 {DRS_BASE_NAME} C "Enter the basename for the spectrum files: "
DEFINE/PARAMETER P5 {DRS_K_S_THRE} N "Enter kappa-sigma clipping threshold: "
DEFINE/PARAMETER P6 {DRS_EXT_MTD} C "Enter the extraction method: "

define/local method/c/1/10 {P6}
method = m$lower(method(1:3))
DEFINE/LOCAL IN_A/c*160/1/1 {P1}
  */

  const char* IN_A=NULL;
  //const char* IN_B=NULL;
  //const char* IN_C=NULL;
  const char* IN_D=NULL;
  const char* IN_E=NULL;


  const double max_dis_card_fract=MAXDISCARDFRACT;
  const int    max_back_iters= MAXBACKITERS;
  const int    max_corr_iters=MAXCORRITERS;
  const int    min_opt_iters_int=MINOPTITERSINT;
  const int    max_opt_iters_int=MAXOPTITERSINT;
  const int    x_kill_size=XKILLSIZE;
  const int    y_kill_size=YKILLSIZE;

  int  bkg_pol[2]={DRS_BKG_FIT_POL[0],DRS_BKG_FIT_POL[1]};

  const char * bkg_fit_in_line=BKGFITINLINE;
  const char * bkg_fit_method="median"; //AMo: Allways median!
  
  const char * bkg_bad_scan=BKGBADSCAN;
  int  bkg_bad_win[2]={BKGBADWIN[0],BKGBADWIN[1]};

  const double bkg_bad_max_frac=BKGBADMAXFRAC;
  const int bkg_bad_max_tot=BKGBADMAXTOT;
  //const double sigma=drs_k_s_thre;
  //const double max_y_shift=drs_maxyshift;
  const double correl_tol=CORRELTOL;
  //const double correl_x_step=CORRELXSTEP;
  const int correl_x_step_int=(int)CORRELXSTEP;


  //const char * cor_max_fnd=drs_cor_max_fnd;
  //const float * cor_def_rng=drs_cor_def_rng;
  //const int *   cor_def_pnt=drs_cor_def_off;
  //const float * cor_def_off=drs_cor_def_off;
  char   cor_tab_shp_id[80];
  double      outputd=0;
  int          outputi=0;


  char mess1[80] = "I'm starting with the standard extraction...";
  char mess2[80] = "The sigma which will be used for the background is %f";
  char mess3[80] = "The integration window which will be used is %d";

 
  check_nomsg(IN_A=cpl_frame_get_filename(sci));
  check_nomsg(IN_D=cpl_frame_get_filename(bkg_frm));
  check_nomsg(IN_E=cpl_frame_get_filename(ordtab));
  uves_msg_debug("IN_A: infile : %s",IN_A);
  uves_msg_debug("IN_D: infile : %s",IN_D);
  uves_msg_debug("IN_E: orderfile : %s",IN_E);

  sprintf(cor_tab_shp_id,"%s%s%s","cor_shape_",prefid,".fits");





  /*
define/local k/i/1/1 0
k = m$parse(p2,"par")
if k .eq. 2 .and. "{method(1:1)}" .ne. "q" then
   DEFINE/LOCAL IN_B/c*160/1/1 {par01}
   DEFINE/LOCAL IN_C/c*160/1/1 {par02}
else if k .eq. 1 .and. "{method(1:1)}" .eq. "q" then
   DEFINE/LOCAL IN_B/c*160/1/1 {par01}
else
  mess/out 1 {pid} "Wrong number of parameters for p2, should be 2: fibre FF catalog and slit FF catalogue"
  return -1
endif 


k = m$parse(P3,"par")
if k .eq. 2 then
   DEFINE/LOCAL IN_D/c*160/1/1 {par01}
   DEFINE/LOCAL IN_E/c*160/1/1 {par02}
else
   mess/out {DRS_MES_LEV} {pid} "Wrong number of parameters for p3, should be 2:
   inter/order table, order/fibre table"
   return -1
endif 

DEFINE/LOCAL BASENAME/C*160/1/1 {P4}
DEFINE/LOCAL SIGMA/D/1/1 {P5}
  */


 



  if ((strcmp(method,"opt") == 0) || 
      (strcmp(method,"fop") == 0)) {

    /*
   DEFINE/PARAM P7 {DRS_MAXYSHIFT} N "Enter max allowable shift to be checked in the correlation function:"
   WRITE/KEYWORD DRS_MAXYSHIFT {P7}
   WRITE/KEYWORD HISTORY EXTRACT/FLAMES
    */
    uves_msg(mess1);
    uves_msg(mess2,drs_k_s_thre);
    
  } else if ((strcmp(method,"std") == 0) || 
             (strcmp(method,"fst") == 0) ) {
  /*
   DEFINE/PARAM P7 {DRS_EXT_W_SIZ} N "Enter integration window size (for standard extraction):"
   DEFINE/LOCAL WINDOW/D/1/1 {P7}
   WRITE/KEYWORD HISTORY EXTRACT/FLAMES
  */
    uves_msg(mess1);
    uves_msg(mess2,drs_k_s_thre);
    uves_msg(mess3,drs_maxyshift);

  } else if (strcmp(method,"qst") == 0) {

  /*
   DEFINE/PARAM P7 {DRS_EXT_W_SIZ} N "Enter integration window size (for standard extraction):"
   DEFINE/LOCAL WINDOW/D/1/1 {P7}
   WRITE/KEYWORD HISTORY EXTRACT/FLAMES
  */

    uves_msg(mess1);
    uves_msg(mess2,drs_k_s_thre);
    uves_msg(mess3,drs_maxyshift);


  } else if (strcmp(method,"qop") == 0) {

//WRITE/KEYWORD HISTORY EXTRACT/FLAMES
  } else {
    uves_msg_error("Extraction method %s unknown. Exit.",method);
    return -1;
  }


  if ((strcmp(method,"opt") == 0) ||
      (strcmp(method,"std") == 0) ) {

  //WRITE/KEYWORD HISTORY EXTRACT/FLAMES

   
  }
  if (strcmp(method,"opt") == 0) {
     

    uves_msg("run: flames_mainopt");
    uves_msg_debug("IN_A: infile : %s",IN_A);
    uves_msg_debug("IN_E: orderfile : %s",IN_E);
    uves_msg_debug("bkg_fit_in_line=%s",bkg_fit_in_line);
    uves_msg_debug(" bkg_fit_method=%s", bkg_fit_method);
    uves_msg_debug("bkg_bad_scan=%s",bkg_bad_scan);
    uves_msg_debug("fnd=%s",drs_cor_max_fnd);
    uves_msg_debug("rng=%f",drs_cor_def_rng);
    uves_msg_debug("pnt=%d",drs_cor_def_pnt);
    uves_msg_debug("off=%f",drs_cor_def_off);


    check_nomsg(flames_mainopt(IN_A,
			       fibff_set,
                               slitff_set,
                               IN_D,
                               IN_E,                  //5
                               base_name,
                               &max_dis_card_fract,
                               &max_back_iters,
                               &max_corr_iters,
                               &min_opt_iters_int,  //10
                               &max_opt_iters_int,
                               &x_kill_size,
                               &y_kill_size,
                               bkg_pol,
                               bkg_fit_in_line, //15
                               bkg_fit_method,
                               bkg_bad_scan,
                               bkg_bad_win,
                               &bkg_bad_max_frac,
                               &bkg_bad_max_tot,//20
                               &drs_k_s_thre,
                               &drs_maxyshift,
                               &correl_tol,   
                               &correl_x_step_int,
                               drs_cor_max_fnd,//25
                               &drs_cor_def_rng,
                               &drs_cor_def_pnt,
                               &drs_cor_def_off,
                               cor_tab_shp_id,
                               &outputd,
                               &outputi));


 
       
  } else if (strcmp(method,"fop") == 0) {

    uves_msg("run: flames_mainoptfast");
    
    ck0_nomsg(flames_mainoptfast(IN_A,
                                 fibff_set,
                                 slitff_set,
                                 IN_D,
                                 IN_E,   //5
                                 base_name,
                                 &max_dis_card_fract,
                                 &max_back_iters,
                                 &min_opt_iters_int,
                                 &max_opt_iters_int,  //10
                                 &x_kill_size,
                                 &y_kill_size,
                                 bkg_pol,
                                 bkg_fit_in_line,    
                                 bkg_fit_method,  //15
                                 bkg_bad_scan,
                                 bkg_bad_win,
                                 &bkg_bad_max_frac, //20
                                 &bkg_bad_max_tot,
                                 &drs_k_s_thre,
                                 &outputd,
                                 &outputi));
    
  } else if (strcmp(method,"qop") == 0) {
 
    uves_msg("run: flames_mainoptquick");
       
    ck0_nomsg(flames_mainoptquick(IN_A,
                                  fibff_set,
                                  IN_D,
                                  IN_E,
                                  base_name,
                                  &max_dis_card_fract,
                                  &max_back_iters,
                                  &min_opt_iters_int,
                                  &max_opt_iters_int,
                                  &x_kill_size,
                                  &y_kill_size,
                                  bkg_pol,
                                  bkg_fit_in_line,
                                  bkg_fit_method,
                                  bkg_bad_scan,
                                  bkg_bad_win,
                                  &bkg_bad_max_frac,
                                  &bkg_bad_max_tot,
                                  &drs_k_s_thre,
                                  &outputd,
                                  &outputi));
       
  } else if (strcmp(method,"qst") == 0) {
      
    uves_msg("run: flames_mainstandquick");

    ck0_nomsg(flames_mainstandquick(IN_A,
                                    fibff_set,
                                    IN_D,
                                    IN_E,
                                    base_name,           //5
                                    &max_dis_card_fract,
                                    &max_back_iters,
                                    bkg_pol,
                                    bkg_fit_in_line,        //10
                                    bkg_fit_method,
                                    bkg_bad_scan,
                                    bkg_bad_win,
                                    &bkg_bad_max_frac,       //15
                                    &bkg_bad_max_tot,
                                    &drs_k_s_thre,
                                    &drs_ext_w_siz,
                                    &outputd,
                                    &outputi));             //20
      
       
  } else if (strcmp(method,"std") == 0) {

    uves_msg("run: flames_mainstand");
       
    ck0_nomsg(flames_mainstand(IN_A,
			       fibff_set,
                               slitff_set,
                               IN_D,
                               IN_E,                //5
                               base_name,
                               &max_dis_card_fract,
                               &max_back_iters,
                               &max_corr_iters,
                               bkg_pol,   //10
                               bkg_fit_in_line,
                               bkg_fit_method,
                               bkg_bad_scan,
                               bkg_bad_win,  
                               &bkg_bad_max_frac, //15
                               &bkg_bad_max_tot,
                               &drs_k_s_thre,
                               &drs_ext_w_siz,  
                               &drs_maxyshift,
                               &correl_tol,     //20
                               &correl_x_step_int,
                               drs_cor_max_fnd,
                               &drs_cor_def_rng, 
                               &drs_cor_def_pnt,
                               &drs_cor_def_off,//25
                               cor_tab_shp_id,
                               &outputd,
                               &outputi));      //30
    
       
  } else if (strcmp(method,"fst") == 0) {
      
    uves_msg("run: flames_mainstandfast");

    ck0_nomsg(flames_mainstandfast(IN_A,
                                   fibff_set,
                                   slitff_set,
                                   IN_D,
                                   IN_E,        //5
                                   base_name,
                                   &max_dis_card_fract,
                                   &max_back_iters,
                                   bkg_pol,
                                   bkg_fit_in_line, //10
                                   bkg_fit_method,
                                   bkg_bad_scan,
                                   bkg_bad_win,
                                   &bkg_bad_max_frac,
                                   &bkg_bad_max_tot,//15
                                   &drs_k_s_thre,
                                   &drs_ext_w_siz,
                                   &outputd,
				   &outputi));
       
  } else {
    uves_msg_error("Extraction method {method} unknown. Exit.");
    return -1;
  }

  
  uves_msg("exit from %s",cpl_func);
cleanup:
  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    //uves_free_imagelist(&obj_cor);
    uves_msg_error("Fail of %s",cpl_func);
    return -1;
  } else {
    return 0;
  }


}
/*---------------------------------------------------------------------------*/
/**
  @brief this entry rebins and merge the data
  @param    ifrm        input science frame
  @param    ordef       order definition frame
  @param    frames      set of frames 
  @param    chip        detector chip id
  @param    xtab        binary table
  @param    parameters  recipe parameters
  @param    order_locations  order locations
  @param    start_time       start time
  @return   0 if everything is ok

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

static int
flames_reduce_rebmerge(const cpl_frame* ifrm, 
                       const cpl_frame* ordef, 
                       cpl_frameset* frames,
		       enum uves_chip chip,
                       cpl_table* xtab,
                       const cpl_table* ozpoz,
		       const cpl_parameterlist *parameters, 
		       polynomial *order_locations,
                       const char* drs_base_name,
                       const char* start_time,
		       merge_method m_method)
{





  /*
define/parameter p1 ? ima "Enter input frame"
define/parameter p2 ? c   "Enter extracted spectra prefix"
  */

  double rsample=0;
  int it=0;
  int fib_min=0;
  int fib_max=0;
  int ord_min=0;
  int ord_max=0;
  
  cpl_table* parFibOrdTab=NULL;
  cpl_table* parLinTab=NULL;
  const char* filename=NULL;
  const char* linetable_filename=NULL;
  int pno=0;  
  char chip_name[80];
  bool flames=true;
  polynomial  *dispersion_relation=NULL;
  polynomial  *absolute_order=NULL;
  cpl_frame* line_frm=NULL;
  uves_propertylist* ref_header=NULL;

 
  int* fibre_mask_lin=NULL;

  int* fibre_mask_frm=NULL;
  uves_propertylist *header = NULL;
 

  int fibre_mask_length=0;
  cpl_type fibre_mask_type=0;

  float* pixel=NULL;
  int pixel_length=0;
  cpl_type pixel_type=0;
  //char prefid[80];
  const cpl_parameter* p=NULL;

  double qc_obs_time=1.0;
  double qc_ra=1.0;
  double qc_dec=1.0;
  double qc_pos=1.0;
  double qc_geolat=1.0;
  double qc_geolon=1.0;

  int status=0;

  double wcen=0;
  int wlen=0;
  double delta1=-1;
  double delta2=-1;

  char file[80];
  char efile[80];
  char wfile[80];
  char wbase[80];
  char mbase[80];

  char bfile[80];
  char mfile[80];
  char cfile[80];
  int fib_max_lit=-1;
  int fib_min_lit=10;

  double barycor=0;
  double helicor=0;

  cpl_table* tmp_tbl=NULL;
  uves_propertylist* tmp_header=NULL;




  uves_propertylist* linetable_header=NULL;
  int abs_ord_min=0;
  int abs_ord_max=0;
 
  cpl_image* wimg=NULL;
  cpl_image* werr=NULL;
  cpl_image* wbpm=NULL;
  cpl_image* mimg=NULL;
  cpl_image* merr=NULL;

  uves_propertylist* wheader=NULL;
  uves_propertylist* eheader=NULL;
  uves_propertylist* bheader=NULL;
  uves_propertylist* mheader=NULL;
  uves_propertylist* pheader=NULL;
  cpl_frameset* line_set=NULL;
  bool format_is_midas;

  //const char *recipe_id = make_str(FLAMES_OBS_SCIRED_ID);

  check_nomsg(filename=cpl_frame_get_filename(ifrm));
  check_nomsg(ref_header=uves_propertylist_load(filename,0));
  
  check_nomsg(filename=cpl_frame_get_filename(ordef));
  check_nomsg(parFibOrdTab=cpl_table_load(filename,1,0));
  //cpl_table_dump(parFibOrdTab,1,3,stdout);
  check_nomsg(ord_min=(int)cpl_table_get_column_min(parFibOrdTab,"Order"));
  check_nomsg(ord_max=(int)cpl_table_get_column_max(parFibOrdTab,"Order"));
  check_nomsg(fib_min=(int)cpl_table_get_column_min(parFibOrdTab,"FIBRE"));
  check_nomsg(fib_max=(int)cpl_table_get_column_max(parFibOrdTab,"FIBRE"));




 
  /*
define/local ifrm/c/1/80 {p1}
define/local opfx/c/1/80 {p2}
define/local rsample/r/1/1 0
define/local it/i/1/1 0

define/local fib_min/i/1/1 0
define/local fib_max/i/1/1 0
define/local ord_min/i/1/1 0
define/local ord_max/i/1/1 0

select/tab {parFibOrdTab} all
statistic/table {parFibOrdTab} :ORDER >Null
ord_min = outputr(1)
ord_max = outputr(2)
statistic/table {parFibOrdTab} :FIBRE >Null
fib_min = outputr(1)
fib_max = outputr(2)
define/local min_rsample/r/1/1 10.
  */


  check_nomsg(line_frm=cpl_frameset_find(frames,FLAMES_LINE_TABLE(chip)));
  check_nomsg(filename=cpl_frame_get_filename(line_frm));
  check_nomsg(pheader=uves_propertylist_load(filename,0));
  check_nomsg(strcpy(chip_name,uves_pfits_get_chipid(pheader,chip)));

  check_nomsg(uves_check_if_format_is_midas(pheader,&format_is_midas));
  uves_free_propertylist(&pheader);

  if(format_is_midas == true) {
    check_nomsg(header=uves_propertylist_load(filename,1));
  } else {
    check_nomsg(header=uves_propertylist_load(filename,0));
  }

  line_set=cpl_frameset_new();
  cpl_frameset_insert(line_set,cpl_frame_duplicate(line_frm));

  /*
  if(chip == UVES_CHIP_REDL) {

    sprintf(prefid,"l_");

  } else {

    sprintf(prefid,"u_");

  }
  */


  check( fibre_mask_lin = uves_read_midas_array(header, 
                                            "FIBREMASK", 
                                            &fibre_mask_length,
                                            &fibre_mask_type, 
                                            NULL),
	 "Error reading FIBREMASK");


 
  assure( fibre_mask_type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
          "Type of FIBREMASK is %s, int expected",
          uves_tostring_cpl_type(fibre_mask_type));


  assure( MAXFIBRES == fibre_mask_length, CPL_ERROR_INCOMPATIBLE_INPUT,
            "FIBREMASK length is %d but MAXFIBRES is %d",
            fibre_mask_length, MAXFIBRES);


  check(pixel = uves_read_midas_array(header, 
                                            "PIXEL", 
                                            &pixel_length,
                                            &pixel_type, 
                                            NULL),
	 "Error reading PIXEL");


  assure( pixel_type == CPL_TYPE_FLOAT, CPL_ERROR_TYPE_MISMATCH,
          "Type of PIXEL is %s, float expected",
          uves_tostring_cpl_type(pixel_type));


  assure( 2 == pixel_length, CPL_ERROR_INCOMPATIBLE_INPUT,
            "PIXEL length is %d but expected size is %d",
            pixel_length, 2 );


  uves_msg_debug("PIXEL: %f %f length=%d",pixel[0],pixel[1],pixel_length);
  rsample=2.*pixel[0]/3.;

  uves_msg_debug("rsample=%f",rsample);

  
  uves_free_propertylist(&header);

  header = uves_propertylist_load(cpl_frame_get_filename(ifrm), 0);
  check( fibre_mask_frm = uves_read_midas_array(header, 
                                            "FIBREMASK", 
                                            &fibre_mask_length,
                                            &fibre_mask_type, 
                                            NULL),
	 "Error reading FIBREMASK");

 
  assure( fibre_mask_type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
          "Type of FIBREMASK is %s, int expected",
          uves_tostring_cpl_type(fibre_mask_type));


  assure( MAXFIBRES == fibre_mask_length, CPL_ERROR_INCOMPATIBLE_INPUT,
            "FIBREMASK length is %d but MAXFIBRES is %d",
            fibre_mask_length, MAXFIBRES);

  /*
  FIXME: here is not clear if rsample really changes

  //1st find min sampling step common to all rebined frames
  for(it=fib_min;it<fib_max;it++) {

    if ( (fibre_mask_lin[i] == 1) && 
         (fibre_mask_frm[i] == 1) ) {
                            
      cpl_table_and_select(parLinTab,"FIBRE",CPL_EQUAL_TO,it);
      
    }
    if(rsample < min_rsample) {

      min_rsample=rsample;

    }

  }
  */


  /*

!1st find min sampling step common to all rebined frames
do it = fib_min fib_max
   set/format i1
   if {{parLinTab},FIBREMASK({it})} .eq. 1 then
   if {{ifrm},FIBREMASK({it})} .eq. 1 then

      select/tab {parLinTab} :fibre.eq.{it}  {SESSOUTV}
      $ln -sf {parLinTab} tmp_{it}_{prefid}.tbl

      $ln -sf  tmp_{it}_{prefid}.tbl  tmp_{prefid}.tbl
      set/format
      rsample = 2.*({tmp_{prefid}.tbl,PIXEL(1)})/3.
      if rsample .lt. min_rsample then 
         min_rsample = rsample
      endif
   endif
   endif
enddo

  */



  check_nomsg(qc_geolat=uves_pfits_get_geolat(header));
  check_nomsg(qc_geolon=uves_pfits_get_geolon(header));
  check_nomsg(qc_obs_time=uves_pfits_get_exptime(header));



  /*
!Barycorr correction
define/local qc_obs_time/d/1/1 1.0
define/local qc_ra/d/1/1 1.0
define/local qc_dec/d/1/1 1.0
define/local qc_pos/d/1/1 1.0
define/local qc_geolat/d/1/1 1.0
define/local qc_geolon/d/1/1 1.0
define/local dpr_type/c/1/80 " " all
define/local tpl_id/c/1/80 " " all
define/local arcfile/c/1/80 " " all
define/local pro_catg/c/1/80 " " all

!Earth to Helio-centric coordinate correction
set/format F12.8

if m$existd(p1,h_geolat)  .gt. 0 then
   qc_geolat   = m$value({p1},{h_geolat})
endif
if m$existd(p1,h_geolon)  .gt. 0 then 
   qc_geolon   = m$value({p1},{h_geolon})
endif
if m$existd(p1,O_TIME(7)) .gt. 0 then 
   qc_obs_time = m$value({p1},O_TIME(7)) 
endif 


                                       !using an image as input it take the
                                       !date from the descriptor O_TIME(1,2,3)
                                       !and the UT from O_TIME(5)


  */

  //TODO
  /*
define/local hms_ra/c/1/80     " " all
define/local dms_dec/c/1/80    " " all
define/local dms_geolat/c/1/80 " " all
define/local dms_geolon/c/1/80 " " all
define/local xtab/c/1/80 xt_sci_{prefid}.tbl

!QC-LOG prehamble 
qc1log/out 2 
if m$existd(p1,"{h_insmode}") .eq. 1 then 
   qc1log/out 1 {xtab} "QC.TEST2.ID" "Science-QC" "Name of QC Test"
endif
@p uves_qc1_log,common {p1} {xtab}
  */

  check_nomsg(wcen=uves_pfits_get_gratwlen(header,chip));
  wlen=(int)wcen;

  check_nomsg(p=cpl_parameterlist_find_const(parameters,"flames_obs_scired.merge_delt1"));
  if(cpl_parameter_get_default_flag(p) != 0) {
    /* if the user has not set the parameter use default */
    check_nomsg(delta1=cpl_parameter_get_double(p));
  }

  check_nomsg(p=cpl_parameterlist_find_const(parameters,"flames_obs_scired.merge_delt2"));
  if(cpl_parameter_get_default_flag(p) != 0) {
    /* if the user has not set the parameter use default */
    check_nomsg(delta2=cpl_parameter_get_double(p));
  }
  
  check_nomsg(flames_set_delta(wlen, chip,&delta1, &delta2));



  uves_msg_debug("wlen=%d delta1=%f delta2=%f",wlen,delta1,delta2);
  //rsample = min_rsample;


/*
@p flames_reduce,SET_DELTA
rsample = min_rsample

*/
  uves_msg_debug("fib min=%d max=%d",fib_min,fib_max);
for(it = fib_min; it<= fib_max; it++) {

    if ( (fibre_mask_lin[it-1] == 1) && 
         (fibre_mask_frm[it-1] == 1) ) {
               

      if(it<fib_min_lit) {
	fib_min_lit=it;
      }
      if(it>fib_max_lit) {
	fib_max_lit=it;
      }
      //cpl_table_dump(xtab,1,cpl_table_get_nrow(xtab),stdout);
      check_nomsg(qc_ra=cpl_table_get_double(xtab,"RA",it-1,&status));
      check_nomsg(qc_dec=cpl_table_get_double(xtab,"DEC",it-1,&status));
      check_nomsg(qc_pos=cpl_table_get_double(xtab,"FIBREPOS",it-1,&status));
  
      uves_msg("fibremask[%d]=%d",it-1,fibre_mask_frm[it-1]);
      if ( (qc_pos != 200.) || (qc_pos != -200.)) {
	//Fixme: in MIDAS the following check with NULL.
        //Here it can eventually be 0. Did I do the right check?
	if ( (qc_ra != 0.) || (qc_dec != 0.) ) {


	  // FIXME: temporarily commented out: 
          //UVES computes barycor from header
	  
	  //check_nomsg(hms_ra=flames_deg2dms(qc_ra));
	  //check_nomsg(dms_dec=flames_deg2dms(qc_dec));
	  //check_nomsg(dms_geolat=flames_deg2dms(qc_geolat));
	  //check_nomsg(dms_geolon=flames_deg2dms(qc_geolon));
	 
          check( uves_baryvel(header, &barycor,&helicor),
           "Could not compute velocity corrections");
	
	} else {
	  
         //qc1log/out 1 {xtab}  "QC.FIB{it}.VRAD.BARYCOR"  {outputr(1)} "Barycorr"
         //qc1log/out 1 {xtab}  "QC.FIB{it}.VRAD.HELICOR"  {outputr(2)} "Helicorr"     
	 

	}
      } else {
	
	//qc1log/out 1 {xtab}  "QC.FIB{it}.VRAD.BARYCOR"  999 "Dummy-Barycorr"
	//qc1log/out 1 {xtab}  "QC.FIB{it}.VRAD.HELICOR"  999 "Dummy-Helicorr"
       
      }


      check_nomsg(uves_load_linetable(line_set, flames,chip_name,
                                  order_locations,ord_min, 
                                  ord_max,&linetable_filename,
                                  &parLinTab,&linetable_header,
                                  &dispersion_relation,
                                  &absolute_order, chip, it, -1));
      uves_polynomial_delete(&absolute_order);
    
       check_nomsg(abs_ord_min=(int)cpl_table_get_column_min(parLinTab,"Order"));
      check_nomsg(abs_ord_max=(int)cpl_table_get_column_max(parLinTab,"Order"));

      if(cpl_table_has_column(parLinTab,"FIBRE")) {

	check_nomsg(cpl_table_and_selected_float(parLinTab,"FIBRE",
						 CPL_EQUAL_TO,it));
      } else {
        
	check_nomsg(cpl_table_and_selected_int(parLinTab,"Fibre",
						 CPL_EQUAL_TO,it));

      }
      /*
      check_nomsg(tmp_tbl=cpl_table_extract_selected(parLinTab));
      check_nomsg(tmp_header=uves_propertylist_duplicate(linetable_header));
      */

      sprintf(wbase,"%s%s","w",drs_base_name);
      sprintf(mbase,"%s%s","m",wbase);


      // RAW data
      // extracted
       sprintf(file,"%s%s%4.4d%s",drs_base_name,"_raw",it,".fits");
      sprintf(wfile,"%s%s","w",file);
      uves_free_propertylist(&wheader);
      flames_rebin_frame(parameters,file,parLinTab,dispersion_relation,
                         abs_ord_max,abs_ord_min,&wimg,&wheader);


      /* fixme: make sure that the  werr  image is non-negative by
         passing the appropriate option to uves_rebin() */
      sprintf(efile,"%s%s%4.4d%s",drs_base_name,"_rawsig",it,".fits");
      flames_rebin_frame(parameters,efile,parLinTab,dispersion_relation,
                         abs_ord_max,abs_ord_min,&werr,&eheader);
      sprintf(wfile,"%s%s","w",efile);
      check_nomsg( uves_save_image(werr,wfile,eheader,true, true) );

      if( m_method == MERGE_FLAMES ) {

	sprintf(bfile,"%s%s%4.4d%s",drs_base_name,"_rawextco",it,".fits");
	flames_rebin_frame(parameters,bfile,parLinTab,dispersion_relation,
			   abs_ord_max,abs_ord_min,&wbpm,&bheader);
	sprintf(wfile,"%s%s","w",bfile);
	check_nomsg( uves_save_image(wbpm,wfile,bheader,true, true) );

	ck0_nomsg(flames_drs_merge(file,wbase,mbase,it,1,delta1,delta2));
      } else {
	uves_free_propertylist(&wheader);
	check( mimg = uves_merge_orders(wimg, werr,wheader,m_method,1,
                                        &mheader,delta1,delta2,chip,&merr),
	       "Error merging frame");
	sprintf(mfile,"%s%s","mw",file);
	check_nomsg( uves_save_image(mimg,mfile,mheader,true, true) );
      }

      //Normal data
      sprintf(file,"%s%s%4.4d%s",drs_base_name,"_",it,".fits");
      sprintf(wfile,"%s%s","w",file);
      // fixme: is eheader leaked here? 
      uves_free_propertylist(&wheader);
      flames_rebin_frame(parameters,file,parLinTab,dispersion_relation,
                         abs_ord_max,abs_ord_min,&wimg,&wheader);
      check_nomsg( uves_save_image(wimg,wfile,wheader,true, true) );

      sprintf(efile,"%s%s%4.4d%s",drs_base_name,"_sig",it,".fits");
      flames_rebin_frame(parameters,efile,parLinTab,dispersion_relation,
                         abs_ord_max,abs_ord_min,&werr,&eheader);

      sprintf(wfile,"%s%s","w",efile);
      check_nomsg( uves_save_image(werr,wfile,eheader,true, true) );

      if( m_method == MERGE_FLAMES ) {
	sprintf(bfile,"%s%s%4.4d%s",drs_base_name,"_extco",it,".fits");
	flames_rebin_frame(parameters,bfile,parLinTab,dispersion_relation,
			   abs_ord_max,abs_ord_min,&wbpm,&bheader);
	sprintf(wfile,"%s%s","w",bfile);
	check_nomsg( uves_save_image(wbpm,wfile,bheader,true, true) );

	ck0_nomsg(flames_drs_merge(file,wbase,mbase,it,0,delta1,delta2));
      } else {
	uves_free_propertylist(&wheader);
	check( mimg = uves_merge_orders(wimg, werr,wheader,m_method,1,
                                        &mheader,delta1,delta2,chip,&merr),
	       "Error merging frame");
	sprintf(mfile,"%s%s","mw",file);
	uves_save_image(mimg,mfile,mheader,true, true);
      }
      uves_free_image(&wimg);
      uves_free_image(&werr);

      uves_polynomial_delete(&dispersion_relation);
    } //end check on fribremask


 }
 uves_free_frameset(&line_set);
 uves_free_propertylist(&wheader);


 uves_free_propertylist(&header);
 int ref_button[]={0,3,135,37,169,69,201,103,235};

 int* fibre_mask=NULL;
 int* but_ozpoz=NULL;
 int* but_xtab=NULL;

 //cpl_table_dump(xtab,0,cpl_table_get_nrow(xtab),stdout);
 //cpl_table_dump(ozpoz,0,cpl_table_get_nrow(ozpoz),stdout);
 fibre_mask=cpl_table_get_data_int(xtab,"FIBREMASK");
 //but_ozpoz=cpl_table_get_data_int(ozpoz,"BUTTON");
 but_xtab=cpl_table_get_data_int(xtab,"BUTTON");
 for(it=fib_min_lit-1;it<fib_max_lit;it++) {
   uves_msg("it %d but %d ref %d",it,but_xtab[it],ref_button[it]);
   if(fibre_mask[it]==1 && but_xtab[it] == ref_button[it]) {
     uves_msg("Lit fibre %d ",it+1);
   } else {
     fibre_mask[it]=0;

   }
 }
 for(it=fib_min_lit-1;it<fib_max_lit;it++) {
   if(fibre_mask[it]==1) {
        uves_msg("Lit fibre %d ",it+1);
   }
 }
 //normal data
 sprintf(file,"%s%s",drs_base_name,"_");
 sprintf(cfile,"%s%s",file,"pack.fits");
 ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,fib_min_lit,fib_max_lit));

 sprintf(file,"%s%s%s","w",drs_base_name,"_");
 sprintf(cfile,"%s%s",file,"pack.fits");
 //ck0_nomsg(flames_images_to_cube(file,cfile,"%4.4d",fib_min_lit,fib_max_lit));

 ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,
				       fib_min_lit,fib_max_lit));


 sprintf(file,"%s%s",drs_base_name,"_sig");
 sprintf(cfile,"%s%s",file,"pack.fits");
 ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,fib_min_lit,fib_max_lit));

 sprintf(file,"%s%s",drs_base_name,"_extco");
 sprintf(cfile,"%s%s",file,"pack.fits");
 ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,fib_min_lit,fib_max_lit));


 sprintf(file,"%s%s%s","w",drs_base_name,"_sig");
 sprintf(cfile,"%s%s",file,"pack.fits");
 ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,fib_min_lit,fib_max_lit));

 if( m_method == MERGE_FLAMES ) {
   sprintf(file,"%s%s%s","w",drs_base_name,"_extco");
   sprintf(cfile,"%s%s",file,"pack.fits");
   ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,fib_min_lit,fib_max_lit));
 }

 check_nomsg(pno=uves_flames_pfits_get_plateid(ref_header));

 sprintf(file,"%s%s%s","mw",drs_base_name,"_");
 sprintf(cfile,"%s%s",file,"pack.fits");
 uves_msg("make work flames_spectra_to_image())");
 ck0_nomsg(flames_spectra_to_image_check(file,"",cfile,fib_min_lit,fib_max_lit,xtab,
				   pno));

 sprintf(file,"%s%s%s","mw",drs_base_name,"_");
 sprintf(cfile,"%s%s",file,"sigma_pack.fits");
 uves_msg("make work flames_spectra_to_image())");
 ck0_nomsg(flames_spectra_to_image_check(file,"_sigma",cfile,fib_min_lit,fib_max_lit,
				   xtab,pno));

 //raw data
 sprintf(file,"%s%s",drs_base_name,"_raw");
 sprintf(cfile,"%s%s",file,"pack.fits");
 ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,fib_min_lit,fib_max_lit));

 sprintf(file,"%s%s%s","w",drs_base_name,"_raw");
 sprintf(cfile,"%s%s",file,"pack.fits");
 ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,fib_min_lit,fib_max_lit));


 sprintf(file,"%s%s",drs_base_name,"_rawsig");
 sprintf(cfile,"%s%s",file,"pack.fits");
 ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,fib_min_lit,fib_max_lit));

 sprintf(file,"%s%s",drs_base_name,"_rawextco");
 sprintf(cfile,"%s%s",file,"pack.fits");
 ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,fib_min_lit,fib_max_lit));


 sprintf(file,"%s%s%s","w",drs_base_name,"_rawsig");
 sprintf(cfile,"%s%s",file,"pack.fits");
 ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,fib_min_lit,fib_max_lit));

 if( m_method == MERGE_FLAMES ) {
   sprintf(file,"%s%s%s","w",drs_base_name,"_rawextco");
   sprintf(cfile,"%s%s",file,"pack.fits");
   ck0_nomsg(flames_images_to_cube_check(file,cfile,"%4.4d",fibre_mask,fib_min_lit,fib_max_lit));
 }

 
 sprintf(file,"%s%s%s","mw",drs_base_name,"_raw");
 sprintf(cfile,"%s%s",file,"pack.fits");
 ck0_nomsg(flames_spectra_to_image_check(file,"",cfile,fib_min_lit,fib_max_lit,xtab,
				   pno));


 sprintf(file,"%s%s%s","mw",drs_base_name,"_raw");
 sprintf(cfile,"%s%s",file,"sigma_pack.fits");
 ck0_nomsg(flames_spectra_to_image_check(file,"_sigma",cfile,fib_min_lit,fib_max_lit,
				   xtab,pno));


 cpl_free(fibre_mask_lin);
 cpl_free(fibre_mask_frm);


/*
do it = fib_min fib_max

   set/format i1
   if {{parLinTab},FIBREMASK({it})} .eq. 1 then
   if {{ifrm},FIBREMASK({it})} .eq. 1 then

      qc_ra  = {{xtab},:RA,@{it}}
      qc_dec = {{xtab},:DEC,@{it}}
      qc_pos = {{xtab},:FIBREPOS,@{it}}

      if qc_pos .ne. 200 .or. qc_pos .ne. -200 then
      if qc_ra .ne. NULL .or. qc_dec .ne. NULL then
         @p uves_deg2hms {qc_ra}
         hms_ra = q1
         @p uves_deg2dms {qc_dec}
         dms_dec = q1
         @p uves_deg2dms {qc_geolat}
         dms_geolat = q1
         @p uves_deg2dms {qc_geolon}
         dms_geolon = q1

         COMPUTE/BARYCORR {p1} {hms_ra} {dms_dec} {dms_geolon} {dms_geolat} >Null
         qc1log/out 1 {xtab}  "QC.FIB{it}.VRAD.BARYCOR"  {outputr(1)} "Barycorr"
         qc1log/out 1 {xtab}  "QC.FIB{it}.VRAD.HELICOR"  {outputr(2)} "Helicorr"     
      else
         qc1log/out 1 {xtab}  "QC.FIB{it}.VRAD.BARYCOR"  999 "Dummy-Barycorr"
         qc1log/out 1 {xtab}  "QC.FIB{it}.VRAD.HELICOR"  999 "Dummy-Helicorr"
      endif
      else
         qc1log/out 1 {xtab}  "QC.FIB{it}.VRAD.BARYCOR"  999 "Dummy-Barycorr"
         qc1log/out 1 {xtab}  "QC.FIB{it}.VRAD.HELICOR"  999 "Dummy-Helicorr"
      endif


      select/tab {parLinTab} :fibre.eq.{it}  {SESSOUTV}
      $ln -sf {parLinTab} tmp_{it}_{prefid}.tbl
 

      !the following are the ones indeed used from necrebi.for
      delete/des  tmp_{it}_{prefid}.tbl ORDER
      delete/des  tmp_{it}_{prefid}.tbl COEFS
      delete/des  tmp_{it}_{prefid}.tbl COEFI
      delete/des  tmp_{it}_{prefid}.tbl COEFD

      copy/dd {parLinTab} ORDER{it}  tmp_{it}_{prefid}.tbl ORDER
      copy/dd {parLinTab} COEFS{it}  tmp_{it}_{prefid}.tbl COEFS
      copy/dd {parLinTab} COEFI{it}  tmp_{it}_{prefid}.tbl COEFI
      copy/dd {parLinTab} COEFD{it}  tmp_{it}_{prefid}.tbl COEFD

      copy/dd {parLinTab} REGRC{it}  tmp_{it}_{prefid}.tbl REGRC 
      copy/dd {parLinTab} REGRI{it}  tmp_{it}_{prefid}.tbl REGRI 
      copy/dd {parLinTab} REGRD{it}  tmp_{it}_{prefid}.tbl REGRD
      copy/dd {parLinTab} REGRR{it}  tmp_{it}_{prefid}.tbl REGRR

      $ln -sf  tmp_{it}_{prefid}.tbl  tmp_{prefid}.tbl
      set/format
      !rsample = 2.*({tmp_{prefid}.tbl,PIXEL(1)})/3.
    
      set/echelle SAMPLE = {rsample}
      set/echelle LINTAB = tmp_{prefid}.tbl

      if "{DRS_MER_MTD}" .eq. "FLAMES" then
         merge/flames {opfx}{prefid}_{it}.bdf w{opfx}{prefid}_{it} -
                    mw{opfx}{prefid}_{it}

         compute/image mw{opfx}{prefid}_err{it}.bdf = sqrt(mw{opfx}{prefid}_{it}_sigma.bdf) {SESSOUTV}

      else 
         rebin/echelle {opfx}{prefid}_{it}.bdf -
                      w{opfx}{prefid}_{it}.bdf {rsample} NONL -
                       tmp_{prefid}.tbl {SESSOUTV}

         rebin/echelle {opfx}{prefid}_sig{it}.bdf -
                     w{opfx}{prefid}_sig{it}.bdf {rsample} NONL -
                      tmp_{prefid}.tbl {SESSOUTV}

         !file_sig is a variance frame
         compute/ima weight.bdf = 1./w{opfx}{prefid}_sig{it}.bdf {SESSOUTV}

         merge/echelle w{opfx}{prefid}_{it}.bdf  -
                      mw{opfx}{prefid}_{it}.bdf {DRS_MER_DELTA} OPTIMAL weight.bdf -
                    varm{opfx}{prefid}_{it}.bdf {SESSOUTV}

         merge/echelle w{opfx}{prefid}_sig{it}.bdf  -
                      mw{opfx}{prefid}_{it}_sigma.bdf {DRS_MER_DELTA} OPTIMAL weight.bdf -
                    varm{opfx}{prefid}_{it}_sigma.bdf {SESSOUTV}

         compute/image mw{opfx}{prefid}_err{it}.bdf = sqrt(mw{opfx}{prefid}_{it}_sigma.bdf) {SESSOUTV}

      endif
      if "{DRS_BLAZE_SW}" .eq. "Y" then
         compute/image blz{opfx}{prefid}_{it} = {opfx}{prefid}_raw{it} * slitff_{prefid}_norm.bdf 
         rebin/echelle blz{opfx}{prefid}_{it}.bdf -
                      wblz{opfx}{prefid}_{it}.bdf {rsample} NONL -
                       tmp_{prefid}.tbl {SESSOUTV}

      endif
      if "{DRS_MER_MTD}" .eq. "FLAMES" then
         merge/flames {opfx}{prefid}_raw{it}.bdf w{opfx}{prefid}_raw{it} -
                    mw{opfx}{prefid}_raw{it} 

         compute/image mw{opfx}{prefid}_rawerr{it}.bdf = sqrt(mw{opfx}{prefid}_raw{it}_sigma.bdf) {SESSOUTV} 
      else
         rebin/echelle {opfx}{prefid}_raw{it}.bdf -
                      w{opfx}{prefid}_raw{it}.bdf {rsample} NONL -
                       tmp_{prefid}.tbl {SESSOUTV}

         rebin/echelle {opfx}{prefid}_rawsig{it}.bdf -
                      w{opfx}{prefid}_rawsig{it}.bdf {rsample} NONL -
                       tmp_{prefid}.tbl {SESSOUTV}

         !file_sig is a variance frame
         compute/ima weight_raw.bdf = 1./w{opfx}{prefid}_rawsig{it}.bdf {SESSOUTV} 

         if {it} .eq. 1 then
            if "{DRS_CVEL_SWITCH}" .eq. "Y" then 
               compute/image blz{opfx}{prefid}_raw{it}.bdf = {opfx}{prefid}_raw{it}.bdf * slitff_{prefid}_norm.bdf

               rebin/echelle blz{opfx}{prefid}_raw{it}.bdf -
                      wblz{opfx}{prefid}_raw{it}.bdf {rsample} NONL -
                       tmp_{prefid}.tbl {SESSOUTV}

               mercut/echelle wblz{opfx}{prefid}_raw{it}.bdf  -
                      mw{opfx}{prefid}_raw{it}.bdf {ord_min},{ord_max} -
                      NOAPPEND 
            endif
         endif
         merge/echelle w{opfx}{prefid}_raw{it}.bdf  -
                      mw{opfx}{prefid}_raw{it}.bdf {DRS_MER_DELTA} OPTIMAL weight_raw.bdf -
                    varm{opfx}{prefid}_raw{it}.bdf {SESSOUTV}

         merge/echelle w{opfx}{prefid}_rawsig{it}.bdf  -
                      mw{opfx}{prefid}_raw{it}_sigma.bdf {DRS_MER_DELTA} OPTIMAL weight_raw.bdf -
                    varm{opfx}{prefid}_raw{it}_sigma.bdf {SESSOUTV}

         compute/image mw{opfx}{prefid}_rawerr{it}.bdf = sqrt(mw{opfx}{prefid}_raw{it}_sigma.bdf) {SESSOUTV}
      endif
      select/tab {parLinTab} all
       @p flames_add_extra_des {ifrm} w{opfx}{prefid}_{it}.bdf 
       @p flames_add_extra_des {ifrm} w{opfx}{prefid}_raw{it}.bdf
       @p flames_add_extra_des {ifrm} mw{opfx}{prefid}_{it}.bdf 
       @p flames_add_extra_des {ifrm} mw{opfx}{prefid}_raw{it}.bdf
       @p flames_add_extra_des {ifrm} mw{opfx}{prefid}_err{it}.bdf 
       @p flames_add_extra_des {ifrm} mw{opfx}{prefid}_rawerr{it}.bdf
       @p flames_add_extra_des {ifrm} mw{opfx}{prefid}_{it}_sigma.bdf 
       @p flames_add_extra_des {ifrm} mw{opfx}{prefid}_raw{it}_sigma.bdf


      !copy/dd {ifrm} *,3  mw{opfx}{prefid}_raw{it}.bdf
      !copy/dd {ifrm} MJD-OBS mw{opfx}{prefid}_raw{it}.bdf
      !copy/dd {ifrm} *,3  mw{opfx}{prefid}_{it}.bdf
      !copy/dd {ifrm} MJD-OBS mw{opfx}{prefid}_{it}.bdf

      XTABDUMP/FLAMES mw{opfx}{prefid}_{it}.bdf {parFibOrdTab} -
          xt_sci_{prefid}.tbl {it}
      XTABDUMP/FLAMES mw{opfx}{prefid}_raw{it}.bdf {parFibOrdTab} -
          xt_sci_{prefid}.tbl {it}

      XTABDUMP/FLAMES mw{opfx}{prefid}_err{it}.bdf {parFibOrdTab} -
          xt_sci_{prefid}.tbl {it}
      XTABDUMP/FLAMES mw{opfx}{prefid}_rawerr{it}.bdf {parFibOrdTab} -
          xt_sci_{prefid}.tbl {it}

      XTABDUMP/FLAMES mw{opfx}{prefid}_{it}_sigma.bdf {parFibOrdTab} -
          xt_sci_{prefid}.tbl {it}
      XTABDUMP/FLAMES mw{opfx}{prefid}_raw{it}_sigma.bdf {parFibOrdTab} -
          xt_sci_{prefid}.tbl {it}


      if "{NICE_CREA}" .eq. "Y" then
         ASSIGN/GRA G,3
         PLOT/UVES  mw{opfx}{prefid}_{it}.bdf -
         P4="FIBRE data ({{ifrm},{h_instrume}}): "  P6={it}
ubas
      endif
  endif
  endif
enddo
qc1log/out 3

  */

 cleanup:
  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    uves_free_propertylist(&wheader);
     uves_free_propertylist(&header);
    //uve_free_imagelist(&obj_cor);
    return -1;
  } else {
    return 0;
  }


}

/*---------------------------------------------------------------------------*/
/**
  @brief this entry classify the data
  @param    ifrm        input science frame
  @param    ordef       order definition frame
  @param    frames      set of frames 
  @param    chip        detector chip id
  @param    xtab        binary table
  @param    parameters  recipe parameters
  @param    order_locations  order locations
  @param    start_time       start time
  @param    qclog       Quality Control keys
  @return   0 if everything is ok

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

static int
flames_reduce_proclass(const cpl_frame* ifrm, 
                       const cpl_frame* ordef, 
                       cpl_frameset* frames,
		       enum uves_chip chip,
                       const cpl_table* xtab,
		       const cpl_parameterlist *parameters, 
		       polynomial *order_locations,
                       const char* drs_base_name,
                       const char* start_time, 
                       cpl_table** qclog)
{



  double rsample=0;
  int it=0;
  int fib_min=0;
  int fib_max=0;
  int ord_min=0;
  int ord_max=0;
 
  cpl_table* parFibOrdTab=NULL;
  const char* filename=NULL;
 
  const char* chip_name=NULL;
  cpl_frame* line_frm=NULL;
  uves_propertylist* ref_header=NULL;

  int* fibre_mask_lin=NULL;

  int* fibre_mask_frm=NULL;
  uves_propertylist *pheader = NULL;
  uves_propertylist *header = NULL;

  int fibre_mask_length=0;
  cpl_type fibre_mask_type=0;

  float* pixel=NULL;
  int pixel_length=0;
  cpl_type pixel_type=0;

  double qc_obs_time=1.0;
  double qc_geolat=1.0;
  double qc_geolon=1.0; 

  double wcen=0;
  int wlen=0;
  double delta1=0;
  double delta2=0;

  char file[80];
  char efile[80];
  char wfile[80];
  char mfile[80];
  char cfile[80];
  bool format_is_midas;               /* Was file written by CPL or MIDAS? */
  const char *recipe_id = make_str(FLAMES_OBS_SCIRED_ID);
  const char* cubify_sw=NULL;
  const char *drs_id=NULL;
 int cubify_products=0;

  check( uves_get_parameter(parameters, NULL, recipe_id, "cubify_sw",
                  CPL_TYPE_STRING, &cubify_sw), 
                             "Could not read parameter");

  if(strcmp(cubify_sw,"N")==0) {
    cubify_products=0;
  } else {
    cubify_products=1;
  }


  check_nomsg(filename=cpl_frame_get_filename(ifrm));
  check_nomsg(ref_header=uves_propertylist_load(filename,0));
  
  check_nomsg(filename=cpl_frame_get_filename(ordef));
  check_nomsg(parFibOrdTab=cpl_table_load(filename,1,0));
  //cpl_table_dump(parFibOrdTab,1,3,stdout);
  check_nomsg(ord_min=(int)cpl_table_get_column_min(parFibOrdTab,"Order"));
  check_nomsg(ord_max=(int)cpl_table_get_column_max(parFibOrdTab,"Order"));
  check_nomsg(fib_min=(int)cpl_table_get_column_min(parFibOrdTab,"FIBRE"));
  check_nomsg(fib_max=(int)cpl_table_get_column_max(parFibOrdTab,"FIBRE"));



  check_nomsg(header=uves_propertylist_load(filename,0));
  check_nomsg(chip_name=uves_pfits_get_chipid(header,chip));
  uves_free_propertylist(&header);

  check_nomsg(line_frm=cpl_frameset_find(frames,FLAMES_LINE_TABLE(chip)));
  check_nomsg(filename=cpl_frame_get_filename(line_frm));
  check_nomsg(pheader=uves_propertylist_load(filename,0));

  if (uves_propertylist_contains(pheader, UVES_DRS_ID)) {
    check( drs_id = uves_pfits_get_drs_id(pheader), 
	   "Error reading DRS ID");
    if (strstr(drs_id, "CPL") != NULL || strstr(drs_id, "cpl") != NULL) {
      format_is_midas = false;
      uves_msg_debug("Line table was written by CPL");
    } else if (strstr(drs_id, "MIDAS") != NULL || 
               strstr(drs_id, "midas") != NULL) {
      format_is_midas = true;
      uves_msg_debug("Line table was written by MIDAS");
    } else {
      assure ( false,
	       CPL_ERROR_ILLEGAL_INPUT,
	       "Unrecognized line table format, DRS_ID = '%s'", drs_id);
    }
  } else {
    format_is_midas = true;
    uves_msg_debug("No '%s' keyword found. Assuming MIDAS format", UVES_DRS_ID);
  }
  uves_free_propertylist(&pheader);

  if(format_is_midas) {
    check_nomsg(header=uves_propertylist_load(filename,1));
  } else {
    check_nomsg(header=uves_propertylist_load(filename,0));
  }


  
  check( fibre_mask_lin = uves_read_midas_array(header, 
                                            "FIBREMASK", 
                                            &fibre_mask_length,
                                            &fibre_mask_type, 
                                            NULL),
	 "Error reading FIBREMASK");

 
 
  assure( fibre_mask_type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
          "Type of FIBREMASK is %s, int expected",
          uves_tostring_cpl_type(fibre_mask_type));


  assure( MAXFIBRES == fibre_mask_length, CPL_ERROR_INCOMPATIBLE_INPUT,
            "FIBREMASK length is %d but MAXFIBRES is %d",
            fibre_mask_length, MAXFIBRES);


  check(pixel = uves_read_midas_array(header, 
                                            "PIXEL", 
                                            &pixel_length,
                                            &pixel_type, 
                                            NULL),
	 "Error reading PIXEL");


 
  assure( pixel_type == CPL_TYPE_FLOAT, CPL_ERROR_TYPE_MISMATCH,
          "Type of PIXEL is %s, float expected",
          uves_tostring_cpl_type(pixel_type));


  assure( 2 == pixel_length, CPL_ERROR_INCOMPATIBLE_INPUT,
            "PIXEL length is %d but expected size is %d",
            pixel_length, 2 );


  uves_msg("PIXEL: %f %f length=%d",pixel[0],pixel[1],pixel_length);
  rsample=2.*pixel[0]/3.;

  uves_msg("rsample=%f",rsample);

  
  uves_free_propertylist(&header);

  
  header = uves_propertylist_load(cpl_frame_get_filename(ifrm), 0);
  check( fibre_mask_frm = uves_read_midas_array(header, 
                                            "FIBREMASK", 
                                            &fibre_mask_length,
                                            &fibre_mask_type, 
                                            NULL),
	 "Error reading FIBREMASK");

 
  assure( fibre_mask_type == CPL_TYPE_INT, CPL_ERROR_TYPE_MISMATCH,
          "Type of FIBREMASK is %s, int expected",
          uves_tostring_cpl_type(fibre_mask_type));


  assure( MAXFIBRES == fibre_mask_length, CPL_ERROR_INCOMPATIBLE_INPUT,
            "FIBREMASK length is %d but MAXFIBRES is %d",
            fibre_mask_length, MAXFIBRES);
 

  check_nomsg(qc_geolat=uves_pfits_get_geolat(header));
  check_nomsg(qc_geolon=uves_pfits_get_geolon(header));
  check_nomsg(qc_obs_time=uves_pfits_get_exptime(header));



  check_nomsg(wcen=uves_pfits_get_gratwlen(header,chip));
  wlen=(int)wcen;
  check_nomsg(flames_set_delta(wlen, chip,&delta1, &delta2));

  uves_msg("wlen=%d delta1=%f delta2=%f",wlen,delta1,delta2);
  //rsample = min_rsample;


  /*
  @p flames_reduce,SET_DELTA
  rsample = min_rsample
  */


  if(cubify_products==0) {


    for(it = fib_min; it<= fib_max; it++) {


      if ( (fibre_mask_lin[it-1] == 1) && 
	   (fibre_mask_frm[it-1] == 1) ) {
               
 
	// RAW data
	// EXTRACTED RAW

	sprintf(file,"%s%s%4.4d%s",drs_base_name,"_raw",it,".fits");
	uves_msg("file=%s",file);
	uves_msg("tag=%s",FLAMES_XB_SCI_RAW(chip));
	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      file,
				      FLAMES_XB_SCI_RAW(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), // fixme: check arguments 
	       "Could not add frame '%s' (%s) to frameset",
	       file, FLAMES_XB_SCI_RAW(chip));
      
	uves_msg("Frame '%s' (%s) added to frameset",
		 file, FLAMES_XB_SCI_RAW(chip));


	//ERROR EXTRACTED RAW

	// fixme: make sure that the  werr  image is non-negative by
	//       passing the appropriate option to uves_rebin() 
	sprintf(efile,"%s%s%4.4d%s",drs_base_name,"_rawsig",it,".fits");
	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      efile,
				      FLAMES_ERR_XB_SCI_RAW(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       efile, FLAMES_ERR_XB_SCI_RAW(chip));


	//REBINNED RAW
	sprintf(wfile,"%s%s","w",file);
	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      wfile,
				      FLAMES_WXB_SCI_RAW(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       wfile, FLAMES_WXB_SCI_RAW(chip));

      
	//ERROR REBINNED RAW
	sprintf(wfile,"%s%s","w",efile);
	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      wfile,
				      FLAMES_ERR_WXB_SCI_RAW(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       wfile, FLAMES_ERR_WXB_SCI_RAW(chip));
     
	uves_msg("Frame '%s' (%s) added to frameset",
		 wfile, FLAMES_ERR_WXB_SCI_RAW(chip));

	//MERGED RAW
	sprintf(mfile,"%s%s","mw",file);
	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      mfile,
				      FLAMES_MWXB_SCI_RAW(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       mfile, FLAMES_MWXB_SCI_RAW(chip));
      
	uves_msg("Frame '%s' (%s) added to frameset",
		 mfile, FLAMES_MWXB_SCI_RAW(chip));


	//ERROR MERGED RAW
	sprintf(file,"%s%s%4.4d%s",drs_base_name,"_raw",it,"_sigma.fits");
	sprintf(mfile,"%s%s","mw",file);
	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      mfile,
				      FLAMES_ERR_MWXB_SCI_RAW(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       mfile, FLAMES_ERR_MWXB_SCI_RAW(chip));
      
	uves_msg("Frame '%s' (%s) added to frameset",
		 mfile, FLAMES_ERR_MWXB_SCI_RAW(chip));


	//EXTRACTED
	sprintf(file,"%s%s%4.4d%s",drs_base_name,"_",it,".fits");
	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      file,
				      FLAMES_XB_SCI(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       file, FLAMES_XB_SCI(chip));
      
	uves_msg("Frame '%s' (%s) added to frameset",
		 file, FLAMES_XB_SCI(chip));


	//ERROR EXTRACTED
	sprintf(efile,"%s%s%4.4d%s",drs_base_name,"_sig",it,".fits");
	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      efile,
				      FLAMES_ERR_XB_SCI(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       efile, FLAMES_ERR_XB_SCI(chip));
      
	uves_msg("Frame '%s' (%s) added to frameset",
		 efile, FLAMES_ERR_XB_SCI(chip));


	//REBINNED
	sprintf(wfile,"%s%s","w",file);
	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      wfile,
				      FLAMES_WXB_SCI(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       wfile, FLAMES_WXB_SCI(chip));
      
	uves_msg("Frame '%s' (%s) added to frameset",
		 wfile, FLAMES_WXB_SCI(chip));

	//ERROR REBINNED
	sprintf(wfile,"%s%s","w",efile);
	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      wfile,
				      FLAMES_ERR_WXB_SCI(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       wfile, FLAMES_ERR_WXB_SCI(chip));
      
	uves_msg("Frame '%s' (%s) added to frameset",
		 wfile, FLAMES_ERR_WXB_SCI(chip));
 
	//MERGED
	sprintf(mfile,"%s%s","mw",file);
       if(it==1) {

	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      mfile,
				      FLAMES_MWXB_SCI(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      qclog, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       mfile, FLAMES_MWXB_SCI(chip));

       } else {

	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      mfile,
				      FLAMES_MWXB_SCI(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       mfile, FLAMES_MWXB_SCI(chip));

       }

      
	uves_msg("Frame '%s' (%s) added to frameset",
		 mfile, FLAMES_MWXB_SCI(chip));


	//MISSING ERROR MERGED?
	sprintf(file,"%s%s%4.4d%s",drs_base_name,"_",it,"_sigma.fits");
 	sprintf(mfile,"%s%s","mw",file);
  	check( flames_frameset_insert(
				      frames,
				      CPL_FRAME_GROUP_PRODUCT,
				      CPL_FRAME_TYPE_IMAGE,
				      CPL_FRAME_LEVEL_INTERMEDIATE,
				      mfile,
				      FLAMES_ERR_MWXB_SCI(chip),
				      ref_header,
				      parameters,
				      recipe_id,
				      PACKAGE "/" PACKAGE_VERSION,
				      NULL, start_time, true, 0), 
	       "Could not add frame '%s' (%s) to frameset",
	       mfile, FLAMES_ERR_MWXB_SCI(chip));
 
	uves_msg("Frame '%s' (%s) added to frameset",
		 mfile, FLAMES_ERR_MWXB_SCI(chip));


      } //end check on fribremask


    }
    uves_free_propertylist(&header);

  } else {



    //normal data
    //EXTRACTED
    sprintf(file,"%s",drs_base_name);
    sprintf(cfile,"%s%s",file,"_pack.fits");
    uves_msg("cfile=%s",cfile);
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_XB_SCI(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_XB_SCI(chip));
      
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_XB_SCI(chip));

    //ERROR EXTRACTED
    sprintf(file,"%s%s",drs_base_name,"_sig");
    sprintf(cfile,"%s%s",file,"pack.fits");
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_ERR_XB_SCI(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_ERR_XB_SCI(chip));
      
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_ERR_XB_SCI(chip));


    //REBINNED
    sprintf(file,"%s%s","w",drs_base_name);
    sprintf(cfile,"%s%s",file,"_pack.fits");
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_WXB_SCI(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_WXB_SCI(chip));
      
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_WXB_SCI(chip));


    //ERROR REBINNED
    sprintf(file,"%s%s%s","w",drs_base_name,"_sig");
    sprintf(cfile,"%s%s",file,"pack.fits");
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_ERR_WXB_SCI(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_ERR_WXB_SCI(chip));
      
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_ERR_WXB_SCI(chip));

    //MERGED
    sprintf(file,"%s%s","mw",drs_base_name);
    sprintf(cfile,"%s%s",file,"_pack.fits");
    if(it==1) {
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_MWXB_SCI(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  qclog, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_MWXB_SCI(chip));
    } else {
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_MWXB_SCI(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_MWXB_SCI(chip));

    }
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_MWXB_SCI(chip));


    //ERROR MERGED
    sprintf(file,"%s%s","mw",drs_base_name);
    uves_msg("file=%s",file);
    sprintf(cfile,"%s%s",file,"_sigma_pack.fits");
    uves_msg("cfile=%s",cfile);
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_ERR_MWXB_SCI(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_ERR_MWXB_SCI(chip));
      
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_ERR_MWXB_SCI(chip));


    //raw data
    //EXTRACTED RAW
    sprintf(file,"%s%s",drs_base_name,"_raw");
    sprintf(cfile,"%s%s",file,"pack.fits");
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_XB_SCI_RAW(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_XB_SCI_RAW(chip));
      
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_XB_SCI_RAW(chip));


    //ERROR EXTRACTED RAW 
    sprintf(file,"%s%s",drs_base_name,"_rawsig");
    sprintf(cfile,"%s%s",file,"pack.fits");
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_ERR_XB_SCI_RAW(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_ERR_XB_SCI_RAW(chip));
      
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_ERR_XB_SCI_RAW(chip));




    //REBINNED RAW
    sprintf(file,"%s%s%s","w",drs_base_name,"_raw");
    sprintf(cfile,"%s%s",file,"pack.fits");
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_WXB_SCI_RAW(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_WXB_SCI_RAW(chip));
      
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_WXB_SCI_RAW(chip));

    //ERROR REBINNED RAW
    sprintf(file,"%s%s%s","w",drs_base_name,"_rawsig");
    sprintf(cfile,"%s%s",file,"pack.fits");
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_ERR_WXB_SCI_RAW(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_ERR_WXB_SCI_RAW(chip));
      
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_ERR_WXB_SCI_RAW(chip));


    //MERGED RAW
    sprintf(file,"%s%s%s","mw",drs_base_name,"_raw");
    sprintf(cfile,"%s%s",file,"pack.fits");
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_MWXB_SCI_RAW(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_MWXB_SCI_RAW(chip));
      
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_MWXB_SCI_RAW(chip));

    //MISSING ERROR MERGED RAW?
    sprintf(file,"%s%s%s","mw",drs_base_name,"_raw");
    sprintf(cfile,"%s%s",file,"sigma_pack.fits");
    check( flames_frameset_insert(
				  frames,
				  CPL_FRAME_GROUP_PRODUCT,
				  CPL_FRAME_TYPE_IMAGE,
				  CPL_FRAME_LEVEL_INTERMEDIATE,
				  cfile,
				  FLAMES_ERR_MWXB_SCI_RAW(chip),
				  ref_header,
				  parameters,
				  recipe_id,
				  PACKAGE "/" PACKAGE_VERSION,
				  NULL, start_time, true, 0), 
	   "Could not add frame '%s' (%s) to frameset",
	   cfile, FLAMES_ERR_MWXB_SCI_RAW(chip));
      
    uves_msg("Frame '%s' (%s) added to frameset",
	     cfile, FLAMES_ERR_MWXB_SCI_RAW(chip));




  }




//PIPPO
 cleanup:
  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    //uve_free_imagelist(&obj_cor);
    return -1;
  } else {
    return 0;
  }


}




/*---------------------------------------------------------------------------*/
/**
  @brief procedure to compute efficiency 
  @return   0 if everything is ok

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

  /*
static int
flames_reduce_compeff(void)
{

  goto cleanup;


define/parameter p1 ? tbl "Enter UVES-FIBRE table name"
define/parameter p2 ? c   "Enter prefix"

define/local uves_fib_tbl/c/1/80 {p1}
define/local opfx/c/1/80 {p2}
define/local type/c/1/80 " " all
define/local fmax/i/1/1 9
define/local kk/i/1/1 0
define/local fib_tmp/i/1/1 0
write/keyword fib_mask/i/1/{fmax} 0 all
write/keyword fib_targ/c*25/1/{fmax} " " all

!identify fiber targets
do kk = 1 {fmax}
   fib_mask({kk}) = {{uves_fib_tbl},:FIBREMASK,{kk}}
   fib_targ({kk}) = "{{uves_fib_tbl},:OBJECT,{kk}}"
   w/o "fibre info: {fib_mask({kk})}-{fib_targ({kk})}"
enddo


!get average sky
copy/ii "blz{opfx}{prefid}_0002.bdf"  "x_avg_sky_{prefid}"
copy/ii "wblz{opfx}{prefid}_0002.bdf" "w_avg_sky_{prefid}"
compute/image x_avg_sky_{prefid} =  x_avg_sky_{prefid} * 0.
compute/image w_avg_sky_{prefid} =  w_avg_sky_{prefid} * 0.
define/local nsky/i/1/1 0
do kk = 1 {fmax}
   fib_tmp = fib_mask({kk})
   if {fib_tmp} .GT. 0 then
      if m$index(fib_targ({kk}),"Sky") .gt. 0 then
         compute_image x_avg_sky_{prefid} = x_avg_sky_{prefid} + blz{opfx}{prefid}_{kk}
         compute_image w_avg_sky_{prefid} = w_avg_sky_{prefid} + wblz{opfx}{prefid}_{kk}
         nsky = nsky+1
      endif
   endif
enddo
compute/image x_avg_sky_{prefid} = x_avg_sky_{prefid} / {nsky}
compute/image w_avg_sky_{prefid} = w_avg_sky_{prefid} / {nsky}

!subtracts average sky to object frame, computes efficiency

do kk = 1 {fmax}
   if {fib_mask({kk})} .gt. 0 then
      if m$index(fib_targ({kk}),"Sky") .eq. 0 then
         copy/ii blz{opfx}{prefid}_{kk}  x_obj_{prefid}_{kk}
         copy/ii wblz{opfx}{prefid}_{kk} w_obj_{prefid}_{kk}
         compute/image x_obj_{prefid}_{kk} = x_obj_{prefid}_{kk} - x_avg_sky_{prefid}
         compute/image w_obj_{prefid}_{kk} = w_obj_{prefid}_{kk} - w_avg_sky_{prefid}
         set/format i1
         @p flames_efficiency,CALC_EFF {parSci} {extinc} {stdstar} w_obj_{prefid}_000{kk} tmp_{kk}_{prefid}.tbl {kk}
         eff = "{q1}" 
         set/format
      endif
   endif
enddo
define/local merged_sw/i/1/1 0
define/local result/c/1/80 " " all
do kk = 1 {fmax}
   parse/path {parSci}
   result = "eff_w_obj_{prefid}_{kk}_{q2}.tbl"
   if m$exist("{result}") .gt. 0 then
      if {merged_sw} .eq. 0 then 
         merge/table {result}  eff_{prefid}.tbl
         compute/table  eff_{prefid}.tbl :FIB_NO = {kk}
         merged_sw = 1
      else
         compute/table  eff_{prefid}.tbl :FIB_NO = {kk}
         -rename eff_{prefid}.tbl tmp.tbl
         merge/table tmp.tbl {result}  eff_{prefid}.tbl
      endif
   endif
enddo


 cleanup:
  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    //uves_free_imagelist(&obj_cor);
    return -1;
  } else {
    return 0;
  }

  
    return 0;

}
  */


/*---------------------------------------------------------------------------*/
/**
  @brief procedure to compute quality control 
  @return   0 if everything is ok

*/
/*---------------------------------------------------------------------------*/
   /*
static int
flames_reduce_qclog(void)
{

  goto cleanup;
 cleanup:
  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    //uves_free_imagelist(&obj_cor);
    return -1;
  } else {
    return 0;
  }


}

   */


/*---------------------------------------------------------------------------*/
/**
  @brief procedure to compute quality control
  @param   wlen    input frame wavelength
  @param   chip    detector's chip
  @param   delta1  left order overlapping size
  @param   delta2  right order overlapping size
  @return   0 if everything is ok

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

static int
flames_set_delta(const int wlen, 
		 enum uves_chip chip,
                 double* delta1, 
                 double* delta2)
{



  if(strcmp(DRS_DEL_SW,"A") == 0) {

    if ( (*delta1 == -1) && (*delta2 == -1) ) {
    switch(wlen) {

      case 520:

      *delta1=14.;
      *delta2=4.;

      break;

      case 580:
      if(chip == UVES_CHIP_BLUE) {

        *delta1=12.;
        *delta2=4.;

      } else {

        *delta1=14.;
        *delta2=4.;

      }
      break;

      case 860:

      *delta1=4.;
      *delta2=0.;

      break;


    }
    }
    uves_msg("delta1=%g delta2=%g",*delta1,*delta2);
   
  } else if (strcmp(DRS_DEL_SW,"U") == 0) {

    if ( (*delta1 == -1) && (*delta2 == -1) ) {
    switch(wlen) {

      case 520:

      *delta1=14.;
      *delta2=4.;

      break;

      case 580:
      if(chip == UVES_CHIP_BLUE) {

        *delta1=12.;
        *delta2=4.;

      } else {

        *delta1=14.;
        *delta2=4.;

      }
      break;

      case 860:

      *delta1=4.;
      *delta2=0.;

      break;


    }

    }
    uves_msg("delta1=%g delta2=%g",*delta1,*delta2);
    

  } else if (strcmp(DRS_DEL_SW,"O") == 0) {


  } else {

      *delta1=5.;
      *delta2=5.;

  }



/*

!==========================================================================
ENTRY SET_DELTA
define/local DELTA1/r/1/1 5.
define/local DELTA2/r/1/1 5.

if "{DRS_DEL_SW}" .eq. "A" then
! Automatic setting: proper values for DELTA1 and DELTA2 are chosen
! according to the wavelength setting
!     MRGMTD = "OPTIMAL"
       if {WLEN} .eq. 520 then
     DELTA1 = 14.
     DELTA2 = 4.
  else if {WLEN} .eq. 580 then
     if PATHID .eq. 1 then
        DELTA1 = 12.
        DELTA2 = 4.
     else
        DELTA1 = 14.
        DELTA2 = 4.
     endif
  else if {WLEN} .eq. 860 then
     DELTA1 = 14.
     DELTA2 = 4.
  endif
else if "{DRS_DEL_SW}" .eq. "U" then
  !do nothing, use User's defined values.
else if "{DRS_DEL_SW}" .eq. "O" then
     DELTA1 = {ECHORD(4)}
     DELTA2 = {ECHORD(5)}
     DRS_MER_DELTA = "?"
else
      DELTA1 = 5
      DELTA2 = 5
endif

DRS_MER_DELTA = "{DELTA1},{DELTA2}"
!==========================================================================
*/

  return 0;

}  




/*---------------------------------------------------------------------------*/
/**
  @brief procedure to rebin a frame
  @param  params   recipe parameters
  @param  filename input frame file name
  @param  lin_tab  input line table
  @param  disp_rel input dispersion relation
  @param  omin     absolute order minimum
  @param  omax     absolute order maximum
  @param  wimg     output wavelength calibrated image
  @param  wheader  output header
  @return   0 if everything is ok

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

static int
flames_rebin_frame(const cpl_parameterlist *params, 
                   const char* filename,
                   const cpl_table* lin_tab,  
                   const polynomial  *disp_rel,
                   const int omax,
                   const int omin,
                   cpl_image** wimg, 
                   uves_propertylist** wheader)
{


  cpl_frame* frm=NULL;
  uves_propertylist* header=NULL;

  cpl_image* img=NULL;
  char wfile[80];

  const char* context = make_str(FLAMES_OBS_SCIRED_ID);

  uves_msg_debug("Rebin %s",filename);
  check_nomsg(frm=cpl_frame_new());

  check_nomsg(cpl_frame_set_filename(frm,filename));
  check_nomsg(cpl_frame_set_type(frm,CPL_FRAME_TYPE_IMAGE));
  //check_nomsg(header=uves_propertylist_load(filename,0));
  check_nomsg(img=uves_load_image(frm,0,0,&header));


  check(*wimg=uves_rebin(img,params,context,lin_tab,disp_rel,omax,omin,1,false,
                         false,wheader),
	"Error resampling extracted science fibre frame %s",filename);

  sprintf(wfile,"%s%s","w",filename);
  uves_save_image(*wimg,wfile,*wheader,true, true);



 cleanup:
  uves_free_image(&img);
  uves_free_propertylist(&header);
  uves_free_frame(&frm);

  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    return -1;
  } else {
    return 0;
  }

}






/**@}*/


