/* @(#)locatefillfibre     */
/*===========================================================================
  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_initfillfibre   Substep: find the "slices" containing bad pixels and, among them, single out  the correctible ones and mark the others as bad    
 *
 */
/*-------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------
                          Includes
 --------------------------------------------------------------------------*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <flames_midas_def.h>
#include <flames_uves.h>
#include <flames_newmatrix.h>
#include <flames_shiftcommon.h>
#include <flames_fillholes.h>

/**@{*/

/*---------------------------------------------------------------------------
                            Implementation
 ---------------------------------------------------------------------------*/
/**
 @name  flames_checksize()  
 @short  find the "slices" containing bad pixels and, among them, single out 
         the correctible ones and mark the others as bad                       
 @author G. Mulas  -  ITAL_FLAMES Consortium. Ported to CPL by A. Modigliani


 @param allflatsin: a structure which contains the set of fibre FF frames  
                    to be used and related scalars                         
 @param iorder:     the given order for the function (pixel coordinates)  
 @param iframe:     the given frame for the function (pixel coordinates)  
 @param ifibre:     the given fibre for the function (pixel coordinates)  
 @param ix:         the given x for the function (pixel coordinates)      

 @param allflatsin  output: the fibre boundaries are, if necessary, reset 
                    here    
 @param badifibre   output: a vector of structures containing the results of 
                    this function                                            
 @param badtotal    output: the total number of bad pixels found     

 @return success or failure code

 DRS Functions called:          
       none                                         

 Pseudocode:                                                             


@note
 */

flames_err 
initfillfibre(
                allflats *allflatsin,
                int32_t iorder,
                int32_t iframe,
                int32_t ifibre,
                int32_t ix,
                badifibrestruct *badifibre,
                int32_t *badtotal)
{
    int32_t goodpixels=0;
    int32_t badpixels=0;
    int32_t iy=0;

    badifibrestruct *mybadifibre=0;
    badixstruct *mybadixs=0;
    int32_t badixcount=0;
    int32_t *lvecbuf1=0;
    int32_t *lvecbuf2=0;
    frame_mask *fmvecbuf1=0;
    frame_mask *fmvecbuf2=0;
    int32_t iorderifibreindex=0;
    int32_t iorderifibreixindex=0;
    int32_t iyixindex=0;

    /* initialise the temporary accumulators to 0 */
    goodpixels = 0;
    badpixels = 0;
    lvecbuf1 = allflatsin->lowfibrebounds[0][0];
    lvecbuf2 = allflatsin->highfibrebounds[0][0];
    fmvecbuf1 = allflatsin->flatdata[iframe].badpixel[0];
    fmvecbuf2 = allflatsin->goodfibres[0][0];
    mybadifibre = badifibre+ifibre;
    badixcount = mybadifibre->badixcount;
    mybadixs = mybadifibre->badixs+badixcount;
    mybadixs->badiycount = 0;
    mybadixs->badiy = 0;
    mybadixs->badix = ix;
    iorderifibreindex = (iorder*allflatsin->maxfibres)+ifibre;
    iorderifibreixindex = (iorderifibreindex*allflatsin->subcols)+ix;
    /* loop over pixels belonging to the fibre */
    for (iy=lvecbuf1[iorderifibreixindex];
                    iy<=lvecbuf2[iorderifibreixindex];
                    iy++){
        iyixindex = (iy*allflatsin->subcols)+ix;
        if (fmvecbuf1[iyixindex] == 0) {
            /* this pixel is good, add to accumulators */
            goodpixels++;
        }
        else {
            /* ouch, we hit a bad pixel, increment badpixels counter */
            badpixels++;
        }
    }
    /* check goodpixels coverage of the fibre */
    if ((double)goodpixels*allflatsin->substepy/(2*allflatsin->halfibrewidth)
                    < allflatsin->minfibrefrac
                    && (lvecbuf1[iorderifibreixindex]-lvecbuf2[iorderifibreixindex]) >=
                    (2*allflatsin->halfibrewidth)) {
        /* the coverage of this fibre at this ix is too low, mark it bad and
       disregard it altogether in the first correction pass */
        fmvecbuf2[iorderifibreixindex] = BADSLICE;
        for (iy=lvecbuf1[iorderifibreixindex];
                        iy<=lvecbuf2[iorderifibreixindex];
                        iy++) {
            iyixindex = (iy*allflatsin->subcols)+ix;
            fmvecbuf1[iyixindex] = 1;
        }
    }
    else if (badpixels != 0) {
        /* this fibre is not clean at this ix */
        mybadixs->badix = ix;
        mybadixs->badiycount = badpixels;
        mybadixs->nextbadindex = mybadifibre->badixcount+1;
        mybadixs->prevbadindex =
                        (mybadifibre->badixcount>0) ? mybadifibre->badixcount-1: 0;
        mybadifibre->badixcount++;
        *badtotal += badpixels;
    }

    return(NOERR);

}

/**@}*/
