/*                                                                            *
 *   This file is part of the ESO UVES Pipeline                               *
 *   Copyright (C) 2004,2005 European Southern Observatory                    *
 *                                                                            *
 *   This library is free software; you can redistribute it and/or modify     *
 *   it under the terms of the GNU General Public License as published by     *
 *   the Free Software Foundation; either version 2 of the License, or        *
 *   (at your option) any later version.                                      *
 *                                                                            *
 *   This program is distributed in the hope that it will be useful,          *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *   GNU General Public License for more details.                             *
 *                                                                            *
 *   You should have received a copy of the GNU General Public License        *
 *   along with this program; if not, write to the Free Software              *
 *   Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA     *
 *                                                                           */
 
/*
 * $Author: amodigli $
 * $Date: 2013-07-22 07:32:55 $
 * $Revision: 1.38 $
 * $Name: not supported by cvs2svn $
 *
 */
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
#include <flames_def_drs_par.h>
#include <flames_reduce_vcorrel.h>
#include <uves_error.h>
/*---------------------------------------------------------------------------*/
/**
 * @defgroup flames_def_drs_par     DRS constant and default parameter values
 */
/*---------------------------------------------------------------------------*/

int BKGPOL[2] = {4, 5};

// To display (Y) or not (N) images or plots
//#define NICE_CREA  "N"

// How large must the SNR on a fibre be in a calibration frame, at a given
// order and x, for that slice to be considered "good"? Give a reasonable
// default value here */
//#define DECENTSNR   10.  
double DECENTSNR = 10;


// How close should a detected fibre be to the position predicted by the 
// 0 order approximation, for it to be recognised and labeled in 
// matchorders() */
double MATCHTHRES = 4;


// Half fibre width on the detector: 520,580 6.5, 860 7.0
// This is updated on the fly during data reduction
//const double HALFIBREWIDTH = 6.5;
double HALFIBREWIDTH = 7.5;

//Maximum number of fibres
int MAXFIBRES = 9;

//SlitFF size & Y shift keywords
//===========================START========================
//Amount of pix from 50% limit of SlitFF flat part discarded
//to be sure to be in the flat part of the SlitFF
//good default value is 3 pix
//#define FLAMES_SAV_BORD_SZ 3
int FLAMES_SAV_BORD_SZ = 3;


//half X window size for median filter. Good default: 3
//#define FLAMES_X_WIND_SIZE 3
int FLAMES_X_WIND_SIZE = 3;


//half Y window size for median filter. Good defauld: 5
//#define FLAMES_Y_WIND_SIZE 5
int FLAMES_Y_WIND_SIZE = 5;


//search window size to filter image. Good default: 100
//#define FLAMES_Y_SEARCH_WIND 100
int FLAMES_Y_SEARCH_WIND = 100;


//number of order cut upper and lower. Robust default: 4
//#define FLAMES_ORD_TRESH 2
int FLAMES_ORD_TRESH = 4;


//k-s clipping iterations over median. Good default: 4
//#define FLAMES_N_CLIP_MED 4
int FLAMES_N_CLIP_MED = 4;

//k-s clipping iterations over average. Good default: 2
//#define FLAMES_N_CLIP_AVG 2
int FLAMES_N_CLIP_AVG = 2;

//signal fraction to set upp and low cut. Good default: 0.5
//Note by AM: 0.5 is small but more trustable to detect the
//real end of a SlitFF. With a small value one could always
//take FLAMES_SAV_BORD_SZ slightly wider (3 pix instead of 2)
//#define FLAMES_INT_TRESH 0.5
double FLAMES_INT_TRESH = 0.5;

//SlitFF size & Y shift keywords

// Number of traces (orders times fibres)
int NBTRACES = 0;

// Minimum fibre fraction coverage for extraction
double MINFIBREFRAC = .3;

// Inline background fitting
const char* BKGFITINLINE="yes";

// Background fitting method:
const char* BKGFITMETHOD="average";

// Background table bad pixel frame scanning switch
// Values:none, fraction, absolute
// Default: none
const char* BKGBADSCAN="none";

// Background table bad pixel frame scanning window size BKGBADWIN 50,50
int BKGBADWIN[2]={50,50};
int BKGBADWINX=50;
int BKGBADWINY=50;

// Background table bad pixel frame scanning threshold fraction
double BKGBADMAXFRAC = 0.02;

// Background table bad pixel frame scanning threshold number
int BKGBADMAXTOT = 200;

// Background window number in each full inter order
int BKG_MAX_IO_WIN = 500;

// Polinomial degree used for BKG fit  order  DRS_BKG_FIT_POL 2,2
int DRS_BKG_FIT_POL[2] = {4,5};
int DRS_BKG_FIT_POL_X = 4;
int DRS_BKG_FIT_POL_Y = 5;

// x,y maximum size of each background window: BKG_XY_WIN_SZ 6,2
double BKG_XY_WIN_SZ[2] = {6.0, 2.0};


// XHALFWINDOW,YHALFWINDOW  window: 2,1    DRS_FILT_HW_XY 2,1
int DRS_FILT_HW[2] = {2,1};
int DRS_FILT_HW_X = 2;
int DRS_FILT_HW_Y = 1;

// maximum filtering iterations in frame preparation 300
int DRS_FILT_IMAX = 300;

// maximum filtering iterations in frame preparation 10
int DRS_FILT_KS = 10;

// Do you want mask saturated pixels in frame preparation ([YES]/NO)? 
const char* DRS_FILT_SAT_SW = "YES";

// Do you want a filter/generated badpixel mask: ([NONE]/MEDIAN)? 
const char* DRS_FILT_MASK = "NONE";

// Gaussian pseudofibre HWHM for correlation
double GAUSSFIBRESIGMA = 1.5;






// Gaussian pseudofibre total halfwidth for correlation
double GAUSSHALFWIDTH = 6.;

// Half width of the interval to scan for correlation, when determining y shift
double MAXYSHIFT = 3.;

// This is the maximum number of kappa-sigma clipping iterations which we 
// are willing to perform in background fitting */
int MAXBACKITERS = 20;

// This is the maximum fraction of windows/pixels which we are willing to 
// discard by kappa-sigma clipping in each iteration of the background 
// fitting loop */
double MAXDISCARDFRACT = .1;

// This is the maximum number of iterations which we 
// are willing to perform in correlation */
int MAXCORRITERS = 30;

// This is the absolute accuracy with which we require in the correlation 
// to determine the y shift */
double CORRELTOL = .005;

// This is the x step to use while computing the correlation: it must be 
// a positive integer, 1 means "use all pixels", 2 means 
// "use every other pixel", 3 means "use one every three" etc. */
int CORRELXSTEP = 1;

// This is the scaling factor with which we define the gaussian width of
// synthetic fibres in correlation */
double GAUSSCORRELSCL = .2;

// This is the scaling factor with which we define window out of which the 
// gaussian synthetic fibres are considered negligible in correlation */
double GAUSSCORRELWND = 5.;

// This is the maximum number of cleaning iterations to be tried on a given
// slice in flames_prep_fibre, before 
// giving up on its normalisability and falling
// back to the second cleaning strategy */
int MAXCLEANITERS = 10;

// this is the maximum acceptable fraction of the flux in a given slices in
// one single pixel; a higher fraction than this means that there was some 
// numerical instability and/or unmasked bad pixel, and that it must be 
// discarded */
double MAXSINGLEPXFRC = .3;

// This is the maximum number of iterations which we are willing to
// perform in optimal extraction */
int MAXOPTITERSINT = 25;

// This is the minimum number of iterations which we are willing to
// perform in optimal extraction */
int MINOPTITERSINT = 2;

// When performing sigma-clipping in the optimal extraction, how many
// other adjacent pixels in the x and/or y direction(s) should be 
// discarded along with the one exceeding the threshold? A cosmic or 
// cosmetic problem is likely to affect a spot larger than 1 pixel */
int XKILLSIZE = 0;
int YKILLSIZE = 1;

// In flames_tracing, a few arrays are statically defined, and need to be
// large enough to contain all the orders which could be possibly found;
// We define it to a hefty one thousend */
int MAXORDER = 1000;


// Width of the y half-window to use when performing order/fibre labelling */
//#define DYRANGE 300
int DYRANGE = 300;

// Step of the scan in y while performing order/fibre labelling */
//#define DYSTEP .1
double DYSTEP = 0.1;

