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