/*===========================================================================
  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  : readallff.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_readallff.h>
#include <flames_uves.h>
#include <flames_dfs.h>
#include <flames_checksize3.h>
#include <flames_newmatrix.h>
#include <flames_allocallflats.h>
#include <uves_msg.h>
#include <uves_dump.h>


flames_err 
readallff(const cpl_frameset *catname, allflats *myflats)
{
  int32_t iframe=0;
  int32_t ifibre=0;
  int32_t ncommon=0;
  int32_t nnormal=0;
  int32_t nnsigma=0;
  char filename[CATREC_LEN+1];
  char identifier[CATREC_LEN+1];
  int status=0;
  int entrynum=0;
  char normalname[CATREC_LEN+1];
  char nsigmaname[CATREC_LEN+1];
  char commoname[CATREC_LEN+1];
  int commonid=0;
  int normid=0;
  int nsigid=0;
  int frameid=0;
  int sigmaid=0;
  int badid=0;
  int ibuf=0;
  int actvals=0;
  int actsize=0;
  int unit=0;
  int null=0;
  int *fibres=0;
  char* fixed_name=NULL;
  int32_t ****longarray=0;
  //Fixme: added to fix a problem with descriptors
  //int comid=0;
  double start[2]={1.0,1.0};

  frame_mask *fmvecbuf1=0;
  int32_t *lvecbuf1=0;
  int32_t *lvecbuf2=0;
  int32_t *lvecbuf3=0;
  int32_t *lvecbuf4=0;
  int32_t *lvecbuf5=0;
  int32_t maxiorderifibreixindex=0;
  int32_t iorderifibreixindex=0;
 
  memset(filename, '\0', CATREC_LEN+1);
  memset(identifier, '\0', CATREC_LEN+1);
  memset(normalname, '\0', CATREC_LEN+1);
  memset(nsigmaname, '\0', CATREC_LEN+1);
  memset(commoname, '\0', CATREC_LEN+1);

  myflats->nflats = 0;
  ncommon = 0;
  nnormal = 0;
  nnsigma = 0;
  /* first open the catalog, count the fibre FF frames, the normalisation
     frame(s) and the common 4D frame present */
  entrynum = 0;

  do {

    if ((status = SCCGET(catname, 1, filename, identifier, &entrynum)) != 0) {
      /* error getting catalog entry */
      return(MAREMMA);
    }
    uves_msg_debug("file=%s with identifier=%s",filename,identifier);
    /* did I get a valid catalog entry? */
    if (filename[0] != ' ') {
      /* is this a int32_t slit FF frame? */
      uves_msg_debug(">%s<\n","Cleaned fibre FF");

      if(strncmp(identifier, "Cleaned fibre FF",16) == 0) {
	//if(strncmp(identifier, "FIB_FF_DT",9) == 0) {
	myflats->nflats++;
      }

      /* is this a normalisation frame? */
      if(strncmp(identifier, "Normalisation data for fibre FF",31) == 0) {
	//if(strncmp(identifier, "FIB_FF_NOR",10) == 0) {
	nnormal++;
	strcpy(normalname, filename);
      }

      /* is this a normalisation frame? */
      if(strncmp(identifier, "Normalisation sigmas for fibre FF",33) == 0) {
	//if(strncmp(identifier, "FIB_FF_NSG",10) == 0) {
	nnsigma++;
	strcpy(nsigmaname, filename);
      }

      /* is this a common frame? */
      if(strncmp(identifier, "Common data for fibre FF",24) == 0) {
	//if(strncmp(identifier, "FIB_FF_COM",10) == 0) {
        //FixMe added to fix a problem of missing descriptors in com fib frame
        //status = SCFOPN(filename, FLAMESDATATYPE, 0, F_IMA_TYPE, &comid);
        //SCDWRC(comid, "SHIFTABLE",  1, "y", 1, 1, &unit);
        //SCDWRC(comid, "NORMALISED", 1, "y", 1, 1, &unit);
        //SCFCLO(comid);
	ncommon++;
	strcpy(commoname, filename);
      }

    }

  } while (filename[0] != ' ');


  /* did I get at least 1 FF frame name? */
  if (myflats->nflats < 1) {
    /* I need at least 1 FF frame! */
    return(MAREMMA);
  }


  /* did I get exactly 1 normalisation frame and common frame name? */
  if (nnormal != 1) {
    /* I need exactly 1 normalisation frame name! */
    return(MAREMMA);
  }


  if (nnsigma != 1) {
    /* I need exactly 1 normalisation sigmas frame name! */
    return(MAREMMA);
  }

  if (ncommon != 1) {
    /* I need exactly 1 common frame name! */
    return(MAREMMA);
  }

  /* open the common frame to get the descriptors */
  if ((status = SCFOPN(commoname, D_I4_FORMAT, 0, F_IMA_TYPE, 
               &commonid)) != 0) {
    /* could not open the frame */
    return(MAREMMA);
  }
  /* read the relevant information from the frame */
  if ((status = SCDRDI(commonid, "NFLATS", 1, 1, &actvals, &ibuf, 
               &unit, &null)) != 0) {
    /* problems reading NFLATS: complain... */
    return(MAREMMA);
  }
  if (myflats->nflats != ibuf) {
    /* mismatch between catalog and descriptors, abort */
    return(MAREMMA);
  }

  if ((status = SCDRDI(commonid, "ROWS", 1, 1, &actvals, &ibuf, 
               &unit, &null)) != 0) {
    /* problems reading ROWS: complain... */
    return(MAREMMA);
  }

  myflats->subrows = (int32_t) ibuf;
  if ((status = SCDRDI(commonid, "COLS", 1, 1, &actvals, &ibuf, 
               &unit, &null)) != 0) {
    /* problems reading COLS: complain... */
    return(MAREMMA);
  }

  myflats->subcols = (int32_t) ibuf;
  if ((status = SCDRDD(commonid, "STARTX", 1, 1, &actvals, 
               &myflats->substartx, &unit, &null)) != 0) {
    /* problems reading STEPX: complain... */
    return(MAREMMA);
  }
  if ((status = SCDRDD(commonid, "STARTY", 1, 1, &actvals, 
               &myflats->substarty, &unit, &null)) != 0) {
    /* problems reading STEPY: complain... */
    return(MAREMMA);
  }
  if ((status = SCDRDD(commonid, "STEPX", 1, 1, &actvals, 
               &myflats->substepx, &unit, &null)) != 0) {
    /* problems reading STEPX: complain... */
    return(MAREMMA);
  }
  if ((status = SCDRDD(commonid, "STEPY", 1, 1, &actvals, 
               &myflats->substepy, &unit, &null)) != 0) {
    /* problems reading STEPY: complain... */
    return(MAREMMA);
  }

  if ((status = SCDRDC(commonid, "CHIPCHOICE", 1, 1, 1, &actvals, 
               &myflats->chipchoice, &unit, &null)) != 0) {
    /* problems reading CHIPCHOICE: complain... */
    return(MAREMMA);
  }
  if ((status = SCDRDD(commonid, "RON", 1, 1, &actvals, 
               &myflats->ron, &unit, &null)) != 0) {
    /* problems reading RON: complain... */
    return(MAREMMA);
  }
  if ((status = SCDRDD(commonid, "GAIN", 1, 1, &actvals, 
               &myflats->gain, &unit, &null)) != 0) {
    /* problems reading GAIN: complain... */
    return(MAREMMA);
  }
  if ((status = SCDRDI(commonid, "ORDERLIM", 1, 1, &actvals, 
               &myflats->firstorder, &unit, &null)) != 0) {
    /* problems reading FIRSTORDER: complain... */
    return(MAREMMA);
  }

  if ((status = SCDRDI(commonid, "ORDERLIM", 2, 1, &actvals, 
               &myflats->lastorder, &unit, &null)) != 0) {
    /* problems reading LASTORDER: complain... */
    return(MAREMMA);
  }
  if ((status = SCDRDI(commonid, "TAB_IN_OUT_OSHIFT", 1, 1, &actvals, 
               &myflats->tab_io_oshift, &unit, &null)) != 0) {
    /* problems reading LASTORDER: complain... */
    return(MAREMMA);
  }
  if ((status = SCDRDI(commonid, "MAXFIBRES", 1, 1, &actvals, &ibuf, 
               &unit, &null)) != 0) {
    /* problems reading COLS: complain... */
    return(MAREMMA);
  }
  myflats->maxfibres = (int32_t) ibuf;
  if ((status = SCDRDD(commonid, "PIXMAX", 1, 1, &actvals, 
               &myflats->pixmax, &unit, &null)) != 0) {
    /* problems reading GAIN: complain... */
    return(MAREMMA);
  }
 

  if ((status = SCDRDD(commonid, "HALFIBREWIDTH", 1, 1, &actvals, 
               &myflats->halfibrewidth, &unit, &null)) != 0) {
    /* problems reading GAIN: complain... */
    return(MAREMMA);
  }
  if ((status = SCDRDD(commonid, "MINFIBREFRAC", 1, 1, &actvals, 
               &myflats->minfibrefrac, &unit, &null)) != 0) {
    /* problems reading GAIN: complain... */
    return(MAREMMA);
  }
  if ((status = SCDRDI(commonid, "NUMFIBRES", 1, 1, &actvals, &ibuf, 
               &unit, &null)) != 0) {
    /* problems reading COLS: complain... */
    return(MAREMMA);
  }
 


 //Fixme: we suppressed the check on SHIFTABLE & NORMALIZED
  myflats->numfibres = (int32_t) ibuf;
  //if ((status = SCDRDC(commonid, "SHIFTABLE", 1, 1, 1, &actvals, 
  //           &myflats->shiftable, &unit, &null)) != 0) {
  //  /* problems reading SHIFTABLE complain... */
  //  return(MAREMMA);
  //}
  myflats->shiftable='y';

  //if ((status = SCDRDC(commonid, "NORMALISED", 1, 1, 1, &actvals, 
  //               &myflats->normalised, &unit, &null)) != 0) {
  //  /* problems reading NORMALISED complain... */
  //  return(MAREMMA);
  //
  //}
  myflats->normalised='y';


  /* allocate dynamic auxiliary vectors */
  fibres = ivector(0,myflats->maxfibres-1);

  /* allocate the arrays in the structure */
  if ((status = allocallflats(myflats)) != NOERR) {
    /* problem allocating internal arrays of myflats */
    return(MAREMMA);
  }

  /* read vectors from descriptors */
  if ((status = SCDRDI(commonid, "FIBREMASK", 1, myflats->maxfibres, 
               &actvals, myflats->fibremask, &unit, &null)) != 0) {
    /* problems reading COLS: complain... */
    return(MAREMMA);
  }

  if ((status = SCDRDI(commonid, "FIBRE2FRAME", 1, myflats->maxfibres, 
               &actvals, myflats->fibre2frame, &unit, &null)) != 0) {
    /* problems reading COLS: complain... */
    return(MAREMMA);
  }

  /* allocate the temporary 4D buffer for the data in the common frame 
     itself */
  longarray = l4tensor(0, 2, 0, myflats->lastorder-myflats->firstorder, 
               0, myflats->maxfibres-1, 0, myflats->subcols-1);

  /* read the common frame into the buffer */
  if ((status = 
       SCFGET(commonid, 1, 
          3*(myflats->lastorder-myflats->firstorder+1)*
          myflats->maxfibres*myflats->subcols, &actsize, 
          (char *)(&longarray[0][0][0][0]))) != 0) {
    /* problems reading common frame: complain */
    return(MAREMMA);
  }
  else if (actsize != 3*(myflats->lastorder-myflats->firstorder+1)*
       myflats->maxfibres*myflats->subcols) {
    /* I read fewer elements than expected: complain... */
    return(MAREMMA);
  }

  /* close the common frame */
  if ((status = SCFCLO(commonid)) != 0) {
    /* problems closing common frame */
    return(MAREMMA);
  }

  /* put values in the structure */
  lvecbuf1 = longarray[0][0][0];
  lvecbuf2 = longarray[1][0][0];
  lvecbuf3 = longarray[2][0][0];
  lvecbuf4 = myflats->lowfibrebounds[0][0];
  lvecbuf5 = myflats->highfibrebounds[0][0];
  fmvecbuf1 = myflats->goodfibres[0][0];

  memcpy(myflats->lowfibrebounds[0][0], longarray[0][0][0], 
     (myflats->lastorder-myflats->firstorder+1)*
     myflats->maxfibres*myflats->subcols*sizeof(int32_t));
  memcpy(myflats->highfibrebounds[0][0], longarray[1][0][0], 
     (myflats->lastorder-myflats->firstorder+1)*
     myflats->maxfibres*myflats->subcols*sizeof(int32_t));
  maxiorderifibreixindex = ((myflats->lastorder-myflats->firstorder+1)*
                myflats->maxfibres*myflats->subcols)-1;


  for (iorderifibreixindex=0; iorderifibreixindex<=maxiorderifibreixindex;
       iorderifibreixindex++) {
    fmvecbuf1[iorderifibreixindex] = (frame_mask)lvecbuf3[iorderifibreixindex];
  }

  /* free the buffer */
  free_l4tensor(longarray, 0, 2, 0, myflats->lastorder-myflats->firstorder, 
        0, myflats->maxfibres-1, 0, myflats->subcols-1);


  /* open the normalisation frame */
  if ((status = SCFOPN(normalname, FLAMESDATATYPE, 0, F_IMA_TYPE, 
               &normid)) != 0) {
    /* could not open the frame */
    return(MAREMMA);
  }

  /* read the normalisation frame */
  if ((status = 
       SCFGET(normid, 1, 
          (myflats->lastorder-myflats->firstorder+1)*
          myflats->maxfibres*myflats->subcols, &actsize, 
          (char *)&myflats->normfactors[0][0][0])) != 0) {
    /* problems reading common frame: complain */
    return(MAREMMA);
  }
  else if (actsize != (myflats->lastorder-myflats->firstorder+1)*
       myflats->maxfibres*myflats->subcols) {
    /* I read fewer elements than expected: complain... */
    return(MAREMMA);
  }

  /* all right, close normalisation frame */
  if ((status = SCFCLO(normid)) != 0) {
    /* problems closing common frame */
    return(MAREMMA);
  }

  /* open the normalisation sigmas frame */
  if ((status = SCFOPN(nsigmaname, FLAMESDATATYPE, 0, F_IMA_TYPE, 
               &nsigid)) != 0) {
    /* could not open the frame */
    return(MAREMMA);
  }
  uves_msg_debug("lastorder=%d firstorder=%d subcols=%d maxfibres=%d",
		   myflats->lastorder,myflats->firstorder,myflats->subcols,
                   myflats->maxfibres);

  /* read the normalisation sigma frame */
  if ((status = 
       SCFGET(nsigid, 1, 
          (myflats->lastorder-myflats->firstorder+1)*
          myflats->maxfibres*myflats->subcols, &actsize, 
          (char *)&myflats->normsigmas[0][0][0])) != 0) {

  uves_msg_debug("check=%d vs=%d",(myflats->lastorder-myflats->firstorder+1)*
		   myflats->maxfibres*myflats->subcols,actsize);

    /* problems reading normsigma frame: complain */
    return(MAREMMA);
  }
  else if (actsize != (myflats->lastorder-myflats->firstorder+1)*
       myflats->maxfibres*myflats->subcols) {
    /* I read fewer elements than expected: complain... */
    return(MAREMMA);
  }


  /* all right, close normalisation sigmas frame */
  if ((status = SCFCLO(nsigid)) != 0) {
    /* problems closing common frame */
    return(MAREMMA);
  }

  /* rescan the catalog from the beginning and, this time, read all
     fibre FF frame names */
  iframe = 0;
  entrynum = 0;
  do {
    if ((status = SCCGET(catname, 1, filename, identifier, &entrynum)) != 0) {
      /* error getting catalog entry */
      return(MAREMMA);
    }
    /* did I get a valid catalog entry? */
    if (filename[0] != ' ') {
      /* is this a fibre FF frame? */
      if(strncmp(identifier, "Cleaned fibre FF",16) == 0) {
	//if(strstr(identifier, "FIB_FF_DT") != NULL) {
    strcpy(myflats->flatdata[iframe].framename, filename);
    iframe++;
      }
    }
  } while ((filename[0] != ' ') && (iframe <= myflats->nflats-1));


  for (iframe=0; iframe<=(myflats->nflats-1); iframe++) {

    /* open the data frame */
    if ((status = SCFOPN(myflats->flatdata[iframe].framename, 
             FLAMESDATATYPE, 0, F_IMA_TYPE, &frameid)) != 0) {
      /* could not open the frame */
      return(MAREMMA);
    }

    /* do some consistency checks */
    /*
    //amodigli: added to fix descriptor START:
    //Midas SPLIT/UVES allways set START to 1-1
    //CPL not. And Bound slitff have -49 on CRPIX1-CRVAL1
    //As bound files are not images we cannor use 
    //flames_reset_crval_to_one, thus we need to modify such 
    //descriptor here
    if(SCDWRD(frameid, "START", start, 1, 2, &unit)) {
        SCFCLO(frameid);
        uves_msg_error("setting START");
         return MAREMMA;
    }
    */

   if (checksize3(frameid, myflats) != NOERR) {
      /* the file dimensions do not match */
      return(MAREMMA);
    }


    /* read the data frame */
    if ((status = 
     SCFGET(frameid, 1, myflats->subcols*myflats->subrows, 
        &actsize, (char *) &myflats->flatdata[iframe].data[0][0]))
    != 0) {
      /* error reading frame data */
      return(MAREMMA);
    }


    if (actsize != myflats->subcols*myflats->subrows) {
      /* wrong number of elements read */
      return(MAREMMA);
    }



    /* read frame-specific data from descriptors */
    if ((status = SCDRDD(frameid, "YSHIFT", 1, 1, &actvals, 
             &myflats->flatdata[iframe].yshift, &unit, 
             &null)) != 0) {
      /* problems reading YSHIFT: complain... */
      return(MAREMMA);
    }


    if ((status = SCDRDI(frameid, "NUMFIBRES", 1, 1, &actvals, 
             &ibuf, &unit, &null)) != 0) {
      /* problems reading NUMFIBRES: complain... */
      return(MAREMMA);
    }
    myflats->flatdata[iframe].numfibres = (int32_t) ibuf;


    if ((status = SCDRDI(frameid, "FIBRES", 1, myflats->maxfibres, 
             &actvals, fibres, &unit, &null)) != 0) {
      /* problems reading FIBRES: complain... */
      return(MAREMMA);
    }


    for(ifibre=0; ifibre<=myflats->flatdata[iframe].numfibres-1; ifibre++){
      myflats->flatdata[iframe].fibres[ifibre] = 
    (int32_t) fibres[ifibre];
    }


    for(; ifibre<=myflats->maxfibres-1; ifibre++){
      myflats->flatdata[iframe].fibres[ifibre] = 0;
    }



    /* read the name of the sigma frame */
    if ((status = SCDGETC(frameid, "SIGMAFILE", 1, CATREC_LEN, &actvals, 
              filename)) != 0) {
      /* problems reading sigma file name from descriptor */
    }


    //AMo: we fix possible .bdf estention
    fixed_name=flames_fix_estention(filename);
    strcpy(filename,fixed_name);
    cpl_free(fixed_name);
    /* open the sigma frame */
    if ((status = SCFOPN(filename, FLAMESDATATYPE, 0, F_IMA_TYPE, 
             &sigmaid)) != 0) {
      /* could not open the frame */
      return(MAREMMA);
    }


    /*
   //amodigli: added to fix descriptor START:
    //Midas SPLIT/UVES allways set START to 1-1
    //CPL not. And Bound slitff have -49 on CRPIX1-CRVAL1
    //As bound files are not images we cannor use 
    //flames_reset_crval_to_one, thus we need to modify such 
    //descriptor here
    if(SCDWRD(sigmaid, "START", start, 1, 2, &unit)) {
        SCFCLO(sigmaid);
        uves_msg_error("setting START");
         return MAREMMA;
    }
    */

    strcpy(myflats->flatdata[iframe].sigmaname, filename);
    /* do some consistency checks */
    if (checksize3(sigmaid, myflats) != NOERR) {
      /* the file dimensions do not match */
      return(MAREMMA);
    }


    /* read the frame */
    if ((status = 
     SCFGET(sigmaid, 1, myflats->subcols*myflats->subrows, 
        &actsize, (char *) &myflats->flatdata[iframe].sigma[0][0]))
    != 0) {
      /* error reading frame sigma */
      return(MAREMMA);
    }

    if (actsize != myflats->subcols*myflats->subrows) {
      /* wrong number of elements read */
      return(MAREMMA);
    }

    /* close the sigma frame */
    if ((status = SCFCLO(sigmaid)) != 0) {
      /* problems closing sigma frame */
      return(MAREMMA);
    }

    /* read the name of the badpixel frame */
    if ((status = SCDGETC(frameid, "BADPIXELFILE", 1, CATREC_LEN, 
              &actvals, filename)) != 0) {
      /* problems reading badpixel file name from descriptor */
    }

    //AMo: we fix possible .bdf estention
    fixed_name=NULL;
    fixed_name=flames_fix_estention(filename);
    strcpy(filename,fixed_name);
    cpl_free(fixed_name);

    /* open the sigma frame */
    if ((status = SCFOPN(filename, FLAMESMASKTYPE, 0, F_IMA_TYPE, 
             &badid)) != 0) {
      /* could not open the frame */
      return(MAREMMA);
    }


    //AMo: added to fix descriptor START
    if(SCDWRD(badid, "START", start, 1, 2, &unit)) {
      SCFCLO(badid);
      uves_msg_error("setting START");
      return MAREMMA;
    }


    /*
   //amodigli: added to fix descriptor START:
    //Midas SPLIT/UVES allways set START to 1-1
    //CPL not. And Bound slitff have -49 on CRPIX1-CRVAL1
    //As bound files are not images we cannor use 
    //flames_reset_crval_to_one, thus we need to modify such 
    //descriptor here
    if(SCDWRD(badid, "START", start, 1, 2, &unit)) {
        SCFCLO(badid);
        uves_msg_error("setting START");
         return MAREMMA;
    }
    */

    strcpy(myflats->flatdata[iframe].badname, filename);
    /* do some consistency checks */
    if (checksize3(badid, myflats) != NOERR) {
      /* the file dimensions do not match */
      return(MAREMMA);
    }

    /* read the bad pixel frame */
    if ((status = SCFGET(badid, 1, myflats->subcols*myflats->subrows, 
             &actsize, 
             (char *) &myflats->flatdata[iframe].badpixel[0][0]))
    != 0) {
      /* error reading frame badpixel */
      return(MAREMMA);
    }

    if (actsize != myflats->subcols*myflats->subrows) {
      /* wrong number of elements read */
      return(MAREMMA);
    }


    /* close the badpixel frame */
    if ((status = SCFCLO(badid)) != 0) {
      /* problems closing badpixel frame */
      return(MAREMMA);
    }


    /* close the data frame */
    if ((status = SCFCLO(frameid)) != 0) {
      /* problems closing data frame */
      return(MAREMMA);
    }

  }

  free_ivector(fibres, 0,myflats->maxfibres-1);
  /* I read it all, exit */

  return NOERR;

}
