/*
 * This file is part of the ESO SINFONI Pipeline
 * Copyright (C) 2004,2005 European Southern Observatory
 *
 * 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, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
 */
/*----------------------------------------------------------------------------
   
   File name    :       sinfo_new_dark.c
   Author       :    A. Modigliani
   Created on   :    Sep 17, 2003
   Description  :    Master sinfo_dark creation 

 ---------------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

/*----------------------------------------------------------------------------
                                Includes
 ---------------------------------------------------------------------------*/
#include "sinfo_new_dark.h"
#include "sinfo_utilities.h"
#include "sinfo_pro_save.h"
#include "sinfo_dark_ini_by_cpl.h"
#include "sinfo_dfs.h"
#include "sinfo_pfits.h"
#include "sinfo_error.h"
#include "sinfo_utils_wrappers.h"
/*----------------------------------------------------------------------------
                                Defines
 ---------------------------------------------------------------------------*/
static int sinfo_dark_ron_reduce(cpl_frameset * framelist,
                            dark_config* cfg,
                            cpl_table* qclog);


static int 
sinfo_dark_compare(const cpl_frame * frame1, const cpl_frame * frame2);

/**@{*/
/**
 * @addtogroup sinfo_rec_mdark Master dark generation
 *
 * TBD
 */



/*----------------------------------------------------------------------------
                             Function Definitions
 ---------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
   @name  sinfo_new_dark()
   @param  plugin_id recipe id
   @param  config input parameterlist
   @param  sof    input set of frames
   @return integer (0 if it worked, -1 if it doesn't) 
   @doc 
                  1) Sorts frames according to integration time
                  2) Take the clean mean of a stack of frames with the 
                  same integration time

 ---------------------------------------------------------------------------*/

