/* $Id: flames_get_flat_size.c,v 1.21 2013-07-25 13:06:44 amodigli Exp $ */

/*===========================================================================
  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_get_flat_size Get size of flat part of FF and offset of its center with respect to order trace
 *
 */
/*-------------------------------------------------------------------------*/

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



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

/* include standard definitions */
#include <flames_get_flat_size.h>      
#include <flames_midas_def.h>      
#include <flames_def_drs_par.h>      
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#include <flames_uves.h>
#include <flames_newmatrix.h>
#define MY_FEPSILON 1e-6   /*1e-6*/
#define FILE_LEN 80                          /* max length of in files */
#define MESS_LEN 80                          /* max length of messages */
#define KEYW_LEN 80                          /* max length of keywords */
#define LABEL_LEN 20                         /* max length of a label  */
//#define BUF_SIZE 12                          /* max size of ima buffer */
#define MAX_STRING_SZ 200                     /* min machine precision */


const char prgName[FILE_LEN] = "flames_get_flat_size";   /* program name */


void
clip_hw_small(double* val,
              int* mask,
              int min,
              int max,
              int DRS_SFF_HW_MIN);

void
update_delta(double* val,
             float  med,
             int    min,
             int    max,
             double* del);

void  
update_mask(double* del,
            float rms,
            int*   mask,
            int   min,
            int   max);

float 
get_y_min(int     xcPix, 
          int     ycTracePix,
          double   int_min,
          float** mInImaF,
          int LOC_SAV_BORD_SZ);

float 
get_y_max(int     xcPix, 
          int     ycTracePix,
          double   int_min,
          float** mInImaF,
          int     LOC_SAV_BORD_SZ);

void
find_mid_y_min_max(int     xcPix, 
                   int     ycTracePix,
                   double   int_min,
                   float** mInImaF,
                   double*  yMin,
                   double*  yMax,
                   int LOC_SAV_BORD_SZ);
void  
find_low_y_min_max(int     xcPix, 
                   int     ycTracePix,
                   double   int_min,
                   float** mInImaF,
                   double*  yMin,
                   double*  yMax,
                   int LOC_SAV_BORD_SZ);
void 
find_upp_y_min_max(int     xcPix, 
                   int     ycTracePix,
                   double  int_min,
                   float** mInImaF,
                   float*  yMin,
                   float*  yMax,
                   int LOC_SAV_BORD_SZ);
float 
get_avg(double* val,
        int*   mask,
        int    min,
        int    max);
float 
get_med(double* val,
        int*   mask,
        int    min,
        int    max);

int 
ima_comp(const void*, const void*);
float **
map2mat(void);              /* map a matrix on a float vector */

void 
clip_hw_new(double* val, int* mask, int* min, int* max);

/**@{*/

/*---------------------------------------------------------------------------
  Implementation
  ---------------------------------------------------------------------------*/
/**
   @name  flames_get_flat_size()  
   @short Get size of flat part of FF and offset of its center with respect to order trace
   @author G. Mulas  -  ITAL_FLAMES Consortium. Ported to CPL by A. Modigliani

   @param IN_A
   @param IN_B
   @param SLIT
   @param ORD_MIN
   @param ORD_MAX
   @param DEFPOL
   @param SAV_BORD_SZ
   @param DRS_SFF_HW_MIN
   @param X_WIND_SIZE
   @param Y_WIND_SIZE
   @param Y_SEARCH_WIND
   @param ORD_TRESH
   @param N_CLIP_MED
   @param N_CLIP_AVG
   @param INT_TRESH

   @return success or failure code

   DRS Functions called:          
   none                                         

   Pseudocode:                                                             

   Finds at central X Xc for central order Mc, Ymin and Ymax 
   such that I[(Ymin(Xc,Mc)]=I[(Ymax(Xc,Mc)]=0.8*I[Yt(Xc,Mc)] were
   Yt(Xc,Mc) is the position of the central trace.
   Ymin, and Ymax are determined with a linear interpolation.
   HALFSIZE=[(Ymax-Yo)-(Ymin-Yo)]/2 were Yo=3pix
   YSHIFT=Yt-Yc(Xc,Mc), with Yc the position of the FF center.

   @note
 */

int 
flames_get_flat_size(
                const char *IN_A,
                const char *IN_B,
                const float *SLIT,
                const int *ORD_MIN,
                const int *ORD_MAX,
                const int *DEFPOL,
                const  int SAV_BORD_SZ,
                const  int DRS_SFF_HW_MIN,
                const  int X_WIND_SIZE,
                const  int Y_WIND_SIZE,
                const  int Y_SEARCH_WIND,
                const  int ORD_TRESH,
                const  int N_CLIP_MED,
                const  int N_CLIP_AVG,
                const  float INT_TRESH)

