/*                                                                            *
 *   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-02-19 13:29:39 $
 * $Revision: 1.54 $
 * $Name: not supported by cvs2svn $
 * $Log: not supported by cvs2svn $
 * Revision 1.53  2013/02/15 06:56:41  amodigli
 * fixed compiler error
 *
 * Revision 1.52  2013/02/14 15:42:12  amodigli
 * fixed a problem in FIPREPOS info in packed product from scired
 *
 * Revision 1.51  2012/12/04 16:31:51  amodigli
 * fixed cpplus-jenkins errors
 *
 * Revision 1.50  2012/11/28 09:43:54  amodigli
 * fixed typo in INF.FIBSTART/INF.FIBEND keywords
 *
 * Revision 1.49  2012/10/29 21:04:34  amodigli
 * fixed mem leaks
 *
 * Revision 1.48  2012/10/28 19:08:42  amodigli
 * fixed mem leaks
 *
 * Revision 1.47  2012/10/28 16:49:38  amodigli
 * fixed mem leaks
 *
 * Revision 1.46  2012/10/27 08:55:16  amodigli
 * fixed mem leaks
 *
 * Revision 1.45  2012/10/27 06:44:20  amodigli
 * fix mem leaks
 *
 * Revision 1.44  2012/10/08 11:33:29  amodigli
 * changed to support data reduction in case of broken fibre
 *
 * Revision 1.43  2012/07/09 08:38:45  amodigli
 * fixed cppcheck (memleak) error
 *
 * Revision 1.42  2012/04/27 09:17:27  amodigli
 * fixed mem leak indicated by jenkins static checks
 *
 * Revision 1.41  2012/01/12 16:46:34  amodigli
 * fixed compiler warnings with CPL6
 *
 * Revision 1.40  2011/04/26 06:24:27  amodigli
 * fixed DFS10228 (problem reducing wavecal fiber mode data due to missing units in tmp table)
 *
 * Revision 1.39  2010/09/24 09:31:30  amodigli
 * put back QFITS dependency to fix problem spot by NRI on FIBER mode (with MIDAS calibs) data
 *
 * Revision 1.37  2009/04/14 07:10:58  amodigli
 * removed flames_reduce_vcorrel implementation
 *
 * Revision 1.36  2009/03/05 08:52:12  amodigli
 * remove print statement
 *
 * Revision 1.35  2009/03/02 15:51:43  amodigli
 * commented out ccf zero point updated to get same results as MIDAS
 *
 * Revision 1.34  2009/02/27 17:00:43  amodigli
 * changes to make zero point update directly in function
 *
 * Revision 1.33  2008/09/29 06:52:10  amodigli
 * add #include <string.h>
 *
 * Revision 1.32  2008/06/27 05:58:34  amodigli
 * dump QC in flames_reduce_vcorrel and clean temporary FITS
 *
 * Revision 1.31  2008/06/26 08:24:06  amodigli
 * fixed CCF computation
 *
 * Revision 1.30  2008/06/20 14:22:42  amodigli
 * fixed bug in corvel
 *
 * Revision 1.29  2008/04/07 07:47:28  amodigli
 * fixed seg fault
 *
 * Revision 1.28  2008/04/04 14:02:28  amodigli
 * added flames_my_cubify2
 *
 * Revision 1.27  2008/03/25 08:56:13  amodigli
 * fixed compilation warnings
 *
 * Revision 1.26  2008/03/03 10:34:37  amodigli
 * added warning
 *
 * Revision 1.25  2008/02/29 15:37:13  amodigli
 * fixed some warning messages on memory allocation
 *
 * Revision 1.24  2008/02/21 07:42:22  amodigli
 * added PIPEFILE to fibreff cubes to fix DFS05026
 *
 * Revision 1.23  2008/02/05 13:55:11  amodigli
 * fixed compilation warnings
 *
 * Revision 1.22  2008/01/30 17:14:10  amodigli
 * fixed some bugs velocity correlation
 *
 * Revision 1.21  2008/01/28 17:09:27  amodigli
 * added fits estention to file name
 *
 * Revision 1.20  2008/01/25 12:25:32  amodigli
 * proper order range for velocity correction computation
 *
 * Revision 1.19  2008/01/17 17:29:13  amodigli
 * debug corvel
 *
 * Revision 1.18  2008/01/10 16:33:42  amodigli
 * fixed bug in packing of spectra in an image
 *
 * Revision 1.17  2007/12/15 09:55:44  amodigli
 * added stuf to vcorrel and changed interface flames_add_desc_set2
 *
 * Revision 1.16  2007/12/10 07:34:50  amodigli
 * added flames_reduce_add_wstart flames_reduce_vcorrel
 *
 * Revision 1.15  2007/11/19 08:09:25  amodigli
 * changed interface flames_spectra_to_image()
 *
 * Revision 1.14  2007/11/02 11:02:51  amodigli
 * cleaned output
 *
 * Revision 1.13  2007/10/31 17:55:43  amodigli
 * Put flames_reset_start_and_npix in proper place
 *
 * Revision 1.12  2007/10/23 06:44:19  amodigli
 * fixed compilation warnings
 *
 * Revision 1.11  2007/10/17 15:04:30  amodigli
 * added and used flames_frameset_insert
 *
 * Revision 1.10  2007/10/15 06:46:11  amodigli
 * fixed bugs in reduction chain
 *
 * Revision 1.9  2007/10/04 06:38:27  amodigli
 * fixed problem with reduction chain
 *
 * Revision 1.8  2007/10/01 17:23:37  amodigli
 * fixed several bugs in cubify/decubify and called function to set proper FITS header and make work properly science reduction
 *
 * Revision 1.7  2007/09/19 11:50:36  amodigli
 * fixed several bugs
 *
 * Revision 1.6  2007/09/17 08:28:09  amodigli
 * cleane output
 *
 * Revision 1.5  2007/09/13 16:02:47  amodigli
 * fixed several bugs
 *
 * Revision 1.4  2007/08/31 14:20:02  amodigli
 * added flames_cubes_to_supercube
 *
 * Revision 1.3  2007/08/31 06:40:05  amodigli
 * added flames_reduce_reset_descriptors flames_my_decubify flames_my_cubify flames_spectra_to_image flames_images_to_cube from flames_obs_scired.c
 *
 * Revision 1.2  2007/08/16 06:54:09  amodigli
 * cleaned
 *
 * Revision 1.1  2007/08/13 12:13:37  amodigli
 * added to repository
 *
 *
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

/*---------------------------------------------------------------------------*/
/**
 * @defgroup flames_utils_science  Utility functions for science recipe
 */
/*---------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
                            Includes
 ----------------------------------------------------------------------------*/
#include <uves_utils_wrappers.h>
#include <uves_error.h>
#include <uves_globals.h>
#include <uves_dump.h>
#include <uves_pfits.h>

#include <uves_dfs.h>
#include <uves_qclog.h>
#include <uves_chip.h>
#include <uves_msg.h>

#include <flames_dfs.h>
#include <flames_uves.h>
#include <flames_corvel.h>
#include <flames_merge.h>
#include <flames_fileutils.h>
#include <flames_utils_science.h>
#include <flames_def_drs_par.h>
#include <flames_midas_def.h>
#include <string.h>

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


/*-----------------------------------------------------------------------------
                            Functions prototypes
 ----------------------------------------------------------------------------*/



static int    
flames_utils_frameset_insert(cpl_frameset** set_out,
                       const char* tag,
                       const char* filename);

static flames_err
flames_reset_desc_set1(const int out_id,
                       const int dat_id, 
                       const int it,
                       const int in_frm_id);


flames_err
flames_reset_desc_set4(const int out_id,
                       const int dat_id, 
                       const int it,
                       const int in_frm_id);
static flames_err
flames_add_desc_set1(const int out_id,
		     const int ref_id, 
		     const int it,
		     const int in_frm_id);

static flames_err
flames_add_desc_set2(const int out_id,
		     const int ref_id, 
		     const int it);

static flames_err
flames_add_desc_set3(const int out_id,
		     const int ref_id, 
		     const int it,
		     const int in_frm_id);

static flames_err
flames_add_desc_set4(const int out_id,
		     const int ref_id, 
		     const int it,
		     const int in_frm_id);



flames_err
flames_reset_desc_sigma(const char* name_inp,
                        const int nflats,
                        const char* base_out,
                        const int in_frm_id,
			 enum uves_chip chip);

flames_err
flames_reset_desc_badpix(const char* name_inp,
                         const int nflats,
			 const char* base_out,
			 const int in_frm_id,
			 enum uves_chip chip);


flames_err
flames_reset_desc_bound(const char* name_inp,
                        const int nflats,
			const char* base_out,
			const int in_frm_id,
			enum uves_chip chip);

int
flames_extract_cube_from_cube(cpl_frameset* frames,
			     const char* tag,
                             enum uves_chip chip,
                             const int nflats,
			     const char* cub_name,
			     cpl_frameset** set_out);

static const char*
flames_get_tag_slice(const char* ctag,enum uves_chip chip,const int i);

/**@{*/

/*-----------------------------------------------------------------------------
  Implementation
  ---------------------------------------------------------------------------*/







/*---------------------------------------------------------------------------*/
/**
   @brief procedure to compute quality control
   @param   name   file name
   @param   format image format type
   @return   0 if everything is ok

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


int
flames_fix_start_and_npix(const char* name, const int format)
{

  int frameid=0;
  int status=0;
  int unit=0;
  double start[3]={1.0,1.0,0.0};
  int npix[2]={4096,2048};

  uves_msg_debug("fix1 name=%s",name);
  if ((status = SCFOPN(name, format, 0, F_IMA_TYPE, &frameid)) != 0) {
    /* could not open the frame */
    return(MAREMMA);
  }

  if (format == FLAMESBOUNDTYPE) {
    uves_msg_debug("fix21");

    if(SCDWRD(frameid, "START", start, 1, 3, &unit)) {
      SCFCLO(frameid);
      uves_msg_error("setting START");
      return MAREMMA;
    }

  } else {
    uves_msg_debug("fix22");


    if(SCDWRD(frameid, "START", start, 1, 2, &unit)) {
      SCFCLO(frameid);
      uves_msg_error("setting START");
      return MAREMMA;
    }
    uves_msg_debug("fix23");


    //amodigli: reset NPIX
    if(SCDWRI(frameid, "NPIX", npix, 1, 2, &unit)) {
      SCFCLO(frameid);
      uves_msg_error("setting NPIX");
      return MAREMMA;
    }
    uves_msg_debug("fix24");



  }
  uves_msg_debug("fix3 frameid=%d",frameid);

  ck0_nomsg(SCFCLO(frameid));

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


}

/*---------------------------------------------------------------------------*/
/**
   @brief    Reset descriptors 
   @param    name of FITS file
   @param    tag  of FITS file
   @return   0 if successfull, else -1
*/
int
flames_reset_start_and_npix(const char* name, const char* tag)
{
  uves_msg_debug("name=%s tag=%s",name,tag);
  if(
     //  (strstr(tag,"FIB_FF_BP")  != NULL) || 
     (strstr(tag,"SLIT_FF_SG") != NULL) || 
     (strstr(tag,"SLIT_FF_DT") != NULL) 
     )
    {
      uves_msg_debug("case1");
      if(strstr(tag,"C") == NULL) {
     uves_msg_debug("Fix start & npix");
	check_nomsg(flames_fix_start_and_npix(name,FLAMESDATATYPE));
      }
    } else if (strstr(tag,"SLIT_FF_BP") != NULL) {
    uves_msg_debug("case2");

    if(strstr(tag,"C") == NULL) {
      check_nomsg(flames_fix_start_and_npix(name,FLAMESMASKTYPE));
    }

  } else if (
	     (strstr(tag,"FIB_FF_DT")  != NULL) ||
	     (strstr(tag,"FIB_FF_SG")  != NULL) 
	     )
    {
      uves_msg_debug("case3");


      if(strstr(tag,"C") == NULL) {
	uves_msg_debug("ck1");
	check_nomsg(flames_fix_start_and_npix(name,FLAMESDATATYPE));
	uves_msg_debug("ck2");
      } 

    } else if (
	       (strstr(tag,"FIB_FF_BN")  != NULL) ||  //Not as NAXIS=3
	       (strstr(tag,"SLIT_FF_BN") != NULL)     //Not as NAXIS=3
	       )
    {
      uves_msg_debug("case4");

      if(strstr(tag,"C") == NULL) {
	check_nomsg(flames_fix_start_and_npix(name,FLAMESBOUNDTYPE));
      }
    }


 cleanup:

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

}



int
flames_reduce_reset_descriptors(uves_propertylist* head_ref,
                                uves_propertylist** head_out,
                                const int i)
{

  const char* cunit=NULL;
  const char* ident=NULL;
  float* lhcuts=NULL;
  double* refpix=NULL;
  int key_length=0;
  cpl_type key_type=0;

  char key_name[80];


  //double crpix[4] = {1, 1, 1, 1};
  //double crval[4] = {1, 1, 1, 1};
  //double cdelt[4] = {1, 1, 1, 1};



  sprintf(key_name,"%s%d%s","ESO.SLC",i,".IDENT");


  check(ident=uves_read_midas_array(head_ref,key_name,&key_length,&key_type,
				    NULL),"Error reading %s",key_name);


  assure( key_type == CPL_TYPE_STRING, CPL_ERROR_TYPE_MISMATCH,
	  "Type of %s is %s, string expected",key_name,
	  uves_tostring_cpl_type(key_type));




  /* 
     assure( 80 == key_length, CPL_ERROR_INCOMPATIBLE_INPUT,
     "%s length is %d but IDENT is %d",
     key_name,key_length, 80);
  */
  uves_msg_debug("******* IDENT=%s",ident);
  if(uves_propertylist_contains(*head_out,"OBJECT")) {

    check_nomsg(uves_propertylist_update_string(*head_out,"OBJECT",ident));

  } else {

    check_nomsg(uves_propertylist_append_string(*head_out,"OBJECT",ident));

  }
  uves_free(ident);

  //check_nomsg(uves_propertylist_update_double(*head_out,"CRPIX1",crpix[0]));


  sprintf(key_name,"%s%d%s","ESO.SLC",i,".CUNIT");

  check(cunit=uves_read_midas_array(head_ref,key_name,&key_length,&key_type,
				    NULL),"Error reading %s",key_name);
 
  assure( key_type == CPL_TYPE_STRING, CPL_ERROR_TYPE_MISMATCH,
	  "Type of %s is %s, string expected",key_name,
	  uves_tostring_cpl_type(key_type));

  if(uves_propertylist_contains(*head_out,"CUNIT")) {
    check_nomsg(uves_propertylist_update_string(*head_out,"CUNIT",cunit));
  } else {
    check_nomsg(uves_propertylist_append_string(*head_out,"CUNIT",cunit));
  }
  uves_free(cunit);

  /*
    assure( 10 == key_length, CPL_ERROR_INCOMPATIBLE_INPUT,
    "%s length is %d but CUNIT is %d",
    key_name,key_length, 10);
  */

  sprintf(key_name,"%s%d%s","ESO.SLC",i,".LHCUTS");
  check(lhcuts=uves_read_midas_array(head_ref,key_name,&key_length,&key_type,
				     NULL),"Error reading %s",key_name);
 
  assure( key_type == CPL_TYPE_FLOAT, CPL_ERROR_TYPE_MISMATCH,
	  "Type of %s is %s, string expected",key_name,
	  uves_tostring_cpl_type(key_type));

  assure( 4 == key_length, CPL_ERROR_INCOMPATIBLE_INPUT,
	  "%s length is %d but LHCUTS is %d",
	  key_name,key_length, 4);



  cpl_free(lhcuts);


  sprintf(key_name,"%s%d%s","ESO.SLC",i,".REFPIX");
  check(refpix=uves_read_midas_array(head_ref,key_name,&key_length,&key_type,
				     NULL),"Error reading %s",key_name);
 
  assure( key_type == CPL_TYPE_DOUBLE, CPL_ERROR_TYPE_MISMATCH,
	  "Type of %s is %s, string expected",key_name,
	  uves_tostring_cpl_type(key_type));

  assure( 2 == key_length, CPL_ERROR_INCOMPATIBLE_INPUT,
	  "%s length is %d but REFPIX is %d",
	  key_name,key_length, 2);

  cpl_free(refpix);


 cleanup:


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

}



flames_err
flames_reset_desc_set0(const int out_id,
                       const int dat_id, 
                       const int it,
                       const int in_frm_id)

{
  int actvals=0;
  int unit=0;
  int null=0;
  const char* h_ident= "IDENT"; 
  //char ident[MED_NAME_SIZE]; 
  char des_name[MED_NAME_SIZE]; 

  const char* d_yshift="YSHIFT";
  const char* prefix="ESO SLC";
  double yshift=0;

  const char* d_n_fibres="NUMFIBRES";
  const char* d_fibres="FIBRES";
  int fibres[N_FIBRES_MAX];
  int n_fibres=0;

  const char* prefix2="ESO.SLC";

  const char* parSlitFFident="Normalised slit FF";
  const char* parFibFFident="Cleaned fibre FF";
  /* The following is valid only for DT: but isn't that the same as 
     copying what in SLCi.IDENT ? */
  if(in_frm_id == 1) {
    if (SCDWRC(out_id,h_ident, 1, parSlitFFident, 1, 72, &unit)) {
      return flames_midas_error(MAREMMA);
    }
  } else {
    if (SCDWRC(out_id,h_ident, 1, parFibFFident, 1, 72, &unit)) {
      return flames_midas_error(MAREMMA);
    }
  }
 
  sprintf(des_name,"%s%d %s",prefix,it,d_yshift);
  if (SCDRDD(dat_id,des_name,1,1,&actvals,&yshift,&unit,&null) != 0 ) {
    return flames_midas_error(MAREMMA);
  }
  if (SCDWRD(out_id,d_yshift,&yshift, 1, 1, &unit)) {
    return flames_midas_error(MAREMMA);
  }

  if(in_frm_id == 2) {
    sprintf(des_name,"%s%d %s",prefix,it,d_n_fibres);
    if (SCDRDI(dat_id,des_name,1,1,&actvals,&n_fibres,&unit,&null) != 0 ) {
      return flames_midas_error(MAREMMA);
    }
    if (SCDWRI(out_id,d_n_fibres,&n_fibres, 1, 1, &unit)) {
      return flames_midas_error(MAREMMA);
    }
   
    sprintf(des_name,"%s%d.%s",prefix2,it,d_fibres);
    if (SCDRDI(dat_id,des_name,1,N_FIBRES_MAX,&actvals,fibres,&unit,&null) 
	!= 0 ) {
      return flames_midas_error(MAREMMA);
    }
    if (SCDWRI(out_id,d_fibres,fibres, 1, N_FIBRES_MAX, &unit)) {
      return flames_midas_error(MAREMMA);
    }

  }

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

}



flames_err
flames_reset_desc_set1(const int out_id,
                       const int dat_id, 
                       const int it,
                       const int in_frm_id)

{

  int actvals=0;
  int unit=0;
  int null=0;
  float lhcuts[4]={0,0,0,0};
  //double refpix[2]={0,0};

  char des_name[MIN_NAME_SIZE];

  char origname[MED_NAME_SIZE];
  char sigmaframe[MED_NAME_SIZE]; 
  char badpixframe[MED_NAME_SIZE]; 
  char ident[MED_NAME_SIZE]; 
  //char cunit[MED_NAME_SIZE]; 

  const char* prefix="ESO.SLC";

  //const char* h_ident= "IDENT"; 
  const char* h_origname= "ORIGFILE"; 
  const char* d_sigmaframe= "SIGMAFRAME"; 
  const char* d_badpixframe="BADPXFRAME"; 
  char type=' ';
  const char* parSlitFFident="Normalised slit FF";
  const char* parFibFFident="Cleaned fibre FF";

  /*
    !{o_frm},{h_ident} = "{{c_frm},{prefix}{it}.{h_ident}}"
    {o_frm},CUNIT     = "{{c_frm},{prefix}{it}.CUNIT}"
    
    {o_frm},LHCUTS(1) = m$value({c_frm},{prefix}{it}.LHCUTS(1))
    {o_frm},LHCUTS(2) = m$value({c_frm},{prefix}{it}.LHCUTS(2))
    {o_frm},LHCUTS(3) = m$value({c_frm},{prefix}{it}.LHCUTS(3))
    {o_frm},LHCUTS(4) = m$value({c_frm},{prefix}{it}.LHCUTS(4))

    {o_frm},REFPIX(1) = m$value({c_frm},{prefix}{it}.REFPIX(1))
    {o_frm},REFPIX(2) = m$value({c_frm},{prefix}{it}.REFPIX(2))
  */
  /* The following creates problems */
  
  sprintf(des_name,"%s%d%s",prefix,it,".IDENT");
  if(0 == SCDPRS(dat_id,des_name,&type,&actvals,&null) ) {
    if ((SCDRDC(dat_id,des_name,1,1,48,&actvals,ident,&unit,&null)!=0)) {
      return flames_midas_error(MAREMMA);
    }

    // FIXME here we have to modify OBJECT descriptor 
    if (SCDWRC(out_id,"IDENT",1,ident,1,actvals, &unit)) {
      return flames_midas_error(MAREMMA);
    } 
  } else {
    if(in_frm_id == 1) {
      if (SCDWRC(out_id,"IDENT",1,parSlitFFident,1,actvals, &unit)) {
	return flames_midas_error(MAREMMA);
      } 
    } else {
      if (SCDWRC(out_id,"IDENT",1,parFibFFident,1,actvals, &unit)) {
	return flames_midas_error(MAREMMA);
      } 

    }
  }
  /*
  sprintf(des_name,"%s%d%s",prefix,it,".CUNIT");
  if(0 == SCDPRS(dat_id,des_name,&type,&actvals,&null) ) {
    if ((SCDRDC(dat_id,des_name,1,1,48,&actvals,cunit,&unit,&null)!=0)) {
      return flames_midas_error(MAREMMA);
    }
    if (SCDWRC(out_id,"CUNIT",1,cunit,1,48, &unit)) {
      return flames_midas_error(MAREMMA);
    }
  } 
  */ 
 

  sprintf(des_name,"%s%d%s",prefix,it,".LHCUTS");
  if(0 == SCDPRS(dat_id,des_name,&type,&actvals,&null) ) {
    if (SCDRDR(dat_id,des_name,1,4,&actvals,lhcuts,&unit,&null) != 0 ) {
      return flames_midas_error(MAREMMA);
    }
    if (SCDWRR(out_id, "LHCUTS", lhcuts, 1, 4, &unit)) {
      return flames_midas_error(MAREMMA);
    }
  }

  /*
  sprintf(des_name,"%s%d%s",prefix,it,".REFPIX");
  uves_msg_warning("des_name=%s",des_name);
  if (SCDRDD(dat_id,des_name,1,2,&actvals,refpix,&unit,&null) != 0 ) {
    return flames_midas_error(MAREMMA);
  }

  
  //AMO: FIXME: this creates problems
  if (SCDWRD(out_id, "REFPIX", refpix, 1, 2, &unit)) {
       return flames_midas_error(MAREMMA);
  }
  */

  /*

  write/descr {o_frm} {h_origname}/c/1/80   "{{c_frm},{prefix}{it}.{h_origname}}"

  {o_frm},{d_sigmaframe}  = {{c_frm},{prefix}{it}.{d_sigmaframe}}
  {o_frm},{d_badpixframe} = {{c_frm},{prefix}{it}.{d_badpixframe}}

  {o_frm},{d_sigmafile}   = {{c_frm},{prefix}{it}.{d_sigmafile}}
  {o_frm},{d_badpixfile}  = {{c_frm},{prefix}{it}.{d_badpixfile}}
  */

  sprintf(des_name,"%s%d.%s",prefix,it,h_origname);
  if(0 == SCDPRS(dat_id,des_name,&type,&actvals,&null) ) {
    if ((SCDRDC(dat_id,des_name,1,1,48,&actvals,origname,&unit,&null)!=0)) {
      return flames_midas_error(MAREMMA);
    }
    if (SCDWRC(out_id,h_origname,1,origname, 1, 48, &unit)) {
      return flames_midas_error(MAREMMA);
    }
  }

  sprintf(des_name,"%s%d.%s",prefix,it,d_sigmaframe);
  if(0 == SCDPRS(dat_id,des_name,&type,&actvals,&null) ) {
    if ((SCDRDC(dat_id,des_name,1,1,48,&actvals,sigmaframe,&unit,&null)!=0)) {
      return flames_midas_error(MAREMMA);
    }
    if (SCDWRC(out_id,d_sigmaframe,1,sigmaframe, 1, 48, &unit)) {
      return flames_midas_error(MAREMMA);
    }
  }

  sprintf(des_name,"%s%d.%s",prefix,it,d_badpixframe);
  if(0 == SCDPRS(dat_id,des_name,&type,&actvals,&null) ) {
    if ((SCDRDC(dat_id,des_name,1,1,48,&actvals,badpixframe,&unit,&null)!=0)) {
      return flames_midas_error(MAREMMA);
    }
    if (SCDWRC(out_id,d_badpixframe,1,badpixframe, 1, 48, &unit)) {
      return flames_midas_error(MAREMMA);
    }
  }

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


}




