/*
 * This file is part of the UVES Pipeline
 * Copyright (C) 2002, 2003, 2004, 2005 European Southern Observatory
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
 */

/*
 * $Author: amodigli $
 * $Date: 2013-08-08 12:31:13 $
 * $Revision: 1.58 $
 * $Name: not supported by cvs2svn $
 */

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

/*----------------------------------------------------------------------------*/
/**
 * @defgroup flames_dfs  DFS related functions
 */
/*----------------------------------------------------------------------------*/

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

#include <flames_dfs.h>

#include <flames_midas_def.h>
#include <flames_pfits.h>
#include <flames_utils.h>

#include <uves_utils_wrappers.h>
#include <uves_propertylist.h>
#include <uves_dfs.h>
#include <uves_pfits.h>
#include <uves_chip.h>
#include <uves_dump.h>
#include <uves_msg.h>
#include <uves_error.h>

#include <cpl.h>
#include <string.h>
#include <stdbool.h>
/*-----------------------------------------------------------------------------
                            Functions prototypes
 -----------------------------------------------------------------------------*/
/**@{*/
static void
load_raw_image_fib(const char *filename, 
           cpl_type type, bool blue, 
           cpl_image *raw_image[2],
           uves_propertylist *raw_header[2], 
           uves_propertylist *rotated_header[2],
           cpl_table* ext_tbl[2]);

static void
fibremask_fill(uves_propertylist *header, enum uves_chip chip, bool warn_tech,cpl_table* ozpoz);