{
    char* bufData;
    char inIma[FILE_LEN];               /* input File */
    char inTable[FILE_LEN];             /* input Table */
    const int max_pol_ordXY=200;        /* max polynomial order: orderX * orderY */

    //  int  messLevel = 0;                 /* message level */

    int  nPix[2];                       /* tmp variable for pixel data */


    int  stat = 0;                      /* status */

    int  inImaId = 0;                   /* Id of input ima frame */
    int  inTabId = 0;                   /* Id of in ima frame */

    int  nCol = 0;                      /* No of columns */
    int  nRow = 0;                      /* No of rows */

    int  unit = 0;                      /* address of unit pointer */
    int  null = 0;                      /* No of null values in data */


    int  imaSizeX = 0;                  /* size of ima along X in pix */
    int  imaSizeY = 0;                  /* size of ima along Y in pix */
    int  imaSizeT = 0;                  /* total ima size */
    int  n_pos_y_shift = 0;             /* No of pos y shift */
    int  n_neg_y_shift = 0;             /* No of neg y shift */


    float *pInImaF;                     /* image frame */
    float **mInImaF;                    /* matrix represent. */


    double dbl_aux=0;                   /* aux double variable */

    float inSlit=0;                     /* input slit size */
    double coeffd[max_pol_ordXY];                  /* coeffd descriptor */
    int nCoeffd = max_pol_ordXY;                   /* No of coeffd */
    int ordMin=0;                       /* ord min */
    int ordMax=0;                       /* ord max */
    int defPol[2];                      /* bivariate polinomial degree */
    int xcPix = 0;                      /* central pixel */
    int cOrd = 0;                       /* central order */

    int slitPix=0;                      /* slit dimension in pixel */


    double yMin=0;                       /* aux var for min Y limit of flat FF */
    double yMax=0;                       /* aux var for max Y limit of flat FF */
    double y_low_min =0;
    double y_low_max =0;
    float y_upp_min =0;
    float y_upp_max =0;

    int ycTracePix=0;                   /* central Y pos of trace Yc(Xc,Mc) */


    double tmpFct=0;                     /* tmp variable */



    double yShift=0;                     /* shift of order trace respect to Yc */

    int SF = 0;                         /* alias for short float */
    int i  = 0;                         /* loop index */
    int j  = 0;                         /* loop index */
    int ord = 0;

    int k=0;
    int m =0;

    float *frame_buf;
    float *i_median;
    double *sto_y_shift;
    double *sto_half_width;
    double *buf_pos_y_shift;
    double *buf_neg_y_shift;
    double *sto_pos_y_shift;
    double *sto_neg_y_shift;


    double *del_y_shift;
    double *del_pos_y_shift;
    double *del_neg_y_shift;

    double *del_half_width;
    double *buf_y_shift;
    double *buf_half_width;
    int   *sto_mask;
    int   *pos_mask;
    int   *neg_mask;

    float med_y_shift =0.;
    float med_half_width =0.;
    float avg_y_shift =0.;
    float avg_half_width =0.;
    float rms_y_shift =0.;
    float rms_half_width =0.;



    float med_pos_y_shift =0.;
    float avg_pos_y_shift =0.;
    float rms_pos_y_shift =0.;


    float med_neg_y_shift =0.;
    float avg_neg_y_shift =0.;
    float rms_neg_y_shift =0.;





    int j_bound_min = 0;
    int j_bound_max = 0;
    int nk = 0;
    int no = 0;

    int ord_min =0;
    int ord_max=0;
    int i_clip=0;


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


    SCSPRO(prgName);                    /* assign program name */




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

    int  nVal = 0;                      /* max no of returned chars */
    SCKGETC(IN_A, 1,FILE_LEN,&nVal,inIma);   /* get input frame */
    SCKGETC(IN_B, 1,FILE_LEN,&nVal,inTable); /* get input table */
    SCKRDR(SLIT, 1,1,&nVal,&inSlit, &unit,&null); /* get slit value */
    SCKRDI(ORD_MIN, 1,1,&nVal,&ordMin,&unit,&null); /* get ord min */
    SCKRDI(ORD_MAX, 1,1,&nVal,&ordMax,&unit,&null); /* get ord max */
    SCKRDI(DEFPOL, 1,2,&nVal,defPol,&unit,&null); /* get ord max */
    slitPix = (int) rint(inSlit);

    /*
    printf("Sav Bord Siz=%i\n",SAV_BORD_SZ);
    printf("X_WIND_SIZE=%i\n",X_WIND_SIZE);
    printf("Y_WIND_SIZE=%i\n",Y_WIND_SIZE);
    printf("Y_SEARCH_WIND=%i\n",Y_SEARCH_WIND);
    printf("ORD_TRESH=%i\n",ORD_TRESH);
    printf("N_CLIP_MED=%i\n",N_CLIP_MED);
    printf("INT_TRESH=%f\n",INT_TRESH);
     */

    printf("polx=%i,poly=%i\n",defPol[0],defPol[1]);

    nCoeffd = (defPol[0]+1)*(defPol[1]+1);
    if (nCoeffd>max_pol_ordXY) {
        return(MAREMMA);
    }
    //jmlarsen:
    //         there is no reason to open this table first with SCFOPN, then with TCTOPN.
    //         to avoid having to implement F_TBL_TYPE support in SCFOPN, just open
    //         the table with TCTOPN

    //before:  SCFOPN(inTable,D_R4_FORMAT,0,F_TBL_TYPE,&inTabId);   /* open input frame */
    //now:
    TCTOPN(inTable,F_I_MODE,&inTabId);
    SCDRDD(inTabId,"COEFFD",1,nCoeffd,&nVal,coeffd,&unit,&null); /* get COEFFD  */

    /*
    for(i=0;i<nCoeffd;i++){

    printf("coeff[%i]=%g\t",i,coeffd[i]);
    }
     */


    SCFOPN(inIma,D_R4_FORMAT,0,F_IMA_TYPE,&inImaId);   /* open input frame */
    SCDRDI(inImaId,"NPIX",1,2,&nVal,nPix,&unit,&null); /* get NPIX descript. */

    imaSizeX = nPix[0];
    imaSizeY = nPix[1];
    imaSizeT = imaSizeX*imaSizeY;

    dbl_aux = (double)(1+nPix[0])/2;
    xcPix = (int) rint(dbl_aux);

    dbl_aux = (double)(ordMin+ordMax)/2;
    cOrd = (int) rint(dbl_aux);

    /*
    printf("central Pixel:%i\n", xcPix);
    printf("central Order:%i\n", cOrd);
     */

    SF = (int) sizeof(float);

    /* do the mapping */

    pInImaF = (float*) malloc((size_t) imaSizeT*SF);
    if (pInImaF == NULL) SCTPUT("No memory for pInImaF");
    bufData = (char*) pInImaF;
    SCFGET(inImaId,1,imaSizeT,&nVal,bufData);    /* read the whole frame */

    /* map data for matrix access */
    /*   mInImaF = map2mat(pInImaF,imaSizeX,imaSizeY,1,1); */

    mInImaF = convert_matrix(pInImaF,1, (int32_t) imaSizeY, 1, (int32_t) imaSizeX);

    /* SCFMAP(inImaId,F_I_MODE,1,imaSizeT,&nVal,&mInImaF); */
    /* get input table data */

    //jmlarsen: this tale was already opened. Do not open again
    //  TCTOPN(inTable,F_I_MODE,&inTabId);
    TCIGET(inTabId, &nCol, &nRow);



    /* Prepare vectors to hold tmp results */
    buf_y_shift     = dvector(0,(ordMax-ordMin));
    buf_pos_y_shift = dvector(0,(ordMax-ordMin));
    buf_neg_y_shift = dvector(0,(ordMax-ordMin));

    del_y_shift     = dvector(0,(ordMax-ordMin));
    del_pos_y_shift = dvector(0,(ordMax-ordMin));
    del_neg_y_shift = dvector(0,(ordMax-ordMin));


    sto_y_shift     = dvector(0,(ordMax-ordMin));
    sto_pos_y_shift = dvector(0,(ordMax-ordMin));
    sto_neg_y_shift = dvector(0,(ordMax-ordMin));

    buf_half_width  = dvector(0,(ordMax-ordMin));
    del_half_width  = dvector(0,(ordMax-ordMin));
    sto_half_width  = dvector(0,(ordMax-ordMin));

    sto_mask        = ivector(0,(ordMax-ordMin));
    pos_mask        = ivector(0,(ordMax-ordMin));
    neg_mask        = ivector(0,(ordMax-ordMin));


    ord_min=(int)(ordMin+ORD_TRESH);
    ord_max=(int)(ordMax-ORD_TRESH);

    /*
    printf("ordmin=%d,ordmax=%d\n",ord_min,ord_max);
     */

    /* loop over orders (cutting ORD_TRESH) orders upp and down */
    for (ord=ord_min;ord<ord_max; ord++){
        cOrd=ord;
        /* printf("current Order:%i\n", cOrd); */


        /* get Y position of trace at central X pix */
        double ycTrace=0;
        int index=0;
        for(j=0;j<=defPol[1];j++){
            tmpFct = pow(cOrd,j);
            /* printf("\nj=%i,tmpFct=%g\t",j,tmpFct); */
            for(i=0;i<=defPol[0];i++){
                /* printf("i=%i, %g\t",i,coeffd[index]); */

                ycTrace += coeffd[index]*pow(xcPix,i)*tmpFct;
                ++index;
            }
        }

        /*
      printf("%f\n",ycTrace); 
         */
        double tmp =  rint(ycTrace);
        ycTracePix = (int) tmp;

        /*
      printf("ycTracePix=%i\n",ycTracePix);
      printf("ycTrace=%f\n",ycTrace); 
      printf("tmp=%f\n",tmp); 
         */
        float refInt = mInImaF[ycTracePix][xcPix];


        /*

    printf("Reference Intensity %f\n",refInt); 

         */
        /*
       =====================================================
       Here we take the median of the intensity values as 
       better intensity reference value for the flat FF
       =====================================================
         */


        int i_bound_min=xcPix-X_WIND_SIZE;
        int i_bound_max=xcPix+X_WIND_SIZE;

        i_median = vector(0,2*Y_SEARCH_WIND);
        frame_buf = vector(0,imaSizeY*3-1);

        if (i_bound_min < 0)        i_bound_min = 0;
        if (i_bound_max > imaSizeX) i_bound_max = imaSizeX;
        float i_max = 0;


        /*
      printf("ycTrace=%f,Y_SEARCH_WIND=%i\n",ycTrace,Y_SEARCH_WIND);
         */


        for(m=ycTracePix-Y_SEARCH_WIND;m<=ycTracePix+Y_SEARCH_WIND; m++)
        {
            j_bound_min = m-Y_WIND_SIZE;
            j_bound_max = m+Y_WIND_SIZE;

            if (j_bound_min < 0)        j_bound_min = 0;
            if (j_bound_max > imaSizeY) j_bound_max = imaSizeY;


            k=0;
            for(j=j_bound_min;j<=j_bound_max; j++)
            {
                for(i=i_bound_min ;i<=i_bound_max; i++)
                {
                    frame_buf[k]=mInImaF[j][i];
                    k++;
                }
            }

            nk=k;
            nk/=2;
            if(nk > imaSizeY*3) printf("Something strage ocxcurred\n");

            qsort(frame_buf, (size_t) nk, sizeof(float), ima_comp);
            i_median[m-ycTracePix+Y_SEARCH_WIND]=frame_buf[nk];

            /* Loop moved outside */
            /*
          if (i_median[m] > i_max) {
	  i_max = i_median[m];
	  }
             */
        }


        for(m=0;m<=2*Y_SEARCH_WIND; m++)
        {
            if (i_median[m] > i_max) {
                i_max = i_median[m];
                /* printf("Max Int=%f m=%i\n",i_max,m); */

            }
        }

        if (i_max <= 0) {
            SCTPUT("Max Intensity <= 0! Something should be wrong we exit!");
            return 0;
        }

        /*
       printf("Max Int=%f \n",i_max);
       printf("Discrepancy (Max-Ref)/Max=%f\n",(i_max-refInt)/i_max);
         */

        /*
       =====================================================
       Now we search for FF borders
       =====================================================

         */

        /*
      printf("ycTrace=%f\n",ycTrace); 
      printf("ycTracePix=%i\n",ycTracePix); 
         */
        /*
	This was the original setting 
	int_max=(1.0+INT_TRESH)*refInt;
	int_min=(1.0-INT_TRESH)*refInt;

         */
        /*
      printf("i_max=%f cut%f\n",i_max, INT_TRESH);
         */

        double int_max=(1.0+INT_TRESH)*i_max;
        double int_min=(1.0-INT_TRESH)*i_max;

        /*
      printf("int_min=%f\n",int_min);
      printf("int_max=%f\n",int_max);
      printf("xcPix=%i\n",xcPix);

      printf("Int Ima=%f\n",mInImaF[ycTracePix][xcPix]);
         */

        if (mInImaF[ycTracePix][xcPix] >= int_min){
            /* we are near the max of the FF */
            /* printf("Inside the flat part of FF\n"); */

            /*
	yMin = get_y_min(xcPix,ycTracePix,int_min,mInImaF,LOC_SAV_BORD_SZ);
	yMax = get_y_max(xcPix,ycTracePix,int_min,mInImaF,LOC_SAV_BORD_SZ);

             */

            /* printf("Before\n"); */
            find_mid_y_min_max(xcPix,
                            ycTracePix,
                            int_min,
                            mInImaF,
                            &yMin,
                            &yMax,
                            LOC_SAV_BORD_SZ);
            /*
	printf("After\n");
             */
        }
        else{
            /* we are in the interorder region */
            /* printf("near the border\n"); */

            /*

      printf("xcPix=%i, ycTracePix=%i, int_min=%f \n",
      xcPix,    ycTracePix,    int_min);
             */


            /*AM: here a critical point of robustness */
            find_low_y_min_max(xcPix,
                            ycTracePix,
                            int_min,
                            mInImaF,
                            &y_low_min,
                            &y_low_max,
                            LOC_SAV_BORD_SZ);


            find_upp_y_min_max(xcPix,
                               ycTracePix,
                               int_min,
                               mInImaF,
                               &y_upp_min,
                               &y_upp_max,
                               LOC_SAV_BORD_SZ);

            /*

      printf("ycTrace=%f\n",ycTrace);
      printf("y_low_min=%f\n",y_low_min);
      printf("y_low_max=%f\n",y_low_max);

      printf("y_upp_min=%f\n",y_upp_min);
      printf("y_upp_max=%f\n",y_upp_max);
             */

            if( (ycTrace-y_low_max) <= (y_upp_min-ycTrace) ){
                /* The distance of the trace from the FF upper border
	   below the Trace is less than the distance of the trace
	   from the FF lower border */

                yMin = y_low_min;
                yMax = y_low_max;
                /* printf("lower\n"); */
            }
            else{
                yMin = y_upp_min;
                yMax = y_upp_max;
                /* printf("upper\n"); */

            }

        }

        /*
      printf("yMin=%f\n",yMin);
      printf("yMax=%f\n",yMax);
         */
        double ycSlitPix=(yMin+yMax)/2.;
        double disTraceYmin=(ycTrace-yMin);
        double disTraceYmax=(yMax-ycTrace);
        yShift=-(ycTrace-ycSlitPix);
        double halfWidth=(yMax-yMin)/2.;

        sto_y_shift[ord]=yShift;
        sto_half_width[ord]=halfWidth;
        sto_mask[ord]=1;

        free_vector(frame_buf,0,imaSizeY*3-1);
        free_vector(i_median,0,2*Y_SEARCH_WIND);



        /*
	printf("ycSlitPix=%f,disTraceYmin=%f,disTraceYmax=%f\n",
	ycSlitPix,   disTraceYmin,   disTraceYmax);



	printf("ord=%i, ycSlitPix=%f yShift=%f halfWidth=%f\n",
	ord,    ycSlitPix,   yShift,   halfWidth);

         */


    } /* end of loop over ord */


    free_convert_matrix(mInImaF,1,(int32_t) imaSizeY,1,(int32_t) imaSizeX);

    /*
    ====================================================
    Now we divide positive from negative Yshifts
    ====================================================
     */

    for (ord = ord_min; ord < ord_max; ord++){

        if (sto_y_shift[ord] >= 0.) {
            sto_pos_y_shift[ord] = sto_y_shift[ord];
            pos_mask[ord] = 1;
            neg_mask[ord] = 0;
            n_pos_y_shift++;
        }
        else {
            sto_neg_y_shift[ord] = sto_y_shift[ord];
            neg_mask[ord] = 1;
            pos_mask[ord] = 0;
            n_neg_y_shift++;
        }

    }


    /*
    ====================================================
    Now we do a k-s clipping
    ====================================================
     */
    /* printf("Now we do a k-s clipping\n"); */
    clip_hw_small(sto_half_width,
                  sto_mask,
                  ord_min,
                  ord_max,
                  DRS_SFF_HW_MIN);

    update_mask(del_half_width,
                rms_half_width,
                sto_mask,
                ord_min,
                ord_max);


    /*
    ====================================================
    we 1st calculate starting points for med,rms,delta
    ====================================================
     */
    /* printf("we 1st calculate starting points for med,rms,delta\n"); */


    avg_pos_y_shift = get_avg(sto_pos_y_shift,
                    pos_mask,
                    ord_min,
                    ord_max);


    avg_neg_y_shift = get_avg(sto_neg_y_shift,
                    neg_mask,
                    ord_min,
                    ord_max);


    avg_y_shift = get_avg(sto_y_shift,
                    sto_mask,
                    ord_min,
                    ord_max);

    avg_half_width = get_avg(sto_half_width,
                    sto_mask,
                    ord_min,
                    ord_max);



    /*
       printf("Average yshift=%f\n",avg_y_shift);
       printf("Average pos yshift=%f\n",avg_pos_y_shift);
       printf("Average neg yshift=%f\n",avg_neg_y_shift);
       printf("Average halfWidth=%f\n",avg_half_width);

       printf("ord_min=%d\n",ord_min);
       printf("ord_max=%d\n",ord_max);

     */

    /*
     * -----------------------------------------------------------
     * Standard data
     * -----------------------------------------------------------
     */

    /* printf("Standard data\n"); */

    no=0;
    for(ord=ord_min;ord<ord_max; ord++){
        del_y_shift[ord]=fabs(sto_y_shift[ord]-avg_y_shift);
        del_half_width[ord]=fabs(sto_half_width[ord]-avg_half_width);
        buf_y_shift[no] = sto_y_shift[ord];
        buf_half_width[no] = sto_half_width[ord];
        no++;
    }
    no/=2.;
    rms_y_shift = get_avg(del_y_shift,
                    sto_mask,
                    ord_min,
                    ord_max);

    rms_half_width = get_avg(del_half_width,
                    sto_mask,
                    ord_min,
                    ord_max);


    /*
    printf("RMS yshift=%f\n",rms_y_shift);
    printf("RMS halfWidth=%f\n",rms_half_width);
     */

    if(no > imaSizeY*3) printf("Something strage ocxcurred\n");

    qsort(buf_y_shift, (size_t) no, sizeof(float), ima_comp);
    med_y_shift=(float)buf_y_shift[no];
    qsort(buf_half_width, (size_t) no, sizeof(float), ima_comp);
    med_half_width=(float)buf_half_width[no];

    /*
    printf("no=%d\n",no);
    printf("buf=%f\n",buf_y_shift[no]);
    printf("buf=%f\n",buf_half_width[no]);
    printf("Median yshift=%f\n",med_y_shift);
    printf("Median halfWidth=%f\n",med_half_width);
     */


    /*
     * -----------------------------------------------------------
     * Positive data
     * -----------------------------------------------------------
     */

    /* printf("Positive data\n"); */

    no=0;
    for(ord=ord_min;ord<ord_max; ord++){
        del_pos_y_shift[ord]= fabs(sto_pos_y_shift[ord]-avg_pos_y_shift);
        buf_pos_y_shift[no] = sto_pos_y_shift[ord];
        no++;
    }
    no/=2.;
    rms_pos_y_shift = get_avg(del_pos_y_shift,
                    pos_mask,
                    ord_min,
                    ord_max);

    if(no > imaSizeY*3) printf("Something strage ocxcurred\n");

    qsort(buf_pos_y_shift, (size_t) no, sizeof(float), ima_comp);
    med_pos_y_shift=(float)buf_pos_y_shift[no];


    /*
     * -----------------------------------------------------------
     * Negative data
     * -----------------------------------------------------------
     */

    /* printf("Negative data\n"); */

    no=0;
    for(ord=ord_min;ord<ord_max; ord++){
        del_neg_y_shift[ord]= fabs(sto_neg_y_shift[ord]-avg_neg_y_shift);
        buf_neg_y_shift[no] = sto_neg_y_shift[ord];
        no++;
    }
    no/=2.;
    rms_neg_y_shift = get_avg(del_neg_y_shift,
                    neg_mask,
                    ord_min,
                    ord_max);

    if(no > imaSizeY*3) printf("Something strage ocxcurred\n");

    qsort(buf_neg_y_shift, (size_t) no, sizeof(float), ima_comp);
    med_neg_y_shift=(float)buf_neg_y_shift[no];



    /*
    for (ord=ord_max;ord<ord_min; ord++){
    if ( (del_half_width[ord] > rms_half_width) ||
    (del_y_shift[ord]    > rms_y_shift)    ) {
    sto_mask[ord]=0;
    }
    }


    printf("min=%i\n",ord_min);
    printf("max=%i\n",ord_max);
    printf("med=%f\n",avg_y_shift);

     */


    /*
    ====================================================
    Next we start the k-s clipping
    ====================================================
     */

    for(i_clip=0;i_clip<N_CLIP_MED;i_clip++){


        /* printf (">>>>>>Median Clipping iter %i<<<<<<\n",i_clip); */


        clip_hw_new(sto_half_width,
                        sto_mask,
                        &ord_min,
                        &ord_max);



        /* y shift */

        update_delta(sto_y_shift,
                     med_y_shift,
                     ord_min,
                     ord_max,
                     del_y_shift);


        update_delta(sto_pos_y_shift,
                     med_pos_y_shift,
                     ord_min,
                     ord_max,
                     del_pos_y_shift);


        update_delta(sto_neg_y_shift,
                     med_neg_y_shift,
                     ord_min,
                     ord_max,
                     del_neg_y_shift);


        /* half width */


        update_delta(sto_half_width,
                     med_half_width,
                     ord_min,
                     ord_max,
                     del_half_width);

        /* mask */


        update_mask(del_half_width,
                    rms_half_width,
                    sto_mask,
                    ord_min,
                    ord_max);


        update_mask(del_y_shift,
                    rms_y_shift,
                    sto_mask,
                    ord_min,
                    ord_max);

        update_mask(del_pos_y_shift,
                    rms_pos_y_shift,
                    pos_mask,
                    ord_min,
                    ord_max);

        update_mask(del_neg_y_shift,
                    rms_neg_y_shift,
                    neg_mask,
                    ord_min,
                    ord_max);





        if (rms_half_width > 5 ) {
            /* printf("RMS HW=%f\n",rms_half_width); */
            rms_half_width=5;
        }
        else {
            /* printf("RMS HW=%f\n",rms_half_width); */
        }


        if (rms_y_shift > 5) {
            /* printf("RMS Y=%f\n",rms_y_shift); */
            rms_y_shift=5;
        }
        else {
            /* printf("RMS Y=%f\n",rms_y_shift); */
        }


        update_mask(del_half_width,
                    rms_half_width,
                    sto_mask,
                    ord_min,
                    ord_max);


        update_mask(del_y_shift,
                    rms_y_shift,
                    sto_mask,
                    ord_min,
                    ord_max);



        update_mask(del_pos_y_shift,
                    rms_pos_y_shift,
                    pos_mask,
                    ord_min,
                    ord_max);

        update_mask(del_neg_y_shift,
                    rms_neg_y_shift,
                    neg_mask,
                    ord_min,
                    ord_max);


        med_y_shift = get_med(sto_y_shift,
                        sto_mask,
                        ord_min,
                        ord_max);


        med_pos_y_shift = get_med(sto_pos_y_shift,
                        pos_mask,
                        ord_min,
                        ord_max);


        med_neg_y_shift = get_med(sto_neg_y_shift,
                        neg_mask,
                        ord_min,
                        ord_max);


        med_half_width = get_med(sto_half_width,
                        sto_mask,
                        ord_min,
                        ord_max);

        /*
      printf("Median yshift=%f\n",med_y_shift);
      printf("Median halfWidth=%f\n",med_half_width);
         */



        rms_y_shift = get_avg(del_y_shift,
                        sto_mask,
                        ord_min,
                        ord_max);


        rms_pos_y_shift = get_avg(del_pos_y_shift,
                        pos_mask,
                        ord_min,
                        ord_max);

        rms_neg_y_shift = get_avg(del_neg_y_shift,
                        neg_mask,
                        ord_min,
                        ord_max);

        rms_half_width = get_avg(del_half_width,
                        sto_mask,
                        ord_min,
                        ord_max);


        /*
      printf("RMS yshift=%f\n",rms_y_shift);
      printf("RMS halfWidth=%f\n",rms_half_width);
         */

        avg_y_shift = get_avg(sto_y_shift,
                        sto_mask,
                        ord_min,
                        ord_max);


        avg_pos_y_shift = get_avg(sto_pos_y_shift,
                        pos_mask,
                        ord_min,
                        ord_max);

        avg_neg_y_shift = get_avg(sto_neg_y_shift,
                        neg_mask,
                        ord_min,
                        ord_max);

        avg_half_width = get_avg(sto_half_width,
                        sto_mask,
                        ord_min,
                        ord_max);

        /*
      printf("Average yshift=%f\n",avg_y_shift);
      printf("Average halfWidth=%f\n",avg_half_width);
         */



    }





    for(i_clip=0;i_clip<N_CLIP_AVG;i_clip++){

        /*     printf (">>>>>>>Average Clipping iter %i<<<<<<<\n",i_clip); */

        clip_hw_new(sto_half_width,
                        sto_mask,
                        &ord_min,
                        &ord_max);


        update_delta(sto_y_shift,
                     avg_y_shift,
                     ord_min,
                     ord_max,
                     del_y_shift);



        update_delta(sto_pos_y_shift,
                     avg_pos_y_shift,
                     ord_min,
                     ord_max,
                     del_pos_y_shift);


        update_delta(sto_neg_y_shift,
                     avg_neg_y_shift,
                     ord_min,
                     ord_max,
                     del_neg_y_shift);



        update_delta(sto_half_width,
                     avg_half_width,
                     ord_min,
                     ord_max,
                     del_half_width);


        update_mask(del_half_width,
                    rms_half_width,
                    sto_mask,
                    ord_min,
                    ord_max);


        update_mask(del_y_shift,
                    rms_y_shift,
                    sto_mask,
                    ord_min,
                    ord_max);

        update_mask(del_pos_y_shift,
                    rms_pos_y_shift,
                    pos_mask,
                    ord_min,
                    ord_max);

        update_mask(del_neg_y_shift,
                    rms_neg_y_shift,
                    neg_mask,
                    ord_min,
                    ord_max);

        avg_y_shift = get_avg(sto_y_shift,
                        sto_mask,
                        ord_min,
                        ord_max);


        avg_pos_y_shift = get_avg(sto_pos_y_shift,
                        pos_mask,
                        ord_min,
                        ord_max);

        avg_neg_y_shift = get_avg(sto_neg_y_shift,
                        neg_mask,
                        ord_min,
                        ord_max);


        avg_half_width = get_avg(sto_half_width,
                        sto_mask,
                        ord_min,
                        ord_max);


        rms_y_shift = get_avg(del_y_shift,
                        sto_mask,
                        ord_min,
                        ord_max);


        rms_pos_y_shift = get_avg(del_pos_y_shift,
                        pos_mask,
                        ord_min,
                        ord_max);

        rms_neg_y_shift = get_avg(del_neg_y_shift,
                        neg_mask,
                        ord_min,
                        ord_max);



        rms_half_width = get_avg(del_half_width,
                        sto_mask,
                        ord_min,
                        ord_max);



        /*
	    printf("RMS yshift=%f\n",rms_y_shift);
	    printf("RMS halfWidth=%f\n",rms_half_width);
         */

        med_y_shift = get_med(sto_y_shift,
                        sto_mask,
                        ord_min,
                        ord_max);



        med_pos_y_shift = get_med(sto_pos_y_shift,
                        pos_mask,
                        ord_min,
                        ord_max);

        med_neg_y_shift = get_med(sto_neg_y_shift,
                        neg_mask,
                        ord_min,
                        ord_max);


        med_half_width = get_med(sto_half_width,
                        sto_mask,
                        ord_min,
                        ord_max);


        /*
      printf("Median yshift=%f\n",med_y_shift);
      printf("Median halfWidth=%f\n",med_half_width);
         */

    }
    if ( strcmp(drs_verbosity,"LOW") == 0 ) {
    } else {
    	char output[MAX_STRING_SZ];
        snprintf(output,MAX_STRING_SZ,"Median yshift=%f\n",med_y_shift);
        SCTPUT(output);
        snprintf(output,MAX_STRING_SZ,"Median halfWidth=%f\n",med_half_width);
        SCTPUT(output);

        snprintf(output,MAX_STRING_SZ,"Median yshift=%f\n",med_y_shift);
        SCTPUT(output);
        snprintf(output,MAX_STRING_SZ,"Median halfWidth=%f\n",med_half_width);
        SCTPUT(output);

        snprintf(output,MAX_STRING_SZ,"Median Positive yshift=%f\n",med_pos_y_shift);
        SCTPUT(output);

        snprintf(output,MAX_STRING_SZ,"Median Negative yshift=%f\n",med_neg_y_shift);
        SCTPUT(output);

        snprintf(output,MAX_STRING_SZ,"RMS Median Positive yshift=%f\n",rms_pos_y_shift);
        SCTPUT(output);

        snprintf(output,MAX_STRING_SZ,"RMS Median Negative yshift=%f\n",rms_neg_y_shift);
        SCTPUT(output);


    }



    if (n_neg_y_shift <= 1){
        SCDWRR(inImaId,"YSHIFT", &avg_y_shift,1,1,&unit);
        SCDWRR(inImaId,"ESO QC YSHIFT RMS", &rms_y_shift,1,1,&unit);
    }
    else if (n_pos_y_shift <= 1){
        SCDWRR(inImaId,"YSHIFT", &avg_y_shift,1,1,&unit);
        SCDWRR(inImaId,"ESO QC YSHIFT RMS", &rms_y_shift,1,1,&unit);
    }
    else{
        /*
       printf("RMS pos =%f RMS neg =%16.14f epsilon=%16.14f \n",
       rms_pos_y_shift,rms_neg_y_shift,MY_FEPSILON);
         */
        if ( (fabs(rms_pos_y_shift) >  MY_FEPSILON) &&
                        (fabs(rms_neg_y_shift) >  MY_FEPSILON) ){
            if (rms_pos_y_shift <= rms_neg_y_shift){
                SCDWRR(inImaId,"YSHIFT", &avg_pos_y_shift,1,1,&unit);
                SCDWRR(inImaId,"ESO QC YSHIFT RMS", &rms_pos_y_shift,1,1,&unit);
            }
            else{
                SCDWRR(inImaId,"YSHIFT", &avg_neg_y_shift,1,1,&unit);
                SCDWRR(inImaId,"ESO QC YSHIFT RMS", &rms_neg_y_shift,1,1,&unit);
            }
        }
        else if (fabs(rms_pos_y_shift) < MY_FEPSILON){
            SCDWRR(inImaId,"YSHIFT", &avg_neg_y_shift,1,1,&unit);
            SCDWRR(inImaId,"ESO QC YSHIFT RMS", &rms_neg_y_shift,1,1,&unit);
        }
        else {
            SCDWRR(inImaId,"YSHIFT", &avg_pos_y_shift,1,1,&unit);
            SCDWRR(inImaId,"ESO QC YSHIFT RMS", &rms_pos_y_shift,1,1,&unit);
        }
    }

    avg_half_width=avg_half_width+LOC_SAV_BORD_SZ-SAV_BORD_SZ;
    SCDWRR(inImaId,"HALFWIDTH", &avg_half_width,1,1,&unit);
    SCDWRR(inImaId,"ESO QC HALFWIDTH RMS", &rms_half_width,1,1,&unit);

    /* free residual allocated memory */
    free_dvector(sto_half_width,0,(ordMax-ordMin));
    free_dvector(del_half_width,0,(ordMax-ordMin));
    free_dvector(buf_half_width,0,(ordMax-ordMin));

    free_dvector(sto_y_shift,0,(ordMax-ordMin));
    free_dvector(sto_pos_y_shift,0,(ordMax-ordMin));
    free_dvector(sto_neg_y_shift,0,(ordMax-ordMin));


    free_dvector(buf_y_shift,0,(ordMax-ordMin));
    free_dvector(buf_pos_y_shift,0,(ordMax-ordMin));
    free_dvector(buf_neg_y_shift,0,(ordMax-ordMin));

    free_dvector(del_y_shift,0,(ordMax-ordMin));
    free_dvector(del_pos_y_shift,0,(ordMax-ordMin));
    free_dvector(del_neg_y_shift,0,(ordMax-ordMin));

    free_ivector(sto_mask,0,(ordMax-ordMin));
    free_ivector(pos_mask,0,(ordMax-ordMin));
    free_ivector(neg_mask,0,(ordMax-ordMin));
    free(pInImaF);
    /* close */
    SCFCLO(inTabId);
    SCFCLO(inImaId);
    SCSEPI();

    return 0;

}

