/*                                                                           *
 *   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: 2012-11-21 15:49:05 $
 * $Revision: 1.151 $
 * $Name: not supported by cvs2svn $
 */

#ifndef XSH_PARAMETERS_H
#define XSH_PARAMETERS_H

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

#include <cpl.h>
#include <xsh_data_instrument.h>

/*----------------------------------------------------------------------------
                                    Typedefs
 ----------------------------------------------------------------------------*/

/*
  Structure housing sigma clipping parameters.
  The "diff" entry is not used in all the cases
*/
typedef struct {
  /* < Sigma */
  double sigma ;
  /* < Number of iteration */
  int niter ;
  /* < Fraction of bad pixels */
  double frac ;
  /* < Only for NIR */
  double diff ;
  /* < Res max */
  double res_max ;
} xsh_clipping_param ;

/*
  Structure housing detect order parameters.
*/
typedef struct {
  /* window size in pixels */
  int search_window_hsize;
  /* threshold */
  double flux_thresh;
  /* min S/N */
  double min_sn;
  /* min order size x */
  int min_order_size_x;
  /* half size of a chunk */
  int chunk_hsize;
  /* IFU: lateral slitlet/central slitlet ratio (0.9) */
  double slitlet_low_factor;
  double slitlet_up_factor;
  /* IFU : flag to used fixed slice */
  int fixed_slice;
  /* IFU : method to trace IFU slices */
  const char* method;
   /* QC: this parameter allow to QC-Garching to skip edge detection for orders
          having edges below min-sn. This allows the recipe to terminate 
          successfully and generate some required QC parameter. 
          Normal users should have this parameter set to FALSE and have 
          eventually a recipe failure if edge S/N is below a minimum tolerable 
          level
   */
   int qc_mode; 
} xsh_detect_order_param;

/*
  Structure housing d2 special detect order parameters.
*/
typedef struct {
  /* min S/N */
  double min_sn;
}xsh_d2_detect_order_param;
  
/* Polynomial degree used in detect_continuum function (recipe xsh_orderpos) */
#define DETECT_CONTINUUM_POLYNOMIAL_DEGREE 5

typedef struct {
  int search_window ;		/**< Window to search for maximum */
  int running_window ;		/**< running median Window */
  int fit_window ;		/**< Window used for gaussian fit (centered on
				 maximum flux) */
  int poly_degree ;		/**< Polynomial degree */
  int poly_step ;		/**< Step */
  double fit_threshold ;	/**< Minimum flux */
  int fmtchk_window ;	/**< Window used to follow an order */
  int fmtchk_step ;		/**< Step in Y used to follow an order */
  double fmtchk_search_sn ;	/**< S/N ratio to find orders at Y = NY/2 */
  double fmtchk_follow_sn ;	/**< S/N ratio used to follow order */
  int dist_order ;
} xsh_detect_continuum_param ;

/*
  Structure housing background parameters.
*/
typedef struct {
  /* number of points of the grid in y direction */
  int sampley;
  /* half size of the subwindow in x direction */
  int radius_x;
  /* half size of the subwindow in x direction */
  int radius_y;

  /* background extraction method: [median],minimum,no */
  int method;
  int edges_margin;
  /* parameters controlling poly method */
  int poly_deg_x;
  int poly_deg_y;
  double poly_kappa;

  /* debug mode: if TRUE generate a table with the grid sampling points */
  int debug;

} xsh_background_param;

/*
  Structure housing xsh_wavecal:follow_arclines) parameters.
*/
#define WAVECAL_RANGE_DEFAULT 13
#define WAVECAL_MARGIN_DEFAULT 3

typedef struct {
  int range ;			/**< Half size in Y direction of search 
				   window */
  int margin ;			/**< Nb of pixels unused (X direction) when
				 searching the edges of a line*/
  xsh_clipping_param *tilt_clipping ; /**< Usual clipping parameters */
  xsh_clipping_param *specres_clipping ; /**< Usual clipping parameters */
  double s_n_min ;		/**< Minimum S/N at the center */
} xsh_follow_arclines_param ;