int sinfo_new_dark (const char* plugin_id, cpl_parameterlist* config, 
          cpl_frameset* sof, char* dark_name)
{
    
    dark_config * cfg=NULL ;
    cpl_imagelist * image_list=NULL ;
    cpl_imagelist * object_list=NULL ;

   
    cpl_image * image=NULL ;
    cpl_image * eclipse_image=NULL ;

    cpl_image* dark_img=NULL;
    cpl_frame* first_frame=NULL;
    cpl_vector* qc_dark_median=NULL;
    cpl_frameset* raw=NULL;
    cpl_table* qclog_tbl=NULL;
    cpl_propertylist* rplist=NULL;
    cpl_frameset* f_one=NULL;
    int no=0;
    float lo_cut=0.;
    float hi_cut=0.;

    int i = 0;
    int j = 0;
    int n = 0;
    int count = 0;
    int* n_times=NULL;
    double exp_time = 0.;    
    float* int_time=NULL;   
    float time_val = 0.; 

    char   ref_file[MAX_NAME_SIZE];
    cpl_size zone_def[4];
    double qc_ron_val=0;
    double qc_ron_err=0;
    double qc_darkmed_ave=0;
    double qc_darkmed_stdev=0;
    double fpn=0;
    cpl_size zone[4];
    int naxis1=0;
    int naxis2=0;

    cpl_size* selection=NULL;
    cpl_size nsets=0;
    /* 
       -----------------------------------------------------------------
       1) parse the file names and parameters to the dark_config data 
          structure cfg 
       -----------------------------------------------------------------
     */
 
    check_nomsg(raw=cpl_frameset_new());
    cknull(cfg = sinfo_parse_cpl_input_dark(config,sof,&raw),
           "could not parse cpl input!") ;

    /* 
       -----------------------------------------------------------------
       2) GET FRAMES AND SORT ACCORDING TO EXPOSURE TIME 
       -----------------------------------------------------------------
     */
     
    /* 
       2.1) get the total integration time from the fits header and 
            store it in an array
     */

    /* 2.1.1) get a data cube to stack darks */
    sinfo_msg("Build data cube");
    /* take a clean mean of the frames */
    check_nomsg(image_list = cpl_imagelist_new());
    int_time = (float*) cpl_calloc(cfg -> nframes, sizeof(float)) ;
    sinfo_check_rec_status(0);
 
    for ( i = 0 ; i < cfg->nframes ; i++ )
    {
        if (sinfo_is_fits_file (cfg->inFrameList[i]) != 1) {
       sinfo_msg_error("Input file %s is not FITS",cfg->inFrameList[i]);
           goto cleanup;
        }

    check_nomsg(cpl_imagelist_set(image_list,
                    cpl_image_load(cfg->inFrameList[i],CPL_TYPE_FLOAT,0,0),i));

        exp_time = sinfo_pfits_get_exptime(cfg->inFrameList[i]);
    if(cpl_error_get_code() != CPL_ERROR_NONE) {
       sinfo_msg_error("could not get exposure time from fits header!\n");
           goto cleanup;
    }
        sinfo_new_array_set_value(int_time, (float)exp_time, i);
    }
    no=cfg->nframes;


    /*
       2.2) find the number of frames with the same integration time
     */
    sinfo_msg("Find frames with same tint");
    n = 0;

    n_times = (int*) cpl_calloc(cfg -> nframes, sizeof(int));
    sinfo_msg("Sort frames with same tint");

    for ( i = 0 ; i < cfg->nframes-1 ; i++ )
    {
         if ( sinfo_new_array_get_value(int_time, i+1) != 
              sinfo_new_array_get_value(int_time, i)
        ) {

    n_times[n] = i+1;
        n = n+1;
    }
    
    }

    /* 
       2.3) store the images with the same tint in data cubes and take 
            clean means
     */
    sinfo_msg("Do clean mean");
    if ( n == 0 ) {

      sinfo_msg("n == 0 ");
       time_val = sinfo_new_array_get_value(int_time, 0);

      cknull(object_list = cpl_imagelist_new(),
         "could not allocate memory for object_list");

       /* here we have a leak of 80 bytes */


       count = 0;
       /* do also QC log */
       check_nomsg(qc_dark_median=cpl_vector_new(cfg->nframes));

       /* AMo here there is a leak */
       for ( j = 0 ; j < cfg->nframes ; j++ ) {
     check_nomsg(cpl_imagelist_set(object_list,
                     cpl_image_duplicate(cpl_imagelist_get(image_list,j)),
                     count));
     check_nomsg(cpl_vector_set(qc_dark_median,j,
                     cpl_image_get_median(cpl_imagelist_get(image_list,j))));
         count = count + 1;
       }


 
       check_nomsg(qc_darkmed_ave=cpl_vector_get_mean(qc_dark_median));
       if (cfg->nframes > 1) {
          check_nomsg(qc_darkmed_stdev=cpl_vector_get_stdev(qc_dark_median));
       }
       /* 
        rms   = stdev * sqrt(1-1/(double)cpl_vector_get_size(myvector)); 
       qc_darkmed_stdev = qc_darkmed_stdev * 
                       sqrt(1-1/(double)cpl_vector_get_size(qc_dark_median));
        */  

       check_nomsg(no=cpl_imagelist_get_size(object_list));
       lo_cut=(floor)(cfg->lo_reject*no+0.5);
       hi_cut=(floor)(cfg->hi_reject*no+0.5);

 
  
       cknull(image=cpl_imagelist_collapse_minmax_create(object_list,
                                                         lo_cut,hi_cut),
          "sinfo_average_with_rejection failed");

       sinfo_free_imagelist(&object_list);

       sinfo_msg("dark_name=%s\n",dark_name);
       
       check_nomsg(first_frame = cpl_frameset_get_frame(raw, 0)) ;
   
       strcpy(ref_file,cpl_frame_get_filename(first_frame)) ;
       cknull_nomsg(rplist = cpl_propertylist_load(ref_file, 0));

       check_nomsg(naxis1=cpl_propertylist_get_int(rplist,"NAXIS1"));
       check_nomsg(naxis2=cpl_propertylist_get_int(rplist,"NAXIS1"));
       sinfo_free_propertylist(&rplist);

       if(cfg->qc_ron_xmin < 1) {
     sinfo_msg_error("qc_ron_xmin %d < 1",cfg->qc_ron_xmin);
         goto cleanup;
       }

       if(cfg->qc_ron_xmax > naxis1) {
     sinfo_msg_error("qc_ron_xmax %d > %d",cfg->qc_ron_xmax,naxis1);
         goto cleanup;
       }

       if(cfg->qc_ron_ymin < 1) {
     sinfo_msg_error("qc_ron_ymin %d < 1",cfg->qc_ron_ymin);
         goto cleanup;
       }

       if(cfg->qc_ron_ymax > naxis2) {
     sinfo_msg_error("qc_ron_ymax %d > %d",cfg->qc_ron_ymax,naxis2);
         goto cleanup;
       }

       zone_def[0]=cfg->qc_ron_xmin;
       zone_def[1]=cfg->qc_ron_xmax;
       zone_def[2]=cfg->qc_ron_ymin;
       zone_def[3]=cfg->qc_ron_ymax;



       check(cpl_flux_get_noise_window(image,
                       zone_def,
                       cfg->qc_ron_hsize,
                       cfg->qc_ron_nsamp,
                       &qc_ron_val,
                       &qc_ron_err),
         "In computation RON on image %s",dark_name);
      
 

       if(cfg->qc_fpn_xmin < 1) {
     sinfo_msg_error("qc_fpn_xmin %d < 1",cfg->qc_fpn_xmin);
         goto cleanup;
       }

       if(cfg->qc_fpn_xmax > naxis1) {
     sinfo_msg_error("qc_fpn_xmax %d > %d",cfg->qc_fpn_xmax,naxis1);
         goto cleanup;
       }

       if(cfg->qc_fpn_ymin < 1) {
     sinfo_msg_error("qc_fpn_ymin %d < 1",cfg->qc_fpn_ymin);
         goto cleanup;
       }

       if(cfg->qc_fpn_ymax > naxis2) {
     sinfo_msg_error("qc_fpn_ymax %d > %d",cfg->qc_fpn_ymax,naxis2);
         goto cleanup;
       }

       zone[0]=cfg->qc_fpn_xmin;
       zone[1]=cfg->qc_fpn_xmax;
       zone[2]=cfg->qc_fpn_ymin;
       zone[3]=cfg->qc_fpn_ymax;
       check(cpl_flux_get_noise_window(image, zone, cfg->qc_fpn_hsize,
                       cfg->qc_fpn_nsamp, &fpn, NULL),
         "Error computing noise in a window");

       /* QC LOG */
       cknull_nomsg(qclog_tbl = sinfo_qclog_init());

       ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC DARKMED AVE",
             qc_darkmed_ave,"Average of raw darks medians","%f"));

       ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC DARKMED STDEV",
                     qc_darkmed_stdev,"STDEV of raw darks medians","%f"));

       ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC RON",
                     qc_ron_val,"Read Out Noise","%f"));
       
       ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC RONRMS",
                     qc_ron_err,"RMS on Read Out Noise","%f"));

       ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC DARKFPN",
                     fpn,"Fixed Pattern Noise of combined frames","%g"));

 
       /* special way to calculate RON: for each couple */
       
       check(selection = cpl_frameset_labelise(raw,sinfo_dark_compare,&nsets),
         "Error labelizing");



       for ( i = 0 ; i < nsets ; i++ ) {
         sinfo_msg("Reduce data set no %d out of %" CPL_SIZE_FORMAT "", i+1, nsets);
         cpl_msg_indent_more();
     check_nomsg(f_one = cpl_frameset_extract(raw,selection,i));
         if (cpl_frameset_get_size(f_one) < 2) {
           sinfo_msg_warning("Skip %d set. One frame, not enough "
                             "to get ron",i+1);
     } else {
           if (sinfo_dark_ron_reduce(f_one,cfg,qclog_tbl) ) {
         sinfo_msg_warning( "Cannot reduce set number %d", i+1) ;
       }
     }
         sinfo_free_frameset(&f_one);
         cpl_msg_indent_less();

       }
       cpl_free(selection);


       /* generate a dummy_set with the master dark and a dummy 
              dark=2*master_dark */

       ck0(sinfo_pro_save_ima(image,raw,sof,dark_name,
                 PRO_MASTER_DARK,qclog_tbl,plugin_id,config),
                           "cannot save ima %s", dark_name);
       sinfo_free_table(&qclog_tbl);
       sinfo_free_image(&image);
 
    } else if (n == 1) {

       sinfo_msg("n == 1");
       time_val = sinfo_new_array_get_value(int_time, 0);
       cknull(object_list = cpl_imagelist_new(),
           "could not allocate memory");

       count = 0;

       for (j =0; j < n_times[0]; j++) {

     check_nomsg(cpl_imagelist_set(object_list,
                     cpl_image_duplicate(cpl_imagelist_get(image_list,j)),
                     count));
     count = count + 1;
       }


       check_nomsg(no=cpl_imagelist_get_size(object_list));
       lo_cut=(floor)(cfg->lo_reject*no+0.5);
       hi_cut=(floor)(cfg->hi_reject*no+0.5);
       check(image=cpl_imagelist_collapse_minmax_create(object_list,
                                                        lo_cut,hi_cut),
                                 "sinfo_average_with_rejection failed!");

       sinfo_free_imagelist(&object_list);

       cknull_nomsg(qclog_tbl = sinfo_qclog_init());
       ck0_nomsg(sinfo_qclog_add_int(qclog_tbl,"QC NAME",1,
                                     "A description","%d"));

       ck0(sinfo_pro_save_ima(image,raw,sof,dark_name,
                  PRO_MASTER_DARK,qclog_tbl,plugin_id,config),
                          "cannot save ima %s", dark_name);


       sinfo_free_image(&image);
       sinfo_free_table(&qclog_tbl);

       time_val = sinfo_new_array_get_value(int_time, n_times[0]);
       cknull(object_list = cpl_imagelist_new(),
          "could not allocate memory");
       count = 0;


       for (j = n_times[0]; j < cfg->nframes; j++) {

     check_nomsg(cpl_imagelist_set(object_list,
                     cpl_image_duplicate(cpl_imagelist_get(image_list,j)),
                     count));
         count = count + 1;
       }


       check_nomsg(no=cpl_imagelist_get_size(object_list));
       lo_cut=(floor)(cfg->lo_reject*no+0.5);
       hi_cut=(floor)(cfg->hi_reject*no+0.5);
       cknull(eclipse_image=cpl_imagelist_collapse_minmax_create(object_list,
                                                                 lo_cut,hi_cut),
          "sinfo_average_with_rejection failed!");

       sinfo_free_imagelist(&object_list);


       cknull_nomsg(qclog_tbl = sinfo_qclog_init());
       ck0_nomsg(sinfo_qclog_add_int(qclog_tbl,"QC NAME",1,
                                     "A description","%d"));

       ck0(sinfo_pro_save_ima(eclipse_image,raw,sof,dark_name,
                  PRO_MASTER_DARK,qclog_tbl,plugin_id,config),
                          "cannot save ima %s", dark_name);

       sinfo_free_image(&eclipse_image);
       sinfo_free_table(&qclog_tbl);

    } else {

       sinfo_msg("n==else\n");

       for (i= 0; i < n+1; i++) {
         if ( i == 0 ) {
           time_val = sinfo_new_array_get_value(int_time, 0);
        check(object_list = cpl_imagelist_new(),
               "could not allocate memory");

            count = 0;
            for (j = 0; j < n_times[0]; j++) {
          check_nomsg(cpl_imagelist_set(object_list,
                          cpl_image_duplicate(cpl_imagelist_get(image_list,j)),
                          count));
          count = count + 1;
        }
        check_nomsg(no=cpl_imagelist_get_size(object_list));
        lo_cut=(floor)(cfg->lo_reject*no+0.5);
        hi_cut=(floor)(cfg->hi_reject*no+0.5);
            check(image=cpl_imagelist_collapse_minmax_create(object_list,
                                                             lo_cut,hi_cut),
                                    "Error computing average with rejection");
            sinfo_free_imagelist(&object_list);

            sinfo_msg("dark_name-%s\n",dark_name);
            cknull_nomsg(qclog_tbl = sinfo_qclog_init());
            ck0_nomsg(sinfo_qclog_add_int(qclog_tbl,"QC NAME",1,
                                          "A description","%d"));

            ck0(sinfo_pro_save_ima(image,raw,sof,dark_name,
                   PRO_MASTER_DARK,qclog_tbl,plugin_id,config),
              "cannot save ima %s", dark_name);


            sinfo_free_table(&qclog_tbl);
            sinfo_free_image(&image);
     } else if ( i == n ) {
            time_val = sinfo_new_array_get_value(int_time, n_times[n-1]);
            cknull(object_list = cpl_imagelist_new(), 
               "could not allocate memory");

            count = 0;
            for (j = n_times[n-1]; j < cfg->nframes; j++) {
          check_nomsg(cpl_imagelist_set(object_list,
                          cpl_image_duplicate(cpl_imagelist_get(image_list,j)),
                          count));
          count = count + 1;
        }
        check_nomsg(no=cpl_imagelist_get_size(object_list));
        lo_cut=(floor)(cfg->lo_reject*no+0.5);
        hi_cut=(floor)(cfg->hi_reject*no+0.5);
            check(image=cpl_imagelist_collapse_minmax_create(object_list,
                                                             lo_cut,hi_cut),
                  "Error computing average with rejection");

            sinfo_free_imagelist(&object_list);

            cknull_nomsg(qclog_tbl = sinfo_qclog_init());
            ck0_nomsg(sinfo_qclog_add_int(qclog_tbl,"QC NAME",1,
                                          "A description","%d"));

            ck0(sinfo_pro_save_ima(image,raw,sof,dark_name,
                   PRO_MASTER_DARK,qclog_tbl,plugin_id,config),
        "cannot save ima %s", dark_name);
            sinfo_free_table(&qclog_tbl);
            sinfo_free_image(&image);
    } else {
        time_val = sinfo_new_array_get_value(int_time, n_times[i-1]);
        cknull(object_list = cpl_imagelist_new(), 
                   "could not allocate memory");

            count = 0;
            for (j = n_times[i-1]; j < n_times[i]; j++) {
          check_nomsg(cpl_imagelist_set(object_list,
                          cpl_image_duplicate(cpl_imagelist_get(image_list,j)),
                          count));
          count = count + 1;
        }
        check_nomsg(no=cpl_imagelist_get_size(object_list));
        lo_cut=(floor)(cfg->lo_reject*no+0.5);
        hi_cut=(floor)(cfg->hi_reject*no+0.5);
            cknull(image=cpl_imagelist_collapse_minmax_create(object_list,
                                                              lo_cut,hi_cut),
                                     "Error computing average with rejection");

            sinfo_free_imagelist(&object_list);

            cknull_nomsg(qclog_tbl = sinfo_qclog_init());
            ck0_nomsg(sinfo_qclog_add_int(qclog_tbl,"QC NAME",1,
                                          "A description","%d"));

            ck0(sinfo_pro_save_ima(image,raw,sof,dark_name,
                   PRO_MASTER_DARK,qclog_tbl,plugin_id,config),
                                   "cannot save ima %s", dark_name);

            sinfo_free_image(&image);
            sinfo_free_table(&qclog_tbl);
    }
       
       } /* end for loop */
    } /* end else over n */

 

       sinfo_free_imagelist(&image_list);
       sinfo_free_my_vector(&qc_dark_median);
       sinfo_free_int(&n_times);
       sinfo_free_float(&int_time);
       sinfo_dark_free(&cfg);
       sinfo_free_frameset(&raw);

      return 0;

 cleanup:
       sinfo_free_frameset(&f_one);
       cpl_free(selection);
       sinfo_free_image(&eclipse_image);
       sinfo_free_table(&qclog_tbl);
       sinfo_free_image(&dark_img);
       sinfo_free_image(&image);
       sinfo_free_propertylist(&rplist);
       sinfo_free_my_vector(&qc_dark_median);
       sinfo_free_imagelist(&object_list);
       sinfo_free_int(&n_times);
       sinfo_free_float(&int_time);
       sinfo_free_imagelist(&image_list);
       sinfo_dark_free(&cfg);
       sinfo_free_frameset(&raw);

       return -1;

}






