/*===========================================================================
  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
===========================================================================*/

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

/* C functions include files */ 
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* MIDAS include files */
#include <flames_stripfitsext.h>
#include <flames_midas_def.h>
/* FLAMES-UVES include files */ 
#include <flames_merge.h>
#include <flames_uves.h>
#include <uves_msg.h>
#include <flames_newmatrix.h>

int flames_merge(const char *INTER_IMA,
                 const char *INTER_SIGMA,
                 const char *INTER_MASK,
                 const char *MBASENAME,
                 const double *MASKTHRES,
                 const double delta1,
                 const double delta2)
{ 
    int i=0;
    int j=0;

    int nval=0;
    char infile[81];
    char insigma[81];
    char inmask[81];
    char basename[81];
    char mbasename[81];
    int infileid=0;
    int insigmaid=0;
    int inmaskid=0;
    int naxis=0;
    int unit=0;
    int null=0;
    double start[2]={0,0};
    double step[2]={0,0};
    int npix[2]={0,0};
    double start2[2]={0,0};
    double step2[2]={0,0};
    int npix2[2]={0,0};
    double *wstart=0;
    int *nptot=0;
    double *wstart2=0;
    int *nptot2=0;
    frame_data **spectrum=0;
    frame_data **sigma=0;
    float **mask=0;
    frame_data *vecspectrum=0;
    frame_data *vecsigma=0;
    float *vecmask=0;
    double mstart=0;
    double mstep=0;
    int ijindex=0;
    int shiftedj=0;
    int mnpix=0;
    double maskthres=0;
    frame_data weight=0;
    frame_data *mspectrum=0;
    frame_data *msigma=0;
    frame_mask *mmask=0;
    char mspecname[85];
    char msigmaname[85];
    char mmaskname[85];
    int mspecid=0;
    int msigmaid=0;
    int mmaskid=0;
    int mnaxis=1;
    frame_data minimum=0;
    frame_data maximum=0;
    char ident[73];
    char cunit[2][16];
    float cuts[4]={0,0,0,0};
    memset(ident, 0, 73);
    memset(cunit[0], 0, 32);
    strncpy(cunit[0], "Relative flux   ", 16);
    strncpy(cunit[1], "Wavelength      ", 16);



    SCSPRO("flames_merge"); /* Get into MIDAS Env. */

    /*
  // read the file names from the MIDAS environment 
  uves_msg_warning("ok1 inter_ima=%s",INTER_IMA);
  if (SCKGETC(INTER_IMA, 1, 60, &nval, infile) != 0) {
    SCTPUT("Error reading the rebinned spectrum name");
    return flames_midas_fail();
  }

  if (SCKGETC(INTER_SIGMA, 1, 60, &nval, insigma) != 0) {
    SCTPUT("Error reading the rebinned variances name");
    return flames_midas_fail();
  }

  if (SCKGETC(INTER_MASK, 1, 60, &nval, inmask) != 0) {
    SCTPUT("Error reading the rebinned mask name");
    return flames_midas_fail();
  }

  // read output base name 
  if (SCKGETC(MBASENAME,1,60,&nval,basename)!=0) {
    // problems reading MBASENAME 
    SCTPUT("Error reading the base name for output spectra");
    return flames_midas_fail();
  }

  // initialise MASKTHRES from keyword 
  if (SCKRDD(MASKTHRES, 1, 1, &nval, &maskthres, &unit, &null) != 0) {
    // problems reading MASKTHRES 
    SCTPUT("Error reading the MASKTHRES keyword");
    return flames_midas_fail();
  }
     */


    maskthres=*MASKTHRES;
    strcpy(infile,INTER_IMA);
    strcpy(insigma,INTER_SIGMA);
    strcpy(inmask,INTER_MASK);
    strcpy(basename,MBASENAME);




    if (stripfitsext(basename, mbasename) != NOERR) {
        SCTPUT("Error stripping basename extension");
        return flames_midas_fail();
    }


    /* open the spectrum to be merged */
    if (SCFOPN(infile, FLAMESDATATYPE, 0, F_IMA_TYPE, &infileid) != 0) {
        SCTPUT("Error opening the rebinned spectrum");
        return flames_midas_fail();
    }


    /* read the main descriptor and make sure they are what they are
     expected to be */
    if (SCDRDI(infileid, "NAXIS", 1, 1, &nval, &naxis, &unit, &null)!=0) {
        SCTPUT("Error getting NAXIS from spectrum");
        return flames_midas_fail();
    }

    if (nval<1) {
        SCTPUT("Error getting NAXIS from spectrum");
        return flames_midas_fail();
    }

    if (naxis != 2) {
        SCTPUT("Error: wrong spectrum dimentions");
        return flames_midas_fail();
    }


    if (SCDRDD(infileid, "START",1, 2, &nval, start, &unit, &null)!=0) {
        SCTPUT("Error getting START from spectrum");
        return flames_midas_fail();
    }
    if (nval<2) {
        SCTPUT("Error getting START from spectrum");
        return flames_midas_fail();
    }


    if (SCDRDD(infileid, "STEP", 1, 2, &nval, step, &unit, &null)!=0) {
        SCTPUT("Error getting STEP from spectrum");
        return flames_midas_fail();
    }
    if (nval<2) {
        SCTPUT("Error getting STEP from spectrum");
        return flames_midas_fail();
    }

    if (SCDRDI(infileid, "NPIX", 1, 2, &nval, npix, &unit, &null)!=0) {
        SCTPUT("Error getting STEP from spectrum");
        return flames_midas_fail();
    }
    if (nval<2) {
        SCTPUT("Error getting NPIX from spectrum");
        return flames_midas_fail();
    }

    /* now we know how large we need wstart and nptot to be, allocate them */
    wstart = dvector(0, npix[1]-1);
    nptot = ivector(0,npix[1]-1);
    wstart2 = dvector(0, npix[1]-1);
    nptot2 = ivector(0,npix[1]-1);
    spectrum = fdmatrix(0,npix[1]-1, 0, npix[0]-1);
    sigma = fdmatrix(0,npix[1]-1, 0, npix[0]-1);
    mask = matrix(0,npix[1]-1, 0, npix[0]-1);
    vecspectrum = spectrum[0];
    vecsigma = sigma[0];
    vecmask = mask[0];


    if (SCDRDD(infileid, "WSTART", 1, npix[1], &nval, wstart, &unit, &null)!=0) {
        SCTPUT("Error reading WSTART from spectrum");
        return flames_midas_fail();
    }
    if (nval<npix[1]) {
        SCTPUT("Error reading WSTART: less values than expected");
        return flames_midas_fail();
    }

    if (SCDRDI(infileid, "NPTOT", 1, npix[1], &nval, nptot, &unit, &null)!=0) {
        SCTPUT("Error reading NPTOT from spectrum");
        return flames_midas_fail();
    }
    if (nval<npix[1]) {
        SCTPUT("Error reading NPTOT: less values than expected");
        return flames_midas_fail();
    }

    if (SCFGET(infileid, 1, npix[0]*npix[1], &nval, (char *) spectrum[0])!=0) {
        SCTPUT("Error reading spectrum");
        return flames_midas_fail();
    }
    if (nval<(npix[0]*npix[1])) {
        SCTPUT("Error reading spectrum: less values than expected");
        return flames_midas_fail();
    }


    /* now do the same with the variance file */
    if (SCFOPN(insigma, FLAMESDATATYPE, 0, F_IMA_TYPE, &insigmaid) != 0) {
        SCTPUT("Error opening the rebinned variances");
        return flames_midas_fail();
    }

    /* read the main descriptor and make sure they are what they are
     expected to be */
    if (SCDRDI(insigmaid, "NAXIS", 1, 1, &nval, &naxis, &unit, &null)!=0) {
        SCTPUT("Error getting NAXIS from variances file");
        return flames_midas_fail();
    }
    if (nval<1) {
        SCTPUT("Error getting NAXIS from spectrum");
        return flames_midas_fail();
    }
    if (naxis != 2) {
        SCTPUT("Error: wrong variances dimentions");
        return flames_midas_fail();
    }

    if (SCDRDD(insigmaid, "START", 1, 2, &nval, start2, &unit, &null)!=0) {
        SCTPUT("Error getting START from variances");
        return flames_midas_fail();
    }
    if (nval<2) {
        SCTPUT("Error getting START from spectrum");
        return flames_midas_fail();
    }
    if ((start2[0] != start[0]) || (start2[1] != start[1])) {
        SCTPUT("Error: mismatch between spectrum and variance START");
        return flames_midas_fail();
    }


    if (SCDRDD(insigmaid, "STEP", 1, 2, &nval, step2, &unit, &null)!=0) {
        SCTPUT("Error getting STEP from variances");
        return flames_midas_fail();
    }
    if (nval<2) {
        SCTPUT("Error getting START from spectrum");
        return flames_midas_fail();
    }
    if ((step2[0] != step[0]) || (step2[1] != step[1])) {
        SCTPUT("Error: mismatch between spectrum and variance STEP");
        return flames_midas_fail();
    }


    if (SCDRDI(insigmaid, "NPIX", 1, 2, &nval, npix2, &unit, &null)!=0) {
        SCTPUT("Error getting NPIX from variances");
        return flames_midas_fail();
    }
    if (nval<2) {
        SCTPUT("Error getting NPIX from variances");
        return flames_midas_fail();
    }
    if ((npix2[0] != npix[0]) || (npix2[1] != npix[1])) {
        SCTPUT("Error: mismatch between spectrum and variance NPIX");
        return flames_midas_fail();
    }


    if (SCDRDD(insigmaid, "WSTART", 1, npix[1], &nval, wstart2, &unit,
                    &null)!=0) {
        SCTPUT("Error reading WSTART from variances");
        return flames_midas_fail();
    }
    if (nval<npix[1]) {
        SCTPUT("Error reading WSTART: less values than expected");
        return flames_midas_fail();
    }
    for (i=0; i<=(npix[1]-1); i++) {
        if (wstart2[i] != wstart[i]) {
            SCTPUT("Error: mismatch between spectrum and variance WSTART");
            return flames_midas_fail();
        }
    }


    if (SCDRDI(insigmaid, "NPTOT", 1, npix[1], &nval, nptot2, &unit, &null)!=0) {
        SCTPUT("Error reading NPTOT from spectrum");
        return flames_midas_fail();
    }
    if (nval<npix[1]) {
        SCTPUT("Error reading NPTOT: less values than expected");
        return flames_midas_fail();
    }
    for (i=0; i<=(npix[1]-1); i++) {
        if (nptot2[i] != nptot[i]) {
            SCTPUT("Error: mismatch between spectrum and variance NPTOT");
            return flames_midas_fail();
        }
    }

    if (SCFGET(insigmaid, 1, npix[0]*npix[1], &nval, (char *) sigma[0])!=0) {
        SCTPUT("Error reading variances");
        return flames_midas_fail();
    }
    if (nval<(npix[0]*npix[1])) {
        SCTPUT("Error reading variances: less values than expected");
        return flames_midas_fail();
    }

    /* We can close the insigma frame */
    if (SCFCLO(insigmaid)!=0) {
        SCTPUT("Error closing variance frame");
        return flames_midas_fail();
    }



    /* now do the same with the mask file */
    /* the mask file was rebinned from an I1 data type, but MIDAS promotes
     it to an R4 data type */
    if (SCFOPN(inmask, D_R4_FORMAT, 0, F_IMA_TYPE, &inmaskid) != 0) {
        SCTPUT("Error opening the rebinned mask");
        return flames_midas_fail();
    }

    /* read the main descriptor and make sure they are what they are
     expected to be */
    if (SCDRDI(inmaskid, "NAXIS", 1, 1, &nval, &naxis, &unit, &null)!=0) {
        SCTPUT("Error getting NAXIS from mask file");
        return flames_midas_fail();
    }
    if (nval<1) {
        SCTPUT("Error getting NAXIS from spectrum");
        return flames_midas_fail();
    }
    if (naxis != 2) {
        SCTPUT("Error: wrong mask dimentions");
        return flames_midas_fail();
    }


    if (SCDRDD(inmaskid, "START", 1, 2, &nval, start2, &unit, &null)!=0) {
        SCTPUT("Error getting START from mask");
        return flames_midas_fail();
    }
    if (nval<2) {
        SCTPUT("Error getting START from mask");
        return flames_midas_fail();
    }
    if ((start2[0] != start[0]) || (start2[1] != start[1])) {
        SCTPUT("Error: mismatch between spectrum and mask START");
        return flames_midas_fail();
    }

    if (SCDRDD(inmaskid, "STEP", 1, 2, &nval, step2, &unit, &null)!=0) {
        SCTPUT("Error getting STEP from mask");
        return flames_midas_fail();
    }
    if (nval<2) {
        SCTPUT("Error getting STEP from mask");
        return flames_midas_fail();
    }
    if ((step2[0] != step[0]) || (step2[1] != step[1])) {
        SCTPUT("Error: mismatch between spectrum and mask STEP");
        return flames_midas_fail();
    }

    if (SCDRDI(inmaskid, "NPIX", 1, 2, &nval, npix2, &unit, &null)!=0) {
        SCTPUT("Error getting STEP from mask");
        return flames_midas_fail();
    }
    if (nval<2) {
        SCTPUT("Error getting NPIX from mask");
        return flames_midas_fail();
    }
    if ((npix2[0] != npix[0]) || (npix2[1] != npix[1])) {
        SCTPUT("Error: mismatch between spectrum and mask NPIX");
        return flames_midas_fail();
    }


    if (SCDRDD(inmaskid, "WSTART", 1, npix[1], &nval, wstart2, &unit,
                    &null)!=0) {
        SCTPUT("Error reading WSTART from mask");
        return flames_midas_fail();
    }
    if (nval<npix[1]) {
        SCTPUT("Error reading WSTART: less values than expected");
        return flames_midas_fail();
    }
    for (i=0; i<=(npix[1]-1); i++) {
        if (wstart2[i] != wstart[i]) {
            SCTPUT("Error: mismatch between spectrum and mask WSTART");
            return flames_midas_fail();
        }
    }


    if (SCDRDI(inmaskid, "NPTOT", 1, npix[1], &nval, nptot2, &unit, &null)!=0) {
        SCTPUT("Error reading NPTOT from mask");
        return flames_midas_fail();
    }
    if (nval<npix[1]) {
        SCTPUT("Error reading NPTOT: less values than expected");
        return flames_midas_fail();
    }
    for (i=0; i<=(npix[1]-1); i++) {
        if (nptot2[i] != nptot[i]) {
            SCTPUT("Error: mismatch between spectrum and mask NPTOT");
            return flames_midas_fail();
        }
    }

    if (SCFGET(inmaskid, 1, npix[0]*npix[1], &nval, (char *) mask[0])!=0) {
        SCTPUT("Error reading mask");
        return flames_midas_fail();
    }
    if (nval<(npix[0]*npix[1])) {
        SCTPUT("Error reading mask: less values than expected");
        return flames_midas_fail();
    }

    /* We can close the insigma frame */
    if (SCFCLO(insigmaid)!=0) {
        SCTPUT("Error closing mask frame");
        return flames_midas_fail();
    }



    /* ok, now go ahead and find the merged frame limits */
    mstart = wstart[0];
    mstep = step[0];
    /* In principle, there should be no reason to truncate to nearest integer,
     since it ought to be an exact integer, but just in case */
    mnpix = ((int) floor(((wstart[npix[1]-1]-wstart[0])/step[0])+0.5)) +
                    nptot[npix[1]-1];

    /* now I can allocate the merged vectors */
    mspectrum = fdvector(0,mnpix-1);
    msigma = fdvector(0,mnpix-1);
    mmask = fmvector(0,mnpix-1);
    /* initialise the above vectors */
    for (j=0; j<=(mnpix-1); j++) {
        mspectrum[j] = 0;
        msigma[j] = 0;
        mmask[j] = 0;
    }


    /* begin the actual merging
     npix[1]=No of orders
     nptot[i]=No of pixels per order
     */
    int jdelta1=delta1/step[0];
    int jdelta2=delta2/step[0];

    for (i=0; i<=(npix[1]-1); i++) {
        /* the i-th order begins at joffset-th pixel in the rebinned frame */
        int joffset = ((int) floor(((wstart[i]-wstart[0])/step[0])+0.5));
        for (j=jdelta1; j<=(nptot[i]-1)-jdelta2; j++) {
            ijindex = (i*npix[0])+j;
            /* is this a good pixel? */
            if (vecmask[ijindex] >= maskthres) {
                shiftedj = j+joffset;
                /* yes, hence use it */
                weight = 1/vecsigma[ijindex];
                mspectrum[shiftedj] += weight*vecspectrum[ijindex];
                /* at the moment, use msigma to hold the normalisation factors to
       be used later */
                msigma[shiftedj] += weight;
                /* we have at least this value at this wavelength, hence this is a
       good pixel */
                mmask[shiftedj] = 1;
            }
        }
    }


    /* to wrap up, normalise the merged spectrum and compute the final
     merged variance */
    for (j=0; j<=(mnpix-1); j++) {
        /* is this a good pixel? */
        if (mmask[j] == 1) {
            /* yes, hence normalise it */
            mspectrum[j] /= msigma[j];
            /* compute the variance */
            msigma[j] = 1/msigma[j];
        }
    }


    /* that's all, folks! Time to write to disk, clean up and exit */
    sprintf(mspecname, "%s.fits", mbasename);
    sprintf(msigmaname, "%s_sigma.fits", mbasename);
    sprintf(mmaskname, "%s_mask.fits", mbasename);
    mnaxis = 1;
    if (SCFCRE(mspecname, FLAMESDATATYPE, F_O_MODE, F_IMA_TYPE, mnpix,
                    &mspecid) != 0) {
        /* could not create the merged spectrum file */
        SCTPUT("Error creating merged spectrum file");
        return flames_midas_fail();
    }
    /* write the spectrum itself */
    if (SCFPUT(mspecid, 1, mnpix, (char *) mspectrum) != 0) {
        SCTPUT("Error writing merged spectrum");
    }
    /* write standard descriptors of file */
    if (SCDWRC(mspecid, "IDENT", 1, ident, 1, 72, &unit)) {
        SCFCLO(mspecid);
        return flames_midas_fail();
    }
    if (SCDWRI(mspecid, "NAXIS", &mnaxis, 1, 1, &unit)) {
        SCFCLO(mspecid);
        return flames_midas_fail();
    }
    if (SCDWRI(mspecid, "NPIX", &mnpix, 1, 1, &unit)) {
        SCFCLO(mspecid);
        return flames_midas_fail();
    }
    if (SCDWRD(mspecid, "START", &mstart, 1, 1, &unit)) {
        /* error writing descriptor */
        SCFCLO(mspecid);
        return flames_midas_fail();
    }
    if (SCDWRD(mspecid, "STEP", &mstep, 1, 1, &unit)) {
        SCFCLO(mspecid);
        return flames_midas_fail();
    }
    if (SCDWRC(mspecid, "CUNIT", 1, cunit[0], 1, 32, &unit)) {
        SCFCLO(mspecid);
        return flames_midas_fail();
    }

    minimum = mspectrum[0];
    maximum = mspectrum[0];
    for (j=0; j<=(mnpix-1); j++) {
        maximum = mspectrum[j] > maximum ? mspectrum[j] : maximum;
        minimum = mspectrum[j] < minimum ? mspectrum[j] : minimum;
    }
    cuts[2] = (float) minimum;
    cuts[3] = (float) maximum;
    if (SCDWRR(mspecid, "LHCUTS", cuts, 1, 4, &unit)) {
        SCFCLO(mspecid);
        return flames_midas_fail();
    }

    /* write the sigma file name as a descriptor of the data file */
    if (SCDWRC(mspecid, "SIGMAFRAME", 1, msigmaname, 1, 80, &unit)) {
        /* error writing descriptor */
        SCFCLO(mspecid);
        return flames_midas_fail();
    }

    /* write the extracted columns file name as a descriptor of the data file */
    if (SCDWRC(mspecid, "MASKFRAME", 1, mmaskname, 1, 80, &unit)) {
        /* error writing descriptor */
        SCFCLO(mspecid);
        return flames_midas_fail();
    }

    /* close the spectrum */
    if (SCFCLO(mspecid) != 0) {
        /* error closing frame */
        SCTPUT("Warning: the merged spectrum could not be closed");
    }



    /* write the merged variance */
    if (SCFCRE(msigmaname, FLAMESDATATYPE, F_O_MODE, F_IMA_TYPE, mnpix,
                    &msigmaid) != 0) {
        /* could not create the merged sigma file */
        SCTPUT("Error creating merged sigma file");
        return flames_midas_fail();
    }
    /* write the variance itself */
    if (SCFPUT(msigmaid, 1, mnpix, (char *) msigma) != 0) {
        SCTPUT("Error writing merged variance");
    }
    /* write standard descriptors of file */
    if (SCDWRC(msigmaid, "IDENT", 1, ident, 1, 72, &unit)) {
        SCFCLO(msigmaid);
        return flames_midas_fail();
    }
    if (SCDWRI(msigmaid, "NAXIS", &mnaxis, 1, 1, &unit)) {
        SCFCLO(msigmaid);
        return flames_midas_fail();
    }
    if (SCDWRI(msigmaid, "NPIX", &mnpix, 1, 1, &unit)) {
        SCFCLO(msigmaid);
        return flames_midas_fail();
    }
    if (SCDWRD(msigmaid, "START", &mstart, 1, 1, &unit)) {
        /* error writing descriptor */
        SCFCLO(msigmaid);
        return flames_midas_fail();
    }
    if (SCDWRD(msigmaid, "STEP", &mstep, 1, 1, &unit)) {
        SCFCLO(msigmaid);
        return flames_midas_fail();
    }
    if (SCDWRC(msigmaid, "CUNIT", 1, cunit[0], 1, 32, &unit)) {
        SCFCLO(msigmaid);
        return flames_midas_fail();
    }
    minimum = msigma[0];
    maximum = msigma[0];
    for (j=0; j<=(mnpix-1); j++) {
        maximum = msigma[j] > maximum ? msigma[j] : maximum;
        minimum = msigma[j] < minimum ? msigma[j] : minimum;
    }
    cuts[2] = (float) minimum;
    cuts[3] = (float) maximum;
    if (SCDWRR(msigmaid, "LHCUTS", cuts, 1, 4, &unit)) {
        SCFCLO(msigmaid);
        return flames_midas_fail();
    }


    /* write the sigma file name as a descriptor of the data file */
    if (SCDWRC(msigmaid, "SPECTRUMFRAME", 1, mspecname, 1, 80, &unit)) {
        /* error writing descriptor */
        SCFCLO(msigmaid);
        return flames_midas_fail();
    }

    /* close the spectrum */
    if (SCFCLO(msigmaid) != 0) {
        /* error closing frame */
        SCTPUT("Warning: the merged sigma could not be closed");
    }


    /* write the merged mask */
    if (SCFCRE(mmaskname, FLAMESMASKTYPE, F_O_MODE, F_IMA_TYPE, mnpix,
                    &mmaskid) != 0) {
        /* could not create the merged mask file */
        SCTPUT("Error creating merged mask file");
        return flames_midas_fail();
    }
    /* write the variance itself */
    if (SCFPUT(mmaskid, 1, mnpix, (char *) mmask) != 0) {
        SCTPUT("Error writing merged mask");
    }
    /* write standard descriptors of file */
    if (SCDWRC(mmaskid, "IDENT", 1, ident, 1, 72, &unit)) {
        SCFCLO(mmaskid);
        return flames_midas_fail();
    }
    if (SCDWRI(mmaskid, "NAXIS", &mnaxis, 1, 1, &unit)) {
        SCFCLO(mmaskid);
        return flames_midas_fail();
    }
    if (SCDWRI(mmaskid, "NPIX", &mnpix, 1, 1, &unit)) {
        SCFCLO(mmaskid);
        return flames_midas_fail();
    }
    if (SCDWRD(mmaskid, "START", &mstart, 1, 1, &unit)) {
        /* error writing descriptor */
        SCFCLO(mmaskid);
        return flames_midas_fail();
    }
    if (SCDWRD(mmaskid, "STEP", &mstep, 1, 1, &unit)) {
        SCFCLO(mmaskid);
        return flames_midas_fail();
    }
    if (SCDWRC(mmaskid, "CUNIT", 1, cunit[0], 1, 32, &unit)) {
        SCFCLO(mmaskid);
        return flames_midas_fail();
    }
    cuts[2] = 0;
    cuts[3] = 1;
    if (SCDWRR(mmaskid, "LHCUTS", cuts, 1, 4, &unit)) {
        SCFCLO(mmaskid);
        return flames_midas_fail();
    }


    /* write the spetrum file name as a descriptor of the data file */
    if (SCDWRC(mmaskid, "SPECTRUMFRAME", 1, mspecname, 1, 80, &unit)) {
        /* error writing descriptor */
        SCFCLO(mmaskid);
        return flames_midas_fail();
    }

    /* close the spectrum */
    if (SCFCLO(mmaskid) != 0) {
        /* error closing frame */
        SCTPUT("Warning: the merged mask could not be closed");
    }


    /* everything written, clean up and get out */
    free_dvector(wstart, 0, npix[1]-1);
    free_ivector(nptot, 0,npix[1]-1);
    free_dvector(wstart2, 0,npix[1]-1);
    free_ivector(nptot2, 0,npix[1]-1);
    free_fdmatrix(spectrum, 0,npix[1]-1, 0, npix[0]-1);
    free_fdmatrix(sigma, 0,npix[1]-1, 0, npix[0]-1);
    free_matrix(mask, 0,npix[1]-1, 0, npix[0]-1);
    free_fdvector(mspectrum, 0,mnpix-1);
    free_fdvector(msigma, 0,mnpix-1);
    free_fmvector(mmask, 0,mnpix-1);

    return SCSEPI();

}