/*=========================================================================*/






int 
ima_comp(const void *arg1, 
         const void *arg2)
{
    float *pixel1= (float *)arg1;
    float *pixel2= (float *)arg2;


    if (fabs((*pixel1)- (*pixel2)) < FEPSILON) {
        return 0;
    }
    else if (*pixel1 > *pixel2) {
        return -1;
    }
    else if (*pixel1 < *pixel2) {
        return 1;
    }
    else return 0;
}


float 
get_y_min(int     xcPix, 
          int     ycTracePix,
          double   int_min,
          float** mInImaF,
          int LOC_SAV_BORD_SZ)
{


    int i = 0;
    int y1 =0;
    int  y2 =0;
    float int1 =0;
    float int2 =0;
    float yMin =0;

    yMin=0;

    /* printf("ycTracePix=%i\n",ycTracePix); */

    i= ycTracePix;

    while(mInImaF[i][xcPix]>int_min){
        --i;
    }
    y1=i;
    y2=i+1;


    int1=mInImaF[y1][xcPix];
    int2=mInImaF[y2][xcPix];
    yMin=(float)(y1+(y2-y1)/(int2-int1)*(int_min-int1));
    yMin+=LOC_SAV_BORD_SZ;

    return yMin;

}  





float 
get_y_max(int     xcPix, 
          int     ycTracePix,
          double   int_min,
          float** mInImaF,
          int     LOC_SAV_BORD_SZ)
{
    int i = 0;
    int y1 =0;
    int  y2 =0;
    float int1 =0;
    float int2 =0;
    float yMax =0;

    /* printf("ycTracePix=%i\n",ycTracePix); */

    yMax=0;
    i=ycTracePix;
    while(mInImaF[i][xcPix]>int_min){
        ++i;
    }
    y1=i-1;
    y2=i;
    int1=mInImaF[y1][xcPix];
    int2=mInImaF[y2][xcPix];
    yMax=(float)(y1+(y2-y1)/(int2-int1)*(int_min-int1));
    yMax-=LOC_SAV_BORD_SZ;

    return yMax;
}




