/*                                                                           *
 *   This file is part of the ESO X-shooter Pipeline                         *
 *   Copyright (C) 2006 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-04-01 18:15:21 $
 * $Revision: 1.113 $
 * $Name: not supported by cvs2svn $
 */

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

/*----------------------------------------------------------------------------
                                Includes
 ----------------------------------------------------------------------------*/
#include <math.h>

#include <xsh_dump.h>
#include <xsh_utils.h>
#include <xsh_error.h>
#include <xsh_msg.h>
#include <xsh_qc_handling.h>
#include <xsh_data_instrument.h>
#include <xsh_pfits.h>
#include <string.h>
#include <cpl.h>
#include <stdbool.h>
/*---------------------------------------------------------------------------*/
/**
 * @defgroup xsh_pfits Tools: FITS header access
 *
 * @defgroup xsh_pfits_general  FITS header general KW access
 * @ingroup xsh_pfits
 *
 */
/*---------------------------------------------------------------------------*/

/**@{*/

/*----------------------------------------------------------------------------
                               Function prototypes
 ----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
                               Function implementation
 ----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/**
  @brief    Find out the template start
  @param    plist       Header to read from
  @return   The requested value, or undefined on error
 */
/*----------------------------------------------------------------------------*/
int xsh_pfits_get_tpl_expno(const cpl_propertylist * plist)
{
    int returnvalue = 0;
    returnvalue=cpl_propertylist_get_int(plist,XSH_TPL_EXPNO);
    return returnvalue;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Find out the template start
  @param    plist       Header to read from
  @return   The requested value, or undefined on error
 */
/*----------------------------------------------------------------------------*/
double xsh_pfits_get_tpl_start(const cpl_propertylist * plist)
{
    double returnvalue = 0;
    returnvalue=cpl_propertylist_get_double(plist,XSH_TPL_START);
    return returnvalue;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Find out the template end
  @param    plist       Header to read from
  @return   The requested value, or undefined on error
 */
/*----------------------------------------------------------------------------*/
double xsh_pfits_get_tpl_end(const cpl_propertylist * plist)
{
    double returnvalue = 0;
    returnvalue=cpl_propertylist_get_double(plist,XSH_TPL_END);
    return returnvalue;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Find out the telescope latitude
  @param    plist       Header to read from
  @return   The requested value, or undefined on error
 */
/*----------------------------------------------------------------------------*/
double xsh_pfits_get_geolat(const cpl_propertylist * plist)
{
    double returnvalue = 0;
    returnvalue=cpl_propertylist_get_double(plist,XSH_GEOLAT);
    return returnvalue;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Find out the telescope longitude
  @param    plist       Header to read from
  @return   The requested value, or undefined on error
 */
/*----------------------------------------------------------------------------*/
double xsh_pfits_get_geolon(const cpl_propertylist * plist)
{
    double returnvalue = 0;
    returnvalue=cpl_propertylist_get_double(plist,XSH_GEOLON);
    return returnvalue;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Find out the observation time
  @param    plist       Header to read from
  @return   The requested value, or undefined on error
 */
/*----------------------------------------------------------------------------*/
double xsh_pfits_get_utc(const cpl_propertylist * plist)
{
    double returnvalue = 0;
    returnvalue=cpl_propertylist_get_double(plist,XSH_UTC);
    return returnvalue;
}



/*---------------------------------------------------------------------------*/
/**
  @brief    find out the number of chopping cycles
  @param    plist   FITS header
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double xsh_pfits_get_pixscale(const cpl_propertylist * plist)
{
  const char* val=NULL;
  val=cpl_propertylist_get_string(plist,"ESO INS OPTI1 NAME");
  return atof(val);
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the value of the CUMOFFSETX keyword in a header
  @param    plist   FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
double xsh_pfits_get_posangle(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"ESO ADA POSANG");
}



/*----------------------------------------------------------------------------*/
/**
  @brief    Find out the modified julian observation date
  @param    plist       Header to read from
  @return   The requested value, or undefined on error
 */
/*----------------------------------------------------------------------------*/
double xsh_pfits_get_mjdobs(const cpl_propertylist * plist)
{
    double returnvalue = 0;
    
    check_msg(xsh_get_property_value(plist, XSH_MJDOBS, 
                                     CPL_TYPE_DOUBLE, &returnvalue),
       "Error reading keyword '%s'", XSH_MJDOBS);
    
  cleanup:
    return returnvalue;
}




/*---------------------------------------------------------------------------*/
/**
  @brief    find out the NAXIS value 
  @param    plist property list to read from
  @return   the requested value
*/
/*---------------------------------------------------------------------------*/

int xsh_pfits_get_naxis (const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_NAXIS, CPL_TYPE_INT);

  cleanup:
    return ret;
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the NAXIS1 value 
  @param    plist property list to read from
  @return   the requested value
*/
/*---------------------------------------------------------------------------*/
int
xsh_pfits_get_naxis1 (const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_NAXIS1, CPL_TYPE_INT);

  cleanup:
    return ret;
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the NAXIS2 value 
  @param    plist property list to read from
  @return   the requested value
*/
/*---------------------------------------------------------------------------*/
int xsh_pfits_get_naxis2 (const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_NAXIS2, CPL_TYPE_INT);

  cleanup:
    return ret;
}
/*---------------------------------------------------------------------------*/
/**
  @brief    find out the NAXIS3 value 
  @param    plist property list to read from
  @return   the requested value
*/
/*---------------------------------------------------------------------------*/
int xsh_pfits_get_naxis3(const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_NAXIS3, CPL_TYPE_INT);

  cleanup:
    return ret;
}

XSH_ARM xsh_pfits_get_arm( const cpl_propertylist * plist)
{
  XSH_ARM ret = XSH_ARM_UNDEFINED;
  const char *arm = "";

  XSH_PFITS_GET( arm, plist, XSH_SEQ_ARM, CPL_TYPE_STRING ) ;
  ret = xsh_arm_get( arm ) ;

 cleanup:
  return ret ;
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the BINX value 
  @param    plist property list to read from
  @return   the requested value
*/
/*---------------------------------------------------------------------------*/
int xsh_pfits_get_binx(const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_WIN_BINX, CPL_TYPE_INT);

  cleanup:
    return ret;
}

/*---------------------------------------------------------------------------*/
/**                                  
  @brief    find out the BINY value 
  @param    plist property list to read from
  @return   the requested value
*/
/*---------------------------------------------------------------------------*/
int xsh_pfits_get_biny(const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_WIN_BINY, CPL_TYPE_INT);

  cleanup:
    return ret;  
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the CHIP NX value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
int xsh_pfits_get_chip_nx (const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_CHIP_NX, CPL_TYPE_INT);

  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the CHIP NY value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
int xsh_pfits_get_chip_ny (const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_CHIP_NY, CPL_TYPE_INT);

  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the OUT NX value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
int xsh_pfits_get_out_nx (const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_OUT_NX, CPL_TYPE_INT);

  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the OUT NY value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
int xsh_pfits_get_out_ny (const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_OUT_NY, CPL_TYPE_INT);

  cleanup:
  return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the OVSCX value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
int xsh_pfits_get_ovscx (const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_OVSCX, CPL_TYPE_INT);

  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the OVSCY value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
int xsh_pfits_get_ovscy (const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_OVSCY, CPL_TYPE_INT);
  
  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the PRSCX value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
int xsh_pfits_get_prscx (const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_PRSCX, CPL_TYPE_INT);

  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the PRSCY value 
  @param    plist       property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
int xsh_pfits_get_prscy (const cpl_propertylist * plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_PRSCY, CPL_TYPE_INT);

  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the RON value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_ron (const cpl_propertylist * plist)
{
  double ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_RON, CPL_TYPE_DOUBLE);

  cleanup:
    return ret;
}



/*--------------------------------------------------------------------------- */
/**
  @brief    find out the LST value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_lst (const cpl_propertylist * plist)
{
  double ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_LST, CPL_TYPE_DOUBLE);

  cleanup:
    return ret;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the TEL AIRM START value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_airm_start (const cpl_propertylist * plist)
{
  double ret = 1. ;

  xsh_get_property_value( plist, XSH_AIRM_START, CPL_TYPE_DOUBLE, &ret ) ;

    return ret;
}
/*--------------------------------------------------------------------------- */
/**
  @brief    find out the mean airmass value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_airm_mean (const cpl_propertylist * plist)
{
  double airmass_start=0;
  double airmass_end=0;
 airmass_start = xsh_pfits_get_airm_start(plist);
 airmass_end = xsh_pfits_get_airm_end(plist);
        
 return 0.5*(airmass_start+airmass_end);
}
/*--------------------------------------------------------------------------- */
/**
  @brief    find out the TEL AIRM END value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_airm_end (const cpl_propertylist * plist)
{
  double ret = 1. ;

  xsh_get_property_value( plist, XSH_AIRM_END, CPL_TYPE_DOUBLE, &ret ) ;

    return ret;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the TEL AMBI START value (Seeing)
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_seeing_start (const cpl_propertylist * plist)
{
  double ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_SEEING_START, CPL_TYPE_DOUBLE);

  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the TEL AMBI END value (Seeing)
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_seeing_end (const cpl_propertylist * plist)
{
  double ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_SEEING_END, CPL_TYPE_DOUBLE);

  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the INS OPTIx NAME value (the width of the slit)
  
  @param    plist property list to read from
  @param    instrument uinstrument arm setting
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_slit_width (const cpl_propertylist * plist,
				 xsh_instrument * instrument )
{
  char * str =NULL;
  double ret = 0;
  XSH_ARM arm ;

  arm = xsh_instrument_get_arm( instrument ) ;

  switch ( arm ) {
  case XSH_ARM_UVB:
  case XSH_ARM_AGC:
    XSH_PFITS_GET( str, plist, XSH_SLIT_UVB, CPL_TYPE_STRING);
    break ;
  case XSH_ARM_VIS:
    XSH_PFITS_GET( str, plist, XSH_SLIT_VIS, CPL_TYPE_STRING);
    break ;
  case XSH_ARM_NIR:
    XSH_PFITS_GET( str, plist, XSH_SLIT_NIR, CPL_TYPE_STRING);
    break ;
  case XSH_ARM_UNDEFINED:
    xsh_msg("arm undefined");
    break;
  }
  sscanf( str, "%64lf", &ret ) ;
 cleanup:
    return ret;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the INS OPTIx NAME value (the width of the slit)
  
  @param    plist property list to read from
  @param    instrument uinstrument arm setting
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
char* xsh_pfits_get_slit_value (const cpl_propertylist * plist,
				 xsh_instrument * instrument )
{
  char * str =NULL;
  XSH_ARM arm ;

  arm = xsh_instrument_get_arm( instrument ) ;

  switch ( arm ) {
  case XSH_ARM_UVB:
  case XSH_ARM_AGC:
    XSH_PFITS_GET( str, plist, XSH_SLIT_UVB, CPL_TYPE_STRING);
    break ;
  case XSH_ARM_VIS:
    XSH_PFITS_GET( str, plist, XSH_SLIT_VIS, CPL_TYPE_STRING);
    break ;
  case XSH_ARM_NIR:
    XSH_PFITS_GET( str, plist, XSH_SLIT_NIR, CPL_TYPE_STRING);
    break ;
  case XSH_ARM_UNDEFINED:
    xsh_msg("arm undefined");
    break;
  }
  
 cleanup:
    return str;
}



/*--------------------------------------------------------------------------- */
/**
  @brief    find out the TELESCOP value (telescope ID)
  
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
const char* xsh_pfits_get_telescop (const cpl_propertylist * plist)
{
  const char * tel =NULL;
  check_msg (xsh_get_property_value(plist, XSH_TELESCOP, CPL_TYPE_STRING, &tel),
	     "Error reading keyword '%s'", XSH_TELESCOP);

 cleanup:
    return tel;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the GAIN value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_gain (const cpl_propertylist * plist)
{
  double ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_DET_GAIN, CPL_TYPE_DOUBLE);

  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the CONAD value 
  @param    plist property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_conad (const cpl_propertylist * plist)
{
  double ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_CONAD, CPL_TYPE_DOUBLE);

  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief
    find out the DATANCOM value
  @param plist
    The property list to read from
  @return
    The requested value
*/
/*--------------------------------------------------------------------------- */
int xsh_pfits_get_datancom( const cpl_propertylist *plist)
{
  int ret = 0;

  XSH_PFITS_GET( ret, plist, XSH_DATANCOM, CPL_TYPE_INT);

  cleanup:
    return ret;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the ESO DET OUT1 GAIN value 
  @param    plist       property list to read from
  @return   the requested value
*/
/*--------------------------------------------------------------------------- */
double
xsh_pfits_get_det_gain (const cpl_propertylist * plist)
{
  double returnvalue = 0;
  
  check_msg (xsh_get_property_value (plist, XSH_DET_GAIN, CPL_TYPE_DOUBLE,
                                     &returnvalue),
             "Error reading keyword '%s'", XSH_DET_GAIN);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the BIAS LEFT MEDIAN value
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_bias_left_median(cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_BIAS_LEFT_MEDIAN, 
    CPL_TYPE_DOUBLE,&returnvalue),
    "Error reading keyword '%s'", XSH_BIAS_LEFT_MEDIAN);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the BIAS RIGHT MEDIAN value
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_bias_right_median(cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_BIAS_RIGHT_MEDIAN, 
    CPL_TYPE_DOUBLE,&returnvalue),
    "Error reading keyword '%s'", XSH_BIAS_RIGHT_MEDIAN);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the BIAS UP MEDIAN value
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_bias_up_median(cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_BIAS_UP_MEDIAN,
    CPL_TYPE_DOUBLE,&returnvalue),
    "Error reading keyword '%s'", XSH_BIAS_UP_MEDIAN);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the BIAS DOWN MEDIAN value
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_bias_down_median(cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_BIAS_DOWN_MEDIAN,
    CPL_TYPE_DOUBLE,&returnvalue),
    "Error reading keyword '%s'", XSH_BIAS_DOWN_MEDIAN);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the BIAS LEFT STDEV value
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */

double xsh_pfits_get_bias_left_stdev(cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_BIAS_LEFT_STDEV, 
    CPL_TYPE_DOUBLE,&returnvalue),
    "Error reading keyword '%s'", XSH_BIAS_LEFT_STDEV);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the BIAS RIGHT STDEV value
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_bias_right_stdev(cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_BIAS_RIGHT_STDEV, 
    CPL_TYPE_DOUBLE,&returnvalue),
    "Error reading keyword '%s'", XSH_BIAS_RIGHT_STDEV);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the BIAS UP STDEV value
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */

double xsh_pfits_get_bias_up_stdev(cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_BIAS_UP_STDEV,
    CPL_TYPE_DOUBLE,&returnvalue),
    "Error reading keyword '%s'", XSH_BIAS_UP_STDEV);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the BIAS DOWN STDEV value
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_bias_down_stdev(cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_BIAS_DOWN_STDEV,
    CPL_TYPE_DOUBLE,&returnvalue),
    "Error reading keyword '%s'", XSH_BIAS_DOWN_STDEV);

cleanup:
  return returnvalue;
}

/**
   @brief    Force a frame PRO.CATG to a given value
   @param    fname frame filename
   @param    tag   frame tag

   @return   0 if no error is detected,-1 else
*/
cpl_error_code
xsh_frame_force_pro_catg(const char* fname, 
                         const char* tag) {


  cpl_propertylist* plist=NULL;
  int naxis=0;
  int update=0;
  const char* current_tag=NULL;
  cpl_table* tab=NULL;
  cpl_image* ima=NULL;
  cpl_imagelist* iml=NULL;
 


  check(plist=cpl_propertylist_load(fname,0));
  check(naxis=xsh_pfits_get_naxis(plist));
  if(cpl_propertylist_has(plist,XSH_PCATG)) {

    check(current_tag=cpl_propertylist_get_string(plist,XSH_PCATG));
    if(strcmp(current_tag,tag)!= 0) {
      check(cpl_propertylist_set_string(plist,XSH_PCATG,tag)) ;
      update=1;
    }

  } else {
    check(cpl_propertylist_append_string(plist,XSH_PCATG,tag)) ;
    update=1;
  }

  if(update) {
    check(naxis=xsh_pfits_get_naxis(plist));
    switch (naxis) {
    case 0: 
      check(tab=cpl_table_load(fname,1,0));
      check(cpl_table_save(tab,plist,NULL,fname,CPL_IO_DEFAULT));
      xsh_free_table(&tab);
      break;    
    case 1:
    case 2:
      check(ima=cpl_image_load(fname,CPL_TYPE_FLOAT,0,0));
      check(cpl_image_save(ima,fname,CPL_BPP_IEEE_FLOAT,plist,CPL_IO_DEFAULT));
      xsh_free_image(&ima);
      break;
    case 3:
      check(iml=cpl_imagelist_load(fname,CPL_TYPE_FLOAT,0));
      check(cpl_image_save(ima,fname,CPL_BPP_IEEE_FLOAT,plist,CPL_IO_DEFAULT));
      xsh_free_imagelist(&iml);
      break;
    default:
      xsh_msg_error("naxis=%d not supported",naxis);
    }

  }

 cleanup:
  xsh_free_propertylist(&plist);
  xsh_free_table(&tab);
  xsh_free_image(&ima);
  xsh_free_imagelist(&iml);

  return cpl_error_get_code();

}


/*--------------------------------------------------------------------------- */
/**
  @brief    Write the EXTNAME value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_extname (cpl_propertylist * plist, const char *value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_EXTNAME, value),
	     "Error writing keyword '%s'", XSH_EXTNAME);
cleanup:
  return;
}
/*--------------------------------------------------------------------------- */

void xsh_pfits_set_arm( cpl_propertylist * plist, xsh_instrument* instr)
{

  const char* value = NULL;

  check( value = xsh_instrument_arm_tostring( instr));  
  check_msg (cpl_propertylist_update_string (plist, XSH_SEQ_ARM, value),
    "Error writing keyword '%s'", XSH_SEQ_ARM);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the PCATG value
 *     @param    plist      Property list to write to
 *     @param    value    The value to write
 *        */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_pcatg (cpl_propertylist * plist, const char *value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_PCATG, value),
	     "Error writing keyword '%s'", XSH_PCATG);
cleanup:
  return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the DPR TYPE value
 *     @param    plist      Property list to write to
 *     @param    value    The value to write
 *        */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_dpr_type (cpl_propertylist * plist, const char *value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_DPR_TYPE, value),
	     "Error writing keyword '%s'", XSH_DPR_TYPE);
cleanup:
  return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the DPR CATG value
 *     @param    plist      Property list to write to
 *     @param    value    The value to write
 *        */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_dpr_catg (cpl_propertylist * plist, const char *value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_DPR_CATG, value),
	     "Error writing keyword '%s'", XSH_DPR_CATG);
cleanup:
  return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the DPR TECH value
 *     @param    plist      Property list to write to
 *     @param    value    The value to write
 *        */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_dpr_tech (cpl_propertylist * plist, const char *value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_DPR_TECH, value),
	     "Error writing keyword '%s'", XSH_DPR_TECH);
cleanup:
  return;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    Write the number of saturated pixels value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_nsat(cpl_propertylist * plist, int value)
{
  check_msg (cpl_propertylist_update_double
	     (plist, XSH_QC_NPIXSAT, value),
	     "Error writing keyword '%s'", XSH_QC_NPIXSAT);
  cpl_propertylist_set_comment(plist, XSH_QC_NPIXSAT, XSH_QC_NPIXSAT_C);

cleanup:
  return;
}



