CRIRES Pipeline Reference Manual  2.3.3
crires_win_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 #include "crires_wlestimate.h"
00036 
00037 /*-----------------------------------------------------------------------------
00038                                 Define
00039  -----------------------------------------------------------------------------*/
00040 
00041 #define RECIPE_STRING "crires_win_jitter"
00042 
00043 /*-----------------------------------------------------------------------------
00044                             Functions prototypes
00045  -----------------------------------------------------------------------------*/
00046 
00047 static int crires_win_jitter_save(const cpl_imagelist **,
00048         const cpl_imagelist *, const cpl_imagelist *, const cpl_table **, 
00049         const cpl_imagelist *, const cpl_imagelist *, 
00050         const cpl_parameterlist *, cpl_frameset *) ;
00051 
00052 static char crires_win_jitter_description[] =
00053 "crires_win_jitter -- Observation recipe in Windowing mode\n"
00054 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00055 "   raw-file.fits "CRIRES_WIN_NODDING_OBJECT_RAW" or\n"
00056 "   raw-file.fits "CRIRES_WIN_NODDING_SKY_RAW" or\n"
00057 "   raw-file.fits "CRIRES_WIN_NODDING_RAW" or\n"
00058 "   raw-file.fits "CRIRES_WIN_NODDING_J_RAW" or\n"
00059 "   raw-file.fits "CRIRES_WIN_NODDING_STD_RAW" or\n"
00060 "   raw-file.fits "CRIRES_WIN_NODDING_J_STD_RAW" or\n"
00061 "   flat-file.fits "CRIRES_CALPRO_FLAT_WIN" or\n" 
00062 "   bpm-file.fits "CRIRES_CALPRO_BPM_WIN" or\n" 
00063 "   detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE" or\n" 
00064 "   dark-file.fits "CRIRES_CALPRO_DARK_WIN" or\n" 
00065 "   wavecal-file.fits "CRIRES_CALPRO_WAVE" or\n" 
00066 "   stdstar-file.fits "CRIRES_CALPRO_STD_PHOTOFLUX" or\n"
00067 "   model-config-file.fits "CRIRES_CALPRO_MODEL_CONFIG".\n"
00068 "\n"
00069 "In the case of a nodding observation (currently, this recipe only\n"
00070 "   supports nodding observations), in order not to degrade the \n"
00071 "   instrument high resolution, the combined images using only NODA\n"
00072 "   or NODB nodding positions can be produced on request. (see --onlyA/B)\n"
00073 "   In this case, the following spectrum extraction can be applied \n"
00074 "   either on the usual combined image or on those NODA/B combined\n"
00075 "   images (see --comb_used).\n"
00076 "\n"
00077 "This recipe produces 6 to 11 files:\n"
00078 "   The combined image      (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
00079 "   The contribution map    (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
00080 "   The combined image using only Nodding A frames (optional)\n"
00081 "                           (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
00082 "   The contribution map using only Nodding A frames (optional)\n"
00083 "                           (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
00084 "   The combined image using only Nodding B frames (optional)\n"
00085 "                           (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
00086 "   The contribution map using only Nodding B frames (optional)\n"
00087 "                           (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
00088 "   The table with the extracted spectrum\n"
00089 "                           (PRO TYPE = "CRIRES_PROTYPE_SPEC_WL") or\n"
00090 "                           (PRO TYPE = "CRIRES_PROTYPE_SENSIT") or\n"
00091 "                           (PRO TYPE = "CRIRES_PROTYPE_CONVERS")\n"
00092 "   The profile image       (PRO TYPE = "CRIRES_PROTYPE_PROFILE")\n"
00093 "   The background map      (PRO TYPE = "CRIRES_PROTYPE_BGD_MAP")\n"
00094 "   The wavelength map      (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n"
00095 "   The wavelength map from the model (optional)\n"
00096 "                           (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n" ;
00097 
00098 CRIRES_RECIPE_DEFINE(crires_win_jitter,
00099         CRIRES_PARAM_DISPLAY            |
00100         CRIRES_PARAM_REFINE             |
00101         CRIRES_PARAM_ONLYA              |
00102         CRIRES_PARAM_ONLYB              |
00103         CRIRES_PARAM_COMB_USED          |
00104         CRIRES_PARAM_HOR_SIZE           |
00105         CRIRES_PARAM_SPEC_HSIZE         |
00106         CRIRES_PARAM_KAPPA              |
00107         CRIRES_PARAM_CLOSING_HSIZE      |
00108         CRIRES_PARAM_CLEAN_RATE         |
00109         CRIRES_PARAM_REJECT             |
00110         CRIRES_PARAM_Y_SPEC_ZONE_CHIP1  |
00111         CRIRES_PARAM_Y_SPEC_ZONE_CHIP2  |
00112         CRIRES_PARAM_Y_SPEC_ZONE_CHIP3  |
00113         CRIRES_PARAM_Y_SPEC_ZONE_CHIP4  |
00114         CRIRES_PARAM_DEGREE,
00115         "Observation recipe in Windowing mode",
00116         crires_win_jitter_description) ;
00117 
00118 /*-----------------------------------------------------------------------------
00119                             Static variables
00120  -----------------------------------------------------------------------------*/
00121 
00122 static struct {
00123     /* Inputs */
00124     int                 comb_refine ;
00125     int                 comb_onlyA ;
00126     int                 comb_onlyB ;
00127     crires_comb_method  comb_used ;
00128     int                 extr_box_hor_size ;
00129     int                 extr_spec_hsize ;
00130     double              extr_kappa ;
00131     int                 extr_closing_hs ;
00132     int                 extr_clean_rate ;
00133     int                 extr_rej_left ;
00134     int                 extr_rej_right ;
00135     const char      *   extr_y_spec_zone_c1 ;
00136     const char      *   extr_y_spec_zone_c2 ;
00137     const char      *   extr_y_spec_zone_c3 ;
00138     const char      *   extr_y_spec_zone_c4 ;
00139     int                 display ;
00140     /* Outputs */
00141     int                 std_mode ;
00142     double              qc_wlcent[CRIRES_NB_DETECTORS] ;
00143     double              qc_wldisp[CRIRES_NB_DETECTORS] ;
00144     int                 qc_specpos[CRIRES_NB_DETECTORS] ;
00145     int                 qc_specwrec[CRIRES_NB_DETECTORS] ;
00146     int                 qc_specwopt[CRIRES_NB_DETECTORS] ;
00147     double              qc_specoptmed[CRIRES_NB_DETECTORS] ;
00148     double              qc_s2nmed[CRIRES_NB_DETECTORS] ;
00149     double              qc_sensmed[CRIRES_NB_DETECTORS] ;
00150     double              qc_convmed[CRIRES_NB_DETECTORS] ;
00151     double              qc_thromed[CRIRES_NB_DETECTORS] ;
00152     double              qc_fwhm_comb_pix[CRIRES_NB_DETECTORS] ;
00153     double              qc_fwhm_comb_as[CRIRES_NB_DETECTORS] ;
00154     double              qc_fwhm_prof_pix[CRIRES_NB_DETECTORS] ;
00155     double              qc_fwhm_prof_as[CRIRES_NB_DETECTORS] ;
00156     double              qc_fwhm_diff[CRIRES_NB_DETECTORS] ;
00157 } crires_win_jitter_config ;
00158 
00159 /*-----------------------------------------------------------------------------
00160                                 Functions code
00161  -----------------------------------------------------------------------------*/
00162 
00163 /*----------------------------------------------------------------------------*/
00170 /*----------------------------------------------------------------------------*/
00171 static int crires_win_jitter(
00172         cpl_frameset            *   frameset,
00173         const cpl_parameterlist *   parlist)
00174 {
00175     const char          *   sval ;
00176     const char          *   y_pos ;
00177     cpl_frameset        *   rawframes ;
00178     const char          *   fname ;
00179     cpl_frame           *   fr ;
00180     double                  tot_ndit ;
00181     const char          *   flat ;
00182     const char          *   dark ;
00183     const char          *   bpm ;
00184     const char          *   detlin ;
00185     const char          *   wavecal ;
00186     const char          *   std_star ;
00187     const char          *   cfg_model ;
00188     cpl_table           *   std_star_tab ;
00189     cpl_bivector        *   std_star_biv ;
00190     cpl_imagelist       **  comblist ;
00191     int                     comblist_offset ;
00192     int                     pix, extr_spec_starty, extr_spec_stopy ;
00193     cpl_polynomial      *   wave_poly ;
00194     cpl_table           *   wave_tab[CRIRES_NB_DETECTORS] ;
00195     cpl_table           *   extr_tab[CRIRES_NB_DETECTORS] ;
00196     cpl_image           *   profiles[CRIRES_NB_DETECTORS] ;
00197     cpl_image           *   bg_maps[CRIRES_NB_DETECTORS] ;
00198     cpl_imagelist       *   prof_list ;
00199     cpl_imagelist       *   bgmap_list ;
00200     cpl_image           *   profile_empty ;
00201     cpl_image           *   bgmap_empty ;
00202     cpl_table           *   extr_tab_empty ;
00203     cpl_imagelist       *   wl_map ;
00204     cpl_imagelist       *   wl_map_model ;
00205     cpl_vector          **  wavelengths ;
00206     int                     i, j ;
00207 
00208     /* Initialise */
00209     rawframes = NULL ;
00210     comblist_offset = -1 ;
00211     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00212         crires_win_jitter_config.qc_wlcent[i] = -1 ;
00213         crires_win_jitter_config.qc_wldisp[i] = -1 ;
00214         crires_win_jitter_config.qc_specpos[i] = -1 ;
00215         crires_win_jitter_config.qc_specwrec[i] = -1 ;
00216         crires_win_jitter_config.qc_specwopt[i] = -1 ;
00217         crires_win_jitter_config.qc_specoptmed[i] = -1.0 ;
00218         crires_win_jitter_config.qc_s2nmed[i] = -1.0 ;
00219         crires_win_jitter_config.qc_sensmed[i] = -1.0 ;
00220         crires_win_jitter_config.qc_convmed[i] = -1.0 ;
00221         crires_win_jitter_config.qc_thromed[i] = -1.0 ;
00222         crires_win_jitter_config.qc_fwhm_comb_pix[i] = -1.0 ;
00223         crires_win_jitter_config.qc_fwhm_comb_as[i] = -1.0 ;
00224         crires_win_jitter_config.qc_fwhm_prof_pix[i] = -1.0 ;
00225         crires_win_jitter_config.qc_fwhm_prof_as[i] = -1.0 ;
00226         crires_win_jitter_config.qc_fwhm_diff[i] = -1.0 ;
00227     }
00228  
00229     /* Retrieve input parameters */
00230     crires_win_jitter_config.display = crires_parameterlist_get_int(parlist,
00231             RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
00232     crires_win_jitter_config.comb_refine = crires_parameterlist_get_bool(
00233             parlist, RECIPE_STRING, CRIRES_PARAM_REFINE) ;
00234     crires_win_jitter_config.comb_onlyA = crires_parameterlist_get_bool(
00235             parlist, RECIPE_STRING, CRIRES_PARAM_ONLYA) ;
00236     crires_win_jitter_config.comb_onlyB = crires_parameterlist_get_bool(
00237             parlist, RECIPE_STRING, CRIRES_PARAM_ONLYB) ;
00238     sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
00239             CRIRES_PARAM_COMB_USED) ;
00240     if (!strcmp(sval, "NODA"))
00241         crires_win_jitter_config.comb_used = CRIRES_COMB_METHOD_NODA ;
00242     else if (!strcmp(sval, "NODB"))
00243         crires_win_jitter_config.comb_used = CRIRES_COMB_METHOD_NODB ;
00244     else if (!strcmp(sval, "COMB"))
00245         crires_win_jitter_config.comb_used = CRIRES_COMB_METHOD_COMB ;
00246     else {
00247         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00248         cpl_msg_error(__func__, "Invalid combination method specified");
00249         return -1;
00250     }
00251     crires_win_jitter_config.extr_box_hor_size = crires_parameterlist_get_int(
00252             parlist, RECIPE_STRING, CRIRES_PARAM_HOR_SIZE) ;
00253     crires_win_jitter_config.extr_spec_hsize = crires_parameterlist_get_int(
00254             parlist, RECIPE_STRING, CRIRES_PARAM_SPEC_HSIZE) ;
00255     crires_win_jitter_config.extr_kappa = crires_parameterlist_get_double(
00256             parlist, RECIPE_STRING, CRIRES_PARAM_KAPPA) ;
00257     crires_win_jitter_config.extr_closing_hs = crires_parameterlist_get_int(
00258             parlist, RECIPE_STRING, CRIRES_PARAM_CLOSING_HSIZE) ;
00259     crires_win_jitter_config.extr_clean_rate = crires_parameterlist_get_double(
00260             parlist, RECIPE_STRING, CRIRES_PARAM_CLEAN_RATE) ;
00261     sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
00262             CRIRES_PARAM_REJECT) ;
00263     if (sscanf(sval, "%d,%d",
00264                     &crires_win_jitter_config.extr_rej_left,
00265                     &crires_win_jitter_config.extr_rej_right)!=2) {
00266         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00267         return -1 ;
00268     }
00269     crires_win_jitter_config.extr_y_spec_zone_c1 =
00270         crires_parameterlist_get_string(parlist, RECIPE_STRING,
00271                 CRIRES_PARAM_Y_SPEC_ZONE_CHIP1) ;
00272     crires_win_jitter_config.extr_y_spec_zone_c2 =
00273         crires_parameterlist_get_string(parlist, RECIPE_STRING,
00274                 CRIRES_PARAM_Y_SPEC_ZONE_CHIP2) ;
00275     crires_win_jitter_config.extr_y_spec_zone_c3 =
00276         crires_parameterlist_get_string(parlist, RECIPE_STRING,
00277                 CRIRES_PARAM_Y_SPEC_ZONE_CHIP3) ;
00278     crires_win_jitter_config.extr_y_spec_zone_c4 =
00279         crires_parameterlist_get_string(parlist, RECIPE_STRING,
00280                 CRIRES_PARAM_Y_SPEC_ZONE_CHIP4) ;
00281 
00282     /* Identify the RAW and CALIB frames in the input frameset */
00283     if (crires_dfs_set_groups(frameset, "crires_win_jitter")) {
00284         cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
00285         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00286         return -1 ;
00287     }
00288 
00289     /* Retrieve calibration data */
00290     flat        = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT_WIN) ;
00291     dark        = crires_extract_filename(frameset, CRIRES_CALPRO_DARK_WIN) ;
00292     bpm         = crires_extract_filename(frameset, CRIRES_CALPRO_BPM_WIN) ;
00293     detlin      = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ;
00294     wavecal     = crires_extract_filename(frameset, CRIRES_CALPRO_WAVE) ;
00295     std_star    = crires_extract_filename(frameset,CRIRES_CALPRO_STD_PHOTOFLUX);
00296     cfg_model   = crires_extract_filename(frameset, CRIRES_CALPRO_MODEL_CONFIG);
00297    
00298     /* Retrieve raw frames */
00299     if ((rawframes = crires_extract_frameset(frameset,
00300                     CRIRES_WIN_NODDING_OBJECT_RAW)) != NULL) {
00301         crires_win_jitter_config.std_mode = 0 ;
00302     } else if ((rawframes = crires_extract_frameset(frameset,
00303                     CRIRES_WIN_NODDING_RAW)) != NULL) {
00304         crires_win_jitter_config.std_mode = 0 ;
00305     } else if ((rawframes = crires_extract_frameset(frameset,
00306                     CRIRES_WIN_NODDING_J_RAW)) != NULL) {
00307         crires_win_jitter_config.std_mode = 0 ;
00308     } else if ((rawframes = crires_extract_frameset(frameset,
00309                     CRIRES_WIN_NODDING_STD_RAW)) != NULL) {
00310         crires_win_jitter_config.std_mode = 1 ;
00311     } else if ((rawframes = crires_extract_frameset(frameset,
00312                     CRIRES_WIN_NODDING_J_STD_RAW)) != NULL) {
00313         crires_win_jitter_config.std_mode = 1 ;
00314     } else {
00315         cpl_msg_error(__func__, "No raw frame in input") ;
00316         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00317         return -1 ;
00318     }
00319 
00320    /* Verify the STRIPE keys conformity */
00321     fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
00322     if (flat != NULL) {
00323         if (crire_stripe_keys_mismatch(fname, flat)) {
00324             cpl_msg_error(__func__,
00325                     "Mismatch of STRIPE keys with the flat frame") ;
00326             cpl_frameset_delete(rawframes) ;
00327             cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00328             return -1 ;
00329         }
00330     }
00331     if (bpm != NULL) {
00332         if (crire_stripe_keys_mismatch(fname, bpm)) {
00333             cpl_msg_error(__func__,
00334                     "Mismatch of STRIPE keys with the bpm frame") ;
00335             cpl_frameset_delete(rawframes) ;
00336             cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00337             return -1 ;
00338         }
00339     }
00340     if (dark != NULL) {
00341         if (crire_stripe_keys_mismatch(fname, dark)) {
00342             cpl_msg_error(__func__,
00343                     "Mismatch of STRIPE keys with the dark frame") ;
00344             cpl_frameset_delete(rawframes) ;
00345             cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00346             return -1 ;
00347         }
00348     }
00349 
00350     /* Checks on the parameters validity */
00351     if ((crires_win_jitter_config.comb_used == CRIRES_COMB_METHOD_NODA)
00352         && (crires_win_jitter_config.comb_onlyA == 0)) {
00353         cpl_msg_warning(__func__,
00354                 "You forgot to require the NODA image to be produced !") ;
00355         crires_win_jitter_config.comb_onlyA = 1 ;
00356     }
00357     if ((crires_win_jitter_config.comb_used == CRIRES_COMB_METHOD_NODB)
00358         && (crires_win_jitter_config.comb_onlyB == 0)) {
00359         cpl_msg_warning(__func__,
00360                 "You forgot to require the NODB image to be produced !") ;
00361         crires_win_jitter_config.comb_onlyB = 1 ;
00362     }
00363 
00364     /* Set comblist_offset */
00365     if (crires_win_jitter_config.comb_used == CRIRES_COMB_METHOD_COMB)
00366         comblist_offset = 0 ;
00367     else if (crires_win_jitter_config.comb_used == CRIRES_COMB_METHOD_NODA)
00368         comblist_offset = 1 ;
00369     else if (crires_win_jitter_config.comb_used == CRIRES_COMB_METHOD_NODB)
00370         comblist_offset = 2 ;
00371 
00372     /* Get the total number of NDIT */
00373     fr = cpl_frameset_get_position(rawframes, 0);
00374     tot_ndit = crires_get_totndit(cpl_frame_get_filename(fr)) ;
00375     if (tot_ndit < 0) {
00376         cpl_msg_error(__func__, "Cannot get the total number of NDIT") ;
00377         cpl_frameset_delete(rawframes) ;
00378         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00379         return -1 ;
00380     }
00381     tot_ndit *= cpl_frameset_get_size(rawframes) ;
00382     
00383     /* Images recombination */
00384     cpl_msg_info(__func__, "Images combination") ;
00385     cpl_msg_indent_more() ;
00386     if ((comblist = crires_combine_imagelist_win(rawframes, 
00387                     flat, dark, bpm, detlin,
00388                     crires_win_jitter_config.comb_refine,
00389                     crires_win_jitter_config.comb_onlyA,
00390                     crires_win_jitter_config.comb_onlyB)) == NULL) {
00391         cpl_msg_error(__func__, "Cannot combine the images") ;
00392         cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
00393         cpl_frameset_delete(rawframes) ;
00394         cpl_msg_indent_less() ;
00395         return -1 ;
00396     }
00397     cpl_msg_indent_less() ;
00398       
00399     /* Spectrum extraction */
00400     cpl_msg_info(__func__, "Spectrum extraction") ;
00401     cpl_msg_indent_more() ;
00402     for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
00403         cpl_msg_info(__func__, "Chip number %d extraction", i+1) ;
00404         cpl_msg_indent_more() ;
00405     
00406         /* Where is the spectrum extraction zone ? */
00407         y_pos = "" ;
00408         if (i == 1) y_pos = crires_win_jitter_config.extr_y_spec_zone_c1 ;
00409         if (i == 2) y_pos = crires_win_jitter_config.extr_y_spec_zone_c2 ;
00410         if (i == 3) y_pos = crires_win_jitter_config.extr_y_spec_zone_c3 ;
00411         if (i == 4) y_pos = crires_win_jitter_config.extr_y_spec_zone_c4 ;
00412         if (sscanf(y_pos,"%d,%d", &extr_spec_starty, &extr_spec_stopy)!=2) {
00413             cpl_msg_warning(__func__, "Wrong Spectral Zone specified: %s",
00414                     y_pos) ;
00415             extr_spec_starty = extr_spec_stopy = -1 ;
00416         }
00417         if ((extr_tab[i] = crires_extract_spectrum(
00418                         cpl_imagelist_get(comblist[0+2*comblist_offset], i),
00419                         cpl_imagelist_get(comblist[1+2*comblist_offset], i),
00420                         crires_win_jitter_config.extr_box_hor_size,
00421                         crires_win_jitter_config.extr_spec_hsize,
00422                         crires_win_jitter_config.extr_kappa,
00423                         crires_win_jitter_config.extr_closing_hs,
00424                         crires_win_jitter_config.extr_clean_rate,
00425                         crires_win_jitter_config.extr_rej_left,
00426                         crires_win_jitter_config.extr_rej_right,
00427                         extr_spec_starty, extr_spec_stopy, i+1, tot_ndit,
00428                         CRIRES_ILLUM_FULL_DETECTOR,
00429                         &(crires_win_jitter_config.qc_specpos[i]),
00430                         &(crires_win_jitter_config.qc_specwrec[i]),
00431                         &(crires_win_jitter_config.qc_specwopt[i]),
00432                         &(crires_win_jitter_config.qc_specoptmed[i]),
00433                         &(crires_win_jitter_config.qc_s2nmed[i]),
00434                         &(profiles[i]),
00435                         &(bg_maps[i]))) == NULL) {
00436             cpl_msg_error(__func__, "Cannot extract the spectrum") ;
00437             cpl_msg_indent_less() ;
00438             cpl_msg_indent_less() ;
00439             for (j=1 ; j<i ; j++) 
00440                 cpl_table_delete(extr_tab[j]) ;
00441             for (j=1 ; j<i ; j++) 
00442                 cpl_image_delete(profiles[j]) ;
00443             for (j=1 ; j<i ; j++) 
00444                 cpl_image_delete(bg_maps[j]) ;
00445             cpl_imagelist_delete(comblist[0]) ;
00446             cpl_imagelist_delete(comblist[1]) ;
00447             if (crires_win_jitter_config.comb_onlyA) {
00448                 cpl_imagelist_delete(comblist[2]) ;
00449                 cpl_imagelist_delete(comblist[3]) ;
00450             }
00451             if (crires_win_jitter_config.comb_onlyB) {
00452                 cpl_imagelist_delete(comblist[4]) ;
00453                 cpl_imagelist_delete(comblist[5]) ;
00454             }
00455             cpl_free(comblist) ;
00456             cpl_frameset_delete(rawframes) ;
00457             return -1 ;
00458         }
00459         cpl_msg_info(__func__, "Chip number %d FWHM Computation", i+1) ;
00460         if (crires_extract_qc_fwhm(
00461                     cpl_imagelist_get(comblist[0+2*comblist_offset], i),
00462                     profiles[i],
00463                     &(crires_win_jitter_config.qc_fwhm_comb_pix[i]),
00464                     &(crires_win_jitter_config.qc_fwhm_comb_as[i]),
00465                     &(crires_win_jitter_config.qc_fwhm_prof_pix[i]),
00466                     &(crires_win_jitter_config.qc_fwhm_prof_as[i]),
00467                     &(crires_win_jitter_config.qc_fwhm_diff[i])) == -1) {
00468             cpl_msg_warning(__func__, "Failed for FWHM computation") ;
00469             crires_win_jitter_config.qc_fwhm_comb_pix[i] = -1.0 ;
00470             crires_win_jitter_config.qc_fwhm_comb_as[i] = -1.0 ;
00471             crires_win_jitter_config.qc_fwhm_prof_pix[i] = -1.0 ;
00472             crires_win_jitter_config.qc_fwhm_prof_as[i] = -1.0 ;
00473             crires_win_jitter_config.qc_fwhm_diff[i] = -1.0 ;
00474         }
00475         cpl_msg_indent_less() ;
00476     }
00477 
00478     /* Create the profile and bg maps */
00479     prof_list = cpl_imagelist_new() ;
00480     bgmap_list = cpl_imagelist_new() ;
00481     profile_empty = cpl_image_duplicate(profiles[1]) ;
00482     bgmap_empty = cpl_image_duplicate(bg_maps[1]) ;
00483     cpl_image_multiply_scalar(profile_empty, 0.0) ;
00484     cpl_image_multiply_scalar(bgmap_empty, 0.0) ;
00485     cpl_imagelist_set(prof_list, cpl_image_duplicate(profile_empty), 0) ;
00486     cpl_imagelist_set(bgmap_list, cpl_image_duplicate(bgmap_empty), 0) ;
00487     for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
00488         cpl_imagelist_set(prof_list, profiles[i], i) ;
00489         cpl_imagelist_set(bgmap_list, bg_maps[i], i) ;
00490     }
00491     cpl_imagelist_set(prof_list, cpl_image_duplicate(profile_empty), 
00492             CRIRES_NB_DETECTORS-1) ;
00493     cpl_imagelist_set(bgmap_list, cpl_image_duplicate(bgmap_empty), 
00494             CRIRES_NB_DETECTORS-1) ;
00495     cpl_image_delete(profile_empty) ;
00496     cpl_image_delete(bgmap_empty) ;
00497     
00498     /* Test that the spectrum is at the same place in all detectors */
00499     if (crires_win_jitter_config.qc_specpos[1] > 0 && 
00500             crires_win_jitter_config.qc_specpos[2] > 0 &&
00501             fabs(crires_win_jitter_config.qc_specpos[1] -
00502                 crires_win_jitter_config.qc_specpos[2]) > 
00503             CRIRES_SPEC_POS_TOLERANCE) {
00504         cpl_msg_warning(__func__,
00505 "The spectrum positions in chip 1 and chip 2 are too different: %d -> %d",
00506                 crires_win_jitter_config.qc_specpos[1], 
00507                 crires_win_jitter_config.qc_specpos[2]) ;
00508     }
00509     cpl_msg_indent_less() ;
00510 
00511     /* Wavelength calibration */
00512     cpl_msg_info(__func__, "Wavelength Calibration") ;
00513     cpl_msg_indent_more() ;
00514     if (wavecal != NULL) {
00515         /* Wavelength solution is provided */
00516         cpl_msg_info(__func__, "Use the provided solution") ;
00517         for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00518             if ((wave_tab[i] = crires_load_table_check(wavecal, i+1,
00519                             CRIRES_PROTYPE_WL_POLY, -1, -1, 0)) == NULL) {
00520                 cpl_msg_error(__func__, "Cannot load the wavelength table") ;
00521                 cpl_msg_indent_less() ;
00522                 cpl_frameset_delete(rawframes) ;
00523                 cpl_imagelist_delete(comblist[0]) ;
00524                 cpl_imagelist_delete(comblist[1]) ;
00525                 if (crires_win_jitter_config.comb_onlyA) {
00526                     cpl_imagelist_delete(comblist[2]) ;
00527                     cpl_imagelist_delete(comblist[3]) ;
00528                 }
00529                 if (crires_win_jitter_config.comb_onlyB) {
00530                     cpl_imagelist_delete(comblist[4]) ;
00531                     cpl_imagelist_delete(comblist[5]) ;
00532                 }
00533                 cpl_free(comblist) ;
00534                 for (j=1 ; j<CRIRES_NB_DETECTORS-1 ; j++)
00535                     cpl_table_delete(extr_tab[j]) ;
00536                 cpl_imagelist_delete(prof_list) ;
00537                 cpl_imagelist_delete(bgmap_list) ;
00538                 return -1 ;
00539             }
00540         }
00541     } else {
00542         /* Calibrate from the keywords */
00543         cpl_msg_info(__func__, "Use the keywords for the wavelength") ;
00544 
00545         /* Reduce the first raw frame */
00546         fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
00547 
00548         /* Loop on the detectors */
00549         for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00550             cpl_msg_info(__func__, "Calibrate chip number %d", i+1) ;
00551             cpl_msg_indent_more() ;
00552             wave_poly = crires_wlestimate_get(fname, i+1) ;
00553             wave_tab[i] = crires_wlcalib_gen_wltab_one(wave_poly, -1, -1.0) ;
00554             cpl_polynomial_delete(wave_poly) ;
00555             cpl_msg_indent_less() ;
00556         }
00557     }
00558 
00559     /* Create the wave map */
00560     if ((wl_map = crires_wlcalib_gen_wlmap((const cpl_table **)wave_tab))
00561             == NULL) {
00562         cpl_msg_error(__func__, "Cannot compute the Wavelength Map") ;
00563         cpl_frameset_delete(rawframes) ;
00564         cpl_imagelist_delete(comblist[0]) ;
00565         cpl_imagelist_delete(comblist[1]) ;
00566         if (crires_win_jitter_config.comb_onlyA) {
00567             cpl_imagelist_delete(comblist[2]) ;
00568             cpl_imagelist_delete(comblist[3]) ;
00569         }
00570         if (crires_win_jitter_config.comb_onlyB) {
00571             cpl_imagelist_delete(comblist[4]) ;
00572             cpl_imagelist_delete(comblist[5]) ;
00573         }
00574         cpl_free(comblist) ;
00575         cpl_imagelist_delete(prof_list) ;
00576         cpl_imagelist_delete(bgmap_list) ;
00577         for (j=1 ; j<CRIRES_NB_DETECTORS-1 ; j++) 
00578             cpl_table_delete(extr_tab[j]) ;
00579         for (j=0 ; j<CRIRES_NB_DETECTORS ; j++) 
00580             if (wave_tab[j] != NULL) cpl_table_delete(wave_tab[j]);
00581         return -1 ;
00582     }
00583     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
00584         if (wave_tab[i] != NULL) cpl_table_delete(wave_tab[i]);
00585 
00586     /* Compute the QC parameters */
00587     for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
00588         crires_win_jitter_config.qc_wlcent[i] =
00589             cpl_image_get(cpl_imagelist_get(wl_map, i),
00590                     512, crires_win_jitter_config.qc_specpos[i], &pix) ;
00591         crires_win_jitter_config.qc_wldisp[i] =
00592             ((cpl_image_get(cpl_imagelist_get(wl_map, i), 1024,
00593                             crires_win_jitter_config.qc_specpos[i], &pix)) -
00594              (cpl_image_get(cpl_imagelist_get(wl_map, i), 1,
00595                             crires_win_jitter_config.qc_specpos[i], &pix)))
00596             / 1023 ;
00597     }
00598 
00599     /* Get the wl map from the model */
00600     fname  = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
00601     if ((cfg_model != NULL) && (!crires_model_off()) && 
00602             (crires_model_config_check(cfg_model, fname) == 0)) {
00603         cpl_msg_info(__func__, "Call the model to get the wavelength map") ;
00604         cpl_msg_indent_more() ;
00605         wl_map_model = crires_model_wavpix(fname, cfg_model, -1) ;
00606         if (wl_map_model == NULL) {
00607             cpl_msg_warning(__func__, "Model function returns NULL") ;
00608             cpl_error_reset() ;
00609         }
00610         cpl_msg_indent_less() ;
00611     } else {
00612         wl_map_model = NULL ;
00613     }
00614     
00615     /* Apply the wavelength */
00616     for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
00617         cpl_table_new_column(extr_tab[i], CRIRES_COL_WAVELENGTH, 
00618                 CPL_TYPE_DOUBLE) ;
00619         for (j=0 ; j<cpl_table_get_nrow(extr_tab[i]) ; j++) {
00620             cpl_table_set_double(extr_tab[i], CRIRES_COL_WAVELENGTH, j, 
00621                     cpl_image_get(cpl_imagelist_get_const(wl_map, i), j+1,
00622                         crires_win_jitter_config.qc_specpos[i], &pix));
00623         }
00624     }
00625 
00626     /* Add the Model Wavelength and Call the model to fill it */
00627     for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
00628         cpl_table_new_column(extr_tab[i], CRIRES_COL_WAVELENGTH_MODEL, 
00629                 CPL_TYPE_DOUBLE) ;
00630         cpl_table_fill_column_window_double(extr_tab[i],
00631                 CRIRES_COL_WAVELENGTH_MODEL, 0,
00632                 cpl_table_get_nrow(extr_tab[i]), -1.0) ;
00633     }
00634     if ((cfg_model != NULL) && (!crires_model_off()) && (1)) {
00635         cpl_msg_info(__func__, "Call the model to get the wavelengths") ;
00636         cpl_msg_indent_more() ;
00637         wavelengths = crires_model_wavelengths(
00638                 cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)),
00639                 cfg_model, -1,
00640                 (double)(crires_win_jitter_config.qc_specpos[0]),
00641                 wl_map_model) ;
00642         if (wavelengths != NULL) {
00643             /* Loop on the detectors */
00644             for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
00645                 /* Loop on the x values */
00646                 for (j=0 ; j<cpl_vector_get_size(wavelengths[i]) ; j++) {
00647                     cpl_table_set_double(extr_tab[i], 
00648                             CRIRES_COL_WAVELENGTH_MODEL, j, 
00649                             cpl_vector_get(wavelengths[i], j)) ;
00650                 }
00651             }
00652             for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) 
00653                 cpl_vector_delete(wavelengths[i]) ;
00654             cpl_free(wavelengths) ;
00655         } else {
00656             cpl_msg_warning(__func__, "Model function returns NULL") ;
00657             cpl_error_reset() ;
00658         }
00659         cpl_msg_indent_less() ;
00660     }
00661 
00662     /* Conversion factor / Sensitivity */
00663     if (crires_win_jitter_config.std_mode) {
00664         cpl_msg_info(__func__, 
00665                 "Sensitivity / Conversion / Throughput computation") ;
00666         cpl_msg_indent_more() ;
00667         /* Load std star */
00668         if ((std_star_tab = crires_load_table_check(std_star, 1,
00669                         CRIRES_PROTYPE_PHO_FLUX, -1, -1, 0)) == NULL) {
00670             cpl_msg_error(__func__, "Cannot load the std star flux") ;
00671         } else {
00672             /* Get the wished std star */
00673             if ((std_star_biv = crires_photom_conv_get_star(std_star_tab, 
00674             cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)))) 
00675                     == NULL) {
00676                 cpl_msg_error(__func__, "Cannot find the star flux") ;
00677                 cpl_table_delete(std_star_tab) ;
00678             } else {
00679                 cpl_table_delete(std_star_tab) ;
00680                 /* Apply the conversion  */
00681                 for (i=1 ; i<CRIRES_NB_DETECTORS-1 ; i++) {
00682                     if (crires_photom_conv_engine(extr_tab[i], std_star_biv,
00683                             i+1, (i+1==crires_win_jitter_config.display))==0){
00684                         crires_win_jitter_config.qc_convmed[i] =
00685                             cpl_table_get_column_median(extr_tab[i],
00686                                     CRIRES_COL_CONVERSION_RECT) ;
00687                         crires_win_jitter_config.qc_thromed[i] =
00688                             cpl_table_get_column_median(extr_tab[i],
00689                                     CRIRES_COL_THROUGHPUT) ;
00690                         /* Apply the sensitivity */
00691                         if (crires_photom_sens_engine(extr_tab[i], 
00692                             cpl_frame_get_filename(cpl_frameset_get_position(
00693                                         rawframes,0)), -1.0, 
00694                                 (i+1==crires_win_jitter_config.display))>0) {
00695                             crires_win_jitter_config.qc_sensmed[i] =
00696                                 cpl_table_get_column_median(extr_tab[i], 
00697                                         CRIRES_COL_SENSITIVITY) ; ;
00698                         }
00699                     }
00700                 }
00701                 cpl_bivector_delete(std_star_biv) ;
00702             }
00703         }
00704         cpl_msg_indent_less() ;
00705     }
00706     cpl_frameset_delete(rawframes) ;
00707 
00708     /* Create empty extr_tab for non-processed chips  */
00709     extr_tab_empty = cpl_table_duplicate(extr_tab[1]) ;
00710     cpl_table_set_size(extr_tab_empty, 0) ;
00711     extr_tab[0] = cpl_table_duplicate(extr_tab_empty) ;
00712     extr_tab[CRIRES_NB_DETECTORS-1] = cpl_table_duplicate(extr_tab_empty) ;
00713     cpl_table_delete(extr_tab_empty) ;
00714  
00715     /* Save the product */
00716     cpl_msg_info(__func__, "Save the product") ;
00717     cpl_msg_indent_more() ;
00718     if (crires_win_jitter_save((const cpl_imagelist **)comblist, 
00719                 prof_list, bgmap_list,
00720                 (const cpl_table **)extr_tab, wl_map, wl_map_model, parlist, 
00721                 frameset)) {
00722         cpl_msg_error(__func__, "Cannot save the product") ;
00723         cpl_imagelist_delete(prof_list) ;
00724         cpl_imagelist_delete(bgmap_list) ;
00725         for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) 
00726             if (extr_tab[i] != NULL) cpl_table_delete(extr_tab[i]) ;
00727         cpl_imagelist_delete(comblist[0]) ;
00728         cpl_imagelist_delete(comblist[1]) ;
00729         if (crires_win_jitter_config.comb_onlyA) {
00730             cpl_imagelist_delete(comblist[2]) ;
00731             cpl_imagelist_delete(comblist[3]) ;
00732         }
00733         if (crires_win_jitter_config.comb_onlyB) {
00734             cpl_imagelist_delete(comblist[4]) ;
00735             cpl_imagelist_delete(comblist[5]) ;
00736         }
00737         cpl_free(comblist) ;
00738         cpl_imagelist_delete(wl_map) ;
00739         if (wl_map_model) cpl_imagelist_delete(wl_map_model) ;
00740         cpl_msg_indent_less() ;
00741         return -1 ;
00742     }
00743     cpl_imagelist_delete(wl_map) ;
00744     if (wl_map_model) cpl_imagelist_delete(wl_map_model) ;
00745     cpl_imagelist_delete(comblist[0]) ;
00746     cpl_imagelist_delete(comblist[1]) ;
00747     if (crires_win_jitter_config.comb_onlyA) {
00748         cpl_imagelist_delete(comblist[2]) ;
00749         cpl_imagelist_delete(comblist[3]) ;
00750     }
00751     if (crires_win_jitter_config.comb_onlyB) {
00752         cpl_imagelist_delete(comblist[4]) ;
00753         cpl_imagelist_delete(comblist[5]) ;
00754     }
00755     cpl_free(comblist) ;
00756     cpl_imagelist_delete(prof_list) ;
00757     cpl_imagelist_delete(bgmap_list) ;
00758     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) 
00759         if (extr_tab[i] != NULL) cpl_table_delete(extr_tab[i]) ;
00760     cpl_msg_indent_less() ;
00761 
00762     /* Return */
00763     if (cpl_error_get_code()) return -1 ;
00764     else return 0 ;
00765 }
00766 
00767 /*----------------------------------------------------------------------------*/
00781 /*----------------------------------------------------------------------------*/
00782 static int crires_win_jitter_save(
00783         const cpl_imagelist     **  images,
00784         const cpl_imagelist     *   prof,
00785         const cpl_imagelist     *   bgmap,
00786         const cpl_table         **  extr_tab,
00787         const cpl_imagelist     *   wl_map,
00788         const cpl_imagelist     *   wl_map_model,
00789         const cpl_parameterlist *   parlist,
00790         cpl_frameset            *   set)
00791 {
00792     cpl_propertylist    **  qclists ;
00793     const cpl_frame     *   ref_frame ;
00794     const char          *   procat ;
00795     const char          *   protype ;
00796     cpl_propertylist    *   inputlist ;
00797     const char          *   recipe_name = "crires_win_jitter" ;
00798     int                     i ;
00799 
00800     /* Get the reference frame */
00801     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
00802 
00803     /* Create the QC lists */
00804     qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
00805     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
00806         qclists[i] = cpl_propertylist_new() ;
00807         cpl_propertylist_append_int(qclists[i], "ESO QC SPECPOS",
00808                 crires_win_jitter_config.qc_specpos[i]) ;
00809         cpl_propertylist_append_int(qclists[i], "ESO QC SPECWREC",
00810                 crires_win_jitter_config.qc_specwrec[i]) ;
00811         cpl_propertylist_append_int(qclists[i], "ESO QC SPECWOPT",
00812                 crires_win_jitter_config.qc_specwopt[i]) ;
00813         cpl_propertylist_append_double(qclists[i], "ESO QC SIGNAL MED",
00814                 crires_win_jitter_config.qc_specoptmed[i]) ;
00815         cpl_propertylist_append_double(qclists[i], "ESO QC S2NMED",
00816                 crires_win_jitter_config.qc_s2nmed[i]) ;
00817         cpl_propertylist_append_double(qclists[i], "ESO QC CENTWL",
00818                 crires_win_jitter_config.qc_wlcent[i]) ;
00819         cpl_propertylist_append_double(qclists[i], "ESO QC DISPWL",
00820                 crires_win_jitter_config.qc_wldisp[i]) ;
00821         cpl_propertylist_append_double(qclists[i], "ESO QC SENSMED",
00822                 crires_win_jitter_config.qc_sensmed[i]) ;
00823         cpl_propertylist_append_double(qclists[i], "ESO QC CONVMED",
00824                 crires_win_jitter_config.qc_convmed[i]) ;
00825         cpl_propertylist_append_double(qclists[i], "ESO QC THROMED",
00826                 crires_win_jitter_config.qc_thromed[i]) ;
00827         cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX COMBINED",
00828                 crires_win_jitter_config.qc_fwhm_comb_pix[i]) ;
00829         cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC COMBINED",
00830                 crires_win_jitter_config.qc_fwhm_comb_as[i]) ;
00831         cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX PROFILE",
00832                 crires_win_jitter_config.qc_fwhm_prof_pix[i]) ;
00833         cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC PROFILE",
00834                 crires_win_jitter_config.qc_fwhm_prof_as[i]) ;
00835         cpl_propertylist_append_double(qclists[i], "ESO QC FWHM DIFF",
00836                 crires_win_jitter_config.qc_fwhm_diff[i]) ;
00837         /* Propagate some keywords from input raw frame extensions */
00838         inputlist = cpl_propertylist_load_regexp(
00839                 cpl_frame_get_filename(ref_frame), i+1,
00840                 CRIRES_HEADER_EXT_FORWARD, 0) ;
00841         cpl_propertylist_copy_property_regexp(qclists[i], inputlist, 
00842                 CRIRES_HEADER_EXT_FORWARD, 0) ;
00843         cpl_propertylist_delete(inputlist) ;
00844     }
00845 
00846     /* PRO.CATG */
00847     if (crires_win_jitter_config.std_mode == 1) {
00848         procat = CRIRES_STD_WIN_COMBINED_IMA ;
00849     } else {
00850         procat = CRIRES_OBS_WIN_COMBINED_IMA ;
00851     }
00852 
00853     /* Write the combined image */
00854     crires_image_save(set,
00855             parlist,
00856             set, 
00857             images[0], 
00858             recipe_name,
00859             procat, 
00860             CRIRES_PROTYPE_COMBINED,
00861             CRIRES_ILLUM_FULL_DETECTOR,
00862             NULL,
00863             (const cpl_propertylist **)qclists, 
00864             PACKAGE "/" PACKAGE_VERSION,
00865             "crires_win_jitter_comb.fits") ;
00866 
00867     /* PRO.CATG */
00868     if (crires_win_jitter_config.std_mode == 1) {
00869         procat = CRIRES_STD_WIN_CONTRIBUTION_IMA ;
00870     } else {
00871         procat = CRIRES_OBS_WIN_CONTRIBUTION_IMA ;
00872     }
00873 
00874     /* Write the contribution map */
00875     crires_image_save(set,
00876             parlist,
00877             set, 
00878             images[1], 
00879             recipe_name,
00880             procat, 
00881             CRIRES_PROTYPE_CONTRIB,
00882             CRIRES_ILLUM_FULL_DETECTOR,
00883             NULL,
00884             (const cpl_propertylist **)qclists, 
00885             PACKAGE "/" PACKAGE_VERSION,
00886             "crires_win_jitter_contrib.fits") ;
00887 
00888     /* Nodded A support */
00889     if (crires_win_jitter_config.comb_onlyA) {
00890         /* PRO.CATG */
00891         if (crires_win_jitter_config.std_mode == 1) {
00892             procat = CRIRES_STD_WIN_COMBINED_NA_IMA ;
00893         } else {
00894             procat = CRIRES_OBS_WIN_COMBINED_NA_IMA ;
00895         }
00896 
00897         /* Write the combined Nodded A image */
00898         crires_image_save(set,
00899                 parlist,
00900                 set,
00901                 images[2],
00902                 recipe_name,
00903                 procat,
00904                 CRIRES_PROTYPE_COMBINED,
00905                 CRIRES_ILLUM_FULL_DETECTOR,
00906                 NULL,
00907                 (const cpl_propertylist **)qclists,
00908                 PACKAGE "/" PACKAGE_VERSION,
00909                 "crires_win_jitter_comb_noddedA.fits") ;
00910 
00911          /* PRO.CATG */
00912         if (crires_win_jitter_config.std_mode == 1) {
00913             procat = CRIRES_STD_WIN_CONTRIBUTION_NA_IMA ;
00914         } else {
00915             procat = CRIRES_OBS_WIN_CONTRIBUTION_NA_IMA ;
00916         }
00917 
00918         /* Write the contribution Nodded A image */
00919         crires_image_save(set,
00920                 parlist,
00921                 set,
00922                 images[3],
00923                 recipe_name,
00924                 procat,
00925                 CRIRES_PROTYPE_CONTRIB,
00926                 CRIRES_ILLUM_FULL_DETECTOR,
00927                 NULL,
00928                 (const cpl_propertylist **)qclists,
00929                 PACKAGE "/" PACKAGE_VERSION,
00930                 "crires_win_jitter_contrib_noddedA.fits") ;
00931     }
00932 
00933     /* Nodded B support */
00934     if (crires_win_jitter_config.comb_onlyB) {
00935         /* PRO.CATG */
00936         if (crires_win_jitter_config.std_mode == 1) {
00937             procat = CRIRES_STD_WIN_COMBINED_NB_IMA ;
00938         } else {
00939             procat = CRIRES_OBS_WIN_COMBINED_NB_IMA ;
00940         }
00941 
00942         /* Write the combined Nodded B image */
00943         crires_image_save(set,
00944                 parlist,
00945                 set,
00946                 images[4],
00947                 recipe_name,
00948                 procat,
00949                 CRIRES_PROTYPE_COMBINED,
00950                 CRIRES_ILLUM_FULL_DETECTOR,
00951                 NULL,
00952                 (const cpl_propertylist **)qclists,
00953                 PACKAGE "/" PACKAGE_VERSION,
00954                 "crires_win_jitter_comb_noddedB.fits") ;
00955 
00956          /* PRO.CATG */
00957         if (crires_win_jitter_config.std_mode == 1) {
00958             procat = CRIRES_STD_WIN_CONTRIBUTION_NB_IMA ;
00959         } else {
00960             procat = CRIRES_OBS_WIN_CONTRIBUTION_NB_IMA ;
00961         }
00962 
00963         /* Write the contribution Nodded B image */
00964         crires_image_save(set,
00965                 parlist,
00966                 set,
00967                 images[5],
00968                 recipe_name,
00969                 procat,
00970                 CRIRES_PROTYPE_CONTRIB,
00971                 CRIRES_ILLUM_FULL_DETECTOR,
00972                 NULL,
00973                 (const cpl_propertylist **)qclists,
00974                 PACKAGE "/" PACKAGE_VERSION,
00975                 "crires_win_jitter_contrib_noddedB.fits") ;
00976     }
00977 
00978     /* PRO.CATG */
00979     if (crires_win_jitter_config.std_mode == 1) {
00980         procat = CRIRES_STD_WIN_EXTRACT_PROFILE_IMA ;
00981     } else {
00982         procat = CRIRES_OBS_WIN_EXTRACT_PROFILE_IMA ;
00983     }
00984 
00985     /* Write the profile image */
00986     crires_image_save(set,
00987             parlist,
00988             set, 
00989             prof, 
00990             recipe_name,
00991             procat, 
00992             CRIRES_PROTYPE_PROFILE,
00993             CRIRES_ILLUM_FULL_DETECTOR,
00994             NULL,
00995             (const cpl_propertylist **)qclists, 
00996             PACKAGE "/" PACKAGE_VERSION,
00997             "crires_win_jitter_prof.fits") ;
00998  
00999     /* PRO.CATG */
01000     if (crires_win_jitter_config.std_mode == 1) {
01001         procat = CRIRES_STD_WIN_EXTRACT_BGMAP_IMA ;
01002     } else {
01003         procat = CRIRES_OBS_WIN_EXTRACT_BGMAP_IMA ;
01004     }
01005 
01006     /* Write the background image */
01007     crires_image_save(set,
01008             parlist,
01009             set, 
01010             bgmap, 
01011             recipe_name,
01012             procat, 
01013             CRIRES_PROTYPE_BGD_MAP,
01014             CRIRES_ILLUM_FULL_DETECTOR,
01015             NULL,
01016             (const cpl_propertylist **)qclists, 
01017             PACKAGE "/" PACKAGE_VERSION,
01018             "crires_win_jitter_bgmap.fits") ;
01019 
01020     /* PRO.CATG */
01021     if (crires_win_jitter_config.std_mode == 1) {
01022         procat = CRIRES_STD_WIN_WL_MAP_IMA ;
01023     } else {
01024         procat = CRIRES_OBS_WIN_WL_MAP_IMA ;
01025     }
01026  
01027     /* Write the map */
01028     crires_image_save(set,
01029             parlist,
01030             set,
01031             wl_map,
01032             recipe_name,
01033             procat,
01034             CRIRES_PROTYPE_WL_MAP,
01035             CRIRES_ILLUM_FULL_DETECTOR,
01036             NULL,
01037             (const cpl_propertylist **)qclists,
01038             PACKAGE "/" PACKAGE_VERSION,
01039             "crires_win_jitter_wlmap.fits") ;
01040 
01041     if (wl_map_model != NULL) {
01042         /* PRO.CATG */
01043         if (crires_win_jitter_config.std_mode == 1) {
01044             procat = CRIRES_STD_WIN_WL_MAP_MODEL_IMA ;
01045         } else {
01046             procat = CRIRES_OBS_WIN_WL_MAP_MODEL_IMA ;
01047         }
01048 
01049         /* Write the model map */
01050         crires_image_save(set,
01051                 parlist,
01052                 set,
01053                 wl_map_model,
01054                 recipe_name,
01055                 procat,
01056                 CRIRES_PROTYPE_WL_MAP,
01057                 CRIRES_ILLUM_FULL_DETECTOR,
01058                 NULL,
01059                 (const cpl_propertylist **)qclists,
01060                 PACKAGE "/" PACKAGE_VERSION,
01061                 "crires_win_jitter_wlmap_model.fits") ;
01062     }
01063     
01064     /* Write the extracted spectra */
01065     /* Get the PRO.CATG */
01066     if (cpl_table_has_column(extr_tab[0], CRIRES_COL_SENSITIVITY)) {
01067         procat = CRIRES_WIN_EXTRACT_SENS_TAB ;
01068         protype = CRIRES_PROTYPE_SENSIT ;
01069     } else if (cpl_table_has_column(extr_tab[0],CRIRES_COL_CONVERSION_OPT)){
01070         procat = CRIRES_WIN_EXTRACT_CONV_TAB ;
01071         protype = CRIRES_PROTYPE_CONVERS ;
01072     } else if (crires_win_jitter_config.std_mode == 1) {
01073         procat = CRIRES_STD_WIN_EXTRACT_WL_TAB ;
01074         protype = CRIRES_PROTYPE_SPEC_WL ;
01075     } else {
01076         procat = CRIRES_OBS_WIN_EXTRACT_WL_TAB ;
01077         protype = CRIRES_PROTYPE_SPEC_WL ;
01078     }
01079     crires_table_save(set, 
01080             parlist, 
01081             set, 
01082             extr_tab, 
01083             recipe_name, 
01084             procat, 
01085             protype,
01086             NULL, 
01087             (const cpl_propertylist **)qclists,
01088             PACKAGE "/" PACKAGE_VERSION,
01089             "crires_win_jitter_extracted.fits") ;
01090 
01091     /* Free and return */
01092     for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
01093         cpl_propertylist_delete(qclists[i]) ;
01094     }
01095     cpl_free(qclists) ;
01096     return  0;
01097 }
01098