void
find_mid_y_min_max(int     xcPix, 
                   int     ycTracePix,
                   double   int_min,
                   float** mInImaF,
                   double*  yMin,
                   double*  yMax,
                   int LOC_SAV_BORD_SZ)
{


    int i = 0;
    int y1 =0;
    int  y2 =0;
    float int1 =0;
    float int2 =0;

    i= ycTracePix;

    /* printf("mid ycTracePix=%i\n",ycTracePix); */

    while( (mInImaF[i][xcPix] > FEPSILON) &&
                    ((mInImaF[i][xcPix]>int_min) ||
                                    (mInImaF[i][xcPix]<0.05*int_min)) ){

        /* printf("i=%d %f %f\n",i,mInImaF[i][xcPix],int_min); */
        --i;
    }
    y1=i;
    y2=i+1;



    int1=mInImaF[y1][xcPix];
    int2=mInImaF[y2][xcPix];

    (*yMin)=(float)(y1+(y2-y1)/(int2-int1)*(int_min-int1));
    (*yMin)+=LOC_SAV_BORD_SZ;




    i=ycTracePix;
    while( (mInImaF[i][xcPix] > FEPSILON) &&
                    ((mInImaF[i][xcPix]>int_min) ||
                                    (mInImaF[i][xcPix]<0.05*int_min)) ){
        ++i;
    }
    y1=i-1;
    y2=i;


    int1=mInImaF[y1][xcPix];
    int2=mInImaF[y2][xcPix];

    (*yMax)=(float)(y1+(y2-y1)/(int2-int1)*(int_min-int1));
    (*yMax)-=LOC_SAV_BORD_SZ;

}  