/*
  Structure housing detect_arclines parameters
*/
#define DETECT_ARCLINES_POLYNOMIAL_DEGREE 5

typedef enum {
  XSH_GAUSSIAN_METHOD,
  XSH_BARYCENTER_METHOD
}  xsh_find_center_method; 
 
typedef struct {
  /* half window size in pixels */
  int fit_window_hsize;
  /* half window size in which search max */
  int search_window_hsize;
  /* half window size running median */
  int running_median_hsize;
  /* degrees of lambda in wave solution polynomial fit */
  int wavesol_deg_lambda;
  /* degrees of order in wave solution polynomial fit */
  int wavesol_deg_order;
  /* degrees of slit in wave solution polynomial fit */
  int wavesol_deg_slit;
  /* Degree of y in orders poynomial fit */
  int ordertab_deg_y ;
  /* minimum S/N to filter lines */
  double min_sn;
  /* method to find the center of the line */
  xsh_find_center_method find_center_method;
  int mode_iterative;
} xsh_detect_arclines_param;

/*
  Parameters for xsh_remove_crh_single function
*/
typedef struct {
  double crh_frac_max ;		/**< Max fraction pf bad pixels allowed */
  double sigma_lim;
  double f_lim;
  int nb_iter ;			/**< Max nb of iteration */
} xsh_remove_crh_single_param ;

/*
  Parameters for xsh_rectify function
*/
#define RECTIFY_KERNEL_PRINT(method)\
  (method) == CPL_KERNEL_TANH ? "TANH" :  \
  (method) == CPL_KERNEL_SINC ? "SINC" : \
  (method) == CPL_KERNEL_SINC2 ? "SINC2" : \
  (method) == CPL_KERNEL_LANCZOS ? "LANCZOS" : \
  (method) == CPL_KERNEL_HAMMING ? "HAMMING" : \
  (method) == CPL_KERNEL_HANN ? "HANN" :"????"

typedef struct {
  char rectif_kernel[16] ;	/**< Interpolation kernel used.
				 Possible choices are:
				   sinc: "ideal" filter
				   sinc2: square sinc
				   lanczos: Lanczos function 2d order
				   hamming: Hamming function
				   hann: Hann function
				   tanh: Hyperbolic tangent
				*/
  cpl_kernel kernel_type ;	/**< type of kernel CPL_KERNEL_XXXX */
  double rectif_radius ;	/**< Interpolation radius (4) */
  double rectif_bin_lambda ;	/**< wavelength step in mm (0.01) */
  double rectif_bin_space ;	/**< position step in arcsec (0.01) */
  int rectify_full_slit ;		/**< if tue, use the full slit, else
				 use the minimum slit size calculated*/
  int conserve_flux;
  double slit_offset ;		/**< offset of the slit. The actual position
				 is POSITION + offset. For example with
				slit_offset = 0.2, the slit position moves
				from -5.8 to 6.2 (instead of -6 to +6)*/
  /* int cut_edges; Not Used */ 
} xsh_rectify_param ;

/*
  Parameters for xsh_localize_obj function
*/
enum localize_method {
  LOC_MANUAL_METHOD,
  LOC_MAXIMUM_METHOD,
  LOC_GAUSSIAN_METHOD
};
#define LOCALIZE_METHOD_PRINT(method)\
  (method) == LOC_MANUAL_METHOD ? "MANUAL" :  \
  (method) == LOC_MAXIMUM_METHOD ? "MAXIMUM" : \
  (method) == LOC_GAUSSIAN_METHOD ? "GAUSSIAN" :"????"

typedef struct {
  int loc_chunk_nb ;	            /**< Nb of chuncks */
  double loc_thresh;	            /**< Threshold */
  int loc_deg_poly;                 /**< Polynomial degree */
  double nod_step ;                 /**< Step between A and B images in 
                                         nodding mode */
  enum localize_method method;
  double slit_position;             /**< Reference slit position to extract */
  double slit_hheight;              /**< Half of height in arc_sec */
  double kappa;                     /**< Kappa value for sigma clipping */
  int niter;                        /**< Number of iterations for sigma 
                                         clipping */
  int use_skymask;
} xsh_localize_obj_param ;