/*--------------------------------------------------------------------------- */
/**
  @brief    Write the fraction of saturated pixels value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_frac_sat(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double
	     (plist, XSH_QC_FPIXSAT, value),
	     "Error writing keyword '%s'", XSH_QC_FPIXSAT);
  cpl_propertylist_set_comment(plist, XSH_QC_FPIXSAT, XSH_QC_FPIXSAT_C);
cleanup:
  return;
}



/*--------------------------------------------------------------------------- */
/**
  @brief    Write the total number of saturated pixels value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_total_nsat(cpl_propertylist * plist, int value)
{
  check_msg (cpl_propertylist_update_double
	     (plist, XSH_QC_NPIXSAT_TOT, value),
	     "Error writing keyword '%s'", XSH_QC_NPIXSAT_TOT);
  cpl_propertylist_set_comment(plist, XSH_QC_NPIXSAT_TOT, XSH_QC_NPIXSAT_TOT_C);

cleanup:
  return;
}



/*--------------------------------------------------------------------------- */
/**
  @brief    Write the fraction of saturated pixels value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_total_frac_sat(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double
	     (plist, XSH_QC_FPIXSAT_TOT, value),
	     "Error writing keyword '%s'", XSH_QC_FPIXSAT_TOT);
  cpl_propertylist_set_comment(plist, XSH_QC_FPIXSAT_TOT, XSH_QC_FPIXSAT_TOT_C);
cleanup:
  return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    Write the number of range pixels value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_n_range_pix(cpl_propertylist * plist, int value)
{
  check_msg (cpl_propertylist_update_double
	     (plist, XSH_QC_NPIXRANGE, value),
	     "Error writing keyword '%s'", XSH_QC_NPIXRANGE);
  cpl_propertylist_set_comment(plist, XSH_QC_NPIXRANGE, XSH_QC_NPIXRANGE_C);

cleanup:
  return;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    Write the fraction of range pixels value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_frac_range_pix(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double
	     (plist, XSH_QC_FPIXRANGE, value),
	     "Error writing keyword '%s'", XSH_QC_FPIXRANGE);
  cpl_propertylist_set_comment(plist, XSH_QC_FPIXRANGE, XSH_QC_FPIXRANGE_C);
cleanup:
  return;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    Write the BIAS LEFT MEDIAN value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_bias_left_median (cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double
	     (plist, XSH_BIAS_LEFT_MEDIAN, value),
	     "Error writing keyword '%s'", XSH_BIAS_LEFT_MEDIAN);
cleanup:
  return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    Write the BIAS RIGHT MEDIAN value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_bias_right_median (cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double
	     (plist, XSH_BIAS_RIGHT_MEDIAN, value),
	     "Error writing keyword '%s'", XSH_BIAS_RIGHT_MEDIAN);
cleanup:
  return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    Write the BIAS UP MEDIAN value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_bias_up_median (cpl_propertylist * plist, double value)
{ 
  check_msg (cpl_propertylist_update_double
             (plist, XSH_BIAS_UP_MEDIAN, value),
             "Error writing keyword '%s'", XSH_BIAS_UP_MEDIAN);
cleanup:
  return;
}

/*--------------------------------------------------------------------------- */
/*
  @brief
    Write the DATANCOM value
  @param plist
    The Property list to write to
  @param value
    The value to write
*/
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_datancom (cpl_propertylist * plist, int value)
{ 
  check_msg (cpl_propertylist_update_int
             (plist, XSH_DATANCOM, value),
             "Error writing keyword '%s'", XSH_DATANCOM);
cleanup:
  return;
}



/*--------------------------------------------------------------------------- */
/**
  @brief    Write the BIAS DOWN MEDIAN value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_bias_down_median (cpl_propertylist * plist, double value)
{ 
  check_msg (cpl_propertylist_update_double
             (plist, XSH_BIAS_DOWN_MEDIAN, value),
             "Error writing keyword '%s'", XSH_BIAS_DOWN_MEDIAN);
cleanup:
  return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    Write the BIAS LEFT STDEV value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_bias_left_stdev (cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double
	     (plist, XSH_BIAS_LEFT_STDEV, value), "Error writing keyword '%s'",
	     XSH_BIAS_LEFT_STDEV);
cleanup:
  return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    Write the BIAS RIGHT STDEV value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_bias_right_stdev (cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double
	     (plist, XSH_BIAS_RIGHT_STDEV, value), "Error writing keyword '%s'",
	     XSH_BIAS_RIGHT_STDEV);
cleanup:
  return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    Write the BIAS UP STDEV value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_bias_up_stdev (cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double
             (plist, XSH_BIAS_UP_STDEV, value), "Error writing keyword '%s'",
             XSH_BIAS_UP_STDEV);
cleanup:
  return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    Write the BIAS DOWN STDEV value
  @param    plist      Property list to write to
  @param    value        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_bias_down_stdev (cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double
             (plist, XSH_BIAS_DOWN_STDEV, value), "Error writing keyword '%s'",
             XSH_BIAS_DOWN_STDEV);
cleanup:
  return;
}
/*--------------------------------------------------------------------------- */
/**
  @brief    Write the DIT value
  @param    plist      Property list to write to
  @param    dit        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_dit (cpl_propertylist * plist, double dit)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_DET_DIT, dit),
	     "Error writing keyword '%s'", XSH_DET_DIT);

cleanup:
  return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    Write the NDIT value
  @param    plist      Property list to write to
  @param    dit        The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_ndit (cpl_propertylist * plist, int ndit)
{
  check_msg (cpl_propertylist_update_int (plist, XSH_DET_NDIT, ndit),
	     "Error writing keyword '%s'", XSH_DET_NDIT);

cleanup:
  return;
}
/*--------------------------------------------------------------------------- */
/**
  @brief    find out the DET WIN1 DIT1 value 
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
double
xsh_pfits_get_win1_dit1 (const cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value
	     (plist, XSH_DET_WIN1_DIT1, CPL_TYPE_DOUBLE, &returnvalue),
	     "Error reading keyword '%s'", XSH_DET_WIN1_DIT1);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the DIT value 
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
double
xsh_pfits_get_dit (const cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value
	     (plist, XSH_DET_DIT, CPL_TYPE_DOUBLE, &returnvalue),
	     "Error reading keyword '%s'", XSH_DET_DIT);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the NDIT value 
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
int
xsh_pfits_get_ndit (const cpl_propertylist * plist)
{
  int returnvalue = 0;

  check_msg (xsh_get_property_value
	     (plist, XSH_DET_NDIT, CPL_TYPE_INT, &returnvalue),
	     "Error reading keyword '%s'", XSH_DET_NDIT);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the ESO.RAW1.NAME  
  @param    plist       property list to read from
  @return   pointer to statically allocated character string
 */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_raw1name (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_RAW1_NAME, CPL_TYPE_STRING, &returnvalue),
	     "Error reading keyword '%s'", XSH_RAW1_NAME);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the BUNIT
  @param    plist       property list to read from
  @return   pointer to statically allocated character string
 */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_bunit (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_BUNIT, CPL_TYPE_STRING, &returnvalue),
	     "Error reading keyword '%s'", XSH_BUNIT);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the CUNIT1 
  @param    plist       property list to read from
  @return   pointer to statically allocated character string
 */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_cunit1 (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_CUNIT1, CPL_TYPE_STRING, &returnvalue),
	     "Error reading keyword '%s'", XSH_CUNIT1);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the CUNIT2 
  @param    plist       property list to read from
  @return   pointer to statically allocated character string
 */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_cunit2 (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_CUNIT2, CPL_TYPE_STRING, &returnvalue),
	     "Error reading keyword '%s'", XSH_CUNIT2);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the CUNIT3 
  @param    plist       property list to read from
  @return   pointer to statically allocated character string
 */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_cunit3 (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_CUNIT3, CPL_TYPE_STRING, &returnvalue),
	     "Error reading keyword '%s'", XSH_CUNIT3);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the ESO.RAW1.CATG 
  @param    plist       property list to read from
  @return   pointer to statically allocated character string
 */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_raw1catg (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_RAW1_CATG, CPL_TYPE_STRING, &returnvalue),
	     "Error reading keyword '%s'", XSH_RAW1_CATG);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the ESO.OBS.TARG.NAME  
  @param    plist       property list to read from
  @return   pointer to statically allocated character string
 */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_obs_targ_name (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_OBS_TARG_NAME, CPL_TYPE_STRING, &returnvalue),
	     "Error reading keyword '%s'", XSH_OBS_TARG_NAME);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the arcfile   
  @param    plist       property list to read from
  @return   pointer to statically allocated character string
 */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_arcfile (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_ARCFILE, CPL_TYPE_STRING, &returnvalue),
	     "Error reading keyword '%s'", XSH_ARCFILE);

cleanup:
  return returnvalue;
}
/**
  @brief    find out the Lamp status (ON/OFF)   
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
bool 
xsh_pfits_get_lamp_on_off (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_LAMP_ON_OFF, CPL_TYPE_BOOL, &returnvalue),
	     "Error reading keyword '%s'", XSH_LAMP_ON_OFF);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    find out the pcatg
 *   @param    plist       property list to read from
 *   @return   pointer to statically allocated character string
 *   */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_pcatg (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_PCATG, CPL_TYPE_STRING, &returnvalue),
	     "Error reading keyword '%s'", XSH_PCATG);
cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    find out the DPR TECH
 *   @param    plist       property list to read from
 *   @return   pointer to statically allocated character string
 *   */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_dpr_tech (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
             (plist, XSH_DPR_TECH, CPL_TYPE_STRING, &returnvalue),
             "Error reading keyword '%s'", XSH_DPR_TECH);
cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    find out the DPR TECH
 *   @param    plist       property list to read from
 *   @return   pointer to statically allocated character string
 *   */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_dpr_type (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
             (plist, XSH_DPR_TYPE, CPL_TYPE_STRING, &returnvalue),
             "Error reading keyword '%s'", XSH_DPR_TYPE);
cleanup:
  return returnvalue;
}



