/* $Id: xsh_drl.h,v 1.227 2013-03-25 14:47:29 amodigli Exp $
 *
 * This file is part of the X-shooter Pipeline
 * Copyright (C) 2006 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * $Author: amodigli $
 * $Date: 2013-03-25 14:47:29 $
 * $Revision: 1.227 $
 * $Name: not supported by cvs2svn $
 */

#ifndef XSH_DRL_H
#define XSH_DRL_H

/*-----------------------------------------------------------------------------
                                    Includes
 -----------------------------------------------------------------------------*/
#include <cpl.h>
#include <xsh_error.h>
#include <xsh_dfs.h>
#include <xsh_utils.h>
#include <xsh_data_pre.h>
#include <xsh_data_rec.h>
#include <xsh_data_instrument.h>
#include <xsh_data_order.h>
#include <xsh_data_dispersol.h>
#include <xsh_parameters.h>
#include <xsh_qc_handling.h>
/*-----------------------------------------------------------------------------
                             Defines
 -----------------------------------------------------------------------------*/
#define XSH_CONCAT(A,B) A ## B
#define XSH_STRING(A) # A

#define PICKUP_NOISE_HOT_PIXEL_MAP 

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

/*-----------------------------------------------------------------------------
                                    Prototypes
 -----------------------------------------------------------------------------*/
#define REGDEBUG_OPTEXTRACT 0
cpl_frame*
xsh_bpmap_2pre(cpl_frame* bpmap,const char* prefix, xsh_instrument* inst);

void 
xsh_prepare( cpl_frameset* frames, cpl_frame* bpmap, cpl_frame* mbias,
	     const char* prefix, xsh_instrument* instr,
	     const int pre_overscan_corr,const bool flag_neg_and_thresh_pix);
cpl_frame * xsh_preframe_extract( cpl_frame* frame, int xmin, int ymin,
  int xmax, int ymax, const char* name, xsh_instrument *instr);

cpl_frame * 
xsh_remove_crh_multiple( cpl_frameset* rawFrames,
			 const char * name,
			 xsh_stack_param* stack_param,
			 xsh_clipping_param * crh_clipping,
			 xsh_instrument* inst ,
			 cpl_imagelist **, 
			 cpl_image** , const int save_tmp) ;

#if defined(PICKUP_NOISE_HOT_PIXEL_MAP)
cpl_frame * 
xsh_compute_noise_map( cpl_imagelist *, cpl_frame * bpmap,
		       xsh_clipping_param *,
		       xsh_instrument* instr,
		       cpl_frame ** noisemap ) ;
#else
cpl_frame * 
xsh_compute_noise_map( cpl_imagelist *, 
		       cpl_frame * bpmap,
		       xsh_clipping_param *, 
		       xsh_instrument* instr) ;
#endif

cpl_frame * 
xsh_create_master_dark( cpl_frame* bpMap,
			xsh_instrument* instr,
			cpl_parameterlist* parameters,
                        cpl_frame* crh_frm,cpl_frame* bp_map_frm);

cpl_frame *
xsh_create_master_dark2(cpl_frameset * raws, 
                        xsh_stack_param* stack_param, 
                        cpl_parameterlist* drs_param,
                        cpl_propertylist* qc_log,
                        xsh_instrument* instr);

cpl_frame *
xsh_compute_qc_on_master_bias (cpl_frameset* raws, 
                        cpl_frame * frame, 
                        xsh_instrument* instr,
                        cpl_parameterlist* drs_params);


cpl_frame * xsh_create_master_flat( cpl_frame* frame,xsh_instrument * instr);
cpl_frame * xsh_create_master_flat_with_mask( cpl_frame* frame,cpl_frame* edges,xsh_instrument * instr);
cpl_frame* 
xsh_create_master_flat2(cpl_frameset *set,
                        cpl_frame * order_tab_cen,
                        xsh_stack_param* stack_par,
                        xsh_instrument* inst);