void 
find_upp_y_min_max(int     xcPix, 
                   int     ycTracePix,
                   double  int_min,
                   float** mInImaF,
                   float*  yMin,
                   float*  yMax,
                   int LOC_SAV_BORD_SZ)
{


    int i = 0;
    int y1 =0;
    int  y2 =0;
    double int1 =0;
    double int2 =0;
    //int j =0; /*for debugging purposes */

    i= ycTracePix;


    /* For debugging purposes
     printf("i=%i,xcPix=%i,int_min=%f,ima=%f ref%f \n",
     i    ,xcPix   ,(int_min), mInImaF[i][xcPix],(0.05*(int_min)) );


     for(j=i-10; j< (i+150);j++){
     printf("i=%i, ima=%f\n",j,mInImaF[j][xcPix]);
     }
     */


    while( (mInImaF[i][xcPix]<int_min) ||
                    (mInImaF[i][xcPix]<0.05*int_min) ){
        ++i;

        if (i >= 2048)
        {

            y1=2047;
            y2=2048;
            goto upp_end;
        }


        /* For debugging purposes*/

        /*
	   printf("i=%i, ima=%f int_min=%f ref_min=%f\n",
	   i,mInImaF[i][xcPix],(int_min),(0.05*(int_min)));
         */
    }
    y1=i;
    y2=i+1;


    int1=mInImaF[y1][xcPix];
    int2=mInImaF[y2][xcPix];

    (*yMin)=(float)(y1+((double)(y2-y1))/(int2-int1)*((int_min)-int1));
    (*yMin)+=LOC_SAV_BORD_SZ;

    /*
    printf("Y1=%d Y2=%d int1=%f int2=%f Imin=%f yMin=%f\n",
    y1,y2,int1,int2,int_min,*yMin);
     */
    i=(int)(*yMin);
    while( (mInImaF[i][xcPix]>int_min) ||
                    (mInImaF[i][xcPix]<0.05*(int_min)) ){
        ++i;

        if (i >= 2048)
        {

            y1=2047;
            y2=2048;
            goto upp_end;
        }
        /* For debugging purposes*/
        /*
      printf("i=%i, ima=%f int_min=%f ref_min=%f\n",
      i,mInImaF[i][xcPix],(int_min),(0.05*(int_min)));
         */
    }



    y1=i-1;
    y2=i;

    upp_end:
    int1=mInImaF[y1][xcPix];
    int2=mInImaF[y2][xcPix];
    (*yMax)=(float)(y1+(float)(y2-y1)/(int2-int1)*((int_min)-int1));
    (*yMax)-=LOC_SAV_BORD_SZ;
    /*
    printf("Y1=%d Y2=%d int1=%f int2=%f Imin=%f yMax=%f\n",
    y1,y2,int1,int2,int_min,*yMax);
     */


}  