/*--------------------------------------------------------------------------- */
/**
 *   @brief    find out the DPR CATG
 *   @param    plist       property list to read from
 *   @return   pointer to statically allocated character string
 *   */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_dpr_catg (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
             (plist, XSH_DPR_CATG, CPL_TYPE_STRING, &returnvalue),
             "Error reading keyword '%s'", XSH_DPR_CATG);
cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    find out the EXTNAME
 *   @param    plist       property list to read from
 *   @return   pointer to statically allocated character string
 *   */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_extname (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
             (plist, XSH_EXTNAME, CPL_TYPE_STRING, &returnvalue),
             "Error reading keyword '%s'", XSH_EXTNAME);
cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the DATE 
  @param    plist       property list to read from
  @return   pointer to statically allocated character string
 */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_date (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_DATE, CPL_TYPE_STRING, &returnvalue),
	     "Error reading keyword '%s'", XSH_DATE);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the DATE 
  @param    plist       property list to read from
  @return   pointer to statically allocated character string
 */
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_date_obs (const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
	     (plist, XSH_DATE_OBS, CPL_TYPE_STRING, &returnvalue),
	     "Error reading keyword '%s'", XSH_DATE_OBS);

cleanup:
  return returnvalue;
}

/**
  @brief    find out the PSZX (size of 1 pixel in Microns) 
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
double
xsh_pfits_get_pszx (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_PSZX, CPL_TYPE_DOUBLE,
				     &returnvalue),
	     "Error reading keyword '%s'", XSH_PSZX);

cleanup:
  return returnvalue;
}

/**
  @brief    find out the PSZY (size of 1 pixel in Microns) 
  @param    plist       property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
double
xsh_pfits_get_pszy (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_PSZY, CPL_TYPE_DOUBLE,
				     &returnvalue),
	     "Error reading keyword '%s'", XSH_PSZY);

cleanup:
  return returnvalue;
}

/**
  @brief    find out the DET CHIP PXSPACE  
  @param    plist property list to read from
  @return   the requested value
 */
/*--------------------------------------------------------------------------- */
double
xsh_pfits_get_det_pxspace(const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_DET_PXSPACE, CPL_TYPE_DOUBLE,
                                     &returnvalue),
             "Error reading keyword '%s'", XSH_DET_PXSPACE);

cleanup:
  return returnvalue;
}



/*--------------------------------------------------------------------------- */
/**
  @brief    find out the FOCU1 POS (UVB prism auto-focus temperature)
  @param    plist       property list to read from
  @return   temp5
 */
/*--------------------------------------------------------------------------- */
int xsh_pfits_get_FOCU1ENC (const cpl_propertylist * plist)
{
  int returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_FOCU1ENC_VAL, CPL_TYPE_INT,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_FOCU1ENC_VAL);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
/**
  @brief    find out the temp5 (VIS prism)
  @param    plist       property list to read from
  @return   temp5
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_temp5 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_TEMP5_VAL, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_TEMP5_VAL);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
/**
  @brief    find out the temp2 (UVB prism)
  @param    plist       property list to read from
  @return   temp5
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_temp2 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_TEMP2_VAL, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_TEMP2_VAL);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
/**
  @brief    find out the temp82 (NIR prisms)
  @param    plist       property list to read from
  @return   temp5
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_temp82 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_TEMP82_VAL, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_TEMP82_VAL);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the crval1 
  @param    plist       property list to read from
  @return   crval1
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_crval1 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CRVAL1, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CRVAL1);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the crval2 
  @param    plist       property list to read from
  @return   crval2
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_crval2 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CRVAL2, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CRVAL2);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the crval3 
  @param    plist       property list to read from
  @return   crval3
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_crval3 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CRVAL3, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CRVAL3);

cleanup:
  return returnvalue;
}


/*-------------------------------------------------------------------------- */
/**
 *   @brief    find out the CRPIX1 value
 *   @param    plist      Property list to write to
 */
/*-------------------------------------------------------------------------- */
double xsh_pfits_get_crpix1(const cpl_propertylist * plist)
{
  double returnvalue = 0.0;
  check_msg (xsh_get_property_value (plist, XSH_CRPIX1, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CRPIX1);

  cleanup:
    return returnvalue;
}

/*-------------------------------------------------------------------------- */
/**
 *   @brief    find out the CRPIX2 value
 *   @param    plist      Property list to write to
 */
/*-------------------------------------------------------------------------- */
double xsh_pfits_get_crpix2(const cpl_propertylist * plist)
{
  double returnvalue = 0.0;
  check_msg (xsh_get_property_value (plist, XSH_CRPIX2, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CRPIX2);

  cleanup:
    return returnvalue;
}

/*-------------------------------------------------------------------------- */
/**
 *   @brief    find out the CRPIX3 value
 *   @param    plist      Property list to write to
 */
/*-------------------------------------------------------------------------- */
double xsh_pfits_get_crpix3(const cpl_propertylist * plist)
{
  double returnvalue = 0.0;
  check_msg (xsh_get_property_value (plist, XSH_CRPIX3, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CRPIX3);

  cleanup:
    return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cd1_1 
  @param    plist       property list to read from
  @return   cd1_1
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cd11 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CD11, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CD11);

cleanup:
  return returnvalue;
}



/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cd1_2 
  @param    plist       property list to read from
  @return   cd1_2
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cd12 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CD12, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CD12);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cd2_1 
  @param    plist       property list to read from
  @return   cd2_1
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cd21 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CD21, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CD21);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cd2_2 
  @param    plist       property list to read from
  @return   cd2_2
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cd22 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CD22, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CD22);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cd1_3 
  @param    plist       property list to read from
  @return   cd1_3
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cd13 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CD13, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CD13);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cd2_3 
  @param    plist       property list to read from
  @return   cd2_3
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cd23 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CD23, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CD23);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cd3_3 
  @param    plist       property list to read from
  @return   cd3_3
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cd33 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CD33, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CD33);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cd3_1 
  @param    plist       property list to read from
  @return   cd3_1
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cd31 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CD31, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CD31);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cd3_2 
  @param    plist       property list to read from
  @return   cd3_2
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cd32 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CD32, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CD32);

cleanup:
  return returnvalue;
}



/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cdelt1 
  @param    plist       property list to read from
  @return   cdelt1
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cdelt1 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CDELT1, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CDELT1);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cdelt2
  @param    plist       property list to read from
  @return   cdelt2
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cdelt2 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CDELT2, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CDELT2);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the cdelt3
  @param    plist       property list to read from
  @return   cdelt3
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cdelt3 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_CDELT3, CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_CDELT3);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the exposure time   
  @param    plist       property list to read from
  @return   Exposure time
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_exptime (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_EXPTIME,CPL_TYPE_DOUBLE,
              &returnvalue),
	     "Error reading keyword '%s'", XSH_EXPTIME);

cleanup:
  return returnvalue;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    find out the user defined exposure time
  @param    plist       property list to read from
  @return   Exposure time
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_det_win1_uit1 (const cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_DET_WIN1_UIT1,CPL_TYPE_DOUBLE,
              &returnvalue),
       "Error reading keyword '%s'", XSH_DET_WIN1_UIT1);