cpl_frame * xsh_create_master_dark_bpmap( cpl_frame* frame,xsh_instrument * instr);

/* compute Linearity related functions */
cpl_frame * xsh_compute_linearity( cpl_frameset *, xsh_instrument *,
				   xsh_clipping_param *,const int decode_bp ) ;

int 
xsh_linear_group_by_exptime( cpl_frameset *, 
			     xsh_instrument *,
			     double ,  
			     cpl_frameset ** ) ;

cpl_frame* 
xsh_subtract_bias(cpl_frame* frame, 
		  cpl_frame* bias,
		  xsh_instrument* instr, 
		   const char* type,
		   const int pre_overscan_corr,const int save_tmp);

cpl_frameset* 
xsh_subtract_nir_on_off(cpl_frameset* on, 
			cpl_frameset* off,
			xsh_instrument* instr);
cpl_frame* 
xsh_subtract_dark(cpl_frame * frame,
		  cpl_frame * dark,
		  const char* filename, 
		  xsh_instrument* instr);

#define XSH_DIVIDE_FLAT_THRESH 1e-10
cpl_frame* xsh_divide_flat(cpl_frame * frame, cpl_frame * flat, 
  const char* filename, xsh_instrument* instr);

#define XSH_MULTIPLY_FLAT_THRESH 1e+30
cpl_frame* xsh_multiply_flat(cpl_frame * frame, cpl_frame * flat, 
  const char* filename, xsh_instrument* instr);


cpl_frame* 
xsh_subtract_background(cpl_frame * frame, 
			cpl_frame* ordertable,
			xsh_background_param* bckg,
			xsh_instrument* instr,
			const char* prefix,
			cpl_frame** grid_frame,
			cpl_frame** frame_backg,const int save_bkg, const int save_grid, const int save_sub_bkg);
cpl_frame* 
xsh_detect_order_edge(cpl_frame* frame,
		      cpl_frame* order_table,
		      xsh_detect_order_param * det_param,
		      xsh_instrument* instr);

cpl_frame * 
xsh_detect_continuum( cpl_frame* frame,
		      cpl_frame* order_table,
		      cpl_frame * spectral_format,
		      xsh_detect_continuum_param * param,
		      xsh_clipping_param * dcn_clipping,
		      xsh_instrument* instr, 
		      cpl_frame** resid_frame) ;

cpl_frame *
xsh_order_table_from_fmtchk( xsh_pre * pre,
			     cpl_frame * spectral_frame,
			     xsh_detect_continuum_param * detect_param,
			     xsh_instrument * instrument ) ;

/* precision between to rays in nm */
#define WAVELENGTH_PRECISION 0.00001
#define SLIT_PRECISION 0.00001
#define SLIT_PRECISION_IFU 0.21

void xsh_create_map( cpl_frame *dispsol_frame, cpl_frame *ordertab_frame,
  cpl_frame *pre_frame, xsh_instrument *instrument, cpl_frame **wavemap_frame,
		     cpl_frame **slitmap_frame,const char* rec_prefix);

cpl_frame * 
xsh_create_wavemap( cpl_frame * in_frame,
		    cpl_frame * resid_frame,
		    cpl_frame * order_frame,
		    xsh_dispersol_param * dispersol_param,
		    xsh_instrument * instrument );

cpl_frame * xsh_create_poly_wavemap( cpl_frame *pre_frame, 
  cpl_frame *wave_tab_2d_frame, cpl_frame *order_tab_frame, 
  cpl_frame *spectral_format_frame, xsh_dispersol_param *dispsol_par, 
  xsh_instrument * instrument, const char * filename, 
  cpl_frame **dispersol_frame, cpl_frame **slitmap_frame);

void 
xsh_create_model_map( cpl_frame* model_frame, xsh_instrument* instrument, 
                      const char* wave_map_tag, const char* slit_map_tag,
                      cpl_frame **wavemap_frame, cpl_frame **slitmap_frame,const int save_tmp);