flames_err
flames_reset_desc_set2(const int out_id,
                       const int dat_id, 
                       const int it)

{

  int actvals=0;
  int unit=0;
  int null=0;

  char des_name[MIN_NAME_SIZE];
  const char* prefix="ESO.SLC";
  const char* d_sigmafile="SIGMAFILE";
  char sigmafile[MED_NAME_SIZE];
  char badpixfile[MED_NAME_SIZE];

  const char* d_badpixfile="BADPIXELFILE";

  sprintf(des_name,"%s%d.%s",prefix,it,d_sigmafile);
  if ((SCDRDC(dat_id,des_name,1,1,48,&actvals,sigmafile,&unit,&null)!=0)) {
    return flames_midas_error(MAREMMA);
  }
  if (SCDWRC(out_id,d_sigmafile,1,sigmafile, 1, 48, &unit)) {
    return flames_midas_error(MAREMMA);
  }

  sprintf(des_name,"%s%d.%s",prefix,it,d_badpixfile);
  if ((SCDRDC(dat_id,des_name,1,1,48,&actvals,badpixfile,&unit,&null)!=0)) {
    return flames_midas_error(MAREMMA);
  }
  if (SCDWRC(out_id,d_badpixfile,1,badpixfile, 1, 48, &unit)) {
    return flames_midas_error(MAREMMA);
  }

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

}


flames_err
flames_reset_desc_set3(const int out_id,
                       const int dat_id, 
                       const int it,
                       const int in_frm_id)

{

  int actvals=0;
  int unit=0;
  int null=0;
  char des_name[MIN_NAME_SIZE];
  const char* prefix="ESO SLC";

  const char* d_x1enc="ESO INS SLIT3 X1ENC";
  const char* d_x2enc="ESO INS SLIT3 X2ENC";

  const char* s_x1enc="INS SLIT3 X1ENC";
  const char* s_x2enc="INS SLIT3 X2ENC";

  const char* d_yshift="YSHIFT";
  const char* d_yshift_rms="ESO QC YSHIFT RMS";

  const char* d_halfwidth="HALFWIDTH";
  const char* d_halfwidth_rms="ESO QC HALFWIDTH RMS";

  int x1enc=0;
  int x2enc=0;

  const char* s_yshift_rms="ESO QC YSHIFT RMS";
  const char* s_halfwidth_rms="ESO QC HALFWIDTH RMS";
  char type=' ';


  double yshift=0;
  double halfwidth=0; 
  float f_halfwidth=0; 
  double yshift_rms=0;
  double halfwidth_rms=0;
 
  /*
    {o_frm},{d_x1enc}       = m$value({c_frm},{prefix}{it}.{d_x1enc(5:)}) 
    {o_frm},{d_x2enc}       = m$value({c_frm},{prefix}{it}.{d_x2enc(5:)}) 

    {o_frm},{d_yshift}      = m$value({c_frm},{prefix}{it}.{d_yshift})
  */


 
  sprintf(des_name,"%s%d %s",prefix,it,s_x1enc);
  if (SCDRDI(dat_id,des_name,1,1,&actvals,&x1enc,&unit,&null) != 0 ) {
    return flames_midas_error(MAREMMA);
  }
  if (SCDWRI(out_id,d_x1enc,&x1enc, 1, 1, &unit)) {
    return flames_midas_error(MAREMMA);
  }

  sprintf(des_name,"%s%d %s",prefix,it,s_x2enc);
  if (SCDRDI(dat_id,des_name,1,1,&actvals,&x2enc,&unit,&null) != 0 ) {
    return flames_midas_error(MAREMMA);
  }
  if (SCDWRI(out_id,d_x2enc,&x2enc, 1, 1, &unit)) {
    return flames_midas_error(MAREMMA);
  }


  /*
 
      
  if in_frm_id .eq. 1 then
  !{o_frm},FILENAME  = {{c_frm},{prefix}{it}.FILENAME}
  if m$existd(o_frm,d_yshift_rms) .gt. 0 then
  {o_frm},{d_yshift_rms}    = m$value({c_frm},{prefix}{it}.{d_yshift_rms})
  {o_frm},{d_halfwidth_rms} = m$value({c_frm},{prefix}{it}.{d_halfwidth_rms})
  else
  {o_frm},{s_yshift_rms}    = m$value({c_frm},{prefix}{it}.{s_yshift_rms})
  {o_frm},{s_halfwidth_rms} = m$value({c_frm},{prefix}{it}.{s_halfwidth_rms})

  endif
  {o_frm},{d_halfwidth}     = m$value({c_frm},{prefix}{it}.{d_halfwidth})
  {o_frm},{d_boundaryfile}  = "{{c_frm},{prefix}{it}.{d_boundaryfile}}"
  else
  {o_frm},{d_n_fibres} = m$value({c_frm},{prefix}{it}.{d_n_fibres})
  copy/dd {c_frm} {prefix}{it}.{d_fibres} {o_frm} {d_fibres}
  endif
  enddo
  */

  if (in_frm_id == 1) {

    if(0 == SCDPRS(dat_id,des_name,&type,&actvals,&null) ) {
      sprintf(des_name,"%s%d %s",prefix,it,d_yshift_rms);
      if (SCDRDD(dat_id,des_name,1,1,&actvals,&yshift_rms,&unit,&null) != 0 ) {
	return flames_midas_error(MAREMMA);
      }
      if (SCDWRD(out_id,d_yshift_rms,&yshift_rms, 1, 1, &unit)) {
	return flames_midas_error(MAREMMA);
      }
 
      sprintf(des_name,"%s%d %s",prefix,it,d_halfwidth_rms);
      if (SCDRDD(dat_id,des_name,1,1,&actvals,&halfwidth_rms,&unit,&null) 
	  != 0 ) {
	return flames_midas_error(MAREMMA);
      }
      if (SCDWRD(out_id,d_halfwidth_rms,&halfwidth_rms, 1, 1, &unit)) {
	return flames_midas_error(MAREMMA);
      }

    } else {
 
      sprintf(des_name,"%s%d %s",prefix,it,s_yshift_rms);
      if (SCDRDD(dat_id,des_name,1,1,&actvals,&yshift_rms,&unit,&null) != 0 ) {
	return flames_midas_error(MAREMMA);
      }
      if (SCDWRD(out_id,s_yshift_rms,&yshift_rms, 1, 1, &unit)) {
	return flames_midas_error(MAREMMA);
      }
    
      sprintf(des_name,"%s%d %s",prefix,it,s_halfwidth_rms);
      if (SCDRDD(dat_id,des_name,1,1,&actvals,&halfwidth_rms,&unit,&null) 
	  != 0 ) {
	return flames_midas_error(MAREMMA);
      }
      if (SCDWRD(out_id,s_halfwidth_rms,&halfwidth_rms, 1, 1, &unit)) {
	return flames_midas_error(MAREMMA);
      }

    }

    sprintf(des_name,"%s%d %s",prefix,it,d_yshift);
    if (SCDRDD(dat_id,des_name,1,1,&actvals,&yshift,&unit,&null) != 0 ) {
      return flames_midas_error(MAREMMA);
    }
    if (SCDWRD(out_id,d_yshift,&yshift, 1, 1, &unit)) {
      return flames_midas_error(MAREMMA);
    }
 
    // AMO: Here one should check if descriptor exists and eventually write it.
      sprintf(des_name,"%s%d %s",prefix,it,d_halfwidth);
       if (SCDRDD(dat_id,des_name,1,1,&actvals,&halfwidth,&unit,&null) != 0 ) {
      return flames_midas_error(MAREMMA);
      }
 
      f_halfwidth=halfwidth;
      if (SCDWRR(out_id,d_halfwidth,&f_halfwidth, 1, 1, &unit)) {
      return flames_midas_error(MAREMMA);
      }

  }

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

}


flames_err
flames_reset_desc_set4(const int out_id,
                       const int dat_id, 
                       const int it,
                       const int in_frm_id)

{

  int actvals=0;
  int unit=0;
  int null=0;
  const char* prefix="ESO SLC";
  const char* prefix2="ESO.SLC";

  char des_name[MIN_NAME_SIZE];
  char boundaryfile[MED_NAME_SIZE];
  double halfwidth;
  float float_halfwidth;


  const char* d_halfwidth="HALFWIDTH";
  const char* d_boundaryfile="BOUNDARYFILE";

  if(in_frm_id ==1) {

    
    sprintf(des_name,"%s%d.%s",prefix2,it,d_boundaryfile);
    if ((SCDRDC(dat_id,des_name,1,1,48,&actvals,boundaryfile,
		&unit,&null)!=0)) {
      return flames_midas_error(MAREMMA);
    }
    if (SCDWRC(out_id,d_boundaryfile,1,boundaryfile, 1, 48, &unit)) {
      return flames_midas_error(MAREMMA);
    }
    

    sprintf(des_name,"%s%d %s",prefix,it,d_halfwidth);
    if (SCDRDD(dat_id,des_name,1,1,&actvals,&halfwidth,&unit,&null) != 0 ) {
      return flames_midas_error(MAREMMA);
    }
    float_halfwidth=halfwidth;
    if (SCDWRR(out_id,d_halfwidth,&float_halfwidth, 1, 1, &unit)) {
      return flames_midas_error(MAREMMA);
    }

  } else {
    
  } 

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

}


flames_err
flames_reset_desc_data(const char* name_inp,
                       const int nflats,
                       const char* base_out,
                       const int in_frm_id,
			enum uves_chip chip)

{
  int it=0;
  char o_frm[MIN_NAME_SIZE];
  //Extra for MIDAS interface
  int out_id=0;
  int dat_id=0;
  int status=0;
  char tag[80];

  /*

  int n_fibres=0;
  int fibres[MAXFIBRES];
  char output[MIN_NAME_SIZE];

  char* cunit=NULL;
  char* ident=NULL;
  char* arcfile=NULL;
  char* origname=NULL;
  char* sigmaname=NULL;
  char* maskname=NULL;
  float* lhcuts=NULL;
  double* refpix=NULL;

  int key_length=0;
  cpl_type key_type=0;

  char key_name[80];
  int i=0;

  set/format i1
  nflats = {{in_frm_co},NFLATS}

  */

  /*
    do it = 1 {nflats}
    o_frm = "{i_base_nm}_data0{it}.bdf"
    extract/ima {o_frm} = {c_frm} [<,<,@{it}:>,>,@{it}]
    if in_frm_id .eq. 1 then
    {o_frm},{h_ident} = "{dummy}"
    {o_frm},{h_ident} = "{parSlitFFident}" 
    else
    {o_frm},{h_ident} = "{dummy}" 
    {o_frm},{h_ident} = "{parFibFFident}" 
    endif
  */

  status = SCFOPN(name_inp, FLAMESDATATYPE, 0, F_IMA_TYPE, &dat_id);
 
  for(it=1;it<=nflats;it++) {
    sprintf(o_frm,"%s%2.2d%s",base_out,it,".fits");
    status = SCFOPN(o_frm, FLAMESDATATYPE, 0, F_IMA_TYPE, &out_id);
    ck0_nomsg(flames_reset_desc_set1(out_id,dat_id,it,in_frm_id));
    ck0_nomsg(flames_reset_desc_set0(out_id,dat_id,it,in_frm_id));
    ck0_nomsg(flames_reset_desc_set2(out_id,dat_id,it));
    ck0_nomsg(flames_reset_desc_set3(out_id,dat_id,it,in_frm_id));
    ck0_nomsg(flames_reset_desc_set4(out_id,dat_id,it,in_frm_id));
    ck0_nomsg(SCFCLO(out_id));
  }
  ck0_nomsg(SCFCLO(dat_id));
  for(it=1;it<=nflats;it++) {
    sprintf(o_frm,"%s%2.2d%s",base_out,it,".fits");
    strcpy(tag,FLAMES_SLIT_FF_DT(it,chip));
    ck0_nomsg(flames_reset_start_and_npix(o_frm,tag));
    strcpy(tag,FLAMES_SLIT_FF_DT(it,chip));
    ck0_nomsg(flames_reset_start_and_npix(o_frm,tag));
  }

 cleanup:


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


}


flames_err
flames_reset_desc_badpix(const char* name_inp,
                         const int nflats,
			 const char* base_out,
			 const int in_frm_id,
			 enum uves_chip chip)


{
  char o_frm[MIN_NAME_SIZE];
  int dat_id=0;
  int out_id=0;
  int it=0;
  int status=0;
  char tag[80];

  status = SCFOPN(name_inp, FLAMESDATATYPE, 0, F_IMA_TYPE, &dat_id);

  for(it=1;it<=nflats;it++) {
    sprintf(o_frm,"%s%2.2d%s",base_out,it,".fits");
    status = SCFOPN(o_frm, FLAMESDATATYPE, 0, F_IMA_TYPE, &out_id);
    ck0_nomsg(flames_reset_desc_set1(out_id,dat_id,it,in_frm_id));
    if(in_frm_id == 1) {
      ck0_nomsg(flames_reset_desc_set3(out_id,dat_id,it,in_frm_id));
    }
    ck0_nomsg(SCFCLO(out_id));
  }
  ck0_nomsg(SCFCLO(dat_id));

  for(it=1;it<=nflats;it++) {
    sprintf(o_frm,"%s%2.2d%s",base_out,it,".fits");
    strcpy(tag,FLAMES_SLIT_FF_BP(it,chip));
    ck0_nomsg(flames_reset_start_and_npix(o_frm,tag));
  }



  /*
    !BADPIXEL
    o_frm = "{i_base_nm}_badpixel01.bdf"
    c_frm = "{i_base_nm}_bpc.bdf"
    do it = 1 {nflats}
    o_frm = "{i_base_nm}_badpixel0{it}.bdf"
    extract/ima {o_frm} = {c_frm} [<,<,@{it}:>,>,@{it}]
    {o_frm},{h_ident} = "{{c_frm},{prefix}{it}.{h_ident}}"
    {o_frm},CUNIT     = {{c_frm},{prefix}{it}.CUNIT}

    {o_frm},LHCUTS(1) = m$value({c_frm},{prefix}{it}.LHCUTS(1))
    {o_frm},LHCUTS(2) = m$value({c_frm},{prefix}{it}.LHCUTS(2))
    {o_frm},LHCUTS(3) = m$value({c_frm},{prefix}{it}.LHCUTS(3))
    {o_frm},LHCUTS(4) = m$value({c_frm},{prefix}{it}.LHCUTS(4))

    {o_frm},REFPIX(1) = m$value({c_frm},{prefix}{it}.REFPIX(1))
    {o_frm},REFPIX(2) = m$value({c_frm},{prefix}{it}.REFPIX(2))

  

    !write/descr {o_frm} {h_filename}/c/1/80  "{{c_frm},{prefix}{it}.{h_filename}}"
    write/descr {o_frm} {h_origname}/c/1/80   "{{c_frm},{prefix}{it}.{h_origname}}"

    {o_frm},{d_sigmaframe}  = "{{c_frm},{prefix}{it}.{d_sigmaframe}}"
    {o_frm},{d_badpixframe} = "{{c_frm},{prefix}{it}.{d_badpixframe}}"

    {o_frm},{d_x1enc}       = m$value({c_frm},{prefix}{it}.{d_x1enc(5:)}) 
    {o_frm},{d_x2enc}       = m$value({c_frm},{prefix}{it}.{d_x2enc(5:)}) 
    if in_frm_id .eq. 1 then
    !{o_frm},FILENAME  = {{c_frm},{prefix}{it}.FILENAME}
    if m$existd(o_frm,d_yshift_rms) .gt. 0 then
    {o_frm},{d_yshift_rms}    = m$value({c_frm},{prefix}{it}.{d_yshift_rms})         
    {o_frm},{d_halfwidth_rms} = m$value({c_frm},{prefix}{it}.{d_halfwidth_rms})
    else
    {o_frm},{s_yshift_rms}    = m$value({c_frm},{prefix}{it}.{s_yshift_rms})         
    {o_frm},{s_halfwidth_rms} = m$value({c_frm},{prefix}{it}.{s_halfwidth_rms})
    endif
    {o_frm},{d_yshift}        = m$value({c_frm},{prefix}{it}.{d_yshift})

    {o_frm},{d_halfwidth}     = m$value({c_frm},{prefix}{it}.{d_halfwidth}) 
    endif
    enddo
  */


 cleanup:


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


}


flames_err
flames_reset_desc_sigma(const char* name_inp,
                        const int nflats,
			const char* base_out,
			const int in_frm_id,
			enum uves_chip chip)



{
  char o_frm[MIN_NAME_SIZE];
  int dat_id=0;
  int out_id=0;
  int it=0;
  int status=0;
  char tag[80];

  status = SCFOPN(name_inp, FLAMESDATATYPE, 0, F_IMA_TYPE, &dat_id);

  for(it=1;it<=nflats;it++) {
    sprintf(o_frm,"%s%2.2d%s",base_out,it,".fits");
    status = SCFOPN(o_frm, FLAMESDATATYPE, 0, F_IMA_TYPE, &out_id);
    ck0_nomsg(flames_reset_desc_set1(out_id,dat_id,it,in_frm_id));
    ck0_nomsg(flames_reset_desc_set3(out_id,dat_id,it,in_frm_id));
    ck0_nomsg(SCFCLO(out_id));
  }
  ck0_nomsg(SCFCLO(dat_id));


  for(it=1;it<=nflats;it++) {
    sprintf(o_frm,"%s%2.2d%s",base_out,it,".fits");
    strcpy(tag,FLAMES_SLIT_FF_SG(it,chip));
    ck0_nomsg(flames_reset_start_and_npix(o_frm,tag));
  }

  /*
    !SIGMA
    o_frm = "{i_base_nm}_sigma01.bdf"
    c_frm = "{i_base_nm}_sgc.bdf"
    do it = 1 {nflats}
    o_frm = "{i_base_nm}_sigma0{it}.bdf"
    extract/ima {o_frm} = {c_frm} [<,<,@{it}:>,>,@{it}]
    {o_frm},{h_ident} = "{{c_frm},{prefix}{it}.{h_ident}}"
    {o_frm},CUNIT     = "{{c_frm},{prefix}{it}.CUNIT}"
    
    {o_frm},LHCUTS(1) = m$value({c_frm},{prefix}{it}.LHCUTS(1))
    {o_frm},LHCUTS(2) = m$value({c_frm},{prefix}{it}.LHCUTS(2))
    {o_frm},LHCUTS(3) = m$value({c_frm},{prefix}{it}.LHCUTS(3))
    {o_frm},LHCUTS(4) = m$value({c_frm},{prefix}{it}.LHCUTS(4))

    {o_frm},REFPIX(1) = m$value({c_frm},{prefix}{it}.REFPIX(1))
    {o_frm},REFPIX(2) = m$value({c_frm},{prefix}{it}.REFPIX(2))

    !write/descr {o_frm} {h_filename}/c/1/80  {{c_frm},{prefix}{it}.{h_filename}}
    write/descr {o_frm} {h_origname}/c/1/80   {{c_frm},{prefix}{it}.{h_origname}}

    {o_frm},{d_sigmaframe}  = {c_frm},{prefix}{it}.{d_sigmaframe}}
    {o_frm},{d_badpixframe} = {c_frm},{prefix}{it}.{d_badpixframe}}

     
    {o_frm},{d_x1enc}       = m$value({c_frm},{prefix}{it}.{d_x1enc(5:)}) 
    {o_frm},{d_x2enc}       = m$value({c_frm},{prefix}{it}.{d_x2enc(5:)}) 
    if in_frm_id .eq. 1 then
    !{o_frm},FILENAME  = {{c_frm},{prefix}{it}.FILENAME}
    if m$existd(o_frm,d_yshift_rms) .gt. 0 then

    {o_frm},{d_yshift_rms}    = m$value({c_frm},{prefix}{it}.{d_yshift_rms})
    {o_frm},{d_halfwidth_rms} = m$value({c_frm},{prefix}{it}.{d_halfwidth_rms})
    else
    {o_frm},{s_yshift_rms}    = m$value({c_frm},{prefix}{it}.{s_yshift_rms})
    {o_frm},{s_halfwidth_rms} = m$value({c_frm},{prefix}{it}.{s_halfwidth_rms})
    endif
    {o_frm},{d_yshift}        = m$value({c_frm},{prefix}{it}.{d_yshift})
    {o_frm},{d_halfwidth}     = m$value({c_frm},{prefix}{it}.{d_halfwidth})
    endif
    enddo
  */

 cleanup:


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


}