cleanup:
  return returnvalue;
}
/**
  @brief    Write the EXPTIME value
  @param    plist      Property list to write to
  @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void
xsh_pfits_set_exptime (cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_EXPTIME, value),
	     "Error writing keyword '%s'", XSH_EXPTIME);

cleanup:
  return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CD1 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cd1(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CD1, value),
             "Error writing keyword '%s'", XSH_CD1);
  cleanup:
    return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CD1_1 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cd11(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CD11, value),
             "Error writing keyword '%s'", XSH_CD11);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CD1_2 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cd12(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CD12, value),
             "Error writing keyword '%s'", XSH_CD12);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CD2_1 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cd21(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CD21, value),
             "Error writing keyword '%s'", XSH_CD21);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CD2_2 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cd22(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CD22, value),
             "Error writing keyword '%s'", XSH_CD22);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CD1_3 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cd13(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CD13, value),
             "Error writing keyword '%s'", XSH_CD13);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CD2_3 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cd23(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CD23, value),
             "Error writing keyword '%s'", XSH_CD23);
  cleanup:
    return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CD3_3 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cd33(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CD33, value),
             "Error writing keyword '%s'", XSH_CD33);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CD3_2 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cd32(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CD32, value),
             "Error writing keyword '%s'", XSH_CD32);
  cleanup:
    return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CD3_2 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cd31(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CD31, value),
             "Error writing keyword '%s'", XSH_CD31);
  cleanup:
    return;
}



/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CRPIX1 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_crpix1(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CRPIX1, value),
             "Error writing keyword '%s'", XSH_CRPIX1);
  cleanup:
    return;
}



/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CRVAL1 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_crval1(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CRVAL1, value),
             "Error writing keyword '%s'", XSH_CRVAL1);
  cleanup:
    return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CDELT1 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cdelt1(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CDELT1, value),
             "Error writing keyword '%s'", XSH_CDELT1);
  cleanup:
    return;
}



/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CRPIX2 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_crpix2(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CRPIX2, value),
             "Error writing keyword '%s'", XSH_CRPIX2);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CRPIX3 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_crpix3(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CRPIX3, value),
             "Error writing keyword '%s'", XSH_CRPIX3);
  cleanup:
    return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CRVAL2 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_crval2(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CRVAL2, value),
             "Error writing keyword '%s'", XSH_CRVAL2);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CRVAL3 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_crval3(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CRVAL3, value),
             "Error writing keyword '%s'", XSH_CRVAL3);
  cleanup:
    return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CDELT2 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cdelt2(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CDELT2, value),
             "Error writing keyword '%s'", XSH_CDELT2);
  cleanup:
    return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CDELT3 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cdelt3(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_CDELT3, value),
             "Error writing keyword '%s'", XSH_CDELT3);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the BUNIT value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_bunit(cpl_propertylist * plist, const char* value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_BUNIT, value),
             "Error writing keyword '%s'", XSH_BUNIT);
  cleanup:
    return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CUNIT1 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cunit1(cpl_propertylist * plist, const char* value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_CUNIT1, value),
             "Error writing keyword '%s'", XSH_CUNIT1);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CUNIT2 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cunit2(cpl_propertylist * plist, const char* value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_CUNIT2, value),
             "Error writing keyword '%s'", XSH_CUNIT2);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CUNIT1 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_cunit3(cpl_propertylist * plist, const char* value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_CUNIT3, value),
             "Error writing keyword '%s'", XSH_CUNIT3);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CTYPE1 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_ctype1(cpl_propertylist * plist, const char* value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_CTYPE1, value),
             "Error writing keyword '%s'", XSH_CTYPE1);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CTYPE2 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_ctype2(cpl_propertylist * plist, const char* value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_CTYPE2, value),
             "Error writing keyword '%s'", XSH_CTYPE2);
  cleanup:
    return;
}


/*--------------------------------------------------------------------------- */
/**
 *   @brief    Write the CTYPE3 value
 *   @param    plist      Property list to write to
 *   @param    value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_ctype3(cpl_propertylist * plist, const char* value)
{
  check_msg (cpl_propertylist_update_string (plist, XSH_CTYPE3, value),
             "Error writing keyword '%s'", XSH_CTYPE3);
  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the min lambda
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavesol_lambda_min(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_WAVESOL_LAMBDA_MIN,
              value),
             "Error writing keyword '%s'", XSH_WAVESOL_LAMBDA_MIN);

  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the max lambda
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavesol_lambda_max(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_WAVESOL_LAMBDA_MAX, 
              value),
             "Error writing keyword '%s'", XSH_WAVESOL_LAMBDA_MAX);

  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the min order
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavesol_order_min(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_WAVESOL_ORDER_MIN, 
              value),
             "Error writing keyword '%s'", XSH_WAVESOL_ORDER_MIN);

  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the max order
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavesol_order_max(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_WAVESOL_ORDER_MAX, 
              value),
             "Error writing keyword '%s'", XSH_WAVESOL_ORDER_MAX);

  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the min slit
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavesol_slit_min(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_WAVESOL_SLIT_MIN, 
              value),
             "Error writing keyword '%s'", XSH_WAVESOL_SLIT_MIN);

  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the max slit
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavesol_slit_max(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_WAVESOL_SLIT_MAX,
              value),
             "Error writing keyword '%s'", XSH_WAVESOL_SLIT_MAX);

  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the min slit for extraction
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_extract_slit_min(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_EXTRACT_SLIT_MIN, 
              value),
             "Error writing keyword '%s'", XSH_EXTRACT_SLIT_MIN);

  cleanup:
    return;
}



/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the min slit for extraction
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_extract_slit_max(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_EXTRACT_SLIT_MAX, 
              value),
             "Error writing keyword '%s'", XSH_EXTRACT_SLIT_MAX);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the min x
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavesol_x_min(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_WAVESOL_X_MIN, 
              value),
             "Error writing keyword '%s'", XSH_WAVESOL_X_MIN);

  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the max x position
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavesol_x_max(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_WAVESOL_X_MAX,
              value),
             "Error writing keyword '%s'", XSH_WAVESOL_X_MAX);

  cleanup:
    return;
}


/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the min y
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavesol_y_min(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_WAVESOL_Y_MIN,    
              value),
             "Error writing keyword '%s'", XSH_WAVESOL_Y_MIN);

  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    WRITE the max y position
  @param    plist       Property list to write to
  @param    value      The requested value
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavesol_y_max(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_WAVESOL_Y_MAX,
              value),
             "Error writing keyword '%s'", XSH_WAVESOL_Y_MAX);

  cleanup:
    return;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the min lambda
  @param    plist       property list to read from
  @return   The requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_wavesol_lambda_min(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_WAVESOL_LAMBDA_MIN,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_WAVESOL_LAMBDA_MIN);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the wavesol max lambda
  @param    plist       property list to read from
  @return        the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_wavesol_lambda_max(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_WAVESOL_LAMBDA_MAX,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_WAVESOL_LAMBDA_MAX);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the min order
  @param    plist       property list to read from
  @return       the request value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_wavesol_order_min(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_WAVESOL_ORDER_MIN,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_WAVESOL_ORDER_MIN);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the wavesol max order
  @param    plist       property list to read from
  @return         the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_wavesol_order_max(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_WAVESOL_ORDER_MAX,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_WAVESOL_ORDER_MAX);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the min slit
  @param    plist       property list to read from
  @return         the request value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_wavesol_slit_min(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_WAVESOL_SLIT_MIN,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_WAVESOL_SLIT_MIN);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the wavesol max slit
  @param    plist       property list to read from
  @return         the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_wavesol_slit_max(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_WAVESOL_SLIT_MAX,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_WAVESOL_SLIT_MAX);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the extraction min slit
  @param    plist       property list to read from
  @return         the request value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_extract_slit_min(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_EXTRACT_SLIT_MIN,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_EXTRACT_SLIT_MIN);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the extraction min slit
  @param    plist       property list to read from
  @return         the request value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_extract_slit_max(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_EXTRACT_SLIT_MAX,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_EXTRACT_SLIT_MAX);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the min x position
  @param    plist       property list to read from
  @return         the request value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_wavesol_x_min(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_WAVESOL_X_MIN,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_WAVESOL_X_MIN);

cleanup:
  return returnvalue;
}
  
/*--------------------------------------------------------------------------- */
/**
  @brief    find out the wavesol max x position
  @param    plist       property list to read from
  @return         the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_wavesol_x_max(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_WAVESOL_X_MAX,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_WAVESOL_X_MAX);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the min y position
  @param    plist       property list to read from
  @return   double      the request value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_wavesol_y_min(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_WAVESOL_Y_MIN,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_WAVESOL_Y_MIN);

cleanup:
  return returnvalue;
} 

/*--------------------------------------------------------------------------- */
/**
  @brief    find out the wavesol max y position
  @param    plist       property list to read from
  @return   double      the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_wavesol_y_max(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_WAVESOL_Y_MAX,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_WAVESOL_Y_MAX);

cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief
    Find out the WAVESOL TYPE
  @param plist
    The property list to read from
  @return
    The pointer to statically allocated character string
*/
/*--------------------------------------------------------------------------- */
const char *
xsh_pfits_get_wavesoltype( const cpl_propertylist * plist)
{
  const char *returnvalue = "";

  check_msg (xsh_get_property_value
             (plist, XSH_WAVESOLTYPE, CPL_TYPE_STRING, &returnvalue),
             "Error reading keyword '%s'", XSH_WAVESOLTYPE);
cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/**
  @brief
    Write the WAVESOL TYPE value
  @param plist
    The property list to write to
  @param value
    The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavesoltype( cpl_propertylist * plist, const char* value)
{
  XSH_REGDEBUG("writing keyword %s = %s", XSH_WAVESOLTYPE, value);
  check_msg (cpl_propertylist_update_string (plist, XSH_WAVESOLTYPE, value),
             "Error writing keyword '%s'", XSH_WAVESOLTYPE);
  cleanup:
    return;
}

/*----------- RECTIFY Specific KEYWORDS ----------------*/
/**
  @brief    WRITE the  lambda binning
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_rectify_bin_lambda(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_RECTIFY_BIN_LAMBDA,
              value),
             "Error writing keyword '%s'", XSH_RECTIFY_BIN_LAMBDA);

  cleanup:
    return;
}

/**
  @brief    WRITE the  space (slit) binning
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_rectify_bin_space(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_RECTIFY_BIN_SPACE,
              value),
             "Error writing keyword '%s'", XSH_RECTIFY_BIN_SPACE);

  cleanup:
    return;
}

/**
  @brief    WRITE the  lambda min value
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_rectify_lambda_min(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_RECTIFY_LAMBDA_MIN,
              value),
             "Error writing keyword '%s'", XSH_RECTIFY_LAMBDA_MIN);

  cleanup:
    return;
}

/**
  @brief    WRITE the  lambda max value
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_rectify_lambda_max(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_RECTIFY_LAMBDA_MAX,
              value),
             "Error writing keyword '%s'", XSH_RECTIFY_LAMBDA_MAX);

  cleanup:
    return;
}

/**
  @brief    WRITE the  space (slit) min value
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_rectify_space_min(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_RECTIFY_SPACE_MIN,
              value),
             "Error writing keyword '%s'", XSH_RECTIFY_SPACE_MIN);

  cleanup:
    return;
}

/**
  @brief    WRITE the  space (slit) max value
  @param    plist       Property list to write to
  @param   value      The value to write
 */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_rectify_space_max(cpl_propertylist * plist, double value)
{
  check_msg (cpl_propertylist_update_double (plist, XSH_RECTIFY_SPACE_MAX,
              value),
             "Error writing keyword '%s'", XSH_RECTIFY_SPACE_MAX);

  cleanup:
    return;
}

/**
  @brief    find out the rectify lambda binning
  @param    plist       property list to read from
  @return   double      the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_rectify_bin_lambda(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_RECTIFY_BIN_LAMBDA,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_RECTIFY_BIN_LAMBDA);

cleanup:
  return returnvalue;
}

/**
  @brief    find out the rectify space (slit) binning
  @param    plist       property list to read from
  @return   double      the requested value
 */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_rectify_bin_space(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_RECTIFY_BIN_SPACE,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_RECTIFY_BIN_SPACE);

cleanup:
  return returnvalue;
}

/**
  @brief    find out the rectify lambda min
  @param    plist       property list to read from
  @return   double      the requested value
 */
double xsh_pfits_get_rectify_lambda_min(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_RECTIFY_LAMBDA_MIN,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_RECTIFY_LAMBDA_MIN);

cleanup:
  return returnvalue;
}

/**
  @brief    find out the rectify lambda max
  @param    plist       property list to read from
  @return   double      the requested value
 */
