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

/*
 * $Author: jtaylor $
 * $Date: 2013-09-24 10:46:00 $
 * $Revision: 1.53 $
 * $Name: not supported by cvs2svn $
 */

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

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

#define visir_pfits_get_int(KEY)    irplib_pfits_get_int(self, KEY)
#define visir_pfits_get_string(KEY) irplib_pfits_get_string(self, KEY)


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

#include <string.h>
#include <assert.h>
#include <math.h>
#include <cpl.h>

#include "irplib_pfits.h"

#include "visir_utils.h"
#include "visir_pfits.h"


/*-----------------------------------------------------------------------------
                        Private function prototypes
 -----------------------------------------------------------------------------*/

static const char * visir_pfits_get_slitname(const cpl_propertylist *);
static double visir_pfits_get_slitwidth_raw(const cpl_propertylist *);

/*----------------------------------------------------------------------------*/
/**
 * @defgroup visir_pfits    FITS header protected access
 *
 */
/*----------------------------------------------------------------------------*/

/**@{*/

/*-----------------------------------------------------------------------------
                              Function codes
 -----------------------------------------------------------------------------*/


static inline double
visir_pfits_get_double(const cpl_propertylist * self, const char *key) {
    if (cpl_propertylist_get_type(self, key) == CPL_TYPE_INT) {
        return irplib_pfits_get_int(self, key);
    }
    return irplib_pfits_get_double(self, key);
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The airmass start
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_airmass_start(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO TEL AIRM START");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The airmass end
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_airmass_end(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO TEL AIRM END");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The alpha angle
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_alpha(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO TEL TARG OFFSETALPHA");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The arcfile   
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_arcfile(const cpl_propertylist * self)
{
    return visir_pfits_get_string("ARCFILE");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The chopping direction
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_chopnod_dir(const cpl_propertylist * self)
{
    return visir_pfits_get_string(VISIR_PFITS_STRING_CHOPNOD_DIR);
}


/*----------------------------------------------------------------------------*/
/**
  @brief    The chopping throw
  @param    self       property list to read from
  @return   Chopping throw
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_chop_throw(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, VISIR_PFITS_DOUBLE_CHOP_THROW)) {
        return visir_pfits_get_double(self, VISIR_PFITS_DOUBLE_CHOP_THROW);
    }
    else {
        return visir_pfits_get_double(self, "ESO DET CHOP THROW");
    }
}


/*----------------------------------------------------------------------------*/
/**
  @brief    The chopping frequency
  @param    self       property list to read from
  @return   chopping frequency
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_chop_freq(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, VISIR_PFITS_DOUBLE_CHOP_FREQ)) {
        return visir_pfits_get_double(self, VISIR_PFITS_DOUBLE_CHOP_FREQ);
    }
    else {
        return visir_pfits_get_double(self, "ESO DET CHOP FREQ");
    }
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The chopping status
  @param    self       property list to read from
  @return   chopping status
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_chop_stat(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, VISIR_PFITS_BOOL_CHOP_STATUS)) {
        return cpl_propertylist_get_bool(self, VISIR_PFITS_BOOL_CHOP_STATUS);
    }
    else {
        return cpl_propertylist_get_bool(self, "ESO DET CHOP ST");
    }
}


/*----------------------------------------------------------------------------*/
/**
  @brief    The chopping position angle in rad
  @param    self       property list to read from
  @return   Chopping position angle in rad
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_chop_posang(const cpl_propertylist * self)
{
    if (!cpl_propertylist_has(self, VISIR_PFITS_DOUBLE_CHOP_POSANG)) {
        return 0.;
    }
    return CPL_MATH_RAD_DEG *
        cpl_propertylist_get_double(self, VISIR_PFITS_DOUBLE_CHOP_POSANG);
}


/*----------------------------------------------------------------------------*/
/**
  @brief    The chopping throw in pixels
  @param    self       property list to read from
  @return   Chopping throw in pixels
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_chop_pthrow(const cpl_propertylist * self)
{
    const double throw = visir_pfits_get_chop_throw(self);
    const double pscale = visir_pfits_get_pixscale(self);
    return pscale > 0.0 ? throw / pscale : 0.0;
}


/*----------------------------------------------------------------------------*/
/**
  @brief    The number of chopping cycles
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_chop_ncycles(const cpl_propertylist * self)
{
    return visir_pfits_get_int("ESO DET CHOP NCYCLES");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The adapter position angle in rad
  @param    self       property list to read from
  @return   Chopping position angle in rad
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_ada_posang(const cpl_propertylist * self)
{
    if (!cpl_propertylist_has(self, VISIR_PFITS_DOUBLE_ADA_POSANG)) {
        return 0.;
    }
    return CPL_MATH_RAD_DEG *
        cpl_propertylist_get_double(self, VISIR_PFITS_DOUBLE_ADA_POSANG);
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The cumulative offset in X
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_cumoffsetx(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO SEQ CUMOFFSETX");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The cumulative offset in Y
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_cumoffsety(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO SEQ CUMOFFSETY");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The date of observation 
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_date_obs(const cpl_propertylist * self)
{
    return visir_pfits_get_string("DATE-OBS");
}

/*----------------------------------------------------------------------------*/
/** 
  @brief    The DELTA keyword in a VISIR header
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_delta(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO TEL TARG OFFSETDELTA");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The DEC
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_dec(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "DEC");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The DIT
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_dit(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, VISIR_PFITS_DOUBLE_SEQ1_DIT))
        return visir_pfits_get_double(self, VISIR_PFITS_DOUBLE_SEQ1_DIT);
    return visir_pfits_get_double(self, VISIR_PFITS_DOUBLE_DIT);
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The NAVRG
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_navrg(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, VISIR_PFITS_INT_NAVRG))
        return visir_pfits_get_int(VISIR_PFITS_INT_NAVRG);
    return 1;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The number of the current exposition
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_expno(const cpl_propertylist * self)
{
    return visir_pfits_get_int("ESO TPL EXPNO");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The filter
  @param    self       property list to read from
  @return   pointer to statically allocated character string or NULL
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_filter(const cpl_propertylist * self)
{

    /* Get the instrument mode */
    const char * val   = visir_pfits_get_insmode(self);
    static const char * spec[] = {
        "N_SW_spec",
        "H2S4_spec",
        "ARIII_spec",
        "NEII_2_spec",
        "H2S3_spec",
        "H2S1_spec",
    };

    
    if (val == NULL) return NULL ;

    /* Imaging mode */
    if (!strcmp(val, "IMG"   ))
        return visir_pfits_get_string("ESO INS FILT1 NAME");
    /* Spectro mode */
    if (!strcmp(val, "SPC"   ))
        return visir_pfits_get_string("ESO INS FILT2 NAME");
    /* Spectro imaging mode */
    if (!strcmp(val, "SPCIMG")) {
        const char * filt =  visir_pfits_get_string("ESO INS FILT2 NAME");
        for (size_t i = 0; i < 6; i++) {
            if (strncmp(spec[i], filt, strlen(spec[i]) - 5) == 0) {
                return spec[i];
            }
        }
        return filt;
    }

    cpl_ensure(0, CPL_ERROR_UNSUPPORTED_MODE, NULL);

}

/*----------------------------------------------------------------------------*/
/**
  @brief    The focus
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_focus(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO TEL FOCU LEN");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The exposure time
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_exptime(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "EXPTIME");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The frame type
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_frame_type(const cpl_propertylist * self)
{
    return visir_pfits_get_string("ESO DET FRAM TYPE");
}


/*----------------------------------------------------------------------------*/
/**
  @brief    The detector name
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_det_name(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, "ESO DET NAME")) {
        return visir_pfits_get_string("ESO DET NAME");
    }
    return NULL;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The name of grating 1
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_grat1_name(const cpl_propertylist * self)
{
    return visir_pfits_get_string("ESO INS GRAT1 NAME");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The mode
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_insmode(const cpl_propertylist * self)
{
    const char * mode = visir_pfits_get_string("ESO INS MODE");
    return mode ? mode : "(none)";
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The instrument
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_instrument(const cpl_propertylist * self)
{
    return visir_pfits_get_string("INSTRUME");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The MJD-OBS
  @param    self       property list to read from
  @return   the requested value 
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_mjdobs(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "MJD-OBS");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The mode name
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_mode(const cpl_propertylist * self)
{
    return visir_pfits_get_string("ESO DET MODE NAME");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The INS.MONOC1.POS
  @param    self       property list to read from
  @return   the requested value 
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_monoc_pos(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO INS MONOC1 POS");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The NDIT keyword
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_ndit(const cpl_propertylist * self)
{   
    return visir_pfits_get_int("ESO DET NDIT");
}
/*----------------------------------------------------------------------------*/
/**
  @brief    The NAXIS1 key
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_naxis1(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, "ZNAXIS1"))
        return visir_pfits_get_int("ZNAXIS1");
    else
        return visir_pfits_get_int("NAXIS1");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The NAXIS2 key
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_naxis2(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, "ZNAXIS2"))
        return visir_pfits_get_int("ZNAXIS2");
    else
        return visir_pfits_get_int("NAXIS2");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The NAXIS3 key
  @param    self       property list to read from
  @return   the requested value
 */ 
/*----------------------------------------------------------------------------*/
int visir_pfits_get_naxis3(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, "ZNAXIS3"))
        return visir_pfits_get_int("ZNAXIS3");
    else
        return visir_pfits_get_int("NAXIS3");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The WIN NX key
  @param    self       property list to read from
  @return   the requested value or -1 if not present
 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_win_nx(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, "ESO DET WIN NX")) {;
        return visir_pfits_get_int("ESO DET WIN NX");
    }
    else if (cpl_propertylist_has(self, "ESO DET1 WIN NX")) {;
        return visir_pfits_get_int("ESO DET1 WIN NX");
    }
    else if (cpl_propertylist_has(self, "ESO DET ACQ1 WIN NX")) {;
        return visir_pfits_get_int("ESO DET ACQ1 WIN NX");
    }
    return -1;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The WIN NY key
  @param    self       property list to read from
  @return   the requested value or -1 if not present
 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_win_ny(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, "ESO DET WIN NY")) {;
        return visir_pfits_get_int("ESO DET WIN NY");
    }
    else if (cpl_propertylist_has(self, "ESO DET1 WIN NY")) {;
        return visir_pfits_get_int("ESO DET1 WIN NY");
    }
    else if (cpl_propertylist_has(self, "ESO DET ACQ1 WIN NY")) {;
        return visir_pfits_get_int("ESO DET ACQ1 WIN NY");
    }
    return -1;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The WIN STRX key
  @param    self       property list to read from
  @return   the requested value or -1 if not present
 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_start_x(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, "ESO DET WIN STRX")) {;
        return visir_pfits_get_int("ESO DET WIN STRX");
    }
    else if (cpl_propertylist_has(self, "ESO DET1 WIN STRX")) {;
        return visir_pfits_get_int("ESO DET1 WIN STRX");
    }
    else if (cpl_propertylist_has(self, "ESO DET ACQ1 WIN STRX")) {;
        return visir_pfits_get_int("ESO DET ACQ1 WIN STRX");
    }
    return -1;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The WIN STRY key
  @param    self       property list to read from
  @return   the requested value or -1 if not present
 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_start_y(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, "ESO DET WIN STRY")) {;
        return visir_pfits_get_int("ESO DET WIN STRY");
    }
    else if (cpl_propertylist_has(self, "ESO DET1 WIN STRY")) {;
        return visir_pfits_get_int("ESO DET1 WIN STRY");
    }
    else if (cpl_propertylist_has(self, "ESO DET ACQ1 WIN STRY")) {;
        return visir_pfits_get_int("ESO DET ACQ1 WIN STRY");
    }
    return -1;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The number of exposures
  @param    self       property list to read from
  @return   the requested value
 */ 
