CRIRES Pipeline Reference Manual  2.3.3
crires_spec_astro.c
00001 /* 
00002  * This file is part of the CRIRES Pipeline
00003  * Copyright (C) 2002,2003 European Southern Observatory
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023 
00024 /*-----------------------------------------------------------------------------
00025                                 Includes
00026  -----------------------------------------------------------------------------*/
00027 
00028 #include "crires_recipe.h"
00029 
00030 #include "crires_model_kernel.h"
00031 #include "crires_combine.h"
00032 #include "crires_extract.h"
00033 #include "crires_photom.h"
00034 #include "crires_wlcalib.h"
00035 
00036 /*-----------------------------------------------------------------------------
00037                                 Define
00038  -----------------------------------------------------------------------------*/
00039 
00040 #define RECIPE_STRING "crires_spec_astro"
00041 
00042 /*-----------------------------------------------------------------------------
00043                             Functions prototypes
00044  -----------------------------------------------------------------------------*/
00045 
00046 static int crires_spec_astro_compare(const cpl_frame *, const cpl_frame *) ;
00047 static cpl_imagelist ** crires_spec_astro_reduce(cpl_frameset *,
00048         const char *, const char *, const char *, const char *, const char *, 
00049         const char *, const char *, const char *, cpl_imagelist **, 
00050         cpl_imagelist **, cpl_imagelist **, cpl_imagelist **,
00051         cpl_table **, cpl_table **, cpl_table **, cpl_table **) ;
00052 static int crires_spec_astro_save(const cpl_imagelist **,
00053         const cpl_imagelist *, const cpl_imagelist *, const cpl_table **, 
00054         const cpl_imagelist *, const cpl_imagelist *, int, 
00055         const cpl_frameset *, const cpl_parameterlist *, cpl_frameset *) ;
00056 
00057 static char crires_spec_astro_description[] =
00058 "crires_spec_astro -- Astrometry recipe\n"
00059 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00060 "raw-file.fits "CRIRES_SPEC_ASTRO_RAW" or\n"
00061 "flat-file.fits "CRIRES_CALPRO_FLAT" or\n" 
00062 "bpm-file.fits "CRIRES_CALPRO_BPM" or\n" 
00063 "dark-file.fits "CRIRES_CALPRO_DARK" or\n" 
00064 "detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE" or\n" 
00065 "wavecal-file.fits "CRIRES_CALPRO_WAVE" or\n" 
00066 "catalog-file.fits "CRIRES_CALPRO_OH_CAT" or\n" 
00067 "catalog-file.fits "CRIRES_CALPRO_HITRAN_CAT" or\n" 
00068 "model-config-file.fits "CRIRES_CALPRO_MODEL_CONFIG".\n"
00069 "\n"
00070 "The input data set is a series of nodding observations using different\n"
00071 "   derotator position angles. The data are reduced separately for each\n"
00072 "   of those positions. In order not to degrade the instrument high\n"
00073 "   resolution, the combined images using only NODA or NODB nodding\n"
00074 "   positions can be produced on request. (see --onlyA/B)\n"
00075 "   In this case, the following spectrum extraction can be applied \n"
00076 "   either on the usual combined image or on those NODA/B combined\n"
00077 "   images (see --comb_used).\n"
00078 "\n"
00079 "This recipe produces 6 to 11 files per rotation angle:\n"
00080 "   The combined image      (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
00081 "   The contribution map    (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
00082 "   The combined image using only Nodding A frames (optional)\n"
00083 "                           (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
00084 "   The contribution map using only Nodding A frames (optional)\n"
00085 "                           (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
00086 "   The combined image using only Nodding B frames (optional)\n"
00087 "                           (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
00088 "   The contribution map using only Nodding B frames (optional)\n"
00089 "                           (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
00090 "   The table with the extracted spectrum\n"
00091 "                           (PRO TYPE = "CRIRES_PROTYPE_SPEC_WL")\n"
00092 "   The profile image       (PRO TYPE = "CRIRES_PROTYPE_PROFILE")\n"
00093 "   The background map      (PRO TYPE = "CRIRES_PROTYPE_BGD_MAP")\n"
00094 "   The wavelength map      (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n"
00095 "   The wavelength map from the model (optional)\n"
00096 "                           (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n" ;
00097 
00098 CRIRES_RECIPE_DEFINE(crires_spec_astro,
00099         CRIRES_PARAM_WAVES              |
00100         CRIRES_PARAM_DISPLAY            |
00101         CRIRES_PARAM_REFINE             |
00102         CRIRES_PARAM_ONLYA              |
00103         CRIRES_PARAM_ONLYB              |
00104         CRIRES_PARAM_COMB_USED          |
00105         CRIRES_PARAM_BLIND              |
00106         CRIRES_PARAM_HOR_SIZE           |
00107         CRIRES_PARAM_SPEC_HSIZE         |
00108         CRIRES_PARAM_KAPPA              |
00109         CRIRES_PARAM_CLOSING_HSIZE      |
00110         CRIRES_PARAM_CLEAN_RATE         |
00111         CRIRES_PARAM_REJECT             |
00112         CRIRES_PARAM_Y_SPEC_ZONE_CHIP1  |
00113         CRIRES_PARAM_Y_SPEC_ZONE_CHIP2  |
00114         CRIRES_PARAM_Y_SPEC_ZONE_CHIP3  |
00115         CRIRES_PARAM_Y_SPEC_ZONE_CHIP4  |
00116         CRIRES_PARAM_WL_ERROR           |
00117         CRIRES_PARAM_XC_LIMIT           |
00118         CRIRES_PARAM_WL_LOG             |
00119         CRIRES_PARAM_WL_NOLIMIT         |
00120         CRIRES_PARAM_WL_NBSAMPLES       |
00121         CRIRES_PARAM_Y_POS_CHIP1        |
00122         CRIRES_PARAM_Y_POS_CHIP2        |
00123         CRIRES_PARAM_Y_POS_CHIP3        |
00124         CRIRES_PARAM_Y_POS_CHIP4        |
00125         CRIRES_PARAM_Y_WIDTH            |
00126         CRIRES_PARAM_DEGREE             |
00127         CRIRES_PARAM_WL_CLEAN,
00128         "Astrometry recipe",
00129         crires_spec_astro_description) ;
00130 
00131 /*-----------------------------------------------------------------------------
00132                             Static variables
00133  -----------------------------------------------------------------------------*/
00134 
00135 static struct {
00136     /* Inputs */
00137     int                 comb_blind ;
00138     int                 comb_refine ;
00139     int                 comb_onlyA ;
00140     int                 comb_onlyB ;
00141     crires_comb_method  comb_used ;
00142     double              wstart[CRIRES_NB_DETECTORS] ;
00143     double              wstop[CRIRES_NB_DETECTORS] ;
00144     int                 wl_nolimit ;
00145     int                 wl_log ;
00146     const char      *   wl_ypos_c1 ;
00147     const char      *   wl_ypos_c2 ;
00148     const char      *   wl_ypos_c3 ;
00149     const char      *   wl_ypos_c4 ;
00150     int                 wl_width ;
00151     double              wl_fwhm ;
00152     double              wl_slitw ;
00153     int                 wl_degree ;
00154     double              wl_err ;
00155     int                 wl_samples ;
00156     int                 wl_clean ;
00157     double              wl_xclimit ;
00158     int                 wl_ppm ;
00159     int                 extr_box_hor_size ;
00160     int                 extr_spec_hsize ;
00161     double              extr_kappa ;
00162     int                 extr_closing_hs ;
00163     int                 extr_clean_rate ;
00164     int                 extr_rej_left ;
00165     int                 extr_rej_right ;
00166     const char      *   extr_y_spec_zone_c1 ;
00167     const char      *   extr_y_spec_zone_c2 ;
00168     const char      *   extr_y_spec_zone_c3 ;
00169     const char      *   extr_y_spec_zone_c4 ;
00170     int                 extr_spec_stopy ;
00171     int                 display ;
00172     /* Outputs */
00173     crires_illum_period period ;
00174     int                 qc_specpos[CRIRES_NB_DETECTORS] ;
00175     int                 qc_specwrec[CRIRES_NB_DETECTORS] ;
00176     int                 qc_specwopt[CRIRES_NB_DETECTORS] ;
00177     double              qc_specoptmed[CRIRES_NB_DETECTORS] ;
00178     double              qc_s2nmed[CRIRES_NB_DETECTORS] ;
00179     double              qc_wlxc[CRIRES_NB_DETECTORS] ;
00180     double              qc_wlcent[CRIRES_NB_DETECTORS] ;
00181     double              qc_wldisp[CRIRES_NB_DETECTORS] ;
00182     double              qc_fwhm_comb_pix[CRIRES_NB_DETECTORS] ;
00183     double              qc_fwhm_comb_as[CRIRES_NB_DETECTORS] ;
00184     double              qc_fwhm_prof_pix[CRIRES_NB_DETECTORS] ;
00185     double              qc_fwhm_prof_as[CRIRES_NB_DETECTORS] ;
00186     double              qc_fwhm_diff[CRIRES_NB_DETECTORS] ;
00187 } crires_spec_astro_config ;
00188 
00189 /*-----------------------------------------------------------------------------
00190                                 Functions code
00191  -----------------------------------------------------------------------------*/
00192 
00193 /*----------------------------------------------------------------------------*/
00200 /*----------------------------------------------------------------------------*/
00201 static int crires_spec_astro(
00202         cpl_frameset            *   frameset,
00203         const cpl_parameterlist *   parlist)
00204 {
00205     cpl_frameset    *   raw_one ;
00206     const char      *   sval ;
00207     cpl_frameset    *   rawframes ;
00208     const char      *   flat ;
00209     const char      *   dark ;
00210     const char      *   bpm ;
00211     const char      *   detlin ;
00212     const char      *   wavecal ;
00213     const char      *   oh_cat ;
00214     const char      *   hitran_cat ;
00215     const char      *   cfg_model ;
00216     cpl_size        *   labels ;
00217     cpl_size            nlabels ;
00218     cpl_imagelist   **  comblist ;
00219     cpl_table       *   extr_tab[CRIRES_NB_DETECTORS] ;
00220     cpl_imagelist   *   prof_list ;
00221     cpl_imagelist   *   bgmap_list ;
00222     cpl_imagelist   *   wl_map ;
00223     cpl_imagelist   *   wl_map_model ;
00224     int                 i, j ;
00225 
00226     /* Initialise */
00227     rawframes = NULL ;
00228     crires_spec_astro_config.wl_ppm = 0 ;
00229     crires_spec_astro_config.wl_slitw = 2.0 ;
00230     crires_spec_astro_config.wl_fwhm = 2.0 ;
00231 
00232     /* Retrieve input parameters */
00233     crires_spec_astro_config.display = crires_parameterlist_get_int(parlist,
00234             RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
00235     crires_spec_astro_config.comb_refine = crires_parameterlist_get_bool(
00236             parlist, RECIPE_STRING, CRIRES_PARAM_REFINE) ;
00237     crires_spec_astro_config.comb_onlyA = crires_parameterlist_get_bool(
00238             parlist, RECIPE_STRING, CRIRES_PARAM_ONLYA) ;
00239     crires_spec_astro_config.comb_onlyB = crires_parameterlist_get_bool(
00240             parlist, RECIPE_STRING, CRIRES_PARAM_ONLYB) ;
00241     sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
00242             CRIRES_PARAM_COMB_USED) ;
00243     if (!strcmp(sval, "NODA"))
00244         crires_spec_astro_config.comb_used = CRIRES_COMB_METHOD_NODA ;
00245     else if (!strcmp(sval, "NODB"))
00246         crires_spec_astro_config.comb_used = CRIRES_COMB_METHOD_NODB ;
00247     else if (!strcmp(sval, "COMB"))
00248         crires_spec_astro_config.comb_used = CRIRES_COMB_METHOD_COMB ;
00249     else {
00250         cpl_msg_error(__func__, "Invalid combination method specified");
00251         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00252         return -1;
00253     }
00254     crires_spec_astro_config.comb_blind = crires_parameterlist_get_bool(
00255             parlist, RECIPE_STRING, CRIRES_PARAM_BLIND) ;
00256     sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
00257             CRIRES_PARAM_WAVES) ;
00258     if (sscanf(sval, "%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg",
00259                     &crires_spec_astro_config.wstart[0],
00260                     &crires_spec_astro_config.wstop[0],
00261                     &crires_spec_astro_config.wstart[1],
00262                     &crires_spec_astro_config.wstop[1],
00263                     &crires_spec_astro_config.wstart[2],
00264                     &crires_spec_astro_config.wstop[2],
00265                     &crires_spec_astro_config.wstart[3],
00266                     &crires_spec_astro_config.wstop[3])!=2*CRIRES_NB_DETECTORS){
00267         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00268         return -1 ;
00269     }
00270     crires_spec_astro_config.wl_log = crires_parameterlist_get_bool(parlist, 
00271             RECIPE_STRING, CRIRES_PARAM_WL_LOG) ;
00272     crires_spec_astro_config.wl_nolimit = crires_parameterlist_get_bool(
00273             parlist, RECIPE_STRING, CRIRES_PARAM_WL_NOLIMIT) ; 
00274     crires_spec_astro_config.wl_degree = crires_parameterlist_get_int(parlist, 
00275             RECIPE_STRING, CRIRES_PARAM_DEGREE) ;
00276     crires_spec_astro_config.wl_err = crires_parameterlist_get_double(parlist, 
00277             RECIPE_STRING, CRIRES_PARAM_WL_ERROR) ;
00278     crires_spec_astro_config.wl_xclimit = crires_parameterlist_get_double(
00279             parlist, RECIPE_STRING, CRIRES_PARAM_XC_LIMIT) ;
00280     crires_spec_astro_config.wl_samples = crires_parameterlist_get_int(parlist,
00281             RECIPE_STRING, CRIRES_PARAM_WL_NBSAMPLES) ;
00282     crires_spec_astro_config.wl_clean = crires_parameterlist_get_bool(parlist, 
00283             RECIPE_STRING, CRIRES_PARAM_WL_CLEAN) ;
00284     crires_spec_astro_config.wl_ypos_c1=(char*)crires_parameterlist_get_string(
00285             parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP1) ;
00286     crires_spec_astro_config.wl_ypos_c2=(char*)crires_parameterlist_get_string(
00287             parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP2) ;
00288     crires_spec_astro_config.wl_ypos_c3=(char*)crires_parameterlist_get_string(
00289             parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP3) ;
00290     crires_spec_astro_config.wl_ypos_c4=(char*)crires_parameterlist_get_string(
00291             parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP4) ;
00292     crires_spec_astro_config.wl_width= crires_parameterlist_get_int(parlist, 
00293             RECIPE_STRING, CRIRES_PARAM_Y_WIDTH) ;
00294     crires_spec_astro_config.extr_box_hor_size = crires_parameterlist_get_int(
00295             parlist, RECIPE_STRING, CRIRES_PARAM_HOR_SIZE) ;
00296     crires_spec_astro_config.extr_spec_hsize = crires_parameterlist_get_int(
00297             parlist, RECIPE_STRING, CRIRES_PARAM_SPEC_HSIZE) ;
00298     crires_spec_astro_config.extr_kappa = crires_parameterlist_get_double(
00299             parlist, RECIPE_STRING, CRIRES_PARAM_KAPPA) ;
00300     crires_spec_astro_config.extr_closing_hs = crires_parameterlist_get_int(
00301             parlist, RECIPE_STRING, CRIRES_PARAM_CLOSING_HSIZE) ;
00302     crires_spec_astro_config.extr_clean_rate = crires_parameterlist_get_double(
00303             parlist, RECIPE_STRING, CRIRES_PARAM_CLEAN_RATE) ;
00304     sval = crires_parameterlist_get_string(parlist, RECIPE_STRING, 
00305             CRIRES_PARAM_REJECT) ;
00306     if (sscanf(sval, "%d,%d",
00307                     &crires_spec_astro_config.extr_rej_left,
00308                     &crires_spec_astro_config.extr_rej_right)!=2) {
00309         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00310         return -1 ;
00311     }
00312     crires_spec_astro_config.extr_y_spec_zone_c1 = 
00313         crires_parameterlist_get_string(parlist, RECIPE_STRING, 
00314             CRIRES_PARAM_Y_SPEC_ZONE_CHIP1) ;
00315     crires_spec_astro_config.extr_y_spec_zone_c2 = 
00316         crires_parameterlist_get_string(parlist, RECIPE_STRING, 
00317             CRIRES_PARAM_Y_SPEC_ZONE_CHIP2) ;
00318     crires_spec_astro_config.extr_y_spec_zone_c3 = 
00319         crires_parameterlist_get_string(parlist, RECIPE_STRING, 
00320             CRIRES_PARAM_Y_SPEC_ZONE_CHIP3) ;
00321     crires_spec_astro_config.extr_y_spec_zone_c4 = 
00322         crires_parameterlist_get_string(parlist, RECIPE_STRING, 
00323             CRIRES_PARAM_Y_SPEC_ZONE_CHIP4) ;
00324 
00325     /* Identify the RAW and CALIB frames in the input frameset */
00326     if (crires_dfs_set_groups(frameset, "crires_spec_astro")) {
00327         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00328         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00329         return -1 ;
00330     }
00331 
00332     /* Retrieve calibration data */
00333     flat        = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT) ;
00334     dark        = crires_extract_filename(frameset, CRIRES_CALPRO_DARK) ;
00335     bpm         = crires_extract_filename(frameset, CRIRES_CALPRO_BPM) ;
00336     detlin      = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ;
00337     wavecal     = crires_extract_filename(frameset, CRIRES_CALPRO_WAVE) ;
00338     oh_cat      = crires_extract_filename(frameset, CRIRES_CALPRO_OH_CAT) ;
00339     hitran_cat  = crires_extract_filename(frameset, CRIRES_CALPRO_HITRAN_CAT) ;
00340     cfg_model   = crires_extract_filename(frameset, CRIRES_CALPRO_MODEL_CONFIG);
00341     
00342     /* Retrieve raw frames */
00343     if ((rawframes = crires_extract_frameset(frameset,
00344                     CRIRES_SPEC_ASTRO_RAW)) == NULL) {
00345         cpl_msg_error(__func__, "No raw frame in input") ;
00346         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00347         return -1 ;
00348     }
00349 
00350     /* Checks on the parameters validity */
00351     if ((crires_spec_astro_config.comb_used == CRIRES_COMB_METHOD_NODA)
00352         && (crires_spec_astro_config.comb_onlyA == 0)) {
00353         cpl_msg_warning(__func__,
00354                 "You forgot to require the NODA image to be produced !") ;
00355         crires_spec_astro_config.comb_onlyA = 1 ;
00356     }
00357     if ((crires_spec_astro_config.comb_used == CRIRES_COMB_METHOD_NODB)
00358         && (crires_spec_astro_config.comb_onlyB == 0)) {
00359         cpl_msg_warning(__func__,
00360                 "You forgot to require the NODB image to be produced !") ;
00361         crires_spec_astro_config.comb_onlyB = 1 ;
00362     }
00363 
00364     /* Get the detector illumination period */
00365     crires_spec_astro_config.period =
00366         crires_get_detector_illum_period(
00367             cpl_frame_get_filename(cpl_frameset_get_position(rawframes, 0))) ;
00368     if (crires_spec_astro_config.period == CRIRES_ILLUM_UNKNOWN) {
00369         cpl_msg_error(__func__,
00370                 "Cannot determine the detector illumination period") ;
00371         cpl_frameset_delete(rawframes) ;
00372         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00373         return -1 ;
00374     } else {
00375         crires_display_detector_illum(crires_spec_astro_config.period) ;
00376     }
00377 
00378     /* Labelise the raw frames with the DROT POSANG */
00379     if ((labels = cpl_frameset_labelise(rawframes, crires_spec_astro_compare,
00380                 &nlabels)) == NULL) {
00381         cpl_msg_error(__func__, "Cannot labelise input frames") ;
00382         cpl_frameset_delete(rawframes) ;
00383         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00384         return -1 ;
00385     }
00386 
00387     /* Loop on the settings */
00388     for (i=0 ; i<(int)nlabels ; i++) {
00389 
00390         /* Initialise */
00391         for (j=0 ; j<CRIRES_NB_DETECTORS ; j++) {
00392             crires_spec_astro_config.qc_specpos[j] = -1 ;
00393             crires_spec_astro_config.qc_specwrec[j] = -1 ;
00394             crires_spec_astro_config.qc_specwopt[j] = -1 ;
00395             crires_spec_astro_config.qc_specoptmed[j] = -1.0 ;
00396             crires_spec_astro_config.qc_s2nmed[j] = -1.0 ;
00397             crires_spec_astro_config.qc_wlxc[j] = -1.0 ;
00398             crires_spec_astro_config.qc_wlcent[j] = -1.0 ;
00399             crires_spec_astro_config.qc_wldisp[j] = -1.0 ;
00400             crires_spec_astro_config.qc_fwhm_comb_pix[j] = -1.0 ;
00401             crires_spec_astro_config.qc_fwhm_comb_as[j] = -1.0 ;
00402             crires_spec_astro_config.qc_fwhm_prof_pix[j] = -1.0 ;
00403             crires_spec_astro_config.qc_fwhm_prof_as[j] = -1.0 ;
00404             crires_spec_astro_config.qc_fwhm_diff[j] = -1.0 ;
00405         }
00406 
00407         /* Get the frames for the current setting */
00408         raw_one = cpl_frameset_extract(rawframes, labels, (cpl_size)i) ;
00409 
00410         /* Reduce data set nb i */
00411         cpl_msg_info(__func__, "Reduce data set %d / %"CPL_SIZE_FORMAT, 
00412                 i+1, nlabels);
00413         cpl_msg_indent_more() ;
00414 
00415         /* Apply the reduction */
00416         if ((comblist = crires_spec_astro_reduce(raw_one, flat, dark, bpm, 
00417                 detlin, wavecal, oh_cat, hitran_cat, cfg_model,
00418                 &wl_map,
00419                 &wl_map_model,
00420                 &prof_list,
00421                 &bgmap_list,
00422                 &(extr_tab[0]),
00423                 &(extr_tab[1]),
00424                 &(extr_tab[2]),
00425                 &(extr_tab[3]))) == NULL) {
00426             cpl_msg_error(__func__, "Cannot reduce setting") ;
00427             cpl_frameset_delete(rawframes) ;
00428             cpl_frameset_delete(raw_one) ;
00429             cpl_free(labels) ;
00430             cpl_msg_indent_less() ;
00431             return -1 ;
00432         }
00433         
00434         /* Save the product */
00435         cpl_msg_info(__func__, "Save the products") ;
00436         cpl_msg_indent_more() ;
00437         if (crires_spec_astro_save((const cpl_imagelist **)comblist, 
00438                     prof_list, bgmap_list,
00439                     (const cpl_table **)extr_tab, wl_map, wl_map_model,
00440                     i+1, raw_one, parlist, frameset)) {
00441             cpl_msg_error(__func__, "Cannot save the product") ;
00442             cpl_imagelist_delete(comblist[0]) ;
00443             cpl_imagelist_delete(comblist[1]) ;
00444             if (crires_spec_astro_config.comb_onlyA) {
00445                 cpl_imagelist_delete(comblist[2]) ;
00446                 cpl_imagelist_delete(comblist[3]) ;
00447             }
00448             if (crires_spec_astro_config.comb_onlyB) {
00449                 cpl_imagelist_delete(comblist[4]) ;
00450                 cpl_imagelist_delete(comblist[5]) ;
00451             }
00452             cpl_free(comblist) ;
00453             cpl_imagelist_delete(prof_list) ;
00454             cpl_imagelist_delete(bgmap_list) ;
00455             for (j=0 ; j<CRIRES_NB_DETECTORS ; j++) 
00456                 if (extr_tab[j] != NULL) cpl_table_delete(extr_tab[j]) ;
00457             cpl_imagelist_delete(wl_map) ;
00458             if (wl_map_model) cpl_imagelist_delete(wl_map_model) ;
00459             cpl_frameset_delete(raw_one) ;
00460             cpl_frameset_delete(rawframes) ;
00461             cpl_free(labels) ;
00462             cpl_msg_indent_less() ;
00463             return -1 ;
00464         }
00465         cpl_imagelist_delete(comblist[0]) ;
00466         cpl_imagelist_delete(comblist[1]) ;
00467         if (crires_spec_astro_config.comb_onlyA) {
00468             cpl_imagelist_delete(comblist[2]) ;
00469             cpl_imagelist_delete(comblist[3]) ;
00470         }
00471         if (crires_spec_astro_config.comb_onlyB) {
00472             cpl_imagelist_delete(comblist[4]) ;
00473             cpl_imagelist_delete(comblist[5]) ;
00474         }
00475         cpl_free(comblist) ;
00476         cpl_imagelist_delete(prof_list) ;
00477         cpl_imagelist_delete(bgmap_list) ;
00478         for (j=0 ; j<CRIRES_NB_DETECTORS ; j++) 
00479             if (extr_tab[j] != NULL) cpl_table_delete(extr_tab[j]) ;
00480         cpl_imagelist_delete(wl_map) ;
00481         if (wl_map_model) cpl_imagelist_delete(wl_map_model) ;
00482         cpl_frameset_delete(raw_one) ;
00483         cpl_msg_indent_less() ;
00484     }
00485     cpl_frameset_delete(rawframes) ;
00486     cpl_free(labels) ;
00487 
00488     /* Here comes the postprocessing on the 180 degrees difference spectra */
00489 
00490 
00491     
00492 
00493     /* Return */
00494     if (cpl_error_get_code()) return -1 ;
00495     else return 0 ;
00496 }
00497 
00498 /*----------------------------------------------------------------------------*/
00503 /*----------------------------------------------------------------------------*/
00504 static cpl_imagelist ** crires_spec_astro_reduce(
00505         cpl_frameset            *   rawframes,
00506         const char              *   flat,
00507         const char              *   dark,
00508         const char              *   bpm,
00509         const char              *   detlin,
00510         const char              *   wavecal,
00511         const char              *   oh_cat,
00512         const char              *   hitran_cat,
00513         const char              *   cfg_model,
00514         cpl_imagelist           **  wl_map,
00515         cpl_imagelist           **  wl_map_model,
00516         cpl_imagelist           **  prof_list,
00517         cpl_imagelist           **  bgmap_list,
00518         cpl_table               **  extr_tab1,
00519         cpl_table               **  extr_tab2,
00520         cpl_table               **  extr_tab3,
00521         cpl_table               **  extr_tab4)
00522 {
00523     cpl_frame           *   fr ;
00524     const char          *   fname ;
00525     const char          *   wl_ypos ;
00526     const char          *   y_pos ;
00527     cpl_propertylist    *   plist ;
00528     double                  wmin, wmax ;
00529     double                  tot_ndit ;
00530     cpl_imagelist       **  comblist ;
00531     int                     comblist_offset ;
00532     cpl_table           *   wave_tab[CRIRES_NB_DETECTORS] ;
00533     cpl_image           *   profiles[CRIRES_NB_DETECTORS] ;
00534     cpl_image           *   bg_maps[CRIRES_NB_DETECTORS] ;
00535     cpl_imagelist       *   wl_map_loc ;
00536     cpl_imagelist       *   wl_map_model_loc ;
00537     cpl_imagelist       *   prof_list_loc ;
00538     cpl_imagelist       *   bgmap_list_loc ;
00539     cpl_table           *   extr_tab[CRIRES_NB_DETECTORS] ;
00540     cpl_vector          **  wavelengths ;
00541     cpl_vector          *   wave_ypos ;
00542     int                     pix ;
00543     int                     extr_spec_stopy, extr_spec_starty ;
00544     int                     i, j ;
00545 
00546     /* Set comblist_offset */
00547     if (crires_spec_astro_config.comb_used == CRIRES_COMB_METHOD_COMB)
00548         comblist_offset = 0 ;
00549     else if (crires_spec_astro_config.comb_used == CRIRES_COMB_METHOD_NODA)
00550         comblist_offset = 1 ;
00551     else if (crires_spec_astro_config.comb_used == CRIRES_COMB_METHOD_NODB)
00552         comblist_offset = 2 ;
00553  
00554     /* Get the total number of NDIT */
00555     fr = cpl_frameset_get_position(rawframes, 0);
00556     tot_ndit = crires_get_totndit(cpl_frame_get_filename(fr)) ;
00557     if (tot_ndit < 0) {
00558         cpl_msg_error(__func__, "Cannot get the total number of NDIT") ;
00559         return NULL ;
00560     }
00561     tot_ndit *= cpl_frameset_get_size(rawframes) ;
00562     
00563     /* Images recombination */
00564     cpl_msg_info(__func__, "Images combination") ;
00565     cpl_msg_indent_more() ;
00566     if ((comblist = crires_combine_imagelist(rawframes, NULL,
00567                     crires_spec_astro_config.period,
00568                     flat, dark, bpm, detlin, 1,
00569                     crires_spec_astro_config.comb_blind,
00570                     crires_spec_astro_config.comb_refine,
00571                     crires_spec_astro_config.comb_onlyA,
00572                     crires_spec_astro_config.comb_onlyB)) == NULL) {
00573         cpl_msg_error(__func__, "Cannot combine the images") ;
00574         cpl_msg_indent_less() ;
00575         return NULL ;
00576     }
00577     cpl_msg_indent_less() ;
00578 
00579     /* Spectrum extraction */
00580     cpl_msg_info(__func__, "Spectrum extraction") ;
00581     cpl_msg_indent_more() ;
00582     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00583         cpl_msg_info(__func__, "Chip number %d extraction", i+1) ;
00584         cpl_msg_indent_more() ;
00585 
00586         /* Where is the spectrum extraction zone ? */
00587         y_pos = "" ;
00588         if (i+1 == 1) y_pos = crires_spec_astro_config.extr_y_spec_zone_c1 ;
00589         if (i+1 == 2) y_pos = crires_spec_astro_config.extr_y_spec_zone_c1 ;
00590         if (i+1 == 3) y_pos = crires_spec_astro_config.extr_y_spec_zone_c3 ;
00591         if (i+1 == 4) y_pos = crires_spec_astro_config.extr_y_spec_zone_c4 ;
00592         if (sscanf(y_pos,"%d,%d", &extr_spec_starty, &extr_spec_stopy)!=2) {
00593             cpl_msg_warning(__func__, "Wrong Spectral Zone specified: %s",
00594                     y_pos) ;
00595             extr_spec_starty = extr_spec_stopy = -1 ;
00596         }
00597 
00598         /* Extraction */
00599         if ((extr_tab[i] = crires_extract_spectrum(
00600                         cpl_imagelist_get(comblist[0+2*comblist_offset], i),
00601                         cpl_imagelist_get(comblist[1+2*comblist_offset], i),
00602                         crires_spec_astro_config.extr_box_hor_size,
00603                         crires_spec_astro_config.extr_spec_hsize,
00604                         crires_spec_astro_config.extr_kappa,
00605                         crires_spec_astro_config.extr_closing_hs,
00606                         crires_spec_astro_config.extr_clean_rate,
00607                         crires_spec_astro_config.extr_rej_left,
00608                         crires_spec_astro_config.extr_rej_right,
00609                         extr_spec_starty, extr_spec_stopy,
00610                         i+1,
00611                         tot_ndit,
00612                         crires_spec_astro_config.period,
00613                         &(crires_spec_astro_config.qc_specpos[i]),
00614                         &(crires_spec_astro_config.qc_specwrec[i]),
00615                         &(crires_spec_astro_config.qc_specwopt[i]),
00616                         &(crires_spec_astro_config.qc_specoptmed[i]),
00617                         &(crires_spec_astro_config.qc_s2nmed[i]),
00618                         &(profiles[i]),
00619                         &(bg_maps[i]))) == NULL) {
00620             cpl_msg_error(__func__, "Cannot extract the spectrum") ;
00621             cpl_msg_indent_less() ;
00622             cpl_msg_indent_less() ;
00623             for (j=0 ; j<i ; j++) 
00624                 cpl_table_delete(extr_tab[j]) ;
00625             for (j=0 ; j<i ; j++) 
00626                 cpl_image_delete(profiles[j]) ;
00627             for (j=0 ; j<i ; j++) 
00628                 cpl_image_delete(bg_maps[j]) ;
00629             cpl_imagelist_delete(comblist[0]) ;
00630             cpl_imagelist_delete(comblist[1]) ;
00631             if (crires_spec_astro_config.comb_onlyA) {
00632                 cpl_imagelist_delete(comblist[2]) ;
00633                 cpl_imagelist_delete(comblist[3]) ;
00634             }
00635             if (crires_spec_astro_config.comb_onlyB) {
00636                 cpl_imagelist_delete(comblist[4]) ;
00637                 cpl_imagelist_delete(comblist[5]) ;
00638             }
00639             cpl_free(comblist) ;
00640             return NULL ;
00641         }
00642         cpl_msg_info(__func__, "Chip number %d FWHM Computation", i+1) ;
00643         if (crires_extract_qc_fwhm(
00644                     cpl_imagelist_get(comblist[0+2*comblist_offset], i),
00645                     profiles[i],
00646                     &(crires_spec_astro_config.qc_fwhm_comb_pix[i]),
00647                     &(crires_spec_astro_config.qc_fwhm_comb_as[i]),
00648                     &(crires_spec_astro_config.qc_fwhm_prof_pix[i]),
00649                     &(crires_spec_astro_config.qc_fwhm_prof_as[i]),
00650                     &(crires_spec_astro_config.qc_fwhm_diff[i])) == -1) {
00651             cpl_msg_warning(__func__, "Failed for FWHM computation") ;
00652             crires_spec_astro_config.qc_fwhm_comb_pix[i] = -1.0 ;
00653             crires_spec_astro_config.qc_fwhm_comb_as[i] = -1.0 ;
00654             crires_spec_astro_config.qc_fwhm_prof_pix[i] = -1.0 ;
00655             crires_spec_astro_config.qc_fwhm_prof_as[i] = -1.0 ;
00656             crires_spec_astro_config.qc_fwhm_diff[i] = -1.0 ;
00657         }
00658         cpl_msg_indent_less() ;
00659     }
00660    
00661     /* Create the profile and bg maps */
00662     prof_list_loc = cpl_imagelist_new() ;
00663     bgmap_list_loc = cpl_imagelist_new() ;
00664     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00665         cpl_imagelist_set(prof_list_loc, profiles[i], i) ;
00666         cpl_imagelist_set(bgmap_list_loc, bg_maps[i], i) ;
00667     }
00668   
00669     /* Test that the spectrum is at the same place in all detectors */
00670     for (i=1 ; i<CRIRES_NB_DETECTORS ; i++) {
00671         if (crires_spec_astro_config.qc_specpos[i-1] > 0 && 
00672                 crires_spec_astro_config.qc_specpos[i] > 0 &&
00673                 fabs(crires_spec_astro_config.qc_specpos[i-1] -
00674                     crires_spec_astro_config.qc_specpos[i]) > 
00675                 CRIRES_SPEC_POS_TOLERANCE) {
00676             cpl_msg_warning(__func__,
00677     "The spectrum positions in chip %d and chip %d are too different: %d -> %d",
00678                     i, i+1, crires_spec_astro_config.qc_specpos[i-1], 
00679                     crires_spec_astro_config.qc_specpos[i]) ;
00680         }
00681     }
00682     cpl_msg_indent_less() ;
00683 
00684     /* Wavelength calibration */
00685     cpl_msg_info(__func__, "Wavelength Calibration") ;
00686     cpl_msg_indent_more() ;
00687     if (wavecal != NULL) {
00688         /* Wavelength solution is provided */
00689         cpl_msg_info(__func__, "Use the provided solution") ;
00690         for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00691             if ((wave_tab[i] = crires_load_table_check(wavecal, i+1,
00692                             CRIRES_PROTYPE_WL_POLY, -1, -1, 0)) == NULL) {
00693                 cpl_msg_error(__func__, "Cannot load the wavelength table") ;
00694                 cpl_msg_indent_less() ;
00695                 cpl_imagelist_delete(comblist[0]) ;
00696                 cpl_imagelist_delete(comblist[1]) ;
00697                 if (crires_spec_astro_config.comb_onlyA) {
00698                     cpl_imagelist_delete(comblist[2]) ;
00699                     cpl_imagelist_delete(comblist[3]) ;
00700                 }
00701                 if (crires_spec_astro_config.comb_onlyB) {
00702                     cpl_imagelist_delete(comblist[4]) ;
00703                     cpl_imagelist_delete(comblist[5]) ;
00704                 }
00705                 cpl_free(comblist) ;
00706                 cpl_imagelist_delete(prof_list_loc) ;
00707                 cpl_imagelist_delete(bgmap_list_loc) ;
00708                 for (j=0 ; j<CRIRES_NB_DETECTORS ; j++)
00709                     cpl_table_delete(extr_tab[j]) ;
00710                 return NULL ;
00711             }
00712         }
00713     } else {
00714         /* Calibrate from the science */
00715         cpl_msg_info(__func__, "Use the science frame sky to calibrate") ;
00716 
00717         /* first raw frame */
00718         fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
00719 
00720         /* Get the Minimum and Maximum wavelengths */
00721         if (crires_spec_astro_config.wl_nolimit == 0) {
00722             plist = cpl_propertylist_load(fname, 0) ;
00723             wmin = crires_pfits_get_wlen_min(plist) ;
00724             wmax = crires_pfits_get_wlen_max(plist) ;
00725             cpl_propertylist_delete(plist) ;
00726             if (cpl_error_get_code()) {
00727                 wmin = wmax = -1.0 ;
00728                 cpl_error_reset() ;
00729             }
00730         } else {
00731             wmin = wmax = -1.0 ;
00732         }
00733 
00734         /* Loop on detectors */
00735         for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00736                     cpl_msg_info(__func__, "Calibrate chip number %d", i+1) ;
00737             cpl_msg_indent_more() ;
00738 
00739             /* Where Compute the wavelength from ? */
00740             if (i+1 == 1) wl_ypos = crires_spec_astro_config.wl_ypos_c1 ;
00741             if (i+1 == 2) wl_ypos = crires_spec_astro_config.wl_ypos_c2 ;
00742             if (i+1 == 3) wl_ypos = crires_spec_astro_config.wl_ypos_c3 ;
00743             if (i+1 == 4) wl_ypos = crires_spec_astro_config.wl_ypos_c4 ;
00744 
00745             if (!strcmp(wl_ypos, "")) {
00746                 /* Use the spectrum position for the wavelength calibration */
00747                 cpl_msg_info(__func__, 
00748                         "Compute the wavelength at the spectrum position: %d",
00749                         crires_spec_astro_config.qc_specpos[i]) ;
00750                 wave_ypos = cpl_vector_new(1) ;
00751                 cpl_vector_set(wave_ypos, 0, 
00752                         (double)(crires_spec_astro_config.qc_specpos[i])) ;
00753             } else {
00754                 cpl_msg_info(__func__, 
00755                         "Use the Y positions provided on the command line") ;
00756                 if ((wave_ypos = crires_parse_y_positions(wl_ypos)) == NULL) {
00757                     cpl_msg_error(__func__, 
00758                             "Cannot parse the y_pos value : %s - use %d",
00759                             wl_ypos, crires_spec_astro_config.qc_specpos[i]) ;
00760                     wave_ypos = cpl_vector_new(1) ;
00761                     cpl_vector_set(wave_ypos, 0,
00762                             (double)(crires_spec_astro_config.qc_specpos[i])) ;
00763                 }
00764             }
00765 
00766             /* Wavelength Calibration */
00767             wave_tab[i] = crires_wlcalib_sky(fname,
00768                     crires_spec_astro_config.period,
00769                     oh_cat, hitran_cat, crires_spec_astro_config.wl_log, 
00770                     flat, dark, bpm, detlin,
00771                     crires_spec_astro_config.wstart[i],
00772                     crires_spec_astro_config.wstop[i],
00773                     wmin, wmax, i+1,
00774                     wave_ypos,
00775                     crires_spec_astro_config.wl_width,
00776                     crires_spec_astro_config.wl_degree,
00777                     crires_spec_astro_config.wl_slitw,
00778                     crires_spec_astro_config.wl_fwhm,
00779                     crires_spec_astro_config.wl_err,
00780                     crires_spec_astro_config.wl_samples,
00781                     crires_spec_astro_config.wl_clean,
00782                     crires_spec_astro_config.wl_xclimit,
00783                     crires_spec_astro_config.wl_ppm,
00784                     (i+1==crires_spec_astro_config.display)) ;
00785             cpl_msg_indent_less() ;
00786         
00787             cpl_vector_delete(wave_ypos) ;
00788         }
00789     }
00790 
00791     /* Create the wave map */
00792     if ((wl_map_loc = crires_wlcalib_gen_wlmap((const cpl_table **)wave_tab)) 
00793             == NULL) {
00794         cpl_msg_error(__func__, "Cannot compute the Wavelength Map") ;
00795         cpl_imagelist_delete(comblist[0]) ;
00796         cpl_imagelist_delete(comblist[1]) ;
00797         if (crires_spec_astro_config.comb_onlyA) {
00798             cpl_imagelist_delete(comblist[2]) ;
00799             cpl_imagelist_delete(comblist[3]) ;
00800         }
00801         if (crires_spec_astro_config.comb_onlyB) {
00802             cpl_imagelist_delete(comblist[4]) ;
00803             cpl_imagelist_delete(comblist[5]) ;
00804         }
00805         cpl_free(comblist) ;
00806         cpl_imagelist_delete(prof_list_loc) ;
00807         cpl_imagelist_delete(bgmap_list_loc) ;
00808         for (j=0 ; j<CRIRES_NB_DETECTORS ; j++) {
00809             cpl_table_delete(extr_tab[j]) ;
00810             if (wave_tab[j] != NULL) cpl_table_delete(wave_tab[j]);
00811         }
00812         return NULL ;
00813     }
00814 
00815     /* Compute the QC parameters */
00816     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00817         crires_spec_astro_config.qc_wlcent[i] =
00818             cpl_image_get(cpl_imagelist_get(wl_map_loc, i), 
00819                     512, crires_spec_astro_config.qc_specpos[i], &pix) ;
00820         crires_spec_astro_config.qc_wldisp[i] =
00821             ((cpl_image_get(cpl_imagelist_get(wl_map_loc, i), 1024, 
00822                             crires_spec_astro_config.qc_specpos[i], &pix)) -
00823              (cpl_image_get(cpl_imagelist_get(wl_map_loc, i), 1, 
00824                             crires_spec_astro_config.qc_specpos[i], &pix))) 
00825             / 1023 ;
00826         crires_spec_astro_config.qc_wlxc[i] = 
00827             crires_wlcalib_get_better_xc(wave_tab[i]) ;
00828     }
00829     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) 
00830         if (wave_tab[i] != NULL) cpl_table_delete(wave_tab[i]);
00831 
00832     /* Get the wl map from the model */
00833     fname  = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
00834     if ((cfg_model != NULL) && (!crires_model_off()) && 
00835             (crires_model_config_check(cfg_model, fname) == 0)) {
00836         cpl_msg_info(__func__, "Call the model to get the wavelength map") ;
00837         cpl_msg_indent_more() ;
00838         wl_map_model_loc = crires_model_wavpix(fname, cfg_model, -1) ;
00839         if (wl_map_model_loc == NULL) {
00840             cpl_msg_warning(__func__, "Model function returns NULL") ;
00841             cpl_error_reset() ;
00842         }
00843         cpl_msg_indent_less() ;
00844     } else {
00845         wl_map_model_loc = NULL ;
00846     }
00847 
00848     /* Apply the wavelength */
00849     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00850         cpl_table_new_column(extr_tab[i], CRIRES_COL_WAVELENGTH, 
00851                 CPL_TYPE_DOUBLE) ;
00852         for (j=0 ; j<cpl_table_get_nrow(extr_tab[i]) ; j++) {
00853             cpl_table_set_double(extr_tab[i], CRIRES_COL_WAVELENGTH, j, 
00854                 cpl_image_get(cpl_imagelist_get_const(wl_map_loc, i), j+1, 
00855                     crires_spec_astro_config.qc_specpos[i], &pix));
00856         }
00857     }
00858 
00859     /* Add the Model Wavelength and Call the model to fill it */
00860     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00861         cpl_table_new_column(extr_tab[i], CRIRES_COL_WAVELENGTH_MODEL, 
00862                 CPL_TYPE_DOUBLE) ;
00863         cpl_table_fill_column_window_double(extr_tab[i],
00864                 CRIRES_COL_WAVELENGTH_MODEL, 0,
00865                 cpl_table_get_nrow(extr_tab[i]), -1.0) ;
00866     }
00867     if ((cfg_model != NULL) && (!crires_model_off()) && (1)) {
00868         cpl_msg_info(__func__, "Call the model to get the wavelengths") ;
00869         cpl_msg_indent_more() ;
00870         wavelengths = crires_model_wavelengths(
00871                 cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)),
00872                 cfg_model, -1,
00873                 (double)(crires_spec_astro_config.qc_specpos[0]),
00874                 wl_map_model_loc) ;
00875         if (wavelengths != NULL) {
00876             /* Loop on the detectors */
00877             for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00878                 /* Loop on the x values */
00879                 for (j=0 ; j<cpl_vector_get_size(wavelengths[i]) ; j++) {
00880                     cpl_table_set_double(extr_tab[i], 
00881                             CRIRES_COL_WAVELENGTH_MODEL, j, 
00882                             cpl_vector_get(wavelengths[i], j)) ;
00883                 }
00884             }
00885             for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) 
00886                 cpl_vector_delete(wavelengths[i]) ;
00887             cpl_free(wavelengths) ;
00888         } else {
00889             cpl_msg_warning(__func__, "Model function returns NULL") ;
00890             cpl_error_reset() ;
00891         }
00892         cpl_msg_indent_less() ;
00893     }
00894 
00895     /* Return */
00896     if (wl_map != NULL)         *wl_map = wl_map_loc ;
00897     else                        cpl_imagelist_delete(wl_map_loc) ;
00898     if (wl_map_model != NULL)   *wl_map_model = wl_map_model_loc ;
00899     else                        cpl_imagelist_delete(wl_map_model_loc) ;
00900     if (prof_list != NULL)      *prof_list = prof_list_loc ;
00901     else                        cpl_imagelist_delete(prof_list_loc) ;
00902     if (bgmap_list != NULL)     *bgmap_list = bgmap_list_loc ;
00903     else                        cpl_imagelist_delete(bgmap_list_loc) ;
00904     if (extr_tab1 != NULL)      *extr_tab1 = extr_tab[0] ;
00905     else                        cpl_table_delete(extr_tab[0]) ;
00906     if (extr_tab2 != NULL)      *extr_tab2 = extr_tab[1] ;
00907     else                        cpl_table_delete(extr_tab[1]) ;
00908     if (extr_tab3 != NULL)      *extr_tab3 = extr_tab[2] ;
00909     else                        cpl_table_delete(extr_tab[2]) ;
00910     if (extr_tab4 != NULL)      *extr_tab4 = extr_tab[3] ;
00911     else                        cpl_table_delete(extr_tab[3]) ;
00912     return comblist ;
00913 }
00914 
00915 /*----------------------------------------------------------------------------*/
00931 /*----------------------------------------------------------------------------*/
00932 static int crires_spec_astro_save(
00933         const cpl_imagelist     **  images,
00934         const cpl_imagelist     *   prof,
00935         const cpl_imagelist     *   bgmap,
00936         const cpl_table         **  extr_tab,
00937         const cpl_imagelist     *   wl_map,
00938         const cpl_imagelist     *   wl_map_model,
00939         int                         setting,
00940         const cpl_frameset      *   cur_set,
00941         const cpl_parameterlist *   parlist,
00942         cpl_frameset            *   set)
00943 {
00944     cpl_propertylist    **  qclists ;
00945     const cpl_frame     *   ref_frame ;
00946     char                *   filename ;
00947     cpl_propertylist    *   inputlist ;
00948     const char          *   recipe_name = "crires_spec_astro" ;
00949     int                     i ;
00950 
00951     /* Get the reference frame */
00952     ref_frame = irplib_frameset_get_first_from_group(cur_set, 
00953             CPL_FRAME_GROUP_RAW) ;
00954 
00955     /* Create the QC lists */
00956     qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
00957     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00958         qclists[i] = cpl_propertylist_new() ;
00959         cpl_propertylist_append_int(qclists[i], "ESO QC SPECPOS",
00960                 crires_spec_astro_config.qc_specpos[i]) ;
00961         cpl_propertylist_append_int(qclists[i], "ESO QC SPECWREC",
00962                 crires_spec_astro_config.qc_specwrec[i]) ;
00963         cpl_propertylist_append_int(qclists[i], "ESO QC SPECWOPT",
00964                 crires_spec_astro_config.qc_specwopt[i]) ;
00965         cpl_propertylist_append_double(qclists[i], "ESO QC SIGNAL MED",
00966                 crires_spec_astro_config.qc_specoptmed[i]) ;
00967         cpl_propertylist_append_double(qclists[i], "ESO QC S2NMED",
00968                 crires_spec_astro_config.qc_s2nmed[i]) ;
00969         cpl_propertylist_append_double(qclists[i], "ESO QC XCORR",
00970                 crires_spec_astro_config.qc_wlxc[i]) ;
00971         cpl_propertylist_append_double(qclists[i], "ESO QC CENTWL",
00972                 crires_spec_astro_config.qc_wlcent[i]) ;
00973         cpl_propertylist_append_double(qclists[i], "ESO QC DISPWL",
00974                 crires_spec_astro_config.qc_wldisp[i]) ;
00975         cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX COMBINED",
00976                 crires_spec_astro_config.qc_fwhm_comb_pix[i]) ;
00977         cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC COMBINED",
00978                 crires_spec_astro_config.qc_fwhm_comb_as[i]) ;
00979         cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX PROFILE",
00980                 crires_spec_astro_config.qc_fwhm_prof_pix[i]) ;
00981         cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC PROFILE",
00982                 crires_spec_astro_config.qc_fwhm_prof_as[i]) ;
00983         cpl_propertylist_append_double(qclists[i], "ESO QC FWHM DIFF",
00984                 crires_spec_astro_config.qc_fwhm_diff[i]) ;
00985         /* Propagate some keywords from input raw frame extensions */
00986         inputlist = cpl_propertylist_load_regexp(
00987                 cpl_frame_get_filename(ref_frame), i+1,
00988                 CRIRES_HEADER_EXT_FORWARD, 0) ;
00989         cpl_propertylist_copy_property_regexp(qclists[i], inputlist, 
00990                 CRIRES_HEADER_EXT_FORWARD, 0) ;
00991         cpl_propertylist_delete(inputlist) ;
00992     }
00993 
00994     /* Write the combined image */
00995     filename = cpl_sprintf("%s_comb_set%02d.fits", recipe_name, setting) ;
00996     crires_image_save(set,
00997             parlist,
00998             cur_set, 
00999             images[0], 
01000             recipe_name,
01001             CRIRES_ASTRO_COMBINED_IMA, 
01002             CRIRES_PROTYPE_COMBINED,
01003             crires_spec_astro_config.period,
01004             NULL,
01005             (const cpl_propertylist **)qclists, 
01006             PACKAGE "/" PACKAGE_VERSION,
01007             filename) ;
01008     cpl_free(filename) ;
01009 
01010     /* Write the contribution map */
01011     filename = cpl_sprintf("%s_contrib_set%02d.fits", recipe_name, setting) ;
01012     crires_image_save(set,
01013             parlist,
01014             cur_set, 
01015             images[1], 
01016             recipe_name,
01017             CRIRES_ASTRO_CONTRIBUTION_IMA, 
01018             CRIRES_PROTYPE_CONTRIB,
01019             crires_spec_astro_config.period,
01020             NULL,
01021             (const cpl_propertylist **)qclists, 
01022             PACKAGE "/" PACKAGE_VERSION,
01023             filename) ;
01024     cpl_free(filename) ;
01025 
01026     /* Nodded A support */
01027     if (crires_spec_astro_config.comb_onlyA) {
01028         /* Write the combined image */
01029         filename = cpl_sprintf("%s_comb_noddedA_set%02d.fits", 
01030                 recipe_name, setting) ;
01031         crires_image_save(set,
01032                 parlist,
01033                 cur_set,
01034                 images[2],
01035                 recipe_name,
01036                 CRIRES_ASTRO_COMBINED_IMA,
01037                 CRIRES_PROTYPE_COMBINED,
01038                 crires_spec_astro_config.period,
01039                 NULL,
01040                 (const cpl_propertylist **)qclists,
01041                 PACKAGE "/" PACKAGE_VERSION,
01042                 filename) ;
01043         cpl_free(filename) ;
01044 
01045         /* Write the contribution map */
01046         filename = cpl_sprintf("%s_contrib_noddedA_set%02d.fits", 
01047                 recipe_name, setting) ;
01048         crires_image_save(set,
01049                 parlist,
01050                 cur_set,
01051                 images[3],
01052                 recipe_name,
01053                 CRIRES_ASTRO_CONTRIBUTION_IMA,
01054                 CRIRES_PROTYPE_CONTRIB,
01055                 crires_spec_astro_config.period,
01056                 NULL,
01057                 (const cpl_propertylist **)qclists,
01058                 PACKAGE "/" PACKAGE_VERSION,
01059                 filename) ;
01060         cpl_free(filename) ;
01061     }
01062 
01063     /* Nodded B support */
01064     if (crires_spec_astro_config.comb_onlyB) {
01065         /* Write the combined image */
01066         filename = cpl_sprintf("%s_comb_noddedB_set%02d.fits", 
01067                 recipe_name, setting) ;
01068         crires_image_save(set,
01069                 parlist,
01070                 cur_set,
01071                 images[4],
01072                 recipe_name,
01073                 CRIRES_ASTRO_COMBINED_IMA,
01074                 CRIRES_PROTYPE_COMBINED,
01075                 crires_spec_astro_config.period,
01076                 NULL,
01077                 (const cpl_propertylist **)qclists,
01078                 PACKAGE "/" PACKAGE_VERSION,
01079                 filename) ;
01080         cpl_free(filename) ;
01081 
01082         /* Write the contribution map */
01083         filename = cpl_sprintf("%s_contrib_noddedB_set%02d.fits", 
01084                 recipe_name, setting) ;
01085         crires_image_save(set,
01086                 parlist,
01087                 cur_set,
01088                 images[5],
01089                 recipe_name,
01090                 CRIRES_ASTRO_CONTRIBUTION_IMA,
01091                 CRIRES_PROTYPE_CONTRIB,
01092                 crires_spec_astro_config.period,
01093                 NULL,
01094                 (const cpl_propertylist **)qclists,
01095                 PACKAGE "/" PACKAGE_VERSION,
01096                 filename) ;
01097         cpl_free(filename) ;
01098     }
01099 
01100     /* Write the profile image */
01101     filename = cpl_sprintf("%s_prof_set%02d.fits", recipe_name, setting) ;
01102     crires_image_save(set,
01103             parlist,
01104             cur_set, 
01105             prof, 
01106             recipe_name,
01107             CRIRES_ASTRO_EXTRACT_PROFILE_IMA, 
01108             CRIRES_PROTYPE_PROFILE,
01109             crires_spec_astro_config.period,
01110             NULL,
01111             (const cpl_propertylist **)qclists, 
01112             PACKAGE "/" PACKAGE_VERSION,
01113             filename) ;
01114     cpl_free(filename) ;
01115  
01116     /* Write the background image */
01117     filename = cpl_sprintf("%s_bgmap_set%02d.fits", recipe_name, setting) ;
01118     crires_image_save(set,
01119             parlist,
01120             cur_set, 
01121             bgmap, 
01122             recipe_name,
01123             CRIRES_ASTRO_EXTRACT_BGMAP_IMA, 
01124             CRIRES_PROTYPE_BGD_MAP,
01125             crires_spec_astro_config.period,
01126             NULL,
01127             (const cpl_propertylist **)qclists, 
01128             PACKAGE "/" PACKAGE_VERSION,
01129             filename) ;
01130     cpl_free(filename) ;
01131 
01132     /* Write the map */
01133     filename = cpl_sprintf("%s_wlmap_set%02d.fits", recipe_name, setting) ;
01134     crires_image_save(set,
01135             parlist,
01136             cur_set,
01137             wl_map,
01138             recipe_name,
01139             CRIRES_ASTRO_WL_MAP_IMA,
01140             CRIRES_PROTYPE_WL_MAP,
01141             crires_spec_astro_config.period,
01142             NULL,
01143             (const cpl_propertylist **)qclists,
01144             PACKAGE "/" PACKAGE_VERSION,
01145             filename) ;
01146     cpl_free(filename) ;
01147 
01148     if (wl_map_model != NULL) {
01149         /* Write the model map */
01150         filename = cpl_sprintf("%s_wlmap_model_set%02d.fits", recipe_name, 
01151                 setting) ;
01152         crires_image_save(set,
01153                 parlist,
01154                 cur_set,
01155                 wl_map_model,
01156                 recipe_name,
01157                 CRIRES_ASTRO_WL_MAP_MODEL_IMA,
01158                 CRIRES_PROTYPE_WL_MAP,
01159                 crires_spec_astro_config.period,
01160                 NULL,
01161                 (const cpl_propertylist **)qclists,
01162                 PACKAGE "/" PACKAGE_VERSION,
01163                 filename) ;
01164         cpl_free(filename) ;
01165     }
01166     
01167     /* Write the extracted spectra */
01168     filename = cpl_sprintf("%s_extracted_set%02d.fits", recipe_name, setting);
01169     crires_table_save(set, 
01170             parlist, 
01171             cur_set, 
01172             extr_tab, 
01173             recipe_name, 
01174             CRIRES_ASTRO_EXTRACT_WL_TAB, 
01175             CRIRES_PROTYPE_SPEC_WL,
01176             NULL, 
01177             (const cpl_propertylist **)qclists,
01178             PACKAGE "/" PACKAGE_VERSION,
01179             filename) ;
01180     cpl_free(filename) ;
01181 
01182     /* Free and return */
01183     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
01184         cpl_propertylist_delete(qclists[i]) ;
01185     }
01186     cpl_free(qclists) ;
01187     return  0;
01188 }
01189 
01190 /*----------------------------------------------------------------------------*/
01197 /*----------------------------------------------------------------------------*/
01198 static int crires_spec_astro_compare(
01199         const cpl_frame   *   frame1,
01200         const cpl_frame   *   frame2)
01201 {
01202     int                     comparison ;
01203     cpl_propertylist    *   plist1 ;
01204     cpl_propertylist    *   plist2 ;
01205     double                  dval1, dval2 ;
01206     int                     ival1, ival2 ;
01207 
01208     /* Test entries */
01209     if (frame1==NULL || frame2==NULL) return -1 ;
01210 
01211     /* Get property lists */
01212     if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),0))==NULL){
01213         cpl_msg_error(__func__, "getting header from reference frame");
01214         return -1 ;
01215     }
01216     if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),0))==NULL){
01217         cpl_msg_error(__func__, "getting header from reference frame");
01218         cpl_propertylist_delete(plist1) ;
01219         return -1 ;
01220     }
01221 
01222     /* Test status */
01223     if (cpl_error_get_code()) {
01224         cpl_propertylist_delete(plist1) ;
01225         cpl_propertylist_delete(plist2) ;
01226         return -1 ;
01227     }
01228 
01229     comparison = 1 ;
01230 
01231     /* Compare the DROT POSANG used */
01232     dval1 = crires_pfits_get_dit(plist1) ;
01233     dval2 = crires_pfits_get_dit(plist2) ;
01234     if (cpl_error_get_code()) {
01235         cpl_msg_error(__func__, "Cannot get the POSANG");
01236         cpl_propertylist_delete(plist1) ;
01237         cpl_propertylist_delete(plist2) ;
01238         return -1 ;
01239     }
01240     if (fabs(dval1-dval2) > 1e-3) comparison = 0 ;
01241 
01242     /* Check if the frames are consecutive */
01243     ival1 = crires_pfits_get_expno(plist1) ;
01244     ival2 = crires_pfits_get_expno(plist2) ;
01245     if (cpl_error_get_code()) {
01246         cpl_msg_error(__func__, "Cannot get the EXPNO");
01247         cpl_propertylist_delete(plist1) ;
01248         cpl_propertylist_delete(plist2) ;
01249         return -1 ;
01250     }
01251     if (fabs(ival2-ival1) != 1.0) comparison = 0 ;
01252 
01253     cpl_propertylist_delete(plist1) ;
01254     cpl_propertylist_delete(plist2) ;
01255     return comparison ;
01256 }