/* @(#)follow_orders.c	19.1 (ESO-IPG) 02/25/03 14:21:25 */
/* 

   Otmar Stahl, Anton Malina

   follow_orders.c   

   follow echelle orders, up and down 

*/

/* system includes */

#include <stdio.h>
#include <math.h>

/* general Midas includes */

#include <midas_def.h>

/* FEROS specific includes */

#include <echelle.h>
#include <nrutil.h>
#include <mutil.h>
#include <misc.h>

int follow_orders
#ifdef __STDC__
(
 int tid, float imageo[], float imagef[], 
 float imaget[],	int npix[], int npixt[], 
 double start[], double step[], int xcenter[], 
 float tab[], int icol[], int icoli[], 
 int nact, int win, int width, int lnfit_method, float rnull
 )
#else
     (
      tid, imageo, imagef, imaget, npix, npixt, 
      start, step, xcenter, tab, icol,  icoli, 
      nact, win, width, lnfit_method, rnull
      )
     int tid, npix[], npixt[], xcenter[]; 
     int icol [], icoli[], nact, win, width, lnfit_method;
     float imageo[], imagef[], imaget[], tab[], rnull;
     double start[], step[];
#endif

{
  int i, j, jj, first_pix, width2, center, first_cut;
  int first_entry = 0, left_edge, right_edge;
  float mini, xcorr;
  float *center_0, *corr_arr;
  int *xcenter_0, *offset;
  char line[80];

  center_0 = vector (0, nact);
  corr_arr = vector(0, npixt[0]);
  offset = ivector (0, nact);
  xcenter_0 = ivector (0, nact);

  first_cut = npix[1] / 2;
  first_pix = npix[0] * first_cut;
  tab[3] = npix[1] * step[1] / 2. + start[1];

  /* fit at y-center */

  for (i = 0; i < nact; i++)
    {
      fit_line(
	       imagef, xcenter[i], tab, start, step, 
	       lnfit_method, win, width, rnull
	       );  
      
      /* lnfit_method gaussian may fail for some weakly exposed orders */

      tab[4] = (float) (i + 1);
      center_0[i] = tab[0];
      xcenter_0[i] = xcenter[i];
      offset[i] = 0;
    }
  
  /* set up correlation arrays */

  width2 = (npixt[0] - 1) / 2;
  left_edge =  width2;
  right_edge = npix[0] - width2;
  for (i = 0; i < nact; i++)
    {
      center = first_pix + xcenter[i];

      /* search minimum */

      mini = 3.e34;
      for (jj= -width2; jj <= width2; jj++) 
	{
	  if (mini > imageo[center + jj])
	    {
	      mini = imageo[center + jj];
	    }
	}

      /* normalize local auto-correlation */

      xcorr =  0.0;
      for (jj = -width2; jj <= width2; jj++)
	{
	  xcorr += SQUARE(imageo[center + jj] - mini);
	}
      xcorr = (float) sqrt((double) xcorr); 
      for (jj = -width2; jj <= width2; jj++) 
	{
	  imaget[npixt[0] * i + jj + width2] = 
	    (imageo[center + jj] - mini) / xcorr;
	}
    }

  /* 
     all preparations done, now loop through lines upwards
     imaget contains the normalized auto-correlation arrays for all orders
     
     centers for all orders at reference positions are
     stored in center_0, xcenter_0
  */

  /* loop up */

  first_entry = 0;
  sprintf(line, "\nfollow up from center\n");
  SCTPUT(line);

  for ( j = first_cut; j < npix[1]; j++)
    {
      center_all_orders
	(
	 imageo, imaget, corr_arr, xcenter, xcenter_0, offset,
	 center_0, j, npixt, tab, start, step, npix,
	 win, width2, nact, tid, first_entry, icol, 
	 left_edge, right_edge, lnfit_method, WM_DOWRITE
	 );
      first_entry += nact;
    }

  /* loop down */

  first_entry -= nact;

  sprintf(line, "\nfollow down from upper edge\n");

  SCTPUT(line);
  
  for (i=0; i<nact ; i++)
    {
      xcenter[i] = xcenter_0[i];
      offset[i] = 0;
    }


  for (j = first_cut; j >= 0; j--)
    {
      center_all_orders
	(
	 imageo, imaget, corr_arr, xcenter, xcenter_0, offset,
	 center_0, j, npixt, tab, start, step, npix,
	 win, width2, nact, tid, first_entry, icol, 
	 left_edge, right_edge, lnfit_method, WM_DOWRITE
	 );
      
      first_entry += nact;
    }
  return 0;
}