/*--------------------------------------------------------------------*/
    /**
          @brief    The recipe data reduction ('ron' part) is implemented here 
          @param    framelist   the frames list of the current set 
          @param    set         the complete frames set
          @return   0 if ok, -1 in error case
     */
/*--------------------------------------------------------------------*/
 static int 
sinfo_dark_ron_reduce(cpl_frameset    *   framelist,
              dark_config     *   cfg,
              cpl_table       *   qclog_tbl)
{
  cpl_imagelist   *   iset =NULL;
  int                 i =0;
  double* ron=NULL;
  /* int nraw=0; */
  int niset=0;
  char key_name[MAX_NAME_SIZE];
  /* Test entries */

  cknull_nomsg(framelist);

  /* Load the current set */
  if ((iset = sinfo_new_frameset_to_iset(framelist)) == NULL) {
    sinfo_msg_error( "Cannot load the data") ;
    return -1 ;
  }
  /* Loop on all pairs */
  /* nraw = cpl_table_get_nrow(qclog_tbl); */
  niset=cpl_imagelist_get_size(iset);

  ron = cpl_calloc(niset,sizeof(double));

  sinfo_get_ron(framelist,
                cfg->qc_ron_xmin,cfg->qc_ron_xmax,
                cfg->qc_ron_ymin,cfg->qc_ron_ymax,
                cfg->qc_ron_hsize,cfg->qc_ron_nsamp,
                &ron);

  for (i=0 ; i<niset-1 ; i++) {

    /* Write the paf file on disk */
    /* Write QC LOG */

    snprintf(key_name,MAX_NAME_SIZE-1,"%s%d","QC RON",i+1);
    sinfo_qclog_add_double(qclog_tbl,key_name,ron[i],
               "Read Out Noise","%f");

  }

  cpl_free(ron);
  sinfo_free_imagelist(&iset) ;

  return 0 ;
 cleanup:
  cpl_free(ron);
  ron=NULL;
  sinfo_free_imagelist(&iset) ;

  return -1;

}