cpl_frame * 
xsh_create_order_table(  cpl_frame * in_frame,
			 cpl_frame * spectralformat_frame,
			 cpl_frame * resid_frame,
			 cpl_frame * arclines,
			 xsh_detect_arclines_param * da,
			 xsh_clipping_param * dac,
			 xsh_instrument * instrument ) ;

#define XSH_DETECT_ARCLINES_TYPE_POLY 0
#define XSH_DETECT_ARCLINES_TYPE_MODEL 1
#define XSH_DETECT_ARCLINES_MODE_NORMAL 0
#define XSH_DETECT_ARCLINES_MODE_CORRECTED 1
#define XSH_DETECT_ARCLINES_MODE_RECOVER 2

typedef enum {
  XSH_SOLUTION_ABSOLUTE,
  XSH_SOLUTION_RELATIVE
} xsh_sol_wavelength;

void 
xsh_detect_arclines( cpl_frame *frame,
		     cpl_frame *theo_tab_frame,
		     cpl_frame *arc_lines_tab_frame,
		     cpl_frame* wave_tab_guess_frame,
		     cpl_frame *order_tab_recov_frame,
		     cpl_frame *config_model_frame,
		     cpl_frame *spectralformat_frame,
		     cpl_frame **resid_tab_orders_frame,
		     cpl_frame **arc_lines_clean_tab_frame,
		     cpl_frame **wave_tab_frame,
		     cpl_frame **resid_tab_frame,
		     xsh_sol_wavelength type,
		     xsh_detect_arclines_param *da, 
		     xsh_clipping_param *dac,
		     xsh_instrument *instr,
                     const char* rec_id,
                     const int clean_tmp,
                     const int resid_tab_name_sw);

void 
xsh_detect_arclines_dan( cpl_frame *frame,
		     cpl_frame *theo_tab_frame,
		     cpl_frame *arc_lines_tab_frame,
		     cpl_frame* wave_tab_guess_frame,
		     cpl_frame *order_tab_recov_frame,
		     cpl_frame *config_model_frame,
		     cpl_frame *spectralformat_frame,
		     cpl_frame **resid_tab_orders_frame,
		     cpl_frame **arc_lines_clean_tab_frame,
		     cpl_frame **wave_tab_frame,
		     cpl_frame **resid_tab_frame,
		     xsh_sol_wavelength type,
		     xsh_detect_arclines_param *da, 
		     xsh_clipping_param *dac,
		     xsh_instrument *instr,
                     const char* rec_id,
			 const int clean_tmp,
			 const int resid_tab_name_sw);

void
xsh_follow_arclines_slit( cpl_frame *inframe,
                     cpl_frame *arclines,
                     cpl_frame *wavesol,
                     cpl_frame *order_table,
                     cpl_frame *spectralformat_frame,
                     cpl_frame *model_config_frame,
                     cpl_frame *wavemap_frame,
                     cpl_frame *slitmap_frame,
                     cpl_frame *disptab_frame,
                     xsh_follow_arclines_param *param,
                     xsh_instrument * instrument,
                     cpl_frame ** tilt_list,
                     cpl_frame ** shift_frame);


void 
xsh_follow_arclines_ifu( cpl_frame *inframe,
			 cpl_frame *arclines,
			 cpl_frame *wavesol, 
			 cpl_frame *order_table,
			 cpl_frame *spectralformat_frame,
			 cpl_frame *model_config_frame,
                         cpl_frame *wavemap_frame,
                         cpl_frame *slitmap_frame,
                         cpl_frame *disptab_frame,
			 xsh_follow_arclines_param *follow_param,
			 xsh_instrument * instrument,
			 cpl_frameset *tilt_set,
			 cpl_frame **shift_frame);