void
find_low_y_min_max(int     xcPix, 
                   int     ycTracePix,
                   double   int_min,
                   float** mInImaF,
                   double*  yMin,
                   double*  yMax,
                   int LOC_SAV_BORD_SZ)
{


    int i = 0;
    int y1 =0;
    int  y2 =0;
    float int1 =0;
    float int2 =0;



    i= ycTracePix;
    while( (mInImaF[i][xcPix]<int_min) ||
                    (mInImaF[i][xcPix]<0.05*int_min) ){

        --i;

        if (i <= 0)
        {

            y1=2;
            y2=1;
            goto low_end;
        }

    }

    y1=i-1;
    y2=i;



    int1=mInImaF[y1][xcPix];
    int2=mInImaF[y2][xcPix];

    (*yMax)=y1+(y2-y1)/(int2-int1)*(int_min-int1);

    (*yMax)-=LOC_SAV_BORD_SZ;


    i=(int) (*yMax);

    if (i < 0)
    {

        y1=2;
        y2=1;
        goto low_end;
    }


    if (i > 4096)
    {

        y1=2;
        y2=1;
        goto low_end;
    }

    while( (mInImaF[i][xcPix]>int_min) ||
                    (mInImaF[i][xcPix]<0.05*int_min) ){
        --i;

        if (i <= 0)
        {

            y1=2;
            y2=1;
            goto low_end;
        }


    }


    y1=i+1;
    y2=i;

    low_end:
    int1=mInImaF[y1][xcPix];
    int2=mInImaF[y2][xcPix];
    (*yMin)=y1+(y2-y1)/(int2-int1)*(int_min-int1);
    (*yMin)+=LOC_SAV_BORD_SZ;

}  



