/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++  */
/* .COPYRIGHT   (C) 1993-2009 European Southern Observatory      */
/* .AUTHORS     Pascal Ballester (ESO/Garching)             */
/*              Cristian Levin   (ESO/La Silla)             */
/*              Otmar Stahl      (LSW)                      */
/* .KEYWORDS    Spectroscopy, Long-Slit                     */
/* .PURPOSE     Wavelength Calibration for 1D, Long and MOS */
/* .VERSION     1.0  Package Creation  17-MAR-1993          */
/* -------------------------------------------------------  */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.IDENT        mosapdisp.c
.MODULE       main program -- mosapdisp.exe
.LANGUAGE     C
.AUTHOR       Otmar Stahl - LSW Heidelberg 
.PURPOSE      Wavelength calibration of "image" of extracted spectra
.KEYWORDS     No rebinning.

.VERSION 1.0  5-Jan-1994   Implementation

 090804		last modif
------------------------------------------------------------ */

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

#include <stdio.h>


#define   ipos(col,row,siz)              row * siz + col

              
void mos_eval_disp(), rebin(), write_dcol();
int  mos_readdisp();



int main ()

{
  char inframe[60], coerbr[60], roottab[40], outtab[60], output[61];
  char number[6];
  int status, actvals;	/* Std Interfaces variables */
  int naxis, npix[2], imno, ypix, ypos[100], slit[100], i;
  double start[2], step[2];
  double *x_world, *lambda, *bin;
  char ident[80], cunit[64];
  char *image;
  int colw, colb, colf, cole, tid, nobjects;
  int dunit, dnull;

  SCSPRO ("mosapdisp");

  strcpy(ident,""), strcpy(cunit,"");

  status = SCKGETC ("IN_A", 1, 60, &actvals, inframe);
  if (status)
    SCTPUT ("Error while reading IN_A");

  status = SCKGETC ("IN_B", 1, 60, &actvals, coerbr);
  if (status)
    SCTPUT ("Error while reading IN_B");

  status = SCKGETC ("OUT_A", 1, 40, &actvals, roottab);
  if (status)
    SCTPUT ("Error while reading OUT_A");

  /* read "line-by-line" frame  */

  SCIGET (inframe, D_R8_FORMAT, F_I_MODE, F_IMA_TYPE, 2, &naxis, npix, start,
	  step, ident, cunit, &image, &imno);

  /* ypos is the original y-position of the spectra (before extraction) */

  SCDRDI (imno, "YPOS", 1, 100, &actvals, ypos, &dunit, &dnull);
  SCDRDI (imno, "SLIT", 1, 100, &actvals, slit, &dunit, &dnull);

  if (naxis == 1)
    {
      npix[1] = 1;
      start[1] = 1.0;
      step[1] = 1.0;
    }

  /* arrays for the columns */

     nobjects = npix[1]/2;

     x_world = (double *)   osmmget(npix[0]*npix[1]*sizeof(double));
     lambda  = (double *)   osmmget(npix[0]*npix[1]*sizeof(double));
     bin     = (double *)   osmmget(npix[0]*npix[1]*sizeof(double));

     /* loop over all rows, and tables  */

  for (i = 0; i < nobjects; i++)
    {
      ypix = i;

      strcpy (outtab, roottab);
      sprintf (number, "%04i", i + 1);
      strcat (outtab, number);
      sprintf (output,"%s", outtab);
      SCTPUT(output);

      if (TCTINI (outtab, F_TRANS, F_O_MODE, 5, npix[0], &tid))
	SCTPUT ("**** Error while creating output table");

      TCCINI (tid, D_R8_FORMAT, 1, "F8.2", "Lambda", "LAMBDA", &colw);
      TCCINI (tid, D_R8_FORMAT, 1, "F8.2", "Bin size", "BIN", &colb);
      TCCINI (tid, D_R8_FORMAT, 1, "F8.2", "Flux", "FLUX", &colf);
      TCCINI (tid, D_R8_FORMAT, 1, "F8.2", "Error", "FLUX_ERROR", &cole);

      /* Do the job */
      
      rebin (coerbr, x_world, lambda, bin, start, step, npix, ypos[i], 
	     slit[i]);

      /* All results are written to the output table */

      write_dcol (tid, npix[0], colw, lambda, 0);
      write_dcol (tid, npix[0], colb, bin, 0);
      write_dcol (tid, npix[0], colf, image, ipos (0, ypix, npix[0]));
      write_dcol (tid, npix[0], cole, image, ipos (0, ypix+nobjects, npix[0]));

      TCSINI(tid);
      TCTCLO (tid);

    }

  /* Close everything and good bye */

  osmmfree ((char *)x_world), osmmfree((char *)lambda), osmmfree ((char *)bin);
  SCFCLO (imno), SCSEPI ();
return 0;
}

/*---------------------------------------------------------------------------*/
#ifdef __STDC__
void rebin (char coerbr[], double x_world[], double lambda[], double bin[],
       double start[], double step[], int npix[], int y, int slit)
#else
void rebin ( coerbr, x_world, lambda, bin, start, step, npix, y, slit)
  char coerbr[];
  double x_world[],lambda[],bin[],start[],step[];
  int npix[],y,slit;
#endif

{

  int pix, status;

  for (pix = 0; pix < npix[0]; pix++)
    x_world[pix] = pix * step[0] + start[0];

  /* The following 4 routines are called (module lndisp.c) to 
     apply the dispersion relation to the world coordinates */

  mos_initdisp (coerbr, "OLD", 0);
  status = mos_readdisp (y, slit);

  if (status == 0) {
    mos_eval_disp (x_world, lambda, npix[0]);
    finishdisp ();
}
  /* Compute bin column (differences of lambda) */

  for (pix = 1; pix < npix[0]; pix++)
    bin[pix] = lambda[pix] - lambda[pix - 1];
  bin[0] = bin[1];

}

#ifdef __STDC__
void write_dcol (int tid, int nb, int colnb, double col[], int start)
#else
void write_dcol (tid, nb, colnb, col, start)
int tid, nb, colnb, start;
double col[];
#endif

{
  int i;

  for (i = 0; i < nb; i++)
    TCEWRD (tid, (i + 1), colnb, &col[start + i]);

}