void xsh_rec_slit_size( xsh_rectify_param *rectify_par, double *slit_min, 
  int *nslit, XSH_MODE mode);

cpl_frame* xsh_rectify_orders( cpl_frame *sci_frame,
  xsh_order_list *orderlist_frame,
  cpl_frame *wavesol_frame,  cpl_frame *model_frame, xsh_instrument *instrument,
  xsh_rectify_param *rectify_par, cpl_frame *spectralformat_frame,
  cpl_frame *disp_tab_frame, const char * res_name, const char* tag,
  cpl_frame** res_frame_ext,cpl_frame** res_frame_tab,
  int min_index, int max_index, double slit_min, int nslit, double slit_shift,
  cpl_frame *slitshift_tab);

cpl_frameset * xsh_rectify_orders_ifu(cpl_frame *sci_frame,
  xsh_order_list *orderlist, cpl_frameset *wavesol_frameset,
  cpl_frameset *shift_frameset,
  cpl_frame *model_frame, xsh_instrument *instrument,
  xsh_rectify_param *rectify_par, cpl_frame *spectralformat_frame,
  cpl_frame * slitmap_frame,cpl_frameset ** rec_frameset_ext, cpl_frameset ** rec_frameset_tab,
  int min_index, int max_index, const char* rec_prefix);

cpl_frame *
xsh_rectify (cpl_frame * sci_frame, cpl_frame * order_table_frame,
	     cpl_frame * wavesol_frame,
	     cpl_frame * model_config_frame,
	     xsh_instrument *instrument,
	     xsh_rectify_param * rectify_par,
	     cpl_frame *spectral_format,
             cpl_frame *disp_tab_frame, 
	     const char * fname,
	     cpl_frame** res_frame_ext,cpl_frame ** res_frame_tab,
	     const char* prefix);

cpl_frame * shift_with_kw( cpl_frame * rec_frame,
                                  xsh_instrument *instrument,
                                  xsh_rectify_param * rectify_par,
                                  const char * fname,
                                  cpl_frame** res_frame_ext,
  double **ref_ra, double **ref_dec, int flag);


cpl_frame * xsh_rectify_and_shift( cpl_frame *sci_frame,
                                   cpl_frame * orderlist_frame,
                                   cpl_frame *wavesol_frame,
                                   cpl_frame * model_frame,
                                   xsh_instrument *instrument,
                                   xsh_rectify_param *rectify_par,
                                   cpl_frame *spectralformat_frame,
                                   cpl_frame * loc_frame,
                                   cpl_frame * loc0_frame,
                                   double *throw_shift,
                                   cpl_frame *disp_tab_frame,
                                   const char * res_name,
                                   cpl_frame** res_frame_ext,
                                   cpl_frame** res_frame_tab);

cpl_frameset *
xsh_rectify_ifu(cpl_frame * sci_frame,
		cpl_frame * order_table_frame,
		cpl_frameset *wavesol_frame_set,
                cpl_frameset *shiftifu_frameset,
		cpl_frame * model_config_frame,
		xsh_instrument *instrument,
		xsh_rectify_param * rectify_par,
		cpl_frame * spectral_format,
		cpl_frame * slitmap_frame, 
                cpl_frameset** rec_frameset_ext, 
                cpl_frameset** rec_frameset_tab, 
                const char* rec_prefix) ;

#define XSH_RECTIFY_TYPE_POLY 0
#define XSH_RECTIFY_TYPE_MODEL 1
cpl_frame * 
xsh_shift_rectified( cpl_frame * rec_frame,
		     cpl_frame * loc_frame,
		     cpl_frame * loc0_frame,
		     const char * file_name,
		     xsh_combine_nod_param * combine_nod_param,
		     xsh_rectify_param * rectif_par,
		     xsh_instrument * instrument,
		     cpl_frame** res_frame_ext  ) ;