/*
  Parameters for xsh_localize_ifu
*/
typedef struct {
  int smooth_hsize;                 /**< Half size of median filter */
  int nscales;                      /**< Nscales for atrous function */
  int HF_skip;                      /**< Number of high frequency skipping */
  double cut_sigma_low;
  double cut_sigma_up;
  double cut_snr_low;
  double cut_snr_up;
  double slitup_edges_mask;
  double slitlow_edges_mask;
  int use_skymask;
  int box_hsize;
   int bckg_deg;
} xsh_localize_ifu_param ;

/* Parameters for xsh_extract function */
enum extract_method {
  LOCALIZATION_METHOD,
  FULL_METHOD,
  NOD_METHOD,
  CLEAN_METHOD,
};

#define EXTRACT_METHOD_PRINT(method)\
  (method) == LOCALIZATION_METHOD ? "LOCALIZATION" :  \
  (method) == FULL_METHOD ? "FULL" :  \
  (method) == CLEAN_METHOD ? "CLEAN" :  \
  (method) == NOD_METHOD ? "NOD" :  "????"

typedef struct {
  enum extract_method method; /**< method of extraction */  
} xsh_extract_param;

typedef struct {
  int mask_hsize; /** mask size */
} xsh_interpolate_bp_param;


/* Parameters for xsh_merge_ord function */
enum merge_method {
  WEIGHTED_MERGE_METHOD,
  MEAN_MERGE_METHOD
};

#define MERGE_METHOD_PRINT(merge_method)\
  (merge_method) == WEIGHTED_MERGE_METHOD ? "WEIGHT" :  \
  (merge_method) == FULL_METHOD ? "MEAN" : "????"

typedef struct {
  enum merge_method method;
} xsh_merge_param;

/* xsh_subtract_sky_single param */
/* Nb of break points used in Bezier curve fitting */
#define SUBTRACT_SKY_SINGLE_NBKPTS 1000

enum sky_method {
    MEDIAN_METHOD,
    BSPLINE_METHOD,
    BSPLINE_METHOD1,
    BSPLINE_METHOD2,
    BSPLINE_METHOD3,
    BSPLINE_METHOD4,
    BSPLINE_METHOD5
};


enum bspline_sampling {
  UNIFORM,
  FINE
};


#define SKY_METHOD_PRINT(method)\
  (method) == BSPLINE_METHOD ? "BSPLINE" :  \
  (method) == BSPLINE_METHOD1 ? "BSPLINE1" :  \
  (method) == BSPLINE_METHOD2 ? "BSPLINE2" :  \
  (method) == BSPLINE_METHOD3 ? "BSPLINE3" :  \
  (method) == BSPLINE_METHOD4 ? "BSPLINE4" :  \
  (method) == BSPLINE_METHOD5 ? "BSPLINE5" :  \
  (method) == MEDIAN_METHOD ? "MEDIAN" : "????"


#define BSPLINE_SAMPLING_PRINT(method)\
  (method) == UNIFORM ? "UNIFORM" :  \
  (method) == FINE ? "FINE" : "????"

/* xsh_subtract_sky_single_param sky subtraction parameters: */
typedef struct {
  int nbkpts1; /* Nb of break points for Bezier curve fitting 
                  (without localization)" */
  int nbkpts2; /* Nb of break points for Bezier curve fitting 
                  (without localization)" */
  int bezier_spline_order;   /* Bezier Spline Order */
  int niter;   /* number of iterations */
  double kappa;/* kappa value in kappa-sigma clip of object */
  double ron;  /* detector ron */
  double gain; /* detector gain */
  enum sky_method method;
  enum bspline_sampling bspline_sampling;
  int median_hsize;
  double slit_edges_mask;
  double pos1;
  double hheight1;
  double pos2;
  double hheight2;
} xsh_subtract_sky_single_param ;



/* xsh_dispersol_list_compute parameters:
   degrees of polynomials (X and Y) */
typedef struct {
  int deg_x;
  int deg_y;
} xsh_dispersol_param ;