float 
get_avg(double* val,
        int*   mask,
        int    min,
        int    max)
{
    /* this calculates the mean (average) of a distribution */
    int cnt=0;
    int i=0;
    float avg=0;


    for (i=min;i<max; i++)
    {
        if (mask[i] == 1) {
            /* printf("i=%i val=%f,med=%f,mask=%i\n",i,val[i],med,mask[i]); */
            avg+=val[i];
            cnt++;
        }
    }
    if (cnt) avg/=cnt;

    return avg;
}


float 
get_med(double* val,
        int*   mask,
        int    min,
        int    max)
{
    /* this calculates the mean (average) of a distribution */
    int cnt=0;
    int i=0;
    int nk=0;
    double med=0;
    double* buf;
    int buf_siz =0;

    for (i=min;i<max; i++)
    {
        if (mask[i] == 1) {
            /* printf("i=%i val=%f,med=%f,mask=%i\n",i,val[i],med,mask[i]); */
            cnt++;
        }
    }

    buf_siz=cnt;
    buf = dvector(0,buf_siz);

    cnt=0;
    for (i=min;i<max; i++)
    {
        if (mask[i] == 1) {
            /* printf("i=%i val=%f,med=%f,mask=%i\n",i,val[i],med,mask[i]); */

            buf[cnt++]=val[i];

        }
    }

    /*nk=(int)rint(cnt/2.); */
    nk=cnt/2.;

    if(nk > buf_siz) printf("Something strage ocxcurred\n");

    qsort(buf, (size_t) nk, sizeof(float), ima_comp);
    med=buf[nk];
    free_dvector(buf,0,buf_siz);

    return (float) med;
}