void xsh_compute_slitlet_center( xsh_order_list * order_list,
				 cpl_frame * slitmap_frame,
				 double * down, double * cen,
				 double * up,
				 XSH_ARM arm ) ;



void xsh_get_slit_edges( cpl_frame *slitmap_frame, double *sdown, double *sup,
  double *sldown, double *slup, xsh_instrument *instrument);

void xsh_compute_slitlet_limits( cpl_frameset *shift_set, double sdown, 
  double sldown, double slup, double sup, double slit_bin,
  double *slitmin_tab, int *nslit_tab, double *slitcen_tab);

cpl_frame * 
xsh_subtract_sky_single (cpl_frame * sci_frame,
			 cpl_frame * order_table_frame,
			 cpl_frame * slitmap_frame,
			 cpl_frame * wavemap_frame,
			 cpl_frame * locTable_frame,
			 cpl_frame* ref_sky_list,
			 cpl_frame* sky_orders_chunks,
			 cpl_frame* usr_defined_break_points_frame,
			 xsh_instrument * instrument,
			 int nbkpts,
                         xsh_subtract_sky_single_param* sky_par, 
                         cpl_frame ** sky_spectrum,
                         cpl_frame ** sky_spectrum_eso,
			 const char* rec_prefix,
			 const int clean_tmp) ;

/*
cpl_frame*
xsh_save_sky_model(cpl_frame* obj_frame,
                   cpl_frame* sub_sky_frame,
                   const char* sky_tag,
                   xsh_instrument* instrument);
                   */

cpl_frame * xsh_add_sky_model( cpl_frame *sub_sky_frame, cpl_frame *sky_frame,
  xsh_instrument * instrument, const char* rec_prefix );

cpl_frame* 
xsh_localize_obj( cpl_frame * sci_frame,
                  cpl_frame *skymask_frame,
		  xsh_instrument *instrument,
		  xsh_localize_obj_param * loc_obj_par,
		  xsh_slit_limit_param * slit_limit_param,
		  const char * fname );

cpl_frameset * 
xsh_localize_obj_ifu( cpl_frameset * sci_frame,
                      cpl_frame *skymask_frame, 
		      xsh_instrument *instrument,
		      xsh_localize_obj_param * loc_obj_par,
		      xsh_slit_limit_param * slit_limit_param);

cpl_frame* xsh_extract ( cpl_frame * rec_frame, 
			 cpl_frame* loc_frame,
			 xsh_instrument* instrument, 
			 xsh_extract_param* extract_par,
			 cpl_frame** res_frame_ext,
			 const char* rec_prefix);

cpl_frame* xsh_extract_clean ( cpl_frame * rec_frame, 
			 cpl_frame* loc_frame,
			 xsh_instrument* instrument, 
			 xsh_extract_param* extract_par,
			 xsh_interpolate_bp_param * ipol_bp,
			 cpl_frame** res_frame_ext,
			 const char* rec_prefix);

cpl_frameset *
xsh_extract_ifu(cpl_frameset * rec_frame_set,
		cpl_frameset * loc_frame_set,
		xsh_instrument* instrument,
		xsh_extract_param * extract_par, 
		const char* rec_prefix) ;

cpl_frame * xsh_abs_remove_crh_single( cpl_frame *sci_frame,
                                   xsh_instrument * instrument,
                                   xsh_remove_crh_single_param * single_par,
                                   const char * res_tag);

cpl_frame * 
xsh_remove_crh_single( cpl_frame * sci_frame,
		       xsh_instrument * instrument, cpl_mask* sky_map,
		       xsh_remove_crh_single_param * single_par,
		       const char * name );

cpl_frame * xsh_merge_ord_slitlet( cpl_frame * rec_frame,
				   xsh_instrument* instrument, 
				   int merge_par, int slitlet,
				   const char* rec_prefix);

cpl_frame *
xsh_merge_ord (cpl_frame * sci_frame, xsh_instrument * instrument,
	       int merge,const char* rec_prefix) ;