// MASKTHRES defines the minimum value a rebinned mask must have in order
// to consider the corresponding pixel of the rebinned spectrum "good".
// Since a pixel in the rebinned frame may be computed using also bad pixels, 
// we want to throw out pixels which contain even a very small fraction of 
// "badness" 
double MASKTHRES = .99;

// FRACSLICESTHRES defines the minimum fraction of slices that must be good, 
// for a fibre to be considered covered enough at the end of fillholes, in 
// flames_prep_fibreff, to avoid stupid instabilities in gaussselfcorrel
//  if a fibre is only very barely covered by the slit FF frames 
//#define FRACSLICESTHRES .3
double FRACSLICESTHRES = 0.3;


// The maximum permitted sizes for the order tables created by the DRS */
int MAXROWS = 300000;
int MAXCOLS = 10;


// ============================================
// Procedures default input parameter settings
// ============================================
// The following settings may be modified 
// (at user wish and own risk) to adjust extraction
// -------------------------------------------

// threshold value for maximum pixel saturation: good: 50000-60000
int DRS_PTHRE_MAX = 55000;

// threshold value for maximum pixel saturation: good: -20
int DRS_PTHRE_MIN = -20;

// extraction method: opt/sta/fop/fst/qopt
const  char* DRS_EXT_MTD = "opt";

// K-S THRESHOLD good: 10
double  DRS_K_S_THRE = 10.;

// K-S THRESHOLD good: 10
int  DRS_KSIGMA_THRE = 10;


// Integration window size good:  10 (if fibre deconvolution works fine)
double  DRS_EXT_W_SIZ = 10.;

// MIDAS to FITS conersion: Y/N
const char*  DRS_MIDAS2FITS = "N";

// BIAS Subtraction method: M/<num>/N
// M:     Master bias subtraction
// <num>: constant value subtraction
// N:     no subtraction
const char*  DRS_BIAS_MTD = "M";

// filter switch
const char* DRS_FILT_SW = "none";

// slitff-fibreff frames preparation: [Y]/N
// Y: yes, slower, for DFO
// N: no, faster, for PSO once the CDB is ready
//#define  DRS_SFF_FIBFF "Y"

// crea Bad Pix table
//#define  DRS_CREA_BP_TAB "N"

// Physical model auto recover switch
// Y: yes, the physical model auto recovers
// N: no, the physical model does not auto recover
//#define  DRS_PHYSMOD_REC "Y"


// What merging method are we using: 
// FLAMES one or the standard ECHELLE? ECHELLE is more robust
//#define DRS_MER_MTD "ECHELLE"


// Produce or not raw science data
//#define DRS_SCI_RAW "Y"


// DRS MIDAS VERBOSITY
const char* DRS_VERBOSITY = "LOW";
//const char* DRS_VERBOSITY = "HIGH";

// DRS MIDAS MESSAGE LEVEL
//      if "{DRS_VERBOSITY}" .eq. "LOW" then
//     #define DRS_MES_LEV/i/1/1 4
// else if "{DRS_VERBOSITY}" .eq. "NORM" then
//     #define DRS_MES_LEV/i/1/1 3
// else if "{DRS_VERBOSITY}" .eq. "HIGH" then
//     #define DRS_MES_LEV/i/1/1 3
// else
//     #define DRS_MES_LEV/i/1/1 3
// endif
//#define DRS_MES_LEV 4


// DRS CUBIFY SWITCH 
const char* DRS_CUBIFY = "N";

// DRS QC key holder  
//#define DRS_BKG_PIX 0
int DRS_BKG_PIX = 0;


// DRS strenghtened correlation shape definition 
// and pre search of maximum switch:
// Y do pre search of correlation's maximum.
// N don't do it (do only search of max with modified Brent method
//  on points -3,0,+3)
const char* DRS_COR_MAX_FND = "Y";

// DRS Correlation function's range: [-DRS_COR_DEF_RNG,+DRS_COR_DEF_RNG] pix
float DRS_COR_DEF_RNG = 6.;

// DRS Correlation function's No of definition points
//  Effective No of points is 2*DRS_COR_DEF_PNT+1
// For PSO we use a default of 50
int DRS_COR_DEF_PNT = 25;

// DRS Correlation function's offset to range center
float DRS_COR_DEF_OFF = 0.;


//  Effective No of points is 2*DRS_COR_DEF_PNT+1
//#define DRS_WAVE_QC_LOG 0

// DRS QC key holder  
//#define DRS_CHI2_RED 0.
double DRS_CHI2_RED = 0;


// DRS QC key holder  
//#define DRS_Y_SHIFT 0.

// DRS N LIT  FIBRES
//#define DRS_NLIT_FIBRES 0
int DRS_NLIT_FIBRES = 0;


// DRS Wavecal linear fit mode:  
//#define DRS_WCAL_MODE "AUTO"

// DRS Wavecal Resolution Plots generation:  
//#define DRS_WCAL_RPLT "Y"

// DRS Wavecal FITS output tables:  
//#define DRS_WCAL_FITS "N"

// DRS Wavecal FITS output tables:  
const char* DRS_BASE_NAME = "fxb";

// DRS Wavecal FITS output tables:  
//#define DRS_SCI_CUBE "N"

// DRS Wavecal polynomial solution degree:  originally 5, 4 is more robust
//#define DRS_WCAL_DC 4

// DRS Wavecal polynomial solution tolerance:  0.6
//#define DRS_WCAL_TOL 0.6


// DRS Wavecal parameters:  
//#define DRS_WCAL_PAR {DRS_WCAL_MODE}, {DRS_WCAL_RPLT}, {DRS_WCAL_FITS}, {DRS_WCAL_DC}, {DRS_WCAL_TOL}


// DRS Multiple parameter: 
//#define DRS_SCI_PAR1 {DRS_EXT_MTD}, {DRS_COR_MAX_FND}, {DRS_COR_DEF_RNG},  {DRS_COR_DEF_PNT}, {DRS_COR_DEF_OFF}

// DRS Wavecal polynomial solution tolerance:  
//#define DRS_SCI_PAR2 {DRS_BIAS_MTD},{DRS_FILT_SW},{DRS_PTHRE_MAX}


// First component of P8 for the 3 settings:
// Sometime in 520 setting one may have less problems
// using a higher value of DRS_P8_OFPOS_S1, like 0.2
// Reasonable values are:
// 520: .05
// 580: .10
// 860: .10 

// DRS Parameter P8 for hough/echelle: Note flames_ofpos (OFPOS/FLAMES)
// Uses values: 
// DRS_P8_OFPOS="{DRS_P8_OFPOS_S1(i)},-.1,.1,.005,1."   i=1,2,3

double DRS_P8_OFPOS_S1_1 = .05;
double DRS_P8_OFPOS_S1_2 = .10;
double DRS_P8_OFPOS_S1_3 = .10;



// Chopped part in CCD in doing hough/echelle
// same meaning of parameter SCAN of hough/echelle 
// DRS_SCAN_MIN: lower part of CCD
// DRS_SCAN_MAX: upper part of CCD
// Those aliases are hardcoded in OFPOS/FLAMES

//#define DRS_SCAN_MIN 55,73,73 // 520: 55
// 580: 73
// 860: 73 
//#define DRS_SCAN_MAX 1993,1975,1975 // 520: 1993 (1993=2048-55)
// 580: 1975 (1975=2048-73)
// 860: 1975 
int DRS_SCAN_MIN_1 = 55;
int DRS_SCAN_MIN_2 = 73;
int DRS_SCAN_MIN_3 = 73;

int DRS_SCAN_MAX_1 = 1993;
int DRS_SCAN_MAX_2 = 1975;
int DRS_SCAN_MAX_3 = 1975;

// To easily temporally test data reduction
//#define DRS_DIR_SPFMT /new_format/with_extensions

//#define DRS_MER_DELTA "5,5"
const char* DRS_DEL_SW="A";


//#define DRS_WCHAR_DEG 4
//#define DRS_WCHAR_WID 4.

// Simultaneous fibre data reduction
//#define DRS_SCI_SIM Y
//#define DRS_CVEL_SWITCH "Y"

// Simultaneous fibre data reduction
//#define FLAMES_DRS_SFF_HW_MIN 10
int FLAMES_DRS_SFF_HW_MIN = 10;



// SWITCH FOR generating not blaze corrected extracted frames.
//#define DRS_BLAZE_SW "Y"
bool DRS_BLAZE_SW = true;