/*----------------------------------------------------------------------------*/
int visir_pfits_get_numbexp(const cpl_propertylist * self) 
{
    return visir_pfits_get_int("ESO TPL NEXP");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The OBS ID
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_obs_id(const cpl_propertylist * self)
{
    return visir_pfits_get_int("ESO OBS ID");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The nodding position
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_nodpos(const cpl_propertylist * self)
{
    return visir_pfits_get_string("ESO SEQ NODPOS");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The pixel scale
  @param    self       property list to read from
  @return   on success double pixel scale, -1. on failure
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_pixscale(const cpl_propertylist * self)
{
    const char * sscale = visir_pfits_get_string(VISIR_PFITS_STRING_PIXSCALE);
    if (sscale && strlen(sscale) > 0)
        return atof(sscale);
    else
        return -1.;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The pixel spacing
  @param    self       property list to read from
  @return   the requested value 
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_pixspace(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, "ESO DET CHIP1 PXSPACE")) {
        return visir_pfits_get_double(self, "ESO DET CHIP1 PXSPACE");
    }
    return visir_pfits_get_double(self, "ESO DET CHIP PXSPACE");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The RA
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_ra(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "RA");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The slit width in Arcseconds
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_slitwidth(const cpl_propertylist * self)
{
    const char * slitname = visir_pfits_get_slitname(self);
    double slitwidth = visir_pfits_get_slitwidth_raw(self);


    if (!cpl_error_get_code()) {

        static const char * slit_name[] = {"CU_0.12", "CU_0.14", "CU_0.16",
                                           "CU_0.20", "CU_0.25", "CU_0.30",
                                           "CU_0.40", "CU_0.50", "CU_0.60",
                                           "CU_0.70", "CU_0.80", "CU_1.00",
                                           "CU_1.20", "CU_1.60", "ST_0.14",
                                           "ST_0.16", "ST_0.20", "ST_0.30",
                                           "ST_0.40", "ST_0.50", "ST_0.60"};

        static double slit_width[] = {0.12, 0.14, 0.16,
                                      0.20, 0.25, 0.30,
                                      0.40, 0.50, 0.60,
                                      0.70, 0.80, 1.00,
                                      1.20, 1.60, 0.14,
                                      0.16, 0.20, 0.30,
                                      0.40, 0.50, 0.60};

        static const int slit_nums = (int)(sizeof(slit_width)/sizeof(double));

        int i;

        for (i=0; i < slit_nums; i++)
            if (strstr(slitname, slit_name[i])) break;

        if (i < slit_nums && fabs(slit_width[i] - slitwidth) < 0.001) {
            /* The Slit width is supposed to be in Arcseconds - as written in
               the comment of the FITS card.
               However, if the Slit width matches the Slit name then the Slit
               width is actually in unit millimeter and is converted */

            cpl_msg_warning(cpl_func,"The Width of slit %s is written in the "
                            "FITS card in units mm. Converting to ArcSecs: "
                            "%g => %g", slitname, slitwidth, slitwidth * 2.5);
            slitwidth *= 2.5;
        }
    }

    return slitwidth;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The std star name 
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_starname(const cpl_propertylist * self)
{
    return visir_pfits_get_string("ESO OBS TARG NAME");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The spectral resolution
  @param    self       property list to read from
  @return   pointer to statically allocated character string
 */
/*----------------------------------------------------------------------------*/
const char * visir_pfits_get_resol(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, "ESO INS RESOL")) {
        return visir_pfits_get_string("ESO INS RESOL");
    }
    return NULL;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The telescope (M1) temperature [Celcius]
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_temp(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO TEL TH M1 TEMP");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The VOLT1.DCTA9
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_volt1dcta9(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO DET VOLT1 DCTA9");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The VOLT1.DCTB9
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_volt1dctb9(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO DET VOLT1 DCTB9");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The VOLT2.DCTA9
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_volt2dcta9(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO DET VOLT2 DCTA9");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The VOLT2.DCTB9
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_volt2dctb9(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO DET VOLT2 DCTB9");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The central wavelength
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_wlen(const cpl_propertylist * self)
{
    if (cpl_propertylist_has(self, VISIR_PFITS_DOUBLE_PWLEN)) {
        return visir_pfits_get_double(self, VISIR_PFITS_DOUBLE_PWLEN);
    }
    return visir_pfits_get_double(self, VISIR_PFITS_DOUBLE_WLEN);
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The relative weight of the image compared to the other images
  @param    self       property list to read from
  @return   the requested value

  e.g. center image in parallel mode has double weight

 */
/*----------------------------------------------------------------------------*/
double visir_pfits_get_img_weight(const cpl_propertylist * self)
{
    double imgwgt = 1.;
    if (cpl_propertylist_has(self, "ESO DRS IMGWGT"))
        imgwgt = cpl_propertylist_get_float(self, "ESO DRS IMGWGT");

    return imgwgt;
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The number of input beams
  @param    self       property list to read from
  @return   the requested value

  with chop-nodding 4, only nodding 2

 */
/*----------------------------------------------------------------------------*/
int visir_pfits_get_nbeams(const cpl_propertylist * self)
{
    const cpl_boolean chop_on =
        cpl_propertylist_get_bool(self, VISIR_PFITS_BOOL_CHOP_STATUS);

    /* FIXME: starring mode support? */

    return chop_on ? 4 : 2;
}

/**@}*/

/*----------------------------------------------------------------------------*/
/**
  @brief    The slit width
  @param    self       property list to read from
  @return   the requested value
  @note  The unit is Arcseconds (or for old files mm)
 */
/*----------------------------------------------------------------------------*/
static double visir_pfits_get_slitwidth_raw(const cpl_propertylist * self)
{
    return visir_pfits_get_double(self, "ESO INS SLIT1 WID");
}

/*----------------------------------------------------------------------------*/
/**
  @brief    The slit name
  @param    self       property list to read from
  @return   the requested value
 */
/*----------------------------------------------------------------------------*/
static const char * visir_pfits_get_slitname(const cpl_propertylist * self)
{
    return visir_pfits_get_string("ESO INS SLIT1 NAME");
}
