/*                                                                            *
 *   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-06-19 06:36:29 $
 * $Revision: 1.3 $
 * $Name: not supported by cvs2svn $
 */
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

/*--------------------------------------------------------------------------*/
/**
  @defgroup xsh_test_tools     
    Test some tools functions for performances check
  @ingroup unit_tests
*/
/*--------------------------------------------------------------------------*/
/**@{*/

/*---------------------------------------------------------------------------
                                Includes
 ---------------------------------------------------------------------------*/
#include <xsh_utils.h>
#include <xsh_error.h>
#include <xsh_msg.h>
#include <xsh_data_instrument.h>
#include <xsh_data_pre.h>
#include <xsh_fit.h>
#include <xsh_pfits.h>
#include <tests.h>
#include <cpl.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include <getopt.h>
#include <xsh_cpl_size.h>
/*---------------------------------------------------------------------------
                            Defines
 ---------------------------------------------------------------------------*/
#define MODULE_ID "XSH_DETECT_LINE_FILE"

static cpl_error_code
xsh_add_fits_key_min_set(cpl_propertylist* plist)
{

  cpl_propertylist_append_double(plist,XSH_EXPTIME,10.);
  cpl_propertylist_append_double(plist,XSH_RON,1.);
  cpl_propertylist_append_double(plist,XSH_CONAD,1.);
  cpl_propertylist_append_double(plist,XSH_DET_GAIN,1.);  
  cpl_propertylist_append_int(plist,XSH_WIN_BINX,1);
  cpl_propertylist_append_int(plist,XSH_WIN_BINY,1);
  cpl_propertylist_append_double(plist,XSH_PSZX,15.);
  cpl_propertylist_append_double(plist,XSH_PSZY,15.);
  //Only for NIR:
  cpl_propertylist_append_double(plist,XSH_DET_PXSPACE,1.800e-05);
  cpl_propertylist_append_int(plist,XSH_CHIP_NY,2048);


   return cpl_error_get_code();

}
#define PI_NUMB     (3.1415926535897932384626433832795)
/*--------------------------------------------------------------------------*/
/**
  @brief
    Some test about performances
  @return
 */