cpl_error_code
flames_def_drs_par(cpl_parameterlist* list, const char* recipe_id)
{
   //cpl_parameter* p=NULL;

  //int BKGPOL[2] = {4, 5};

// To display (Y) or not (N) images or plots
//#define NICE_CREA  "N"

  uves_parameters_new_double(list,recipe_id,"BKGPOLX",4,
			     "Polynomial degree used for inter-order background computation");

  uves_parameters_new_double(list,recipe_id,"BKGPOLY",5,
			     "Polynomial degree used for inter-order background computation");


  uves_parameters_new_double(list,recipe_id,"DECENTSNR",10,
   "How large must the SNR on a fibre be in a calibration frame, at a given "
   "order and x, for that slice to be considered 'good'? Give a reasonable "
			     "default value here.");


  uves_parameters_new_double(list,recipe_id,"MATCHTHRESH",4,
   "How close should a detected fibre be to the position predicted by the" 
   "0 order approximation, for it to be recognised and labeled in" 
			     "matchorders()");

  uves_parameters_new_double(list,recipe_id,"HALFIBREWIDTH",7.5,
   "Half fibre width on the detector: 520,580 6.5, 860 7.0"
			     "This is updated on the fly during data reduction");

  uves_parameters_new_int(list,recipe_id,"MAXFIBRES",9,
			  "Maximum number of fibres");


  uves_parameters_new_int(list,recipe_id,"FLAMES_SAV_BORD_SZ",3,
"Amount of pix from 50% limit of SlitFF flat part discarded"
			  "to be sure to be in the flat part of the SlitFF");

  uves_parameters_new_int(list,recipe_id,"FLAMES_X_WIND_SIZE",3,
			  "half X window size for median filter.");


  uves_parameters_new_int(list,recipe_id,"FLAMES_Y_WIND_SIZE",5,
			  "half X window size for median filter.");

  uves_parameters_new_int(list,recipe_id,"FLAMES_Y_SEARCH_WIND",100,
			  "search window size to filter image.");


  uves_parameters_new_int(list,recipe_id,"FLAMES_ORD_TRESH",2,
			  "number of order cut upper and lower.");

  uves_parameters_new_int(list,recipe_id,"FLAMES_N_CLIP_MED",4,
			  "k-s clipping iterations over median");

  uves_parameters_new_int(list,recipe_id,"FLAMES_N_CLIP_AVG",2,
			  "k-s clipping iterations over average");


  uves_parameters_new_double(list,recipe_id,"FLAMES_INT_TRESH",0.5,
"signal fraction to set upp and low cut. Good default: 0.5"
"Note by AM: 0.5 is small but more trustable to detect the"
"real end of a SlitFF. With a small value one could always"
			     "take FLAMES_SAV_BORD_SZ slightly wider (3 pix instead of 2)");


//SlitFF size & Y shift keywords

  uves_parameters_new_int(list,recipe_id,"NBTRACES",0,
			  "Number of traces (orders times fibres)");

  uves_parameters_new_double(list,recipe_id,"MINFIBREFRAC",0.3,
			     "Minimum fibre fraction coverage for extraction");

  uves_parameters_new_string(list,recipe_id,"BKGFITINLINE","yes",
			     "Inline background fitting");

  uves_parameters_new_string(list,recipe_id,"BKGFITMETHOD","average",
			     "Background fitting method:");


// Background table bad pixel frame scanning switch
// Values:none, fraction, absolute
// Default: none
//const char* BKGBADSCAN="none";

// Background table bad pixel frame scanning window size BKGBADWIN 50,50
//int BKGBADWIN[2]={50,50};
//int BKGBADWINX=50;
//int BKGBADWINY=50;


  uves_parameters_new_int(list,recipe_id,"BKGBADWINX",50,
			  "Background table bad pixel frame scanning window X size");

  uves_parameters_new_int(list,recipe_id,"BKGBADWINY",50,
			  "Background table bad pixel frame scanning window Y size");


  uves_parameters_new_double(list,recipe_id,"BKGBADMAXFRAC",0.02,
			     "Background table bad pixel frame scanning threshold fraction");

  uves_parameters_new_int(list,recipe_id,"BKGBADMAXTOT",200,
			  "Background table bad pixel frame scanning threshold number");

  uves_parameters_new_int(list,recipe_id,"BKG_MAX_IO_WIN",500,
			  "Background window number in each full inter order");

// Polinomial degree used for BKG fit  order  DRS_BKG_FIT_POL 2,2
//int DRS_BKG_FIT_POL[2] = {4,5};
//int DRS_BKG_FIT_POL_X = 4;
//int DRS_BKG_FIT_POL_Y = 5;


  uves_parameters_new_int(list,recipe_id,"DRS_BKG_FIT_POL_X",4,
			  "Polinomial X degree used for BKG fit  order");
  uves_parameters_new_int(list,recipe_id,"DRS_BKG_FIT_POL_Y",5,
			  "Polinomial Y degree used for BKG fit  order");

// x,y maximum size of each background window: BKG_XY_WIN_SZ 6,2
//double BKG_XY_WIN_SZ[2] = {6.0, 2.0};


// XHALFWINDOW,YHALFWINDOW  window: 2,1    DRS_FILT_HW_XY 2,1
//int DRS_FILT_HW[2] = {2,1};
//int DRS_FILT_HW_X = 2;
//int DRS_FILT_HW_Y = 1;


  uves_parameters_new_int(list,recipe_id,"DRS_FILT_HW_X",2,
			  "X Half width window for background computation");
  uves_parameters_new_int(list,recipe_id,"DRS_FILT_HW_X",1,
			  "Y Half width window for background computation");


  uves_parameters_new_int(list,recipe_id,"DRS_FILT_IMAX",300,
			  "maximum filtering iterations in frame preparation");

  uves_parameters_new_int(list,recipe_id,"DRS_FILT_KS",10,
			  "maximum filtering iterations in frame preparation");

  //AMO: Here better enum
  uves_parameters_new_string(list,recipe_id,"DRS_FILT_SAT_SW","YES",
			     "Do you want mask saturated pixels in frame preparation ([YES]/NO)?");


  //AMO: Here better enum
  uves_parameters_new_string(list,recipe_id,"DRS_FILT_MASK","NONE",
			     "Do you want a filter/generated badpixel mask: ([NONE]/MEDIAN)?");

  uves_parameters_new_double(list,recipe_id,"GAUSSFIBRESIGMA",1.5,
			     "Gaussian pseudofibre HWHM for correlation");

  uves_parameters_new_double(list,recipe_id,"GAUSSHALFWIDTH",6,
			     "Gaussian pseudofibre total halfwidth for correlation");


  uves_parameters_new_double(list,recipe_id,"MAXYSHIFT",3,
			     "Half width of the interval to scan for correlation, when determining y shift");

  uves_parameters_new_int(list,recipe_id,"MAXBACKITERS",20,
"This is the maximum number of kappa-sigma clipping iterations which we" 
			  "are willing to perform in background fitting");



  uves_parameters_new_double(list,recipe_id,"MAXDISCARDFRACT",.1,
"This is the maximum fraction of windows/pixels which we are willing to " 
"discard by kappa-sigma clipping in each iteration of the background " 
			     "fitting loop");

  uves_parameters_new_int(list,recipe_id,"MAXCORRITERS",30,
"This is the maximum number of iterations which we "
			  "are willing to perform in correlation ");

  uves_parameters_new_double(list,recipe_id,"CORRELTO",.005,
"This is the absolute accuracy with which we require in the correlation "
			     "to determine the y shift ");

  uves_parameters_new_int(list,recipe_id,"CORRELXSTEP",1,
"This is the x step to use while computing the correlation: it must be "
"a positive integer, 1 means 'use all pixels', 2 means "
			  " 'use every other pixel', 3 means 'use one every three' etc.");


  uves_parameters_new_double(list,recipe_id,"GAUSSCORRELSCL",.2,
"This is the scaling factor with which we define the gaussian width of "
			     "synthetic fibres in correlation");

  uves_parameters_new_double(list,recipe_id,"GAUSSCORRELWND",5.,
  "This is the scaling factor with which we define window out of which the "
			     "Gaussian synthetic fibres are considered negligible in correlation");

  uves_parameters_new_int(list,recipe_id,"MAXCLEANITERS",10,
"This is the maximum number of cleaning iterations to be tried on a given "
"slice in flames_prep_fibre, before " 
"giving up on its normalisability and falling "
			  "back to the second cleaning strategy");


  uves_parameters_new_double(list,recipe_id,"MAXSINGLEPXFRC",.3,
"this is the maximum acceptable fraction of the flux in a given slices in "
"one single pixel; a higher fraction than this means that there was some "
"numerical instability and/or unmasked bad pixel, and that it must be "
			     "discarded ");

  uves_parameters_new_int(list,recipe_id,"MAXOPTITERSINT",25,
"This is the maximum number of iterations which we are willing to "
			  "perform in optimal extraction ");

  uves_parameters_new_int(list,recipe_id,"MINOPTITERSINT",2,
"This is the minimum number of iterations which we are willing to "
"perform in optimal extraction ");

  uves_parameters_new_int(list,recipe_id,"XKILLSIZE",0,
"When performing sigma-clipping in the optimal extraction, how many "
"other adjacent pixels in the x and/or y direction(s) should be "
"discarded along with the one exceeding the threshold? A cosmic or "
"cosmetic problem is likely to affect a spot larger than 1 pixel ");

  uves_parameters_new_int(list,recipe_id,"YKILLSIZE",1,
"When performing sigma-clipping in the optimal extraction, how many "
"other adjacent pixels in the x and/or y direction(s) should be "
"discarded along with the one exceeding the threshold? A cosmic or "
"cosmetic problem is likely to affect a spot larger than 1 pixel ");


  uves_parameters_new_int(list,recipe_id,"MAXORDER",1000,
"In flames_tracing, a few arrays are statically defined, and need to be "
"large enough to contain all the orders which could be possibly found; "
"We define it to a hefty one thousend ");


  uves_parameters_new_int(list,recipe_id,"DYRANGE",300,
			  "Width of the y half-window to use when performing order/fibre labelling ");

  uves_parameters_new_double(list,recipe_id,"DYSTEP",0.1,
			     "Step of the scan in y while performing order/fibre labelling ");

  uves_parameters_new_double(list,recipe_id,"MASKTHRES",0.99,
"MASKTHRES defines the minimum value a rebinned mask must have in order "
"to consider the corresponding pixel of the rebinned spectrum 'good'. "
"Since a pixel in the rebinned frame may be computed using also bad pixels, " 
"we want to throw out pixels which contain even a very small fraction of " 
			     "'badness'"); 

  uves_parameters_new_double(list,recipe_id,"FRACSLICESTHRES",0.3,
"FRACSLICESTHRES defines the minimum fraction of slices that must be good, " 
"for a fibre to be considered covered enough at the end of fillholes, in "
"flames_prep_fibreff, to avoid stupid instabilities in gaussselfcorrel "
			     "if a fibre is only very barely covered by the slit FF frames ");


  uves_parameters_new_int(list,recipe_id,"MAXROWS",300000,
			     "The maximum permitted sizes for the order tables created by the DRS");


  uves_parameters_new_int(list,recipe_id,"MAXROWS",10,
			     "The maximum permitted sizes for the order tables created by the DRS");



// ============================================
// Procedures default input parameter settings
// ============================================
// The following settings may be modified 
// (at user wish and own risk) to adjust extraction
// -------------------------------------------


  uves_parameters_new_int(list,recipe_id,"DRS_PTHRE_MAX",55000,
			  "threshold value for maximum pixel saturation: good: 50000-60000");


  uves_parameters_new_int(list,recipe_id,"DRS_PTHRE_MIN",-20,
			  "threshold value for maximum pixel saturation: good: -20");

// extraction method: opt/sta/fop/fst/qopt
//const  char* DRS_EXT_MTD = "opt";



// K-S THRESHOLD good: 10
//double  DRS_K_S_THRE = 10.;


  uves_parameters_new_double(list,recipe_id,"DRS_K_S_THRE",10,
			     "K-S THRESHOLD good: 10");

  uves_parameters_new_double(list,recipe_id,"DRS_EXT_W_SIZ",10,
			     "Integration window size good:  10 (if fibre deconvolution works fine)");

// MIDAS to FITS conersion: Y/N
//const char*  DRS_MIDAS2FITS = "N";

// BIAS Subtraction method: M/<num>/N
// M:     Master bias subtraction
// <num>: constant value subtraction
// N:     no subtraction
//const char*  DRS_BIAS_MTD = "M";

// filter switch
//const char* DRS_FILT_SW = "none";

  uves_parameters_new_string(list,recipe_id,"DRS_FILT_SW","none",
			     "filter switch");


// slitff-fibreff frames preparation: [Y]/N
// Y: yes, slower, for DFO
// N: no, faster, for PSO once the CDB is ready
//#define  DRS_SFF_FIBFF "Y"

// crea Bad Pix table
//#define  DRS_CREA_BP_TAB "N"

// Physical model auto recover switch
// Y: yes, the physical model auto recovers
// N: no, the physical model does not auto recover
//#define  DRS_PHYSMOD_REC "Y"


// What merging method are we using: 
// FLAMES one or the standard ECHELLE? ECHELLE is more robust
//#define DRS_MER_MTD "ECHELLE"


// Produce or not raw science data
//#define DRS_SCI_RAW "Y"


// DRS MIDAS VERBOSITY
//const char* DRS_VERBOSITY = "LOW";
//const char* DRS_VERBOSITY = "HIGH";

// DRS MIDAS MESSAGE LEVEL
//      if "{DRS_VERBOSITY}" .eq. "LOW" then
//     #define DRS_MES_LEV/i/1/1 4
// else if "{DRS_VERBOSITY}" .eq. "NORM" then
//     #define DRS_MES_LEV/i/1/1 3
// else if "{DRS_VERBOSITY}" .eq. "HIGH" then
//     #define DRS_MES_LEV/i/1/1 3
// else
//     #define DRS_MES_LEV/i/1/1 3
// endif
//#define DRS_MES_LEV 4


// DRS CUBIFY SWITCH 
//const char* DRS_CUBIFY = "N";


//Here better an enum
  uves_parameters_new_string(list,recipe_id,"DRS_CUBIFY","N",
			     "Switch to have products in imagelists");

// DRS QC key holder  
//#define DRS_BKG_PIX 0
//int DRS_BKG_PIX = 0;

//AMO: solve this
  uves_parameters_new_int(list,recipe_id,"DRS_BKG_PIX",0,
			     "DRS QC key holder??");


// DRS strenghtened correlation shape definition 
// and pre search of maximum switch:
// Y do pre search of correlation's maximum.
// N don't do it (do only search of max with modified Brent method
//  on points -3,0,+3)
//const char* DRS_COR_MAX_FND = "Y";

  uves_parameters_new_string(list,recipe_id,"DRS_COR_MAX_FND","Y",
"DRS strenghtened correlation shape definition "
"and pre search of maximum switch: "
" Y do pre search of correlation's maximum."
" N don't do it (do only search of max with modified Brent method"
			     " on points (-3,0,+3)");

  uves_parameters_new_float(list,recipe_id,"DRS_COR_DEF_RNG",6,
			    "DRS Correlation function's range: [-DRS_COR_DEF_RNG,+DRS_COR_DEF_RNG] pix");


  uves_parameters_new_int(list,recipe_id,"DRS_COR_DEF_PNT",25,
"DRS Correlation function's No of definition points "
"Effective No of points is 2*DRS_COR_DEF_PNT+1 "
			  "For PSO we use a default of 50 ");

  uves_parameters_new_float(list,recipe_id,"DRS_COR_DEF_OFF",0,
			    "DRS Correlation function's offset to range center");

// DRS QC key holder  
//#define DRS_CHI2_RED 0.
//double DRS_CHI2_RED = 0;


// DRS QC key holder  
//#define DRS_Y_SHIFT 0.

//#define DRS_NLIT_FIBRES 0

  uves_parameters_new_int(list,recipe_id,"DRS_NLIT_FIBRES",0,
			  "DRS N LIT  FIBRES");


// DRS Wavecal linear fit mode:  
//#define DRS_WCAL_MODE "AUTO"

// DRS Wavecal Resolution Plots generation:  
//#define DRS_WCAL_RPLT "Y"

// DRS Wavecal FITS output tables:  
//#define DRS_WCAL_FITS "N"


  uves_parameters_new_string(list,recipe_id,"DRS_BASE_NAME","fxb",
			  "File prefix fopr extracted frames");

// DRS Wavecal FITS output tables:  
//#define DRS_SCI_CUBE "N"

// DRS Wavecal polynomial solution degree:  originally 5, 4 is more robust
//#define DRS_WCAL_DC 4

// DRS Wavecal polynomial solution tolerance:  0.6
//#define DRS_WCAL_TOL 0.6


// DRS Wavecal parameters:  
//#define DRS_WCAL_PAR {DRS_WCAL_MODE}, {DRS_WCAL_RPLT}, {DRS_WCAL_FITS}, {DRS_WCAL_DC}, {DRS_WCAL_TOL}


// DRS Multiple parameter: 
//#define DRS_SCI_PAR1 {DRS_EXT_MTD}, {DRS_COR_MAX_FND}, {DRS_COR_DEF_RNG},  {DRS_COR_DEF_PNT}, {DRS_COR_DEF_OFF}

// DRS Wavecal polynomial solution tolerance:  
//#define DRS_SCI_PAR2 {DRS_BIAS_MTD},{DRS_FILT_SW},{DRS_PTHRE_MAX}


// First component of P8 for the 3 settings:
// Sometime in 520 setting one may have less problems
// using a higher value of DRS_P8_OFPOS_S1, like 0.2
// Reasonable values are:
// 520: .05
// 580: .10
// 860: .10 

// DRS Parameter P8 for hough/echelle: Note flames_ofpos (OFPOS/FLAMES)
// Uses values: 
// DRS_P8_OFPOS="{DRS_P8_OFPOS_S1(i)},-.1,.1,.005,1."   i=1,2,3


  uves_parameters_new_double(list,recipe_id,"DRS_P8_OFPOS_S1_1",0.05,
			     "DRS Parameter P8 for hough/echelle, 1st value");
  uves_parameters_new_double(list,recipe_id,"DRS_P8_OFPOS_S1_2",0.1,
			     "DRS Parameter P8 for hough/echelle, 2nd value");
  uves_parameters_new_double(list,recipe_id,"DRS_P8_OFPOS_S1_3",0.1,
			     "DRS Parameter P8 for hough/echelle, 3rd value");



// Chopped part in CCD in doing hough/echelle
// same meaning of parameter SCAN of hough/echelle 
// DRS_SCAN_MIN: lower part of CCD
// DRS_SCAN_MAX: upper part of CCD
// Those aliases are hardcoded in OFPOS/FLAMES

//#define DRS_SCAN_MIN 55,73,73 // 520: 55
// 580: 73
// 860: 73 
//#define DRS_SCAN_MAX 1993,1975,1975 // 520: 1993 (1993=2048-55)
// 580: 1975 (1975=2048-73)
// 860: 1975 

  uves_parameters_new_int(list,recipe_id,"DRS_SCAN_MIN_1",55,
			     "Chopped part in CCD in doing hough/echellee"
"same meaning of parameter SCAN of hough/echelle" 
"DRS_SCAN_MIN: lower part of CCD");


  uves_parameters_new_int(list,recipe_id,"DRS_SCAN_MIN_2",73,
			     "Chopped part in CCD in doing hough/echellee"
"same meaning of parameter SCAN of hough/echelle" 
"DRS_SCAN_MIN: lower part of CCD");


  uves_parameters_new_int(list,recipe_id,"DRS_SCAN_MIN_3",73,
			     "Chopped part in CCD in doing hough/echellee"
"same meaning of parameter SCAN of hough/echelle" 
"DRS_SCAN_MIN: lower part of CCD");



  uves_parameters_new_int(list,recipe_id,"DRS_SCAN_MAX_1",1993,
			     "Chopped part in CCD in doing hough/echellee"
"same meaning of parameter SCAN of hough/echelle" 
"DRS_SCAN_MAX: upper part of CCD");


  uves_parameters_new_int(list,recipe_id,"DRS_SCAN_MAX_2",1975,
			     "Chopped part in CCD in doing hough/echellee"
"same meaning of parameter SCAN of hough/echelle" 
"DRS_SCAN_MAX: upper part of CCD");


  uves_parameters_new_int(list,recipe_id,"DRS_SCAN_MAX_3",1975,
			     "Chopped part in CCD in doing hough/echellee"
"same meaning of parameter SCAN of hough/echelle" 
"DRS_SCAN_MAX: upper part of CCD");



// To easily temporally test data reduction
//#define DRS_DIR_SPFMT /new_format/with_extensions

//#define DRS_MER_DELTA "5,5"
//const char* DRS_DEL_SW="A";

 


//#define DRS_WCHAR_DEG 4
//#define DRS_WCHAR_WID 4.

// Simultaneous fibre data reduction
//#define DRS_SCI_SIM Y
//#define DRS_CVEL_SWITCH "Y"


 uves_parameters_new_int(list,recipe_id,"FLAMES_DRS_SFF_HW_MIN",10,
			 "Minimum half width of slit flat field");

// Simultaneous corvel simcal data reduction
//double DRS_CVEL_MIN = -6.;
//double DRS_CVEL_MAX = +6.;
//double DRS_CVEL_STEP = 0.5;


 uves_parameters_new_boolean(list,recipe_id,"DRS_BLAZE_SW",true,
			 "SWITCH FOR generating not blaze corrected extracted frames.");

 return cpl_error_get_code();
}

