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