/*--------------------------------------------------------------------------*/
int main( int argc, char** argv)
{
  int ret = 0;
  int sx=4096;
  int sy=4096;

  //char *image_name = NULL;
  cpl_image* image = NULL;
  cpl_image* gauss = NULL;
  cpl_image* img_err = NULL;
  cpl_image* img_line = NULL;
 


  //double min_noise=-10;
  //double max_noise=10;
  //double mean_level=100;

  //double gauss_a=1.e5;
  double gauss_sx=8;
  double gauss_sy=8;
  //const int dim=2;
  cpl_size xpos=sx/2;
  cpl_size ypos=sy/2;
  int size=1+2*(gauss_sx+gauss_sy);

  double norm=0;
  double cen_x=0;
  double cen_y=0;
  double sig_x=0;
  double sig_y=0;
  double fwhm_x=0;
  double fwhm_y=0;
  cpl_frame* frm_raw=NULL;
  cpl_frame* frm_line=NULL;
  xsh_instrument* instrument=NULL;
  const char* name_out="line.fits";
  //const char* name_raw="raw.fits";
  //xsh_pre* pre = NULL;
  cpl_propertylist* plist=NULL;
  const char* name_line = NULL;
  int nb_frames=0;
  double back=0;

  TESTS_INIT( MODULE_ID);
  cpl_msg_set_level( CPL_MSG_DEBUG);
  xsh_debug_level_set( XSH_DEBUG_LEVEL_MEDIUM) ;



  nb_frames = argc - optind;
  if ( nb_frames == 1 ) {
    name_line = argv[optind];
  }
  else{
    xsh_msg( "********** NOT ENOUGH INPUT FRAMES **********" ) ;
    exit(0);
  }


  img_line = cpl_image_load(name_line,CPL_TYPE_DOUBLE,0,0);
  sx=cpl_image_get_size_x(img_line);
  sy=cpl_image_get_size_y(img_line);
  xpos=sx/2;
  ypos=sy/2;

  instrument=xsh_instrument_new();
  xsh_instrument_set_arm(instrument,XSH_ARM_UVB);
  plist=cpl_propertylist_new();
  xsh_add_fits_key_min_set(plist);
 

  check(cpl_image_save(img_line,name_out,
                       CPL_BPP_IEEE_FLOAT,plist,CPL_IO_DEFAULT));

  xsh_free_propertylist(&plist);

  check(frm_line=xsh_frame_product(name_out,"BIAS",
                                   CPL_FRAME_TYPE_IMAGE,
                                   CPL_FRAME_GROUP_RAW,
                                   CPL_FRAME_LEVEL_FINAL));

 
   img_err=cpl_image_new(sx,sy,CPL_TYPE_DOUBLE);
  cpl_image_add_scalar(img_err,1.);
  //cpl_image_power(img_err,0.5);

  cpl_size i=0;
  cpl_array* parameters=cpl_array_new(7, CPL_TYPE_DOUBLE);
  cpl_array* err_params=cpl_array_new(7, CPL_TYPE_DOUBLE);
  cpl_array* fit_params=cpl_array_new(7, CPL_TYPE_INT);

  /*All parameter should be fitted*/
  for (i = 0; i < 7; i++)
     cpl_array_set(fit_params, i, 1);

  double rms=0;
  double red_chisq=0;
  cpl_matrix* covariance=NULL;
  cpl_matrix* phys_cov=NULL;
  double major=0;
  double minor=0;
  double angle=0;
  /* Parameter names 
  const char  *p[7] = { 
     "Background       ",
     "Normalisation    ",
     "Correlation      ",
     "Center position x",
     "Center position y",
     "Sigma x          ",
     "Sigma y          "};
  */


  check(cpl_fit_image_gaussian(img_line, img_err, xpos, ypos,size,size,
                               parameters,err_params,fit_params,
                               &rms,&red_chisq,&covariance,
                               &major,&minor,&angle,&phys_cov));

  /*
  for (i = 0; i < 7; i++){
     cpl_msg_info(cpl_func,"%s: %f",
                  p[i], cpl_array_get(parameters,i,NULL));
  }
  */
  /*
  xsh_msg("G Results: rms: %f red_chisq: %f major: %f minor: %f angle: %f",
          rms,red_chisq,major,minor,angle);
  */

  double rho=0;
  back=cpl_array_get(parameters,0,NULL);
  norm=cpl_array_get(parameters,1,NULL);
  rho=cpl_array_get(parameters,2,NULL);

  cen_x=cpl_array_get(parameters,3,NULL);
  cen_y=cpl_array_get(parameters,4,NULL);
  sig_x=cpl_array_get(parameters,5,NULL);
  sig_y=cpl_array_get(parameters,6,NULL);
  fwhm_x=sig_x*CPL_MATH_FWHM_SIG;
  fwhm_y=sig_y*CPL_MATH_FWHM_SIG;

  double sig_xy=sig_x*sig_x;
  double sig_x2=sig_x*sig_x;
  double sig_y2=sig_y*sig_y;
  double rho2=rho*rho;
  double theta=0.5*atan( 2.*rho * (sig_xy) / (sig_x2 - sig_y2) );
  double a=sig_xy*sqrt( 2.*(1.-rho2) * cos(2.*theta)/(sig_x2+sig_y2) * cos(2.*theta) + sig_y2 - sig_x2);
  double b=sig_xy*sqrt( 2.*(1.-rho2) * cos(2.*theta)/(sig_x2+sig_y2) * cos(2.*theta) - sig_y2 + sig_x2);

  xsh_msg("%s R: [%f,%f], Back: %f Norm: %f Sigma: [%f,%f] FWHM [%f,%f] theta,a,b: [%f(%f),%f,%f]",
          name_line,cen_x,cen_y,back,norm,sig_x,sig_y,fwhm_x,fwhm_y,theta,theta*180./PI_NUMB,a,b);
  /*
  check(xsh_image_find_barycenter(img_line,xpos,ypos,size,&norm,&cen_x,&cen_y, 
                                  &sig_x, &sig_y, &fwhm_x, &fwhm_y));

  xsh_msg("B Measured Pos: [%f,%f], Amp: %f Sigma: [%f,%f] FWHM: [%f,%f]",
          cen_x,cen_y,norm,sig_x,sig_y,fwhm_x,fwhm_y);


  check(pre=xsh_pre_create(frm_raw,NULL,img_line,instrument,0,CPL_FALSE));

  check(cpl_image_save(pre->data,"pre_ima_raw.fits",
                       CPL_BPP_IEEE_FLOAT,plist,CPL_IO_DEFAULT));

  check(cpl_image_get_maxpos(pre->data,&xpos,&ypos));

  xsh_msg("Pos Max: [%" CPL_SIZE_FORMAT ",%" CPL_SIZE_FORMAT "]",xpos,ypos);

  check(cpl_image_fit_gaussian(pre->data, xpos, ypos,size,&norm, &cen_x, &cen_y, 
                               &sig_x, &sig_y, &fwhm_x, &fwhm_y));

  xsh_msg("G Measured Pos: [%f,%f], Amp: %f Sigma: [%f,%f] FWHM: [%f,%f]",
          cen_x,cen_y,norm,sig_x,sig_y,fwhm_x,fwhm_y);



  check(xsh_image_find_barycenter(pre->data,xpos,ypos,size,&norm,&cen_x,&cen_y, 
                                  &sig_x, &sig_y, &fwhm_x, &fwhm_y));

  xsh_msg("B Measured Pos: [%f,%f], Amp: %f Sigma: [%f,%f] FWHM: [%f,%f]",
          cen_x,cen_y,norm,sig_x,sig_y,fwhm_x,fwhm_y);
  */
  cleanup:

  xsh_free_image(&image);
  xsh_free_image(&gauss);
  xsh_free_image(&img_line);
  xsh_free_frame(&frm_raw);
  xsh_free_frame(&frm_line);
  xsh_free_propertylist(&plist);


    if (cpl_error_get_code() != CPL_ERROR_NONE) {
      xsh_error_dump(CPL_MSG_ERROR);
      ret  = 1;
    }
    return ret;
}

/**@}*/
