CRIRES Pipeline Reference Manual  2.3.2
crires_win_flat.c
00001 /* $Id: crires_win_flat.c,v 1.7 2012-09-19 14:52:00 yjung Exp $
00002  *
00003  * This file is part of the CRIRES Pipeline
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: yjung $
00023  * $Date: 2012-09-19 14:52:00 $
00024  * $Revision: 1.7 $
00025  * $Name: not supported by cvs2svn $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include "crires_recipe.h"
00037 
00038 #include "crires_combine.h"
00039 
00040 /*-----------------------------------------------------------------------------
00041                                 Define
00042  -----------------------------------------------------------------------------*/
00043 
00044 #define RECIPE_STRING "crires_win_flat"
00045 
00046 /*-----------------------------------------------------------------------------
00047                             Functions prototypes
00048  -----------------------------------------------------------------------------*/
00049 
00050 static cpl_imagelist * crires_win_flat_reduce(cpl_frameset *, const char *, 
00051         const char *) ;
00052 static cpl_imagelist * crires_win_flat_bpm(cpl_imagelist *, double, 
00053         double, double) ;
00054 static int crires_win_flat_save(const cpl_imagelist *, const cpl_imagelist *, 
00055         int, cpl_frameset *, const cpl_parameterlist *, cpl_frameset *) ;
00056 static int crires_win_flat_compare(const cpl_frame *, const cpl_frame *) ;
00057 
00058 static char crires_win_flat_description[] =
00059 "crires_win_flat -- Flat-field recipe in Windowing mode\n"
00060 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00061 "raw-file.fits "CRIRES_WIN_FLAT_RAW" or\n"
00062 "dark-file.fits "CRIRES_CALPRO_DARK" or\n"
00063 "detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE".\n" ;
00064 
00065 CRIRES_RECIPE_DEFINE(crires_win_flat,
00066         CRIRES_PARAM_THRESHOLDS     |
00067         CRIRES_PARAM_BPM_RATE       |
00068         CRIRES_PARAM_REPLACE        |
00069         CRIRES_PARAM_KAPPA_SIGCLIP  |
00070         CRIRES_PARAM_COLLAPSE_METH,
00071         "Flatfield recipe in Windowing mode",
00072         crires_win_flat_description) ;
00073 
00074 /*-----------------------------------------------------------------------------
00075                             Static variables
00076  -----------------------------------------------------------------------------*/
00077 
00078 static struct {
00079     /* Input */
00080     double                  bpm_low ;
00081     double                  bpm_high ;
00082     double                  bpm_lines_ratio ;
00083     int                     replace_flag ;
00084     double                  kappa_sigclip ;
00085     crires_collapse_method  coll_meth ;
00086     /* Output */
00087     int                     bpm_nb[CRIRES_NB_DETECTORS] ;
00088     double                  flat_mean[CRIRES_NB_DETECTORS] ;
00089     double                  flat_stdev[CRIRES_NB_DETECTORS] ;
00090     double                  flat_flux[CRIRES_NB_DETECTORS] ;
00091     double                  flat_master_rms[CRIRES_NB_DETECTORS] ;
00092 } crires_win_flat_config ;
00093 
00094 /*-----------------------------------------------------------------------------
00095                                 Functions code
00096  -----------------------------------------------------------------------------*/
00097 
00098 /*----------------------------------------------------------------------------*/
00105 /*----------------------------------------------------------------------------*/
00106 static int crires_win_flat(
00107         cpl_frameset            *   frameset,
00108         const cpl_parameterlist *   parlist)
00109 {
00110     const char      *   sval ;
00111     cpl_size        *   labels ;
00112     cpl_size            nlabels ;
00113     cpl_frameset    *   rawframes ;
00114     const char      *   dark ;
00115     const char      *   detlin ;
00116     cpl_imagelist   *   flat ;
00117     cpl_frameset    *   flat_one ;
00118     cpl_imagelist   *   bpm ;
00119     int                 i ;
00120 
00121     /* Initialise */
00122     rawframes = NULL ;
00123     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00124         crires_win_flat_config.bpm_nb[i] = -1 ;
00125         crires_win_flat_config.flat_mean[i] = -1.0 ;
00126         crires_win_flat_config.flat_stdev[i] = -1.0 ;
00127         crires_win_flat_config.flat_flux[i] = -1.0 ;
00128         crires_win_flat_config.flat_master_rms[i] = -1.0 ;
00129     }
00130     
00131     /* Retrieve input parameters */
00132     sval = crires_parameterlist_get_string(parlist, RECIPE_STRING, 
00133             CRIRES_PARAM_THRESHOLDS) ;
00134     if (sscanf(sval, "%lg,%lg",
00135                     &crires_win_flat_config.bpm_low,
00136                     &crires_win_flat_config.bpm_high)!=2) {
00137         return -1 ;
00138     }
00139     crires_win_flat_config.replace_flag = crires_parameterlist_get_bool(
00140             parlist, RECIPE_STRING, CRIRES_PARAM_REPLACE) ;
00141     crires_win_flat_config.bpm_lines_ratio = crires_parameterlist_get_double( 
00142             parlist, RECIPE_STRING, CRIRES_PARAM_BPM_RATE) ;
00143     crires_win_flat_config.kappa_sigclip = crires_parameterlist_get_double( 
00144             parlist, RECIPE_STRING, CRIRES_PARAM_KAPPA_SIGCLIP) ;
00145     sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
00146             CRIRES_PARAM_COLLAPSE_METH) ;
00147     if (!strcmp(sval, "avg"))
00148         crires_win_flat_config.coll_meth = CRIRES_COLLAPSE_AVG ;
00149     else if (!strcmp(sval, "med"))
00150         crires_win_flat_config.coll_meth = CRIRES_COLLAPSE_MED ;
00151     else if (!strcmp(sval, "sig"))
00152         crires_win_flat_config.coll_meth = CRIRES_COLLAPSE_SIG ;
00153     else {
00154         cpl_msg_error(__func__, "Invalid collapse method specified");
00155         return -1;
00156     }
00157  
00158     /* Identify the RAW and CALIB frames in the input frameset */
00159     if (crires_dfs_set_groups(frameset, "crires_win_flat")) {
00160         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00161         return -1 ;
00162     }
00163 
00164     /* Retrieve calibration data */
00165     dark        = crires_extract_filename(frameset, CRIRES_CALPRO_DARK_WIN) ;
00166     detlin      = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ;
00167 
00168     /* Retrieve raw frames */
00169     if ((rawframes = crires_extract_frameset(frameset, 
00170                     CRIRES_WIN_FLAT_RAW)) == NULL) {
00171         cpl_msg_error(__func__, "No raw frame in input") ;
00172         return -1 ;
00173     }
00174 
00175     /* Labelise all input frames */
00176     if ((labels = cpl_frameset_labelise(rawframes, crires_win_flat_compare,
00177                 &nlabels)) == NULL) {
00178         cpl_msg_error(__func__, "Cannot labelise input frames") ;
00179         cpl_frameset_delete(rawframes) ;
00180         return -1 ;
00181     }
00182 
00183     /* Extract settings and reduce each of them */
00184     for (i=0 ; i<(int)nlabels ; i++) {
00185         /* Reduce data set nb i */
00186         cpl_msg_info(__func__, "Reduce data set %d / %"CPL_SIZE_FORMAT, 
00187                 i+1, nlabels);
00188         cpl_msg_indent_more() ;
00189         flat_one = cpl_frameset_extract(rawframes, labels, (cpl_size)i) ;
00190         flat = crires_win_flat_reduce(flat_one, dark, detlin) ;
00191         cpl_msg_indent_less() ;
00192 
00193         /* Save the products */
00194         cpl_msg_info(__func__, "Save the products") ;
00195         cpl_msg_indent_more() ;
00196         if (flat == NULL) {
00197             cpl_msg_warning(__func__, "Cannot reduce set nb %d", i+1) ;
00198         } else {
00199             if ((bpm = crires_win_flat_bpm(flat,
00200                             crires_win_flat_config.bpm_low,
00201                             crires_win_flat_config.bpm_high,
00202                             crires_win_flat_config.bpm_lines_ratio)) == NULL) {
00203                 cpl_msg_warning(__func__, "Cannot create bad pixels map") ;
00204             }
00205             crires_win_flat_save(flat, bpm, i+1, flat_one, parlist, frameset) ;
00206             cpl_imagelist_delete(flat) ;
00207             cpl_imagelist_delete(bpm) ;
00208         }
00209         cpl_msg_indent_less() ;
00210         cpl_frameset_delete(flat_one) ;
00211     }
00212     cpl_frameset_delete(rawframes) ;
00213     cpl_free(labels) ;
00214 
00215     /* Return */
00216     if (cpl_error_get_code()) return -1 ;
00217     else return 0 ;
00218 }
00219 
00220 /*----------------------------------------------------------------------------*/
00228 /*----------------------------------------------------------------------------*/
00229 static cpl_imagelist * crires_win_flat_reduce(
00230         cpl_frameset    *   flatframes,
00231         const char      *   dark,
00232         const char      *   detlin)
00233 {
00234     cpl_propertylist    *   plist ;
00235     cpl_frame           *   ref_frame ;
00236     const char          *   fname ;
00237     int                     nframes ;
00238     double                  dit_frame, dit_dark ;
00239     cpl_imagelist       *   in ;
00240     cpl_imagelist       *   out ;
00241     cpl_vector          *   medians ;
00242     double                  median ;
00243     cpl_image           *   ima[CRIRES_NB_DETECTORS] ;
00244     int                     offset_y, stripe_y, center_y ;
00245     int                     i, j, k ;
00246 
00247     /* Test entries */
00248     if (flatframes == NULL) return NULL ;
00249 
00250     /* Initialize */
00251     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00252         ima[i] = NULL ;
00253     }
00254     nframes = cpl_frameset_get_size(flatframes) ;
00255 
00256     /* Get the DIT from the RAW frame */
00257     ref_frame = cpl_frameset_get_position(flatframes, 0) ;
00258     fname = cpl_frame_get_filename(ref_frame) ;
00259     if ((plist=cpl_propertylist_load(fname, 0)) == NULL) {
00260         cpl_msg_error(__func__, "Getting header from RAW file");
00261         cpl_msg_indent_less() ;
00262         return NULL ;
00263     }
00264     dit_frame = crires_pfits_get_dit(plist) ;
00265     offset_y = crires_pfits_get_stripe_offsety(plist) ;
00266     center_y = crires_pfits_get_stripe_centery(plist) ;
00267     cpl_propertylist_delete(plist) ;
00268     if (cpl_error_get_code()) {
00269         cpl_msg_error(__func__, 
00270                 "Cannot get the DIT or STRIPE keywords from RAW file") ;
00271         cpl_msg_indent_less() ;
00272         return NULL ;
00273     }
00274     cpl_msg_info(__func__, "DIT value: %g sec.", dit_frame) ;
00275     
00276     /* Verify the DIT of the dark */
00277     if (dark != NULL) {
00278         cpl_msg_info(__func__, "Verify the dark DIT") ;
00279         cpl_msg_indent_more() ;
00280         if ((plist=cpl_propertylist_load(dark, 0)) == NULL) {
00281             cpl_msg_error(__func__, "Getting header from DARK");
00282             cpl_msg_indent_less() ;
00283             return NULL ;
00284         }
00285         dit_dark = crires_pfits_get_dit(plist) ;
00286         cpl_propertylist_delete(plist) ;
00287         if (cpl_error_get_code()) {
00288             cpl_msg_error(__func__, "Cannot get the DIT from DARK") ;
00289             cpl_msg_indent_less() ;
00290             return NULL ;
00291         }
00292         if (fabs(dit_dark-dit_frame) > 1e-5) {
00293             cpl_msg_error(__func__, "Mismatch RAW DIT (%g) / DARK DIT (%g)",
00294                     dit_frame, dit_dark) ;
00295             cpl_msg_indent_less() ;
00296             return NULL ;
00297         }
00298         cpl_msg_indent_less() ;
00299 
00300         /* Verify the STRIPE keys conformity */
00301         if (crire_stripe_keys_mismatch(fname, dark)) {
00302             cpl_msg_error(__func__, 
00303                     "Mismatch of STRIPE keys with the dark frame") ;
00304             return NULL ;
00305         }
00306     }
00307 
00308     /* Loop on the detectors */
00309     for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
00310         cpl_msg_info(__func__, "Compute the MASTER FLAT for chip nb %d", i+1) ;
00311         cpl_msg_indent_more() ;
00312 
00313         /* Load the data */
00314         in = crires_load_frameset(flatframes, CRIRES_ILLUM_FULL_DETECTOR, 
00315                 i+1, CPL_TYPE_FLOAT) ;
00316         stripe_y = (int)(cpl_image_get_size_y(cpl_imagelist_get(in, 0))/2.0) ;
00317 
00318         /* Correct for dark */
00319         if (crires_calib_chip_list(in, CRIRES_ILLUM_FULL_DETECTOR, i+1, 
00320                     NULL, dark, NULL, detlin, dit_frame, center_y, offset_y, 
00321                     stripe_y)) {
00322             cpl_msg_error(__func__, "Cannot apply the calibrations") ;
00323             cpl_imagelist_delete(in) ;
00324             for (j=1 ; j<i ; j++) 
00325                 cpl_image_delete(ima[j]);
00326             return NULL ;
00327         }
00328 
00329         /* Create medians vector */
00330         medians = cpl_vector_new(nframes) ;
00331 
00332         /* Loop on all the frames */
00333         cpl_msg_info(__func__, "Normalise with the median") ;
00334         for (j=0 ; j<nframes ; j++) {
00335             median = cpl_image_get_median(cpl_imagelist_get(in, j)) ;
00336             if (cpl_error_get_code()) {
00337                 cpl_msg_error(__func__, "Cannot compute the median") ;
00338                 cpl_imagelist_delete(in) ;
00339                 cpl_vector_delete(medians) ;
00340                 for (k=1 ; k<i ; k++) 
00341                     cpl_image_delete(ima[k]);
00342                 return NULL ;
00343             }
00344             cpl_vector_set(medians, j, median) ;
00345             if (fabs(median) > 1e-3) 
00346                 cpl_image_divide_scalar(cpl_imagelist_get(in, j), median) ;
00347         }
00348 
00349         /* Fill QCs */
00350         crires_win_flat_config.flat_mean[i] = cpl_vector_get_mean(medians) ;
00351         if (cpl_vector_get_size(medians) > 1) 
00352             crires_win_flat_config.flat_stdev[i]=cpl_vector_get_stdev(medians);
00353         else
00354             crires_win_flat_config.flat_stdev[i] = -1.0 ;
00355         crires_win_flat_config.flat_flux[i] =
00356             crires_win_flat_config.flat_mean[i] / dit_frame ;
00357        
00358         /* Collapse the frames */
00359         if ((ima[i] = crires_combine_collapse_imagelist(in, medians, 
00360                         crires_win_flat_config.kappa_sigclip,
00361                         i+1,
00362                         crires_win_flat_config.coll_meth)) == NULL) {
00363             cpl_msg_error(__func__, "Cannot average the flats") ;
00364             cpl_imagelist_delete(in) ;
00365             cpl_vector_delete(medians) ;
00366             for (j=1 ; j<i ; j++) 
00367                 cpl_image_delete(ima[j]);
00368             return NULL ;
00369         }
00370         cpl_vector_delete(medians) ;
00371         cpl_imagelist_delete(in) ;
00372 
00373         /* Add QC */
00374         crires_win_flat_config.flat_master_rms[i] =
00375             cpl_image_get_stdev(ima[i]) ;
00376         
00377         cpl_msg_indent_less() ;
00378     }
00379 
00380     /* Reconstruct chips (windowing mode) using detector 2 */
00381     if (ima[1] != NULL) {
00382         ima[0] = cpl_image_duplicate(ima[1]) ;
00383         cpl_image_multiply_scalar(ima[0], 0.0) ;
00384         ima[CRIRES_NB_DETECTORS-1] = cpl_image_duplicate(ima[0]) ;
00385     }
00386     
00387     /* Create the image list */
00388     out = cpl_imagelist_new() ;
00389     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) 
00390         cpl_imagelist_set(out, ima[i], i) ;
00391 
00392     return out ;
00393 }
00394 
00395 /*----------------------------------------------------------------------------*/
00404 /*----------------------------------------------------------------------------*/
00405 static cpl_imagelist * crires_win_flat_bpm(
00406         cpl_imagelist       *   flat,
00407         double                  low,
00408         double                  high,
00409         double                  bad_per_line_limit)
00410 {
00411     cpl_imagelist   *   bpm ;
00412     int                 nima ;
00413     cpl_image       *   bpm_cur ;
00414     cpl_mask        *   mask_cur ;
00415     cpl_binary      *   pmask_cur ;
00416     int                 nx, ny, cur_bp_nb ;
00417     int                 i, j, k ;
00418 
00419     /* Test entries */
00420     if (flat == NULL) return NULL ;
00421 
00422     /* Initialise */
00423     nima = cpl_imagelist_get_size(flat) ;
00424 
00425     /* Create the output image list */
00426     bpm = cpl_imagelist_new() ;
00427 
00428     /* Loop on the images */
00429     for (i=0 ; i<nima ; i++) {
00430         /* Threshold to get the BPMs */
00431         if ((mask_cur = cpl_mask_threshold_image_create(
00432                         cpl_imagelist_get(flat, i), low, high)) == NULL) {
00433             cpl_msg_error(__func__, "Cannot create bad pixels map") ;
00434             cpl_imagelist_delete(bpm) ;
00435             return NULL ;
00436         }
00437         cpl_mask_not(mask_cur) ;
00438 
00439         /*
00440         Post processing : Big zones of bad pixels are not considered as
00441         bad pixels. Each line containing more than
00442         100*bad_per_line_limit percent bad pixels is reset to contain
00443         anly good pixels.
00444         */
00445         nx = cpl_mask_get_size_x(mask_cur) ;
00446         ny = cpl_mask_get_size_y(mask_cur) ;
00447         pmask_cur = cpl_mask_get_data(mask_cur) ;
00448         for (j=0 ; j<ny ; j++) {
00449             cur_bp_nb = cpl_mask_count_window(mask_cur, 1, j+1, nx, j+1) ;
00450             /* Check if the line has too many bad pixels */
00451             if (cur_bp_nb > bad_per_line_limit * nx) {
00452                 /* Reset the bad pixels on the current line */
00453                 for (k=0 ; k<nx ; k++) {
00454                     pmask_cur[k+j*nx] = CPL_BINARY_0 ;
00455                 }
00456             }
00457         }
00458 
00459         /* Convert mask to image */
00460         bpm_cur = cpl_image_new_from_mask(mask_cur) ;
00461         crires_win_flat_config.bpm_nb[i] = cpl_mask_count(mask_cur) ;
00462         cpl_mask_delete(mask_cur) ;
00463         cpl_imagelist_set(bpm, bpm_cur, i) ;
00464 
00465         /* Set the flat to 1 outside of the bounds */
00466         if (crires_win_flat_config.replace_flag) {
00467             cpl_image_threshold(cpl_imagelist_get(flat, i),
00468                     low, high, 1.0, 1.0) ;
00469         }
00470     }
00471     return bpm ;
00472 }
00473 
00474 /*----------------------------------------------------------------------------*/
00484 /*----------------------------------------------------------------------------*/
00485 static int crires_win_flat_save(
00486         const cpl_imagelist     *   flat,
00487         const cpl_imagelist     *   bpm,
00488         int                         set_nb,
00489         cpl_frameset            *   set,
00490         const cpl_parameterlist *   parlist,
00491         cpl_frameset            *   set_tot)
00492 {
00493     cpl_propertylist    **  qclists ;
00494     const cpl_frame     *   ref_frame ;
00495     char                *   filename ;
00496     cpl_propertylist    *   inputlist ;
00497     const char          *   recipe_name = "crires_win_flat" ;
00498     int                     i ;
00499 
00500     /* Get the reference frame */
00501     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
00502 
00503     /* Create the QC lists */
00504     qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
00505     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00506         qclists[i] = cpl_propertylist_new() ;
00507         cpl_propertylist_append_int(qclists[i], "ESO QC NBBAD",
00508                 crires_win_flat_config.bpm_nb[i]) ;
00509         cpl_propertylist_append_double(qclists[i], "ESO QC FLAT MEAN",
00510                 crires_win_flat_config.flat_mean[i]) ;
00511         cpl_propertylist_append_double(qclists[i], "ESO QC FLAT STDEV",
00512                 crires_win_flat_config.flat_stdev[i]) ;
00513         cpl_propertylist_append_double(qclists[i], "ESO QC FLAT FLUX",
00514                 crires_win_flat_config.flat_flux[i]) ;
00515         cpl_propertylist_append_double(qclists[i], "ESO QC FLAT MASTER RMS",
00516                 crires_win_flat_config.flat_master_rms[i]) ;
00517 
00518         /* Propagate some keywords from input raw frame extensions */
00519         inputlist = cpl_propertylist_load_regexp(
00520                 cpl_frame_get_filename(ref_frame), i+1,
00521                 CRIRES_HEADER_EXT_FORWARD, 0) ;
00522         cpl_propertylist_copy_property_regexp(qclists[i], inputlist, 
00523                 CRIRES_HEADER_EXT_FORWARD, 0) ;
00524         cpl_propertylist_delete(inputlist) ;
00525     }
00526 
00527     /* Write the flat image */
00528     filename = cpl_sprintf("%s_set%02d.fits", recipe_name, set_nb) ;
00529     crires_image_save(set_tot,
00530             parlist,
00531             set, 
00532             flat, 
00533             recipe_name,
00534             CRIRES_CALPRO_FLAT_WIN, 
00535             CRIRES_PROTYPE_FLAT,
00536             CRIRES_ILLUM_FULL_DETECTOR,
00537             NULL,
00538             (const cpl_propertylist**)qclists, 
00539             PACKAGE "/" PACKAGE_VERSION,
00540             filename) ;
00541     cpl_free(filename) ;
00542 
00543     /* Write the BPM */
00544     if (bpm != NULL) {
00545         filename = cpl_sprintf("%s_set%02d_bpm.fits", recipe_name, set_nb) ;
00546         crires_image_save(set_tot,
00547                 parlist,
00548                 set, 
00549                 bpm, 
00550                 recipe_name,
00551                 CRIRES_CALPRO_BPM_WIN, 
00552                 CRIRES_PROTYPE_BPM,
00553                 CRIRES_ILLUM_FULL_DETECTOR,
00554                 NULL,
00555                 (const cpl_propertylist**)qclists, 
00556                 PACKAGE "/" PACKAGE_VERSION,
00557                 filename) ;
00558         cpl_free(filename) ;
00559     }
00560 
00561     /* Free and return */
00562     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00563         cpl_propertylist_delete(qclists[i]) ;
00564     }
00565     cpl_free(qclists) ;
00566     return  0;
00567 }
00568 
00569 /*----------------------------------------------------------------------------*/
00576 /*----------------------------------------------------------------------------*/
00577 static int crires_win_flat_compare(
00578         const cpl_frame   *   frame1,
00579         const cpl_frame   *   frame2)
00580 {
00581     int                     comparison ;
00582     cpl_propertylist    *   plist1 ;
00583     cpl_propertylist    *   plist2 ;
00584     double                  dval1, dval2 ;
00585 
00586     /* Test entries */
00587     if (frame1==NULL || frame2==NULL) return -1 ;
00588 
00589     /* Get property lists */
00590     if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),0))==NULL){
00591         cpl_msg_error(__func__, "getting header from reference frame");
00592         return -1 ;
00593     }
00594     if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),0))==NULL){
00595         cpl_msg_error(__func__, "getting header from reference frame");
00596         cpl_propertylist_delete(plist1) ;
00597         return -1 ;
00598     }
00599 
00600     /* Test status */
00601     if (cpl_error_get_code()) {
00602         cpl_propertylist_delete(plist1) ;
00603         cpl_propertylist_delete(plist2) ;
00604         return -1 ;
00605     }
00606 
00607     comparison = 1 ;
00608 
00609     /* Compare the DIT used */
00610     dval1 = crires_pfits_get_dit(plist1) ;
00611     dval2 = crires_pfits_get_dit(plist2) ;
00612     if (cpl_error_get_code()) {
00613         cpl_msg_error(__func__, "Cannot get the DIT");
00614         cpl_propertylist_delete(plist1) ;
00615         cpl_propertylist_delete(plist2) ;
00616         return -1 ;
00617     }
00618     if (fabs(dval1-dval2) > 1e-3) comparison = 0 ;
00619 
00620     /* Compare the WLEN REF used */
00621     dval1 = crires_pfits_get_refwlen(plist1) ;
00622     dval2 = crires_pfits_get_refwlen(plist2) ;
00623     if (cpl_error_get_code()) {
00624         cpl_msg_error(__func__, "Cannot get the reference wavelength");
00625         cpl_propertylist_delete(plist1) ;
00626         cpl_propertylist_delete(plist2) ;
00627         return -1 ;
00628     }
00629     if (fabs(dval1-dval2) > 1e-3) comparison = 0 ;
00630 
00631     /* Compare the SHUT1 POS used */
00632     dval1 = crires_pfits_get_bafflepos(plist1) ;
00633     dval2 = crires_pfits_get_bafflepos(plist2) ;
00634     if (cpl_error_get_code()) {
00635         cpl_msg_error(__func__, "Cannot get the baffle position");
00636         cpl_propertylist_delete(plist1) ;
00637         cpl_propertylist_delete(plist2) ;
00638         return -1 ;
00639     }
00640     if (fabs(dval1-dval2) > 1e-3) comparison = 0 ;
00641 
00642     cpl_propertylist_delete(plist1) ;
00643     cpl_propertylist_delete(plist2) ;
00644     return comparison ;
00645 }
00646