CRIRES Pipeline Reference Manual
2.3.2
|
00001 /* $Id: crires_spec_wavecal.c,v 1.75 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.75 $ 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_combine.h" 00039 #include "crires_wlcalib.h" 00040 #include "crires_extract.h" 00041 #include "crires_model_kernel.h" 00042 00043 /*----------------------------------------------------------------------------- 00044 Define 00045 -----------------------------------------------------------------------------*/ 00046 00047 #define RECIPE_STRING "crires_spec_wavecal" 00048 00049 /*----------------------------------------------------------------------------- 00050 Functions prototypes 00051 -----------------------------------------------------------------------------*/ 00052 00053 static int crires_spec_wavecal_save(const cpl_imagelist *, 00054 const cpl_imagelist *, const cpl_table **, const cpl_parameterlist *, 00055 cpl_frameset *) ; 00056 00057 static char crires_spec_wavecal_description[] = 00058 "crires_spec_wavecal -- Wavelength calibration\n" 00059 "The files listed in the Set Of Frames (sof-file) must be tagged:\n" 00060 "raw-file.fits "CRIRES_SPEC_WAVECAL_SKY_RAW" or\n" 00061 "raw-file.fits "CRIRES_SPEC_WAVECAL_LAMP_RAW" or\n" 00062 "raw-file.fits "CRIRES_SPEC_WAVECAL_ABS_RAW" or\n" 00063 "flat-file.fits "CRIRES_CALPRO_FLAT" or\n" 00064 "bpm-file.fits "CRIRES_CALPRO_BPM" or\n" 00065 "dark-file.fits "CRIRES_CALPRO_DARK" or\n" 00066 "detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE" or\n" 00067 "catalog-file.fits "CRIRES_CALPRO_THAR_CAT" or\n" 00068 "catalog-file.fits "CRIRES_CALPRO_OH_CAT" or\n" 00069 "catalog-file.fits "CRIRES_CALPRO_HITRAN_CAT" or\n" 00070 "ypos-file.fits "CRIRES_CALPRO_THAR_POS" or\n" 00071 "model-config-file.fits "CRIRES_CALPRO_MODEL_CONFIG".\n" 00072 "\n" 00073 "This recipe produces 3 files:\n" 00074 "First product: the image with the wavelength values.\n" 00075 " (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n" 00076 "Second product: the image with the wavelength values from the model.\n" 00077 " (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n" 00078 "Third product: the table with the wavelength polynomial coefficients.\n" 00079 " (PRO TYPE = "CRIRES_PROTYPE_WL_POLY")\n" ; 00080 00081 CRIRES_RECIPE_DEFINE(crires_spec_wavecal, 00082 CRIRES_PARAM_WAVES | 00083 CRIRES_PARAM_DISPLAY | 00084 CRIRES_PARAM_WL_LOG | 00085 CRIRES_PARAM_WL_NOLIMIT | 00086 CRIRES_PARAM_WL_ERROR | 00087 CRIRES_PARAM_XC_LIMIT | 00088 CRIRES_PARAM_WL_NBSAMPLES | 00089 CRIRES_PARAM_Y_POS_CHIP1 | 00090 CRIRES_PARAM_Y_POS_CHIP2 | 00091 CRIRES_PARAM_Y_POS_CHIP3 | 00092 CRIRES_PARAM_Y_POS_CHIP4 | 00093 CRIRES_PARAM_Y_WIDTH | 00094 CRIRES_PARAM_DEGREE | 00095 CRIRES_PARAM_WL_CLEAN, 00096 "Wavelength calibration", 00097 crires_spec_wavecal_description) ; 00098 00099 /*----------------------------------------------------------------------------- 00100 Static variables 00101 -----------------------------------------------------------------------------*/ 00102 00103 static struct { 00104 /* Inputs */ 00105 double wstart[CRIRES_NB_DETECTORS] ; 00106 double wstop[CRIRES_NB_DETECTORS] ; 00107 int wl_nolimit ; 00108 int wl_log ; 00109 const char * wl_ypos_c1 ; 00110 const char * wl_ypos_c2 ; 00111 const char * wl_ypos_c3 ; 00112 const char * wl_ypos_c4 ; 00113 int wl_width ; 00114 double wl_fwhm ; 00115 double wl_slitw ; 00116 int wl_degree ; 00117 double wl_err ; 00118 int wl_samples ; 00119 int wl_clean ; 00120 double wl_xclimit ; 00121 int wl_ppm ; 00122 int display ; 00123 /* Outputs */ 00124 crires_illum_period period ; 00125 int mode ; 00126 double qc_wlxc[CRIRES_NB_DETECTORS] ; 00127 double qc_wlcent[CRIRES_NB_DETECTORS] ; 00128 double qc_wldisp[CRIRES_NB_DETECTORS] ; 00129 double qc_lines_flux[CRIRES_NB_DETECTORS] ; 00130 double qc_fwhm[CRIRES_NB_DETECTORS] ; 00131 double qc_rpower[CRIRES_NB_DETECTORS] ; 00132 } crires_spec_wavecal_config ; 00133 00134 /*----------------------------------------------------------------------------- 00135 Functions code 00136 -----------------------------------------------------------------------------*/ 00137 00138 /*----------------------------------------------------------------------------*/ 00145 /*----------------------------------------------------------------------------*/ 00146 static int crires_spec_wavecal( 00147 cpl_frameset * frameset, 00148 const cpl_parameterlist * parlist) 00149 { 00150 const char * sval ; 00151 const char * wl_ypos ; 00152 cpl_frameset * rawframes ; 00153 const char * fname ; 00154 const char * flat ; 00155 const char * dark ; 00156 const char * bpm ; 00157 const char * detlin ; 00158 const char * thar_cat ; 00159 const char * n2o_cat ; 00160 const char * oh_cat ; 00161 const char * hitran_cat ; 00162 const char * cfg_model ; 00163 const char * thar_positions ; 00164 cpl_propertylist * plist ; 00165 double wmin, wmax ; 00166 cpl_table * wave_tab[CRIRES_NB_DETECTORS] ; 00167 cpl_imagelist * wl_map ; 00168 cpl_imagelist * wl_map_model ; 00169 cpl_vector * wave_ypos ; 00170 int pix ; 00171 int i, j ; 00172 00173 /* Initialise */ 00174 rawframes = NULL ; 00175 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00176 crires_spec_wavecal_config.qc_wlxc[i] = -1.0 ; 00177 crires_spec_wavecal_config.qc_wlcent[i] = -1.0 ; 00178 crires_spec_wavecal_config.qc_wldisp[i] = -1.0 ; 00179 crires_spec_wavecal_config.qc_lines_flux[i] = -1.0 ; 00180 crires_spec_wavecal_config.qc_fwhm[i] = -1.0 ; 00181 crires_spec_wavecal_config.qc_rpower[i] = -1.0 ; 00182 } 00183 crires_spec_wavecal_config.wl_ppm = 0 ; 00184 crires_spec_wavecal_config.wl_slitw = 2.0 ; 00185 crires_spec_wavecal_config.wl_fwhm = 2.0 ; 00186 00187 /* Retrieve input parameters */ 00188 00189 sval = crires_parameterlist_get_string(parlist, RECIPE_STRING, 00190 CRIRES_PARAM_WAVES) ; 00191 if (sscanf(sval, "%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg", 00192 &crires_spec_wavecal_config.wstart[0], 00193 &crires_spec_wavecal_config.wstop[0], 00194 &crires_spec_wavecal_config.wstart[1], 00195 &crires_spec_wavecal_config.wstop[1], 00196 &crires_spec_wavecal_config.wstart[2], 00197 &crires_spec_wavecal_config.wstop[2], 00198 &crires_spec_wavecal_config.wstart[3], 00199 &crires_spec_wavecal_config.wstop[3])!=2*CRIRES_NB_DETECTORS){ 00200 return -1 ; 00201 } 00202 crires_spec_wavecal_config.display = crires_parameterlist_get_int(parlist, 00203 RECIPE_STRING, CRIRES_PARAM_DISPLAY) ; 00204 crires_spec_wavecal_config.wl_log = crires_parameterlist_get_bool(parlist, 00205 RECIPE_STRING, CRIRES_PARAM_WL_LOG) ; 00206 crires_spec_wavecal_config.wl_nolimit = crires_parameterlist_get_bool( 00207 parlist, RECIPE_STRING, CRIRES_PARAM_WL_NOLIMIT) ; 00208 crires_spec_wavecal_config.wl_degree = crires_parameterlist_get_int(parlist, 00209 RECIPE_STRING, CRIRES_PARAM_DEGREE) ; 00210 crires_spec_wavecal_config.wl_err = crires_parameterlist_get_double(parlist, 00211 RECIPE_STRING, CRIRES_PARAM_WL_ERROR) ; 00212 crires_spec_wavecal_config.wl_xclimit = crires_parameterlist_get_double( 00213 parlist, RECIPE_STRING, CRIRES_PARAM_XC_LIMIT) ; 00214 crires_spec_wavecal_config.wl_ypos_c1=crires_parameterlist_get_string( 00215 parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP1) ; 00216 crires_spec_wavecal_config.wl_ypos_c2=crires_parameterlist_get_string( 00217 parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP2) ; 00218 crires_spec_wavecal_config.wl_ypos_c3=crires_parameterlist_get_string( 00219 parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP3) ; 00220 crires_spec_wavecal_config.wl_ypos_c4=crires_parameterlist_get_string( 00221 parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP4) ; 00222 crires_spec_wavecal_config.wl_width= crires_parameterlist_get_int(parlist, 00223 RECIPE_STRING, CRIRES_PARAM_Y_WIDTH) ; 00224 crires_spec_wavecal_config.wl_samples = crires_parameterlist_get_int( 00225 parlist, RECIPE_STRING, CRIRES_PARAM_WL_NBSAMPLES) ; 00226 crires_spec_wavecal_config.wl_clean = crires_parameterlist_get_bool(parlist, 00227 RECIPE_STRING, CRIRES_PARAM_WL_CLEAN) ; 00228 00229 /* Identify the RAW and CALIB frames in the input frameset */ 00230 if (crires_dfs_set_groups(frameset, "crires_spec_wavecal")) { 00231 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ; 00232 return -1 ; 00233 } 00234 00235 /* Retrieve calibration data */ 00236 flat = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT) ; 00237 dark = crires_extract_filename(frameset, CRIRES_CALPRO_DARK) ; 00238 bpm = crires_extract_filename(frameset, CRIRES_CALPRO_BPM) ; 00239 detlin = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ; 00240 thar_cat = crires_extract_filename(frameset, CRIRES_CALPRO_THAR_CAT) ; 00241 n2o_cat = crires_extract_filename(frameset, CRIRES_CALPRO_N2O_CAT) ; 00242 oh_cat = crires_extract_filename(frameset, CRIRES_CALPRO_OH_CAT) ; 00243 hitran_cat = crires_extract_filename(frameset, CRIRES_CALPRO_HITRAN_CAT) ; 00244 cfg_model = crires_extract_filename(frameset, CRIRES_CALPRO_MODEL_CONFIG) ; 00245 thar_positions = crires_extract_filename(frameset, CRIRES_CALPRO_THAR_POS) ; 00246 00247 /* Retrieve raw frames */ 00248 if ((rawframes = crires_extract_frameset(frameset, 00249 CRIRES_SPEC_WAVECAL_SKY_RAW)) != NULL) { 00250 crires_spec_wavecal_config.mode = 1 ; 00251 } else if ((rawframes = crires_extract_frameset(frameset, 00252 CRIRES_SPEC_WAVECAL_LAMP_RAW)) != NULL) { 00253 crires_spec_wavecal_config.mode = 2 ; 00254 } else if ((rawframes = crires_extract_frameset(frameset, 00255 CRIRES_SPEC_WAVECAL_ABS_RAW)) != NULL) { 00256 crires_spec_wavecal_config.mode = 3 ; 00257 } else { 00258 cpl_msg_error(__func__, "No raw frame in input") ; 00259 return -1 ; 00260 } 00261 00262 /* Get the detector illumination period */ 00263 crires_spec_wavecal_config.period = 00264 crires_get_detector_illum_period( 00265 cpl_frame_get_filename(cpl_frameset_get_position(rawframes, 0))) ; 00266 if (crires_spec_wavecal_config.period == CRIRES_ILLUM_UNKNOWN) { 00267 cpl_msg_error(__func__, 00268 "Cannot determine the detector illumination period") ; 00269 cpl_frameset_delete(rawframes) ; 00270 return -1 ; 00271 } else { 00272 crires_display_detector_illum(crires_spec_wavecal_config.period) ; 00273 } 00274 00275 /* Reduce the first raw frame */ 00276 fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ; 00277 00278 /* Get the Minimum and Maximum wavelengths */ 00279 if (crires_spec_wavecal_config.wl_nolimit == 0) { 00280 plist = cpl_propertylist_load(fname, 0) ; 00281 wmin = crires_pfits_get_wlen_min(plist) ; 00282 wmax = crires_pfits_get_wlen_max(plist) ; 00283 cpl_propertylist_delete(plist) ; 00284 if (cpl_error_get_code()) { 00285 wmin = wmax = -1.0 ; 00286 cpl_error_reset() ; 00287 } 00288 } else { 00289 wmin = wmax = -1.0 ; 00290 } 00291 00292 /* Wavelength calibration */ 00293 cpl_msg_info(__func__, "Apply the Wavelength Calibration") ; 00294 cpl_msg_indent_more() ; 00295 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00296 cpl_msg_info(__func__, "Calibrate chip number %d", i+1) ; 00297 cpl_msg_indent_more() ; 00298 00299 /* Where Compute the wavelength from ? */ 00300 wl_ypos = "" ; 00301 if (i+1 == 1) wl_ypos = crires_spec_wavecal_config.wl_ypos_c1 ; 00302 if (i+1 == 2) wl_ypos = crires_spec_wavecal_config.wl_ypos_c2 ; 00303 if (i+1 == 3) wl_ypos = crires_spec_wavecal_config.wl_ypos_c3 ; 00304 if (i+1 == 4) wl_ypos = crires_spec_wavecal_config.wl_ypos_c4 ; 00305 00306 /* Try to parse the user specified positions */ 00307 if (!strcmp(wl_ypos, "")) { 00308 wave_ypos = NULL ; 00309 } else { 00310 cpl_msg_info(__func__, 00311 "Use the Y positions provided on the command line") ; 00312 if ((wave_ypos = crires_parse_y_positions(wl_ypos)) == NULL) { 00313 cpl_msg_warning(__func__, 00314 "Cannot parse the y_positions value : %s", wl_ypos) ; 00315 } 00316 } 00317 00318 /* Otherwise use passed calibration file */ 00319 if (wave_ypos == NULL && thar_positions != NULL) { 00320 cpl_msg_info(__func__, 00321 "Use the Y positions provided in the FITS file") ; 00322 if ((wave_ypos = crires_read_y_positions(thar_positions, 00323 i+1)) == NULL) { 00324 cpl_msg_warning(__func__, 00325 "Cannot read the Y positions from file %s", 00326 thar_positions) ; 00327 } 00328 } 00329 00330 /* Try to detect the positions */ 00331 if (wave_ypos == NULL) { 00332 cpl_msg_info(__func__, 00333 "Try an automatic detection of the Y positions") ; 00334 wave_ypos = crires_wlcalib_detect_wave_ypos(fname, 00335 crires_spec_wavecal_config.period, i+1); 00336 } 00337 00338 /* Check the Mode */ 00339 if (crires_spec_wavecal_config.mode == 1) { 00340 /* Calibrate from the sky */ 00341 cpl_msg_info(__func__,"Get the calibration from the oh/hitran sky"); 00342 wave_tab[i] = crires_wlcalib_sky(fname, 00343 crires_spec_wavecal_config.period, 00344 oh_cat, hitran_cat, crires_spec_wavecal_config.wl_log, 00345 flat, dark, bpm, detlin, 00346 crires_spec_wavecal_config.wstart[i], 00347 crires_spec_wavecal_config.wstop[i], 00348 wmin, wmax, i+1, 00349 wave_ypos, 00350 crires_spec_wavecal_config.wl_width, 00351 crires_spec_wavecal_config.wl_degree, 00352 crires_spec_wavecal_config.wl_slitw, 00353 crires_spec_wavecal_config.wl_fwhm, 00354 crires_spec_wavecal_config.wl_err, 00355 crires_spec_wavecal_config.wl_samples, 00356 crires_spec_wavecal_config.wl_clean, 00357 crires_spec_wavecal_config.wl_xclimit, 00358 crires_spec_wavecal_config.wl_ppm, 00359 (i+1==crires_spec_wavecal_config.display)) ; 00360 } else if (crires_spec_wavecal_config.mode == 2) { 00361 /* Calibrate from the lamp */ 00362 cpl_msg_info(__func__, "Get the calibration from the thar lamp") ; 00363 wave_tab[i] = crires_wlcalib_lamp(fname, 00364 crires_spec_wavecal_config.period, 00365 thar_cat, crires_spec_wavecal_config.wl_log, 00366 flat, dark, bpm, detlin, 00367 crires_spec_wavecal_config.wstart[i], 00368 crires_spec_wavecal_config.wstop[i], 00369 wmin, wmax, i+1, 00370 wave_ypos, 00371 crires_spec_wavecal_config.wl_width, 00372 crires_spec_wavecal_config.wl_degree, 00373 crires_spec_wavecal_config.wl_slitw, 00374 crires_spec_wavecal_config.wl_fwhm, 00375 crires_spec_wavecal_config.wl_err, 00376 crires_spec_wavecal_config.wl_samples, 00377 crires_spec_wavecal_config.wl_clean, 00378 crires_spec_wavecal_config.wl_xclimit, 00379 crires_spec_wavecal_config.wl_ppm, 00380 (i+1==crires_spec_wavecal_config.display), 00381 &(crires_spec_wavecal_config.qc_lines_flux[i]), 00382 &(crires_spec_wavecal_config.qc_fwhm[i]), 00383 &(crires_spec_wavecal_config.qc_rpower[i])) ; 00384 } else if (crires_spec_wavecal_config.mode == 3) { 00385 /* Calibrate from the gas cell */ 00386 cpl_msg_info(__func__, "Get the calibration from the n2o gas cell"); 00387 wave_tab[i] = crires_wlcalib_lamp(fname, 00388 crires_spec_wavecal_config.period, 00389 n2o_cat, crires_spec_wavecal_config.wl_log, 00390 flat, dark, bpm, detlin, 00391 crires_spec_wavecal_config.wstart[i], 00392 crires_spec_wavecal_config.wstop[i], 00393 wmin, wmax, i+1, 00394 wave_ypos, 00395 crires_spec_wavecal_config.wl_width, 00396 crires_spec_wavecal_config.wl_degree, 00397 crires_spec_wavecal_config.wl_slitw, 00398 crires_spec_wavecal_config.wl_fwhm, 00399 crires_spec_wavecal_config.wl_err, 00400 crires_spec_wavecal_config.wl_samples, 00401 crires_spec_wavecal_config.wl_clean, 00402 crires_spec_wavecal_config.wl_xclimit, 00403 crires_spec_wavecal_config.wl_ppm, 00404 (i+1==crires_spec_wavecal_config.display), 00405 &(crires_spec_wavecal_config.qc_lines_flux[i]), 00406 &(crires_spec_wavecal_config.qc_fwhm[i]), 00407 &(crires_spec_wavecal_config.qc_rpower[i])) ; 00408 } 00409 cpl_msg_indent_less() ; 00410 cpl_vector_delete(wave_ypos) ; 00411 } 00412 cpl_msg_indent_less() ; 00413 00414 /* Create the wave map */ 00415 if ((wl_map = crires_wlcalib_gen_wlmap((const cpl_table **)wave_tab)) 00416 == NULL) { 00417 cpl_msg_error(__func__, "Cannot compute the Wavelength Map") ; 00418 cpl_frameset_delete(rawframes) ; 00419 for (j=0 ; j<CRIRES_NB_DETECTORS ; j++) { 00420 if (wave_tab[j] != NULL) cpl_table_delete(wave_tab[j]); 00421 } 00422 return -1 ; 00423 } 00424 00425 /* Compute the QC parameters */ 00426 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00427 crires_spec_wavecal_config.qc_wlcent[i] = 00428 cpl_image_get(cpl_imagelist_get(wl_map, i), 00429 512, 256, &pix) ; 00430 crires_spec_wavecal_config.qc_wldisp[i] = 00431 ((cpl_image_get(cpl_imagelist_get(wl_map, i), 1024, 00432 256, &pix)) - 00433 (cpl_image_get(cpl_imagelist_get(wl_map, i), 1, 00434 256, &pix))) 00435 / 1023 ; 00436 crires_spec_wavecal_config.qc_wlxc[i] = 00437 crires_wlcalib_get_better_xc(wave_tab[i]) ; 00438 } 00439 00440 /* Get the wl map from the model */ 00441 if ((cfg_model != NULL) && (!crires_model_off()) && 00442 (crires_model_config_check(cfg_model, fname) == 0)) { 00443 cpl_msg_info(__func__, "Call the model to get the wavelength map") ; 00444 cpl_msg_indent_more() ; 00445 wl_map_model = crires_model_wavpix(fname, cfg_model, -1) ; 00446 if (wl_map_model == NULL) { 00447 cpl_msg_warning(__func__, "Model function returns NULL") ; 00448 cpl_error_reset() ; 00449 } 00450 cpl_msg_indent_less() ; 00451 } else { 00452 wl_map_model = NULL ; 00453 } 00454 cpl_frameset_delete(rawframes) ; 00455 00456 /* Save the product */ 00457 cpl_msg_info(__func__, "Save the product") ; 00458 cpl_msg_indent_more() ; 00459 if (crires_spec_wavecal_save(wl_map, wl_map_model, 00460 (const cpl_table **)wave_tab, parlist, frameset)) { 00461 cpl_msg_error(__func__, "Cannot save the product") ; 00462 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) 00463 if (wave_tab[i] != NULL) cpl_table_delete(wave_tab[i]); 00464 cpl_imagelist_delete(wl_map) ; 00465 if (wl_map_model) cpl_imagelist_delete(wl_map_model) ; 00466 cpl_msg_indent_less() ; 00467 return -1 ; 00468 } 00469 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) 00470 if (wave_tab[i] != NULL) cpl_table_delete(wave_tab[i]); 00471 cpl_imagelist_delete(wl_map) ; 00472 if (wl_map_model) cpl_imagelist_delete(wl_map_model) ; 00473 cpl_msg_indent_less() ; 00474 00475 /* Return */ 00476 if (cpl_error_get_code()) return -1 ; 00477 else return 0 ; 00478 } 00479 00480 /*----------------------------------------------------------------------------*/ 00490 /*----------------------------------------------------------------------------*/ 00491 static int crires_spec_wavecal_save( 00492 const cpl_imagelist * ilist, 00493 const cpl_imagelist * ilist_model, 00494 const cpl_table ** wl_tab, 00495 const cpl_parameterlist * parlist, 00496 cpl_frameset * set) 00497 { 00498 cpl_propertylist ** qclists ; 00499 const cpl_frame * ref_frame ; 00500 cpl_propertylist * inputlist ; 00501 const char * recipe_name = "crires_spec_wavecal" ; 00502 int i ; 00503 00504 /* Get the reference frame */ 00505 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ; 00506 00507 /* Create the QC lists */ 00508 qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ; 00509 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00510 qclists[i] = cpl_propertylist_new() ; 00511 cpl_propertylist_append_double(qclists[i], "ESO QC CENTWL", 00512 crires_spec_wavecal_config.qc_wlcent[i]) ; 00513 cpl_propertylist_append_double(qclists[i], "ESO QC DISPWL", 00514 crires_spec_wavecal_config.qc_wldisp[i]) ; 00515 cpl_propertylist_append_double(qclists[i], "ESO QC XCORR", 00516 crires_spec_wavecal_config.qc_wlxc[i]) ; 00517 cpl_propertylist_append_double(qclists[i], "ESO QC LINES FLUX", 00518 crires_spec_wavecal_config.qc_lines_flux[i]) ; 00519 cpl_propertylist_append_double(qclists[i], "ESO QC FWHM MED", 00520 crires_spec_wavecal_config.qc_fwhm[i]) ; 00521 cpl_propertylist_append_double(qclists[i], "ESO QC RESOL MED", 00522 crires_spec_wavecal_config.qc_rpower[i]) ; 00523 00524 /* Propagate some keywords from input raw frame extensions */ 00525 inputlist = cpl_propertylist_load_regexp( 00526 cpl_frame_get_filename(ref_frame), i+1, 00527 CRIRES_HEADER_EXT_FORWARD, 0) ; 00528 cpl_propertylist_copy_property_regexp(qclists[i], inputlist, 00529 CRIRES_HEADER_EXT_FORWARD, 0) ; 00530 cpl_propertylist_delete(inputlist) ; 00531 } 00532 00533 /* Write the image */ 00534 crires_image_save(set, 00535 parlist, 00536 set, 00537 ilist, 00538 recipe_name, 00539 CRIRES_WL_MAP_IMA, 00540 CRIRES_PROTYPE_WL_MAP, 00541 crires_spec_wavecal_config.period, 00542 NULL, 00543 (const cpl_propertylist **)qclists, 00544 PACKAGE "/" PACKAGE_VERSION, 00545 "crires_spec_wavecal_ima.fits") ; 00546 00547 if (ilist_model != NULL) { 00548 /* Write the image */ 00549 crires_image_save(set, 00550 parlist, 00551 set, 00552 ilist_model, 00553 recipe_name, 00554 CRIRES_WL_MAP_MODEL_IMA, 00555 CRIRES_PROTYPE_WL_MAP, 00556 crires_spec_wavecal_config.period, 00557 NULL, 00558 (const cpl_propertylist **)qclists, 00559 PACKAGE "/" PACKAGE_VERSION, 00560 "crires_spec_wavecal_ima_model.fits") ; 00561 } 00562 00563 /* Write the table */ 00564 crires_table_save(set, 00565 parlist, 00566 set, 00567 wl_tab, 00568 recipe_name, 00569 CRIRES_CALPRO_WAVE, 00570 CRIRES_PROTYPE_WL_POLY, 00571 NULL, 00572 (const cpl_propertylist **)qclists, 00573 PACKAGE "/" PACKAGE_VERSION, 00574 "crires_spec_wavecal_tab.fits") ; 00575 00576 /* Free and return */ 00577 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) { 00578 cpl_propertylist_delete(qclists[i]) ; 00579 } 00580 cpl_free(qclists) ; 00581 return 0; 00582 }