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