/*===========================================================================
  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  : writeslitff.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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <flames_midas_def.h>
#include <flames_writeslitff.h>
#include <flames_uves.h>
#include <uves_msg.h>
#include <flames_newmatrix.h>


/* Take care of both ANSI and K&R possibilities in the definition */
flames_err 
writeslitff(allslitflats *slitflats, 
            const char *basename, 
        cpl_frameset* *catname)
{

  int status=0;
  int oldfileid=0;
  int dataid=0;
  int sigmaid=0;
  int badid=0;
  int commid=0;
  int boundid=0;
  int normid=0;
  int unit=0;
  int null=0;
  int32_t iframe=0;
  int32_t ***longarray=0;
  char filename[CATREC_LEN+1];
  char dummychar[CATREC_LEN+1];
  int ibuf[3]={0,0,0};
  float lhcuts[4]={0,0,0,0};
  double dbuf[3]={0,0,0};
  char blank[]="     ";
  char cunit[65];

  slitFF *myslit=0;
  frame_data *fdvecbuf1=0;
  frame_mask *fmvecbuf1=0;
  int32_t *lvecbuf1=0;
  int32_t boundsize=0;
  int32_t iorderixend=0;
  int32_t iiorderixend=0;
  int32_t iiorderixend2=0;
  int32_t iorderixindex=0;
  int32_t iiorderixindex=0;
  float minimum=0;
  float maximum=0;
  float fbuf1=0;

  memset(filename, '\0', CATREC_LEN+1);
  memset(dummychar, '\0', CATREC_LEN+1);
  memset(cunit, '\0', 65);

  boundsize = (slitflats->lastorder-slitflats->firstorder+1)*
    slitflats->subcols;
  iiorderixend = 2*boundsize-1;
  iiorderixend2 = 3*boundsize-1;
  iorderixend = boundsize-1;

  /* create the empty catalog catname */
  if ((status = SCCCRE(catname, F_IMA_TYPE, 0)) != 0) {
    /* could not create the catalog: complain... */
    return flames_midas_error(MAREMMA);
  }

  /* allocate the memory for the boundaries buffer */
  longarray = l3tensor(0, 1, 0, slitflats->lastorder-slitflats->firstorder, 
               0, slitflats->subcols-1);
  /* run a loop over the flat frames */
  for(iframe=0; iframe<=slitflats->nflats-1; iframe++) {
    myslit = slitflats->slit+iframe;
    /* open the old frame from which the descriptors must be copied */
    if ((status = SCFOPN(myslit->framename, FLAMESDATATYPE, 
             0, F_IMA_TYPE, &oldfileid)) != 0) {
      /* could not open the file */
      return flames_midas_error(MAREMMA);
    }

    /* data frame */
    /* create the filename */
    sprintf(filename,"%s_data%02d.fits",basename,iframe+1);
    /* create the normalised data frame on disk */
    if ((status = SCFCRE(filename, FLAMESDATATYPE, F_O_MODE, F_IMA_TYPE, 
             slitflats->subrows*slitflats->subcols, &dataid))
    != 0) {
      /* could not create the file */
      return flames_midas_error(MAREMMA);
    }
    /* copy the descriptors from the old frame to the normalised frame */
    if ((status = SCDCOP(oldfileid, dataid, 1)) != 0) {
      /* I could not copy the descriptors: complain... */
      return flames_midas_error(MAREMMA);
    }

    /* write the IDENT descriptor */
    if ((status = SCDWRC(dataid, "IDENT", 1, "Normalised slit FF", 1, 
             CATREC_LEN+1, &null)) != 0) {
      /* I could not write the descriptor: complain... */
      return flames_midas_error(MAREMMA);
    }
    /* actually write the data frame to the new file*/
    if ((status = SCFPUT(dataid, 1, slitflats->subrows*slitflats->subcols,
             (char *) myslit->data[0])) != 0) {
      /* I could not write the data to disk: complain... */
      return flames_midas_error(MAREMMA);
    }
    /* add the name of this frame to the catalog */
    if ((status = SCCADD(*catname, filename, blank)) != 0) {
      /* coud not add filename to the catalog: complain */
      return flames_midas_error(MAREMMA);
    }

    /* sigma frame */
    /* create the filename */
    sprintf(filename,"%s_sigma%02d.fits",basename,iframe+1);
    /* create the sigma frame on disk */
    if ((status = SCFCRE(filename, FLAMESDATATYPE, F_O_MODE, F_IMA_TYPE, 
             slitflats->subrows*slitflats->subcols, &sigmaid))
    != 0) {
      /* could not create the file */
      return flames_midas_error(MAREMMA);
    }
    /* write the name of the sigma file as a descriptor of the data frame */
    if ((status = SCDWRC(dataid, "SIGMAFILE", 1, filename, 1, CATREC_LEN+1, 
             &null)) != 0) {
      /* I could not write the descriptor: complain... */
      return flames_midas_error(MAREMMA);
    }
    /* copy the descriptors from the old frame to the sigma frame */
    if ((status = SCDCOP(oldfileid, sigmaid, 1)) != 0) {
      /* I could not copy the descriptors: complain... */
      return flames_midas_error(MAREMMA);
    }
    /* actually write the sigma frame to the new file*/
    if ((status = SCFPUT(sigmaid, 1, slitflats->subrows*slitflats->subcols,
             (char*) myslit->sigma[0])) != 0) {
      /* I could not write the data to disk: complain... */
      return flames_midas_error(MAREMMA);
    }
    /* close the sigma frame */
    if ((status = SCFCLO(sigmaid)) != 0) {
      /* I could not close the data file: complain... */
      return flames_midas_error(MAREMMA);
    }

    /* badpixel frame */
    /* create the filename */
    sprintf(filename,"%s_badpixel%02d.fits",basename,iframe+1);
    /* create the badpixel frame on disk */
    if ((status = SCFCRE(filename, FLAMESMASKTYPE, F_O_MODE, F_IMA_TYPE, 
             slitflats->subrows*slitflats->subcols, &badid))
    != 0) {
      /* could not create the file */
      return flames_midas_error(MAREMMA);
    }
    /* write the name of the badpixel file as a descriptor of the data frame */
    if ((status = SCDWRC(dataid, "BADPIXELFILE", 1, filename, 1, CATREC_LEN+1, 
             &null)) != 0) {
      /* I could not write the descriptor: complain... */
      return flames_midas_error(MAREMMA);
    }
    /* copy the descriptors from the old frame to the badpixel frame */
    if ((status = SCDCOP(oldfileid, badid, 1)) != 0) {
      /* I could not copy the descriptors: complain... */
      return flames_midas_error(MAREMMA);
    }
    /* actually write the badpixel frame to the new file*/
    if ((status = SCFPUT(badid, 1, slitflats->subrows*slitflats->subcols,
             (char *) myslit->badpixel[0])) != 0) {
      /* I could not write the data to disk: complain... */
      return flames_midas_error(MAREMMA);
    }
    /* close the badpixel frame */
    if ((status = SCFCLO(badid)) != 0) {
      /* I could not close the data file: complain... */
      return flames_midas_error(MAREMMA);
    }

    /* boundaries frame */
    /* concoct the name of the pixel-order frame containing lowbound (first
       layer and highbound (second layer). */
    sprintf(filename,"%s_bound%02d.fits",basename,iframe+1);
    /* create this frame on disk */
    if ((status = SCFCRE(filename, D_I4_FORMAT, F_O_MODE, F_IMA_TYPE, 
             2*(slitflats->lastorder-slitflats->firstorder+1)*
             slitflats->subcols, &boundid))
    != 0) {
      /* could not create the file */
      return flames_midas_error(MAREMMA);
    }

    /* copy the descriptors from the data file */

    //jmlarsen: The following SCDCOP does not really work.
    //  The NPIX values in the boundid frame are incompatible
    //  with the allocated buffer. Therefore, replace this
    //  call with an equivalent call which ignores the NPIX values
    //  this is fine because NPIX/NAXIS is set below

//    if ((status = SCDCOP(dataid, boundid, 1)) != 0) {
    if ((status = SCDCOP_nonaxis(dataid, boundid, 1)) != 0) {
      /* I could not copy the descriptors */
      return flames_midas_error(MAREMMA);
    }


    /* write the name of the boundaries file as a descriptor of the data 
       frame */
    if ((status = SCDWRC(dataid, "BOUNDARYFILE", 1, filename, 1, CATREC_LEN+1, 
             &null)) != 0) {
      /* I could not write the descriptor: complain... */
      return flames_midas_error(MAREMMA);
    }

 
    /* build the 3D array to be dumped to disk */
    memcpy(longarray[0][0], myslit->lowbound[0], boundsize*sizeof(int32_t));
    memcpy(longarray[1][0], myslit->highbound[0], boundsize*sizeof(int32_t));
    /* write the 3D array to file */
    if ((status = SCFPUT(boundid, 1, 2*boundsize, 
             (char *) longarray[0][0])) != 0) {
      /* I could not write this big frame to disk: complain... */
      return flames_midas_error(MAREMMA);
    }


    /* write the standard descriptors */
    if ((status = SCDWRC(boundid, "IDENT", 1, "3D frame containing lowbound, \
highbound for a specific slit FF", 1, 63, &unit)) != 0) {
      /* error writing IDENT */
      return flames_midas_error(MAREMMA);
    }

    ibuf[0] = 3;
    if ((status = SCDWRI(boundid, "NAXIS", ibuf, 1, 1, &unit)) != 0) {
      /* error writing NAXIS */
      return flames_midas_error(MAREMMA);
    }
    ibuf[0] = (int) (slitflats->subcols);
    ibuf[1] = (int) (slitflats->lastorder-slitflats->firstorder+1);
    ibuf[2] = 2;

    if ((status = SCDWRI(boundid, "NPIX", ibuf, 1, 3, &unit)) != 0) {
      /* error writing NPIX */
      return flames_midas_error(MAREMMA);
    }
    dbuf[0] = slitflats->substartx;
    dbuf[1] = (double) slitflats->firstorder;
    dbuf[2] = 0;
    if ((status = SCDWRD(boundid, "START", dbuf, 1, 3, &unit)) != 0) {
      /* error writing START */
      return flames_midas_error(MAREMMA);
    }


    dbuf[0] = slitflats->substepx;

    dbuf[1] = 1;

    dbuf[2] = 1;
    if ((status = SCDWRD(boundid, "STEP", dbuf, 1, 3, &unit)) != 0) {
      /* error writing START */
      return flames_midas_error(MAREMMA);
    }

    /* initialise CUNIT an LHCUTS, otherwise MIDAS will complain*/
    memset(cunit, ' ', 16);
    cunit[16] = '\0';
    strncat(cunit, "PIXEL           ", 16);
    strncat(cunit, "FIBRE           ", 16);
    strncat(cunit, "TYPE            ", 16);

    /* write the CUNIT descriptor */

    if ((status = SCDWRC(boundid, "CUNIT", 1, cunit, 1, 64, &null)) != 0) {
      /* I could not write the descriptor: complain... */
        return flames_midas_error(MAREMMA);
    }
    

    lvecbuf1 = longarray[0][0];
    lhcuts[0] = lhcuts[1] = 0;
    minimum = maximum = (float)lvecbuf1[0];
    for (iiorderixindex=1; iiorderixindex<=iiorderixend; iiorderixindex++) {
      fbuf1 = (float) lvecbuf1[iiorderixindex];
      if (fbuf1<minimum) minimum = fbuf1;
      if (fbuf1>maximum) maximum = fbuf1;
    }
    lhcuts[2] = minimum;
    lhcuts[3] = maximum;
    /* write the LHCUTS descriptor */
    if ((status = SCDWRR(boundid, "LHCUTS", lhcuts, 1, 4, &null)) != 0) {
      /* I could not write the descriptor: complain... */
      return flames_midas_error(MAREMMA);
    }


    /* close the boundaries frame */
    if ((status = SCFCLO(boundid)) != 0) {
      /* I could not close the boundaries file: complain... */
      return flames_midas_error(MAREMMA);
    }

    /* close the data frame */
    if ((status = SCFCLO(dataid)) != 0) {
      /* I could not close the data file: complain... */
      return flames_midas_error(MAREMMA);
    }

    /* close the old frame */
    if ((status = SCFCLO(oldfileid)) != 0) {
      /* I could not close the old file: complain... */
      return flames_midas_error(MAREMMA);
    }    
  }
  /* free the 3D array */
  free_l3tensor(longarray, 0, 1, 0, 
        slitflats->lastorder-slitflats->firstorder,
        0, slitflats->subcols-1);

  /* now proceed to the data which are not in the slit member of the
     structure */
  /* concoct the name of the pixel-order frame containing normfactor */
  sprintf(filename,"%s_norm.fits",basename);
  /* create this frame on disk */
  if ((status = SCFCRE(filename, FLAMESDATATYPE, F_O_MODE, F_IMA_TYPE, 
               boundsize, &normid))
      != 0) {
    /* could not create the file */
    return flames_midas_error(MAREMMA);
  }
  /* write the array to file */
  if ((status = SCFPUT(normid, 1, boundsize, 
               (char *) slitflats->normfactor[0])) != 0) {
    /* I could not write this frame to disk: complain... */
    return flames_midas_error(MAREMMA);
  }


  /* initialise lhcuts */
  fdvecbuf1 = slitflats->normfactor[0];
  lhcuts[0] = lhcuts[1] = 0;
  minimum = maximum = (float) fdvecbuf1[0];
  for (iorderixindex=1; iorderixindex<=iorderixend; iorderixindex++) {
    fbuf1 = (float) fdvecbuf1[iorderixindex];
    if (fbuf1<minimum) minimum = fbuf1;
    if (fbuf1>maximum) maximum = fbuf1;
  }
  lhcuts[2] = minimum;
  lhcuts[3] = maximum;
  /* write the standard descriptors */
  if ((status = SCDWRC(normid, "IDENT", 1, "2D frame containing normfactor for a slit FF set", 1, 49, &unit)) != 0) {
    /* error writing IDENT */
    return flames_midas_error(MAREMMA);
  }
  ibuf[0] = 2;
  if ((status = SCDWRI(normid, "NAXIS", ibuf, 1, 1, &unit)) != 0) {
    /* error writing NAXIS */
    return flames_midas_error(MAREMMA);
  }
  ibuf[0] = (int) (slitflats->subcols);
  ibuf[1] = (int) (slitflats->lastorder-slitflats->firstorder+1);
  if ((status = SCDWRI(normid, "NPIX", ibuf, 1, 2, &unit)) != 0) {
    /* error writing NPIX */
    return flames_midas_error(MAREMMA);
  }
  dbuf[0] = slitflats->substartx;
  dbuf[1] = (double) slitflats->firstorder;
  if ((status = SCDWRD(normid, "START", dbuf, 1, 2, &unit)) != 0) {
    /* error writing START */
    return flames_midas_error(MAREMMA);
  }
  dbuf[0] = slitflats->substepx;
  dbuf[1] = 1;
  if ((status = SCDWRD(normid, "STEP", dbuf, 1, 2, &unit)) != 0) {
    /* error writing START */
    return flames_midas_error(MAREMMA);
  }
  /* I do not initialise CUNIT and LHCUTS, should I? ask amodigli...*/
  /* initialise CUNIT */
  memset(cunit, ' ', 16);
  cunit[16] = '\0';
  strncat(cunit, "PIXEL           ", 16);
  strncat(cunit, "FIBRE           ", 16);
  /* write the CUNIT descriptor */
  if ((status = SCDWRC(normid, "CUNIT", 1, cunit, 1, 48, &null)) != 0) {
    /* I could not write the descriptor: complain... */
    return flames_midas_error(MAREMMA);
  }
  /* write the LHCUTS descriptor */
  if ((status = SCDWRR(normid, "LHCUTS", lhcuts, 1, 4, &null)) != 0) {
    /* I could not write the descriptor: complain... */
    return flames_midas_error(MAREMMA);
  }
  /* write the IDENT descriptor */
  if ((status = SCDWRC(normid, "IDENT", 1, "Normalisation data for slit FF", 
               1, CATREC_LEN+1, &null)) != 0) {
    /* I could not write the descriptor: complain... */
    return flames_midas_error(MAREMMA);
  }
  /* write the name of this file to the output catalog */
  if ((status = SCCADD(*catname, filename, blank)) != 0) {
    /* coud not add filename to the catalog: complain */
    return flames_midas_error(MAREMMA);
  }
  /* that's all folks! close the normalisation frame */
  if ((status = SCFCLO(normid)) != 0) {
    /* error closing common frame: complain */
    return flames_midas_error(MAREMMA);
  }
 

  /* concoct the name of the pixel-order frame containing lowbound (first
     layer, highbound (second layer) and goodx (third layer). */
  sprintf(filename,"%s_common.fits",basename);
  /* create this frame on disk */
  if ((status = SCFCRE(filename, D_I4_FORMAT, F_O_MODE, F_IMA_TYPE, 
               3*boundsize, &commid)) != 0) {
    /* could not create the file */
    return flames_midas_error(MAREMMA);
  }
  /* build the 3D array to be dumped to disk */
  /* allocate the memory */
  longarray = l3tensor(0, 2, 0, slitflats->lastorder-slitflats->firstorder, 
               0, slitflats->subcols-1);
  /* fill the 3D array */
  memcpy(longarray[0][0], slitflats->lowbound[0], boundsize*sizeof(int32_t));
  memcpy(longarray[1][0], slitflats->highbound[0], boundsize*sizeof(int32_t));
  lvecbuf1 = longarray[2][0];
  fmvecbuf1 = slitflats->goodx[0];
  for (iorderixindex=0; iorderixindex<=iorderixend; iorderixindex++) {
    lvecbuf1[iorderixindex] = (int32_t) fmvecbuf1[iorderixindex];
  }
  /* write the 3D array to file */
  if ((status = SCFPUT(commid, 1, 3*boundsize, 
               (char *) longarray[0][0])) != 0) {
    /* I could not write this big frame to disk: complain... */
    return flames_midas_error(MAREMMA);
  }
  /* initialise lhcuts */
  lvecbuf1 = longarray[0][0];
  lhcuts[0] = lhcuts[1] = 0;
  minimum = maximum = (float) lvecbuf1[0];
  for (iiorderixindex=1; iiorderixindex<=iiorderixend2; iiorderixindex++) {
    fbuf1 = (float) lvecbuf1[iiorderixindex];
    if (fbuf1<minimum) minimum = fbuf1;
    if (fbuf1>maximum) maximum = fbuf1;
  }
  lhcuts[2] = minimum;
  lhcuts[3] = maximum;
  /* free the 3D array */
  free_l3tensor(longarray, 0, 2, 0, 
        slitflats->lastorder-slitflats->firstorder,
        0, slitflats->subcols-1);
  /* write the standard descriptors */
  if ((status = SCDWRC(commid, "IDENT", 1, "3D frame containing lowbound, highbound and goodx for a slit FF set", 1, 68, &unit)) != 0) {
    /* error writing IDENT */
    return flames_midas_error(MAREMMA);
  }
  ibuf[0] = 3;
  if ((status = SCDWRI(commid, "NAXIS", ibuf, 1, 1, &unit)) != 0) {
    /* error writing NAXIS */
    return flames_midas_error(MAREMMA);
  }
  ibuf[0] = (int) (slitflats->subcols);
  ibuf[1] = (int) (slitflats->lastorder-slitflats->firstorder+1);
  ibuf[2] = 3;
  if ((status = SCDWRI(commid, "NPIX", ibuf, 1, 3, &unit)) != 0) {
    /* error writing NPIX */
    return flames_midas_error(MAREMMA);
  }
  dbuf[0] = slitflats->substartx;
  dbuf[1] = (double) slitflats->firstorder;
  dbuf[2] = 0;
  if ((status = SCDWRD(commid, "START", dbuf, 1, 3, &unit)) != 0) {
    /* error writing START */
    return flames_midas_error(MAREMMA);
  }
  dbuf[0] = slitflats->substepx;
  dbuf[1] = 1;
  dbuf[2] = 1;
  if ((status = SCDWRD(commid, "STEP", dbuf, 1, 3, &unit)) != 0) {
    /* error writing START */
    return flames_midas_error(MAREMMA);
  }
  /* I do not initialise CUNIT an LHCUTS, should I? ask amodigli...*/
  /* initialise CUNIT */
  memset(cunit, ' ', 16);
  cunit[16] = '\0';
  strncat(cunit, "PIXEL           ", 16);
  strncat(cunit, "FIBRE           ", 16);
  strncat(cunit, "TYPE            ", 16);
  /* write the CUNIT descriptor */
  if ((status = SCDWRC(commid, "CUNIT", 1, cunit, 1, 64, &null)) != 0) {
    /* I could not write the descriptor: complain... */
    return flames_midas_error(MAREMMA);
  }
  /* write the LHCUTS descriptor */
  if ((status = SCDWRR(commid, "LHCUTS", lhcuts, 1, 4, &null)) != 0) {
    /* I could not write the descriptor: complain... */
    return flames_midas_error(MAREMMA);
  }
  /* write the other scalars in the slitflats structure to descriptors 
     in the common frame */
  ibuf[0] = (int) slitflats->nflats;
  if ((status = SCDWRI(commid, "NFLATS", &ibuf[0], 1, 1, &unit)) 
      != 0) {
    /* error writing NFLATS */
    return flames_midas_error(MAREMMA);
  }
  ibuf[0] = (int) slitflats->subrows;
  if ((status = SCDWRI(commid, "ROWS", &ibuf[0], 1, 1, &unit)) 
      != 0) {
    /* error writing ROWS */
    return flames_midas_error(MAREMMA);
  }
  ibuf[0] = (int) slitflats->subcols;
  if ((status = SCDWRI(commid, "COLS", &ibuf[0], 1, 1, &unit)) 
      != 0) {
    /* error writing COLS */
    return flames_midas_error(MAREMMA);
  }
  if ((status = SCDWRD(commid, "STARTX", &slitflats->substartx, 1, 1, &unit)) 
      != 0) {
    /* error writing STARTX */
    return flames_midas_error(MAREMMA);
  }
  if ((status = SCDWRD(commid, "STARTY", &slitflats->substarty, 1, 1, &unit)) 
      != 0) {
    /* error writing STARTY */
    return flames_midas_error(MAREMMA);
  }
  if ((status = SCDWRD(commid, "STEPX", &slitflats->substepx, 1, 1, &unit)) 
      != 0) {
    /* error writing STEPX */
    return flames_midas_error(MAREMMA);
  }
  if ((status = SCDWRD(commid, "STEPY", &slitflats->substepy, 1, 1, &unit)) 
      != 0) {
    /* error writing STEPY */
    return flames_midas_error(MAREMMA);
  }
  if ((status = SCDWRC(commid, "CHIPCHOICE", 1, &slitflats->chipchoice, 1, 1, 
               &unit)) != 0) {
    /* error writing chipchoice */
    return flames_midas_error(MAREMMA);
  }
  if ((status = SCDWRD(commid, "RON", &slitflats->ron, 1, 1, &unit)) != 0) {
    /* error writing RON */
    return flames_midas_error(MAREMMA);
  }
  if ((status = SCDWRD(commid, "GAIN", &slitflats->gain, 1, 1, &unit)) != 0) {
    /* error writing GAIN */
    return flames_midas_error(MAREMMA);
  }
  ibuf[0] = (int)slitflats->firstorder;
  if ((status = SCDWRI(commid, "ORDERLIM", ibuf, 1, 1, &unit)) != 0) {
    /* error writing FIRSTORDER */
    return flames_midas_error(MAREMMA);
  }
  ibuf[0] = (int)slitflats->lastorder;
  if ((status = SCDWRI(commid, "ORDERLIM", ibuf, 2, 1, &unit)) != 0) {
    /* error writing LASTORDER */
    return flames_midas_error(MAREMMA);
  }
  /* write the TAB_IN_OUT_OSHIFT descriptor */
  if ((status = SCDWRI(commid, "TAB_IN_OUT_OSHIFT", &slitflats->tab_io_oshift,
               1, 1, &unit)) != 0) {
    /* error writing TAB_IN_OUT_OSHIFT */
    return flames_midas_error(MAREMMA);
  }
  /* write the IDENT descriptor */
  if ((status = SCDWRC(commid, "IDENT", 1, "Common data for slit FF", 1, 
               CATREC_LEN+1, &null)) != 0) {
    /* I could not write the descriptor: complain... */
    return flames_midas_error(MAREMMA);
  }
  /* write the name of this file to the output catalog */
  if ((status = SCCADD(*catname, filename, blank)) != 0) {
    /* coud not add filename to the catalog: complain */
    return flames_midas_error(MAREMMA);
  }
  /* that's all folks! close the common frame */
  if ((status = SCFCLO(commid)) != 0) {
    /* error closing common frame: complain */
    return flames_midas_error(MAREMMA);
  }

  return(NOERR);

}