cpl_frameset * 
xsh_merge_ord_ifu(cpl_frameset * rec_frameset,
		  xsh_instrument* instrument, 
		  int merge_par,const char* rec_prefix) ;


#define XSH_OBJPOS_NB_COL 2
#define XSH_OBJPOS_COLNAME_WAVELENGTH "Wavelength"
#define XSH_OBJPOS_UNIT_WAVELENGTH "nm"
#define XSH_OBJPOS_COLNAME_SLIT "Slit"
#define XSH_OBJPOS_UNIT_SLIT "arcsec"
#define XSH_LAMBDA_DIMM 0.0000005

double xsh_convert_seeing( cpl_frame* frame);

cpl_frame* xsh_localize_ifu_slitlet( cpl_frame *merge2d_slitlet, 
  cpl_frame *skymask_frame, int smooth_hsize,
  int nscales, int HF_skip, const char* resname, double cut_sigma_low,
  double cut_sigma_up, double cut_snr_low, double cut_snr_up,
  double slit_min, double slit_max, int deg, int box_hsize, xsh_instrument *instr);

cpl_frameset* xsh_localize_ifu( cpl_frameset *merge2d_frameset,
  cpl_frame *skymask_frame, 
  xsh_localize_ifu_param * locifu_par, xsh_instrument *instrument, 
  const char* resname);

#define XSH_SHIFTIFU_NB_COL 2
#define XSH_SHIFTIFU_COLNAME_WAVELENGTH "Wavelength"
#define XSH_SHIFTIFU_UNIT_WAVELENGTH "nm"
#define XSH_SHIFTIFU_COLNAME_SHIFTSLIT "Slit_shift"
#define XSH_SHIFTIFU_UNIT_SHIFTSLIT "arcsec"

cpl_frame* xsh_compute_shift_ifu_slitlet( double lambda_ref, cpl_frame *objpos_frame,
  cpl_frame *shiftifu_frame, double lambdaref_hsize, const char* resname);

cpl_frameset* xsh_compute_shift_ifu( double lambda_ref, double lambdaref_hsize,
  cpl_frameset *objpos_frameset,
  cpl_frameset *shiftifu_frameset, xsh_instrument* instr, const char* prefix);

cpl_frameset * 
xsh_subtract_sky_nod( cpl_frameset * raws, xsh_instrument * instrument,
  int mode_fast);

void 
xsh_flat_merge_qth_d2( cpl_frame *qth_frame,
		       cpl_frame *qth_order_tab_frame,  
		       cpl_frame *d2_frame,
		       cpl_frame *d2_order_tab_frame,
		       cpl_frame *qth_bkg_frame,
		       cpl_frame *d2_bkg_frame,
		       cpl_frame **qth_d2_flat_frame,
		       cpl_frame **qth_d2_bkg_frame,
		       cpl_frame **qth_d2_order_tab_frame,
		       xsh_instrument *instrument);
void
xsh_flat_merge_qth_d2_smooth( cpl_frame *qth_frame, 
			      cpl_frame *qth_order_tab_frame,
			      cpl_frame *d2_frame,cpl_frame *d2_order_tab_frame,
			      cpl_frame *qth_bkg_frame, cpl_frame *d2_bkg_frame,
			      cpl_frame **qth_d2_flat_frame,
			      cpl_frame **qth_d2_bkg_frame,
			      cpl_frame **qth_d2_order_tab_frame,
			      xsh_instrument *instrument);
cpl_frame*
xsh_flat_merge_qth_d2_tabs(cpl_frame *qth_edges_tab,cpl_frame *d2_edges_tab,xsh_instrument *instrument);


cpl_error_code
xsh_extract_clean_slice(const float* flux,
    const float* errs, int* qual,
    const double* lambda,
    const int ilambda,
    xsh_instrument* instrument,
    const int slit_min, const int slit_max,
    const int nlambda,const int nslit,
    const int mask_hsize,
    double* fluxval, double* errval, int* qualval,float*,float*,float*);