/* xsh_scired_slit_nod specific parameters */
enum combine_method {
  COMBINE_MEDIAN_METHOD,
  COMBINE_MEAN_METHOD
};

#define COMBINE_METHOD_PRINT(method)\
  (method) == COMBINE_MEDIAN_METHOD ? "MEDIAN" :  \
  (method) == COMBINE_MEAN_METHOD ? "MEAN" : "????"


typedef struct {
  int nod_min ;			/**< minimum NS size of resulting 
					   frame in pixels (5) */
  int nod_clip ;	/**< TRUE if do sigma clipping (TRUE) */
  double nod_clip_sigma ;	/**< nb of sigma (5.) */
  int nod_clip_niter ;		/**< nb of iteration (2) */
  double nod_clip_diff ;	/**< minimum change in sigma (0.1) */
  char* throwname;	        /**< if true, use localisation to shift
				 rectified at the good place, otherwise
				 use the Kw RELOFFSET, CUMOFFSET, NODTRHOW */
  enum combine_method method;

} xsh_combine_nod_param ;

typedef struct {
  int sub_med ;		/**< TRUE if subtract median of each
				   wavelength bin (FALSE) */
  double sub_hsigma ;		/**< nb of sigma (5) */
  int sub_niter ;		/**< Nb of iteration (2) */
  double sub_diff ;		/**< minimum change in sigma (0.1) */
} xsh_subtract_nod_param ;


/*
 *   Parameters for xsh_optextract function
 *   */
enum optextract_method {
  GAUSS_METHOD,
  GENERAL_METHOD,
};
#define OPTEXTRACT_METHOD_PRINT(method)\
  (method) == GAUSS_METHOD ? "GAUSSIAN" :  \
  (method) == GENERAL_METHOD ? "GENERAL" : "????"

typedef struct {
  int oversample;         /**< oversample the image */
  int box_hsize; /**< extract box half window size */
  int chunk_size; /**< size of a chunk in pixel */
  double lambda_step; /**< step in lambda */
  double clip_kappa ;		/**< Kappa for detection of cosmics */
  double clip_frac;
  int clip_niter;
  int niter;
  enum optextract_method method;
} xsh_opt_extract_param;


typedef struct {
      int hot_cold_pix_search; /** dis-activate search */
      double cold_pix_kappa;/** kappa for pix detection */
      int cold_pix_niter;         /** number of iterations */
      double hot_pix_kappa;/** kappa for pix detection */
      int hot_pix_niter;         /** number of iterations */
}xsh_hot_cold_pix_param;

typedef struct {
      int fpn_llx;/** FPN llx */
      int fpn_lly;/** FPN lly */
      int fpn_urx;/** FPN urx */
      int fpn_ury;/** FPN ury */
      int fpn_hsize;/** FPN sampling area size */
      int fpn_nsamples;/** FPN number of samples */
}xsh_fpn_param;

typedef struct {
      int pd_dc_x;/** FPN dc_x */
      int pd_dc_y;/** FPN dc_y */
      int pd_compute;/** FPN compute */
}xsh_pd_noise_param;


typedef struct {
      const char* ron_method;/** RON method */
      int ron_random_sizex;/** RON random box X size */
      int ron_random_nsamples;/** RON random number of sampling boxes */

      int ron_prescan_llx;/** RON prescan llx */
      int ron_prescan_lly;/** RON prescan lly */
      int ron_prescan_urx;/** RON prescan urx */
      int ron_prescan_ury;/** RON prescan ury */

      int ron_overscan_llx;/** RON overscan llx */
      int ron_overscan_lly;/** RON overscan lly */
      int ron_overscan_urx;/** RON overscan urx */
      int ron_overscan_ury;/** RON overscan ury */

      int ron_ref_llx;/** RON reference region llx */
      int ron_ref_lly;/** RON reference region lly */
      int ron_ref_urx;/** RON reference region urx */
      int ron_ref_ury;/** RON reference region ury */

      int stacking_ks_low;/** Lower value of kappa-sigma clip in stacking*/
      int stacking_ks_iter;/** Number of iterations in kappa-sigma clip in stacking */
}xsh_ron_param;