void uves_parameters_new_int( cpl_parameterlist* list,
  const char* recipe_id, const char* name,int value, const char* comment)
{
  char paramname[256];
  char recipename[256];
  cpl_parameter* p =NULL;


  sprintf(recipename,"xsh.%s",recipe_id);
  sprintf(paramname,"%s.%s",recipename,name);

  assure(list != NULL,CPL_ERROR_NULL_INPUT,"parameters list is NULL"); 

  check_nomsg(p = cpl_parameter_new_value(paramname,CPL_TYPE_INT,comment,
    recipename,value));
  check_nomsg(cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,name));
  check_nomsg(cpl_parameterlist_append(list,p));

  cleanup:
    return;
}


void uves_parameters_new_boolean( cpl_parameterlist* list,
  const char* recipe_id, const char* name,int value, const char* comment)
{
  char paramname[256];
  char recipename[256];
  cpl_parameter* p =NULL;
                                                                                                                                                             
                                                                                                                                                             
  sprintf(recipename,"xsh.%s",recipe_id);
  sprintf(paramname,"%s.%s",recipename,name);
  assure(list != NULL,CPL_ERROR_NULL_INPUT,"parameters list is NULL"); 

  check_nomsg(p = cpl_parameter_new_value(paramname,CPL_TYPE_BOOL,comment,
    recipename,value));
  check_nomsg(cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,name));
  check_nomsg(cpl_parameterlist_append(list,p));
                                                                                                                                                             
  cleanup:
    return;
}

