/* 

   Otmar Stahl, Anton Malina
   
   echloc.c
   
   Search echelle orders with template matching technique
   Center lines: center of gravity or gaussian

.VERSION	030406	delivered to ESO

110214		last modif
*/

/* system includes */

#include <stdio.h>
#include <ctype.h>

/* general Midas includes */

#include <tbldef.h>
#include <midas_def.h>
#include <ok.h>

/* FEROS specific includes */

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

int main ()
{
  int npix[2], npixo[2], npixt[2], npixtt[2];
  int win, width, fit_deg, nact;
  int ncol, nrow, nsort, acol, arow, xcol, i;

  int actvals, kun, knul, tid, tidi;
  int imno, imnoo, imnof, imnot, imnott, naxis, naxist;
  int lnfit_method;
  int xcenter[MAXORDERS];

  int icol[6], icoli[7], iparam[3], cut_step, center, cut_nr, first_pix;
  int cut_nr1, cut_nr2, first_cut, inull;

  char in_image[60], in_table[60], out_image[60], ech_table[60], cunit[64], ident[72];
  char foldimage[80], in_template[80], out_template[80];
  char line[80], qualif[4];

  float param[1], thres, rnull, xpos;
  float *imageo, *imagef, *imaget, *imagett, tab[6];

  double start[2], step[2], stepo[2], starto[2];
  double startt[2], stept[2], starttt[2], steptt[2];
  double dnull;

  /*         get into Midas and get parameters             */

nact = lnfit_method = 0;

  SCSPRO ("echloc");
  TCMNUL(&inull, &rnull, &dnull); 

  /* handle table as matrix, get repres of null values */

  SCKGETC ("IN_A", 1, 60, &actvals, in_image);        

 /* read kwds into vars */

  SCKGETC ("IN_B", 1, 60, &actvals, in_table);
  SCKGETC ("OUT_B", 1, 60, &actvals, ech_table);
  SCKGETC ("CUTS_IMG", 1, 60, &actvals, out_image);
  SCKGETC ("FOLD_IMG", 1, 80, &actvals, foldimage);
  SCKGETC ("TEMPL_IMG", 1, 80, &actvals, in_template);
  SCKGETC ("TEMPLT_IMG", 1, 80, &actvals, out_template);
  SCKRDI  ("INPUTI", 1, 3, &actvals, iparam, &kun, &knul);
  SCKRDR  ("INPUTR", 1, 1, &actvals, param, &kun, &knul);
  SCKGETC ("INPUTC", 1, 2, &actvals, qualif);

  SCFOPN (in_image, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, &imno); 
  
  /* open frame */

  SCDRDI (imno, "NAXIS", 1, 1, &actvals, &naxis, &kun, &knul);

  /* read int descriptor */

  if (naxis != 2) 
    {
      SCTPUT("Frame not 2-D, exiting");
      SCSEPI();
    }
  SCDRDI (imno, "NPIX", 1, 2, &actvals, npix, &kun, &knul);     /* read */
  SCDRDD (imno, "START", 1, 2, &actvals, start, &kun, &knul);  /* descriptors */
  SCDRDD (imno, "STEP", 1, 2, &actvals, step, &kun, &knul);
  thres = param[0];
  cut_step = iparam[0];
  win  = (int) iparam[1] / 2;
  fit_deg = iparam[2];
  width = 2 * win + 1;

  center = npix[1] / 2;
  cut_nr1 = (center - 1) / cut_step;
  cut_nr2 = (npix[1] - center) / cut_step;
  cut_nr = cut_nr1 + cut_nr2;
  first_cut = center % cut_step;

  stepo[0] = step[0];
  stepo[1] = step[1] * cut_step;
  starto[0] = start[0];
  starto[1] = start[1] + step[1] * (first_cut - 1);

  npixo[0] = npix[0];
  npixo[1] = cut_nr;
  SCTPUT ("search orders");
  SCTPUT ("-------------\n");
  sprintf (line, "Input image:         %s", in_image);
  SCTPUT (line);
  sprintf (line, "Output image:        %s", out_image);
  SCTPUT (line);
  sprintf (line, "Output table:        %s\n", ech_table);
  SCTPUT (line);
  SCTPUT ("input parameters:");
  sprintf (line, "step, window, degree: %04i %04i %04i", cut_step, width, fit_deg);
  SCTPUT (line);
  sprintf (line, "threshold:  %6.2f", thres);
  SCTPUT (line);

  /*          extract cuts                             */

  SCIPUT(out_image, D_R4_FORMAT, F_O_MODE, F_IMA_TYPE, 2, npixo,
	 starto, stepo, "Cut frame", "mm", (char **) &imageo, &imnoo); 
  extract_cuts(imno, first_cut, cut_step, cut_nr, imageo, npix);
  sprintf(line, "cuts extracted");
  SCTPUT(line);

  SCIPUT(foldimage, D_R4_FORMAT, F_O_MODE, F_IMA_TYPE, 1, npixo, 
	 starto, stepo, "Folded frame", "mm", (char **) &imagef, &imnof);    
  SCIGET(in_template, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, 2, &naxist, npixt, 
	 startt, stept, ident, cunit, (char **) &imaget, &imnot);

  first_pix = cut_nr / 2 * npix[0];
  fold_image(imageo, imagef, imaget, first_pix, npix, npixt[0]);

  switch (toupper(qualif[0]))
    {
    case ('S') :  /* here for searching orders */
      {
	sprintf(line, "search orders");
	SCTPUT(line);
	nact = search_lines(imagef, xcenter, npix, win, width, thres);
	sprintf(line, "%i orders found", nact);
	SCTPUT(line);
	break;
      }
    case ('G') :  /* here for guess table, read xcenter and nact */
      {
	TCTOPN(in_table, F_I_MODE, &tidi);
	TCIGET(tidi, &ncol, &nrow, &nsort, &acol, &arow);
	TCLSER(tidi, "X_AXIS", &xcol);
	for ( i = 0; i < nrow ; i++)
	  {
	    TCERDR (tidi, i + 1, xcol, &xpos, &knul);
	    xpos = (xpos - start[0]) / step[0];
	    xcenter[i] = (int) xpos;                   /* pixel coords */
	  }
	TCTCLO(tidi);
	nact = nrow;
	sprintf(line, "%d positions read", nact);
	SCTPUT(line);
	break;
    }
    default :
      {
	sprintf(line, "Error: Unknown qualifier %s", qualif);
	SCTPUT(line);
	SCETER(9, "Exiting...");
	break;
      }
    }
  switch (toupper(qualif[1]))
    {
    case 'R': /* gravity */
      {
	lnfit_method = GRAVITY;
	break;
      }
    case 'A': /* gaussian */
      {
	lnfit_method = GAUSSIAN;
	break;
      }
    default:
      {
	sprintf(line, "Error: Unknown qualifier %s", qualif);
	SCTPUT(line);
	SCETER(9, "Exiting...");
	break;
      }
    }

  if (TCTINI(ech_table, F_TRANS, F_O_MODE, 7, nact, &tid))
    SCTPUT ("Error creating table");
  TCCINI(tid, D_R4_FORMAT, 1, "F7.2", "mm", "Xpos", &icol[0]);
  TCCINI(tid, D_R4_FORMAT, 1, "F7.4", "mm", "Ypos", &icol[1]);
  TCCINI(tid, D_R4_FORMAT, 1, "F7.2", "(no unit)", "Order", &icol[2]);
  TCCINI(tid, D_R4_FORMAT, 1, "F7.2", "(no unit)", "XCorr", &icol[3]);
  TCCINI(tid, D_R4_FORMAT, 1, "F7.2", "mm", "Fit_pos", &icol[4]);
  TCCINI(tid, D_R4_FORMAT, 1, "F7.2", "mm", "Residual", &icol[5]);
  npixtt[0] = npixt[0];
  npixtt[1] = nact;
  starttt[0] = starttt[1] = steptt[0] = steptt[1] = 1;

  SCIPUT(out_template, D_R4_FORMAT, F_O_MODE, F_IMA_TYPE, 2, npixtt, 
	 starttt, steptt, "template frame", "mm", (char **) &imagett, &imnott);

  follow_orders
    (
     tid, imageo, imagef, imagett, npixo, npixt, starto, stepo,
     xcenter, tab, icol, icoli, nact, win, width, lnfit_method, rnull
     );

  TCSINI(tid);

  fit_orders(tid, nact, fit_deg, tab, icol, rnull);
 
  TCTCLO(tid);
 
  SCSEPI();  /* disconnect from midas */
  return(0);
}