double xsh_pfits_get_rectify_lambda_max(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_RECTIFY_LAMBDA_MAX,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_RECTIFY_LAMBDA_MAX);

cleanup:
  return returnvalue;
}

/**
  @brief    find out the rectify space min
  @param    plist       property list to read from
  @return   double      the requested value
 */
double xsh_pfits_get_rectify_space_min(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_RECTIFY_SPACE_MIN,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_RECTIFY_SPACE_MIN);

cleanup:
  return returnvalue;
}

/**
  @brief    find out the rectify SPACE max
  @param    plist       property list to read from
  @return   double      the requested value
 */
double xsh_pfits_get_rectify_space_max(cpl_propertylist * plist)
{
  double returnvalue = 0.0;

  check_msg (xsh_get_property_value (plist, XSH_RECTIFY_SPACE_MAX,
    CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_RECTIFY_SPACE_MAX);

cleanup:
  return returnvalue;
}


/**
  @brief    find out the OBS ID 
  @param    plist       property list to read from
  @return   double      the requested value
 */
int xsh_pfits_get_obs_id(cpl_propertylist * plist)
{
  int returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_OBS_ID,
    CPL_TYPE_INT, &returnvalue),
    "Error reading keyword '%s'", XSH_OBS_ID);

cleanup:
  return returnvalue;
}


/**
  @brief
    Get the number of pinhole
  @param[in] plist
    property list to read from
  @return
    Number of pinhole
 */
int xsh_pfits_get_nb_pinhole( const cpl_propertylist * plist){
  int nb_pinhole=1;
  const char* pinhole = NULL;

  XSH_ASSURE_NOT_NULL( plist);
  check( pinhole = xsh_pfits_get_dpr_tech( plist));

  if ( strcmp(  pinhole, XSH_DPR_TECH_MULTI_PINHOLE) == 0 ){
    nb_pinhole = XSH_NB_PINHOLE;
  }
  else if (strcmp( pinhole, XSH_DPR_TECH_SINGLE_PINHOLE) == 0){
    nb_pinhole = 1;
  }
  else{
    xsh_error_msg( "Undefined pinhole : can't identify DPR keyword %s\n\
      Authorized keyword are ( single %s multi %s )", pinhole, 
      XSH_DPR_TECH_SINGLE_PINHOLE, XSH_DPR_TECH_MULTI_PINHOLE);
  }
  cleanup:
    return nb_pinhole;
}

/**
  @brief
    Get the TEL TARG ALPHA 
  @param[in] plist
    property list to read from
  @return
    right ascension of telescoce FOV centre
 */
double xsh_pfits_get_tel_targ_alpha( const cpl_propertylist * plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_TEL_TARG_ALPHA,
				     CPL_TYPE_DOUBLE, &returnvalue),
	     "Error reading keyword '%s'", XSH_TEL_TARG_ALPHA ) ;

 cleanup:
  return returnvalue;
}

/**
  @brief
    Get the TEL TARG DELTA
  @param[in] plist
    property list to read from
  @return
    declination of telescope centre
 */
double xsh_pfits_get_tel_targ_delta( const cpl_propertylist * plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_TEL_TARG_DELTA,
				     CPL_TYPE_DOUBLE, &returnvalue),
	     "Error reading keyword '%s'", XSH_TEL_TARG_DELTA ) ;

 cleanup:
  return returnvalue;
}

/**
  @brief
    Get the Right Ascension 
  @param[in] plist
    property list to read from
  @return
    right ascension
 */
double xsh_pfits_get_ra( const cpl_propertylist * plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_RA,
				     CPL_TYPE_DOUBLE, &returnvalue),
	     "Error reading keyword '%s'", XSH_RA ) ;

 cleanup:
  return returnvalue;
}


/**
  @brief
    Get the Right Ascension 
  @param[in] plist
    property list to read from
  @return
    right ascension
 */
double xsh_pfits_get_dec( const cpl_propertylist * plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_DEC,
				     CPL_TYPE_DOUBLE, &returnvalue),
	     "Error reading keyword '%s'", XSH_DEC ) ;

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_posang(  const cpl_propertylist *plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_POSANG,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_POSANG) ;

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_ra_reloffset( const cpl_propertylist *plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_RELATIVE_OFFSET_RA,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_NOD_RELATIVE_OFFSET_RA) ;

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_dec_reloffset( const cpl_propertylist *plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_RELATIVE_OFFSET_DEC,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_NOD_RELATIVE_OFFSET_DEC) ;

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

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

