/*===========================================================================
  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;

}
/**@}*/