flames_err
flames_reset_desc_bound(const char* name_inp,
                        const int nflats,
			const char* base_out,
			const int in_frm_id,
			enum uves_chip chip)

{

  char o_frm[MIN_NAME_SIZE];
  int dat_id=0;
  int out_id=0;
  int it=0;
  int status=0;
  char tag[80];
  status = SCFOPN(name_inp, FLAMESDATATYPE, 0, F_IMA_TYPE, &dat_id);

  for(it=1;it<=nflats;it++) {
    sprintf(o_frm,"%s%2.2d%s",base_out,it,".fits");
    status = SCFOPN(o_frm, FLAMESDATATYPE, 0, F_IMA_TYPE, &out_id);
    ck0_nomsg(flames_reset_desc_set1(out_id,dat_id,it,in_frm_id));
    ck0_nomsg(flames_reset_desc_set2(out_id,dat_id,it));
    ck0_nomsg(flames_reset_desc_set3(out_id,dat_id,it,in_frm_id));
    ck0_nomsg(SCFCLO(out_id));
  }
  ck0_nomsg(SCFCLO(dat_id));

  for(it=1;it<=nflats;it++) {
    sprintf(o_frm,"%s%2.2d%s",base_out,it,".fits");
    strcpy(tag,FLAMES_SLIT_FF_BN(it,chip));
    ck0_nomsg(flames_reset_start_and_npix(o_frm,tag));
  }

  /*
    if in_frm_id .eq. 1 then


    !BOUND
    c_frm = "{i_base_nm}_bnc.bdf"
    define/local jj/i/1/1 0
    define/local sz/i/1/1 0
    define/local pp_min/i/1/1 0
    define/local pp_max/i/1/1 0

    copy/dk {c_frm} NPIX  o_npix
    copy/dk {c_frm} START o_start
    copy/dk {c_frm} STEP  o_step
    sz = {o_npix(3)}/{nflats}
    do it = 1 {nflats}
    o_frm = "{i_base_nm}_bound0{it}.bdf"
    pp_min = ((it-1)*sz+1)
    pp_max = (it*sz)
    extract/ima {o_frm} = {c_frm} [<,<,@{pp_min}:>,>,@{pp_max}]
    {o_frm},{h_ident} = {{c_frm},{prefix}{it}.{h_ident}}
    {o_frm},CUNIT     = {{c_frm},{prefix}{it}.CUNIT}
    {o_frm},START(3)     = 0

    {o_frm},LHCUTS(1) = m$value({c_frm},{prefix}{it}.LHCUTS(1))
    {o_frm},LHCUTS(2) = m$value({c_frm},{prefix}{it}.LHCUTS(2))
    {o_frm},LHCUTS(3) = m$value({c_frm},{prefix}{it}.LHCUTS(3))
    {o_frm},LHCUTS(4) = m$value({c_frm},{prefix}{it}.LHCUTS(4))

    {o_frm},REFPIX(1) = m$value({c_frm},{prefix}{it}.REFPIX(1))
    {o_frm},REFPIX(2) = m$value({c_frm},{prefix}{it}.REFPIX(2))

    !write/descr {o_frm} {h_filename}/c/1/80  {{c_frm},{prefix}{it}.{h_filename}}
    write/descr {o_frm} {h_origname}/c/1/80   {{c_frm},{prefix}{it}.{h_origname}}

    {o_frm},{d_sigmaframe}  = {{c_frm},{prefix}{it}.{d_sigmaframe}}
    {o_frm},{d_badpixframe} = {{c_frm},{prefix}{it}.{d_badpixframe}}

    {o_frm},{d_sigmafile}   = {{c_frm},{prefix}{it}.{d_sigmafile}}
    {o_frm},{d_badpixfile}  = {{c_frm},{prefix}{it}.{d_badpixfile}}

 
    {o_frm},{d_x1enc}       = m$value({c_frm},{prefix}{it}.{d_x1enc(5:)}) 
    {o_frm},{d_x2enc}       = m$value({c_frm},{prefix}{it}.{d_x2enc(5:)}) 
    {o_frm},{d_yshift}      = m$value({c_frm},{prefix}{it}.{d_yshift})
    if in_frm_id .eq. 1 then
    !{o_frm},FILENAME  = {{c_frm},{prefix}{it}.FILENAME}
    if m$existd(o_frm,d_yshift_rms) .gt. 0 then

    {o_frm},{d_yshift_rms}    = m$value({c_frm},{prefix}{it}.{d_yshift_rms})
    {o_frm},{d_halfwidth_rms} = m$value({c_frm},{prefix}{it}.{d_halfwidth_rms})
    else
    {o_frm},{s_yshift_rms}    = m$value({c_frm},{prefix}{it}.{s_yshift_rms})
    {o_frm},{s_halfwidth_rms} = m$value({c_frm},{prefix}{it}.{s_halfwidth_rms})
    endif
    {o_frm},{d_halfwidth}     = m$value({c_frm},{prefix}{it}.{d_halfwidth}) 
    endif

    enddo

    endif
    set/format
  */

 cleanup:


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


}




flames_err
flames_add_desc_set0(const int out_id,
                     const int ref_id, 
                     const int it,
                     const int in_frm_id)

{


  int actvals=0;
  int unit=0;
  int null=0;
  const char* h_ident= "IDENT"; 
  //char ident[MED_NAME_SIZE]; 
  char des_name[MED_NAME_SIZE]; 

  const char* d_yshift="YSHIFT";
  const char* prefix="ESO SLC";
  double yshift=0;

  const char* d_n_fibres="NUMFIBRES";
  const char* d_fibres="FIBRES";
  int fibres[N_FIBRES_MAX];
  int n_fibres=0;

  const char* prefix2="ESO.SLC";

  const char* parSlitFFident="Normalised slit FF";
  const char* parFibFFident="Cleaned fibre FF";
  /* The following is valid only for DT: but isn't that the same as 
     copying what in SLCi.IDENT ? */

  /* FIXME: should this be written? */
  if(in_frm_id == 1) {
    sprintf(des_name,"%s%d.%s",prefix,it,parSlitFFident);
    if (SCDWRC(out_id,h_ident, 1,des_name, 1, 72, &unit)) {
      return flames_midas_error(MAREMMA);
    }
  } else {
    sprintf(des_name,"%s%d.%s",prefix,it,parFibFFident);
    if (SCDWRC(out_id,h_ident, 1,des_name, 1, 72, &unit)) {
      return flames_midas_error(MAREMMA);
    }
  }
  


  if (SCDRDD(ref_id,d_yshift,1,1,&actvals,&yshift,&unit,&null) != 0 ) {
    return flames_midas_error(MAREMMA);
  }
  sprintf(des_name,"%s%d %s",prefix,it,d_yshift);
  if (SCDWRD(out_id,des_name,&yshift, 1, 1, &unit)) {
    return flames_midas_error(MAREMMA);
  }

  if(in_frm_id == 2) {
    if (SCDRDI(ref_id,d_n_fibres,1,1,&actvals,&n_fibres,&unit,&null) != 0 ) {
      return flames_midas_error(MAREMMA);
    }
    sprintf(des_name,"%s%d %s",prefix,it,d_n_fibres);
    if (SCDWRI(out_id,des_name,&n_fibres, 1, 1, &unit)) {
      return flames_midas_error(MAREMMA);
    }
   
    if (SCDRDI(ref_id,d_fibres,1,N_FIBRES_MAX,&actvals,fibres,&unit,&null) 
	!= 0 ) {
      return flames_midas_error(MAREMMA);
    }
    sprintf(des_name,"%s%d.%s",prefix2,it,d_fibres);
    if (SCDWRI(out_id,des_name,fibres, 1, N_FIBRES_MAX, &unit)) {
      return flames_midas_error(MAREMMA);
    }

  }

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

}


static flames_err
flames_add_desc_set1(const int out_id,
		     const int ref_id, 
		     const int it,
		     const int in_frm_id)

{



  int actvals=0;
  int unit=0;
  int null=0;
  float lhcuts[4]={0,0,0,0};
  double refpix[2]={0,0};
  char cunit[3][16];
  char des_name[MIN_NAME_SIZE];
  //char type=' ';
  //char origname[MED_NAME_SIZE];
  char sigmaframe[MED_NAME_SIZE]; 
  char badpixframe[MED_NAME_SIZE]; 
  char ident[MED_NAME_SIZE]; 
  //char cunit[MED_NAME_SIZE]; 

  const char* prefix="ESO.SLC";

  //const char* h_ident= "IDENT"; 
  //const char* h_origname= "ORIGFILE"; 
  const char* d_sigmaframe= "SIGMAFRAME"; 
  const char* d_badpixframe="BADPXFRAME"; 
  //const char* parSlitFFident="Normalised slit FF";
  //const char* parFibFFident="Cleaned fibre FF";


  /* The following creates problems: we need to read OBJECT */
  /*
  sprintf(des_name,"%s%d%s",prefix,it,".IDENT");
  if(0 == SCDPRS(ref_id,des_name,&type,&actvals,&null) ) {
    uves_msg("it should not pass through here 1");
    if ((SCDRDC(ref_id,des_name,1,1,48,&actvals,ident,&unit,&null)!=0)) {
      return flames_midas_error(MAREMMA);
    }
    uves_msg("it should not pass through here 2");

    // FIXME here we have to modify OBJECT descriptor 
    if (SCDWRC(out_id,"IDENT",1,ident,1,actvals, &unit)) {
      return flames_midas_error(MAREMMA);
    }
    uves_msg("it should not pass through here 3");
  } else {
    if(in_frm_id == 1) {
    uves_msg("Add IDENT to slitff");

      if (SCDWRC(out_id,"IDENT",1,parSlitFFident,1,actvals, &unit)) {
	return flames_midas_error(MAREMMA);
      }
    uves_msg("Added IDENT to slitff");
    } else {
    uves_msg("Add IDENT to fibreff");
      if (SCDWRC(out_id,"IDENT",1,parFibFFident,1,actvals, &unit)) {
	return flames_midas_error(MAREMMA);
      }
    uves_msg("Added IDENT to fibreff");
    }
  }
  */

  if ((SCDRDC(ref_id,"OBJECT",1,1,48,&actvals,ident,&unit,&null)!=0)) {
    return flames_midas_error(MAREMMA);
  }
  sprintf(des_name,"%s%d%s",prefix,it,".IDENT");
  if (SCDWRC(out_id,des_name,1,ident,1,actvals, &unit)) {
    return flames_midas_error(MAREMMA);
  }

  //Fill CUNIT with dummy values
  memset(cunit[0], '\0', 48);
  strncpy(cunit[0], "                ", 16);
  strncpy(cunit[1], "PIXEL           ", 16);
  strncpy(cunit[2], "PIXEL           ", 16);

  sprintf(des_name,"%s%d%s",prefix,it,".CUNIT");
  if (SCDWRC(out_id,des_name,1,cunit[0],1,48, &unit)) {
    return flames_midas_error(MAREMMA);
  }

  //Fill LHCUTS with dummy values
  sprintf(des_name,"%s%d%s",prefix,it,".LHCUTS");
  if (SCDWRR(out_id,des_name, lhcuts, 1, 4, &unit)) {
    return flames_midas_error(MAREMMA);
  }


  //Fill LHCUTS with dummy values
  sprintf(des_name,"%s%d%s",prefix,it,".REFPIX");
  if (SCDWRD(out_id,des_name, refpix, 1, 2, &unit)) {
       return flames_midas_error(MAREMMA);
  }


  /*problems if input if from CPL
  if(0 == SCDPRS(ref_id,"CUNIT",&type,&actvals,&null) ) {
    if ((SCDRDC(ref_id,"CUNIT",1,1,48,&actvals,cunit,&unit,&null)!=0)) {
      return flames_midas_error(MAREMMA);
    }
    sprintf(des_name,"%s%d%s",prefix,it,".CUNIT");
    if (SCDWRC(out_id,des_name,1,cunit,1,48, &unit)) {
      return flames_midas_error(MAREMMA);
    }
  }

  if(0 == SCDPRS(ref_id,"LHCUTS",&type,&actvals,&null) ) {
    if (SCDRDR(ref_id,"LHCUTS",1,4,&actvals,lhcuts,&unit,&null) != 0 ) {
      return flames_midas_error(MAREMMA);
    }
    sprintf(des_name,"%s%d%s",prefix,it,".LHCUTS");
    if (SCDWRR(out_id,des_name, lhcuts, 1, 4, &unit)) {
      return flames_midas_error(MAREMMA);
    }
  }
  
  */

  /*
  sprintf(des_name,"%s%d%s",prefix,it,".REFPIX");
  uves_msg_warning("des_name=%s",des_name);
  if (SCDRDD(ref_id,des_name,1,2,&actvals,refpix,&unit,&null) != 0 ) {
    return flames_midas_error(MAREMMA);
  }

  
  //AMO: FIXME: this creates problems
  if (SCDWRD(out_id, "REFPIX", refpix, 1, 2, &unit)) {
       return flames_midas_error(MAREMMA);
  }
  */

  /* this fail
  if ((SCDRDC(ref_id,h_origname,1,1,48,&actvals,origname,&unit,&null)!=0)) {
    return flames_midas_error(MAREMMA);
  }
  sprintf(des_name,"%s%d.%s",prefix,it,h_origname);
  if (SCDWRC(out_id,des_name,1,origname, 1, 48, &unit)) {
    return flames_midas_error(MAREMMA);
  }
  */
  if ((SCDRDC(ref_id,d_sigmaframe,1,1,48,&actvals,sigmaframe,&unit,&null)!=0)) {
    return flames_midas_error(MAREMMA);
  }
  sprintf(des_name,"%s%d.%s",prefix,it,d_sigmaframe);
  if (SCDWRC(out_id,d_sigmaframe,1,sigmaframe, 1, 48, &unit)) {
    return flames_midas_error(MAREMMA);
  }

  if ((SCDRDC(ref_id,d_badpixframe,1,1,48,&actvals,badpixframe,&unit,&null)!=0)) {
    return flames_midas_error(MAREMMA);
  }
  sprintf(des_name,"%s%d.%s",prefix,it,d_badpixframe);
  if (SCDWRC(out_id,d_badpixframe,1,badpixframe, 1, 48, &unit)) {
    return flames_midas_error(MAREMMA);
  }

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

}



static flames_err
flames_add_desc_set2(const int out_id,
                       const int ref_id, 
                       const int it)

{


  int actvals=0;
  int unit=0;
  int null=0;

  char des_name[MIN_NAME_SIZE];
  const char* prefix="ESO.SLC";
  const char* d_sigmafile="SIGMAFILE";
  char sigmafile[MED_NAME_SIZE];
  char badpixfile[MED_NAME_SIZE];

  const char* d_badpixfile="BADPIXELFILE";


  if ((SCDRDC(ref_id,d_sigmafile,1,1,48,&actvals,sigmafile,&unit,&null)!=0)) {
    return flames_midas_error(MAREMMA);
  }
  sprintf(des_name,"%s%d.%s",prefix,it,d_sigmafile);
  if (SCDWRC(out_id,des_name,1,sigmafile, 1, 48, &unit)) {
    return flames_midas_error(MAREMMA);
  }

  if ((SCDRDC(ref_id,d_badpixfile,1,1,48,&actvals,badpixfile,&unit,&null)!=0)) {
    return flames_midas_error(MAREMMA);
  }
  sprintf(des_name,"%s%d.%s",prefix,it,d_badpixfile);
  if (SCDWRC(out_id,des_name,1,badpixfile, 1, 48, &unit)) {
    return flames_midas_error(MAREMMA);
  }

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



}


static flames_err
flames_add_desc_set3(const int out_id,
                       const int ref_id, 
                       const int it,
                       const int in_frm_id)

{




  int actvals=0;
  int unit=0;
  int null=0;
  char des_name[MIN_NAME_SIZE];
  const char* prefix="ESO SLC";

  const char* d_x1enc="ESO INS SLIT3 X1ENC";
  const char* d_x2enc="ESO INS SLIT3 X2ENC";

  const char* s_x1enc="INS SLIT3 X1ENC";
  const char* s_x2enc="INS SLIT3 X2ENC";

  const char* d_yshift="YSHIFT";
  const char* d_yshift_rms="ESO QC YSHIFT RMS";

  const char* d_halfwidth="HALFWIDTH";
  const char* d_halfwidth_rms="ESO QC HALFWIDTH RMS";

  int x1enc=0;
  int x2enc=0;

  const char* s_yshift_rms="ESO QC YSHIFT RMS";
  const char* s_halfwidth_rms="ESO QC HALFWIDTH RMS";
  char type=' ';


  double yshift=0;
  double halfwidth=0; 
  float f_halfwidth=0; 
  double yshift_rms=0;
  double halfwidth_rms=0;
 


 
  if (SCDRDI(ref_id,d_x1enc,1,1,&actvals,&x1enc,&unit,&null) != 0 ) {
    return flames_midas_error(MAREMMA);
  }
  sprintf(des_name,"%s%d %s",prefix,it,s_x1enc);
  if (SCDWRI(out_id,des_name,&x1enc, 1, 1, &unit)) {
    return flames_midas_error(MAREMMA);
  }


  if (SCDRDI(ref_id,d_x2enc,1,1,&actvals,&x2enc,&unit,&null) != 0 ) {
    return flames_midas_error(MAREMMA);
  }
  sprintf(des_name,"%s%d %s",prefix,it,s_x2enc);
  if (SCDWRI(out_id,des_name,&x2enc, 1, 1, &unit)) {
    return flames_midas_error(MAREMMA);
  }



  if (in_frm_id == 1) {

    if(0 == SCDPRS(ref_id,d_yshift_rms,&type,&actvals,&null) ) {
      if (SCDRDD(ref_id,d_yshift_rms,1,1,&actvals,&yshift_rms,&unit,&null) != 0 ) {
	return flames_midas_error(MAREMMA);
      }
      sprintf(des_name,"%s%d %s",prefix,it,d_yshift_rms);
      if (SCDWRD(out_id,des_name,&yshift_rms, 1, 1, &unit)) {
	return flames_midas_error(MAREMMA);
      }
 
      if (SCDRDD(ref_id,d_halfwidth_rms,1,1,&actvals,&halfwidth_rms,&unit,&null) 
	  != 0 ) {
	return flames_midas_error(MAREMMA);
      }
      sprintf(des_name,"%s%d %s",prefix,it,d_halfwidth_rms);
      if (SCDWRD(out_id,des_name,&halfwidth_rms, 1, 1, &unit)) {
	return flames_midas_error(MAREMMA);
      }

    } else {

      if (SCDRDD(ref_id,d_yshift_rms,1,1,&actvals,&yshift_rms,&unit,&null) != 0 ) {
	return flames_midas_error(MAREMMA);
      }
      sprintf(des_name,"%s%d %s",prefix,it,s_yshift_rms);
      if (SCDWRD(out_id,des_name,&yshift_rms, 1, 1, &unit)) {
	return flames_midas_error(MAREMMA);
      }
    
      if (SCDRDD(ref_id,s_halfwidth_rms,1,1,&actvals,&halfwidth_rms,&unit,&null) 
	  != 0 ) {
	return flames_midas_error(MAREMMA);
      }
      sprintf(des_name,"%s%d %s",prefix,it,s_halfwidth_rms);
      if (SCDWRD(out_id,des_name,&halfwidth_rms, 1, 1, &unit)) {
	return flames_midas_error(MAREMMA);
      }

    }


    if (SCDRDD(ref_id,d_yshift,1,1,&actvals,&yshift,&unit,&null) != 0 ) {
      return flames_midas_error(MAREMMA);
    }
    sprintf(des_name,"%s%d %s",prefix,it,d_yshift);
    if (SCDWRD(out_id,des_name,&yshift, 1, 1, &unit)) {
      return flames_midas_error(MAREMMA);
    }

    // AMO: Here one should check if descriptor exists and eventually write it.
       if (SCDRDR(ref_id,d_halfwidth,1,1,&actvals,&f_halfwidth,&unit,&null) != 0 ) {
      return flames_midas_error(MAREMMA);
      }
 
      halfwidth=f_halfwidth;
      sprintf(des_name,"%s%d %s",prefix,it,d_halfwidth);
      if (SCDWRD(out_id,des_name,&halfwidth, 1, 1, &unit)) {
      return flames_midas_error(MAREMMA);
      }

  }

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

}



static flames_err
flames_add_desc_set4(const int out_id,
                       const int ref_id, 
                       const int it,
                       const int in_frm_id)

{



  int actvals=0;
  int unit=0;
  int null=0;
  const char* prefix="ESO SLC";
  const char* prefix2="ESO.SLC";

  char des_name[MIN_NAME_SIZE];
  char boundaryfile[MED_NAME_SIZE];
  double halfwidth;
  float float_halfwidth;


  const char* d_halfwidth="HALFWIDTH";
  const char* d_boundaryfile="BOUNDARYFILE";

  if(in_frm_id ==1) {

    
    if ((SCDRDC(ref_id,d_boundaryfile,1,1,48,&actvals,boundaryfile,
		&unit,&null)!=0)) {
      return flames_midas_error(MAREMMA);
    }
    sprintf(des_name,"%s%d.%s",prefix2,it,d_boundaryfile);
    if (SCDWRC(out_id,des_name,1,boundaryfile, 1, 48, &unit)) {
      return flames_midas_error(MAREMMA);
    }
    

    if (SCDRDR(ref_id,d_halfwidth,1,1,&actvals,&float_halfwidth,&unit,&null) != 0 ) {
      return flames_midas_error(MAREMMA);
    }
    halfwidth=float_halfwidth;
    sprintf(des_name,"%s%d %s",prefix,it,d_halfwidth);
    if (SCDWRD(out_id,des_name,&halfwidth, 1, 1, &unit)) {
      return flames_midas_error(MAREMMA);
    }

  } 

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


}