/*----------------------------------------------------------------------------*/
/**
  @brief    Write HISTORY keyword
  @param    header    to write to
  @param    name      descriptor name
  @param    val       value to write
**/
/*----------------------------------------------------------------------------*/
static void 
set_header_int_1(uves_propertylist *header,
                 const char *name, int val)
{
    const char *val_str = uves_sprintf("%d", val);
    flames_dfs_set_history_val(header, 'I', name, val_str);
    uves_free_string_const(&val_str);
    return;
}
/*----------------------------------------------------------------------------*/
/**
  @brief    Write HISTORY keyword
  @param    header    to write to
  @param    name      descriptor name
  @param    val       value to write
**/
/*----------------------------------------------------------------------------*/
void 
flames_set_header_char_1(uves_propertylist *header,
                 const char *name, char val)
{
    const char *s = uves_sprintf("%c", val);
    flames_dfs_set_history_val(header, 'C', name, s);
    uves_free_string_const(&s);
    return;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Write HISTORY int array
  @param    header    to write to
  @param    name      descriptor name
  @param    val1      value to write
  @param    val2      value to write
  @param    val3      value to write
  @param    val4      value to write
  @param    val5      value to write
  @param    val6      value to write
  @param    val7      value to write
  @param    val8      value to write
**/
/*----------------------------------------------------------------------------*/
static void 
set_header_int_9(uves_propertylist *header,
                 const char *name, 
                 int val1, int val2, int val3, int val4,
                 int val5, int val6, int val7, int val8, int val9)
{
    const char *s = uves_sprintf("%d %d %d %d %d %d %d %d %d", 
                                 val1, val2, val3, val4, val5, val6, val7, val8, val9);

    flames_dfs_set_history_val(header, 'I', name, s);
    uves_free_string_const(&s);

    return;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Loads a raw frame of a type used by the order position recipe
  @param    frames        The input frame set
  @param    raw_filename  (output) Filename of raw frame
  @param    raw_image     (output) The loaded image(s)
  @param    raw_header    (output) The raw image header(s)
  @param    rotated_header (output) Header(s) containing keywords to describe
                           the output rotated frame(s)
  @param    ext_tbl (output) tables to describe the fiber caracteristics
  @param    blue          (output) Flag indicating if the raw frame is blue (true) or red (false)
  @return   CPL_ERROR_NONE iff OK

 */
/*----------------------------------------------------------------------------*/
cpl_error_code
flames_load_ofpos(const cpl_frameset *frames,
          const char **raw_filename,
          cpl_image *raw_image[2],
          uves_propertylist *raw_header[2], 
                  uves_propertylist *rotated_header[2], 
                  cpl_table *ext_tbl[2], 
                  bool *blue)
{
    const char *tags[] = {FLAMES_FIB_FF_ODD, 
              FLAMES_FIB_FF_EVEN,  
              FLAMES_FIB_FF_ALL};  
    int number_of_tags = sizeof(tags) / sizeof(char *);
    int indx;
    
    check( *raw_filename = uves_find_frame(frames, tags, number_of_tags, &indx,
                       NULL),
       "Could not find raw frame (%s, %s or %s) in SOF", 
              tags[0], tags[1], tags[2]);
    
     *blue = (indx == 0) || (indx == 2);

 
     /* Load the image */
    check( load_raw_image_fib(*raw_filename,
              CPL_TYPE_DOUBLE,
              *blue,
              raw_image,
              raw_header,
              rotated_header,ext_tbl),
       "Error loading image from file '%s'", *raw_filename);

      
  cleanup:
    if (cpl_error_get_code() != CPL_ERROR_NONE)
    {
        *raw_filename = NULL;
    }
    
    return cpl_error_get_code();
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Loads a raw frame of a given type
  @param    frames        The input frame set
  @param    raw_filename  (output) Filename of raw frame
  @param    raw_image     (output) The loaded image(s)
  @param    raw_header    (output) The raw image header(s)
  @param    rotated_header (output) Header(s) containing keywords to describe
                           the output rotated frame(s)
  @param    ext_tbl (output) tables to describe the fiber caracteristics
  @param    tag      frame tag 
  @return   CPL_ERROR_NONE iff OK

  The function searches the frame set for a frame with TAG=tag.
  Results are returned using the last five parameters (NULL on error).
 */
/*----------------------------------------------------------------------------*/
cpl_error_code
flames_load_frame(const cpl_frameset *frames,
                  const char **raw_filename,
                  cpl_image *raw_image[2],
                  uves_propertylist *raw_header[2], 
                  uves_propertylist *rotated_header[2], 
                  cpl_table *ext_tbl[2], 
                  const char* tag)
{
    const char *tags[1];
    int indx;
  
    tags[0] = tag;

    check( *raw_filename = uves_find_frame(frames, tags, 1, &indx, NULL),
       "Could not find raw frame (%s) in SOF", tags[0]);

     /* Load the image */
    check( load_raw_image_fib(*raw_filename,
                  CPL_TYPE_DOUBLE,
                  false,
                  raw_image,
                  raw_header,
                  rotated_header,ext_tbl),
       "Error loading image from file '%s'", *raw_filename);
     
  cleanup:
    if (cpl_error_get_code() != CPL_ERROR_NONE)
    {
        *raw_filename = NULL;
    }
    
    return cpl_error_get_code();
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Loads a raw frame of a given type
  @param    frames        The input frame set
  @param    raw_filename  (output) Filename of raw frame
  @param    raw_image     (output) The loaded image(s)
  @param    raw_header    (output) The raw image header(s)
  @param    rotated_header (output) Header(s) containing keywords to describe
                           the output rotated frame(s)
  @param    ext_tbl (output) tables to describe the fiber caracteristics
  @param    indx      frame index 
  @return   CPL_ERROR_NONE iff OK

  The function searches the frame set for a frame with TAG=tag.
  Results are returned using the last five parameters (NULL on error).
 */
/*----------------------------------------------------------------------------*/
cpl_error_code
flames_load_frame_index(const cpl_frameset *frames,
          const char **raw_filename,
          cpl_image *raw_image[2],
          uves_propertylist *raw_header[2], 
                  uves_propertylist *rotated_header[2], 
                  cpl_table *ext_tbl[2], 
          const int indx)
{
    const cpl_frame* frm=NULL;
    
    frm = cpl_frameset_get_frame_const(frames,indx);
    *raw_filename=cpl_frame_get_filename(frm);

     /* Load the image */
    check( load_raw_image_fib(*raw_filename,
              CPL_TYPE_DOUBLE,
              false,
              raw_image,
              raw_header,
              rotated_header,ext_tbl),
       "Error loading image from file '%s'", *raw_filename);
     
  cleanup:
    if (cpl_error_get_code() != CPL_ERROR_NONE)
    {
        *raw_filename = NULL;
            frm=NULL;
    }
    
    return cpl_error_get_code();
}






/*----------------------------------------------------------------------------*/
/**
   @brief    Load the ordef image
   @param    frames               The input frame set
   @param    chip_name            CCD chip name
   @param    ordef_filename       (output) Filename of ordef image
   @param    ordef                (output) The ordef image
   @param    mdark_header         (output) FITS header
   @param    chip                 CCD chip
*/
/*----------------------------------------------------------------------------*/

void
flames_load_ordef(const cpl_frameset *frames, const char *chip_name,
                  const char **ordef_filename, cpl_image **ordef,
                  uves_propertylist **ordef_header, enum uves_chip chip)
{
    const char *tags[2];
    int number_of_tags = sizeof(tags) / sizeof(char *);
    int extension;
    int indx;
    const bool flames = true;
    
    *ordef        = NULL;
    *ordef_header = NULL;

    tags[0]   = FLAMES_ORDEF(flames, chip);
    extension = FLAMES_ORDEF_EXTENSION(flames, chip);
    
    check( *ordef_filename = uves_find_frame(frames, tags, number_of_tags, &indx, NULL), 
       "Could not find %s or %s in frame set", tags[0], tags[1]);
    
    /* Load the ordef image */
    check( *ordef = cpl_image_load(*ordef_filename,
                   CPL_TYPE_DOUBLE,           /* Convert to this type */
                   0,                         /* plane number */
                   extension                  /* Extension number */
           ),
       "Could not load master dark from extension %d of file '%s'", 
       extension, *ordef_filename);

    /* Load the header */
    check( *ordef_header = uves_propertylist_load(*ordef_filename,
                         extension),
       "Could not load header from extension %d of file '%s'", 
       extension, *ordef_filename);
    
    check_nomsg( uves_warn_if_chip_names_dont_match(*ordef_header, chip_name, chip) );
    /* FLAMES MIDAS C-code wants the START (CRVAL) to be 1 */
    check_nomsg( flames_reset_crval_to_one(ordef_header));


    /* The DPR keywords were (correctly) removed by cpl_dfs_setup_product_header(),
       But flames_dfs_write_descr() depends on these, therefore add */   
    check_nomsg( uves_pfits_set_dpr_catg(*ordef_header, "MOS"));
    check_nomsg( uves_pfits_set_dpr_type(*ordef_header, "LAMP,ORDERDEF,SimCal"));
    check_nomsg( uves_pfits_set_dpr_catg(*ordef_header, "CALIB"));

    check_nomsg( flames_dfs_write_descr(*ordef_header, chip, true,NULL) );

  cleanup:
    if (cpl_error_get_code() != CPL_ERROR_NONE) 
    {
        *ordef_filename = NULL;
        uves_free_image(ordef);
        uves_free_propertylist(ordef_header);
    }
    return;
}


/*----------------------------------------------------------------------------*/
/**
  @brief    Load a table
  @param    frames    The input frameset
  @param    filename  File containing the table
  @param    extension The table extension
  @param    table     Loaded table
  @param    pheader   Loaded primary header, if non-NULL
  @param    theader   Loaded table header, if non-NULL
  @param    tag       The table TAG

  @return   CPL_ERROR_NONE iff OK

  The function...
 */
/*----------------------------------------------------------------------------*/
void
flames_load_table(const cpl_frameset *frames, 
          const char **filename, 
          cpl_table **table, 
          uves_propertylist **pheader,
          uves_propertylist **theader,
          const int extension, 
          const char* tag)
{
    const char *tags[1];
    int indx;
    
    tags[0] = tag;

    /* Get filename */
    check( *filename = uves_find_frame(frames, tags, 1, &indx, NULL),
       "No line reference table (%s) found in SOF", tag);
    
    /* Load table */
    check( *table = cpl_table_load(*filename,
                   extension,
                       1),         /* Mark identified 
                              invalid values? (1=yes) */
       "Error loading line reference table from extension %d of file '%s'", 
       extension, *filename);

   
    if(uves_erase_invalid_table_rows(*table, NULL) > 0) { 
      uves_msg_warning("Table in extension %d of file '%s' "
                       "contains invalid rows", extension, *filename);
    }

    /* Load headers if requested */
    if (pheader != NULL)
    {
        check( *pheader = uves_propertylist_load(*filename, 0),
           "Could not load primary header of FLAMES table in '%s'", *filename);
    }

    if (theader != NULL)
    {
        check( *theader = uves_propertylist_load(*filename, 1),
           "Could not load header of FLAMES table in '%s'", *filename);
    }

  cleanup:
    if (cpl_error_get_code() != CPL_ERROR_NONE) 
    {
        uves_free_table(table);
        if (pheader != NULL) uves_free_propertylist(pheader);
        if (theader != NULL) uves_free_propertylist(theader);
    }
    return;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Loads a UVES raw image
  @param    filename       Filename of raw frame
  @param    blue           Flag indicating if the raw frame is blue (true) or red (false)
  @param    type           Load the image as this type
  @param    raw_image      (output) The loaded image(s)
  @param    raw_header     (output) The raw image header(s)
  @param    rotated_header (output) Header(s) containing the proper CDELT, CRPIX... 
  @param    ext_tbl (output) Extension table with FIBER mode info. 

  @return   CPL_ERROR_NONE iff OK

  The function loads a raw blue or red image from the specified file.
  Results are returned through the arrays @em raw_image and @em raw_header,
  which must be 2d arrays. If red, array index 0 is REDL and array index 1 is REDU.
  If blue, array index 1 is not used.

  The loaded images are rotated into standard orientation, and pre- and
  overscan areas are removed (see @c uves_crop_and_rotate() ).  

  @note The provided arrays must have size at least two.
 */
/*----------------------------------------------------------------------------*/

static void
load_raw_image_fib(const char *filename, 
           cpl_type type, bool blue, 
           cpl_image *raw_image[2],
           uves_propertylist *raw_header[2], 
           uves_propertylist *rotated_header[2],
           cpl_table* ext_tbl[2])
{
    cpl_image *image = NULL;
    uves_propertylist *primary_header = NULL;
    uves_propertylist *ext_header = NULL;
    int nextensions;
    int plane = 0;   /* Only one plane in UVES raw files */

    /* Initialize parameters */
    raw_image[0] = NULL;
    raw_image[1] = NULL;
    raw_header[0] = NULL;
    raw_header[1] = NULL;
    rotated_header[0] = NULL;
    rotated_header[1] = NULL;
    ext_tbl[0]=NULL;
    ext_tbl[1]=NULL;


    check( nextensions = uves_get_nextensions(filename),
       "Error reading number of extensions of file '%s'", filename);

    uves_msg_low("Raw frame is %s, file '%s' has %d extensions", 
         (blue) ? "blue" : "red", filename, nextensions);
    
    /* If the raw frame is blue, or if it's an old format red frame */
    if (blue || (!blue && nextensions == 0))
    {
        int extension;
        enum uves_chip chip;
        bool new_format = false;

        uves_msg("frame is blue or old format");
        
        assure( nextensions == 0, CPL_ERROR_ILLEGAL_INPUT, 
            "Unrecognized format of file '%s'. No extensions expected. %d found.", 
            filename, nextensions);

        extension = 0;

        check( image = cpl_image_load(filename,
                      CPL_TYPE_DOUBLE,
                      plane,   
                      extension
               ), "Could not load image from extension %d of file '%s' ", 
           extension, filename);

        /* Load the header */
        check( raw_header[0] = uves_propertylist_load(filename,
                             extension),
           "Could not load header from extension %d of file '%s'", 
           extension, filename);

        /* Get blue (or lower red) chip */
        chip = (blue) ? UVES_CHIP_BLUE : UVES_CHIP_REDL;
        check( raw_image[0] = uves_crop_and_rotate(image, raw_header[0], 
                               chip, raw_header[0],
                               new_format, 
                               &rotated_header[0]),
           "Error splitting image");

        check_nomsg( flames_dfs_write_descr(raw_header[0], chip, true,ext_tbl[0]) );

        if (!blue)
        {
            const uves_propertylist *redl_header;
            /* Upper red chip, use again the primary header */
            check( raw_header[1] = uves_propertylist_duplicate(raw_header[0]),
               "Error duplicating FITS header");
            
            /* Get upper red chip */
            chip = UVES_CHIP_REDU;
            redl_header = raw_header[0];
            check( raw_image[1] = uves_crop_and_rotate(image, raw_header[1],
                                   chip, redl_header, 
                                   new_format,
                                   &rotated_header[1]),
               "Error splitting red image");

            check_nomsg( flames_dfs_write_descr(raw_header[1], chip, true,ext_tbl[0]) );
        }
        else
        {
            raw_image[1] = NULL;
            raw_header[1] = NULL;
            rotated_header[1] = NULL;
        }
    }
    else if (blue || (!blue && nextensions == 2))
      {
    enum uves_chip chip;
    int extension;
    bool new_format = false;
    uves_msg_debug("Frame is red, old format, flames-uves");

    assure( nextensions == 2, CPL_ERROR_UNSUPPORTED_MODE,
            "File '%s' (red frame) has %d extensions. 0 or 2 HDUs expected",
            filename, nextensions);
       
    uves_msg_debug("Old red format, flames-uves");
 
        check(ext_tbl[0]=cpl_table_load(filename,1,0),"loading %s ext table1", filename);
        check(ext_tbl[1]=cpl_table_load(filename,2,0),"loading %s ext table2", filename);

    /* Load primary header */
    extension = 0;
    check( primary_header = uves_propertylist_load(filename,
                              extension),
           "Could not load header from extension %d of file '%s'", 
                extension, filename);



        check( image = cpl_image_load(filename,
                      CPL_TYPE_DOUBLE,
                      plane,   
                      extension
               ), "Could not load image from extension %d of file '%s' ", 
           extension, filename);

        /* Load the header */
        check( raw_header[0] = uves_propertylist_load(filename,
                             extension),
           "Could not load header from extension %d of file '%s'", 
           extension, filename);

        /* Get blue (or lower red) chip */
        chip = (blue) ? UVES_CHIP_BLUE : UVES_CHIP_REDL;
            /* Remove pre-, overscan */
        check( raw_image[0] = uves_crop_and_rotate(image, raw_header[0], 
                               chip, raw_header[0],
                               new_format, 
                               &rotated_header[0]),
           "Error splitting image");
        
	//PIPPO       
        check_nomsg( flames_dfs_write_descr(raw_header[0], chip, true,ext_tbl[0]) );

        if (!blue)
        {
            const uves_propertylist *redl_header;

            /* Upper red chip, use again the primary header */
            check( raw_header[1] = uves_propertylist_duplicate(raw_header[0]),
               "Error duplicating FITS header");
            
            /* Get upper red chip */
            chip = UVES_CHIP_REDU;
            redl_header = raw_header[0];
            check( raw_image[1] = uves_crop_and_rotate(image, raw_header[1],
                                   chip, redl_header,
                                   new_format,
                                   &rotated_header[1]),
               "Error splitting red image");

	//PIPPO       
            check_nomsg( flames_dfs_write_descr(raw_header[1], chip, true,ext_tbl[0]) );
        }
        else
        {
            raw_image[1] = NULL;
            raw_header[1] = NULL;
            rotated_header[1] = NULL;
        }



      }
    else
    /* Red, new format. Must have 2 or 4 extensions */
    {
        int extension;
        bool new_format = true;
 
        assure( nextensions == 2 ||
                nextensions == 4, CPL_ERROR_UNSUPPORTED_MODE,
                "File '%s' (red frame) has %d extensions. 0, 2 or 4 HDUs expected",
                filename, nextensions);

	//PIPPO       
        uves_msg("New red format");
        uves_msg_debug("New red format");
 
        /* Load primary header */
        extension = 0;
        check( primary_header = uves_propertylist_load(filename,
                              extension),
           "Could not load header from extension %d of file '%s'", 
           extension, filename);
        
        for (extension = 1; extension <= 2; extension++)
        {
            /* In the FITS file, REDU is stored
               in extension 1, and REDL is stored in
               extension 2 */
            enum uves_chip chip = (extension == 1) ? UVES_CHIP_REDU : UVES_CHIP_REDL;
            
            int indx = uves_chip_get_index(chip);

            /* Load the extension header */
            uves_free_propertylist(&ext_header);
            check( ext_header = uves_propertylist_load(filename,
                                  extension),
               "Could not load header from extension %d of file '%s'", 
               extension, filename);
            
            /* Merge with primary header */
            check( raw_header[indx] = uves_propertylist_duplicate(primary_header),
               "Error cloning primary header");
            

            if (!uves_propertylist_is_empty(ext_header))
            {
                check( uves_propertylist_copy_property_regexp(raw_header[indx], 
                                     ext_header, ".*", 0),
                   "Error merging primary header with extension %d header", 
                   extension);
            }

        }

        if (nextensions == 4) {
            check(ext_tbl[0]=cpl_table_load(filename,3,0),"loading %s ext table1", filename);
            check(ext_tbl[1]=cpl_table_load(filename,4,0),"loading %s ext table2", filename);
        }

        for (extension = 1; extension <= 2; extension++)
        {
            enum uves_chip chip = (extension == 1) ? UVES_CHIP_REDU : UVES_CHIP_REDL;
            
            int indx = uves_chip_get_index(chip);
            int indx_redl = uves_chip_get_index(UVES_CHIP_REDL);

            uves_free_image(&image);
            check( image = cpl_image_load(filename,
                          type,
                          plane,               
                          extension),
               "Could not load image from extension %d of file '%s' ", 
               extension, filename);
            
            /* Remove pre-, overscan */
            check( raw_image[indx] = uves_crop_and_rotate(image, 
                                  raw_header[indx],
                                  chip, raw_header[indx_redl],
                                  new_format,
                                  &rotated_header[indx]),
               "Error splitting red image");

	//PIPPO       
       check_nomsg( flames_dfs_write_descr(raw_header[indx], chip, true,ext_tbl[0]) );
        }
    

    }/* New format */
    
  cleanup:
    uves_free_image(&image);
    uves_free_propertylist(&primary_header);
    uves_free_propertylist(&ext_header);

    if (cpl_error_get_code() != CPL_ERROR_NONE)
    {
        uves_free_image       (&raw_image[0]);
        uves_free_image       (&raw_image[1]);
        uves_free_propertylist(&raw_header[0]);
        uves_free_propertylist(&raw_header[1]);
        uves_free_propertylist(&rotated_header[0]);
        uves_free_propertylist(&rotated_header[1]);
    }
    
    return;
}



/*----------------------------------------------------------------------------*/
/**
  @brief    Write value to HISTORY keywords
  @param    plist        property list to write to
  @param    type         'I' for integer, 'C' for char    
  @param    name         name
  @param    val          value as string, e.g. '5 4 3 23 1' for an integer array

  This function adds 

  HISTORY 'name','I'
  HISTORY value
  HISTORY

  If an entry with value prefix "'name','I'" already exists, it will be updated.
 */
/*----------------------------------------------------------------------------*/
void
flames_dfs_set_history_val(uves_propertylist *header, char type,
                const char *name, const char *val)
{
    char *new_name = NULL;
    cpl_property *existing = NULL;
    cpl_property *next = NULL;
    const long header_size = uves_propertylist_get_size(header);
    int i;

    uves_msg_debug("Searching for %s", name);

    for (i = 0;
     existing == NULL && i < header_size-2; i++)
    {
        cpl_property *p = uves_propertylist_get(header, i);
        const char *pname = cpl_property_get_name(p);
        
        if (strcmp(pname, "HISTORY") == 0)
        {
            const char *pval;
            check( pval = cpl_property_get_string(p),
               "Error reading property value");
            
            /* match the string  "'name','I" (for any type I) */

            if (strlen(pval) >= 1 + strlen(name) + 4 &&
            pval[0] == '\'' && 
                        strncmp(pval+1, name, strlen(name)) == 0 &&
            pval[strlen(name)+1] == '\'')
            {
                            assure( strncmp(pval+strlen(name)+1, "','", 3) == 0 &&
                                    pval[strlen(name)+4] == type,
                                    CPL_ERROR_TYPE_MISMATCH,
                                    "Keyword '%s' has wrong type, '%c' expected",
                                    pval, type);
                            
                /* Remember the next position and stop searching */
                            existing = uves_propertylist_get(header, i+1);
                            next = uves_propertylist_get(header, i+2);

                            assure( strcmp(cpl_property_get_name(next), "HISTORY") == 0,
                                    CPL_ERROR_ILLEGAL_INPUT,
                                    "Missing HISTORY='' termination of keyword '%s'",
                                    name);
            }
                }
        }

    uves_msg_debug("HISTORY %s keyword %sfound", name, (existing == NULL) ? "not " : "");

    assure( strlen("HISTORY ") + strlen(val) <= 80, CPL_ERROR_ILLEGAL_INPUT,
            "String 'HISTORY %s' length (%zu) is more than 80", val, 
            strlen("HISTORY ") + strlen(val));

    if (existing != NULL)
    {
        check( cpl_property_set_string(existing, val),
           "Error updating HISTORY keyword with value '%s'", val);
        
            check( cpl_property_set_string(next, ""),
           "Error updating HISTORY keyword with value ''");
    }
    else
        /* append */
    {
            new_name = uves_sprintf("'%s','%c'", name, type);

        check( uves_propertylist_append_string(header, "HISTORY", new_name),
           "Error writing HISTORY keyword with value '%s'", new_name);

        check( uves_propertylist_append_string(header, "HISTORY", val),
           "Error updating HISTORY keyword with value '%s'", val);
        check( uves_propertylist_append_string(header, "HISTORY", ""),
           "Error updating HISTORY keyword with value ''");
        }

  cleanup:
    cpl_free(new_name);
    return;
}


/*----------------------------------------------------------------------------*/
/**
  @brief    Write descriptors special for FLAMES reduction
  @param    header    to write to
  @param    warn_tech  if true, prints warning when DPR TECH is unknown
  @param    chip      CCD chip
**/
/*----------------------------------------------------------------------------*/
void
flames_dfs_write_descr(uves_propertylist *header, enum uves_chip chip,
                       bool warn_tech, cpl_table* ozpoz)
{
    check( flames_set_header_char_1(header, FLAMES_CHIPCHOICE, uves_chip_tochar(chip)),
       "Error writing chip choice descriptor");

    check( fibremask_fill(header, chip, warn_tech,ozpoz),
       "Error writing fibre mask to raw frame header");

  cleanup:
    return;
}


/*----------------------------------------------------------------------------*/
/**
  @brief    Set fibremask keyword using ozpoz table info
  @param    table    ozpoz table
  @return   fibremask string
**/
/*----------------------------------------------------------------------------*/

void flames_set_fibremask(cpl_table* table, char* fibremask,
				 const int size, const int mode) {

  int f0_bcal = 0;
  int f1_b3 = 0;
  int f2_b135 = 0;
  int f3_b37 = 0;
  int f4_b169 = 0;
  int f5_b69 = 0;
  int f6_b201 = 0;
  int f7_b103 = 0;
  int f8_b235 = 0;

  if (mode ==1) {
    f0_bcal = 1;
  }


  //cpl_table_dump(table,0,9,stdout);
  f1_b3 = cpl_table_and_selected_int(table, "BUTTON", CPL_EQUAL_TO, 3);
  //uves_msg("f1_b3=%d",f1_b3);
  cpl_table_select_all(table);

  f2_b135 = cpl_table_and_selected_int(table, "BUTTON", CPL_EQUAL_TO, 135);
  //uves_msg("f2_b135=%d",f2_b135);
  cpl_table_select_all(table);

  f3_b37 = cpl_table_and_selected_int(table, "BUTTON", CPL_EQUAL_TO, 37);
  //uves_msg("f3_b37=%d",f3_b37);
  cpl_table_select_all(table);

  f4_b169 = cpl_table_and_selected_int(table, "BUTTON", CPL_EQUAL_TO, 169);
  //uves_msg("f4_b169=%d",f4_b169);
  cpl_table_select_all(table);

  f5_b69 = cpl_table_and_selected_int(table, "BUTTON", CPL_EQUAL_TO, 69);
  //uves_msg("f5_b69=%d",f5_b69);
  cpl_table_select_all(table);

  f6_b201 = cpl_table_and_selected_int(table, "BUTTON", CPL_EQUAL_TO, 201);
  //uves_msg("f6_b201=%d",f6_b201);
  cpl_table_select_all(table);

  f7_b103 = cpl_table_and_selected_int(table, "BUTTON", CPL_EQUAL_TO, 103);
  //uves_msg("f7_b103=%d",f7_b103);
  cpl_table_select_all(table);

  f8_b235 = cpl_table_and_selected_int(table, "BUTTON", CPL_EQUAL_TO, 235);
  //uves_msg("f8_b235=%d",f8_b235);
  cpl_table_select_all(table);

  snprintf(fibremask, size, "%d,%d,%d,%d,%d,%d,%d,%d,%d", f0_bcal, f1_b3,
      f2_b135, f3_b37, f4_b169, f5_b69, f6_b201, f7_b103, f8_b235);

  //uves_msg("fibremask=%s string of size %d", fibremask, size);

  return;
}

/*----------------------------------------------------------------------------*/
/**
 @brief    Set fibremask keyword
 @param    header    to write to
 @param    chip      CCD chip
 **/
/*----------------------------------------------------------------------------*/

static void fibremask_fill(uves_propertylist *header, enum uves_chip chip,
    bool warn_tech, cpl_table* ozpoz)

{
  const char * const maxfibres = "MAXFIBRES";
  const char * const fibremask = "FIBREMASK";
  const char *dpr_tech = " ";
  const char *dpr_type = " ";
  int maxf = 0;
  //const char *mask = " ";
  const int size = 40;
  char mask[size];
  int simc = 0;
  int check = 0;
  int wlen = 0;

//if m$existd(in_ima,h_dprtech) .gt. 0 dpr_tech = "{{in_ima},{h_dprtech}}"
//if m$existd(in_ima,h_dprtype) .gt. 0 dpr_type = "{{in_ima},{h_dprtype}}"
//if m$existd(in_ima,h_cwlen({PATHID})) .gt. 0 wlen = {{in_ima},{h_cwlen({PATHID})}}
//if m$existd(in_ima,simcal_id_key) .gt. 0 simc = {{in_ima},{simcal_id_key}}

  if (uves_propertylist_contains(header, UVES_DPR_TECH)) {
    check_nomsg( dpr_tech = uves_pfits_get_dpr_tech(header));
  }

  if (uves_propertylist_contains(header, UVES_DPR_TYPE)) {
    check_nomsg( dpr_type = uves_pfits_get_dpr_type(header));
  }
  if (uves_propertylist_contains(header, UVES_GRATWLEN(chip))) {
    check_nomsg(
        wlen = uves_round_double( uves_pfits_get_gratwlen(header, chip)));
  }
  if (uves_propertylist_contains(header, UVES_OCS_SIMCAL)) {
    check_nomsg( simc = uves_pfits_get_ocs_simcal(header));
  }

//branch wlen 520,580,860 WC_520,WC_580,WC_860
  switch (wlen) {

//WC_520:
//if "{dpr_tech}" .eq. "ECHELLE" then
//   if m$index(dpr_type,"FLAT") .gt. 0 then
//      write/des {in_ima} MAXFIBRES/i/1/1 0 
//         check = 2
//   else if m$index(dpr_type,"LAMP,SFLAT") .gt. 0 then
//      write/des {in_ima} MAXFIBRES/i/1/1 0 
//         check = 2
//   else if m$index(dpr_type,"LAMP,FMTCHK") .gt. 0 then
//         check = 3
//   else
//         check = 1
//   endif
  case 520:
    if (strcmp(dpr_tech, "ECHELLE") == 0) {
      if (strstr(dpr_type, "FLAT") != NULL) {
        check( set_header_int_1(header, maxfibres, 0),
            "Could not write %s keyword", maxfibres);

        check = 2;
      } else if (strstr(dpr_type, "LAMP,SFLAT") != NULL) {
        check( set_header_int_1(header, maxfibres, 0),
            "Could not write %s keyword", maxfibres);
        check = 2;
      } else if (strstr(dpr_type, "LAMP,FMTCHK") != NULL) {
        check = 3;
      } else {
        check = 1;
      }
//else if m$index(dpr_type,"LAMP,FLAT") .gt. 0 then
//   if m$index(dpr_type,"OzPoz") .gt. 0 then
//      if m$index(dpr_type,"ODD") .gt. 0 then
//         maxf = 9
//         mask = "0,1,0,1,0,1,0,0,0"
//         check = 0
//      else if m$index(dpr_type,"EVEN") .gt. 0 then
//         maxf = 9
//         mask = "0,0,1,0,1,0,1,0,0"
//         check = 0
//      else if m$index(dpr_type,"ALL") .gt. 0 then
//         maxf = 9
//         mask = "0,1,1,1,1,1,1,0,0"
//         check = 0
//      else
//        check = 1
//      endif
    } else if (strstr(dpr_type, "LAMP,FLAT") != NULL) {
      if (strstr(dpr_type, "OzPoz") != NULL) {
        if (strstr(dpr_type, "ODD") != NULL) {
          maxf = 9;

          //snprintf(mask,size,"%s","0,1,0,1,0,1,0,0,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,0);
          //uves_msg("computed fibremask='%s'",mask);
          check = 0;
        } else if (strstr(dpr_type, "EVEN") != NULL) {
          maxf = 9;
          //snprintf(mask,size,"%s","0,0,1,0,1,0,1,0,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,0);
          //uves_msg("computed fibremask='%s'",mask);
          check = 0;
        } else if (strstr(dpr_type, "ALL") != NULL) {
          maxf = 9;
          //snprintf(mask,size,"%s","0,1,1,1,1,1,1,0,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,0);
          //uves_msg("computed fibremask='%s'",mask);
          check = 0;
        } else {
          check = 1;
        }
        //   else if m$index(dpr_type,"SimCal") .gt. 0 then
//      if m$index(dpr_type,"ODD") .gt. 0 then
//         maxf = 9
//         mask = "0,1,0,1,0,1,0,0,0"
//         check = 0
//      else if m$index(dpr_type,"EVEN") .gt. 0 then
//         maxf = 9
//         mask = "1,0,1,0,1,0,0,0,0"
//         check = 0
//      else if m$index(dpr_type,"ALL") .gt. 0 then
//         maxf = 9
//         mask = "1,1,1,1,1,1,0,0,0"
//         check = 0
//      else
//        check = 1
//      endif
      } else if (strstr(dpr_type, "SimCal") != NULL) {
        if (strstr(dpr_type, "ODD") != NULL) {
          maxf = 9;
          //snprintf(mask,size,"%s","0,1,0,1,0,1,0,0,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,0);
          //uves_msg("computed fibremask='%s'",mask);
          check = 0;
        } else if (strstr(dpr_type, "EVEN") != NULL) {
          maxf = 9;
          //snprintf(mask,size,"%s","1,0,1,0,1,0,0,0,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,1);
          //uves_msg("computed fibremask='%s'",mask);
          check = 0;
        } else if (strstr(dpr_type, "ALL") != NULL) {
          maxf = 9;
          //snprintf(mask,size,"%s","1,1,1,1,1,1,0,0,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,1);
          //uves_msg("computed fibremask='%s'",mask);
          check = 0;
        } else {
          check = 1;
        }
//   else if m$index(dpr_type,"NASMYTH") .gt. 0 then
//         maxf = 9
//         if simc .eq. 0 then
//            mask = "0,1,1,1,1,1,1,0,0"
//         else
//            mask = "1,1,1,1,1,1,0,0,0"
//         endif
//         check = 0
//   else
//      check = 1
//   endif
      } else if (strstr(dpr_type, "NASMYTH") != NULL) {
        maxf = 9;
        if (simc == 0) {
          //snprintf(mask,size,"%s","0,1,1,1,1,1,1,0,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,0);
          //uves_msg("computed fibremask='%s'",mask);
        } else {
          //snprintf(mask,size,"%s","1,1,1,1,1,1,0,0,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,1);
          //uves_msg("computed fibremask='%s'",mask);
        }
        check = 0;
      } else {
        check = 1;
      }
//else if m$index(dpr_type,"LAMP,WAVE,OzPoz") .gt. 0 then
//         maxf = 9
//         mask = "0,1,1,1,1,1,1,0,0"
//         check = 0
    } else if (strstr(dpr_type, "LAMP,WAVE,OzPoz") != NULL) {
      maxf = 0;
      //snprintf(mask,size,"%s","0,1,1,1,1,1,1,0,0");
      //uves_msg("expected fibremask='%s'",mask);
      flames_set_fibremask(ozpoz, mask, size,0);
      //uves_msg("computed fibremask='%s'",mask);
      check = 0;
    }
//else if m$index(dpr_type,"LAMP,WAVE,SimCal") .gt. 0 then
//         maxf = 9
//         mask = "1,1,1,1,1,1,0,0,0"
//         check = 0
    else if (strstr(dpr_type, "LAMP,WAVE,SimCal") != NULL) {
      maxf = 9;
      //snprintf(mask,size,"%s","1,1,1,1,1,1,0,0,0");
      //uves_msg("expected fibremask='%s'",mask);
      flames_set_fibremask(ozpoz, mask, size,1);
      //uves_msg("computed fibremask='%s'",mask);
      check = 0;
    }
//else if m$index(dpr_type,"OBJECT,OzPoz") .gt. 0  then
//         maxf = 9
//         mask = "0,1,1,1,1,1,1,0,0"
//         check = 0
    else if (strstr(dpr_type, "OBJECT,OzPoz") != NULL) {
      maxf = 9;
      //snprintf(mask,size,"%s","0,1,1,1,1,1,1,0,0");
      //uves_msg("expected fibremask='%s'",mask);
      flames_set_fibremask(ozpoz, mask, size,0);
      //uves_msg("computed fibremask='%s'",mask);
      check = 0;
    }
//else if m$index(dpr_type,"OBJECT,COMBINED") .gt. 0  then
//         maxf = 9
//         if simc .eq. 0 then
//            mask = "0,1,1,1,1,1,1,0,0"
//         else
//            mask = "1,1,1,1,1,1,0,0,0"
//         endif
//         check = 0
    else if (strstr(dpr_type, "OBJECT,COMBINED") != NULL) {
      maxf = 9;
      if (simc == 0) {
        //snprintf(mask,size,"%s","0,1,1,1,1,1,1,0,0");
        //uves_msg("expected fibremask='%s'",mask);
        flames_set_fibremask(ozpoz, mask, size,0);
        //uves_msg("computed fibremask='%s'",mask);
      } else {
        //snprintf(mask,size,"%s","1,1,1,1,1,1,0,0,0");
        //uves_msg("expected fibremask='%s'",mask);
        flames_set_fibremask(ozpoz, mask, size,1);
        //uves_msg("computed fibremask='%s'",mask);
      }
      check = 0;
    }
//else if m$index(dpr_type,"OBJECT,SimCal") .gt. 0 then
//         maxf = 9
//         mask = "1,1,1,1,1,1,0,0,0"
//         check = 0
    else if (strstr(dpr_type, "OBJECT,SimCal") != NULL) {
      maxf = 9;
      //snprintf(mask,size,"%s","1,1,1,1,1,1,0,0,0");
      //uves_msg("expected fibremask='%s'",mask);
      flames_set_fibremask(ozpoz, mask, size,1);
      //uves_msg("computed fibremask='%s'",mask);
      check = 0;
    }
//else if m$index(dpr_type,"LAMP,FMTCHK,OzPoz") .gt. 0 then
//         check = 3
//else if m$index(dpr_type,"LAMP,FMTCHK,SimCal") .gt. 0 then
//         check = 3
//else if m$index(dpr_type,"LAMP,FMTCHK") .gt. 0 then
//         check = 3
    else if (strstr(dpr_type, "LAMP,FMTCHK,OzPoz") != NULL
        || strstr(dpr_type, "LAMP,FMTCHK,SimCal") != NULL
        || strstr(dpr_type, "LAMP,FMTCHK") != NULL) {
      check = 3;
    }
//else if m$index(dpr_type,"LAMP,ORDERDEF,OzPoz") .gt. 0 then
//         maxf = 9
//         mask = "0,0,0,0,1,0,0,0,0"
//         check = 0
    else if (strstr(dpr_type, "LAMP,ORDERDEF,OzPoz") != NULL) {
      maxf = 9;
      snprintf(mask, size, "%s", "0,0,0,0,1,0,0,0,0");
      check = 0;
    }

//else if m$index(dpr_type,"LAMP,ORDERDEF,SimCal") .gt. 0 then
//         maxf = 9
//         mask = "1,0,0,0,0,0,0,0,0"
//         check = 0
//else
//     check = 1
//endif
    else if (strstr(dpr_type, "LAMP,ORDERDEF,SimCal") != NULL) {
      maxf = 9;
      snprintf(mask, size, "%s", "1,0,0,0,0,0,0,0,0");
      check = 0;
    } else {
      check = 1;
    }
//GOTO END
    break;

//WC_580:
//WC_860:
  case 580:
  case 860:
//if "{dpr_tech}" .eq. "ECHELLE" then
//   if m$index(dpr_type,"FLAT") .gt. 0 then
//      write/des {in_ima} MAXFIBRES/i/1/1 0 
//         check = 2
//   else if m$index(dpr_type,"LAMP,SFLAT") .gt. 0 then
//      write/des {in_ima} MAXFIBRES/i/1/1 0 
//         check = 2
//   else if m$index(dpr_type,"LAMP,FMTCHK") .gt. 0 then
//         check = 3
//   else
//         check = 1
//   endif
    if (strcmp(dpr_tech, "ECHELLE") == 0) {
      if (strstr(dpr_type, "FLAT") != NULL) {
        check( set_header_int_1(header, maxfibres, 0),
            "Could not write %s keyword", maxfibres);

        check = 2;
      } else if (strstr(dpr_type, "LAMP,SFLAT") != NULL) {
        check( set_header_int_1(header, maxfibres, 0),
            "Could not write %s keyword", maxfibres);
        check = 2;
      } else if (strstr(dpr_type, "LAMP,FMTCHK") != NULL) {
        check = 3;
      } else {
        check = 1;
      }
//else if m$index(dpr_type,"LAMP,FLAT") .gt. 0 then
//   if m$index(dpr_type,"OzPoz") .gt. 0 then
//      if m$index(dpr_type,"ODD") .gt. 0 then
//         maxf = 9
//         mask = "0,1,0,1,0,1,0,1,0"
//         check = 0
//      else if m$index(dpr_type,"EVEN") .gt. 0 then
//         maxf = 9
//         mask = "0,0,1,0,1,0,1,0,1"
//         check = 0
//      else if m$index(dpr_type,"ALL") .gt. 0 then
//         maxf = 9
//         mask = "0,1,1,1,1,1,1,1,1"
//         check = 0
//      else
//        check = 1
//      endif
    } else if (strstr(dpr_type, "LAMP,FLAT") != NULL) {
      if (strstr(dpr_type, "OzPoz") != NULL) {
        if (strstr(dpr_type, "ODD") != NULL) {
          maxf = 9;
          //snprintf(mask,size,"%s","0,1,0,1,0,1,0,1,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,0);
          //uves_msg("computed fibremask='%s'",mask);
          //mask = "0,1,0,0,0,1,0,1,0";
          check = 0;
        } else if (strstr(dpr_type, "EVEN") != NULL) {
          maxf = 9;
          //snprintf(mask,size,"%s","0,0,1,0,1,0,1,0,1");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,0);
          //uves_msg("computed fibremask='%s'",mask);
          check = 0;
        } else if (strstr(dpr_type, "ALL") != NULL) {
          maxf = 9;
          //snprintf(mask,size,"%s","0,1,1,1,1,1,1,1,1");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,0);
          //uves_msg("computed fibremask='%s'",mask);
          //mask = "0,1,1,0,1,1,1,1,1";
          check = 0;
        } else {
          check = 1;
        }
//   else if m$index(dpr_type,"SimCal") .gt. 0 then
//      if m$index(dpr_type,"ODD") .gt. 0 then
//         maxf = 9
//         mask = "0,1,0,1,0,1,0,1,0"
//         check = 0
//      else if m$index(dpr_type,"EVEN") .gt. 0 then
//         maxf = 9
//         mask = "0,0,1,0,1,0,1,0,0"
//         check = 0
//      else if m$index(dpr_type,"ALL") .gt. 0 then
//         maxf = 9
//         mask = "1,1,1,1,1,1,1,1,0"
//         check = 0
//      else
//        check = 1
//      endif
      } else if (strstr(dpr_type, "SimCal") != NULL) {
        if (strstr(dpr_type, "ODD") != NULL) {
          maxf = 9;
          //snprintf(mask,size,"%s","0,1,0,1,0,1,0,1,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,0);
          //uves_msg("computed fibremask='%s'",mask);
          check = 0;
        } else if (strstr(dpr_type, "EVEN") != NULL) {
          maxf = 9;
          //snprintf(mask,size,"%s","0,0,1,0,1,0,1,0,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,0);
          //uves_msg("computed fibremask='%s'",mask);
          check = 0;
        } else if (strstr(dpr_type, "ALL") != NULL) {
          maxf = 9;
          //snprintf(mask,size,"%s","1,1,1,1,1,1,1,1,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,1);
          //uves_msg("computed fibremask='%s'",mask);
     
          check = 0;
        } else {
          check = 1;
        }
      }
//   else if m$index(dpr_type,"NASMYTH") .gt. 0 then
//         maxf = 9
//         if simc .eq. 0 then
//            mask = "0,1,1,1,1,1,1,1,1"
//         else
//            mask = "1,1,1,1,1,1,1,1,0"
//         endif
//         check = 0
//   else
//      check = 1
//   endif
      else if (strstr(dpr_type, "NASMYTH") != NULL) {
        maxf = 9;
        if (simc == 0) {
          //snprintf(mask,size,"%s","0,1,1,1,1,1,1,1,1");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,0);
          //uves_msg("computed fibremask='%s'",mask);
        } else {
          //snprintf(mask,size,"%s","1,1,1,1,1,1,1,1,0");
          //uves_msg("expected fibremask='%s'",mask);
          flames_set_fibremask(ozpoz, mask, size,1);
          //uves_msg("computed fibremask='%s'",mask);
        }
        check = 0;
      } else {
        check = 1;
      }

//else if m$index(dpr_type,"LAMP,WAVE,OzPoz") .gt. 0 then
//         maxf = 9
//         mask = "0,1,1,1,1,1,1,1,1"
//         check = 0
    } else if (strstr(dpr_type, "LAMP,WAVE,OzPoz") != NULL) {
      maxf = 9;
      //snprintf(mask,size,"%s","0,1,1,1,1,1,1,1,1");
      //uves_msg("expected fibremask='%s'",mask);
      flames_set_fibremask(ozpoz, mask, size,0);
      //uves_msg("computed fibremask='%s'",mask);
      check = 0;
    }
//else if m$index(dpr_type,"OBJECT,OzPoz") .gt. 0  then
//         maxf = 9
//         mask = "0,1,1,1,1,1,1,1,1"
//         check = 0
    else if (strstr(dpr_type, "OBJECT,OzPoz") != NULL) {
      maxf = 9;
      //snprintf(mask,size,"%s","0,1,1,1,1,1,1,1,1");
      //uves_msg("expected fibremask='%s'",mask);
      flames_set_fibremask(ozpoz, mask, size,0);
      //uves_msg("computed fibremask='%s'",mask);
      check = 0;
    }
//else if m$index(dpr_type,"LAMP,WAVE,OzPoz") .gt. 0 then
//         maxf = 9
//         mask = "0,1,1,1,1,1,1,1,1"
//         check = 0
    else if (strstr(dpr_type, "LAMP,WAVE,OzPoz") != NULL) {
      maxf = 9;
      //snprintf(mask,size,"%s","0,1,1,1,1,1,1,1,1");
      //uves_msg("expected fibremask='%s'",mask);
      flames_set_fibremask(ozpoz, mask, size,0);
      //uves_msg("computed fibremask='%s'",mask);
      check = 0;
    }
//else if m$index(dpr_type,"OBJECT,COMBINED") .gt. 0  then
//         maxf = 9
//         if simc .eq. 0 then
//            mask = "0,1,1,1,1,1,1,1,1"
//         else
//            mask = "1,1,1,1,1,1,1,1,0"
//         endif
//         check = 0
    else if (strstr(dpr_type, "OBJECT,COMBINED") != NULL) {
      maxf = 9;
      if (simc == 0) {
        //snprintf(mask,size,"%s","0,1,1,1,1,1,1,1,1");
        //uves_msg("expected fibremask='%s'",mask);
        flames_set_fibremask(ozpoz, mask, size,0);
        //uves_msg("computed fibremask='%s'",mask);
      } else {
        //snprintf(mask,size,"%s","1,1,1,1,1,1,1,1,0");
        //uves_msg("expected fibremask='%s'",mask);
        flames_set_fibremask(ozpoz, mask, size,1);
        //uves_msg("computed fibremask='%s'",mask);
      }
      check = 0;
    }
//else if m$index(dpr_type,"OBJECT,SimCal") .gt. 0 then
//         maxf = 9
//         mask = "1,1,1,1,1,1,1,1,0"
//         check = 0
    else if (strstr(dpr_type, "OBJECT,SimCal") != NULL) {
      maxf = 9;
      //snprintf(mask,size,"%s","1,1,1,1,1,1,1,1,0");
      //uves_msg("expected fibremask='%s'",mask);
      flames_set_fibremask(ozpoz, mask, size,1);

      //uves_msg("computed fibremask='%s'",mask);
      check = 0;
    }
//else if m$index(dpr_type,"LAMP,FMTCHK,OzPoz") .gt. 0 then
//         check = 3
//else if m$index(dpr_type,"LAMP,FMTCHK,SimCal") .gt. 0 then
//         check = 3
//else if m$index(dpr_type,"LAMP,FMTCHK") .gt. 0 then
//         check = 3
    else if (strstr(dpr_type, "LAMP,FMTCHK,OzPoz") != NULL
        || strstr(dpr_type, "LAMP,FMTCHK,SimCal") != NULL
        || strstr(dpr_type, "LAMP,FMTCHK") != NULL) {
      check = 3;
    }
//else if m$index(dpr_type,"LAMP,ORDERDEF,OzPoz") .gt. 0 then
//         maxf = 9
//         mask = "0,0,0,0,1,0,0,0,0"
//         check = 0
    else if (strstr(dpr_type, "LAMP,ORDERDEF,OzPoz") != NULL) {
      maxf = 9;
      snprintf(mask, size, "%s", "0,0,0,0,1,0,0,0,0");
      check = 0;
    }
//else if m$index(dpr_type,"LAMP,ORDERDEF,SimCal") .gt. 0 then
//         maxf = 9
//         mask = "1,0,0,0,0,0,0,0,0"
//         check = 0
//else
//     check = 1
//endif
    else if (strstr(dpr_type, "LAMP,ORDERDEF,SimCal") != NULL) {
      maxf = 9;
      snprintf(mask, size, "%s", "1,0,0,0,0,0,0,0,0");
      check = 0;
    } else {
      check = 1;
    }
    break;
  default:
    uves_msg_warning("Unrecognized (non-standard) wavelength: %d", wlen);
    break;
  }
//END:

//if check .eq. 0 then
//write/desc {in_ima} FIBREMASK/i/1/9 {mask}
//WRITE/DESC {in_ima} MAXFIBRES/i/1/1 {maxf}
  if (check == 0) {
    check(
        set_header_int_9(header, fibremask, mask[0*2] - '0', mask[1*2] - '0', mask[2*2] - '0', mask[3*2] - '0', mask[4*2] - '0', mask[5*2] - '0', mask[6*2] - '0', mask[7*2] - '0', mask[8*2] - '0'),
        "Could not write %s keyword", maxfibres);

    check( set_header_int_1(header, maxfibres, maxf),
        "Could not write %s keyword", maxfibres);
  } else if (check == 3) {
//else if check .eq. 3 then
//   mess/out {DRS_MES_LEV} {pid} "Type {dpr_type} catg {dpr_catg} tech {dpr_tech} known"
//   mess/out {DRS_MES_LEV} {pid} "Do not require FIBREMASK & MAXFIBRES descriptors "
    uves_msg("Type %s tech %s is known and "
    "does not require FIBREMASK & MAXFIBRES descriptors", dpr_tech, dpr_type);
  } else if (check == 2) {
//else if check .eq. 2 then
//   mess/out {DRS_MES_LEV} {pid} "Type {dpr_type} catg {dpr_catg} tech {dpr_tech} known"
//   mess/out {DRS_MES_LEV} {pid} "require MAXFIBRES only descriptor "
    uves_msg("Type %s tech %s is known and "
    "requires FIBREMASK & MAXFIBRES descriptors", dpr_tech, dpr_type);
  }
//else
  else {
//   mess/out 1 {pid} "Type {dpr_type} catg {dpr_catg} tech {dpr_tech} unknown!"
    if (warn_tech) {
      uves_msg_warning("Type '%s' tech '%s' is unknown!", dpr_type, dpr_tech);
    }

    check( set_header_int_1(header, maxfibres, maxf),
        "Could not write %s keyword", maxfibres);

//endif
//set/format
//return 0
  }

  cleanup: return;
}

/*---------------------------------------------------------------------------*/
/**
  @brief    Set extension to fits if bdf
  @param    filename    to check for extension
  @return   outname     newly allocated filename with corrected extension
**/
/*--------------------------------------------------------------------------*/
char *
flames_fix_estention(const char* filename)
{
  if (strlen(filename) > 4 &&
      strcmp(filename + strlen(filename) - 4, ".bdf") == 0) {
      
      int n = strlen(filename);
      char *outname = cpl_malloc((n + 2)*sizeof(char));

      strcpy(outname, filename);
      outname[n - 3] = 'f';
      outname[n - 2] = 'i';
      outname[n - 1] = 't';
      outname[n - 0] = 's';
      outname[n + 1] = '\0';
      return outname;
  }
  else {
      return cpl_strdup(filename);
  }
}

/*

int
flames_clas_drs_prod(const char* tag, 
                     cpl_frameset* inp,
                     cpl_frameset** frames,
                     cpl_parameters* parameters,
                     const char* recipe_id,
                     const char* starttime)

{

  cpl_frames* frm=NULL;
  const char* filename=NULL;
  frm=cpl_frameset_get_frame(inp,tag);
  filename=cpl_frame_get_filename(frm);
  
  check( flames_frameset_insert(
				*frames,
				CPL_FRAME_GROUP_PRODUCT,
				CPL_FRAME_TYPE_IMAGE,
				CPL_FRAME_LEVEL_INTERMEDIATE,
				product_filename,
				tag,
				header,
				parameters,
				recipe_id,
				PACKAGE "/" PACKAGE_VERSION,
				NULL, starttime, false, UVES_ALL_STATS),
	 "Could not add frame %s (%s) to frameset",
	 product_filename,tag);
                
  uves_msg("Frame %s (%s) added to frameset",
	   it, product_filename, tag);
                

  return 0;

}
                    
*/
/*---------------------------------------------------------------------------*/
/**
  @brief    Create FLAMES pipeline product
  @param    frames       @see uves_frameset_insert
  @param    group        @see uves_frameset_insert
  @param    type         @see uves_frameset_insert
  @param    level        @see uves_frameset_insert
  @param    filename     input/output FITS filename
  @param    tag          @see uves_frameset_insert
  @param    raw_header   @see uves_frameset_insert
  @param    parameters   @see uves_frameset_insert
  @param    recipe_id    @see uves_frameset_insert
  @param    pipeline     @see uves_frameset_insert
  @param    qc           @see uves_frameset_insert
  @param    start_time   @see uves_frameset_insert
  @param    dump_paf     @see uves_frameset_insert
  @param    stats_mask   @see uves_frameset_insert

  This function is like uves_frameset_insert() but supports 3d, 4d images
**/
/*--------------------------------------------------------------------------*/

void
flames_frameset_insert(cpl_frameset *frames, 
		       cpl_frame_group group, 
		       cpl_frame_type type, 
		       cpl_frame_level level,
		       const char *filename,
		       const char *tag, 
		       const uves_propertylist *raw_header,
		       const cpl_parameterlist *parameters, 
		       const char *recipe, 
		       const char *pipeline,
		       cpl_table **qc,
		       const char *start_time,
		       bool dump_paf,
		       unsigned stats_mask)
{
    void *buffer;

    cpl_table *table = NULL;
    cpl_image *out_image = NULL;
    uves_propertylist *primary_header = NULL;
    uves_propertylist *extension_header = NULL;

    /*  Pseudocode:

        If image
             Load the image buffer, determine dimension (2d, 3d, 4d)

             Call uves_frameset_insert() to create an empty image with the correct
             header.

             Load the file, write the image data, don't change the header. Save.

        If table
             Load table + headers
             Call uves_frameset_insert()
    */

    if (type == CPL_FRAME_TYPE_IMAGE) {
        int image;
        int dattype;
        int dimension;
        int naxis[4];
        double crpix[4] = {1, 1, 1, 1};
        double crval[4] = {1, 1, 1, 1};
        double cdelt[4] = {1, 1, 1, 1};
        const char *bunit = NULL;
        const char *ctype1 = NULL;
        const char *ctype2 = NULL;
        const char *ctype3 = NULL;
        const char *ctype4 = NULL;

        int size;
        
        /* Get type */
        {
            int info[2];
            assure( 0 == SCFINF(filename, 4, info),
                    CPL_ERROR_ILLEGAL_OUTPUT,
                    "Could not get %s image data type", filename);
            
            dattype = info[1];

            uves_msg_debug("dattype is %d", dattype);

        }
        
        /* Open */
        assure( 0 == SCFOPN(filename, dattype, 0, F_IMA_TYPE, &image),
                CPL_ERROR_ILLEGAL_OUTPUT,
                "Could not open image %s", filename);

        /* Get dimension */
        {
            int maxvals = 4;
            int felem = 1;
            int unit, null;
            
            assure( 0 == SCDRDI(image, "NPIX", felem, maxvals, &dimension, naxis, &unit, &null),
                    CPL_ERROR_ILLEGAL_OUTPUT,
                    "Could not read NAXIS from %s", filename);
            
            uves_msg_debug("Image dimension is %d", dimension);
        }

        /* Load pixel data */
        {
            int actsize;
            cpl_type ctype;
            
            switch (dimension) {
            case 1: size = naxis[0]; break;
            case 2: size = naxis[0] * naxis[1]; break;
            case 3: size = naxis[0] * naxis[1] * naxis[2]; break;
            case 4: size = naxis[0] * naxis[1] * naxis[2] * naxis[3]; break;
            default:
                assure( false, CPL_ERROR_UNSUPPORTED_MODE,
                        "Dimension is %d", dimension);
                break;
            }
            
            ctype = flames_midas_image_dtype_to_cpltype(dattype);
            switch(ctype) {
            case CPL_TYPE_INT:
                buffer = cpl_malloc(sizeof(int)   * size); 
                out_image = cpl_image_wrap_int(size, 1, buffer);
                break;
            case CPL_TYPE_FLOAT: 
                buffer = cpl_malloc(sizeof(float) * size);
                out_image = cpl_image_wrap_float(size, 1, buffer);
                break;
            default:
                assure( false, CPL_ERROR_UNSUPPORTED_MODE,
                        "Type is %s", uves_tostring_cpl_type(type));
                break;
            }
            assure_mem( buffer );

            assure( 0 == SCFGET(image, 1, size, &actsize, buffer),
                    CPL_ERROR_ILLEGAL_OUTPUT,
                    "Could not load image %s data", filename);

            assure( actsize == size, CPL_ERROR_ILLEGAL_OUTPUT,
                    "Tried to read %d pixels from %s, got %d",
                    size, filename, actsize);
            
            assure( 0 == SCFCLO(image), CPL_ERROR_ILLEGAL_OUTPUT,
                    "Could not close file %s", filename);
        }

        /* Create empty file with correct header */
        check( primary_header = uves_propertylist_load(filename, 0),
               "Could not load primary header from %s", filename);
        
        /* Cannot write stats (DATAMIN, DATAMAX, ...) inside uves_frameset_insert(),
           need the image buffer for that
        */


        if (stats_mask != 0) {
            check_nomsg( uves_dfs_write_statistics(out_image, primary_header,
                                                   stats_mask));
        }
        
        if (dimension >= 1 &&
            uves_propertylist_contains(primary_header, "CRPIX1")) {
            crpix[0] = uves_propertylist_get_double(primary_header, "CRPIX1");
        }
        if (dimension >= 2 &&
            uves_propertylist_contains(primary_header, "CRPIX2")) {
            crpix[1] = uves_propertylist_get_double(primary_header, "CRPIX2");
        }
        if (dimension >= 3 &&
            uves_propertylist_contains(primary_header, "CRPIX3")) {
            crpix[2] = uves_propertylist_get_double(primary_header, "CRPIX3");
        }
        if (dimension >= 4 &&
            uves_propertylist_contains(primary_header, "CRPIX4")) {
            crpix[3] = uves_propertylist_get_double(primary_header, "CRPIX4");
        }

        if (dimension >= 1 &&
            uves_propertylist_contains(primary_header, "CRVAL1")) {
            crval[0] = uves_propertylist_get_double(primary_header, "CRVAL1");
        }
        if (dimension >= 2 &&
            uves_propertylist_contains(primary_header, "CRVAL2")) {
            crval[1] = uves_propertylist_get_double(primary_header, "CRVAL2");
        }
        if (dimension >= 3 &&
            uves_propertylist_contains(primary_header, "CRVAL3")) {
            crval[2] = uves_propertylist_get_double(primary_header, "CRVAL3");
        }
        if (dimension >= 4 &&
            uves_propertylist_contains(primary_header, "CRVAL4")) {
            crval[3] = uves_propertylist_get_double(primary_header, "CRVAL4");
        }

        if (dimension >= 1 &&
            uves_propertylist_contains(primary_header, "CDELT1")) {
            cdelt[0] = uves_propertylist_get_double(primary_header, "CDELT1");
        }
        if (dimension >= 2 &&
            uves_propertylist_contains(primary_header, "CDELT2")) {
            cdelt[1] = uves_propertylist_get_double(primary_header, "CDELT2");
        }
        if (dimension >= 3 &&
            uves_propertylist_contains(primary_header, "CDELT3")) {
            cdelt[2] = uves_propertylist_get_double(primary_header, "CDELT3");
        }
        if (dimension >= 4 &&
            uves_propertylist_contains(primary_header, "CDELT4")) {
            cdelt[3] = uves_propertylist_get_double(primary_header, "CDELT4");
        }

        if (dimension >= 1 &&
            uves_propertylist_contains(primary_header, "CTYPE1")) {
            ctype1 = uves_propertylist_get_string(primary_header, "CTYPE1");
        }
        if (dimension >= 2 &&
            uves_propertylist_contains(primary_header, "CTYPE2")) {
            ctype2 = uves_propertylist_get_string(primary_header, "CTYPE2");
        }
        if (dimension >= 3 &&
            uves_propertylist_contains(primary_header, "CTYPE3")) {
            ctype3 = uves_propertylist_get_string(primary_header, "CTYPE3");
        }
        if (dimension >= 4 &&
            uves_propertylist_contains(primary_header, "CTYPE4")) {
            ctype4 = uves_propertylist_get_string(primary_header, "CTYPE4");
        }

        if (uves_propertylist_contains(primary_header, "BUNIT")) {
            bunit = uves_propertylist_get_string(primary_header, "BUNIT");
        }


        {
            int i;
            for (i = 0; i < uves_propertylist_get_size(primary_header); i++) {
                cpl_property *p = uves_propertylist_get(primary_header, i);

                if (strcmp(cpl_property_get_name(p), "HISTORY") == 0) {
                    const char *value = cpl_property_get_string(p);

                    if (strstr(value, "ESO-DESCRIPTORS START")) {
                        cpl_property_set_string(p, "EDS");
                        /* This is to avoid that MIDAS' INTAPE/FITS command
                           warns about the header not being in MIDAS format */
                    }
                }
            }
        }

        check_nomsg( uves_frameset_insert(frames,
                                          NULL,      /* Image */
                                          group,
                                          type,
                                          level,
                                          filename,
                                          tag,
                                          raw_header,
                                          primary_header,
                                          NULL,
                                          parameters,
                                          recipe,
                                          pipeline,
                                          qc,
                                          start_time,
                                          dump_paf,
                                          0));
        


        /* Write pixels data */
        {
            int unit;


            assure( 0 == SCFOPN(filename, dattype, 0, F_IMA_TYPE, &image),
                    CPL_ERROR_ILLEGAL_OUTPUT,
                    "Could not open image %s", filename);

            /* The image should now have NAXIS = 0, overwrite with correct dimension/size */
            assure( 0 == SCDWRI(image, "NPIX", naxis,
                                1, dimension, &unit),
                    CPL_ERROR_ILLEGAL_OUTPUT,
                    "Could not set size of %dd image %s", dimension, filename);

            assure_nomsg( 0 == SCDWRD(image, "CRPIX", crpix, 1, dimension, &unit),
                          CPL_ERROR_ILLEGAL_OUTPUT);
            assure_nomsg( 0 == SCDWRD(image, "CRVAL", crval, 1, dimension, &unit),
                          CPL_ERROR_ILLEGAL_OUTPUT);
            assure_nomsg( 0 == SCDWRD(image, "CDELT", cdelt, 1, dimension, &unit),
                          CPL_ERROR_ILLEGAL_OUTPUT);

            if (bunit == NULL) {
                bunit = "                ";
            }

            assure_nomsg( 0 == SCDWRC(image, "BUNIT", 1, bunit, 1, strlen(bunit)+1, &unit),
                          CPL_ERROR_ILLEGAL_OUTPUT);
            
            if (ctype1 != NULL) {
                assure_nomsg( 0 == SCDWRC(image, "CTYPE1", 1, ctype1, 1, strlen(ctype1)+1, &unit),
                              CPL_ERROR_ILLEGAL_OUTPUT);
            }
            if (ctype2 != NULL) {
                assure_nomsg( 0 == SCDWRC(image, "CTYPE2", 1, ctype2, 1, strlen(ctype2)+1, &unit),
                              CPL_ERROR_ILLEGAL_OUTPUT);
            }
            if (ctype3 != NULL) {
                assure_nomsg( 0 == SCDWRC(image, "CTYPE3", 1, ctype3, 1, strlen(ctype3)+1, &unit),
                              CPL_ERROR_ILLEGAL_OUTPUT);
            }
            if (ctype4 != NULL) {
                assure_nomsg( 0 == SCDWRC(image, "CTYPE4", 1, ctype4, 1, strlen(ctype4)+1, &unit),
                              CPL_ERROR_ILLEGAL_OUTPUT);
            }
            
            assure( 0 == SCFPUT(image, 1, size, buffer), CPL_ERROR_ILLEGAL_OUTPUT,
                    "Could not rewrite image data to %dd image %s", dimension, filename);
            
            assure( 0 == SCFCLO(image), CPL_ERROR_ILLEGAL_OUTPUT,
                    "Could not close file %s", filename);
        }

    }
    else if (type == CPL_FRAME_TYPE_TABLE) {
 

        check( table = cpl_table_load(filename, 1, 1),
               "Could not load table %s", filename);
        check( primary_header = uves_propertylist_load(filename, 0),
               "Could not load primary header from %s", filename);
        check( extension_header = uves_propertylist_load(filename, 1),
               "Could not load 1st extension header from %s", filename);

 
        check_nomsg( uves_frameset_insert(frames,
                                          table,
                                          group,
                                          type,
                                          level,
                                          filename,
                                          tag,
                                          raw_header,
                                          primary_header,
                                          extension_header,
                                          parameters,
                                          recipe,
                                          pipeline,
                                          qc,
                                          start_time,
                                          dump_paf,
                                          stats_mask));
 
 
   }
 

  cleanup:
    uves_free_table(&table);
    uves_free_image(&out_image);
    uves_free_propertylist(&primary_header);
    uves_free_propertylist(&extension_header);
    return;
}


cpl_error_code
flames_clean_tmp_products_ofpos(enum uves_chip chip, const int cubify)
{

  char command[1024];

  //REDU ok
  //  sprintf(command,"rm -f  slitff_*_bound*.fits slitff_*_badpixel*.fits bp_b_set_?_mf???*.fits b_set_?_mf???*.fits *odd*.fits *even*.fits *all*.fits middumm*.fits bkg_*.fits mbias_*.fits ord_gue_*.fits first.fits third.fits flames_create_full_ot.fits rof*.fits sp_red*.fits");
  uves_msg("cip=%d vs %d",chip,UVES_CHIP_REDU);
  if(chip == UVES_CHIP_REDL) {
    uves_msg("cubify=%d",cubify);
    if (cubify==0) {
      sprintf(command,"rm -f bp_ordef_redl.fits ordef_redl.fits b_ordef_redl.fits b_ordef_redl_*.fits odd*.fits even*.fits all*.fits trap_redl.fits b*odd_l*.fits b*even_l*.fits b*all_l*.fits *set?*_redl*.fits odd*_sigma.fits bp_b_set_?_mf???*.fits b_set_?_mf???*.fits middumm*.fits bkg_*.fits mbias_*.fits ord_gue_*.fits first.fits third.fits flames_create_full_ot.fits rofl.fits sp_redl.fits");
    } else {
      sprintf(command,"rm -f bp_ordef_redl.fits ordef_redl.fits b_ordef_redl.fits b_ordef_redl_*.fits first.fits third.fits flames_create_full_ot.fits trap_redl.fits sp_redl.fits rofl.fits bkg_l.fits mbias_redl.fits ord_gue_redl.fits odd*.fits b*odd_l*.fits even*.fits b*even_l*.fits all*.fits b*all_l*.fits middumm*.fits *set?_*redl*.fits b_*set_l_mf???*.fits b_odd_l*.fits b_even_l*.fits b_all_l*.fits fibreff_l_data0?.fits fibreff_l_sigma0?.fits fibreff_l_badpixel0?.fits slitff_l_data0?.fits slitff_l_sigma0?.fits slitff_l_bound0?.fits  slitff_l_badpixel0?.fits slitff_l_bound0?.fits");
    }

  } else {
    if (cubify==0) {
      sprintf(command,"rm -f bp_ordef_redu.fits ordef_redu.fits b_ordef_redu.fits b_ordef_redu_*.fits odd*.fits even*.fits all*.fits trap_redu.fits *odd_u*.fits *even_u*.fits *all_u*.fits xt_*u.fits *set?*_redu*.fits odd*_sigma.fits bp_b_set_?_mf???*.fits b_set_?_mf???*.fits middumm*.fits bkg_*.fits mbias_*.fits ord_gue_*.fits first.fits third.fits flames_create_full_ot.fits rofu.fits sp_redu.fits");
    } else {
      sprintf(command,"rm -f bp_ordef_redu.fits ordef_redu.fits b_ordef_redu.fits b_ordef_redu_*.fits xt_*u.fits first.fits third.fits flames_create_full_ot.fits trap_redu.fits sp_redu.fits rofu.fits bkg_u.fits mbias_redu.fits ord_gue_redu.fits odd*.fits b*odd_u*.fits even*.fits b*even_u*.fits all*.fits b*all_u*.fits middumm*.fits *set?_*redu*.fits b_*set_u_mf???*.fits b_odd_u*.fits b_even_u*.fits b_all_u*.fits fibreff_u_data0?.fits fibreff_u_sigma0?.fits fibreff_u_badpixel0?.fits slitff_u_data0?.fits slitff_u_sigma0?.fits slitff_u_bound0?.fits  slitff_u_badpixel0?.fits slitff_u_bound0?.fits");
    }
  }
  system(command);
  uves_msg("end cleanup");
  return cpl_error_get_code();
}

cpl_error_code
flames_clean_tmp_products_sci(enum uves_chip chip, const int cubify)
{

  char command[1024];

  if(chip == UVES_CHIP_REDL) {
    if (cubify==0) {
      sprintf(command,"rm -f   sp_redl.fits sci_l.fits cor_shape_l.fits m_tbl_redl.fits trap_redl.fits mbias_l.fits ordef_l.fits bkg_l.fits ext?.fits *sci_l*.fits *pack.fits middumm*.fits fibreff_l_data0?.fits fibreff_l_sigma0?.fits fibreff_l_badpixel0?.fits fibreff_l_dtc.fits fibreff_l_sgc.fits fibreff_l_bpc.fits fibreff_l_norm.fits fibreff_l_nsigma.fits fibreff_l_common.fits slitff_l_data0?.fits slitff_l_sigma0?.fits slitff_l_bound0?.fits slitff_l_badpixel0?.fits slitff_l_dtc.fits slitff_l_sgc.fits slitff_l_bpc.fits slitff_l_bnc.fits slitff_l_norm.fits slitff_l_nsigma.fits slitff_l_common.fits mwfxb_*mask.fits fxb_*extco*.fits wfxb_*extco*.fits");
    } else {
      sprintf(command,"rm -f  sp_redl.fits sci_l.fits cor_shape_l.fits m_tbl_redl.fits trap_redl.fits mbias_l.fits ordef_l.fits bkg_l.fits ext?.fits *b_sci_l*.fits middumm*.fits *fxb_l_*0*.fits fibreff_l_data0?.fits fibreff_l_sigma0?.fits fibreff_l_badpixel0?.fits fibreff_l_dtc.fits fibreff_l_sgc.fits fibreff_l_bpc.fits fibreff_l_nsigma.fits fibreff_l_norm.fits fibreff_l_common.fits slitff_l_data0?.fits slitff_l_sigma0?.fits slitff_l_bound0?.fits slitff_l_badpixel0?.fits slitff_l_dtc.fits slitff_l_sgc.fits slitff_l_bpc.fits slitff_l_bnc.fits slitff_l_norm.fits slitff_l_common.fits b_set_l_mf???*.fits *fxb_l_*extco*.fits");
    }
  } else {
    if (cubify==0) {
      sprintf(command,"rm -f   sp_redu.fits sci_u.fits cor_shape_u.fits m_tbl_redu.fits trap_redu.fits mbias_u.fits ordef_u.fits bkg_u.fits ext?.fits *sci_u*.fits *pack.fits middumm*.fits fibreff_u_data0?.fits fibreff_u_sigma0?.fits fibreff_u_badpixel0?.fits fibreff_u_dtc.fits fibreff_u_sgc.fits fibreff_u_bpc.fits fibreff_u_norm.fits fibreff_u_nsigma.fits fibreff_u_common.fits slitff_u_data0?.fits slitff_u_sigma0?.fits slitff_u_bound0?.fits slitff_u_badpixel0?.fits slitff_u_dtc.fits slitff_u_sgc.fits slitff_u_bpc.fits slitff_u_bnc.fits slitff_u_norm.fits slitff_u_nsigma.fits slitff_u_common.fits mwfxb_*mask.fits fxb_*extco*.fits wfxb_*extco*.fits");
    } else {
      sprintf(command,"rm -f  sp_redu.fits sci_u.fits cor_shape_u.fits m_tbl_redu.fits trap_redu.fits mbias_u.fits ordef_u.fits bkg_u.fits ext?.fits *b_sci_u*.fits middumm*.fits *fxb_u_*0*.fits fibreff_u_data0?.fits fibreff_u_sigma0?.fits fibreff_u_badpixel0?.fits fibreff_u_dtc.fits fibreff_u_sgc.fits fibreff_u_bpc.fits fibreff_u_nsigma.fits fibreff_u_norm.fits fibreff_u_common.fits slitff_u_data0?.fits slitff_u_sigma0?.fits slitff_u_bound0?.fits slitff_u_badpixel0?.fits slitff_u_dtc.fits slitff_u_sgc.fits slitff_u_bpc.fits slitff_u_bnc.fits slitff_u_norm.fits slitff_u_common.fits b_set_u_mf???*.fits *fxb_u_*extco*.fits");
    }

  }
  system(command);

  return cpl_error_get_code();
}

/**@}*/