void uves_parameters_new_string( cpl_parameterlist* list,
				       const char* recipe_id,
				       const char* name,
				       const char *value,
				       const char* comment)
{
  char * paramname = NULL ;
  char * recipename = NULL ;
  cpl_parameter* p =NULL;

  recipename = cpl_sprintf( "uves.%s", recipe_id);
  paramname = cpl_sprintf( "%s.%s",recipename, name);

  assure(list != NULL,CPL_ERROR_NULL_INPUT,"parameters list is NULL"); 

  check_nomsg(p = cpl_parameter_new_value(paramname,CPL_TYPE_STRING, comment,
				    recipename, value));
  check_nomsg(cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,name));
  check_nomsg(cpl_parameterlist_append(list,p));

 cleanup:
  cpl_free(recipename);
  cpl_free(paramname);
  return;
}

void uves_parameters_new_double( cpl_parameterlist* list,
  const char* recipe_id,const char* name,double value, const char* comment)
{
  char * paramname = NULL ;
  char * recipename = NULL ;
  cpl_parameter* p =NULL;


  recipename = cpl_sprintf( "uves.%s", recipe_id);
  paramname = cpl_sprintf( "%s.%s",recipename, name);

  assure(list != NULL,CPL_ERROR_NULL_INPUT,"parameters list is NULL");

  check_nomsg(p = cpl_parameter_new_value(paramname,CPL_TYPE_DOUBLE,comment,
    recipename,value));
  check_nomsg(cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,name));
  check_nomsg(cpl_parameterlist_append(list,p));

  cleanup:
  cpl_free(recipename);
  cpl_free(paramname);
    return;
}