flames_err
flames_add_desc_data(const char* base_ref,
                     const char* file_out,
                     const int nval,
                     const int in_frm_id)
{

  int i=0;
  int k=0;
  int status=0;
  int ref_id=0;
  int out_id=0;
  //int unit=0;
  char file_ref[MIN_NAME_SIZE];

   status = SCFOPN(file_out, FLAMESDATATYPE, 0, F_IMA_TYPE, &out_id);


  for(i=0;i<nval;i++) {
    k=i+1;
    sprintf(file_ref,"%s%2.2d%s",base_ref,k,".fits");
    uves_msg_debug("file_ref=%s",file_ref);
    status = SCFOPN(file_ref, FLAMESDATATYPE, 0, F_IMA_TYPE, &ref_id);
    check_nomsg(flames_add_desc_set1(out_id,ref_id, k,in_frm_id));
    check_nomsg(flames_add_desc_set0(out_id,ref_id, k,in_frm_id));
    check_nomsg(flames_add_desc_set2(out_id,ref_id, k));
    check_nomsg(flames_add_desc_set3(out_id,ref_id, k,in_frm_id));
    check_nomsg(flames_add_desc_set4(out_id,ref_id, k,in_frm_id));
    ck0_nomsg(SCFCLO(ref_id));

  }
  ck0_nomsg(SCFCLO(out_id));


/*
!DATA
nflats = {{in_frm_co},NFLATS}
  set/format i1
  i_dtf = "{i_base_nm}_data01.bdf"
  copy/dk {i_dtf} NPIX  o_npix
  copy/dk {i_dtf} START o_start
  copy/dk {i_dtf} STEP  o_step
  create/ima {o_frm} 3,{o_npix(1)},{o_npix(2)},{nflats} -
             {o_start(1)},{o_start(2)},1.0,{o_step(1)},{o_step(2)},1.0 

  copy/dd {i_dtf} *,3 {i_base_nm}_dtc.bdf
  do it = 1 {nflats}
     i_dtf = "{i_base_nm}_data0{it}.bdf"
     insert/ima {i_dtf} {o_frm} @1,@1,@{it}
  enddo
  do it = 1 {nflats}
     i_dtf = "{i_base_nm}_data0{it}.bdf"
     write/descr {o_frm} {prefix}{it}.{h_ident}/c/1/80 "{{i_dtf},{h_ident}}"  
     write/descr {o_frm} {prefix}{it}.CUNIT/c/1/80 "{{i_dtf},CUNIT}"

     write/descr {o_frm} {prefix}{it}.LHCUTS/r/1/4  0 all
     {o_frm},{prefix}{it}.LHCUTS(1) = m$value({i_dtf},LHCUTS(1))
     {o_frm},{prefix}{it}.LHCUTS(2) = m$value({i_dtf},LHCUTS(2))
     {o_frm},{prefix}{it}.LHCUTS(3) = m$value({i_dtf},LHCUTS(3))
     {o_frm},{prefix}{it}.LHCUTS(4) = m$value({i_dtf},LHCUTS(4))

     write/descr {o_frm} {prefix}{it}.REFPIX/d/1/2  0 all
     {o_frm},{prefix}{it}.REFPIX(1) = m$value({i_dtf},REFPIX(1))
     {o_frm},{prefix}{it}.REFPIX(2) = m$value({i_dtf},REFPIX(2))


  
     write/descr {o_frm} {prefix}{it}.{h_arcfile}/c/1/80 "{{i_dtf},{h_arcfile}}"  

     write/descr {o_frm} {prefix}{it}.{h_origname}/c/1/80  "{{i_dtf},{h_origname}}"

     write/descr {o_frm} {prefix}{it}.{d_sigmaframe}/c/1/80 "{{i_dtf},{d_sigmaframe}}"
     write/descr {o_frm} {prefix}{it}.{d_badpixframe}/c/1/80 "{{i_dtf},{d_badpixframe}}"

     write/descr {o_frm} {prefix}{it}.{d_sigmafile}/c/1/80  "{{i_dtf},{d_sigmafile}}"
     write/descr {o_frm} {prefix}{it}.{d_badpixfile}/c/1/80 "{{i_dtf},{d_badpixfile}}"

     write/descr {o_frm} {prefix}{it}.{d_yshift}/d/1/1 0
     {o_frm},{prefix}{it}.{d_yshift} = m$value({i_dtf},{d_yshift})
 
     write/descr {o_frm} {prefix}{it}.{d_x1enc(5:)}/i/1/1 0
     {o_frm},{prefix}{it}.{d_x1enc(5:)} = m$value({i_dtf},{d_x1enc}) 
     write/descr {o_frm} {prefix}{it}.{d_x2enc(5:)}/i/1/1 0
     {o_frm},{prefix}{it}.{d_x2enc(5:)} = m$value({i_dtf},{d_x2enc})

     if in_frm_id .eq. 1 then
        write/descr {o_frm} {prefix}{it}.{d_halfwidth}/d/1/1 0
        write/descr {o_frm} {prefix}{it}.{d_yshift_rms}/d/1/1 0
        write/descr {o_frm} {prefix}{it}.{d_halfwidth_rms}/d/1/1 0 
        write/descr {o_frm} {prefix}{it}.{d_boundaryfile}/c/1/80 -
            {{i_dtf},{d_boundaryfile}}

        {o_frm},{prefix}{it}.{d_halfwidth} = m$value({i_dtf},{d_halfwidth})

        if m$existd(i_dtf,d_yshift_rms) .gt. 0 then
           {o_frm},{prefix}{it}.{d_yshift_rms} = m$value({i_dtf},{d_yshift_rms})
           {o_frm},{prefix}{it}.{d_halfwidth_rms} = m$value({i_dtf},{d_halfwidth_rms})
        else
           {o_frm},{prefix}{it}.{d_yshift_rms} = m$value({i_dtf},{s_yshift_rms})
           {o_frm},{prefix}{it}.{d_halfwidth_rms} = m$value({i_dtf},{s_halfwidth_rms})
        endif
      else
        write/descr {o_frm} {prefix}{it}.{d_n_fibres}/i/1/1 0
        {o_frm},{prefix}{it}.{d_n_fibres} = m$value({i_dtf},{d_n_fibres})

        write/descr {o_frm} {prefix}{it}.{d_fibres}/i/1/{MAXFIBRES} 0 all
        copy/dd {i_dtf} {d_fibres} {o_frm} {prefix}{it}.{d_fibres}



      endif
  enddo
*/

 cleanup:
  if (cpl_error_get_code() != CPL_ERROR_NONE || status != 0) {
    return -1;
  } else {
    return 0;
  }

}



flames_err
flames_add_desc_bpmap(const char* base_ref,
                     const char* file_out,
		      const int nval,
                      const int in_frm_id)

{

  int status=0;
  int ref_id=0;
  int out_id=0;
  int i=0;
  int k=0;
  char file_ref[MIN_NAME_SIZE];

  status = SCFOPN(file_out, FLAMESDATATYPE, 0, F_IMA_TYPE, &out_id);


 for(i=0;i<nval;i++) {
    k=i+1;
    sprintf(file_ref,"%s%2.2d%s",base_ref,k,".fits");
    uves_msg_debug("file_ref=%s",file_ref);
    status = SCFOPN(file_ref, FLAMESDATATYPE, 0, F_IMA_TYPE, &ref_id);
    check_nomsg(flames_add_desc_set1(out_id,ref_id, k,in_frm_id));
    check_nomsg(flames_add_desc_set3(out_id,ref_id, k,in_frm_id));
    ck0_nomsg(SCFCLO(ref_id));


  }

  ck0_nomsg(SCFCLO(out_id));


  /*
    !BADPIXEL
    i_dtf = "{i_base_nm}_badpixel01.bdf"
    o_frm = "{i_base_nm}_bpc.bdf"
    copy/dk {i_dtf} NPIX  o_npix
    copy/dk {i_dtf} START o_start
    copy/dk {i_dtf} STEP  o_step
    create/ima {o_frm} 3,{o_npix(1)},{o_npix(2)},{nflats} -
    {o_start(1)},{o_start(2)},1.0,{o_step(1)},{o_step(2)},1.0 
    copy/dd {i_dtf} *,3 {o_frm}
    do it = 1 {nflats}
    i_dtf = "{i_base_nm}_badpixel0{it}.bdf"
    insert/ima {i_dtf} {o_frm} @1,@1,@{it}
    enddo
    do it = 1 {nflats}
    i_dtf = "{i_base_nm}_badpixel0{it}.bdf"
    write/descr {o_frm} {prefix}{it}.{h_ident}/c/1/80 "{{i_dtf},{h_ident}}"  
    write/descr {o_frm} {prefix}{it}.CUNIT/c/1/80 "{{i_dtf},CUNIT}"
    write/descr {o_frm} {prefix}{it}.LHCUTS/r/1/4  0 all
    {o_frm},{prefix}{it}.LHCUTS(1) = m$value({i_dtf},LHCUTS(1))
    {o_frm},{prefix}{it}.LHCUTS(2) = m$value({i_dtf},LHCUTS(2))
    {o_frm},{prefix}{it}.LHCUTS(3) = m$value({i_dtf},LHCUTS(3))
    {o_frm},{prefix}{it}.LHCUTS(4) = m$value({i_dtf},LHCUTS(4))

    write/descr {o_frm} {prefix}{it}.REFPIX/d/1/2  0 all
    {o_frm},{prefix}{it}.REFPIX(1) = m$value({i_dtf},REFPIX(1))
    {o_frm},{prefix}{it}.REFPIX(2) = m$value({i_dtf},REFPIX(2))

    write/descr {o_frm} {prefix}{it}.{h_arcfile}/c/1/80 "{{i_dtf},{h_arcfile}}"  

    write/descr {o_frm} {prefix}{it}.{h_origname}/c/1/80  "{{i_dtf},{h_origname}}"

    write/descr {o_frm} {prefix}{it}.{d_sigmaframe}/c/1/80 "{{i_dtf},{d_sigmaframe}}"
    write/descr {o_frm} {prefix}{it}.{d_badpixframe}/c/1/80 "{{i_dtf},{d_badpixframe}}"

    write/descr {o_frm} {prefix}{it}.{d_x1enc(5:)}/i/1/1 0
    {o_frm},{prefix}{it}.{d_x1enc(5:)} = m$value({i_dtf},{d_x1enc}) 
    write/descr {o_frm} {prefix}{it}.{d_x2enc(5:)}/i/1/1 0
    {o_frm},{prefix}{it}.{d_x2enc(5:)} = m$value({i_dtf},{d_x2enc})

    if in_frm_id .eq. 1 then
    write/descr {o_frm} {prefix}{it}.{d_yshift}/d/1/1 0
    write/descr {o_frm} {prefix}{it}.{d_halfwidth}/d/1/1 0
    write/descr {o_frm} {prefix}{it}.{d_yshift_rms}/d/1/1 0
    write/descr {o_frm} {prefix}{it}.{d_halfwidth_rms}/d/1/1 0 

    {o_frm},{prefix}{it}.{d_yshift} = m$value({i_dtf},{d_yshift})
    {o_frm},{prefix}{it}.{d_halfwidth} = m$value({i_dtf},{d_halfwidth})

    if m$existd(i_dtf,d_yshift_rms) .gt. 0 then
    {o_frm},{prefix}{it}.{d_yshift_rms} = m$value({i_dtf},{d_yshift_rms})
    {o_frm},{prefix}{it}.{d_halfwidth_rms} = m$value({i_dtf},{d_halfwidth_rms})
    else
    {o_frm},{prefix}{it}.{d_yshift_rms} = m$value({i_dtf},{s_yshift_rms})
    {o_frm},{prefix}{it}.{d_halfwidth_rms} = m$value({i_dtf},{s_halfwidth_rms})
    endif
    else
    !write/descr {o_frm} {prefix}{it}.FILENAME/c/1/80 "{{i_dtf},FILENAME}"
    !write/descr {o_frm} {prefix}{it}.{h_filename}/c/1/80  "{{i_dtf},{h_filename}}"
    endif
    enddo
  */


 cleanup:
  if (cpl_error_get_code() != CPL_ERROR_NONE || status != 0) {
    return -1;
  } else {
    return 0;
  }

}


flames_err
flames_add_desc_sigma(const char* base_ref,
                     const char* file_out,
		      const int nval,
                      const int in_frm_id)

{

  int status=0;
  int ref_id=0;
  int out_id=0;
  int i=0;
  int k=0;
  char file_ref[MIN_NAME_SIZE];

  status = SCFOPN(file_out, FLAMESDATATYPE, 0, F_IMA_TYPE, &out_id);

 for(i=0;i<nval;i++) {
    k=i+1;
    sprintf(file_ref,"%s%2.2d%s",base_ref,k,".fits");
    uves_msg_debug("file_ref=%s",file_ref);
    status = SCFOPN(file_ref, FLAMESDATATYPE, 0, F_IMA_TYPE, &ref_id);
    check_nomsg(flames_add_desc_set1(out_id,ref_id, k,in_frm_id));
    check_nomsg(flames_add_desc_set3(out_id,ref_id, k,in_frm_id));
    ck0_nomsg(SCFCLO(ref_id));

  }


  ck0_nomsg(SCFCLO(out_id));

  /*
    !SIGMA
    i_dtf = "{i_base_nm}_sigma01.bdf"
    o_frm = "{i_base_nm}_sgc.bdf"
    copy/dk {i_dtf} NPIX  o_npix
    copy/dk {i_dtf} START o_start
    copy/dk {i_dtf} STEP  o_step
    create/ima {o_frm} 3,{o_npix(1)},{o_npix(2)},{nflats} -
    {o_start(1)},{o_start(2)},1.0,{o_step(1)},{o_step(2)},1.0 
    copy/dd {i_dtf} *,3 {o_frm}
    do it = 1 {nflats}
    i_dtf = "{i_base_nm}_sigma0{it}.bdf"
    insert/ima {i_dtf} {o_frm} @1,@1,@{it}
    enddo
    do it = 1 {nflats}
    i_dtf = "{i_base_nm}_sigma0{it}.bdf"
    write/descr {o_frm} {prefix}{it}.{h_ident}/c/1/80 "{{i_dtf},{h_ident}}"  
    write/descr {o_frm} {prefix}{it}.CUNIT/c/1/80 "{{i_dtf},CUNIT}"
    write/descr {o_frm} {prefix}{it}.LHCUTS/r/1/4  0 all
    {o_frm},{prefix}{it}.LHCUTS(1) = m$value({i_dtf},LHCUTS(1))
    {o_frm},{prefix}{it}.LHCUTS(2) = m$value({i_dtf},LHCUTS(2))
    {o_frm},{prefix}{it}.LHCUTS(3) = m$value({i_dtf},LHCUTS(3))
    {o_frm},{prefix}{it}.LHCUTS(4) = m$value({i_dtf},LHCUTS(4))

    write/descr {o_frm} {prefix}{it}.REFPIX/d/1/2  0 all
    {o_frm},{prefix}{it}.REFPIX(1) = m$value({i_dtf},REFPIX(1))
    {o_frm},{prefix}{it}.REFPIX(2) = m$value({i_dtf},REFPIX(2))

    write/descr {o_frm} {prefix}{it}.{h_arcfile}/c/1/80 "{{i_dtf},{h_arcfile}}"  

    write/descr {o_frm} {prefix}{it}.{h_origname}/c/1/80  "{{i_dtf},{h_origname}}"

    write/descr {o_frm} {prefix}{it}.{d_sigmaframe}/c/1/80 "{{i_dtf},{d_sigmaframe}}"
    write/descr {o_frm} {prefix}{it}.{d_badpixframe}/c/1/80 "{{i_dtf},{d_badpixframe}}"

    write/descr {o_frm} {prefix}{it}.{d_x1enc(5:)}/i/1/1 0
    {o_frm},{prefix}{it}.{d_x1enc(5:)} = m$value({i_dtf},{d_x1enc}) 
    write/descr {o_frm} {prefix}{it}.{d_x2enc(5:)}/i/1/1 0
    {o_frm},{prefix}{it}.{d_x2enc(5:)} = m$value({i_dtf},{d_x2enc})

    if in_frm_id .eq. 1 then
    !   write/descr {o_frm} {prefix}{it}.WINDOW_FROM/i/1/2  {{i_dtf},WINDOW_FROM}
    !     write/descr {o_frm} {prefix}{it}.WINDOW_TO/i/1/2  {{i_dtf},WINDOW_TO}
    !     write/descr {o_frm} {prefix}{it}.DISPLAY_DATA/i/1/9  {{i_dtf},DISPLAY_DATA}
    write/descr {o_frm} {prefix}{it}.{d_yshift}/d/1/1 0
    write/descr {o_frm} {prefix}{it}.{d_halfwidth}/d/1/1 0
    write/descr {o_frm} {prefix}{it}.{d_yshift_rms}/d/1/1 0
    write/descr {o_frm} {prefix}{it}.{d_halfwidth_rms}/d/1/1 0 

    {o_frm},{prefix}{it}.{d_yshift} = m$value({i_dtf},{d_yshift})
    {o_frm},{prefix}{it}.{d_halfwidth} = m$value({i_dtf},{d_halfwidth})
    if m$existd(i_dtf,d_yshift_rms) .gt. 0 then
    {o_frm},{prefix}{it}.{d_yshift_rms} = m$value({i_dtf},{d_yshift_rms})
    {o_frm},{prefix}{it}.{d_halfwidth_rms} = m$value({i_dtf},{d_halfwidth_rms})
    else
    {o_frm},{prefix}{it}.{d_yshift_rms} = m$value({i_dtf},{s_yshift_rms})
    {o_frm},{prefix}{it}.{d_halfwidth_rms} = m$value({i_dtf},{s_halfwidth_rms})

    endif
    else
    !write/descr {o_frm} {prefix}{it}.FILENAME/c/1/80 "{{i_dtf},FILENAME}"
    !write/descr {o_frm} {prefix}{it}.{h_filename}/c/1/80  "{{i_dtf},{h_filename}}"
    endif
    enddo


  */

 cleanup:
  if (cpl_error_get_code() != CPL_ERROR_NONE || status != 0) {
    return -1;
  } else {
    return 0;
  }

}


flames_err
flames_add_desc_bound(const char* base_ref,
                     const char* file_out,
		      const int nval,
                      const int in_frm_id)

{

  int status=0;
  int ref_id=0;
  int out_id=0;
  int i=0;
  int k=0;
  char file_ref[MIN_NAME_SIZE];

  status = SCFOPN(file_out, FLAMESDATATYPE, 0, F_IMA_TYPE, &out_id);

 for(i=0;i<nval;i++) {
    k=i+1;
    sprintf(file_ref,"%s%2.2d%s",base_ref,k,".fits");
    uves_msg_debug("file_ref=%s",file_ref);
    status = SCFOPN(file_ref, FLAMESDATATYPE, 0, F_IMA_TYPE, &ref_id);
    check_nomsg(flames_add_desc_set1(out_id,ref_id, k,in_frm_id));
    check_nomsg(flames_add_desc_set2(out_id,ref_id, k));
    check_nomsg(flames_add_desc_set3(out_id,ref_id, k,in_frm_id));
    ck0_nomsg(SCFCLO(ref_id));
  }


  ck0_nomsg(SCFCLO(out_id));

  /*

  if in_frm_id .eq. 1 then


  !BOUND
  i_dtf = "{i_base_nm}_bound01.bdf"
  o_frm = "{i_base_nm}_bnc.bdf"
  copy/dk {i_dtf} NPIX  o_npix
  copy/dk {i_dtf} START o_start
  copy/dk {i_dtf} STEP  o_step
  define/local sz/i/1/1 0
  sz = {o_npix(3)}*{nflats}
  define/local jj/i/1/1 0
  define/local pp/i/1/1 0
  create/ima {o_frm} 3,{o_npix(1)},{o_npix(2)},{sz} -
  {o_start(1)},{o_start(2)},1.0,{o_step(1)},{o_step(2)},1.0 
  copy/dd {i_dtf} *,3 {o_frm}
  do it = 1 {nflats}
  i_dtf = "{i_base_nm}_bound0{it}.bdf"
  do jj = 1 {o_npix(3)}
  pp = (({it}-1)*{o_npix(3)}+{jj})
  w/o "it={it} jj={jj} pp={pp}"
  insert/ima {i_dtf}@{jj} {o_frm} @1,@1,@{pp}
  enddo
  enddo
  do it = 1 {nflats}
  i_dtf = "{i_base_nm}_bound0{it}.bdf"
  write/descr {o_frm} {prefix}{it}.{h_ident}/c/1/80 "{{i_dtf},{h_ident}}"  
  write/descr {o_frm} {prefix}{it}.CUNIT/c/1/80 "{{i_dtf},CUNIT}"
  write/descr {o_frm} {prefix}{it}.LHCUTS/r/1/4  0 all
  {o_frm},{prefix}{it}.LHCUTS(1) = m$value({i_dtf},LHCUTS(1))
  {o_frm},{prefix}{it}.LHCUTS(2) = m$value({i_dtf},LHCUTS(2))
  {o_frm},{prefix}{it}.LHCUTS(3) = m$value({i_dtf},LHCUTS(3))
  {o_frm},{prefix}{it}.LHCUTS(4) = m$value({i_dtf},LHCUTS(4))

  write/descr {o_frm} {prefix}{it}.REFPIX/d/1/2  0 all
  {o_frm},{prefix}{it}.REFPIX(1) = m$value({i_dtf},REFPIX(1))
  {o_frm},{prefix}{it}.REFPIX(2) = m$value({i_dtf},REFPIX(2))

  write/descr {o_frm} {prefix}{it}.{h_arcfile}/c/1/80 "{{i_dtf},{h_arcfile}}"  

  write/descr {o_frm} {prefix}{it}.{h_origname}/c/1/80  "{{i_dtf},{h_origname}}"

  write/descr {o_frm} {prefix}{it}.{d_sigmaframe}/c/1/80 "{{i_dtf},{d_sigmaframe}}"
  write/descr {o_frm} {prefix}{it}.{d_badpixframe}/c/1/80 "{{i_dtf},{d_badpixframe}}"

  write/descr {o_frm} {prefix}{it}.{d_sigmafile}/c/1/80 "{{i_dtf},{d_sigmafile}}"
  write/descr {o_frm} {prefix}{it}.{d_badpixfile}/c/1/80 "{{i_dtf},{d_badpixfile}}"

  write/descr {o_frm} {prefix}{it}.{d_x1enc(5:)}/i/1/1 0
  {o_frm},{prefix}{it}.{d_x1enc(5:)} = m$value({i_dtf},{d_x1enc}) 
  write/descr {o_frm} {prefix}{it}.{d_x2enc(5:)}/i/1/1 0
  {o_frm},{prefix}{it}.{d_x2enc(5:)} = m$value({i_dtf},{d_x2enc})

  write/descr {o_frm} {prefix}{it}.{d_yshift}/d/1/1 {{i_dtf},{d_yshift}}
  if in_frm_id .eq. 1 then
  write/descr {o_frm} {prefix}{it}.{d_yshift}/d/1/1 0
  write/descr {o_frm} {prefix}{it}.{d_halfwidth}/d/1/1 0
  write/descr {o_frm} {prefix}{it}.{d_yshift_rms}/d/1/1 0
  write/descr {o_frm} {prefix}{it}.{d_halfwidth_rms}/d/1/1 0 

  {o_frm},{prefix}{it}.{d_yshift} = m$value({i_dtf},{d_yshift})
  {o_frm},{prefix}{it}.{d_halfwidth} = m$value({i_dtf},{d_halfwidth})
  if m$existd(i_dtf,d_yshift_rms) .gt. 0 then
  {o_frm},{prefix}{it}.{d_yshift_rms} = m$value({i_dtf},{d_yshift_rms})
  {o_frm},{prefix}{it}.{d_halfwidth_rms} = m$value({i_dtf},{d_halfwidth_rms})
  else
  {o_frm},{prefix}{it}.{d_yshift_rms} = m$value({i_dtf},{s_yshift_rms})
  {o_frm},{prefix}{it}.{d_halfwidth_rms} = m$value({i_dtf},{s_halfwidth_rms})

  endif
  else
  write/descr {o_frm} {prefix}{it}.FILENAME/c/1/80 "{{i_dtf},FILENAME}"
  write/descr {o_frm} {prefix}{it}.{h_filename}/c/1/80  "{{i_dtf},{h_filename}}"
  endif
  enddo
  endif
  set/format
  RETURN

  */

 cleanup:
  if (cpl_error_get_code() != CPL_ERROR_NONE || status != 0) {
    return -1;
  } else {
    return 0;
  }

}