/*---------------------------------------------------------------------------*/
/**
  @brief    Comparison function to identify different settings
  @param    frame1  first frame 
  @param    frame2  second frame 
  @return   0 if frame1!=frame2, 1 if frame1==frame2, -1 in error case
 */
/*---------------------------------------------------------------------------*/
static int sinfo_dark_compare(
        const cpl_frame   *   frame1,
        const cpl_frame   *   frame2)
{
    int                 comparison=0 ;
    cpl_propertylist *  plist1=NULL;
    cpl_propertylist *  plist2=NULL;

    char            *   sval ;
    char                mode1[512] ;
    char                mode2[512] ;
    double              dval1=0;
    double              dval2=0;
    int                 ival1=0;
    int                 ival2=0;

    /* Test entries */
    if (frame1==NULL || frame2==NULL) return -1 ;

    /* Get property lists */
    cknull(plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),0),
        "getting header from reference frame");

    cknull(plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),0),
        "getting header from reference frame");
     
    /* Compare exposure time */
    comparison = 1 ;
    check(dval1=sinfo_pfits_get_exp_time(plist1),"To get exptime");
    check(dval2=sinfo_pfits_get_exp_time(plist2),"To get exptime");

    if (fabs(dval1-dval2) > 1e-5) comparison = 0 ;

    /* Compare the readout mode */
    check(ival1=sinfo_pfits_get_rom(plist1),"to get read out mode");
    check(ival2=sinfo_pfits_get_rom(plist2),"to get read out mode");
    if (ival1 != ival2) comparison = 0 ;


    /* Compare the detector mode */
    cknull(sval=sinfo_pfits_get_mode(plist1),"to get detector mode");
    strcpy(mode1, sval) ;

    cknull(sval=sinfo_pfits_get_mode(plist2),"to get detector mode");
    strcpy(mode2, sval) ;


    if (strcmp(mode1, mode2)) comparison = 0 ;

    /* Files have to be consequtive */
    /*
    check(ival1 = sinfo_pfits_get_expno(plist1),"to get exposure number");
    check(ival2 = sinfo_pfits_get_expno(plist1),"to get exposure number");
    if (ival1 != ival2) comparison = 0 ;
    */
    sinfo_free_propertylist(&plist1);
    sinfo_free_propertylist(&plist2);

    return comparison ;
 cleanup:
    sinfo_free_propertylist(&plist1);
    sinfo_free_propertylist(&plist2);
    return -1 ;


}
/**@}*/