void uves_parameters_new_float( cpl_parameterlist* list,
  const char* recipe_id,const char* name,float value, const char* comment)
{
  char * paramname = NULL ;
  char * recipename = NULL ;
  cpl_parameter* p =NULL;


  recipename = cpl_sprintf( "uves.%s", recipe_id);
  paramname = cpl_sprintf( "%s.%s",recipename, name);

  assure(list != NULL,CPL_ERROR_NULL_INPUT,"parameters list is NULL");

  check_nomsg(p = cpl_parameter_new_value(paramname,CPL_TYPE_FLOAT,comment,
    recipename,value));
  check_nomsg(cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,name));
  check_nomsg(cpl_parameterlist_append(list,p));

  cleanup:
  cpl_free(recipename);
  cpl_free(paramname);
    return;
}

void uves_parameters_new_range_int( cpl_parameterlist* list,
					  const char* recipe_id,
					  const char* name,
					  int def, int min, int max,
					  const char* comment)
{
  char * paramname = NULL ;
  char * recipename = NULL ;
  cpl_parameter* p =NULL;


  recipename = cpl_sprintf( "uves.%s", recipe_id);
  paramname = cpl_sprintf( "%s.%s",recipename, name);

  assure(list != NULL,CPL_ERROR_NULL_INPUT,"parameters list is NULL");

  check_nomsg(p = cpl_parameter_new_range( paramname,CPL_TYPE_INT, comment,
    recipename, def, min, max ));
  check_nomsg(cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,name));
  check_nomsg(cpl_parameterlist_append(list,p));

  cleanup:
  cpl_free(recipename);
  cpl_free(paramname);
    return;
}


void uves_parameters_new_range_float( cpl_parameterlist* list,
					  const char* recipe_id,
					  const char* name,
					  float def, float min, float max,
					  const char* comment)
{
  char * paramname = NULL ;
  char * recipename = NULL ;
  cpl_parameter* p =NULL;

  recipename = cpl_sprintf( "uves.%s", recipe_id);
  paramname = cpl_sprintf( "%s.%s",recipename, name);


  assure(list != NULL,CPL_ERROR_NULL_INPUT,"parameters list is NULL");

  check_nomsg(p = cpl_parameter_new_range( paramname,CPL_TYPE_FLOAT, comment,
    recipename, def, min, max ));
  check_nomsg(cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,name));
  check_nomsg(cpl_parameterlist_append(list,p));

  cleanup:
  cpl_free(recipename);
  cpl_free(paramname);
    return;
}


void uves_parameters_new_range_double( cpl_parameterlist* list,
					  const char* recipe_id,
					  const char* name,
					  double def, double min, double max,
					  const char* comment)
{
  char * paramname = NULL ;
  char * recipename = NULL ;
  cpl_parameter* p =NULL;

  recipename = cpl_sprintf( "uves.%s", recipe_id);
  paramname = cpl_sprintf( "%s.%s",recipename, name);


  assure(list != NULL,CPL_ERROR_NULL_INPUT,"parameters list is NULL");

  check_nomsg(p = cpl_parameter_new_range( paramname,CPL_TYPE_DOUBLE, comment,
    recipename, def, min, max ));
  check_nomsg(cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,name));
  check_nomsg(cpl_parameterlist_append(list,p));

  cleanup:
  cpl_free(recipename);
  cpl_free(paramname);
    return;
}

char * uves_parameters_get_string( const cpl_parameterlist* list,
  const char* recipe_id, const char* name)
{
  char paramname[256];
  cpl_parameter * p =NULL;
  char * result = NULL ;

  sprintf(paramname,"xsh.%s.%s",recipe_id, name);

  p = cpl_parameterlist_find( (cpl_parameterlist *)list, paramname);
  if ( p == NULL ) goto cleanup ;
  result = (char *)cpl_parameter_get_string(p) ;

  cleanup:
    return result;
}


int uves_parameters_get_boolean( const cpl_parameterlist * list,
				const char* recipe_id, const char* name)
{
  char * paramname = NULL ;
  char * recipename = NULL ;
  cpl_parameter* p =NULL;
  int result = 0;
                                                                                                                                                             
  recipename = cpl_sprintf( "uves.%s", recipe_id);
  paramname = cpl_sprintf( "%s.%s",recipename, name);
                                                                                                                                                             
  assure(list != NULL,CPL_ERROR_NULL_INPUT,"parameters list is NULL");
                                                                                                                                                             
  check_nomsg(p = cpl_parameterlist_find( (cpl_parameterlist *)list,paramname));
  check_nomsg(result = cpl_parameter_get_bool( p));
                                                                                                                                                             
  cleanup:
  cpl_free(recipename);
  cpl_free(paramname);
    return result;
}


int uves_parameters_get_int( cpl_parameterlist* list,
  const char* recipe_id, const char* name)
{
  char * paramname =NULL;
  char * recipename =NULL;
  cpl_parameter* p =NULL;
  int result = 0;
  assure(list != NULL,CPL_ERROR_NULL_INPUT,"parameters list is NULL");
  assure(recipe_id != NULL,CPL_ERROR_NULL_INPUT,"input recipe id is NULL");
  assure(name != NULL,CPL_ERROR_NULL_INPUT,"input param name is NULL");

  sprintf(recipename,"xsh.%s",recipe_id);
  sprintf(paramname,"%s.%s",recipename,name);

  check_nomsg(p = cpl_parameterlist_find( (cpl_parameterlist *)list,paramname));
  check_nomsg(result = cpl_parameter_get_int(p));

  cleanup:
    return result;
}

double uves_parameters_get_double( cpl_parameterlist* list,
  const char* recipe_id, const char* name)
{
  char * paramname = NULL ;
  char * recipename = NULL ;
  cpl_parameter* p =NULL;
  double result = 0.0;

  recipename = cpl_sprintf( "uves.%s", recipe_id);
  paramname = cpl_sprintf( "%s.%s",recipename, name);

  assure(list != NULL,CPL_ERROR_NULL_INPUT,"parameters list is NULL");
  
  check_nomsg(p = cpl_parameterlist_find(list,paramname));
  check_nomsg(result = cpl_parameter_get_double(p));

  cleanup:
  cpl_free(recipename);
  cpl_free(paramname);
    return result;
} 