/*---------------------------------------------------------------------------*/
/**
   @brief procedure to group spectra into an image 
   @param  inp_basename  input file basename
   @param  out_filename  output file name
   @param  out_filename_qual        output file qualifier
   @param  min           minimum file index
   @param  max           maximum file index
   @return   0 if everything is ok

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

int
flames_spectra_to_image(
			const char* inp_basename,
			const char* inp_filename_qual,
			const char* out_filename,
			const int min,
			const int max,
                        const cpl_table* xtab,
                        const int pno)
{


  cpl_frame* frm=NULL;
  uves_propertylist* h=NULL;
  uves_propertylist* hx=NULL;

  cpl_image* inp=NULL;
  cpl_vector* vec=NULL;
  cpl_image* out=NULL;

  char filename[80];
  char* kname=NULL;
  char* kcomm=NULL;
  double kdval=0;
 
  int kival=0;
  const char* ksval=NULL;
  char* kcol=NULL;

  float* pinp=NULL;  
  float* pout=NULL;
  int xsz=0;
  int i=0;
  int j=0;
  int k=0;
  int ysz=max-min+1;
  int status=0;


  sprintf(filename,"%s%4.4d%s%s",inp_basename,min,inp_filename_qual,".fits");

  check_nomsg(vec=cpl_vector_load(filename,0));
  check_nomsg(inp=uves_vector_to_image(vec,CPL_TYPE_FLOAT));
  uves_free_vector(&vec);


  check_nomsg(xsz=cpl_image_get_size_x(inp));
  uves_free_image(&inp);
  check_nomsg(out=cpl_image_new(xsz,ysz,CPL_TYPE_FLOAT));
  check_nomsg(pout=cpl_image_get_data_float(out));


  for(j=0;j<ysz;j++) {
    k=min+j;
    sprintf(filename,"%s%4.4d%s",inp_basename,k,".fits");
    uves_msg_debug("loading %s",filename);
    check_nomsg(h=uves_propertylist_load(filename,0));
    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(inp=uves_load_image(frm,0,0,&h));
    check_nomsg(pinp=cpl_image_get_data_float(inp));

    for(i=0;i<xsz;i++) {
      pout[j*xsz+i]=pinp[i];
    }

    uves_free_image(&inp);
    uves_free_propertylist(&h);
    uves_free_frame(&frm);

  }
 


  check_nomsg(hx=uves_propertylist_new());
  check_nomsg(uves_propertylist_append_c_int(hx,"ESO INF FIBSTART",min,
					     "comment"));
  check_nomsg(uves_propertylist_append_c_int(hx,"ESO INF FIBEND",max,
					     "comment"));



  for(j=min;j<max;j++) {

    //FIBREPOS
    kname=uves_sprintf("%s%d%s","ESO INF F",j," FIBREPOS");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","FIBREPOS");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //FIBREMASK
    kname=uves_sprintf("%s%d%s","ESO INF F",j," FIBREMASK");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","FIBREMASK");
    check_nomsg( kival=cpl_table_get_int(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_int(hx,kname,kival,kcomm));

    //FIBREORD
    kname=uves_sprintf("%s%d%s","ESO INF F",j," FIBREORD");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","FIBREORD");
    check_nomsg(kival=cpl_table_get_int(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_int(hx,kname,kival,kcomm));

    //OBJECT
    kname=uves_sprintf("%s%d%s","ESO INF F",j," OBJECT");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","OBJECT");
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //RA
    kname=uves_sprintf("%s%d%s","ESO INF F",j," RA");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","RA");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //DEC
    kname=uves_sprintf("%s%d%s","ESO INF F",j," DEC");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","DEC");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));


    //R
    kname=uves_sprintf("%s%d%s","ESO INF F",j," R");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","R");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //R_ERROR
    kname=uves_sprintf("%s%d%s","ESO INF F",j," R_ERROR");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","R_ERROR");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //THETA
    kname=uves_sprintf("%s%d%s","ESO INF F",j," THETA");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","THETA");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //THETA_ERROR
    kname=uves_sprintf("%s%d%s","ESO INF F",j," THETA_ERROR");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","THETA_ERROR");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //TYPE
    kname=uves_sprintf("%s%d%s","ESO INF F",j," TYPE");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","TYPE");
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //BUTTON
    kname=uves_sprintf("%s%d%s","ESO INF F",j," BUTTON");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","BUTTON");
    check_nomsg(kival=cpl_table_get_int(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_int(hx,kname,kival,kcomm));
   
    //PRIORITY
    kname=uves_sprintf("%s%d%s","ESO INF F",j," PRIORITY");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","PRIORITY");
    check_nomsg(kival=cpl_table_get_int(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_int(hx,kname,kival,kcomm));

    //ORIENT
    kname=uves_sprintf("%s%d%s","ESO INF F",j," ORIENT");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","ORIENT");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //IN_TOL
    kname=uves_sprintf("%s%d%s","ESO INF F",j," IN_TOL");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s","IN_TOL");
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //SLIT
    kname=uves_sprintf("%s%d%s","ESO INF F",j," SLIT");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s%d","Slit_pt",pno);
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));
 
    //FPS
    kname=uves_sprintf("%s%d%s","ESO INF F",j," FPS");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s%d","FPS_pt",pno);
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //RETRACTOR
    kname=uves_sprintf("%s%d%s","ESO INF F",j," RETRACTOR");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s%d","Retractor_pt",pno);
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //BN
    kname=uves_sprintf("%s%d%s","ESO INF F",j," BN");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s%d","BN_pt",pno);
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //FBN
    kname=uves_sprintf("%s%d%s","ESO INF F",j," FBN");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s%d","FBN_pt",pno);
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //RP
    kname=uves_sprintf("%s%d%s","ESO INF F",j," RP");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s%d","RP_pt",pno);
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //E400
    kname=uves_sprintf("%s%d%s","ESO INF F",j," E400");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s%d","_400_pt",pno);
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //E420
    kname=uves_sprintf("%s%d%s","ESO INF F",j," E420");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s%d","_420_pt",pno);
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //E500
    kname=uves_sprintf("%s%d%s","ESO INF F",j," E500");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s%d","_500_pt",pno);
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //E700
    kname=uves_sprintf("%s%d%s","ESO INF F",j," E700");
    kcomm=uves_sprintf("%s","comment");
    kcol=uves_sprintf("%s%d","_700_pt",pno);
    check_nomsg(ksval=cpl_table_get_string(xtab,kcol,j));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

  }



  check_nomsg(h=uves_propertylist_load(filename,0));

  check_nomsg(uves_propertylist_append(h,hx)); 
  uves_save_image(out,out_filename,h,true, true);



 cleanup:
  uves_free_vector(&vec);
  uves_free_image(&out);
  uves_free_image(&inp);
  uves_free_propertylist(&h);
  uves_free_propertylist(&hx);
  uves_free_frame(&frm);

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

}


int
flames_spectra_to_image_check(
			const char* inp_basename,
			const char* inp_filename_qual,
			const char* out_filename,
			const int min,
			const int max,
                        const cpl_table* xtab,
                        const int pno)
{

  const int size=40;
  cpl_frame* frm=NULL;
  uves_propertylist* h=NULL;
  uves_propertylist* hx=NULL;

  cpl_image* inp=NULL;
  cpl_vector* vec=NULL;
  cpl_image* out=NULL;

  char filename[80];
  char kname[size];
  char kcomm[size];
  double kdval=0;
 
  int kival=0;
  char ksval[size];
  char kcol[size];

  float* pinp=NULL;  
  float* pout=NULL;
  int xsz=0;
  int i=0;
  int j=0;
  int k=0;
  int ysz=max-min+1;
  int status=0;
  const int* fibre_mask=NULL;
  fibre_mask=cpl_table_get_data_int_const(xtab,"FIBREMASK");
  sprintf(filename,"%s%4.4d%s%s",inp_basename,min,inp_filename_qual,".fits");

  check_nomsg(vec=cpl_vector_load(filename,0));
  check_nomsg(inp=uves_vector_to_image(vec,CPL_TYPE_FLOAT));
  uves_free_vector(&vec);


  check_nomsg(xsz=cpl_image_get_size_x(inp));
  uves_free_image(&inp);
  check_nomsg(out=cpl_image_new(xsz,ysz,CPL_TYPE_FLOAT));
  check_nomsg(pout=cpl_image_get_data_float(out));


  for(j=0;j<ysz;j++) {
    k=min+j;
    if(fibre_mask[k-1]) {
    sprintf(filename,"%s%4.4d%s",inp_basename,k,".fits");
    uves_msg_debug("loading %s",filename);
    check_nomsg(h=uves_propertylist_load(filename,0));
    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(inp=uves_load_image(frm,0,0,&h));
    check_nomsg(pinp=cpl_image_get_data_float(inp));

    for(i=0;i<xsz;i++) {
      pout[j*xsz+i]=pinp[i];
    }

    uves_free_image(&inp);
    uves_free_propertylist(&h);
    uves_free_frame(&frm);
    }
  }
 


  check_nomsg(hx=uves_propertylist_new());
  check_nomsg(uves_propertylist_append_c_int(hx,"ESO INF FIBSTART",min,
					     "comment"));
  check_nomsg(uves_propertylist_append_c_int(hx,"ESO INF FIBEND",max,
					     "comment"));



  for(j=min;j<=max;j++) {

    //FIBREPOS
    snprintf(kname,size,"%s%d%s","ESO INF F",j," FIBREPOS");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","FIBREPOS");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //FIBREMASK
    snprintf(kname,size,"%s%d%s","ESO INF F",j," FIBREMASK");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","FIBREMASK");
    check_nomsg( kival=cpl_table_get_int(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_int(hx,kname,kival,kcomm));

    //FIBREORD
    snprintf(kname,size,"%s%d%s","ESO INF F",j," FIBREORD");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","FIBREORD");
    check_nomsg(kival=cpl_table_get_int(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_int(hx,kname,kival,kcomm));

    //OBJECT
    snprintf(kname,size,"%s%d%s","ESO INF F",j," OBJECT");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","OBJECT");
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //RA
    snprintf(kname,size,"%s%d%s","ESO INF F",j," RA");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","RA");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //DEC
    snprintf(kname,size,"%s%d%s","ESO INF F",j," DEC");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","DEC");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));


    //R
    snprintf(kname,size,"%s%d%s","ESO INF F",j," R");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","R");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //R_ERROR
    snprintf(kname,size,"%s%d%s","ESO INF F",j," R_ERROR");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","R_ERROR");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //THETA
    snprintf(kname,size,"%s%d%s","ESO INF F",j," THETA");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","THETA");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //THETA_ERROR
    snprintf(kname,size,"%s%d%s","ESO INF F",j," THETA_ERROR");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","THETA_ERROR");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //TYPE
    snprintf(kname,size,"%s%d%s","ESO INF F",j," TYPE");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","TYPE");
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //BUTTON
    snprintf(kname,size,"%s%d%s","ESO INF F",j," BUTTON");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","BUTTON");
    check_nomsg(kival=cpl_table_get_int(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_int(hx,kname,kival,kcomm));
   
    //PRIORITY
    snprintf(kname,size,"%s%d%s","ESO INF F",j," PRIORITY");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","PRIORITY");
    check_nomsg(kival=cpl_table_get_int(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_int(hx,kname,kival,kcomm));

    //ORIENT
    snprintf(kname,size,"%s%d%s","ESO INF F",j," ORIENT");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","ORIENT");
    check_nomsg(kdval=cpl_table_get_double(xtab,kcol,j-1,&status));
    check_nomsg(uves_propertylist_append_c_double(hx,kname,kdval,kcomm));

    //IN_TOL
    snprintf(kname,size,"%s%d%s","ESO INF F",j," IN_TOL");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s","IN_TOL");
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //SLIT
    snprintf(kname,size,"%s%d%s","ESO INF F",j," SLIT");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s%d","Slit_pt",pno);
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));
 
    //FPS
    snprintf(kname,size,"%s%d%s","ESO INF F",j," FPS");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s%d","FPS_pt",pno);
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //RETRACTOR
    snprintf(kname,size,"%s%d%s","ESO INF F",j," RETRACTOR");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s%d","Retractor_pt",pno);
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //BN
    snprintf(kname,size,"%s%d%s","ESO INF F",j," BN");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s%d","BN_pt",pno);
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //FBN
    snprintf(kname,size,"%s%d%s","ESO INF F",j," FBN");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s%d","FBN_pt",pno);
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //RP
    snprintf(kname,size,"%s%d%s","ESO INF F",j," RP");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s%d","RP_pt",pno);
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //E400
    snprintf(kname,size,"%s%d%s","ESO INF F",j," E400");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s%d","_400_pt",pno);
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //E420
    snprintf(kname,size,"%s%d%s","ESO INF F",j," E420");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s%d","_420_pt",pno);
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //E500
    snprintf(kname,size,"%s%d%s","ESO INF F",j," E500");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s%d","_500_pt",pno);
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

    //E700
    snprintf(kname,size,"%s%d%s","ESO INF F",j," E700");
    snprintf(kcomm,size,"%s","comment");
    snprintf(kcol,size,"%s%d","_700_pt",pno);
    snprintf(ksval,size,"%s",cpl_table_get_string(xtab,kcol,j-1));
    check_nomsg(uves_propertylist_append_c_string(hx,kname,ksval,kcomm));

  }



  uves_free_propertylist(&h);
  check_nomsg(h=uves_propertylist_load(filename,0));

  check_nomsg(uves_propertylist_append(h,hx)); 
  uves_save_image(out,out_filename,h,true, true);



 cleanup:
  uves_free_vector(&vec);
  uves_free_image(&out);
  uves_free_image(&inp);
  uves_free_propertylist(&h);
  uves_free_propertylist(&hx);
  uves_free_frame(&frm);

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

}



/*---------------------------------------------------------------------------*/
/**
   @brief procedure to group image into a cube 
   @param  inp_basename      input file basename
   @param  out_filename      output file name
   @param  inp_format_digit  format of digit part of out file name
   @param  min               minimum file index
   @param  max               maximum file index
   @return   0 if everything is ok

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

int
flames_images_to_cube(
		      const char* inp_basename,
		      const char* out_filename,
		      const char* inp_format_digit,
		      const int min,
		      const int max)
{



  uves_propertylist* header=NULL;

  cpl_image* inp=NULL;
  cpl_imagelist* out=NULL;
  
  char filename[80];

  int zsz=max-min+1;
  int xsz=0;
  int ysz=0;
  int xsz_max=0;
  float* ptdata=NULL;
  float* pidata=NULL;
  cpl_image* tmp=NULL;
  int i=0;
  int j=0;
  int k=0;
  int kk=0;
  char format[MIN_NAME_SIZE];

  sprintf(format,"%s%s%s","%s",inp_format_digit,"%s");

  check_nomsg(out=cpl_imagelist_new());
  for(i=0;i<zsz;i++) {

    k=min+i;
    sprintf(filename,format,inp_basename,k,".fits");
    uves_msg_debug("filename=%s",filename);
    check_nomsg(inp=cpl_image_load(filename,CPL_TYPE_FLOAT,0,0));
    check_nomsg(xsz=cpl_image_get_size_x(inp));
    if(xsz> xsz_max) {
      xsz_max=xsz;
    }
    uves_free_image(&inp);

  }

  for(k=0;k<zsz;k++) {
    kk=min+k;
    sprintf(filename,format,inp_basename,kk,".fits");
    check_nomsg(inp=cpl_image_load(filename,CPL_TYPE_FLOAT,0,0));
    check_nomsg(xsz=cpl_image_get_size_x(inp));
    check_nomsg(ysz=cpl_image_get_size_y(inp));
    check_nomsg(tmp=cpl_image_new(xsz_max,ysz,CPL_TYPE_FLOAT));
    check_nomsg(ptdata=cpl_image_get_data_float(tmp));
    check_nomsg(pidata=cpl_image_get_data_float(inp));

    for(j=0;j<ysz;j++) {
      for(i=0;i<xsz;i++) {
	ptdata[j*xsz_max+i]=pidata[j*xsz+i];
      }
    }

    check_nomsg(cpl_imagelist_set(out,tmp,k));
    uves_free_image(&inp);
  }

  uves_msg("save file %s",out_filename);
  check_nomsg(header=uves_propertylist_load(filename,0));
  if(uves_propertylist_has(header,"PIPEFILE")==1) {
      uves_propertylist_set_string(header,"PIPEFILE",out_filename);
    } else {
      uves_propertylist_append_string(header,"PIPEFILE",out_filename);
  }
  uves_save_imagelist(out,out_filename,header);



 cleanup:
  uves_free_imagelist(&out);;
  uves_free_propertylist(&header);

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


}


/**
   @brief procedure to group image into a cube 
   @param  inp_basename      input file basename
   @param  out_filename      output file name
   @param  inp_format_digit  format of digit part of out file name
   @param  min               minimum file index
   @param  max               maximum file index
   @return   0 if everything is ok

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

int
flames_images_to_cube_check(
		      const char* inp_basename,
		      const char* out_filename,
		      const char* inp_format_digit,
		      int* fibre_mask_frm,
		      const int min, 
		      const int max)
{



  uves_propertylist* header=NULL;

  cpl_image* inp=NULL;
  cpl_imagelist* out=NULL;
  
  char filename[80];

  int zsz=max-min+1;
  int xsz=0;
  int ysz=0;
  int xsz_max=0;
  float* ptdata=NULL;
  float* pidata=NULL;
  cpl_image* tmp=NULL;
  int i=0;
  int j=0;
  int k=0;
  int kk=0;
  char format[MIN_NAME_SIZE];

  sprintf(format,"%s%s%s","%s",inp_format_digit,"%s");
  uves_msg("Found %d fibres to load",zsz);

  check_nomsg(out=cpl_imagelist_new());
  for(i=min;i<max;i++) {
    if(fibre_mask_frm[i-1]==1) {
      k=i;
      sprintf(filename,format,inp_basename,k,".fits");
      uves_msg_debug("filename=%s",filename);
      check_nomsg(inp=cpl_image_load(filename,CPL_TYPE_FLOAT,0,0));
      check_nomsg(xsz=cpl_image_get_size_x(inp));
      if(xsz> xsz_max) {
	xsz_max=xsz;
      }
      uves_free_image(&inp);
    }
  }

  kk=0;
  for(k=min;k<max;k++) {
    
    if(fibre_mask_frm[k-1]==1) {
      sprintf(filename,format,inp_basename,k,".fits");
      uves_msg("Found image %s to load",filename);
      check_nomsg(inp=cpl_image_load(filename,CPL_TYPE_FLOAT,0,0));
      check_nomsg(xsz=cpl_image_get_size_x(inp));
      check_nomsg(ysz=cpl_image_get_size_y(inp));
      check_nomsg(tmp=cpl_image_new(xsz_max,ysz,CPL_TYPE_FLOAT));
      check_nomsg(ptdata=cpl_image_get_data_float(tmp));
      check_nomsg(pidata=cpl_image_get_data_float(inp));

      for(j=0;j<ysz;j++) {
	for(i=0;i<xsz;i++) {
	  ptdata[j*xsz_max+i]=pidata[j*xsz+i];
	}
      }

      uves_msg("Insert frame %d",kk);
      check_nomsg(cpl_imagelist_set(out,tmp,kk));
      uves_free_image(&inp);
      kk++;
    }
  }

  uves_msg("save file %s",out_filename);
  uves_msg("load file %s",filename);
  check_nomsg(header=uves_propertylist_load(filename,0));
  if(uves_propertylist_has(header,"PIPEFILE")==1) {
      uves_propertylist_set_string(header,"PIPEFILE",out_filename);
    } else {
      uves_propertylist_append_string(header,"PIPEFILE",out_filename);
  }
  uves_save_imagelist(out,out_filename,header);



 cleanup:
  uves_free_imagelist(&out);;
  uves_free_propertylist(&header);

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


}

/*---------------------------------------------------------------------------*/
/**
   @brief procedure to group image into a cube 
   @param  inp_basename      input file basename
   @param  out_filename      output file name
   @param  inp_format_digit  format of digit part of out file name
   @param  min               minimum file index
   @param  max               maximum file index
   @return   0 if everything is ok

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

int
flames_cubes_to_supercube(
			  const char* inp_basename,
			  const char* out_filename,
			  const char* inp_format_digit,
			  const int min,
			  const int max)
{

  uves_propertylist* header=NULL;
  cpl_imagelist* out=NULL;
  char filename[80];
  int zsz=max-min+1;
  int isz=0;
  int osz=0;
  cpl_image* tmp=NULL;
  cpl_imagelist* iml=NULL;
  int i=0;
  int j=0;
  int k=0;

  char format[MIN_NAME_SIZE];

  sprintf(format,"%s%s%s","%s",inp_format_digit,"%s");
  //sprintf(filename,format,inp_basename,01,".fits");
  //check_nomsg(iml=cpl_imagelist_load(filename,CPL_TYPE_FLOAT,0));
 
  check_nomsg(out=cpl_imagelist_new());

  for(i=0;i<zsz;i++) {
    k=min+i;
    sprintf(filename,format,inp_basename,k,".fits");
    uves_msg_debug("filename=%s",filename);
    check_nomsg(iml=cpl_imagelist_load(filename,CPL_TYPE_FLOAT,0));
    check_nomsg(isz=cpl_imagelist_get_size(iml));

    for(j=0;j<isz;j++) {
      osz++;
      check_nomsg(tmp=cpl_imagelist_get(iml,j));
      uves_msg_debug("size: %" CPL_SIZE_FORMAT "x%" CPL_SIZE_FORMAT "",
	       cpl_image_get_size_x(tmp),
	       cpl_image_get_size_y(tmp));
      uves_msg_debug("pos=%d",i*isz+j);
      check_nomsg(cpl_imagelist_set(out,cpl_image_duplicate(tmp),i*isz+j));
    }
 
    uves_free_imagelist(&iml);
  }
 
  uves_msg("save file %s",out_filename); 
  check_nomsg(header=uves_propertylist_load(filename,0));
  check_nomsg(uves_propertylist_set_int(header,"NAXIS3",osz));
  uves_save_imagelist(out,out_filename,header);

 cleanup:
 
  uves_free_imagelist(&out);;

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


}

int
flames_my_cubify2(enum uves_chip chip,
		 const int frm_type,
		 cpl_frameset** set_out,
                      cpl_frameset *frames,
                      const uves_propertylist *raw_header,
                      const cpl_parameterlist *parameters,
                      const char *recipe_id,
                 const char *starttime)

{

  char file_com[MIN_NAME_SIZE];
  char file_nor[MIN_NAME_SIZE];
  char file_nsg[MIN_NAME_SIZE];
  char prefix[MIN_NAME_SIZE];

  int nflats=0;
  char file_out[MIN_NAME_SIZE];
  //char file_inp[MIN_NAME_SIZE];
  char ibase[MIN_NAME_SIZE];
  //char btag[MIN_NAME_SIZE];
  char ctag[MIN_NAME_SIZE];
  //int i=0;
  //int k=0;
  //cpl_frame* frm=NULL;
  cpl_image* img=NULL;
  cpl_imagelist* iml=NULL;
  uves_propertylist* plist=NULL;
  char ident[MIN_NAME_SIZE];
  int com_id=0;
  int status=0;
  int unit=0;
  int fibre_mask_length;
  int* fibre_mask=NULL;
  cpl_type fibre_mask_type;
  const char* inp_base_format="%2.2d";

  if(frm_type == 1) {
    sprintf(prefix,"%s%c","slitff_",uves_chip_tochar(chip));
    //We need to add IDENT to common and norm

    //get nflats
    sprintf(file_com,"%s%s",prefix,"_common.fits");
     check_nomsg(plist=uves_propertylist_load(file_com,0));
    check_nomsg(nflats=uves_flames_pfits_get_nflats(plist));


    sprintf(ident,"%s","Common data for slit FF");
    if(uves_propertylist_has(plist,"IDENT")==1) {
      uves_propertylist_set_string(plist,"IDENT",ident);
    } else {
      uves_propertylist_append_string(plist,"IDENT",ident);
    }
    if(uves_propertylist_has(plist,"OBJECT")==1) {
      uves_propertylist_set_string(plist,"OBJECT",ident);
    } else {
      uves_propertylist_append_string(plist,"OBJECT",ident);
    }
    check_nomsg(iml=cpl_imagelist_load(file_com,CPL_TYPE_FLOAT,0));
    check_nomsg(uves_save_imagelist(iml,file_com,plist));
    uves_free_propertylist(&plist);
    uves_free_imagelist(&iml);

    sprintf(file_nor,"%s%s",prefix,"_norm.fits");
    check_nomsg(plist=uves_propertylist_load(file_nor,0));
    sprintf(ident,"%s","Normalisation data for slit FF");
    if(uves_propertylist_has(plist,"IDENT")==1) {
      uves_propertylist_set_string(plist,"IDENT",ident);
    } else {
      uves_propertylist_append_string(plist,"IDENT",ident);
    }
    if(uves_propertylist_has(plist,"OBJECT")==1) {
      uves_propertylist_set_string(plist,"OBJECT",ident);
    } else {
      uves_propertylist_append_string(plist,"OBJECT",ident);
    }
    check_nomsg(img=cpl_image_load(file_nor,CPL_TYPE_FLOAT,0,0));
    check_nomsg(uves_save_image(img,file_nor,plist,true,true));
    uves_free_propertylist(&plist);
    uves_free_image(&img);

    //SLITFF DATA
    sprintf(ibase,"%s%s",prefix,"_data");
    sprintf(file_out,"%s%s",prefix,"_dtc.fits");
    strcpy(ctag,FLAMES_SLIT_FF_DTC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_data(ibase,file_out,nflats,1));
    //ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));

    check( flames_frameset_insert(frames,
                                  CPL_FRAME_GROUP_PRODUCT,
                                  CPL_FRAME_TYPE_IMAGE,
                                  CPL_FRAME_LEVEL_INTERMEDIATE,
                                  file_out,
                                  ctag,
                                  raw_header,
                                  parameters,
                                  recipe_id,
                                  PACKAGE "/" PACKAGE_VERSION,
                                  NULL, starttime, false, UVES_ALL_STATS),
           "Could not add frame %s (%s) to frameset",
           file_out, ctag);
                
    uves_msg("Frame %s (%s) added to frameset",file_out, ctag);




    //SLITFF SIGMA
    sprintf(ibase,"%s%s",prefix,"_sigma");
    sprintf(file_out,"%s%s",prefix,"_sgc.fits");
    strcpy(ctag,FLAMES_SLIT_FF_SGC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_sigma(ibase,file_out,nflats,1));
    //ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));


    check( flames_frameset_insert(frames,
                                  CPL_FRAME_GROUP_PRODUCT,
                                  CPL_FRAME_TYPE_IMAGE,
                                  CPL_FRAME_LEVEL_INTERMEDIATE,
                                  file_out,
                                  ctag,
                                  raw_header,
                                  parameters,
                                  recipe_id,
                                  PACKAGE "/" PACKAGE_VERSION,
                                  NULL, starttime, false, UVES_ALL_STATS),
           "Could not add frame %s (%s) to frameset",
           file_out, ctag);



    //SLITFF BADPIXEL
    sprintf(ibase,"%s%s",prefix,"_badpixel");
    sprintf(file_out,"%s%s",prefix,"_bpc.fits");
    strcpy(ctag,FLAMES_SLIT_FF_BPC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_bpmap(ibase,file_out,nflats,1));
    //ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));


    check( flames_frameset_insert(frames,
                                  CPL_FRAME_GROUP_PRODUCT,
                                  CPL_FRAME_TYPE_IMAGE,
                                  CPL_FRAME_LEVEL_INTERMEDIATE,
                                  file_out,
                                  ctag,
                                  raw_header,
                                  parameters,
                                  recipe_id,
                                  PACKAGE "/" PACKAGE_VERSION,
                                  NULL, starttime, false, UVES_ALL_STATS),
           "Could not add frame %s (%s) to frameset",
           file_out, ctag);



    //SLITFF BOUND
    sprintf(ibase,"%s%s",prefix,"_bound");
    sprintf(file_out,"%s%s",prefix,"_bnc.fits");
    strcpy(ctag,FLAMES_SLIT_FF_BNC(chip));

    ck0_nomsg(flames_cubes_to_supercube(ibase,file_out,inp_base_format,1,
					nflats));
    check_nomsg(flames_add_desc_bound(ibase,file_out,nflats,1));
    //ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));

    check( flames_frameset_insert(frames,
                                  CPL_FRAME_GROUP_PRODUCT,
                                  CPL_FRAME_TYPE_IMAGE,
                                  CPL_FRAME_LEVEL_INTERMEDIATE,
                                  file_out,
                                  ctag,
                                  raw_header,
                                  parameters,
                                  recipe_id,
                                  PACKAGE "/" PACKAGE_VERSION,
                                  NULL, starttime, false, UVES_ALL_STATS),
           "Could not add frame %s (%s) to frameset",
           file_out, ctag);




  } else {
    sprintf(ident,"%s","Common data for fibre FF");
    sprintf(prefix,"%s%c","fibreff_",uves_chip_tochar(chip));
    sprintf(file_com,"%s%s",prefix,"_common.fits");


    status = SCFOPN(file_com, FLAMESDATATYPE, 0, F_IMA_TYPE, &com_id);
    if (SCDWRC(com_id, "IDENT", 1,ident, 1,48, &unit)) {
      return flames_midas_fail();
    }
    if (SCDWRC(com_id, "OBJECT", 1,ident, 1,48, &unit)) {
      return flames_midas_fail();
    }
    ck0_nomsg(SCFCLO(com_id));


    sprintf(file_nor,"%s%s",prefix,"_norm.fits");
    check_nomsg(plist=uves_propertylist_load(file_nor,0));
    sprintf(ident,"%s","Normalisation data for fibre FF");



    if(uves_propertylist_has(plist,"IDENT")==1) {
      uves_propertylist_set_string(plist,"IDENT",ident);
    } else {
      uves_propertylist_append_string(plist,"IDENT",ident);
    }
    if(uves_propertylist_has(plist,"OBJECT")==1) {
      uves_propertylist_set_string(plist,"OBJECT",ident);
    } else {
      uves_propertylist_append_string(plist,"OBJECT",ident);
    }
    check_nomsg(iml=cpl_imagelist_load(file_nor,CPL_TYPE_FLOAT,0));
    check_nomsg(uves_save_imagelist(iml,file_nor,plist));
    uves_free_propertylist(&plist);
    uves_free_imagelist(&iml);


    sprintf(file_nsg,"%s%s",prefix,"_nsigma.fits");
    uves_msg("file_nsg=%s",file_nsg);
    check_nomsg(plist=uves_propertylist_load(file_nsg,0));
    sprintf(ident,"%s","Normalisation sigmas for fibre FF");
    if(uves_propertylist_has(plist,"IDENT")==1) {
      uves_propertylist_set_string(plist,"IDENT",ident);
    } else {
      uves_propertylist_append_string(plist,"IDENT",ident);
    }
    if(uves_propertylist_has(plist,"OBJECT")==1) {
      uves_propertylist_set_string(plist,"OBJECT",ident);
    } else {
      uves_propertylist_append_string(plist,"OBJECT",ident);
    }
    check_nomsg(iml=cpl_imagelist_load(file_nsg,CPL_TYPE_FLOAT,0));
    check_nomsg(uves_save_imagelist(iml,file_nsg,plist));
    uves_free_propertylist(&plist);
    uves_free_imagelist(&iml);

    //get nflats
    sprintf(file_com,"%s%s",prefix,"_common.fits");
    check_nomsg(plist=uves_propertylist_load(file_com,0));
    check_nomsg(nflats=uves_flames_pfits_get_nflats(plist));
    uves_free_propertylist(&plist);


    //FIBREFF DATA
    sprintf(ibase,"%s%s",prefix,"_data");
    sprintf(file_out,"%s%s",prefix,"_dtc.fits");
    strcpy(ctag,FLAMES_FIB_FF_DTC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_data(ibase,file_out,nflats,2));
    //ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));


    check( flames_frameset_insert(frames,
                                  CPL_FRAME_GROUP_PRODUCT,
                                  CPL_FRAME_TYPE_IMAGE,
                                  CPL_FRAME_LEVEL_INTERMEDIATE,
                                  file_out,
                                  ctag,
                                  raw_header,
                                  parameters,
                                  recipe_id,
                                  PACKAGE "/" PACKAGE_VERSION,
                                  NULL, starttime, false, UVES_ALL_STATS),
           "Could not add frame %s (%s) to frameset",
           file_out, ctag);




    //FIBREFF SIGMA
    sprintf(ibase,"%s%s",prefix,"_sigma");
    sprintf(file_out,"%s%s",prefix,"_sgc.fits");
    strcpy(ctag,FLAMES_FIB_FF_SGC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_sigma(ibase,file_out,nflats,2));
    //ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));



    check( flames_frameset_insert(frames,
                                  CPL_FRAME_GROUP_PRODUCT,
                                  CPL_FRAME_TYPE_IMAGE,
                                  CPL_FRAME_LEVEL_INTERMEDIATE,
                                  file_out,
                                  ctag,
                                  raw_header,
                                  parameters,
                                  recipe_id,
                                  PACKAGE "/" PACKAGE_VERSION,
                                  NULL, starttime, false, UVES_ALL_STATS),
           "Could not add frame %s (%s) to frameset",
           file_out, ctag);


    //FIBREFF BADPIXEL
    sprintf(ibase,"%s%s",prefix,"_badpixel");
    sprintf(file_out,"%s%s",prefix,"_bpc.fits");
    strcpy(ctag,FLAMES_FIB_FF_BPC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_bpmap(ibase,file_out,nflats,2));
    //ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));

    check( flames_frameset_insert(frames,
                                  CPL_FRAME_GROUP_PRODUCT,
                                  CPL_FRAME_TYPE_IMAGE,
                                  CPL_FRAME_LEVEL_INTERMEDIATE,
                                  file_out,
                                  ctag,
                                  raw_header,
                                  parameters,
                                  recipe_id,
                                  PACKAGE "/" PACKAGE_VERSION,
                                  NULL, starttime, false, UVES_ALL_STATS),
           "Could not add frame %s (%s) to frameset",
           file_out, ctag);



  }


 cleanup:

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


}




int
flames_my_cubify(enum uves_chip chip,
		 const int frm_type,
		 cpl_frameset** set_out)
{


  char file_com[MIN_NAME_SIZE];
  char file_nor[MIN_NAME_SIZE];
  char file_nsg[MIN_NAME_SIZE];
  char prefix[MIN_NAME_SIZE];

  int nflats=0;
  char file_out[MIN_NAME_SIZE];
  //char file_inp[MIN_NAME_SIZE];
  char ibase[MIN_NAME_SIZE];
  //char btag[MIN_NAME_SIZE];
  char ctag[MIN_NAME_SIZE];
  //int i=0;
  //int k=0;
  //cpl_frame* frm=NULL;
  cpl_image* img=NULL;
  cpl_imagelist* iml=NULL;
  uves_propertylist* plist=NULL;
  char ident[MIN_NAME_SIZE];
  int com_id=0;
  int status=0;
  int unit=0;

  const char* inp_base_format="%2.2d";

  if(frm_type == 1) {
    sprintf(prefix,"%s%c","slitff_",uves_chip_tochar(chip));
    //We need to add IDENT to common and norm

    //get nflats
    sprintf(file_com,"%s%s",prefix,"_common.fits");
     check_nomsg(plist=uves_propertylist_load(file_com,0));
    check_nomsg(nflats=uves_flames_pfits_get_nflats(plist));

    sprintf(ident,"%s","Common data for slit FF");
    if(uves_propertylist_has(plist,"IDENT")==1) {
      uves_propertylist_set_string(plist,"IDENT",ident);
    } else {
      uves_propertylist_append_string(plist,"IDENT",ident);
    }
    if(uves_propertylist_has(plist,"OBJECT")==1) {
      uves_propertylist_set_string(plist,"OBJECT",ident);
    } else {
      uves_propertylist_append_string(plist,"OBJECT",ident);
    }
    check_nomsg(iml=cpl_imagelist_load(file_com,CPL_TYPE_FLOAT,0));
    check_nomsg(uves_save_imagelist(iml,file_com,plist));
    uves_free_propertylist(&plist);

    sprintf(file_nor,"%s%s",prefix,"_norm.fits");
    check_nomsg(plist=uves_propertylist_load(file_nor,0));
    sprintf(ident,"%s","Normalisation data for slit FF");
    if(uves_propertylist_has(plist,"IDENT")==1) {
      uves_propertylist_set_string(plist,"IDENT",ident);
    } else {
      uves_propertylist_append_string(plist,"IDENT",ident);
    }
    if(uves_propertylist_has(plist,"OBJECT")==1) {
      uves_propertylist_set_string(plist,"OBJECT",ident);
    } else {
      uves_propertylist_append_string(plist,"OBJECT",ident);
    }
    check_nomsg(img=cpl_image_load(file_nor,CPL_TYPE_FLOAT,0,0));
    check_nomsg(uves_save_image(img,file_nor,plist,true,true));
    uves_free_propertylist(&plist);


    //SLITFF DATA
    sprintf(ibase,"%s%s",prefix,"_data");
    sprintf(file_out,"%s%s",prefix,"_dtc.fits");
    strcpy(ctag,FLAMES_SLIT_FF_DTC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_data(ibase,file_out,nflats,1));
    ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));


    //SLITFF SIGMA
    sprintf(ibase,"%s%s",prefix,"_sigma");
    sprintf(file_out,"%s%s",prefix,"_sgc.fits");
    strcpy(ctag,FLAMES_SLIT_FF_SGC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_sigma(ibase,file_out,nflats,1));
    ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));

    //SLITFF BADPIXEL
    sprintf(ibase,"%s%s",prefix,"_badpixel");
    sprintf(file_out,"%s%s",prefix,"_bpc.fits");
    strcpy(ctag,FLAMES_SLIT_FF_BPC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_bpmap(ibase,file_out,nflats,1));
    ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));


    //SLITFF BOUND
    sprintf(ibase,"%s%s",prefix,"_bound");
    sprintf(file_out,"%s%s",prefix,"_bnc.fits");
    strcpy(ctag,FLAMES_SLIT_FF_BNC(chip));

    ck0_nomsg(flames_cubes_to_supercube(ibase,file_out,inp_base_format,1,
					nflats));
    check_nomsg(flames_add_desc_bound(ibase,file_out,nflats,1));
    ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));

  } else {
    sprintf(ident,"%s","Common data for fibre FF");
    sprintf(prefix,"%s%c","fibreff_",uves_chip_tochar(chip));
    sprintf(file_com,"%s%s",prefix,"_common.fits");


    status = SCFOPN(file_com, FLAMESDATATYPE, 0, F_IMA_TYPE, &com_id);
    if (SCDWRC(com_id, "IDENT", 1,ident, 1,48, &unit)) {
      return flames_midas_fail();
    }
    if (SCDWRC(com_id, "OBJECT", 1,ident, 1,48, &unit)) {
      return flames_midas_fail();
    }
    ck0_nomsg(SCFCLO(com_id));


    sprintf(file_nor,"%s%s",prefix,"_norm.fits");
    check_nomsg(plist=uves_propertylist_load(file_nor,0));
    sprintf(ident,"%s","Normalisation data for fibre FF");
    if(uves_propertylist_has(plist,"IDENT")==1) {
      uves_propertylist_set_string(plist,"IDENT",ident);
    } else {
      uves_propertylist_append_string(plist,"IDENT",ident);
    }
    if(uves_propertylist_has(plist,"OBJECT")==1) {
      uves_propertylist_set_string(plist,"OBJECT",ident);
    } else {
      uves_propertylist_append_string(plist,"OBJECT",ident);
    }
    check_nomsg(iml=cpl_imagelist_load(file_nor,CPL_TYPE_FLOAT,0));
    check_nomsg(uves_save_imagelist(iml,file_nor,plist));
    uves_free_propertylist(&plist);



    sprintf(file_nsg,"%s%s",prefix,"_nsigma.fits");
    uves_msg("file_nsg=%s",file_nsg);
    check_nomsg(plist=uves_propertylist_load(file_nsg,0));
    sprintf(ident,"%s","Normalisation sigmas for fibre FF");
    if(uves_propertylist_has(plist,"IDENT")==1) {
      uves_propertylist_set_string(plist,"IDENT",ident);
    } else {
      uves_propertylist_append_string(plist,"IDENT",ident);
    }
    if(uves_propertylist_has(plist,"OBJECT")==1) {
      uves_propertylist_set_string(plist,"OBJECT",ident);
    } else {
      uves_propertylist_append_string(plist,"OBJECT",ident);
    }
    check_nomsg(iml=cpl_imagelist_load(file_nsg,CPL_TYPE_FLOAT,0));
    check_nomsg(uves_save_imagelist(iml,file_nsg,plist));
    uves_free_propertylist(&plist);

    //get nflats
    sprintf(file_com,"%s%s",prefix,"_common.fits");
    check_nomsg(plist=uves_propertylist_load(file_com,0));
    check_nomsg(nflats=uves_flames_pfits_get_nflats(plist));
    uves_free_propertylist(&plist);


    //FIBREFF DATA
    sprintf(ibase,"%s%s",prefix,"_data");
    sprintf(file_out,"%s%s",prefix,"_dtc.fits");
    strcpy(ctag,FLAMES_FIB_FF_DTC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_data(ibase,file_out,nflats,2));
    ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));


    //FIBREFF SIGMA
    sprintf(ibase,"%s%s",prefix,"_sigma");
    sprintf(file_out,"%s%s",prefix,"_sgc.fits");
    strcpy(ctag,FLAMES_FIB_FF_SGC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_sigma(ibase,file_out,nflats,2));
    ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));

    //FIBREFF BADPIXEL
    sprintf(ibase,"%s%s",prefix,"_badpixel");
    sprintf(file_out,"%s%s",prefix,"_bpc.fits");
    strcpy(ctag,FLAMES_FIB_FF_BPC(chip));

    ck0_nomsg(flames_images_to_cube(ibase,file_out,inp_base_format,1,nflats));
    check_nomsg(flames_add_desc_bpmap(ibase,file_out,nflats,2));
    ck0_nomsg(flames_utils_frameset_insert(set_out,ctag,file_out));

  }


 cleanup:

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

}

static int    
flames_utils_frameset_insert(cpl_frameset** set_out,
                       const char* tag,
                       const char* filename)
{

  cpl_frame* frm=NULL;
  uves_propertylist* plist=NULL;
  int naxis=0;
  cpl_image* img=NULL;
  cpl_imagelist* iml=NULL;
  const char* pctg="ESO PRO CATG";

  check_nomsg(plist=uves_propertylist_load(filename,0));
  check_nomsg(naxis=uves_pfits_get_naxis(plist));

  switch (naxis) {

  case 1:
  case 2:
    if(uves_propertylist_has(plist,pctg)==1) {
      uves_propertylist_set_string(plist,pctg,tag);
    } else {
      uves_propertylist_append_string(plist,pctg,tag);
    }
    check_nomsg(img=cpl_image_load(filename,CPL_TYPE_FLOAT,0,0));
    check_nomsg(uves_save_image(img,filename,plist,true,true));
    break;    
    
  case 3:
    if(uves_propertylist_has(plist,pctg)==1) {
      uves_propertylist_set_string(plist,pctg,tag);
    } else {
      uves_propertylist_append_string(plist,pctg,tag);
    }
    check_nomsg(iml=cpl_imagelist_load(filename,CPL_TYPE_FLOAT,0));
    check_nomsg(uves_save_imagelist(iml,filename,plist));
    break;

  default: uves_msg_warning("PRO.CATG of file %s may be wrong",filename);

  }
  uves_free_propertylist(&plist);

  check_nomsg(frm=cpl_frame_new());
  check_nomsg(cpl_frame_set_tag(frm,tag));
  check_nomsg(cpl_frame_set_filename(frm,filename));
  check_nomsg(cpl_frame_set_group(frm,CPL_FRAME_GROUP_PRODUCT));
  check_nomsg(cpl_frame_set_level(frm,CPL_FRAME_LEVEL_INTERMEDIATE));
  cpl_frameset_insert(*set_out,frm);


 cleanup:

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

}

int
flames_my_decubify(cpl_frameset* set,
                   enum uves_chip chip,
		   const int frm_type,
                   cpl_frameset** set_out)
{

  cpl_image* img=NULL;

  char file_com[80];
  char base_out[80];
  char cname[80];
  char ibase[80];

  char tag[80];
  char prefix[80];


  int nflats=0;
  uves_propertylist* plist=NULL;
  uves_propertylist* head_out=NULL;
  cpl_frame* frame=NULL;






  if(frm_type == 1) {
    sprintf(prefix,"%s%c","slitff_",uves_chip_tochar(chip));
  } else {
    sprintf(prefix,"%s%c","fibreff_",uves_chip_tochar(chip));
  }
  //get nflats
  sprintf(file_com,"%s%s",prefix,"_common.fits");
  sprintf(base_out,"%s%s",prefix,"_data");
  check_nomsg(plist=uves_propertylist_load(file_com,0));
  check_nomsg(nflats=uves_flames_pfits_get_nflats(plist));
  uves_free_propertylist(&plist);


  if(frm_type == 1) {

    //Extract images from cube
    strcpy(tag,FLAMES_SLIT_FF_DTC(chip));
    sprintf(cname,"%s%s",prefix,"_dtc.fits");
    sprintf(ibase,"%s%s",prefix,"_data");
  
    ck0_nomsg(flames_extract_ima_from_cube(set,tag,chip,cname,set_out));
    check_nomsg(flames_reset_desc_data(cname,nflats,ibase,frm_type,chip));


     //Extract images from cube
    strcpy(tag,FLAMES_SLIT_FF_BPC(chip));
    sprintf(cname,"%s%s",prefix,"_bpc.fits");
    sprintf(ibase,"%s%s",prefix,"_badpixel");

    ck0_nomsg(flames_extract_ima_from_cube(set,tag,chip,cname,set_out));
    check_nomsg(flames_reset_desc_badpix(cname,nflats,ibase,frm_type,chip));


    //Extract images from cube
    strcpy(tag,FLAMES_SLIT_FF_SGC(chip));
    sprintf(cname,"%s%s",prefix,"_sgc.fits");
    sprintf(ibase,"%s%s",prefix,"_sigma");

    ck0_nomsg(flames_extract_ima_from_cube(set,tag,chip,cname,set_out));
    check_nomsg(flames_reset_desc_sigma(cname,nflats,ibase,frm_type,chip));

    //Extract images from cube
    strcpy(tag,FLAMES_SLIT_FF_BNC(chip));
    sprintf(cname,"%s%s",prefix,"_bnc.fits");
    sprintf(ibase,"%s%s",prefix,"_bound");

    ck0_nomsg(flames_extract_cube_from_cube(set,tag,chip,nflats,cname,set_out));
    check_nomsg(flames_reset_desc_bound(cname,nflats,ibase,frm_type,chip));
  

  } else {

    //Extract images from cube
    strcpy(tag,FLAMES_FIB_FF_DTC(chip));
    sprintf(cname,"%s%s",prefix,"_dtc.fits");
    sprintf(ibase,"%s%s",prefix,"_data");
    ck0_nomsg(flames_extract_ima_from_cube(set,tag,chip,cname,set_out));
    check_nomsg(flames_reset_desc_data(cname,nflats,ibase,frm_type,chip));

    //Extract images from cube
    strcpy(tag,FLAMES_FIB_FF_BPC(chip));
    sprintf(cname,"%s%s",prefix,"_bpc.fits");
    sprintf(ibase,"%s%s",prefix,"_badpixel");
    ck0_nomsg(flames_extract_ima_from_cube(set,tag,chip,cname,set_out));
    check_nomsg(flames_reset_desc_badpix(cname,nflats,ibase,frm_type,chip));
 
  
    //Extract images from cube
    strcpy(tag,FLAMES_FIB_FF_SGC(chip));
    sprintf(cname,"%s%s",prefix,"_sgc.fits");
    sprintf(ibase,"%s%s",prefix,"_sigma");
    ck0_nomsg(flames_extract_ima_from_cube(set,tag,chip,cname,set_out));
    check_nomsg(flames_reset_desc_sigma(cname,nflats,ibase,frm_type,chip));


  }

 cleanup:
  uves_free_image(&img);
  uves_free_propertylist(&head_out);
  uves_free_frame(&frame);

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

}

static const char*
flames_get_file_name_slice(const char* ctag,enum uves_chip chip,const int i)
{

  char prefix[MIN_NAME_SIZE];
  if(strstr(ctag,"FIB") != NULL) {
    sprintf(prefix,"%s%c","fibreff_",uves_chip_tochar(chip));
    //FIBFF
    if(strstr(ctag,"DT") != NULL) {
      return cpl_sprintf("%s%s%2.2d%s",prefix,"_data",i,".fits");
    } else if(strstr(ctag,"SG") != NULL) {
      return cpl_sprintf("%s%s%2.2d%s",prefix,"_sigma",i,".fits");
      } else if(strstr(ctag,"BP") != NULL) {
      return cpl_sprintf("%s%s%2.2d%s",prefix,"_badpixel",i,".fits");
    } else {
      uves_msg_error("tag %s not supported",ctag);
      return NULL;
    }
  } else {
    sprintf(prefix,"%s%c","slitff_",uves_chip_tochar(chip));
    //SLITFF
    if(strstr(ctag,"DT") != NULL) {
      return cpl_sprintf("%s%s%2.2d%s",prefix,"_data",i,".fits");
    } else if(strstr(ctag,"SG") != NULL) {
      return cpl_sprintf("%s%s%2.2d%s",prefix,"_sigma",i,".fits");
    } else if(strstr(ctag,"BP") != NULL) {
      return cpl_sprintf("%s%s%2.2d%s",prefix,"_badpixel",i,".fits");
    } else if(strstr(ctag,"BN") != NULL) {
      return cpl_sprintf("%s%s%2.2d%s",prefix,"_bound",i,".fits");
    } else {
      uves_msg_error("tag %s not supported",ctag);
      return NULL;
    }
  }
  return NULL;

}



static const char*
flames_get_tag_slice(const char* ctag,enum uves_chip chip,const int i)
{

  if(strstr(ctag,"FIB") != NULL) {
    //FIBFF
    if(strstr(ctag,"DT") != NULL) {
      return FLAMES_FIB_FF_DT(i,chip);
    } else if(strstr(ctag,"SG") != NULL) {
      return FLAMES_FIB_FF_SG(i,chip);
    } else if(strstr(ctag,"BP") != NULL) {
      return FLAMES_FIB_FF_BP(i,chip);
    } else {
      uves_msg_error("tag %s not supported",ctag);
      return NULL;
    }
  } else {
    //SLITFF
    if(strstr(ctag,"DT") != NULL) {
      return FLAMES_SLIT_FF_DT(i,chip);
    } else if(strstr(ctag,"SG") != NULL) {
      return FLAMES_SLIT_FF_SG(i,chip);
    } else if(strstr(ctag,"BP") != NULL) {
      return FLAMES_SLIT_FF_BP(i,chip);
    } else if(strstr(ctag,"BN") != NULL) {
      return FLAMES_SLIT_FF_BN(i,chip);
    } else {
      uves_msg_error("tag %s not supported",ctag);
      return NULL;
    }
  }
  return NULL;

}



/*---------------------------------------------------------------------------*/
/**
  @brief    to set fibre FF names to DRS standard
  @param    frames input frame list
  @param    tag    input frame tag
  @param    cub_name input frame name
  @param    set_out  output image set
  @return   0 if everything is ok

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


int
flames_extract_ima_from_cube(cpl_frameset* frames,
			     const char* tag,
                             enum uves_chip chip,
			     const char* cub_name,
			     cpl_frameset** set_out)
{

  uves_propertylist* head_ref=NULL;
  uves_propertylist* head_out=NULL;
  cpl_imagelist* iml=NULL;
  cpl_frame* frame=NULL;
  cpl_image* img=NULL;
  char ntag[80];

  char file_name[MIN_NAME_SIZE];
  int i=0;
  int size=0;
  int k=0;

  //Note that if the cube miss hiearrch keys then those are lost.

  ck0_nomsg(flames_replicate_frame(frames,tag,cub_name,set_out));

  check_nomsg(head_ref=uves_propertylist_load(cub_name,0));
  check_nomsg(head_out=uves_propertylist_duplicate(head_ref));

  check_nomsg(iml=cpl_imagelist_load(cub_name,CPL_TYPE_FLOAT,0));
  check_nomsg(size=cpl_imagelist_get_size(iml));
 

  for(i=0;i<size;i++) {
    k=i+1;
    //FIXME: Is the following needed?
    //ck0_nomsg(flames_reduce_reset_descriptors(head_ref,&head_out,k));
    frame=cpl_frame_new();
    check_nomsg(img=cpl_imagelist_get(iml,i));
    strcpy(file_name,flames_get_file_name_slice(tag,chip,k));
    check_nomsg(uves_save_image(img,file_name,head_out,true,true));
    strcpy(ntag,flames_get_tag_slice(tag,chip,k));
    ck0_nomsg(flames_reset_start_and_npix(file_name,ntag));
    check_nomsg(cpl_frame_set_tag(frame,ntag));
    check_nomsg(cpl_frame_set_filename(frame,file_name));
    check_nomsg(cpl_frameset_insert(*set_out,frame));
  }

 cleanup:

  uves_free_propertylist(&head_ref);
  uves_free_propertylist(&head_out);
  uves_free_imagelist(&iml);

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

}

/*---------------------------------------------------------------------------*/
/**
  @brief    to set fibre FF names to DRS standard
  @param    frames input frame list
  @param    tag    input frame tag
  @param    cub_name input frame name
  @param    set_out  output image set
  @return   0 if everything is ok

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

int
flames_extract_cube_from_cube(cpl_frameset* frames,
			     const char* tag,
                             enum uves_chip chip,
			      const int nflats,
			     const char* cub_name,
			     cpl_frameset** set_out)
{

  uves_propertylist* head_ref=NULL;
  uves_propertylist* head_out=NULL;
  cpl_imagelist* iml=NULL;
  cpl_imagelist* cub=NULL;
  cpl_frame* frame=NULL;
  cpl_image* img=NULL;
  char file_name[MIN_NAME_SIZE];
  char ntag[MIN_NAME_SIZE];
  int i=0;
  int it=0;
  
  int isize=0;
  int osize=0;
  int pp_min=0;
  int pp_max=0;

  int k=0;


  ck0_nomsg(flames_replicate_frame(frames,tag,cub_name,set_out));
  check_nomsg(head_ref=uves_propertylist_load(cub_name,0));
  check_nomsg(head_out=uves_propertylist_duplicate(head_ref));
  check_nomsg(iml=cpl_imagelist_load(cub_name,CPL_TYPE_FLOAT,0));
  check_nomsg(isize=cpl_imagelist_get_size(iml));
  osize = isize/nflats; 

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

    pp_min=i*osize;
    pp_max= (i+1)*osize-1;

    //Here problem with CUNIT: only 2 p;resent but NAXIS=3
    ck0_nomsg(flames_reduce_reset_descriptors(head_ref,&head_out,k));
    strcpy(ntag,FLAMES_SLIT_FF_BN(k,chip));
    check_nomsg(cub=cpl_imagelist_new());
    for(it=pp_min;it<=pp_max;it++) {
      check_nomsg(img=cpl_imagelist_get(iml,it));
      cpl_imagelist_set(cub,cpl_image_duplicate(img),(it-pp_min));
    }
    strcpy(file_name,flames_get_file_name_slice(tag,chip,k));
    check_nomsg(uves_save_imagelist(cub,file_name,head_out));
    uves_msg_debug("saved frame %s",file_name);
    ck0_nomsg(flames_reset_start_and_npix(file_name,ntag));

    check_nomsg(frame=cpl_frame_new());
    check_nomsg(cpl_frame_set_filename(frame,file_name));
    check_nomsg(cpl_frame_set_tag(frame,ntag));
    check_nomsg(cpl_frameset_insert(*set_out,frame));
    uves_free_imagelist(&cub);
  }


 cleanup:
  uves_free_propertylist(&head_ref);
  uves_free_propertylist(&head_out);
  uves_free_imagelist(&iml);
 
  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    return -1;
  } else {
    return 0;
  }


}


/*---------------------------------------------------------------------------*/
/**
  @brief  Merge wavelength calibrated frames. Before add missing descriptors
  @param  inp_ima input extracted frame 
  @param  out_base_reb output rebinned base name
  @param  out_base_mer output merged base name
  @param  fibre_id input fibre id
  @param  raw_switch  is it a raw or simple frame?
  @return 0 if everything is ok
  @doc This routine merges wavelength calibrated frames using the merging
  routine developed by the ITAL-FLAMES consortium. This routine takes into 
  account of the sigma and bad pixel map frames and does an optimal merging.
  Before starting some missing descriptors (WSTART,NPTOT) are created.

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

int
flames_drs_merge(const char* inp_ima, 
                 const char* out_base_reb, 
                 const char* out_base_mer,
                 const int fibre_id,
                 const int raw_switch,
                 const double delta1,
                 const double delta2)
{

  char base_mer[MED_NAME_SIZE];


  char inter_ima[MED_NAME_SIZE];
  char inter_sig[MED_NAME_SIZE];
  char inter_msk[MED_NAME_SIZE];

  char des_name[MED_NAME_SIZE];


  char in_sig[MED_NAME_SIZE];
  char in_msk[MED_NAME_SIZE];

  int ima_id=0;
  int sig_id=0;
  int msk_id=0;
  int unit=0;
  int null=0;
  int actvals=0;
  int naxis2=0;
  int i=0;
  double* wstart=NULL;
  double* wend=NULL;
  int* nptot=NULL;
  double wstep=0;

  SCSPRO("flames_drs_merge");
  uves_msg_warning("inp_ima=%s",inp_ima);
  if (SCFOPN(inp_ima, FLAMESDATATYPE, 0, F_IMA_TYPE, &ima_id) != 0) {
    SCTPUT("Error opening the extracted spectrum");
    return flames_midas_fail();
  }
  if (SCDRDC(ima_id,"SIGMAFRAME",1,1,48,&actvals,in_sig,&unit,&null)!=0) {
    SCTPUT("Error getting SIGMAFRAME");
    return flames_midas_fail();
  }
  if (SCDRDC(ima_id,"MASKFRAME",1,1,48,&actvals,in_msk,&unit,&null)!=0) {
    SCTPUT("Error getting SIGMAFRAME");
    return flames_midas_fail();
  }

  if(raw_switch == 0) {
    sprintf(inter_ima,"%s_%4.4d.fits",out_base_reb,fibre_id);
    sprintf(inter_sig,"%s_sig%4.4d.fits",out_base_reb,fibre_id);
    sprintf(inter_msk,"%s_extco%4.4d.fits",out_base_reb,fibre_id);
    sprintf(base_mer,"%s_%4.4d",out_base_mer,fibre_id);
  } else {
    sprintf(inter_ima,"%s_raw%4.4d.fits",out_base_reb,fibre_id);
    sprintf(inter_sig,"%s_rawsig%4.4d.fits",out_base_reb,fibre_id);
    sprintf(inter_msk,"%s_rawextco%4.4d.fits",out_base_reb,fibre_id);
    sprintf(base_mer,"%s_raw%4.4d",out_base_mer,fibre_id);
  }
  uves_msg_debug("in_sig=%s",in_sig);
  uves_msg_debug("in_msk=%s",in_msk);

  SCFCLO(ima_id);


  if (SCFOPN(inter_ima, FLAMESDATATYPE, 0, F_IMA_TYPE, &ima_id) != 0) {
    SCTPUT("Error opening the extracted spectrum");
    return flames_midas_fail();
  }
  if (SCDWRC(ima_id, "SIGMAFRAME", 1,inter_sig, 1,48, &unit)) {
    SCFCLO(ima_id); 
    return flames_midas_fail();
  }
  if (SCDWRC(ima_id, "MASKFRAME", 1,inter_sig, 1,48, &unit)) {
    SCFCLO(ima_id); 
    return flames_midas_fail();
  }
  if (SCDRDI(ima_id,"NAXIS2",1,1,&actvals,&naxis2,&unit,&null)){
    SCFCLO(ima_id);
    return flames_midas_fail();
  }


  //Add some missing descriptor files: WSTART,NPTOT
  wstart = calloc(naxis2, sizeof(double));
  wend   = calloc(naxis2, sizeof(double));
  nptot  = calloc(naxis2, sizeof(int));
  if (SCDRDD(ima_id,"CDELT1",1,1,&actvals,&wstep,&unit,&null)){
    SCFCLO(ima_id);
    free(wstart);
    free(nptot);
    return flames_midas_fail();
  }
  for(i=0;i<naxis2;i++) {
    sprintf(des_name,"%s%d","WSTART",i+1);
    if (SCDRDD(ima_id,des_name,1,1,&actvals,&wstart[i],&unit,&null)){
      SCFCLO(ima_id);
      free(wstart);
      free(wend);
      free(nptot);
      return flames_midas_fail();
    }
    //uves_msg_warning("WSTART[%d]=%f",i,wstart[i]);
    sprintf(des_name,"%s%d","WEND",i+1);
    if (SCDRDD(ima_id,des_name,1,1,&actvals,&wend[i],&unit,&null)){
      SCFCLO(ima_id);
      free(wstart);
      return flames_midas_fail();
    }
    //uves_msg_warning("WEND[%d]=%f",i,wend[i]);
    nptot[i]=(wend[i]-wstart[i])/wstep;
    //uves_msg_warning("NPTOT[%d]=%d",i,nptot[i]);
  }
  if (SCDWRD(ima_id, "WSTART", wstart, 1, naxis2, &unit)) {
    SCFCLO(ima_id); 
    free(wstart);
    return flames_midas_fail();
  }
  if (SCDWRI(ima_id, "NPTOT", nptot, 1, naxis2, &unit)) {
    SCFCLO(ima_id); 
    free(wstart);
    return flames_midas_fail();
  }


  if (SCFOPN(inter_sig, FLAMESDATATYPE, 0, F_IMA_TYPE, &sig_id) != 0) {
    SCTPUT("Error opening the extracted spectrum");
    free(wstart);
    return flames_midas_fail();
  }
  if (SCDWRC(sig_id, "SCIENCEFRAME", 1,inter_ima, 1,48, &unit)) {
    SCFCLO(sig_id); 
    free(wstart);
    return flames_midas_fail();
  }

  //Add some missing descriptor files: WSTART,NPTOT
  if (SCDWRD(sig_id, "WSTART", wstart, 1, naxis2, &unit)) {
    SCFCLO(ima_id); 
    return flames_midas_fail();
  }
  if (SCDWRI(sig_id, "NPTOT", nptot, 1, naxis2, &unit)) {
    SCFCLO(ima_id); 
    free(wstart);
    return flames_midas_fail();
  }
 
  ck0_nomsg(SCFCLO(sig_id));

  if (SCFOPN(inter_msk, FLAMESDATATYPE, 0, F_IMA_TYPE, &msk_id) != 0) {
    SCTPUT("Error opening the extracted spectrum");
    free(wstart);
    return flames_midas_fail();
  }
  if (SCDWRC(msk_id, "SCIENCEFRAME", 1,inter_msk, 1,48, &unit)) {
    SCFCLO(msk_id); 
    free(wstart);
    return flames_midas_fail();
  }


  
  //Add some missing descriptor files: WSTART,NPTOT
  if (SCDWRD(msk_id, "WSTART", wstart, 1, naxis2, &unit)) {
    SCFCLO(ima_id); 
    free(wstart);
    return flames_midas_fail();
  }

  if (SCDWRI(msk_id, "NPTOT", nptot, 1, naxis2, &unit)) {
    SCFCLO(ima_id); 
    free(wstart);
    return flames_midas_fail();
  }

  ck0_nomsg(SCFCLO(msk_id));
  ck0_nomsg(SCFCLO(ima_id));

  SCSEPI();


  ck0_nomsg(flames_merge(inter_ima,inter_sig,inter_msk,base_mer,&MASKTHRES,
			 delta1,delta2));



 cleanup:
  free(nptot);
  free(wend);
  free(wstart);

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

}


/*---------------------------------------------------------------------------*/
/**
  @brief    to set fibre FF names to DRS standard
  @param    frames input frame list
  @param    tag    input frame tag
  @param    name   input frame name
  @return   0 if everything is ok

*/
/*---------------------------------------------------------------------------*/
int
flames_replicate_frame(cpl_frameset* frames,
                       const char* tag,
		       const char* name,
                       cpl_frameset** set)
{

  
  //flames_ipercube* icub=NULL;
  //cpl_table* tbl=NULL;
  cpl_image* ima=NULL;
  //cpl_imagelist* iml=NULL;
  uves_propertylist* plist=NULL;
  //int naxis=0;

 cpl_frame* frame=NULL;                 /* The current frame being processed */
 cpl_frame_type frame_type;           /* Type of the current frame */

 const char* src_name=NULL;
 const char* out_name=NULL;
 char current_dir[FILENAME_MAX];         /* Name of current (work) directory */
 const char* cmd=NULL;

 check_nomsg(frame=cpl_frameset_find(frames,tag));
 check_nomsg(src_name=cpl_frame_get_filename(frame));

 uves_msg_debug("input frame name=%s",name);
 uves_msg_debug("rename tag=%s",tag);
 /* Determine the frame type */
 check_nomsg(frame_type = cpl_frame_get_type (frame));
 uves_msg_debug("frame_type=%d",frame_type);
 current_dir[0] = '\0';

 // Determine the name of the current directory 
 (void) getcwd (current_dir, (size_t) FILENAME_MAX);
 //uves_msg("current_dir: %s",current_dir);
 cknull_nomsg(out_name=flames_fileutils_create_fqfname(current_dir,(char*)name));
 uves_msg_debug("out_name: %s",out_name);
 //uves_msg("name: %s",name);
 uves_msg_debug("src_name: %s",src_name);

 if(flames_fileutils_file_exists(out_name)==0) {
   ck0_nomsg(flames_fileutils_link(out_name,src_name));
   cmd = uves_sprintf("chmod 644 %s ", out_name);
   assure( system(cmd) == 0,CPL_ERROR_UNSPECIFIED,"failed file copy" );
 }
 ck0_nomsg(flames_reset_start_and_npix(out_name,tag));
 check_nomsg(cpl_frame_set_filename(frame,out_name));
 check_nomsg(cpl_frame_set_filename(frame,out_name));

 check_nomsg(cpl_frameset_insert(*set,frame));
 cleanup:

 uves_free_image(&ima);
 uves_free_propertylist(&plist);
 
  if (cpl_error_get_code() != CPL_ERROR_NONE) {
    return -1;
  } else {
    return 0;
  }

}