#define XSH_MATH_SQRT_2 1.4142135623730951
void xsh_opt_extract( cpl_frame *sci_frame, cpl_frame *order_table_frame, 
  cpl_frame *wavesol_frame, cpl_frame *model_frame, cpl_frame *wavemap_frame,
  cpl_frame *slitmap_frame, cpl_frame *loc_frame,
  cpl_frame *spectralformat_frame, cpl_frame *masterflat_frame,
  xsh_instrument *instrument, xsh_opt_extract_param *opt_extract_par,
		      const char* rec_prefix,
		      cpl_frame **orderext1d_frame, 
                      cpl_frame **orderoxt1d_frame,
                      cpl_frame **orderoxt1d_eso_frame,
		      cpl_frame** qc_subextract_frame,
		      cpl_frame** qc_s2ddiv1d_frame,
		      cpl_frame** qc_model_frame,
		      cpl_frame** qc_weight_frame);


#define REGDEBUG_GAUSSIAN 0
#define REGDEBUG_BLAZE 0
#define REGDEBUG_EXTRACT 0
#define REGDEBUG_EXTRACT_XY 0
#define REGDEBUG_SUBEXTRACT_XY 0
#define REGDEBUG_EXTRACT_STD 0
#define REGDEBUG_N 0

void xsh_opt_extract_orders( cpl_frame *sci_frame,
                 cpl_frame *orderlist_frame,
                 cpl_frame *wavesol_frame,
                 cpl_frame *model_frame,
                 cpl_frame *wavemap_frame,
                 cpl_frame *slitmap_frame,
                 cpl_frame *loc_frame,
                 cpl_frame *spectralformat_frame,
                 cpl_frame *masterflat_frame,
                 xsh_instrument *instrument,
                 xsh_opt_extract_param* opt_extract_par,
			     int min_index, int max_index,
			     const char* rec_refix,
                 cpl_frame** orderext1d_frame,
                             cpl_frame** orderoxt1d_frame,
                cpl_frame** orderoxt1d_eso_frame,
		cpl_frame** qc_subextract_frame,
	        cpl_frame** qc_s2ddiv1d_frame,
		cpl_frame** qc_model_frame,
		cpl_frame** qc_weight_frame);

cpl_frame * 
xsh_combine_nod( cpl_frameset * frames,
		 xsh_combine_nod_param * param,
		 const char * fname,
		 xsh_instrument * instrument,
		 cpl_frame** res_frame_ext ) ;


cpl_frame* 
xsh_create_master_bias2(cpl_frameset* rawFrames,xsh_stack_param* stack_par,
                        xsh_instrument* instr,
                        const char* result_name,const int method_code);

cpl_frame* xsh_compute_slice_dist( cpl_frameset *loc_frame_set, 
  cpl_frame *order_tab, cpl_frame *slitmap_frame, 
  cpl_frameset *merge_frameset, double lambda, xsh_instrument *instrument);

cpl_frame * 
xsh_format( cpl_frameset * rect_frame_set,
	    const char * result_name,
	    xsh_instrument * instrument, const char* rec_prefix ) ;

cpl_frame* xsh_cube( cpl_frameset *merge2d_frameset,
  xsh_instrument * instrument, const char* rec_prefix);
  
void xsh_center_cube( cpl_frame *cube_frame, cpl_frame *sky_line_frame,
  int chunk_size, xsh_instrument *instrument);

cpl_frameset * 
xsh_subtract_sky_offset( cpl_frameset * object_raws,
			 cpl_frameset * sky_raws,
			 int nraws,
			 xsh_instrument * instrument ) ;

cpl_frame * 
xsh_combine_offset (cpl_frameset * rawFrames, 
		    const char *result_name, 
		    xsh_stack_param* stack_par,
		    xsh_instrument* instr, 
		    cpl_imagelist ** list,
		    cpl_image** crh_ima, const int save_tmp) ;