cpl_error_code
flames_update_drs_par(cpl_propertylist* plist)
{

  
  //const int BKGPOL[2] = {4, 5};
  DECENTSNR=cpl_propertylist_get_double(plist,"DECENTSNR");
  MATCHTHRES=cpl_propertylist_get_double(plist,"MATCHTHRES");
  HALFIBREWIDTH=cpl_propertylist_get_double(plist,"HALFIBREWIDTH");
  MAXFIBRES=cpl_propertylist_get_int(plist,"MAXFIBRES");
  FLAMES_SAV_BORD_SZ=cpl_propertylist_get_int(plist,"FLAMES_SAV_BORD_SZ");
  FLAMES_X_WIND_SIZE = cpl_propertylist_get_int(plist,"FLAMES_X_WIND_SIZE");
  FLAMES_Y_WIND_SIZE = cpl_propertylist_get_int(plist,"FLAMES_Y_WIND_SIZE");
  FLAMES_Y_SEARCH_WIND=cpl_propertylist_get_int(plist,"FLAMES_Y_SEARCH_WIND");
  FLAMES_ORD_TRESH=cpl_propertylist_get_int(plist,"FLAMES_ORD_TRESH");
  FLAMES_N_CLIP_MED=cpl_propertylist_get_int(plist,"FLAMES_N_CLIP_MED");
  FLAMES_N_CLIP_AVG = cpl_propertylist_get_int(plist,"FLAMES_N_CLIP_AVG");
  FLAMES_INT_TRESH = cpl_propertylist_get_double(plist,"FLAMES_INT_TRESH");
  NBTRACES=cpl_propertylist_get_int(plist,"NBTRACES");
  MINFIBREFRAC =cpl_propertylist_get_double(plist,"MINFIBREFRAC");
  BKGFITINLINE=cpl_propertylist_get_string(plist,"BKGFITINLINE");
  BKGFITMETHOD=cpl_propertylist_get_string(plist,"BKGFITMETHOD");
  BKGBADSCAN=cpl_propertylist_get_string(plist,"BKGBADSCAN");

  //const int BKGBADWIN[2]={50,50};
  BKGBADWINX=cpl_propertylist_get_int(plist,"BKGBADWINX");
  BKGBADWINY=cpl_propertylist_get_int(plist,"BKGBADWINY");

  BKGBADMAXFRAC = cpl_propertylist_get_double(plist,"BKGBADMAXFRAC");
  BKGBADMAXTOT = cpl_propertylist_get_int(plist,"BKGBADMAXTOT");
  BKG_MAX_IO_WIN =cpl_propertylist_get_int(plist,"BKG_MAX_IO_WIN");
  //const int DRS_BKG_FIT_POL[2] = {4,5};
  DRS_BKG_FIT_POL_X = cpl_propertylist_get_int(plist,"DRS_BKG_FIT_POL_X");
  DRS_BKG_FIT_POL_Y = cpl_propertylist_get_int(plist,"DRS_BKG_FIT_POL_Y");
  //const int DRS_FILT_HW[2] = {2,1};
  DRS_FILT_HW_X = cpl_propertylist_get_int(plist,"DRS_FILT_HW_X");
  DRS_FILT_HW_Y = cpl_propertylist_get_int(plist,"DRS_FILT_HW_Y");
  DRS_FILT_IMAX = cpl_propertylist_get_int(plist,"DRS_FILT_IMAX");
  DRS_FILT_KS = cpl_propertylist_get_int(plist,"DRS_FILT_KS");
  DRS_FILT_SAT_SW =cpl_propertylist_get_string(plist,"DRS_FILT_SAT_SW");
  DRS_FILT_MASK = cpl_propertylist_get_string(plist,"DRS_FILT_MASK");
  GAUSSFIBRESIGMA =cpl_propertylist_get_double(plist,"GAUSSFIBRESIGMA");
  GAUSSHALFWIDTH =cpl_propertylist_get_double(plist,"GAUSSHALFWIDTH");
  MAXYSHIFT =cpl_propertylist_get_double(plist,"MAXYSHIFT");
  MAXBACKITERS =cpl_propertylist_get_int(plist,"MAXBACKITERS");
  MAXDISCARDFRACT =cpl_propertylist_get_double(plist,"MAXDISCARDFRACT");
  MAXCORRITERS =cpl_propertylist_get_int(plist,"MAXCORRITERS");
  CORRELTOL =cpl_propertylist_get_double(plist,"CORRELTOL");
  CORRELXSTEP =cpl_propertylist_get_int(plist,"CORRELXSTEP");
  GAUSSCORRELSCL =cpl_propertylist_get_double(plist,"GAUSSCORRELSCL");
  GAUSSCORRELWND =cpl_propertylist_get_double(plist,"GAUSSCORRELWND");
  MAXCLEANITERS =cpl_propertylist_get_int(plist,"MAXCLEANITERS");
  MAXSINGLEPXFRC =cpl_propertylist_get_double(plist,"MAXSINGLEPXFRC");
  MAXOPTITERSINT =cpl_propertylist_get_int(plist,"MAXOPTITERSINT");
  MINOPTITERSINT =cpl_propertylist_get_int(plist,"MINOPTITERSINT");
  XKILLSIZE =cpl_propertylist_get_int(plist,"XKILLSIZE");
  YKILLSIZE =cpl_propertylist_get_int(plist,"YKILLSIZE");
  MAXORDER =cpl_propertylist_get_int(plist,"MAXORDER");
  DYRANGE =cpl_propertylist_get_int(plist,"DYRANGE");
  DYSTEP =cpl_propertylist_get_double(plist,"DYSTEP");
  MASKTHRES =cpl_propertylist_get_double(plist,"MASKTHRES");
  FRACSLICESTHRES =cpl_propertylist_get_double(plist,"FRACSLICESTHRES");
  MAXROWS =cpl_propertylist_get_int(plist,"MAXROWS");
  MAXCOLS =cpl_propertylist_get_int(plist,"MAXCOLS");
  DRS_PTHRE_MAX =cpl_propertylist_get_int(plist,"DRS_PTHRE_MAX");
  DRS_PTHRE_MIN =cpl_propertylist_get_int(plist,"DRS_PTHRE_MIN");
  DRS_EXT_MTD = cpl_propertylist_get_string(plist,"DRS_EXT_MTD");
  DRS_K_S_THRE =cpl_propertylist_get_double(plist,"DRS_K_S_THRE");
  DRS_KSIGMA_THRE =cpl_propertylist_get_int(plist,"DRS_KSIGMA_THRE");
  DRS_EXT_W_SIZ =cpl_propertylist_get_double(plist,"DRS_EXT_W_SIZ");
  DRS_MIDAS2FITS = cpl_propertylist_get_string(plist,"DRS_MIDAS2FITS");

// <num>: constant value subtraction
  DRS_BIAS_MTD = cpl_propertylist_get_string(plist,"DRS_BIAS_MTD");
  DRS_FILT_SW = cpl_propertylist_get_string(plist,"DRS_FILT_SW");
  DRS_VERBOSITY = cpl_propertylist_get_string(plist,"DRS_VERBOSITY");
  DRS_CUBIFY = cpl_propertylist_get_string(plist,"DRS_CUBIFY");
//const char* DRS_VERBOSITY = "HIGH";
  DRS_COR_MAX_FND = cpl_propertylist_get_string(plist,"DRS_COR_MAX_FND");
  DRS_COR_DEF_RNG = cpl_propertylist_get_float(plist,"DRS_COR_DEF_RNG");
  DRS_COR_DEF_PNT = cpl_propertylist_get_int(plist,"DRS_COR_DEF_PNT");
  DRS_COR_DEF_OFF = cpl_propertylist_get_float(plist,"DRS_COR_DEF_OFF");

  DRS_BASE_NAME = cpl_propertylist_get_string(plist,"DRS_BASE_NAME");

  DRS_P8_OFPOS_S1_1 =cpl_propertylist_get_double(plist,"DRS_P8_OFPOS_S1_1");
  DRS_P8_OFPOS_S1_2 =cpl_propertylist_get_double(plist,"DRS_P8_OFPOS_S1_2");
  DRS_P8_OFPOS_S1_3 =cpl_propertylist_get_double(plist,"DRS_P8_OFPOS_S1_3");

  DRS_SCAN_MIN_1 =cpl_propertylist_get_int(plist,"DRS_SCAN_MIN_1");
  DRS_SCAN_MIN_2 =cpl_propertylist_get_int(plist,"DRS_SCAN_MIN_2");
  DRS_SCAN_MIN_3 =cpl_propertylist_get_int(plist,"DRS_SCAN_MIN_3");
  DRS_SCAN_MAX_1 =cpl_propertylist_get_int(plist,"DRS_SCAN_MAX_1");
  DRS_SCAN_MAX_2 =cpl_propertylist_get_int(plist,"DRS_SCAN_MAX_2");
  DRS_SCAN_MAX_3 =cpl_propertylist_get_int(plist,"DRS_SCAN_MAX_3");
  DRS_DEL_SW = cpl_propertylist_get_string(plist,"DRS_DEL_SW");
  FLAMES_DRS_SFF_HW_MIN=cpl_propertylist_get_int(plist,"FLAMES_DRS_SFF_HW_MIN");
  DRS_CVEL_MIN =cpl_propertylist_get_double(plist,"DRS_CVEL_MIN");
  DRS_CVEL_MAX =cpl_propertylist_get_double(plist,"DRS_CVEL_MAX");
  DRS_CVEL_STEP =cpl_propertylist_get_double(plist,"DRS_CVEL_STEP");

  //DRS_BLAZE_SW =cpl_propertylist_get_boolean(plist,"DRS_BLAZE_SW");
  

  return cpl_error_get_code();

}



