/* @(#)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);

}

/**@}*/