void
update_mask(double* del,
            float rms,
            int*   mask,
            int   min,
            int   max)
{
    /*
     this routine catch the point which have maximum distance from the mean,
     and greater that the rms of distances respect to the mean and mask it out
     */
    int i=0;
    int i_max=-1;
    float tresh=rms;
    int n_msk=0;
    for (i=min;i<max; i++)
    {
        if (mask[i] == 1) {
            /* if ((del[i] > tresh) || (del[i] > 5)) {*/
            if (del[i] > tresh) {
                /*
	    printf("Tresh %f\n",tresh);
	    printf("Value %f pos %i mask %i\n",del[i],i,mask[i]);
                 */
                i_max=i;
                tresh=(float) del[i];
            }
            n_msk++;
        }
    }
    if ((i_max >= 0) && n_msk >1) { /*We need to have at least one left point */
        /*
      printf("Maskera %i\n",i_max);
      printf("Value %f\n",del[i_max]);
         */
        mask[i_max]=0;
    }
}



void
update_delta(double* val,
             float  med,
             int    min,
             int    max,
             double* del)
{
    /* this routine update distances of values from a given mean */
    int i=0;

    for (i= min;i<max; i++)
    {
        del[i]=(float)fabs(val[i]-med);
    }
}



void
clip_hw_new(double* val,
            int* mask,
            int* min,
            int* max)
{
    /* this routine mask out negative half width values */
    int i=0;
    for (i= (*min);i<(*max); i++)
    {
        if (val[i] <= 0)  mask[i]=0;
    }
}


void
clip_hw_small(double* val,
              int* mask,
              int min,
              int max,
              int DRS_SFF_HW_MIN)
{
    /* this routine mask out negative half width values */
    int i=0;
    for (i= min;i<max; i++)
    {
        if (val[i] < DRS_SFF_HW_MIN)  mask[i]=0;
    }
}

/**@}*/