/*---------------------------------------------------------------------------*/
/**
  @brief    Add WSTART descriptor
  @param    head_ref reference FITS header
  @param    head_out output FITS header
  @param    nord     number of orders
  @return   0 if everything is ok

*/
/*---------------------------------------------------------------------------*/
int
flames_reduce_add_wstart(uves_propertylist* head_ref,
                         uves_propertylist** head_out,
                         const int nord)
{

  double wstart=0;
  char key_name[80];
  int i=0;

  for(i=1;i<=nord;i++) {

    sprintf(key_name,"%s%d","WSTART",i);

    check(wstart=uves_propertylist_get_double(head_ref,key_name),
	  "Error reading %s",key_name);

    check_nomsg(uves_propertylist_append_double(*head_out,key_name,wstart));
    
   
  }

 cleanup:
  return 0;

}

/*---------------------------------------------------------------------------*/
/**
  @brief procedure to perform a cross correlation and calculate the velocity 
         shift between two spectra
  @return   0 if everything is ok

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

int
flames_reduce_vcorrel(const char* sci_pfx, 
                      const char* cvel_pfx, 
                      const char* ccd_id,
                      const int ord_max,
                      const cpl_frame* cvel_tab, 
                      const char* xxima_pfx, 
                      const char* xwcal_pfx,
                      const double drs_cvel_min,
                      const double drs_cvel_max,
                      double* zero_point,
                      double* avg_cnt,
                      double* sig_cnt,
		      cpl_table* qclog)
{

   int ord = 0;
   int ord_min=1;
   char cvel_tab_name[80];
   char tim_ccf[80];
   char nim_ccf[80];
   char iim_pfx[80];
   char tab_pfx[80];
   char nim_pfx[80];
   char tim_pfx[80];
   char ref_frm[80];
   char otab[80];
   const int npix=(drs_cvel_max-drs_cvel_min)/DRS_CVEL_STEP+1;

   cpl_image* tim_ccf_ima=NULL;
   cpl_image* nim_ccf_ima=NULL;

   cpl_table* cvel_tbl=NULL;
   double ccfcnt[ord_max];
   int    num_ord=0;
   int status=0;
   int unit=0;
   int actvals=0;
   int null=0;
 
   int in_ima_id=0;
   int iim_pfx_id=0;

   char out_cvel_tab[80];
   char out_tot_ima[80];
   char out_nrm_ima[80];
   cpl_table* cvel_ord_tbl=NULL;
   int row_pos=0;

   cpl_image* tot_ima=NULL;
   cpl_image* nrm_ima=NULL;
   int nrow=0;

   double ccf_max=0;
   double wav_rng=0;
   double pix_tot=0;
   int lin_tot=0;
   cpl_propertylist* plist_ima_new=NULL;
   cpl_propertylist* plist_tbl_new=NULL;

   double corvel_max=0;
   char key_name[80];

   const char* command=NULL;
   const char* cunit=NULL;




   //Fixme
   uves_msg_debug("sci_pfx=%s",sci_pfx);
   uves_msg_debug("ccd_id=%s",ccd_id);

   sprintf(otab,"%s%s%s",cvel_pfx,ccd_id,".fits");
   sprintf(tim_ccf,"%s%s%s%s","tot_",cvel_pfx,ccd_id,".fits");
   sprintf(nim_ccf,"%s%s%s%s","nrm_",cvel_pfx,ccd_id,".fits");
   sprintf(iim_pfx,"%s%s%s%s","mw",sci_pfx,xxima_pfx,".fits");
   sprintf(tab_pfx,"%s%s%s","tab_",ccd_id,"_");
   sprintf(nim_pfx,"%s%s%s","nrm_",ccd_id,"_");
   sprintf(tim_pfx,"%s%s%s","tot_",ccd_id,"_");
   sprintf(ref_frm,"%s%s%s","w",sci_pfx,xwcal_pfx);


   uves_msg_debug("pointer=%p",cvel_tab);

   uves_msg("name=%s",cpl_frame_get_filename(cvel_tab));
   sprintf(cvel_tab_name,"%s",cpl_frame_get_filename(cvel_tab));

   uves_msg_debug("npix=%d",npix);
   tim_ccf_ima=cpl_image_new(npix,ord_max,CPL_TYPE_FLOAT);
   nim_ccf_ima=cpl_image_new(npix,ord_max,CPL_TYPE_FLOAT);


   //AMO:Fixme
   row_pos=0;
   uves_msg_debug("ord_max=%d nlines=%d",ord_max,npix*ord_max);
   //cvel_tbl=cpl_table_new(npix*ord_max);
   cvel_tbl=cpl_table_new(0);
   check_nomsg(cpl_table_new_column(cvel_tbl,"Select",CPL_TYPE_INT));
   check_nomsg(cpl_table_new_column(cvel_tbl,"ccf_pos",CPL_TYPE_DOUBLE));
   check_nomsg(cpl_table_new_column(cvel_tbl,"ccf_nrm",CPL_TYPE_DOUBLE));
   check_nomsg(cpl_table_new_column(cvel_tbl,"ccf_out",CPL_TYPE_DOUBLE));
   check_nomsg(cpl_table_new_column(cvel_tbl,"ORDER",CPL_TYPE_INT));
   check_nomsg(plist_ima_new=cpl_propertylist_new());


  
   ck0_nomsg(uves_qclog_add_string(qclog,
				   "QC TEST2 ID",
				   "Fibre-Science-QC",
				   "Name of QC test",
				   "%s"));
   uves_check_rec_status(0);

   for (ord=ord_min;ord<=ord_max;ord++) {
      ccfcnt[ord]=0;
      //for (ord=2;ord<=2;ord++) {
 
      sprintf(out_cvel_tab,"%s%s%d%s","tab_",ccd_id,ord,".fits");
      sprintf(out_tot_ima,"%s%s%d%s","tot_",ccd_id,ord,".fits");
      sprintf(out_nrm_ima,"%s%s%d%s","nrm_",ccd_id,ord,".fits");

 
      uves_msg_debug("vc2 %s %s %s",out_cvel_tab,out_tot_ima,out_nrm_ima);
      uves_msg_debug("iim_pfx=%s cvel_tab_name=%s ord=%d",
                       iim_pfx,cvel_tab_name,ord);
 
      uves_msg_debug("out_cvel_tab=%s",out_cvel_tab);
      uves_msg_debug("out_tot_ima=%s",out_tot_ima);
      uves_msg_debug("out_nrm_ima=%s",out_nrm_ima);
      uves_msg_debug("ord=%d",ord);

 


      check_nomsg(flames_corvel(iim_pfx,
                                cvel_tab_name,
                                ord,
                                out_cvel_tab,
                                out_tot_ima,
                                out_nrm_ima,
                                drs_cvel_min,
                                drs_cvel_max,
                                DRS_CVEL_STEP));


      uves_msg_debug("CVEL MAX=%f MIN=%f STEP=%f",
		       drs_cvel_min,drs_cvel_max,DRS_CVEL_STEP);

      check_nomsg(tot_ima=cpl_image_load(out_tot_ima,CPL_TYPE_FLOAT,0,0));
      check_nomsg(nrm_ima=cpl_image_load(out_nrm_ima,CPL_TYPE_FLOAT,0,0));
      check_nomsg(cpl_image_copy(tim_ccf_ima,tot_ima,1,ord-ord_min+1));
      check_nomsg(cpl_image_copy(nim_ccf_ima,nrm_ima,1,ord-ord_min+1));
      check_nomsg(cvel_ord_tbl=cpl_table_load(out_cvel_tab,1,1));
 

      check_nomsg(cpl_table_new_column(cvel_ord_tbl,"ORDER",CPL_TYPE_INT));
      check_nomsg(nrow=cpl_table_get_nrow(cvel_ord_tbl));

      check_nomsg(cpl_table_fill_column_window_int(cvel_ord_tbl,"ORDER",0,nrow,ord));
      cunit=cpl_table_get_column_unit(cvel_ord_tbl,"ccf_pos");
      cpl_table_set_column_unit(cvel_tbl,"ccf_pos",cunit);

      cunit=cpl_table_get_column_unit(cvel_ord_tbl,"ccf_nrm");
      cpl_table_set_column_unit(cvel_tbl,"ccf_nrm",cunit);

      cunit=cpl_table_get_column_unit(cvel_ord_tbl,"ccf_out");
      cpl_table_set_column_unit(cvel_tbl,"ccf_out",cunit);

      cunit=cpl_table_get_column_unit(cvel_ord_tbl,"ORDER");
      cpl_table_set_column_unit(cvel_tbl,"ORDER",cunit);

      check_nomsg(cpl_table_insert(cvel_tbl,cvel_ord_tbl,row_pos));
      row_pos+=nrow;

      if((status=SCFOPN(out_tot_ima,D_R4_FORMAT,0,F_IMA_TYPE,&in_ima_id))!=0) {
         uves_msg_error("opening frame %s",out_tot_ima);
         return flames_midas_error(MAREMMA);
      }

      if((status=SCFOPN(iim_pfx,D_R4_FORMAT,0,F_IMA_TYPE,&iim_pfx_id))!=0) {
         uves_msg_error("opening frame %s",iim_pfx);
         return flames_midas_error(MAREMMA);
      }



      sprintf(key_name,"%s","CORVEL_MAX");
      if((status=SCDRDD(iim_pfx_id,key_name,1,1,&actvals,&corvel_max,&unit,&null)) 
         != 0) {
	uves_msg_error("Reading descriptor %s from frame %s",
		       key_name,out_tot_ima);
         return flames_midas_error(MAREMMA);
      }

 

      sprintf(key_name,"%s%d","CCF_PMX",ord);
      uves_msg_debug("corvel_max=%g",corvel_max);
      if(!irplib_isnan(corvel_max)) {
         ccfcnt[ord]=corvel_max;
	 check_nomsg(cpl_propertylist_append_double(plist_ima_new,key_name,
						    corvel_max));


	     
	 ck0_nomsg(uves_qclog_add_double(qclog,
					 cpl_sprintf("%s%d%s",
						     "QC CCF",ord," POSMAX"),
					 corvel_max,
					 "CCF pos Max",
					 "%f"));
	 

      } else {
         ccfcnt[ord]=999;
	 check_nomsg(cpl_propertylist_append_double(plist_ima_new,key_name,
						    999));


	 
     
	 ck0_nomsg(uves_qclog_add_double(qclog,
					 cpl_sprintf("%s%d%s",
						     "QC CCF",ord," POSMAX"),
					 999,
					 "CCF pos Max",
					 "%f"));
	 

      }


      sprintf(key_name,"%s","CCF_MAX");
      if((status=SCDRDD(in_ima_id,key_name,1,1,&actvals,&ccf_max,&unit,&null)) 
         != 0) {
	uves_msg_error("Reading descriptor %s from frame %s",
		       key_name,out_tot_ima);
         return flames_midas_error(MAREMMA);
      }


      sprintf(key_name,"%s%d","CCF_MAX",ord);
      uves_msg_debug("ccf_max=%g",ccf_max);
      check_nomsg(cpl_propertylist_append_double(plist_ima_new,key_name,ccf_max));

      
      ck0_nomsg(uves_qclog_add_double(qclog,
				    cpl_sprintf("%s%d%s",
						"QC CCF",ord," INTMAX"),
				      ccf_max,
				      "CCF Int Max",
				      "%f"));

      
 
      sprintf(key_name,"%s","WAV_RNG");
      if((status=SCDRDD(in_ima_id,key_name,1,1,&actvals,&wav_rng,&unit,&null)) 
         != 0) {
	uves_msg_error("Reading descriptor %s from frame %s",
		       key_name,out_tot_ima);
         return flames_midas_error(MAREMMA);
      }

      sprintf(key_name,"%s%d","WAV_RNG",ord);
      uves_msg_debug("wav_rng=%g",wav_rng);
      uves_msg_debug("key_name=%s",key_name);
      check_nomsg(cpl_propertylist_append_double(plist_ima_new,key_name,wav_rng));

      
      ck0_nomsg(uves_qclog_add_double(qclog,
				    cpl_sprintf("%s%d%s",
						"QC CCF",ord," WAVRNG"),
				      wav_rng,
				      "CCF Range",
				      "%f"));

      
     
      sprintf(key_name,"%s","PIX_TOT");
      if((status=SCDRDD(in_ima_id,key_name,1,1,&actvals,&pix_tot,&unit,&null)) 
         != 0) {
	uves_msg_error("Reading descriptor %s from frame %s",
		       key_name,out_tot_ima);
         return flames_midas_error(MAREMMA);
      }
 
     
      uves_msg_debug("pix_tot=%g",pix_tot);
      if(!irplib_isinf(pix_tot)) {

	sprintf(key_name,"%s%d","PIX_TOT",ord);
	check_nomsg(cpl_propertylist_append_double(plist_ima_new,key_name,pix_tot));

	ck0_nomsg(uves_qclog_add_double(qclog,
					cpl_sprintf("%s%d%s",
						    "QC CCF",ord," PIXTOT"),
					pix_tot,
					"CCF Pix",
					"%f"));

      } else {

	sprintf(key_name,"%s%d","PIX_TOT",ord);
	check_nomsg(cpl_propertylist_append_double(plist_ima_new,key_name,999.));

	ck0_nomsg(uves_qclog_add_double(qclog,
					cpl_sprintf("%s%d%s",
						    "QC CCF",ord," PIXTOT"),
					999,
					"CCF Pix",
					"%f"));


      }

      sprintf(key_name,"%s","LIN_TOT");
      if((status=SCDRDI(in_ima_id,key_name,1,1,&actvals,&lin_tot,&unit,&null)) 
         != 0) {
	uves_msg_error("Reading descriptor %s from frame %s",
		       key_name,out_tot_ima);
         return flames_midas_error(MAREMMA);
      }


      sprintf(key_name,"%s%d","LIN_TOT",ord);

      check_nomsg(cpl_propertylist_append_int(plist_ima_new,key_name,lin_tot));
      uves_msg_debug("lin_tot=%d",lin_tot);

           
      ck0_nomsg(uves_qclog_add_int(qclog,
				    cpl_sprintf("%s%d%s",
						"QC CCF",ord," LINTOT"),
				      pix_tot,
				      "CCF Lin",
				      "%d"));
     
     
      if((status = SCFCLO(in_ima_id))!=0) {
         uves_msg_error("Closing frame %d",in_ima_id);
         return flames_midas_error(MAREMMA);
      }
      if((status = SCFCLO(iim_pfx_id))!=0) {
         uves_msg_error("Closing frame %d",iim_pfx_id);
         return flames_midas_error(MAREMMA);
      }
 
     
      uves_free_table(&cvel_ord_tbl);
      uves_free_image(&tot_ima);
      uves_free_image(&nrm_ima);

      command=uves_sprintf("%s%s","rm -rf ",out_cvel_tab);
      system(command);
      command=uves_sprintf("%s%s","rm -rf ",out_tot_ima);
      system(command);
      command=uves_sprintf("%s%s","rm -rf ",out_nrm_ima);
      system(command);


   } //end loop over orders


   check_nomsg(cpl_image_save(tim_ccf_ima, "tot_ima.fits",CPL_BPP_IEEE_FLOAT,
			      plist_ima_new,CPL_IO_DEFAULT));
   check_nomsg(cpl_image_save(nim_ccf_ima, "nrm_ima.fits",CPL_BPP_IEEE_FLOAT,
			      plist_ima_new,CPL_IO_DEFAULT));
 
   check_nomsg(cpl_table_save(cvel_tbl, plist_tbl_new, NULL, otab, 
			      CPL_IO_DEFAULT));
 
   uves_free_image(&tim_ccf_ima);
   uves_free_image(&nim_ccf_ima);
   uves_free_table(&cvel_tbl);

   ord = ord_max-ord_min+1;
   //flames_cveltab(cpfx_ccd_id_tbl,ord);



   num_ord = 0;
   *avg_cnt=0;
   for (ord=ord_min; ord<= ord_max; ord++) {
      if (ccfcnt[ord] != 999) {
         *avg_cnt +=ccfcnt[ord];
         uves_msg_debug("POSMAX avg=%g cnt=%g ord=%d",*avg_cnt,ccfcnt[ord],ord);
         num_ord += 1;
      }
   }
 
   *avg_cnt /= num_ord;
   *sig_cnt=0;
   for (ord = ord_min; ord <= ord_max; ord++) {
      if (ccfcnt[ord] != 999) {
         *sig_cnt += (ccfcnt[ord]-*avg_cnt)*(ccfcnt[ord]-*avg_cnt);
         uves_msg_debug("sig=%g cnt=%g ord=%d",*sig_cnt,ccfcnt[ord],ord);
      }
   }
   *sig_cnt = sqrt(*sig_cnt/(num_ord-1));

   *zero_point+=(*avg_cnt);


   /*
   uves_msg("POSMAX avg=%g sig=%g zp=%g",*avg_cnt,*sig_cnt,*zero_point);
   */

   ck0_nomsg(uves_qclog_add_double(qclog,
				   "QC CCF POSAVG",
				   *avg_cnt,
				   "CCF pos avg",
				   "%f"));


   ck0_nomsg(uves_qclog_add_double(qclog,
				   "QC CCF POSRMS",
				   *sig_cnt,
				   "CCF pos rms",
				   "%f"));
   /* commented out to match FUVES-MIDAS results

  ck0_nomsg(uves_qclog_add_double(qclog,
				   "QC CCF POSOFF",
				   *zero_point,
				   "CCF pos avg from ThAr calibration",
				   "%f"));

   */
 


   uves_msg_debug("POSAVG=%f POSRMS=%f",*avg_cnt,*sig_cnt);
 

   /*
     do ord = ord_min ord_max

     CORVEL/FLAMES {iim_pfx}{ord}.bdf {cvel_tab} {ord} -
     {tab_pfx}{ord}.tbl {tim_pfx}{ord}.bdf {nim_pfx}{ord}.bdf
    
 

     insert/ima {tim_pfx}{ord}.bdf {tim_ccf} @1,@{ord}
     insert/ima {nim_pfx}{ord}.bdf {nim_ccf} @1,@{ord}
     
     create/column {tab_pfx}{ord}.tbl :ORDER
     compute/table {tab_pfx}{ord}.tbl :ORDER = {ord}
     if counter .eq. 0 then
     merge/table {tab_pfx}{ord}.tbl  {cpfx}_{ccd_id}.tbl
     counter = counter + 1
     else
     -rename {cpfx}_{ccd_id}.tbl tmp.tbl
     merge/table tmp.tbl {tab_pfx}{ord}.tbl  {cpfx}_{ccd_id}.tbl  
     endif
     copy/dd {iim_pfx}{ord}.bdf CORVEL_MAX {cpfx}_{ccd_id}.tbl CCF_PMX{ord}
     qc1log/out 1 {otab}  "QC.CCF{ord}.POSMAX" {{iim_pfx}{ord}.bdf,CORVEL_MAX} "CCF pos Max"
     qc1log/out 1 {otab}  "QC.CCF{ord}.INTMAX" {{tab_pfx}{ord}.tbl,CCF_MAX} "CCF Int Max"
     qc1log/out 1 {otab}  "QC.CCF{ord}.WAVRNG" {{tab_pfx}{ord}.tbl,WAV_RNG} "CCF Range"
     qc1log/out 1 {otab}  "QC.CCF{ord}.PIXTOT" {{tab_pfx}{ord}.tbl,PIX_TOT} "CCF Pix"
     qc1log/out 1 {otab}  "QC.CCF{ord}.LINTOT" {{tab_pfx}{ord}.tbl,LIN_TOT} "CCF Lin"
     if "{{iim_pfx}{ord}.bdf,CORVEL_MAX}" .ne. "NAN" then
     ccfcnt({ord}) = {{iim_pfx}{ord}.bdf,CORVEL_MAX}
     else
     mess/out 2 {pid} "Pos Max Nan for order {ord}. Skip it"
     ccfcnt({ord}) = 999
     endif

     copy/dd {tab_pfx}{ord}.tbl CCF_MAX {cpfx}_{ccd_id}.tbl CCF_MAX{ord}
     copy/dd {tab_pfx}{ord}.tbl WAV_RNG {cpfx}_{ccd_id}.tbl WAV_RNG{ord}
     copy/dd {tab_pfx}{ord}.tbl PIX_TOT {cpfx}_{ccd_id}.tbl PIX_TOT{ord}
     copy/dd {tab_pfx}{ord}.tbl LIN_TOT {cpfx}_{ccd_id}.tbl LIN_TOT{ord}



     copy/dd {iim_pfx}{ord}.bdf CORVEL_MAX {tim_ccf} CCF_PMX{ord}
     copy/dd {tim_pfx}{ord}.bdf CCF_MAX    {tim_ccf} CCF_MAX{ord}
     copy/dd {tim_pfx}{ord}.bdf WAV_RNG    {tim_ccf} WAV_RNG{ord}
     copy/dd {tim_pfx}{ord}.bdf PIX_TOT    {tim_ccf} PIX_TOT{ord}
     copy/dd {tim_pfx}{ord}.bdf LIN_TOT    {tim_ccf} LIN_TOT{ord}

     copy/dd {iim_pfx}{ord}.bdf CORVEL_MAX {nim_ccf} CCF_PMX{ord}
     copy/dd {nim_pfx}{ord}.bdf CCF_MAX    {nim_ccf} CCF_MAX{ord}
     copy/dd {nim_pfx}{ord}.bdf WAV_RNG    {nim_ccf} WAV_RNG{ord}
     copy/dd {nim_pfx}{ord}.bdf PIX_TOT    {nim_ccf} PIX_TOT{ord}
     copy/dd {nim_pfx}{ord}.bdf LIN_TOT    {nim_ccf} LIN_TOT{ord}

     enddo
     ord = {ord_max}-{ord_min}+1
     CVELTAB/FLAMES {cpfx}_{ccd_id}.tbl {ord}



     nord = 0
     do ord = ord_min ord_max
     if ccfcnt({ord}) .ne. 999 then
     avgcnt = avgcnt+ccfcnt({ord})
     nord = nord+1
     endif
     enddo
     avgcnt = avgcnt/(nord)
     do ord = ord_min ord_max
     if ccfcnt({ord}) .ne. 999 then
     sigcnt = sigcnt+(ccfcnt({ord})-avgcnt)*(ccfcnt({ord})-avgcnt)
     endif
     enddo
     sigcnt = m$sqrt(sigcnt/(nord-1))


     mess/out {DRS_MES_LEV} {pid} "POSAVG={avgcnt} POSRMS={sigcnt}"
     qc1log/out 1 {otab}  "QC.CCF.POSAVG" {avgcnt} "CCF pos avg"
     qc1log/out 1 {otab}  "QC.CCF.POSRMS" {sigcnt} "CCF pos rms"
     qc1log/out 1 {otab}  "QC.CCF.POSOFF" {p8}  "CCF pos avg from ThAr calibration"

     qc1log/out 3
     return {avgcnt}
     !set/format {cpfx}_{ccd_id}.tbl


   */
  cleanup:

   if(plist_ima_new!=NULL) {
      cpl_propertylist_delete(plist_ima_new);
      plist_ima_new=NULL;
   }
   uves_free_table(&cvel_tbl);
   uves_free_image(&tim_ccf_ima);
   uves_free_image(&nim_ccf_ima);
   uves_free_image(&tot_ima);
   uves_free_image(&nrm_ima);
   uves_free_table(&cvel_ord_tbl);
 


   if (cpl_error_get_code() != CPL_ERROR_NONE || status != 0) {
      uves_check_rec_status(9);
      //uves_free_imagelist(&obj_cor);
      return -1;
   } else {
      return 0;
   }

}


/**@}*/