cpl_error_code
flames_save_drs_par(cpl_propertylist* plist)
{

  
  //const int BKGPOL[2] = {4, 5};
  cpl_propertylist_set_double(plist,"DECENTSNR",DECENTSNR);
  cpl_propertylist_set_double(plist,"MATCHTHRES",MATCHTHRES);
  cpl_propertylist_set_double(plist,"HALFIBREWIDTH",HALFIBREWIDTH);
  cpl_propertylist_set_int(plist,"MAXFIBRES",MAXFIBRES);
  cpl_propertylist_set_int(plist,"FLAMES_SAV_BORD_SZ",FLAMES_SAV_BORD_SZ);
  cpl_propertylist_set_int(plist,"FLAMES_X_WIND_SIZE",FLAMES_X_WIND_SIZE);
  cpl_propertylist_set_int(plist,"FLAMES_Y_WIND_SIZE",FLAMES_Y_WIND_SIZE);
  cpl_propertylist_set_int(plist,"FLAMES_Y_SEARCH_WIND",FLAMES_Y_SEARCH_WIND);
  cpl_propertylist_set_int(plist,"FLAMES_ORD_TRESH",FLAMES_ORD_TRESH);
  cpl_propertylist_set_int(plist,"FLAMES_N_CLIP_MED",FLAMES_N_CLIP_MED);
  cpl_propertylist_set_int(plist,"FLAMES_N_CLIP_AVG",FLAMES_N_CLIP_AVG);
  cpl_propertylist_set_double(plist,"FLAMES_INT_TRESH",FLAMES_INT_TRESH);
  cpl_propertylist_set_int(plist,"NBTRACES",NBTRACES);
  cpl_propertylist_set_double(plist,"MINFIBREFRAC",MINFIBREFRAC);
  cpl_propertylist_set_string(plist,"BKGFITINLINE",BKGFITINLINE);
  cpl_propertylist_set_string(plist,"BKGFITMETHOD",BKGFITMETHOD);
  cpl_propertylist_set_string(plist,"BKGBADSCAN",BKGBADSCAN);

  //const int BKGBADWIN[2]={50,50};
  cpl_propertylist_set_int(plist,"BKGBADWINX",BKGBADWINX);
  cpl_propertylist_set_int(plist,"BKGBADWINY",BKGBADWINY);

  cpl_propertylist_set_double(plist,"BKGBADMAXFRAC",BKGBADMAXFRAC);
  cpl_propertylist_set_int(plist,"BKGBADMAXTOT",BKGBADMAXTOT);
  cpl_propertylist_set_int(plist,"BKG_MAX_IO_WIN",BKG_MAX_IO_WIN);
  //const int DRS_BKG_FIT_POL[2] = {4,5};
  cpl_propertylist_set_int(plist,"DRS_BKG_FIT_POL_X",DRS_BKG_FIT_POL_X);
  cpl_propertylist_set_int(plist,"DRS_BKG_FIT_POL_Y",DRS_BKG_FIT_POL_Y);
  //const int DRS_FILT_HW[2] = {2,1};
  cpl_propertylist_set_int(plist,"DRS_FILT_HW_X",DRS_FILT_HW_X);
  cpl_propertylist_set_int(plist,"DRS_FILT_HW_Y",DRS_FILT_HW_Y);
  cpl_propertylist_set_int(plist,"DRS_FILT_IMAX",DRS_FILT_IMAX);
  cpl_propertylist_set_int(plist,"DRS_FILT_KS",DRS_FILT_KS);
  cpl_propertylist_set_string(plist,"DRS_FILT_SAT_SW",DRS_FILT_SAT_SW);
  cpl_propertylist_set_string(plist,"DRS_FILT_MASK",DRS_FILT_MASK);
  cpl_propertylist_set_double(plist,"GAUSSFIBRESIGMA",GAUSSFIBRESIGMA);
  cpl_propertylist_set_double(plist,"GAUSSHALFWIDTH",GAUSSHALFWIDTH);
  cpl_propertylist_set_double(plist,"MAXYSHIFT",MAXYSHIFT);
  cpl_propertylist_set_int(plist,"MAXBACKITERS",MAXBACKITERS);
  cpl_propertylist_set_double(plist,"MAXDISCARDFRACT",MAXDISCARDFRACT);
  cpl_propertylist_set_int(plist,"MAXCORRITERS",MAXCORRITERS);
  cpl_propertylist_set_double(plist,"CORRELTOL",CORRELTOL);
  cpl_propertylist_set_int(plist,"CORRELXSTEP",CORRELXSTEP);
  cpl_propertylist_set_double(plist,"GAUSSCORRELSCL",GAUSSCORRELSCL);
  cpl_propertylist_set_double(plist,"GAUSSCORRELWND",GAUSSCORRELWND);
  cpl_propertylist_set_int(plist,"MAXCLEANITERS",MAXCLEANITERS);
  cpl_propertylist_set_double(plist,"MAXSINGLEPXFRC",MAXSINGLEPXFRC);
  cpl_propertylist_set_int(plist,"MAXOPTITERSINT",MAXOPTITERSINT);
  cpl_propertylist_set_int(plist,"MINOPTITERSINT",MINOPTITERSINT);
  cpl_propertylist_set_int(plist,"XKILLSIZE",XKILLSIZE);
  cpl_propertylist_set_int(plist,"YKILLSIZE",YKILLSIZE);
  cpl_propertylist_set_int(plist,"MAXORDER",MAXORDER);
  cpl_propertylist_set_int(plist,"DYRANGE",DYRANGE);
  cpl_propertylist_set_double(plist,"DYSTEP",DYSTEP);
  cpl_propertylist_set_double(plist,"MASKTHRES",MASKTHRES);
  cpl_propertylist_set_double(plist,"FRACSLICESTHRES",FRACSLICESTHRES);
  cpl_propertylist_set_int(plist,"MAXROWS",MAXROWS);
  cpl_propertylist_set_int(plist,"MAXCOLS",MAXCOLS);
  cpl_propertylist_set_int(plist,"DRS_PTHRE_MAX",DRS_PTHRE_MAX);
  cpl_propertylist_set_int(plist,"DRS_PTHRE_MIN",DRS_PTHRE_MIN);
  cpl_propertylist_set_string(plist,"DRS_EXT_MTD",DRS_EXT_MTD);
  cpl_propertylist_set_double(plist,"DRS_K_S_THRE",DRS_K_S_THRE);
  cpl_propertylist_set_int(plist,"DRS_KSIGMA_THRE",DRS_KSIGMA_THRE);
  cpl_propertylist_set_double(plist,"DRS_EXT_W_SIZ",DRS_EXT_W_SIZ);
  cpl_propertylist_set_string(plist,"DRS_MIDAS2FITS",DRS_MIDAS2FITS);

// <num>: constant value subtraction
  cpl_propertylist_set_string(plist,"DRS_BIAS_MTD",DRS_BIAS_MTD);
  cpl_propertylist_set_string(plist,"DRS_FILT_SW",DRS_FILT_SW);
  cpl_propertylist_set_string(plist,"DRS_VERBOSITY",DRS_VERBOSITY);
  cpl_propertylist_set_string(plist,"DRS_CUBIFY",DRS_CUBIFY);
//const char* DRS_VERBOSITY = "HIGH";
  cpl_propertylist_set_string(plist,"DRS_COR_MAX_FND",DRS_COR_MAX_FND);
  cpl_propertylist_set_float(plist,"DRS_COR_DEF_RNG",DRS_COR_DEF_RNG);
  cpl_propertylist_set_int(plist,"DRS_COR_DEF_PNT",DRS_COR_DEF_PNT);
  cpl_propertylist_set_float(plist,"DRS_COR_DEF_OFF",DRS_COR_DEF_OFF);

  cpl_propertylist_set_string(plist,"DRS_BASE_NAME",DRS_BASE_NAME);

  cpl_propertylist_set_double(plist,"DRS_P8_OFPOS_S1_1",DRS_P8_OFPOS_S1_1);
  cpl_propertylist_set_double(plist,"DRS_P8_OFPOS_S1_2",DRS_P8_OFPOS_S1_2);
  cpl_propertylist_set_double(plist,"DRS_P8_OFPOS_S1_3",DRS_P8_OFPOS_S1_3);

  cpl_propertylist_set_int(plist,"DRS_SCAN_MIN_1",DRS_SCAN_MIN_1);
  cpl_propertylist_set_int(plist,"DRS_SCAN_MIN_2",DRS_SCAN_MIN_2);
  cpl_propertylist_set_int(plist,"DRS_SCAN_MIN_3",DRS_SCAN_MIN_3);
  cpl_propertylist_set_int(plist,"DRS_SCAN_MAX_1",DRS_SCAN_MAX_1);
  cpl_propertylist_set_int(plist,"DRS_SCAN_MAX_2",DRS_SCAN_MAX_2);
  cpl_propertylist_set_int(plist,"DRS_SCAN_MAX_3",DRS_SCAN_MAX_3);

  cpl_propertylist_set_string(plist,"DRS_DEL_SW",DRS_DEL_SW);
  cpl_propertylist_set_int(plist,"FLAMES_DRS_SFF_HW_MIN",FLAMES_DRS_SFF_HW_MIN);
  cpl_propertylist_set_double(plist,"DRS_CVEL_MIN",DRS_CVEL_MIN);
  cpl_propertylist_set_double(plist,"DRS_CVEL_MAX",DRS_CVEL_MAX);
  cpl_propertylist_set_double(plist,"DRS_CVEL_STEP",DRS_CVEL_STEP);

  //cpl_propertylist_set_boolean(plist,"DRS_BLAZE_SW",DRS_BLAZE_SW);
 

  return cpl_error_get_code();

}

/**@}*/