typedef struct {
      const char* stack_method;/** frame stacking method */

      double klow;/** Lower value of kappa-sigma clip in stacking*/
      double khigh;/** Upper value of kappa-sigma clip in stacking*/

}xsh_stack_param;


typedef struct {
      int prescan_llx;/** RON prescan llx */
      int prescan_lly;/** RON prescan lly */
      int prescan_urx;/** RON prescan urx */
      int prescan_ury;/** RON prescan ury */

}xsh_prescan_param;

typedef struct {
      int overscan_llx;/** RON overscan llx */
      int overscan_lly;/** RON overscan lly */
      int overscan_urx;/** RON overscan urx */
      int overscan_ury;/** RON overscan ury */

}xsh_overscan_param;

typedef struct {
      int ref_llx;/** RON ref llx */
      int ref_lly;/** RON ref lly */
      int ref_urx;/** RON ref urx */
      int ref_ury;/** RON ref ury */

}xsh_ref_param;

typedef struct {
      int ref_x;/** structure ref x */
      int ref_y;/** structure ref y */

}xsh_struct_param;

typedef struct {
      int ron_llx;/** RON llx */
      int ron_lly;/** RON lly */
      int ron_urx;/** RON urx */
      int ron_ury;/** RON ury */
      int ron_hsize; /** RON sample size */
      int ron_nsamp; /** RON number of samplea */
     
}xsh_ron_dark_param;

/* Actual slit limits used to localize and extract */
typedef struct {
  double min_slit ;		/**< Actual slit min */
  double max_slit ;		/**< Actual slit max */
  int min_slit_idx ;
  int max_slit_idx ;
} xsh_slit_limit_param ;

/* Small binning used in compute response */
typedef struct {
  double lambda_bin ;
} xsh_compute_response_param ;

#define DECODE_BP_FLAG_MAX  2147483647
#define DECODE_BP_FLAG_ALL  2146435071
#define DECODE_BP_FLAG_DEF  2144337919
//#define DECODE_BP_FLAG_NOD  1875902463  // Pre Jan 2021
#define DECODE_BP_FLAG_NOD  1741684735  // PIPE-7965 update - MCW 21-01-19

/*----------------------------------------------------------------------------
   				    Prototypes
 ----------------------------------------------------------------------------*/

/*
  Parameters common to all XSH recipes
     "keep_temp" = "yes"/"no" (default is "no" ie Temp files are deleted in
                               function xsh_end(....)
     "dbg-level" = "none", "low", "medium", "high"
*/

cpl_parameter* 
xsh_parameters_find( cpl_parameterlist* list,
                     const char* recipe_id, const char* name);


void 
xsh_parameters_ron_dark_create(const char* recipe_id,cpl_parameterlist* list, 
                               xsh_ron_dark_param p);

void 
xsh_parameters_prescan_create(const char* recipe_id,cpl_parameterlist* list, 
                              xsh_prescan_param p);
void 
xsh_parameters_overscan_create(const char* recipe_id,cpl_parameterlist* list, 
                              xsh_overscan_param p);
void 
xsh_parameters_struct_create(const char* recipe_id,cpl_parameterlist* list, 
                              xsh_struct_param p);
void 
xsh_parameters_ref1_create(const char* recipe_id,cpl_parameterlist* list, 
                              xsh_ref_param p);
void 
xsh_parameters_ref2_create(const char* recipe_id,cpl_parameterlist* list, 
                              xsh_ref_param p);
void 
xsh_parameters_ron_create(const char* recipe_id,cpl_parameterlist* list, 
                          xsh_ron_param p);
void 
xsh_parameters_pd_noise_create(const char* recipe_id,
  cpl_parameterlist* list, xsh_pd_noise_param p);
void
xsh_parameters_fpn_create(const char* recipe_id,cpl_parameterlist* list, 
                          xsh_fpn_param p);

void 
xsh_parameters_hot_cold_pix_create(const char* recipe_id,
                                   cpl_parameterlist* list, 
                                   xsh_hot_cold_pix_param p);