double xsh_pfits_get_cumoffsetx( const cpl_propertylist *plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_CUMULATIVE_OFFSETX,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_NOD_CUMULATIVE_OFFSETX) ;

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_cumoffsety( const cpl_propertylist *plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_CUMULATIVE_OFFSETY,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_NOD_CUMULATIVE_OFFSETY) ;

 cleanup:
  return returnvalue;
}

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_ra_cumoffset( const cpl_propertylist *plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_CUMULATIVE_OFFSET_RA,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_NOD_CUMULATIVE_OFFSET_RA) ;

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_dec_cumoffset( const cpl_propertylist *plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_CUMULATIVE_OFFSET_DEC,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_NOD_CUMULATIVE_OFFSET_DEC) ;

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_b_ra_reloffset( const cpl_propertylist *plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_RELATIVE_B_OFFSET_RA,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_NOD_RELATIVE_B_OFFSET_RA) ;

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_b_dec_reloffset( const cpl_propertylist *plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_RELATIVE_B_OFFSET_DEC,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_NOD_RELATIVE_B_OFFSET_DEC) ;

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_b_ra_cumoffset( const cpl_propertylist *plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_CUMULATIVE_B_OFFSET_RA,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_NOD_CUMULATIVE_B_OFFSET_RA) ;

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_b_dec_cumoffset( const cpl_propertylist *plist)
{
  double returnvalue = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_CUMULATIVE_B_OFFSET_DEC,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_NOD_CUMULATIVE_B_OFFSET_DEC);

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_b_ra_reloffset(cpl_propertylist * plist, double value)
{
  check_msg( cpl_propertylist_update_double
    (plist, XSH_NOD_RELATIVE_B_OFFSET_RA, value),
    "Error writing keyword '%s'", XSH_NOD_RELATIVE_B_OFFSET_RA);
  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_b_dec_reloffset(cpl_propertylist * plist, double value)
{
  check_msg( cpl_propertylist_update_double
    (plist, XSH_NOD_RELATIVE_B_OFFSET_DEC, value),
    "Error writing keyword '%s'", XSH_NOD_RELATIVE_B_OFFSET_DEC);
  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */


/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_b_ra_cumoffset(cpl_propertylist * plist, double value)
{
  check_msg( cpl_propertylist_update_double
    (plist, XSH_NOD_CUMULATIVE_B_OFFSET_RA, value),
    "Error writing keyword '%s'", XSH_NOD_CUMULATIVE_B_OFFSET_RA);
  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_b_dec_cumoffset(cpl_propertylist * plist, double value)
{
  check_msg( cpl_propertylist_update_double
    (plist, XSH_NOD_CUMULATIVE_B_OFFSET_DEC, value),
    "Error writing keyword '%s'", XSH_NOD_CUMULATIVE_B_OFFSET_DEC);
  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_slitmap_order_edgup( cpl_propertylist * plist, int absorder, 
  double value)
{
  char name[256];

  sprintf( name, XSH_SLITMAP_ORDER_EDGUP, absorder);

  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_slitmap_order_edglo( cpl_propertylist * plist, int absorder, 
  double value)
{
  char name[256];

  sprintf( name, XSH_SLITMAP_ORDER_EDGLO, absorder);

  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
void xsh_pfits_set_slitmap_order_slicup( cpl_propertylist * plist, int absorder,
  double value)
{
  char name[256];

  sprintf( name, XSH_SLITMAP_ORDER_SLICUP, absorder);

  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
void xsh_pfits_set_slitmap_order_sliclo( cpl_propertylist * plist, int absorder,
  double value)
{
  char name[256];

  sprintf( name, XSH_SLITMAP_ORDER_SLICLO, absorder);

  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_slitmap_order_cen( cpl_propertylist * plist, int absorder, 
  double value)
{
  char name[256];

  sprintf( name, XSH_SLITMAP_ORDER_CEN, absorder);

  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */


/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_slitmap_median_edgup( cpl_propertylist * plist,
  double value)
{
  const char* name = XSH_SLITMAP_MEDIAN_EDGUP;


  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_slitmap_median_edglo( cpl_propertylist * plist,
  double value)
{
  const char* name = XSH_SLITMAP_MEDIAN_EDGLO;


  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_slitmap_median_sliclo( cpl_propertylist * plist,
  double value)
{
  const char* name = XSH_SLITMAP_MEDIAN_SLICLO;


  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_slitmap_median_slicup( cpl_propertylist * plist,
  double value)
{
  const char* name = XSH_SLITMAP_MEDIAN_SLICUP;


  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_slitmap_median_cen( cpl_propertylist * plist,
  double value)
{
  const char* name = XSH_SLITMAP_MEDIAN_CEN;


  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_slitmap_median_edgup(const cpl_propertylist * plist)
{
  double returnvalue = 0.;
  const char *name = XSH_SLITMAP_MEDIAN_EDGUP;

  check_msg( xsh_get_property_value (plist, name,
                                     CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", name);

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_slitmap_median_edglo(const cpl_propertylist * plist)
{
  double returnvalue = 0.;
  const char *name = XSH_SLITMAP_MEDIAN_EDGLO;

  check_msg( xsh_get_property_value (plist, name,
                                     CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", name);

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_slitmap_median_cen(const cpl_propertylist * plist)
{
  double returnvalue = 0.;
  const char *name = XSH_SLITMAP_MEDIAN_CEN;

  check_msg( xsh_get_property_value (plist, name,
                                     CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", name);

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_slitmap_median_slicup(const cpl_propertylist * plist)
{
  double returnvalue = 0.;
  const char *name = XSH_SLITMAP_MEDIAN_SLICUP;

  check_msg( xsh_get_property_value (plist, name,
                                     CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", name);

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_slitmap_median_sliclo(const cpl_propertylist * plist)
{
  double returnvalue = 0.;
  const char *name = XSH_SLITMAP_MEDIAN_SLICLO;

  check_msg( xsh_get_property_value (plist, name,
                                     CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", name);

 cleanup:
  return returnvalue;
}
/*--------------------------------------------------------------------------- */


/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavemap_order_lambda_min( cpl_propertylist * plist, int absorder,
  double value)
{
  char name[256];

  sprintf( name, XSH_WAVEMAP_ORDER_LAMBDA_MIN, absorder);

  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_wavemap_order_lambda_max( cpl_propertylist * plist, int absorder,
  double value)
{
  char name[256];

  sprintf( name, XSH_WAVEMAP_ORDER_LAMBDA_MAX, absorder);

  check_msg( cpl_propertylist_update_double
    (plist, name, value),
    "Error writing keyword '%s'", name);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_shiftifu_lambdaref( cpl_propertylist * plist,
  double value)
{

  check_msg( cpl_propertylist_update_double
    (plist, XSH_SHIFTIFU_WAVEREF, value),
    "Error writing keyword '%s'", XSH_SHIFTIFU_WAVEREF);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_shiftifu_lambdaref( cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_SHIFTIFU_WAVEREF,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_SHIFTIFU_WAVEREF);
  cleanup:
    return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_shiftifu_slitref( cpl_propertylist * plist,
  double value)
{

  check_msg( cpl_propertylist_update_double
    (plist, XSH_SHIFTIFU_SLITREF, value),
    "Error writing keyword '%s'", XSH_SHIFTIFU_SLITREF);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_shiftifu_slitdownref( cpl_propertylist * plist,
  double value)
{

  check_msg( cpl_propertylist_update_double
    (plist, XSH_SHIFTIFU_SLITDOWNREF, value),
    "Error writing keyword '%s'", XSH_SHIFTIFU_SLITDOWNREF);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_shiftifu_slitcenref( cpl_propertylist * plist,
  double value)
{

  check_msg( cpl_propertylist_update_double
    (plist, XSH_SHIFTIFU_SLITCENREF, value),
    "Error writing keyword '%s'", XSH_SHIFTIFU_SLITCENREF);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
void xsh_pfits_set_shiftifu_slitupref( cpl_propertylist * plist,
  double value)
{

  check_msg( cpl_propertylist_update_double
    (plist, XSH_SHIFTIFU_SLITUPREF, value),
    "Error writing keyword '%s'", XSH_SHIFTIFU_SLITUPREF);

  cleanup:
    return;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------- */
double xsh_pfits_get_shiftifu_slitref( cpl_propertylist * plist)
{
  double returnvalue = 0;

  check_msg (xsh_get_property_value (plist, XSH_SHIFTIFU_SLITREF,
                                     CPL_TYPE_DOUBLE, &returnvalue),
             "Error reading keyword '%s'", XSH_SHIFTIFU_SLITREF);
  cleanup:
    return returnvalue;
}
/*--------------------------------------------------------------------------- */

/*--------------------------------------------------------------------------- */
/**
  @brief
    Get the Relative Jitter Offset 
  @param[in] plist
    property list to read from
  @return
    reloffset
 */
double xsh_pfits_get_nod_reloffset( const cpl_propertylist * plist)
{
  double returnvalue = 0. ;
  double dec = 0., ra = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_RELATIVE_OFFSET_DEC,
				     CPL_TYPE_DOUBLE, &dec),
	     "Error reading keyword '%s'", XSH_NOD_RELATIVE_OFFSET_DEC ) ;
  check_msg (xsh_get_property_value (plist, XSH_NOD_RELATIVE_OFFSET_RA,
				     CPL_TYPE_DOUBLE, &ra),
	     "Error reading keyword '%s'", XSH_NOD_RELATIVE_OFFSET_RA ) ;
  returnvalue = sqrt( dec*dec + ra*ra ) ;
  xsh_msg_dbg_high( "dec: %lf, ra: %lf, reloffset: %lf", dec, ra, returnvalue ) ;

 cleanup:
  return returnvalue;
}

/**
  @brief
    Get the Cumulative Jitter Offset 
  @param[in] plist
    property list to read from
  @return
    cumoffset
 */
double xsh_pfits_get_nod_cumoffset( const cpl_propertylist * plist)
{
  double returnvalue = 0 ;
  double dec = 0., ra = 0. ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_CUMULATIVE_OFFSET_DEC,
				     CPL_TYPE_DOUBLE, &dec),
	     "Error reading keyword '%s'", XSH_NOD_CUMULATIVE_OFFSET_DEC ) ;
  check_msg (xsh_get_property_value (plist, XSH_NOD_CUMULATIVE_OFFSET_RA,
				     CPL_TYPE_DOUBLE, &ra),
	     "Error reading keyword '%s'", XSH_NOD_CUMULATIVE_OFFSET_RA ) ;
  returnvalue = sqrt( dec*dec + ra*ra ) ;
  xsh_msg_dbg_high ("dec: %lf, ra: %lf, cumoffset: %lf", dec, ra, returnvalue ) ;

 cleanup:
  return returnvalue;

}

/**
  @brief
    Get the Jitter Box size 
  @param[in] plist
    property list to read from
  @return
    cumoffset
 */
double xsh_pfits_get_nod_jitterwidth( const cpl_propertylist * plist)
{
  double returnvalue = 0 ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_JITTER_BOX,
				     CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_NOD_JITTER_BOX );

 cleanup:
  return returnvalue;

}

/**
  @brief
    Get the Nod Throw value 
  @param[in] plist
    property list to read from
  @return
    nodthrow
 */
double xsh_pfits_get_nodthrow( const cpl_propertylist * plist)
{
  double returnvalue = 0 ;

  check_msg (xsh_get_property_value (plist, XSH_NOD_THROW,
				     CPL_TYPE_DOUBLE, &returnvalue),
    "Error reading keyword '%s'", XSH_NOD_THROW);

 cleanup:
  return returnvalue;

}


/**
@brief set hdu keys 
@param plist input propertylist
@param hduclas1 hdu classification1 value
@param hduclas2 hdu classification2 value
@param hduclas3 hdu classification3 value
@return updated propertylist
*/
static cpl_error_code
xsh_plist_set_extra_common_keys(cpl_propertylist* plist)
{

    cpl_propertylist_append_string(plist,"HDUCLASS", "ESO") ;
    cpl_propertylist_set_comment(plist,"HDUCLASS","hdu classification") ;

    cpl_propertylist_append_string(plist,"HDUDOC", "DICD") ;
    cpl_propertylist_set_comment(plist,"HDUDOC","hdu reference document") ;

    cpl_propertylist_append_string(plist,"HDUVERS", "DICD V6.0") ;
    cpl_propertylist_set_comment(plist,"HDUVERS","hdu reference document version") ;

    return cpl_error_get_code();
}

/**
@brief set hdu keys 
@param plist input propertylist
@param hduclas1 hdu classification1 value
@param hduclas2 hdu classification2 value
@param hduclas3 hdu classification3 value
@param scidata  name of data extension
@param errdata  name of errs extension
@param qualdata name of qual extension
@param type type of extension: 0 data, 1 errs, 2 qual
@return updated propertylist
*/
cpl_error_code
xsh_plist_set_extra_keys(cpl_propertylist* plist,
                         const char* hduclas1,
                         const char* hduclas2,
                         const char* hduclas3,
                         const char* scidata,
                         const char* errdata,
                         const char* qualdata,
                         const int type)
{

    //XSH_ASSURE_NOT_ILLEGAL_MSG(type<3,"type  < 3");
    XSH_ASSURE_NOT_ILLEGAL_MSG(type>=0,"type  > 0");

    xsh_plist_set_extra_common_keys(plist);

    cpl_propertylist_append_string(plist,"HDUCLAS1",hduclas1) ;
    cpl_propertylist_set_comment(plist,"HDUCLAS1","hdu format classification") ;

    cpl_propertylist_append_string(plist,"HDUCLAS2",hduclas2) ;
    cpl_propertylist_set_comment(plist,"HDUCLAS2","hdu type classification") ;

    if(type == 0) {
        if(!cpl_propertylist_has(plist,"EXTNAME")) {
            cpl_propertylist_append_string(plist,"EXTNAME",scidata) ;
            cpl_propertylist_set_comment(plist,"EXTNAME","name of data extension") ;
        }
    }

    if(type!=0) {
        if(!cpl_propertylist_has(plist,"HDUCLAS3")) {
            cpl_propertylist_append_string(plist,"HDUCLAS3",hduclas3) ;
            cpl_propertylist_set_comment(plist,"HDUCLAS3","hdu info classification") ;
        }
        if(!cpl_propertylist_has(plist,"SCIDATA")) {
            cpl_propertylist_append_string(plist,"SCIDATA",scidata) ;
            cpl_propertylist_set_comment(plist,"SCIDATA","name of data extension") ;
        }
    }

    if(type!=1) {
        if(!cpl_propertylist_has(plist,"ERRDATA")) {
            cpl_propertylist_append_string(plist,"ERRDATA",errdata) ;
            cpl_propertylist_set_comment(plist,"ERRDATA","name of errs extension") ;
        }
    }

    if(type!=2) {
        if(!cpl_propertylist_has(plist,"QUALDATA")) {
            cpl_propertylist_append_string(plist,"QUALDATA",qualdata) ;
            cpl_propertylist_set_comment(plist,"QUALDATA","name of qual extension") ;
        }
    }
    cleanup:
    return cpl_error_get_code();
}

cpl_error_code 
xsh_pfits_set_wcs1(cpl_propertylist* header,
                   const double crpix1,
                   const double crval1,
                   const double cdelt1) {

  cpl_propertylist_append_double(header, XSH_CRPIX1, crpix1);
  cpl_propertylist_append_double(header, XSH_CRVAL1, crval1);
  cpl_propertylist_append_double(header, XSH_CDELT1, cdelt1);
  cpl_propertylist_append_string(header, XSH_CTYPE1, "LINEAR");

  return cpl_error_get_code();
}


cpl_error_code
xsh_pfits_set_wcs2(cpl_propertylist* header,
                   const double crpix2,
                   const double crval2,
                   const double cdelt2) {

  cpl_propertylist_append_double(header, XSH_CRPIX2, crpix2);
  cpl_propertylist_append_double(header, XSH_CRVAL2, crval2);
  cpl_propertylist_append_double(header, XSH_CDELT2, cdelt2);
  cpl_propertylist_append_string(header, XSH_CTYPE2, "LINEAR");

  return cpl_error_get_code();
}

cpl_error_code
xsh_pfits_set_wcs3(cpl_propertylist* header,
                   const double crpix3,
                   const double crval3,
                   const double cdelt3) {

  cpl_propertylist_append_double(header, XSH_CRPIX3, crpix3);
  cpl_propertylist_append_double(header, XSH_CRVAL3, crval3);
  cpl_propertylist_append_double(header, XSH_CDELT3, cdelt3);
  cpl_propertylist_append_string(header, XSH_CTYPE3, "LINEAR");

  return cpl_error_get_code();
}
cpl_error_code
xsh_pfits_set_cd_matrix(cpl_propertylist* header,
                        const double cdelt1,
                        const double cdelt2) {

  xsh_pfits_set_cd11(header, cdelt1);
  xsh_pfits_set_cd12(header, 0);
  xsh_pfits_set_cd21(header, 0);
  xsh_pfits_set_cd22(header, cdelt2);

  return cpl_error_get_code();
}



cpl_error_code
xsh_pfits_set_wcs(cpl_propertylist* header, const double crpix1,
    const double crval1, const double cdelt1, const double crpix2,
    const double crval2, const double cdelt2) {

  xsh_pfits_set_wcs1(header, crpix1, crval1, cdelt1);
  xsh_pfits_set_wcs2(header, crpix2, crval2, cdelt2);
  xsh_pfits_set_cd_matrix(header, cdelt1, cdelt2);

  return cpl_error_get_code();
}

static cpl_error_code
xsh_key_bin_mult_by_fct(cpl_propertylist** plist,const char* kname,const int fct)
{

  int value=0;
  if(cpl_propertylist_has(*plist,kname) > 0) {
    xsh_get_property_value(*plist,kname,CPL_TYPE_INT,&value);
    if(value<2) {
      check(cpl_propertylist_set_int(*plist,kname,value*fct));
    }
  } else {
    if(fct>1) {
      cpl_propertylist_append_int(*plist,kname,1);
    }
  }

 cleanup:
  return cpl_error_get_code();
}

static cpl_error_code
xsh_key_scan_div_by_fct(cpl_propertylist** plist,const char* kname,const int fct)
{

  int value=0;
  if(cpl_propertylist_has(*plist,kname) > 0) {
    xsh_get_property_value(*plist,kname,CPL_TYPE_INT,&value);
    if(value<2) {
      check(cpl_propertylist_set_int(*plist,kname,value/fct));
    }
  } else {
    if(value>1) {
      cpl_propertylist_append_int(*plist,kname,1);
    }
  }

 cleanup:
  return cpl_error_get_code();
}


cpl_error_code
xsh_plist_div_by_fct(cpl_propertylist** plist,const int fctx,const int fcty)
{
  xsh_key_bin_mult_by_fct(plist,XSH_WIN_BINX,fctx);
  xsh_key_bin_mult_by_fct(plist,XSH_WIN_BINY,fcty);

  xsh_key_scan_div_by_fct(plist,XSH_PRSCX,fctx);
  xsh_key_scan_div_by_fct(plist,XSH_PRSCY,fcty);
  xsh_key_scan_div_by_fct(plist,XSH_OVSCX,fctx);
  xsh_key_scan_div_by_fct(plist,XSH_OVSCY,fcty);

  return cpl_error_get_code();
}

cpl_error_code
xsh_pfits_combine_headers(cpl_propertylist* header,cpl_frameset* set)
{
  int size=0;
  int i=0;
  int expno_min=999;
  int expno_max=-999;
  int expno_cur=0;
  int i_min=0;
  int i_max=0;
  cpl_propertylist* plist=NULL;
  cpl_propertylist* head_first=NULL;
  cpl_propertylist* head_last=NULL;
  const char* fname=NULL;
  cpl_frame* frame=NULL;

  cpl_error_ensure(header != NULL, CPL_ERROR_NULL_INPUT,
                  return CPL_ERROR_NULL_INPUT, "NULL input header");
  cpl_error_ensure(set != NULL, CPL_ERROR_NULL_INPUT,
                   return CPL_ERROR_NULL_INPUT, "NULL input frameset");

  size=cpl_frameset_get_size(set);
  if(size == 1) {
      return CPL_ERROR_NONE;
  }
  for(i=0;i<size;i++) {
      frame=cpl_frameset_get_frame(set,i);
      fname=cpl_frame_get_filename(frame);
      //xsh_msg("fname=%s",fname);
      //xsh_msg("i_min=%d i_max=%d",i_min,i_max);
      plist=cpl_propertylist_load(fname,0);
      expno_cur=xsh_pfits_get_tpl_expno(plist);

      if(expno_cur < expno_min) {
          expno_min=expno_cur;
          i_min=i;
      }
      if(expno_cur > expno_max) {
          expno_max=expno_cur;
          i_max=i;
      }
      xsh_free_propertylist(&plist);
  }
  //xsh_msg("i_min=%d i_max=%d",i_min,i_max);
  frame=cpl_frameset_get_frame(set,i_min);
  fname=cpl_frame_get_filename(frame);
  //xsh_msg("fname=%s",fname);
  //xsh_msg("init airm start=%g end %g",xsh_pfits_get_airm_start(header),xsh_pfits_get_airm_end(header));
  head_first=cpl_propertylist_load_regexp(fname,0,"START",0);
  cpl_propertylist_copy_property_regexp(header,head_first,"START",0);
  //xsh_msg("first airm start=%g end %g",xsh_pfits_get_airm_start(header),xsh_pfits_get_airm_end(header));

  frame=cpl_frameset_get_frame(set,i_max);
  fname=cpl_frame_get_filename(frame);
  //xsh_msg("fname=%s",fname);

  head_last=cpl_propertylist_load_regexp(fname,0,"END",0);
  cpl_propertylist_copy_property_regexp(header,head_last,"END",0);
  //xsh_msg("last airm start=%g end %g",xsh_pfits_get_airm_start(header),xsh_pfits_get_airm_end(header));

  xsh_free_propertylist(&head_first);
  xsh_free_propertylist(&head_last);
  xsh_free_propertylist(&plist);
 
  return cpl_error_get_code();

}


cpl_error_code
xsh_pfits_combine_two_frames_headers(cpl_frame* first, cpl_frame* second)
{

    int expno_min = 999;

    int expno_cur = 0;
    /*
    int expno_max = -999;
    int size = 0;
    int i = 0;
    int i_min = 0;
    int i_max = 0;
    cpl_frame* frame = NULL;
    */
    cpl_propertylist* plist = NULL;
    cpl_propertylist* head_first = NULL;
    cpl_propertylist* head_last = NULL;
    const char* fname = NULL;


    cpl_error_ensure(first != NULL, CPL_ERROR_NULL_INPUT,
                    return CPL_ERROR_NULL_INPUT, "NULL input header");
    cpl_error_ensure(second != NULL, CPL_ERROR_NULL_INPUT,
                    return CPL_ERROR_NULL_INPUT, "NULL input frameset");

    fname = cpl_frame_get_filename(first);
    plist = cpl_propertylist_load(fname, 0);
    expno_cur = xsh_pfits_get_tpl_expno(plist);
    if (expno_cur < expno_min) {
       head_first = cpl_propertylist_duplicate(plist);
       expno_min=expno_cur;
    }

    xsh_free_propertylist(&plist);
    fname = cpl_frame_get_filename(second);
    plist = cpl_propertylist_load(fname, 0);
    expno_cur = xsh_pfits_get_tpl_expno(plist);
    if (expno_cur < expno_min) {
         xsh_free_propertylist(&head_first);
         head_first = cpl_propertylist_load(cpl_frame_get_filename(second), 0);
         head_last = cpl_propertylist_load(cpl_frame_get_filename(first), 0);
    } else {
        head_last = cpl_propertylist_load(cpl_frame_get_filename(second), 0);
    }
    xsh_free_propertylist(&plist);


    /* we now adjust the final frame FITS header */
    plist = cpl_propertylist_load(cpl_frame_get_filename(first), 0);

    cpl_propertylist_copy_property_regexp(plist,head_first, "START", 0);
    cpl_propertylist_copy_property_regexp(plist,head_last, "END", 0);

    xsh_free_propertylist(&head_first);
    xsh_free_propertylist(&head_last);
    xsh_free_propertylist(&plist);
   
    return cpl_error_get_code();

}

int
xsh_pfits_is_obs(cpl_propertylist* plist)
{
	int res=0;
	//xsh_msg("DPR TYPE: %s",xsh_pfits_get_dpr_catg (plist));
	if ( strcmp( xsh_pfits_get_dpr_catg (plist), "SCIENCE" ) == 0 ) {
		return 1;
	} else if ( strstr(xsh_pfits_get_dpr_type (plist), "STD" ) != NULL) {
		return 1;
	} else {
		return 0;
	}

	return res;
}


int
xsh_pfits_is_flat(cpl_propertylist* plist)
{
	int res=0;
	//xsh_msg("DPR TYPE: %s",xsh_pfits_get_dpr_catg (plist));
	if ( strstr(xsh_pfits_get_dpr_type (plist), "FLAT" ) != NULL) {
		return 1;
	} else {
		return 0;
	}

	return res;
}
/**@}*/

