/* 
   Otmar Stahl, Anton Malina

   echext.c  

   extract echelle orders

.VERSION    030406	delivery to ESO

 110214		last modif

*/

/* system includes */

#include <ctype.h>
#include <string.h>
#include <stdio.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>
#include <misc.h>

int main ()
{
  char  out_image[68], sky_image[68], fit_image1[68], mask_image1[68],
    fit_image2[68], mask_image2[68], app_name[68], straight_image1[68],
    straight_image2[68], xpos_image1[68], xpos_image2[68],
    dy_image1[68], dy_image2[68],
    coeffile[68], coeff_file[68];
  char cunit[64], ident[72];
  char line[80], qualif[4], number[4];

  int niter, actvals, kun, knul, imnor;
  int dunit, dnul, inull, straight1, straight2, xpos1, xpos2, dy1, dy2;
  int i, norder, nlines, npts, iparam[2], npixo[2], *npoints;

  float rnull;
  float ccd_param[3];
  float v0,             /* ron in e  */
    gain,           /* gain in e/ADU */
    thres,          /* thres in sigma^2 */
    ec, es, eb, ea; /* errors in spatial profile modeling */
  float *imageo;
  float lhcuts[4];
 
  double start[2], step[2], stepo[2], starto[2], dnull;

  size_t name_len;

  BOOLEAN get_profile, write_imgs;



  strcpy(ident,"extracted frame");
  strcpy(cunit,"flux            position");

  /* get into Midas and get parameters */

  SCSPRO("echext");                          /* connect to Midas */
  TCMNUL(&inull, &rnull, &dnull);            /* bit pattern for null values */

  SCKGETC("IN_C", 1, 60, &actvals, straight_image1);
  SCKGETC("IN_C", 1, 60, &actvals, straight_image2);
  strcpy(xpos_image1, straight_image1);
  strcpy(xpos_image2, straight_image1);
  strcpy(dy_image1, straight_image1);
  strcpy(dy_image2, straight_image1);
  SCKGETC("OUT_A", 1, 60, &actvals, out_image);
  SCKGETC("OUT_B", 1, 60, &actvals, sky_image);
  SCKGETC("OUT_C", 1, 60, &actvals, coeff_file);
  SCKGETC("OUT_D", 1, 60, &actvals, fit_image1);
  SCKGETC("OUT_D", 1, 60, &actvals, fit_image2);
  SCKGETC("OUT_E", 1, 60, &actvals, mask_image1);
  SCKGETC("OUT_E", 1, 60, &actvals, mask_image2);
  SCKGETC("INPUTC",1, 5, &actvals, qualif);
  SCKRDI("INPUTI", 1, 2, &actvals, iparam, &kun, &knul);
  SCKRDR("CCD_PAR", 1, 3, &actvals, ccd_param, &kun, &knul);

  v0 = ccd_param[0]; 
  gain = 1.0 / ccd_param[1]; 
  thres = SQUARE(ccd_param[2]);

  ec = 0.0; 
  es = 0.0; 
  eb = 0.0; 
  ea = 0.0;
 
  SCTPUT("Extract orders");                                    /* write info */
  SCTPUT("--------------\n");
  sprintf(line, "Input image:  %s", straight_image1);
  SCTPUT(line);
  sprintf(line, "Output image: %s", out_image);
  SCTPUT(line);
  niter = iparam[1]; 
  get_profile = (toupper(qualif[2]) == 'Y');
  write_imgs = (toupper(qualif[3]) == 'Y');
  switch (toupper(qualif[0]))
    {
    case ('F') :    /* Fiber mode, subtract background and extract */
      strcat(straight_image1, "_C");
      strcat(xpos_image1, "_X");
      strcat(dy_image1, "_D");
      SCFOPN(straight_image1, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, &straight1);
      SCFOPN(xpos_image1, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, &xpos1);
      SCFOPN(dy_image1, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, &dy1);

      SCDRDI(straight1, "NLINES", 1, 1, &actvals, &nlines, &dunit, &dnul);
      SCDRDI(straight1, "NORDER", 1, 1, &actvals, &norder, &dunit, &dnul);
      SCDRDD(straight1, "START", 1, 2, &actvals, start, &dunit, &dnul);
      SCDRDD(straight1, "STEP", 1, 2, &actvals, step, &dunit, &dnul);
      stepo[0] = step[0]; stepo[1] = 1.0;
      starto[0] = start[0]; starto[1] = 1.0;
      npoints = ivector(1, norder);
      SCDRDI(straight1, "NPOINTS", 1, norder, &actvals, &npoints[1], 
	     &dunit, &dnul);

      /* find maximum point number */

      npts = 0;
      for(i = 1; i <= norder; ++i)
	{
	  if (npts < npoints[i]) npts = npoints[i];
	}
      npixo[0] = npts; npixo[1] = norder;
      strcpy(coeffile, coeff_file);
      SCIPUT(out_image, D_R4_FORMAT, F_O_MODE, F_IMA_TYPE, /* create .bdf */
	     2, npixo, starto, stepo, ident, cunit,     /* file out_image */
	     (char **) &imageo, &imnor);                /* and write desc */
      SCDWRR (imnor, "LHCUTS", lhcuts, 1, 4, &kun);
      extract_spec
	(imageo, iparam[0], qualif[1], v0, gain, thres, niter,
	 norder, nlines, npts, npoints, straight1, xpos1, dy1, 
	 coeffile, get_profile, write_imgs, fit_image1,
	 mask_image1
	 );
      free_ivector(npoints, 1, norder);
      SCFCLO(imnor);
      SCFCLO(straight1); 
      SCFCLO(xpos1); 
      SCFCLO(dy1);
      break;

    case ('G') :    /* extract two spectra -- FEROS mode  */

      /* create two output images */

      name_len = strcspn(out_image,".");
      out_image[name_len] = '\0';

      /* first fiber */

      strcat(straight_image1, "_C1");
      strcat(xpos_image1, "_X1");
      strcat(dy_image1, "_D1");
      strcat(fit_image1, "1");
      strcat(mask_image1, "1");
      SCFOPN(straight_image1, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, &straight1);
      SCFOPN(xpos_image1, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, &xpos1);
      SCFOPN(dy_image1, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, &dy1);
      SCDRDI(straight1, "NLINES", 1, 1, &actvals, &nlines, &dunit, &dnul);
      SCDRDI(straight1, "NORDER", 1, 1, &actvals, &norder, &dunit, &dnul);
      SCDRDD(straight1, "START", 1, 2, &actvals, start, &dunit, &dnul);
      SCDRDD(straight1, "STEP", 1, 2, &actvals, step, &dunit, &dnul);
      stepo[0] = step[0]; stepo[1] = 1.0;
      starto[0] = start[0]; starto[1] = 1.0;
      npoints = ivector(1, norder);
      SCDRDI(straight1,"NPOINTS", 1, norder, &actvals, 
	     &npoints[1], &dunit, &dnul);

      /* find maximum point number */

      npts = 0;
      for(i = 1; i <= norder; ++i)
	{
	  if (npts < npoints[i]) npts = npoints[i];
	}

      npixo[0] = npts; 
      npixo[1] = norder;

      out_image[name_len] = '\0';
      sprintf(number, "%01i", 1);
      strcpy(app_name, out_image);
      strcat(app_name, number);
      strcpy(coeffile, coeff_file);
      strcat(coeffile, number);
      sprintf(line, "%s", app_name); SCTPUT(line);

      SCIPUT(app_name, D_R4_FORMAT, F_O_MODE, F_IMA_TYPE,
	     2, npixo, starto, stepo, ident, cunit,
	     (char **) &imageo, &imnor);
      SCDWRR (imnor, "LHCUTS", lhcuts, 1, 4, &kun);
      extract_spec(imageo,
		    iparam[0], qualif[1], v0, gain, thres, niter,
		    norder, nlines, npts, npoints, straight1, xpos1, dy1,
		    coeffile, get_profile, write_imgs, fit_image1,
		    mask_image1);

      free_ivector(npoints, 1, norder); 
      SCFCLO(imnor);
      SCFCLO(straight1); 
      SCFCLO(xpos1);
      SCFCLO(dy1);

      /* second fiber */

      strcat(straight_image2, "_C2");
      strcat(xpos_image2, "_X2");
      strcat(dy_image2, "_D2");
      strcat(fit_image2, "2");
      strcat(mask_image2, "2");
      SCFOPN(straight_image2, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, &straight2);
      SCFOPN(xpos_image2, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, &xpos2);
      SCFOPN(dy_image2, D_R4_FORMAT, F_I_MODE, F_IMA_TYPE, &dy2);
      SCDRDI(straight2, "NLINES", 1, 1, &actvals, &nlines, &dunit, &dnul);
      SCDRDI(straight2, "NORDER", 1, 1, &actvals, &norder, &dunit, &dnul);
      SCDRDD(straight2, "START", 1, 2, &actvals, start, &dunit, &dnul);
      SCDRDD(straight2, "STEP", 1, 2, &actvals, step, &dunit, &dnul);
      stepo[0] = step[0]; stepo[1] = 1.0;
      starto[0] = start[0]; starto[1] = 1.0;
      npoints = ivector(1, norder);
      SCDRDI(straight2,"NPOINTS", 1, norder, &actvals, &npoints[1], &dunit, &dnul);
      
      /* find maximum point number */

      npts = 0;
      for(i = 1; i <= norder; ++i)
	{
	  if (npts < npoints[i]) npts = npoints[i];
	}
      npixo[0] = npts; 
      npixo[1] = norder;
      sprintf(number, "%01i", 2);
      strcpy(app_name, out_image);
      strcat(app_name, number);
      strcpy(coeffile, coeff_file);
      strcat(coeffile, number);
      sprintf(line, "%s", app_name); 
      SCTPUT(line);
      SCIPUT(app_name, D_R4_FORMAT, F_O_MODE, F_IMA_TYPE,
	     2, npixo, starto, stepo, ident, cunit,
	     (char **) &imageo, &imnor);
      SCDWRR (imnor, "LHCUTS", lhcuts, 1, 4, &kun);
      extract_spec(imageo,
		    iparam[0], qualif[1], v0, gain, thres, niter,
		    norder, nlines, npts, npoints, straight2, xpos2, dy2, 
		    coeffile, get_profile, write_imgs, fit_image2,
		    mask_image2);
      free_ivector(npoints, 1, norder);
      SCFCLO(imnor);
      SCFCLO(straight2); 
      SCFCLO(xpos2); 
      SCFCLO(dy2);
      break;

    default :
      sprintf(line, "Error: Unknown qualifier %s", qualif);
      SCTPUT(line);
      SCETER(9, "Exiting...");
    } /* end switch(toupper(qualif[0])) */
  SCSEPI(); /* epilogue */
  return(0);
}