void 
xsh_parameters_new_int( cpl_parameterlist* list,
                        const char* recipe_id, 
                        const char* name,
                        int value, 
                        const char* comment);
void 
xsh_parameters_new_double( cpl_parameterlist* list,
                           const char* recipe_id,
                           const char* name,
                           double value, 
                           const char* comment);


void xsh_parameters_new_boolean( cpl_parameterlist* list,
  const char* recipe_id, const char* name,int value, const char* comment);
int xsh_parameters_get_boolean( const cpl_parameterlist* list,
  const char* recipe_id, const char* name);
int xsh_parameters_get_int(const cpl_parameterlist* list,
                            const char* recipe_id, const char* name);
double xsh_parameters_get_double(const cpl_parameterlist* list,
  const char* recipe_id, const char* name);
char * xsh_parameters_get_string( const cpl_parameterlist* list,
  const char* recipe_id, const char* name);

void xsh_parameters_generic( const char *recipe_id,
			     cpl_parameterlist * plist ) ;
void xsh_parameters_pre_overscan( const char *recipe_id,
			     cpl_parameterlist * plist ) ;
int xsh_parameters_get_temporary( const char* recipe_id,
				  const cpl_parameterlist* list ) ;
int xsh_parameters_debug_level_get( const char* recipe_id,
				    const cpl_parameterlist* list ) ;
char * xsh_parameters_test_mode_get( const char * recipe_id,
				     const cpl_parameterlist * list ) ;
int xsh_parameters_time_stamp_get( const char * recipe_id,
				   const cpl_parameterlist * list ) ;

int xsh_parameters_cut_uvb_spectrum_get( const char * recipe_id,
                                         const cpl_parameterlist * list );

XSH_ARM  xsh_parameters_get_arm(  const char * recipe_id,
                                     const cpl_parameterlist * list );

void xsh_parameters_use_model_create( const char * recipe_id,
				      cpl_parameterlist * list ) ;
int xsh_parameters_use_model_get( const char * recipe_id,
				  const cpl_parameterlist * list ) ;


/* compute noise map */
void xsh_parameters_clipping_noise_create(const char* recipe_id,
					  cpl_parameterlist* list,
					  xsh_clipping_param noise_clip_param);
xsh_clipping_param* xsh_parameters_clipping_noise_get(const char* recipe_id,
  cpl_parameterlist* list);

/* detect continuum */
void xsh_parameters_clipping_dcn_create(const char* recipe_id,
  cpl_parameterlist* list);
xsh_clipping_param* xsh_parameters_clipping_dcn_get( const char* recipe_id,
  cpl_parameterlist* list);
void xsh_parameters_detect_continuum_create( const char* recipe_id,
					     cpl_parameterlist* list,
					     xsh_detect_continuum_param par ) ;
xsh_detect_continuum_param *
xsh_parameters_detect_continuum_get(
				    const char* recipe_id,
				    cpl_parameterlist* list) ;


xsh_interpolate_bp_param * xsh_parameters_interpolate_bp_get(
  const char* recipe_id, cpl_parameterlist* list);

/* remove crh multiple */
void xsh_parameters_clipping_crh_create(const char* recipe_id,
  cpl_parameterlist* list, xsh_clipping_param p);
xsh_clipping_param* xsh_parameters_clipping_crh_get(const char* recipe_id,
  cpl_parameterlist* list);

/* detect order */
void xsh_parameters_detect_order_create(const char* recipe_id,
  cpl_parameterlist* list);
xsh_detect_order_param* xsh_parameters_detect_order_get(const char* recipe_id,
  cpl_parameterlist* list,cpl_parameterlist* drs);
void xsh_parameters_d2_detect_order_create(const char* recipe_id,
  cpl_parameterlist* list);
xsh_d2_detect_order_param* xsh_parameters_d2_detect_order_get(
  const char* recipe_id, cpl_parameterlist* list);

/* detect arclines */
void xsh_parameters_clipping_detect_arclines_create(const char* recipe_id,
  cpl_parameterlist* list, xsh_clipping_param p);
xsh_clipping_param* xsh_parameters_clipping_detect_arclines_get(
  const char* recipe_id, cpl_parameterlist* list);
