/*===========================================================================
  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
===========================================================================*/
/* Program  : writespectrum.c                                              */
/* Author   : G. Mulas  -  ITAL_FLAMES Consortium                          */
/* Date     :                                                              */
/*                                                                         */
/* Purpose  : Missing                                                      */
/*                                                                         */
/*                                                                         */
/* Input:  see interface                                                   */ 
/*                                                                      */
/* Output:                                                              */
/*                                                                         */
/* DRS Functions called:                                                   */
/* none                                                                    */ 
/*                                                                         */ 
/* Pseudocode:                                                             */
/* Missing                                                                 */ 
/*                                                                         */ 
/* Version  :                                                              */
/* Last modification date: 2002/08/05                                      */
/* Who     When        Why                Where                            */
/* AMo     02-08-05   Add header         header                            */
/*-------------------------------------------------------------------------*/

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

#include <stdio.h>
#include <stdlib.h>
#include <flames_midas_def.h>
#include <flames_write_spectra.h>
#include <flames_uves.h>
#include <flames_newmatrix.h>
#include <string.h>

flames_err Write_Spectra(flames_frame *Science_Frame, /* Frame whose spectra are to 
                          be written */
                         int32_t nf, /* number of fibre whose spectrum is to 
                     be written */
             char *Base_Name)     /* base filename for the 
                         spectra */
{

  int naxis=0;
  int maxfibres=0;
  int status=0;
  int npix[2]={0,0};
  int unit=0;
  int dataid=0;
  int sigmaid=0;
  int maskid=0;
  int rawdataid=0;
  int rawsigmaid=0;
  int rawmaskid=0;
  int fibrenum=0;
  int32_t ix=0;
  int32_t no=0;
  int32_t numorders=0;

  float minimum=0;
  float maximum=0;

  float cuts[4]={0,0,0,0};

  double start[2]={0,0};
  double step[2]={0,0};

  frame_data **Poutarray=0;
  frame_mask **Poutmask=0;

  char output[70];
  char ident[73];
  char cunit[3][16];
  char dataname[CATREC_LEN+1];
  char sigmaname[CATREC_LEN+1];
  char maskname[CATREC_LEN+1];
  char rawdataname[CATREC_LEN+1];
  char rawsigmaname[CATREC_LEN+1];
  char rawmaskname[CATREC_LEN+1];
  char ans[CATREC_LEN+100];

  frame_data *fdvecbuf1=0;
  frame_data *fdvecbuf2=0;
  frame_mask *fmvecbuf1=0;
  frame_mask *fmvecbuf2=0;
  float fbuf1=0;
  int32_t ixnonfoffsetstep=0;
  int32_t ixnonfoffsetend=0;
  int32_t ixnonfoffset=0;
  int32_t noixindex=0;
  int32_t ixnonfindex=0;


  memset(output, '\0', 70);
  memset(dataname, '\0', CATREC_LEN+1);
  memset(sigmaname, '\0', CATREC_LEN+1);
  memset(maskname, '\0', CATREC_LEN+1);
  memset(rawdataname, '\0', CATREC_LEN+1);
  memset(rawsigmaname, '\0', CATREC_LEN+1);
  memset(rawmaskname, '\0', CATREC_LEN+1);
  memset(ident, '\0', 73);
  memset(cunit[0], '\0', 48);
  
  numorders = Science_Frame->lastorder-Science_Frame->firstorder+1;
  ixnonfoffsetstep = numorders*Science_Frame->maxfibres;
  ixnonfoffsetend = ((Science_Frame->subcols*numorders)-1)*
    Science_Frame->maxfibres;

  npix[0] = Science_Frame->subcols;  
  npix[1] = numorders;
  naxis = 2;
  cuts[0] = 0;
  cuts[1] = 0;
  start[0] = Science_Frame->substartx;
  start[1] = Science_Frame->firstorder;
  step[0] = Science_Frame->substepx;
  step[1] = Science_Frame->substepy;
 
  strncpy(cunit[1], "PIXEL           ", 16);
  strncpy(cunit[2], "PIXEL           ", 16);

  sprintf(ans,"Base_Name is %s\n",Base_Name);
  SCTPUT(ans);

  sprintf(dataname, "%s_%04d.fits", Base_Name, nf+1);
  sprintf(ans,"dataname is %s",dataname);
  SCTPUT(ans);

  sprintf(sigmaname, "%s_sig%04d.fits", Base_Name, nf+1);
  sprintf(ans,"sigmaname is %s",sigmaname);
  SCTPUT(ans);
   
  sprintf(rawdataname, "%s_raw%04d.fits", Base_Name, nf+1);
  sprintf(ans,"rawdataname is %s",dataname);
  SCTPUT(ans);

  sprintf(rawsigmaname, "%s_rawsig%04d.fits", Base_Name, nf+1);
  sprintf(ans,"rawsigmaname is %s",rawsigmaname);
  SCTPUT(ans);
   
  sprintf(maskname, "%s_extco%04d.fits", Base_Name, nf+1);
  sprintf(ans,"maskname is %s",maskname);
  SCTPUT(ans);

  sprintf(rawmaskname, "%s_rawextco%04d.fits", Base_Name, nf+1);
  sprintf(ans,"rawmaskname is %s",rawmaskname);
  SCTPUT(ans);

  if(SCFCRE(dataname, FLAMESDATATYPE, F_O_MODE, F_IMA_TYPE, 
        Science_Frame->subcols*numorders,
        &dataid)) {
    /* could not create the data file */
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  /* write standard descriptors of file */
  if (SCDWRC(dataid, "IDENT", 1, ident, 1, 72, &unit)) {
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  if (SCDWRI(dataid, "NAXIS", &naxis, 1, 1, &unit)) {
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  if (SCDWRI(dataid, "NPIX", npix, 1, 2, &unit)) {
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  if (SCDWRD(dataid, "START", start, 1, 2, &unit)) {
    /* error writing descriptor */
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  if (SCDWRD(dataid, "STEP", step, 1, 2, &unit)) { 
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  if (SCDWRC(dataid, "CUNIT", 1, cunit[0], 1, 48, &unit)) {
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  fdvecbuf1 = Science_Frame->normspec[0][0]+nf;
  minimum = maximum = (float) fdvecbuf1[0];
  for (ixnonfoffset=Science_Frame->maxfibres; ixnonfoffset<=ixnonfoffsetend; 
       ixnonfoffset+=Science_Frame->maxfibres) {
    fbuf1 = (float) fdvecbuf1[ixnonfoffset];
    if (fbuf1<minimum) minimum = fbuf1;
    if (fbuf1>maximum) maximum = fbuf1;
  }
  cuts[2] = minimum;
  cuts[3] = maximum;
  if (SCDWRR(dataid, "LHCUTS", cuts, 1, 4, &unit)) {
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  
  /* write the sigma file name as a descriptor of the data file */
  if (SCDWRC(dataid, "SIGMAFRAME", 1, sigmaname, 1, 80, &unit)) {
    /* error writing descriptor */
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  
  /* write the extracted columns file name as a descriptor of the data file */
  if (SCDWRC(dataid, "MASKFRAME", 1, maskname, 1, 80, &unit)) {
    /* error writing descriptor */
    SCFCLO(dataid); 
    return(MAREMMA);
  }

  /* write the scalars in descriptors */
  maxfibres = (int) Science_Frame->maxfibres;
  if (SCDWRI(dataid, "MAXFIBRES", &maxfibres, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  if (SCDWRC(dataid, "CHIPCHOICE", 1, &Science_Frame->chipchoice, 1, 1, 
         &unit)) {
    /* error writing descriptor */
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  if (SCDWRD(dataid, "RON", &Science_Frame->ron, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  if (SCDWRD(dataid, "GAIN", &Science_Frame->gain, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(dataid); 
    return(MAREMMA);
  }

  if (Science_Frame->nflats > 0) {
    if (SCDWRD(dataid, "YSHIFT", Science_Frame->yshift, 1, 
           Science_Frame->nflats, &unit)) {
      /* error writing descriptor */
      SCFCLO(dataid); 
      return(MAREMMA);
    }
  }
  if (SCDWRI(dataid, "ORDERLIM", &Science_Frame->firstorder, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  if (SCDWRI(dataid, "ORDERLIM", &Science_Frame->lastorder, 2, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(dataid); 
    return(MAREMMA);
  }
  if (SCDWRI(dataid, "TAB_IN_OUT_OSHIFT", &Science_Frame->tab_io_oshift, 
         1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(dataid); 
    return(MAREMMA);
  }

  fibrenum = (int) nf;
  if (SCDWRI(dataid, "FIBRENUM", &fibrenum, 1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(dataid); 
    return(MAREMMA);
  }

  sprintf(output,"I'm writing %s", dataname);
  SCTPUT(output);

  Poutarray=fdmatrix(0,numorders-1,0,Science_Frame->subcols-1);
  fdvecbuf1 = Science_Frame->normspec[0][0]+nf;
  fdvecbuf2 = Poutarray[0];
  for (ix=0; ix<=(Science_Frame->subcols-1); ix++) {
    ixnonfoffset = ix*ixnonfoffsetstep;
    for (no=0; no<=(numorders-1); no++) {
      noixindex = (no*Science_Frame->subcols)+ix;
      ixnonfindex = ixnonfoffset+no*Science_Frame->maxfibres;
      fdvecbuf2[noixindex]=fdvecbuf1[ixnonfindex];
    }
  }

  if(SCFPUT(dataid, 1, Science_Frame->subcols*numorders, 
        (char *) Poutarray[0])) {  
    free(Poutarray); 
    status = SCFCLO(dataid);
    return(MAREMMA);
  }
  free_fdmatrix(Poutarray,0,numorders-1,0,Science_Frame->subcols-1); 
  SCFCLO(dataid);

  /* now let's write the sigmafile */  

  if(SCFCRE(sigmaname, FLAMESDATATYPE, F_O_MODE, F_IMA_TYPE, 
        Science_Frame->subcols*numorders,
        &sigmaid)) {
    /* could not create the data file */
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  /* write standard descriptors of file */
  if (SCDWRC(sigmaid, "IDENT", 1, ident, 1, 72, &unit)) {
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  if (SCDWRI(sigmaid, "NAXIS", &naxis, 1, 1, &unit)) {
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  if (SCDWRI(sigmaid, "NPIX", npix, 1, 2, &unit)) {
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  if (SCDWRD(sigmaid, "START", start, 1, 2, &unit)) {
    /* error writing descriptor */
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  if (SCDWRD(sigmaid, "STEP", step, 1, 2, &unit)) {
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  if (SCDWRC(sigmaid, "CUNIT", 1, cunit[0], 1, 48, &unit)) {
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  fdvecbuf1 = Science_Frame->normsigma[0][0]+nf;
  minimum = maximum = fdvecbuf1[0];
  for (ixnonfoffset=Science_Frame->maxfibres; ixnonfoffset<=ixnonfoffsetend; 
       ixnonfoffset+=Science_Frame->maxfibres) {
    fbuf1 = (float) fdvecbuf1[ixnonfoffset];
    if (fbuf1<minimum) minimum = fbuf1;
    if (fbuf1>maximum) maximum = fbuf1;
  }
  cuts[2] = (float) minimum;
  cuts[3] = (float) maximum;
  if (SCDWRR(sigmaid, "LHCUTS", cuts, 1, 4, &unit)) {
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }

  if (SCDWRC(sigmaid, "SCIENCEFRAME", 1, dataname, 1, 80, &unit)) {
    /* error writing descriptor */
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }

  /* write the scalars in descriptors */
  maxfibres = (int) Science_Frame->maxfibres;
  if (SCDWRI(sigmaid, "MAXFIBRES", &maxfibres, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  if (SCDWRC(sigmaid, "CHIPCHOICE", 1, &Science_Frame->chipchoice, 1, 1, 
         &unit)) {
    /* error writing descriptor */
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  if (SCDWRD(sigmaid, "RON", &Science_Frame->ron, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  if (SCDWRD(sigmaid, "GAIN", &Science_Frame->gain, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }

  if (Science_Frame->nflats > 0) {
    if (SCDWRD(sigmaid, "YSHIFT", Science_Frame->yshift, 1, 
           Science_Frame->nflats, &unit)) {
      /* error writing descriptor */
      SCFCLO(sigmaid); 
      return(MAREMMA);
    }
  }
  if (SCDWRI(sigmaid, "ORDERLIM", &Science_Frame->firstorder, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  if (SCDWRI(sigmaid, "ORDERLIM", &Science_Frame->lastorder, 2, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }
  if (SCDWRI(sigmaid, "TAB_IN_OUT_OSHIFT", &Science_Frame->tab_io_oshift, 
         1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }

  fibrenum = (int) nf;
  if (SCDWRI(sigmaid, "FIBRENUM", &fibrenum, 1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(sigmaid); 
    return(MAREMMA);
  }

  sprintf(output,"I'm writing %s", sigmaname);
  SCTPUT(output);

  Poutarray=fdmatrix(0,numorders-1,0,Science_Frame->subcols-1);
  fdvecbuf1 = Science_Frame->normsigma[0][0]+nf;
  fdvecbuf2 = Poutarray[0];
  for (ix=0; ix<=(Science_Frame->subcols-1); ix++) {
    ixnonfoffset = ix*ixnonfoffsetstep;
    for (no=0; no<=(numorders-1); no++) {
      noixindex = (no*Science_Frame->subcols)+ix;
      ixnonfindex = ixnonfoffset+no*Science_Frame->maxfibres;
      fdvecbuf2[noixindex]=fdvecbuf1[ixnonfindex];
    }
  }

  if(SCFPUT(sigmaid, 1, Science_Frame->subcols*numorders, 
        (char *) Poutarray[0])) {
    free(Poutarray); 
    status = SCFCLO(sigmaid);
    return(MAREMMA);
  }
  free_fdmatrix(Poutarray,0,numorders-1,0,Science_Frame->subcols-1); 
  SCFCLO(sigmaid);

  /* Let's write the spectrum good columns mask */

  if(SCFCRE(maskname, FLAMESMASKTYPE, F_O_MODE, F_IMA_TYPE, 
        Science_Frame->subcols*numorders,
        &maskid))  {
    /* could not create the data file */
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  /* write standard descriptors of file */
  if (SCDWRC(maskid, "IDENT", 1, ident, 1, 72, &unit)) {
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  if (SCDWRI(maskid, "NAXIS", &naxis, 1, 1, &unit)) {
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  if (SCDWRI(maskid, "NPIX", npix, 1, 2, &unit)) {
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  if (SCDWRD(maskid, "START", start, 1, 2, &unit)) {
    /* error writing descriptor */
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  if (SCDWRD(maskid, "STEP", step, 1, 2, &unit)) {
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  if (SCDWRC(maskid, "CUNIT", 1, cunit[0], 1, 48, &unit)) {
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  fmvecbuf1 = Science_Frame->normmask[0][0]+nf;
  minimum = maximum = (float) fmvecbuf1[0];
  for (ixnonfoffset=Science_Frame->maxfibres; ixnonfoffset<=ixnonfoffsetend; 
       ixnonfoffset+=Science_Frame->maxfibres) {
    fbuf1 = (float) fmvecbuf1[ixnonfoffset];
    if (fbuf1<minimum) minimum = fbuf1;
    if (fbuf1>maximum) maximum = fbuf1;
  }
  cuts[2] = (float) minimum;
  cuts[3] = (float) maximum;
  if (SCDWRR(maskid, "LHCUTS", cuts, 1, 4, &unit)) {
    SCFCLO(maskid); 
    return(MAREMMA);
  }

  if (SCDWRC(maskid, "SCIENCEFRAME", 1, dataname, 1, 80, &unit)) {
    /* error writing descriptor */
    SCFCLO(maskid); 
    return(MAREMMA);
  }

  /* write the scalars in descriptors */
  maxfibres = (int) Science_Frame->maxfibres;
  if (SCDWRI(maskid, "MAXFIBRES", &maxfibres, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  if (SCDWRC(maskid, "CHIPCHOICE", 1, &Science_Frame->chipchoice, 1, 1, 
         &unit)) {
    /* error writing descriptor */
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  if (SCDWRD(maskid, "RON", &Science_Frame->ron, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  if (SCDWRD(maskid, "GAIN", &Science_Frame->gain, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(maskid); 
    return(MAREMMA);
  }

  if (Science_Frame->nflats > 0) {
    if (SCDWRD(maskid, "YSHIFT", Science_Frame->yshift, 1, 
           Science_Frame->nflats, &unit)) {
      /* error writing descriptor */
      SCFCLO(maskid); 
      return(MAREMMA);
    }
  }
  if (SCDWRI(maskid, "ORDERLIM", &Science_Frame->firstorder, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  if (SCDWRI(maskid, "ORDERLIM", &Science_Frame->lastorder, 2, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(maskid); 
    return(MAREMMA);
  }
  if (SCDWRI(maskid, "TAB_IN_OUT_OSHIFT", &Science_Frame->tab_io_oshift, 
         1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(maskid); 
    return(MAREMMA);
  }

  fibrenum = (int) nf;
  if (SCDWRI(maskid, "FIBRENUM", &fibrenum, 1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(maskid); 
    return(MAREMMA);
  }

  sprintf(output,"I'm writing %s", maskname);
  SCTPUT(output);

  Poutmask=fmmatrix(0,numorders-1,0,Science_Frame->subcols-1);
  fmvecbuf1 = Science_Frame->normmask[0][0]+nf;
  fmvecbuf2 = Poutmask[0];
  for (ix=0; ix<=(Science_Frame->subcols-1); ix++) {
    ixnonfoffset = ix*ixnonfoffsetstep;
    for (no=0; no<=(numorders-1); no++) {
      noixindex = (no*Science_Frame->subcols)+ix;
      ixnonfindex = ixnonfoffset+no*Science_Frame->maxfibres;
      fmvecbuf2[noixindex]=fmvecbuf1[ixnonfindex];
    }
  }

  if(SCFPUT(maskid, 1, Science_Frame->subcols*numorders, 
        (char *) Poutmask[0])) {  
    free(Poutmask); 
    status = SCFCLO(maskid);
    return(MAREMMA);
  }
  free_fmmatrix(Poutmask,0,numorders-1,0,Science_Frame->subcols-1); 
  SCFCLO(maskid);


  /* now write the unnormalised spectra */

  if(SCFCRE(rawdataname, FLAMESDATATYPE, F_O_MODE, F_IMA_TYPE, 
        Science_Frame->subcols*numorders,
        &rawdataid)) {
    /* could not create the data file */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  /* write standard descriptors of file */
  if (SCDWRC(rawdataid, "IDENT", 1, ident, 1, 72, &unit)) {
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawdataid, "NAXIS", &naxis, 1, 1, &unit)) {
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawdataid, "NPIX", npix, 1, 2, &unit)) {
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawdataid, "START", start, 1, 2, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawdataid, "STEP", step, 1, 2, &unit)) { 
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  if (SCDWRC(rawdataid, "CUNIT", 1, cunit[0], 1, 48, &unit)) {
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  fdvecbuf1 = Science_Frame->spectrum[0][0]+nf;
  minimum = maximum = (float) fdvecbuf1[0];
  for (ixnonfoffset=Science_Frame->maxfibres; ixnonfoffset<=ixnonfoffsetend; 
       ixnonfoffset+=Science_Frame->maxfibres) {
    fbuf1 = (float) fdvecbuf1[ixnonfoffset];
    if (fbuf1<minimum) minimum = fbuf1;
    if (fbuf1>maximum) maximum = fbuf1;
  }
  cuts[2] = (float) minimum;
  cuts[3] = (float) maximum;
  if (SCDWRR(rawdataid, "LHCUTS", cuts, 1, 4, &unit)) {
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  
  /* write the raw sigma file name as a descriptor of the data file */
  if (SCDWRC(rawdataid, "SIGMAFRAME", 1, rawsigmaname, 1, 80, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  
  /* write the extracted columns file name as a descriptor of the data file */
  if (SCDWRC(rawdataid, "MASKFRAME", 1, rawmaskname, 1, 80, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }

  /* write the scalars in descriptors */
  maxfibres = (int) Science_Frame->maxfibres;
  if (SCDWRI(rawdataid, "MAXFIBRES", &maxfibres, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  if (SCDWRC(rawdataid, "CHIPCHOICE", 1, &Science_Frame->chipchoice, 1, 1, 
         &unit)) {
    /* error writing descriptor */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawdataid, "RON", &Science_Frame->ron, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawdataid, "GAIN", &Science_Frame->gain, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }

  if (Science_Frame->nflats > 0) {
    if (SCDWRD(rawdataid, "YSHIFT", Science_Frame->yshift, 1, 
           Science_Frame->nflats, &unit)) {
      /* error writing descriptor */
      SCFCLO(rawdataid); 
      return(MAREMMA);
    }
  }
  if (SCDWRI(rawdataid, "ORDERLIM", &Science_Frame->firstorder, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawdataid, "ORDERLIM", &Science_Frame->lastorder, 2, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawdataid, "TAB_IN_OUT_OSHIFT", &Science_Frame->tab_io_oshift, 
         1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }

  fibrenum = (int) nf;
  if (SCDWRI(rawdataid, "FIBRENUM", &fibrenum, 1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(rawdataid); 
    return(MAREMMA);
  }

  sprintf(output,"I'm writing %s", rawdataname);
  SCTPUT(output);

  Poutarray=fdmatrix(0,numorders-1,0,Science_Frame->subcols-1);
  fdvecbuf1 = Science_Frame->spectrum[0][0]+nf;
  fdvecbuf2 = Poutarray[0];
  for (ix=0; ix<=(Science_Frame->subcols-1); ix++) {
    ixnonfoffset = ix*ixnonfoffsetstep;
    for (no=0; no<=(numorders-1); no++) {
      noixindex = (no*Science_Frame->subcols)+ix;
      ixnonfindex = ixnonfoffset+no*Science_Frame->maxfibres;
      fdvecbuf2[noixindex]=fdvecbuf1[ixnonfindex];
    }
  }

  if(SCFPUT(rawdataid, 1, Science_Frame->subcols*numorders, 
        (char *) Poutarray[0])) {  
    free(Poutarray); 
    status = SCFCLO(rawdataid);
    return(MAREMMA);
  }
  free_fdmatrix(Poutarray,0,numorders-1,0,Science_Frame->subcols-1); 
  SCFCLO(rawdataid);

  /* now let's write the rawsigmafile */  

  if(SCFCRE(rawsigmaname, FLAMESDATATYPE, F_O_MODE, F_IMA_TYPE, 
        Science_Frame->subcols*numorders,
        &rawsigmaid)) {
    /* could not create the data file */
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  /* write standard descriptors of file */
  if (SCDWRC(rawsigmaid, "IDENT", 1, ident, 1, 72, &unit)) {
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawsigmaid, "NAXIS", &naxis, 1, 1, &unit)) {
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawsigmaid, "NPIX", npix, 1, 2, &unit)) {
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawsigmaid, "START", start, 1, 2, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawsigmaid, "STEP", step, 1, 2, &unit)) {
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  if (SCDWRC(rawsigmaid, "CUNIT", 1, cunit[0], 1, 48, &unit)) {
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  fdvecbuf1 = Science_Frame->specsigma[0][0]+nf;
  minimum = maximum = (float) fdvecbuf1[0];
  for (ixnonfoffset=Science_Frame->maxfibres; ixnonfoffset<=ixnonfoffsetend; 
       ixnonfoffset+=Science_Frame->maxfibres) {
    fbuf1 = (float) fdvecbuf1[ixnonfoffset];
    if (fbuf1<minimum) minimum = fbuf1;
    if (fbuf1>maximum) maximum = fbuf1;
  }
  cuts[2] = (float) minimum;
  cuts[3] = (float) maximum;
  if (SCDWRR(rawsigmaid, "LHCUTS", cuts, 1, 4, &unit)) {
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }

  if (SCDWRC(rawsigmaid, "SCIENCEFRAME", 1, rawdataname, 1, 80, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }

  /* write the scalars in descriptors */
  maxfibres = (int) Science_Frame->maxfibres;
  if (SCDWRI(rawsigmaid, "MAXFIBRES", &maxfibres, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  if (SCDWRC(rawsigmaid, "CHIPCHOICE", 1, &Science_Frame->chipchoice, 1, 1, 
         &unit)) {
    /* error writing descriptor */
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawsigmaid, "RON", &Science_Frame->ron, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawsigmaid, "GAIN", &Science_Frame->gain, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }

  if (Science_Frame->nflats > 0) {
    if (SCDWRD(rawsigmaid, "YSHIFT", Science_Frame->yshift, 1, 
           Science_Frame->nflats, &unit)) {
      /* error writing descriptor */
      SCFCLO(rawsigmaid); 
      return(MAREMMA);
    }
  }
  if (SCDWRI(rawsigmaid, "ORDERLIM", &Science_Frame->firstorder, 
         1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawsigmaid, "ORDERLIM", &Science_Frame->lastorder, 
         2, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawsigmaid, "TAB_IN_OUT_OSHIFT", &Science_Frame->tab_io_oshift, 
         1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }

  fibrenum = (int) nf;
  if (SCDWRI(rawsigmaid, "FIBRENUM", &fibrenum, 1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(rawsigmaid); 
    return(MAREMMA);
  }

  sprintf(output,"I'm writing %s", rawsigmaname);
  SCTPUT(output);

  Poutarray=fdmatrix(0,numorders-1,0,Science_Frame->subcols-1);
  fdvecbuf1 = Science_Frame->specsigma[0][0]+nf;
  fdvecbuf2 = Poutarray[0];
  for (ix=0; ix<=(Science_Frame->subcols-1); ix++) {
    ixnonfoffset = ix*ixnonfoffsetstep;
    for (no=0; no<=(numorders-1); no++) {
      noixindex = (no*Science_Frame->subcols)+ix;
      ixnonfindex = ixnonfoffset+no*Science_Frame->maxfibres;
      fdvecbuf2[noixindex]=fdvecbuf1[ixnonfindex];
    }
  }

  if(SCFPUT(rawsigmaid, 1, Science_Frame->subcols*numorders, 
        (char *) Poutarray[0])) {
    free(Poutarray); 
    status = SCFCLO(rawsigmaid);
    return(MAREMMA);
  }
  free_fdmatrix(Poutarray,0,numorders-1,0,Science_Frame->subcols-1); 
  SCFCLO(rawsigmaid);

  /* Let's write the raw spectrum good columns mask */

  if(SCFCRE(rawmaskname, FLAMESMASKTYPE, F_O_MODE, F_IMA_TYPE, 
        Science_Frame->subcols*numorders,
        &rawmaskid))  {
    /* could not create the data file */
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  /* write standard descriptors of file */
  if (SCDWRC(rawmaskid, "IDENT", 1, ident, 1, 72, &unit)) {
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawmaskid, "NAXIS", &naxis, 1, 1, &unit)) {
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawmaskid, "NPIX", npix, 1, 2, &unit)) {
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawmaskid, "START", start, 1, 2, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawmaskid, "STEP", step, 1, 2, &unit)) {
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  if (SCDWRC(rawmaskid, "CUNIT", 1, cunit[0], 1, 48, &unit)) {
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  fmvecbuf1 = Science_Frame->specmask[0][0]+nf;
  minimum = maximum = (float) fmvecbuf1[0];
  for (ixnonfoffset=Science_Frame->maxfibres; ixnonfoffset<=ixnonfoffsetend; 
       ixnonfoffset+=Science_Frame->maxfibres) {
    fbuf1 = (float) fmvecbuf1[ixnonfoffset];
    if (fbuf1<minimum) minimum = fbuf1;
    if (fbuf1>maximum) maximum = fbuf1;
  }
  cuts[2] = (float) minimum;
  cuts[3] = (float) maximum;
  if (SCDWRR(rawmaskid, "LHCUTS", cuts, 1, 4, &unit)) {
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }

  if (SCDWRC(rawmaskid, "SCIENCEFRAME", 1, rawdataname, 1, 80, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }

  /* write the scalars in descriptors */
  maxfibres = (int) Science_Frame->maxfibres;
  if (SCDWRI(rawmaskid, "MAXFIBRES", &maxfibres, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  if (SCDWRC(rawmaskid, "CHIPCHOICE", 1, &Science_Frame->chipchoice, 1, 1, 
         &unit)) {
    /* error writing descriptor */
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawmaskid, "RON", &Science_Frame->ron, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  if (SCDWRD(rawmaskid, "GAIN", &Science_Frame->gain, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }

  if (Science_Frame->nflats > 0) {
    if (SCDWRD(rawmaskid, "YSHIFT", Science_Frame->yshift, 1, 
           Science_Frame->nflats, &unit)) {
      /* error writing descriptor */
      SCFCLO(rawmaskid); 
      return(MAREMMA);
    }
  }
  if (SCDWRI(rawmaskid, "ORDERLIM", &Science_Frame->firstorder, 1, 1, &unit)) {
    /* error writing descriptor */
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawmaskid, "ORDERLIM", &Science_Frame->lastorder, 2, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }
  if (SCDWRI(rawmaskid, "TAB_IN_OUT_OSHIFT", &Science_Frame->tab_io_oshift, 
         1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }

  fibrenum = (int) nf;
  if (SCDWRI(rawmaskid, "FIBRENUM", &fibrenum, 1, 1,  &unit)) {
    /* error writing descriptor */
    SCFCLO(rawmaskid); 
    return(MAREMMA);
  }

  sprintf(output,"I'm writing %s", rawmaskname);
  SCTPUT(output);

  Poutmask=fmmatrix(0,numorders-1,0,Science_Frame->subcols-1);
  fmvecbuf1 = Science_Frame->specmask[0][0]+nf;
  fmvecbuf2 = Poutmask[0];
  for (ix=0; ix<=(Science_Frame->subcols-1); ix++) {
    ixnonfoffset = ix*ixnonfoffsetstep;
    for (no=0; no<=(numorders-1); no++) {
      noixindex = (no*Science_Frame->subcols)+ix;
      ixnonfindex = ixnonfoffset+no*Science_Frame->maxfibres;
      fmvecbuf2[noixindex]=fmvecbuf1[ixnonfindex];
    }
  }

  if(SCFPUT(rawmaskid, 1, Science_Frame->subcols*numorders, 
        (char *) Poutmask[0])) {  
    free(Poutmask); 
    status = SCFCLO(rawmaskid);
    return(MAREMMA);
  }
  free_fmmatrix(Poutmask,0,numorders-1,0,Science_Frame->subcols-1); 
  SCFCLO(rawmaskid);



  return(NOERR);

}
