/*                                                                           *
 *   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-30 16:07:18 $
 * $Revision: 1.65 $
 * $Name: not supported by cvs2svn $
 */

#ifndef XSH_DATA_PRE_H
#define XSH_DATA_PRE_H

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

#include <cpl.h>
#include <xsh_error.h>

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

#define XSH_PRE_DATA_TYPE CPL_TYPE_FLOAT
#define XSH_PRE_DATA_BPP CPL_BPP_IEEE_FLOAT
#define XSH_PRE_ERRS_TYPE CPL_TYPE_FLOAT
#define XSH_PRE_ERRS_BPP CPL_BPP_IEEE_FLOAT
#define XSH_PRE_QUAL_TYPE CPL_TYPE_INT
#define XSH_PRE_QUAL_BPP CPL_BPP_32_SIGNED

/* NIR have RON and CONAD now

#define XSH_NIR_DEFAULT_RON 1.43
#define XSH_NIR_DEFAULT_CONAD 0.36
#define XSH_NIR_DEFAULT_GAIN 2.78

*/

/* cut in pixels along X, Y on RAW data */
#define XSH_NIR_DEFAULT_CUT 4
#define XSH_NIR_DEFAULT_CUT_X 4
#define XSH_NIR_DEFAULT_CUT_Y 20

#define XSH_WINDOW_MEDIAN_FRAC 0.3333 

typedef struct {
  cpl_image *data;
  cpl_propertylist *data_header;

  cpl_image *errs;
  cpl_propertylist *errs_header;
    
  cpl_image *qual;
  cpl_propertylist *qual_header;

  cpl_frame_group group;
  /* instrument related with PRE */
  xsh_instrument* instrument; 
  /* NAXIS1 and NAXIS2 keywords */
  int naxis1, naxis2;
  /* BINX et BINY keywords */
  int binx, biny;
  /* image size (DATA,ERRS,QUAL) in pixels */
  int nx, ny;
  /* translation in X,Y between detector and image */
  int cutx, cuty;
  /* max in X,Y of the cut */
  int cutmx, cutmy;
  /* pixels size in microns */
  float pszx, pszy;
  /* conversion from eletcrons to ADU */
  float gain;
  /* exposure time */
  float exptime;
  /* ron */
  double ron;
  /* conad */
  double conad;
  /* decode_bp */
   int decode_bp;
} xsh_pre;

#include <xsh_badpixelmap.h>


/*----------------------------------------------------------------------------
                                    Methods
 ----------------------------------------------------------------------------*/

/* Create/destroy */
xsh_pre* xsh_pre_create( cpl_frame* raw, cpl_frame* bpmap, cpl_image* bias,
			 xsh_instrument* instr,const int pre_overscan_corr,const bool flag_neg_and_thresh_pix);
xsh_pre* xsh_pre_wavemap_create(cpl_frame* raw, xsh_pre * sci,
				xsh_instrument* instr) ;
void xsh_pre_free(xsh_pre** pre);
xsh_pre* xsh_pre_load(cpl_frame* frame, xsh_instrument* instr);
void xsh_pre_init_with_header(xsh_pre* pre, cpl_propertylist* header);
xsh_pre* xsh_pre_duplicate(const xsh_pre *pre);
cpl_frame* xsh_pre_save(const xsh_pre *pre, const char *filename, const char *tag,int temp);
cpl_frame* xsh_pre_save_product(xsh_pre *pre, cpl_frame* frame,
  cpl_frameset* frameset,const cpl_parameterlist* parameters,
  const char* recipe_id, const char *prefix );

xsh_pre* xsh_pre_new(int size_x, int size_y);

/* get */
int xsh_pre_get_nx(const xsh_pre *pre);
int xsh_pre_get_ny(const xsh_pre *pre);
int xsh_pre_get_binx( const xsh_pre *pre ) ;
int xsh_pre_get_biny( const xsh_pre *pre ) ;