void xsh_parameters_detect_arclines_create(const char* recipe_id,
  cpl_parameterlist* list,  xsh_detect_arclines_param p);
xsh_detect_arclines_param* xsh_parameters_detect_arclines_get(
  const char* recipe_id, cpl_parameterlist* list) ;

/* subtract_background */
void xsh_parameters_background_create(const char* recipe_id,
  cpl_parameterlist* list);
xsh_background_param* xsh_parameters_background_get(
  const char* recipe_id, cpl_parameterlist* list);

/* follow arclines */
void xsh_parameters_clipping_tilt_create(const char* recipe_id,
					 cpl_parameterlist* list) ;
xsh_clipping_param* xsh_parameters_clipping_tilt_get(const char* recipe_id,
						     cpl_parameterlist* list) ;
void xsh_parameters_clipping_specres_create(const char* recipe_id,
                                         cpl_parameterlist* list) ;
xsh_clipping_param* xsh_parameters_clipping_specres_get(const char* recipe_id,
                                                     cpl_parameterlist* list) ;

void xsh_parameters_wavecal_range_create(const char* recipe_id,
					 cpl_parameterlist* list) ;
int xsh_parameters_wavecal_range_get( const char* recipe_id,
				      cpl_parameterlist* list) ;
int xsh_parameters_wavecal_margin_get( const char* recipe_id,
				       cpl_parameterlist* list) ;
void xsh_parameters_wavecal_margin_create(const char* recipe_id,
					  cpl_parameterlist* list);
void xsh_parameters_wavecal_s_n_create(const char* recipe_id,
				       cpl_parameterlist* list) ;
double xsh_parameters_wavecal_s_n_get( const char* recipe_id,
				       cpl_parameterlist* list) ;
/* remove_crh_single */
void xsh_parameters_remove_crh_single_create( const char * recipe_id,
					      cpl_parameterlist * plist,
					      xsh_remove_crh_single_param p );
xsh_remove_crh_single_param * xsh_parameters_remove_crh_single_get(
                                        const char* recipe_id,
					cpl_parameterlist* list);

void 
xsh_parameters_stack_create(const char* recipe_id,
			    cpl_parameterlist* list, xsh_stack_param sp);
/* xsh_rectify */
void xsh_parameters_rectify_create( const char * recipe_id,
				    cpl_parameterlist * plist,
				    xsh_rectify_param p ) ;
xsh_rectify_param * xsh_parameters_rectify_get(
					       const char* recipe_id,
					       cpl_parameterlist* list);
int xsh_parameters_rectify_fast_get( const char* recipe_id,
				     cpl_parameterlist* list);

/* xsh_compute_response */
void xsh_parameters_compute_response_create( const char * recipe_id,
					     cpl_parameterlist * plist,
					     xsh_compute_response_param p ) ;
xsh_compute_response_param *
xsh_parameters_compute_response_get( const char * recipe_id,
				     cpl_parameterlist * list) ;

/* xsh_localize_object */
void xsh_parameters_localize_obj_create( const char * recipe_id,
  cpl_parameterlist * plist, xsh_localize_obj_param p ) ;
xsh_localize_obj_param * xsh_parameters_localize_obj_get(
  const char* recipe_id, cpl_parameterlist* list);

/* xsh_localize_ifu */
void xsh_parameters_localize_ifu_create( const char * recipe_id,
  cpl_parameterlist * plist, xsh_localize_ifu_param p ) ;
xsh_localize_ifu_param * xsh_parameters_localize_ifu_get(
  const char* recipe_id, cpl_parameterlist* list);

/* xsh_extract */
void xsh_parameters_extract_create( const char * recipe_id,
                                    cpl_parameterlist * plist, 
                                    xsh_extract_param p, 
                                    enum extract_method method) ;

void xsh_parameters_interpolate_bp_create( const char * recipe_id,
                                    cpl_parameterlist * plist,
                                    xsh_interpolate_bp_param p);
xsh_extract_param * xsh_parameters_extract_get(
  const char* recipe_id, cpl_parameterlist* list);