cpl_frame * 
xsh_compute_response( cpl_frame * rect_frame,
		      cpl_frame * std_star_flux_frame,
		      cpl_frame * atmos_ext_frame,
		      cpl_frame * high_abs_tab_frame,
		      xsh_instrument * instrument,
		      double exptime ) ;


cpl_frame * 
xsh_compute_response2( cpl_frame * rect_frame,
		      cpl_frame * std_star_flux_frame,
		      cpl_frame * atmos_ext_frame,
		      cpl_frame * high_abs_tab_frame,
                      cpl_frame* resp_fit_points,
		      cpl_frame * tell_mod_cat_frame,
		      xsh_instrument * instrument,
		       double exptime,const int tell_corr ) ;

cpl_frame * 
xsh_compute_response_ord( cpl_frame * rect_frame,
		      cpl_frame * std_star_flux_frame,
		      cpl_frame * atmos_ext_frame,
		      cpl_frame * high_abs_tab_frame,
		      xsh_instrument * instrument,
		      double exptime) ;

void xsh_data_check_spectralformat( cpl_frame *spectralformat_frame,
  cpl_frame *orderlist_frame, cpl_frame *wavesol_frame, 
  cpl_frame *model_config, 
  xsh_instrument *instr);

cpl_error_code
xsh_wavemap_qc(cpl_frame* frm_map,const cpl_frame* frm_tab);

cpl_error_code
xsh_wavetab_qc(cpl_frame* frm_tab,const int is_poly);

cpl_frame* 
xsh_flexcor( cpl_frame* afc_frame,
             cpl_frame *wave_tab_frame,
             cpl_frame *model_config_frame,
             cpl_frame *order_tab_frame,
             cpl_frame *attresidtab_frame,
             int afc_xmin, int afc_ymin, xsh_instrument *instr,
             cpl_frame **afc_order_tab_frame, 
             cpl_frame **afc_model_config_frame);

cpl_frame* xsh_afcthetab_create( cpl_frame *wave_tab_frame,
  cpl_frame *model_config_frame,  int order, 
  cpl_frame *spectralformat_frame,cpl_frame *arclines_frame,
                                 int xmin, int ymin, 
                                 xsh_instrument *instr,const int clean_tmp);

cpl_frameset* xsh_ifu_wavetab_create( cpl_frame *wave_tab_frame, 
  cpl_frame *shift_tab_frame, xsh_instrument *instr);

cpl_frame * xsh_calibrate_flux( cpl_frame * spectrum_frame,
				cpl_frame * respon_frame,
				cpl_frame * atmos_ext_frame,
				const char * fname,
				xsh_instrument * instrument ) ;

cpl_frame* 
xsh_create_dispersol_physmod(cpl_frame* pre_frame,
			     cpl_frame *order_tab_frame,
                             cpl_frame* mod_cfg_frame,
			     cpl_frame* wave_map_frame,
			     cpl_frame* slit_map_frame,
                             xsh_dispersol_param *dispsol_param,
                             cpl_frame* spectral_format_frame,
                             xsh_instrument* instrument,
                             const int clean_tmp);

#define LSTART_COLUMN_NAME "LAMBDASTART"
#define LEND_COLUMN_NAME "LAMBDAEND"
#define GUESS_TELL_MASK_RESOLUTION_UVB  9100
#define GUESS_TELL_MASK_RESOLUTION_VIS  17400
#define GUESS_TELL_MASK_RESOLUTION_NIR  11300
cpl_frame* xsh_compute_absorp( cpl_frame *s1d_frame, cpl_frame *telllist_frame,
  int filter_hsize, double threshold, xsh_instrument* instr);

void xsh_mark_tell( cpl_frame *s1d_frame, cpl_frame *tellmask_frame);

#endif