void xsh_pre_from_raw_get(xsh_pre* pre, double raw_x, double raw_y, double* x, double* y);
float xsh_pre_get_pszx(const xsh_pre *pre);
float xsh_pre_get_pszy(const xsh_pre *pre);
float xsh_pre_get_gain(const xsh_pre *pre);
cpl_frame_group xsh_pre_get_group(const xsh_pre* pre);
cpl_mask* xsh_pre_get_bpmap(const xsh_pre* pre);

/* I/O */
void xsh_pre_dump(const xsh_pre *pre, FILE *stream);

/* Standard arithmetic operations used by several recipes */
void xsh_pre_add(xsh_pre * self, const xsh_pre *right);
void xsh_pre_subtract(xsh_pre* self, const xsh_pre *right);
void xsh_pre_divide(xsh_pre* self, const xsh_pre *right, const int is_flat, double threshold);
void xsh_pre_multiply_scalar(const xsh_pre *pre, double x);
void xsh_pre_multiply_image(const xsh_pre *pre, cpl_image* img);
void xsh_pre_multiply (xsh_pre* self, const xsh_pre * right, double threshold);

cpl_frame * xsh_pre_frame_subtract( cpl_frame * one, cpl_frame *two,
                                    const char *fname, xsh_instrument * instr,
                                    const int clean_temp ) ;
cpl_image* xsh_pre_abs (const xsh_pre * pre);
/* special computation on data */
int xsh_pre_window_best_median_flux_pos( xsh_pre* pre, int xcen, int ycen,
  int search_window_hsize, int running_median_hsize,  int* xadj, int* yadj);
double xsh_pre_data_window_median_flux_pa(xsh_pre* pre, int x, int y,
  int size_x, int size_y,double* tab,int* status);

void xsh_pre_normalize( xsh_pre* self);
void xsh_pre_median_mean_stdev( xsh_pre * preFrame, double * mean,
				double * median, double * stdev ) ;

void xsh_pre_median_mean_stdev_window( xsh_pre * preFrame, double * mean,
                                       double * median, double * stdev,
                                       const int llx, const int lly,
                                       const int urx, const int ury );
/* Accessor functions
 * (const/non-const variants of each) 
 */
const
cpl_propertylist *xsh_pre_get_header_const(const xsh_pre *pre);
cpl_propertylist *xsh_pre_get_header      (      xsh_pre *pre);

const
cpl_image  *xsh_pre_get_data_const(const xsh_pre *pre);
cpl_image  *xsh_pre_get_data      (      xsh_pre *pre);

const
cpl_image  *xsh_pre_get_errs_const(const xsh_pre *pre);
cpl_image  *xsh_pre_get_errs      (      xsh_pre *pre);

const
cpl_image  *xsh_pre_get_qual_const(const xsh_pre *pre);
cpl_image  *xsh_pre_get_qual      (      xsh_pre *pre);

const
double     *xsh_pre_get_data_buffer_const(const xsh_pre *pre);
double     *xsh_pre_get_data_buffer      (      xsh_pre *pre);

const
double     *xsh_pre_get_errs_buffer_const(const xsh_pre *pre);
double     *xsh_pre_get_errs_buffer      (      xsh_pre *pre);

void xsh_pre_turn( xsh_pre * pre, int rot ) ;
void xsh_pre_flip( xsh_pre * pre, int angle);
void xsh_pre_extract( xsh_pre *pre, int xmin, int ymin, int xmax, int ymax);
cpl_frame* 
xsh_frameset_average_pre(cpl_frameset *set, 
                         xsh_instrument* instr, 
                         const char* tag);


cpl_frameset* xsh_pre_frameset_subtract_frame( cpl_frameset *set,
                                            cpl_frame *sub,
                                               const char* spec,
                                               xsh_instrument *instr);

void xsh_pre_subtract_scalar (const xsh_pre * pre, double x);
void xsh_pre_add_scalar (const xsh_pre * pre, double x);
void xsh_pre_divide_scalar (const xsh_pre * pre, double x);
xsh_pre* xsh_pre_subsample (xsh_pre* self, const int  binx, const int biny, const int rescale,xsh_instrument* inst);

/* The following is exposed for SDP format generation in xsh_dfs.c */
double xsh_compute_ron_nir(const double dit);

#endif