/* xsh_subtract_sky_single */
void xsh_parameters_subtract_sky_single_create( const char * recipe_id,
  cpl_parameterlist * plist, xsh_subtract_sky_single_param p);
xsh_subtract_sky_single_param* xsh_parameters_subtract_sky_single_get(
  const char* recipe_id, cpl_parameterlist* list);


int xsh_parameters_subtract_sky_single_get_first( const char* recipe_id,
						  cpl_parameterlist* list) ;
int xsh_parameters_subtract_sky_single_get_second( const char* recipe_id,
						   cpl_parameterlist* list) ;

int xsh_parameters_subtract_sky_single_get_niter( const char* recipe_id,
						  cpl_parameterlist* list) ;


double xsh_parameters_subtract_sky_single_get_kappa( const char* recipe_id,
						   cpl_parameterlist* list) ;


int xsh_parameters_subtract_sky_single_get_true( const char* recipe_id,
  cpl_parameterlist* list) ;

void xsh_parameters_dosky_domap_get( const char *recipe_id,
                                     cpl_parameterlist *list, 
                                     cpl_frame* wavemap_frame,
                                     cpl_frame* slitmap_frame,
                                     int* dosky, int* domap);


/* xsh_merge_ord */
void xsh_parameters_merge_ord_create( const char * recipe_id,
				      cpl_parameterlist * plist,
				      int p ) ;
xsh_merge_param * xsh_parameters_merge_ord_get( const char* recipe_id,
				  cpl_parameterlist* list) ;

/* xsh_optimal_extract */
void xsh_parameters_optimal_extract_create( const char * recipe_id,
					    cpl_parameterlist * plist,
					    int p ) ;
double xsh_parameters_optimal_extract_get_kappa( const char* recipe_id,
					   cpl_parameterlist* list) ;
void xsh_parameters_dispersol_create(const char* recipe_id,
  cpl_parameterlist* list, xsh_dispersol_param p) ;
xsh_dispersol_param* xsh_parameters_dispersol_get( const char* recipe_id,
					       cpl_parameterlist* list) ;

void xsh_parameters_combine_nod_create( const char * recipe_id,
					cpl_parameterlist* list,
					xsh_combine_nod_param p) ;
xsh_combine_nod_param * xsh_parameters_combine_nod_get( const char * recipe_id,
						       cpl_parameterlist* list);

void xsh_parameters_opt_extract_create( const char* recipe_id, 
  cpl_parameterlist* list, xsh_opt_extract_param opt_extract_par);
xsh_opt_extract_param*  xsh_parameters_opt_extract_get( const char* recipe_id,
   cpl_parameterlist* list);

#if 0
void xsh_parameters_subtract_nod_create( const char* recipe_id,
					 cpl_parameterlist* list,
					 xsh_subtract_nod_param p) ;
#endif

void xsh_parameters_slit_limit_create( const char* recipe_id,
				       cpl_parameterlist* list,
				       xsh_slit_limit_param p ) ;
xsh_slit_limit_param * xsh_parameters_slit_limit_get( const char * recipe_id,
						cpl_parameterlist* list ) ;

void xsh_parameters_geom_ifu_mode_create( const char* recipe_id,
					  cpl_parameterlist* list ) ;
int xsh_parameters_geom_ifu_mode_get( const char * recipe_id,
				      cpl_parameterlist* list) ;
cpl_parameterlist*
xsh_parameters_create_from_drs_table(const cpl_table* tab);

cpl_error_code
xsh_recipe_params_check(cpl_parameterlist * parameters,xsh_instrument* instrument,const char* rec_id);

cpl_error_code
xsh_recipe_params_drs_check(cpl_parameterlist * parameters,xsh_instrument* instrument,const char* rec_id);

xsh_stack_param* 
xsh_stack_frames_get(const char* recipe_id, cpl_parameterlist* list);

cpl_error_code
xsh_parameters_decode_bp_set( const char *recipe_id,cpl_parameterlist * plist,const int ival);
cpl_error_code
xsh_parameters_decode_bp( const char *recipe_id,cpl_parameterlist * plist,const int ival );

#endif
