/*===========================================================================
  Copyright (C) 2001 European Southern Observatory (ESO)
 
  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., 675 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding concerning ESO-MIDAS should be addressed as follows:
  Internet e-mail: midas@eso.org
  Postal address: European Southern Observatory
  Data Management Division 
  Karl-Schwarzschild-Strasse 2
  D 85748 Garching bei Muenchen 
  GERMANY
  ===========================================================================*/
/*-------------------------------------------------------------------------*/
/**
 * @defgroup flames_doquickptimal  
 *
 */
/*---------------------------------------------------------------------------
  Includes
  --------------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <flames_midas_def.h>
#include <flames_def_drs_par.h>
#include <flames_uves.h>
#include <flames_quickoptimal.h>
#include <flames_optimal.h>
#include <flames_ordselect.h>
#include <flames_doquickoptimal.h>
#include <flames_newmatrix.h>

/*---------------------------------------------------------------------------
  Implementation
  ---------------------------------------------------------------------------*/
/**
   @name  flames_doquickptimal()  
   @short  this function performs the actual optimal extraction on a frame,
   "quick and dirty" no y shift correction flavour
   @author G. Mulas  -  ITAL_FLAMES Consortium. Ported to CPL by A. Modigliani

   @param ScienceFrame all fibre frame to be optimally extracted
   @param Order            fibre-order position table
   @param Shifted_FF       shifted flat field structure
   @param kappa2           square of kappa to be used in kappa-sigma clip
   @param mask             bad pixel mask frame
   @param backframe        inter-order background frame
   @param minoptitersint   minimum number of optimal extraction iterations
   @param maxoptitersint   maximum number of optimal extraction iterations
   @param xkillsize        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
   @param ykillsize      see above


   @return success or failure code

   DRS Functions called:          
   none                                         
                                                                         
   Pseudocode:                                                             


   @note
*/


flames_err 
doquickoptimal(flames_frame *ScienceFrame, 
               orderpos *Order, 
               allflats *Shifted_FF, 
               double kappa2, 
               frame_mask **mask, 
               frame_data **backframe, 
               int32_t minoptitersint, 
               int32_t maxoptitersint, 
               int32_t xkillsize, 
               int32_t ykillsize)
{

  int32_t ordsta=0, ordend=0, i=0, xysize=0;
  char output[100];

  int actvals=0;
  char drs_verbosity[10];
  int status=0;

  frame_mask **newmask=0;
  frame_mask *fmvecbuf1=0;

  memset(drs_verbosity, 0, 10);
  if ((status=SCKGETC(DRS_VERBOSITY, 1, 3, &actvals, drs_verbosity))
      != 0) {
    /* the keyword seems undefined, protest... */
    return(MAREMMA);
  }


  newmask=fmmatrix(0,ScienceFrame->subrows-1,0,ScienceFrame->subcols-1);
  fmvecbuf1 = newmask[0];
  xysize = (ScienceFrame->subrows*ScienceFrame->subcols)-1;
  for (i=0; i<=xysize; i++) fmvecbuf1[i] = 0;

  for (ordsta=ordend=Order->firstorder; ordsta<=Order->lastorder; 
       ordsta=++ordend) 
    {
      /* at least we extract from ordsta to ordend */
      /* select a set of orders which is disjoint from other orders */
      if (ordselect(Order, ScienceFrame, Shifted_FF, &ordend)!=NOERR) 
	{
	  SCTPUT("Error selecting an order subset to estract\n");
	  return flames_midas_error(MAREMMA);
	}

      /* A little bit of advertising */
      sprintf(output, "Extracting orders from nr. %d to nr. %d....", 
	      ordsta, ordend);
      SCTPUT(output);

      /* let's make the optimal extraction */  
      switch(quickoptimal(ScienceFrame, Shifted_FF, Order, ordsta, ordend, 
			  kappa2, mask, newmask, backframe, minoptitersint, 
			  maxoptitersint, xkillsize, ykillsize)) {
      case 0:
	if (strcmp(drs_verbosity,"LOW") == 0 ){
	} else {
	  sprintf(output, "Optimal extraction for orders from nr. %d to %d \
completed\n", ordsta, ordend);
	  SCTPUT(output);
	}
	break;
      case 1:
	sprintf(output, "Error in optimal extraction\n");
	SCTPUT(output);
	return flames_midas_error(MAREMMA);
	break;
      case 2:
	sprintf(output, "Error in sigma clipping\n");
	SCTPUT(output);
	return flames_midas_error(MAREMMA);
	break;
      case 3:
	sprintf(output, "Error in covariance calculation\n");
	SCTPUT(output);
	return flames_midas_error(MAREMMA);
	break;
      case 4:
	sprintf(output, "Error in cross-correlation\n");
	SCTPUT(output);
	return flames_midas_error(MAREMMA);
	break;
      default :
	sprintf(output, "Unknown error\n");
	SCTPUT(output);
	return flames_midas_error(MAREMMA);
	break;
      }
    }

  free_fmmatrix(newmask, 0,ScienceFrame->subrows-1,0,ScienceFrame->subcols-1);

  return NOERR;

}
/**@}*/
