CRIRES Pipeline Reference Manual 2.3.17
crires_spec_astro.c
1/*
2 * This file is part of the CRIRES Pipeline
3 * Copyright (C) 2002,2003 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27
28#include <locale.h>
29#include "crires_recipe.h"
30
31#include "crires_model_kernel.h"
32#include "crires_combine.h"
33#include "crires_extract.h"
34#include "crires_photom.h"
35#include "crires_wlcalib.h"
36#include "irplib_utils.h"
37
38/*-----------------------------------------------------------------------------
39 Define
40 -----------------------------------------------------------------------------*/
41
42#define RECIPE_STRING "crires_spec_astro"
43
44/*-----------------------------------------------------------------------------
45 Functions prototypes
46 -----------------------------------------------------------------------------*/
47
48static int crires_spec_astro_compare(const cpl_frame *, const cpl_frame *) ;
49static cpl_imagelist ** crires_spec_astro_reduce(cpl_frameset *,
50 const char *, const char *, const char *, const char *, const char *,
51 const char *, const char *, const char *, cpl_imagelist **,
52 cpl_imagelist **, cpl_imagelist **, cpl_imagelist **,
53 cpl_table **, cpl_table **, cpl_table **, cpl_table **) ;
54static int crires_spec_astro_save(const cpl_imagelist **,
55 const cpl_imagelist *, const cpl_imagelist *, const cpl_table **,
56 const cpl_imagelist *, const cpl_imagelist *, int,
57 const cpl_frameset *, const cpl_parameterlist *, cpl_frameset *) ;
58
59static char crires_spec_astro_description[] =
60"crires_spec_astro -- Astrometry recipe\n"
61"The files listed in the Set Of Frames (sof-file) must be tagged:\n"
62"raw-file.fits "CRIRES_SPEC_ASTRO_RAW" or\n"
63"flat-file.fits "CRIRES_CALPRO_FLAT" or\n"
64"bpm-file.fits "CRIRES_CALPRO_BPM" or\n"
65"dark-file.fits "CRIRES_CALPRO_DARK" or\n"
66"detlin-file.fits "CRIRES_CALPRO_COEFFS_CUBE" or\n"
67"wavecal-file.fits "CRIRES_CALPRO_WAVE" or\n"
68"catalog-file.fits "CRIRES_CALPRO_OH_CAT" or\n"
69"catalog-file.fits "CRIRES_CALPRO_HITRAN_CAT" or\n"
70"model-config-file.fits "CRIRES_CALPRO_MODEL_CONFIG".\n"
71"\n"
72"The input data set is a series of nodding observations using different\n"
73" derotator position angles. The data are reduced separately for each\n"
74" of those positions. In order not to degrade the instrument high\n"
75" resolution, the combined images using only NODA or NODB nodding\n"
76" positions can be produced on request. (see --onlyA/B)\n"
77" In this case, the following spectrum extraction can be applied \n"
78" either on the usual combined image or on those NODA/B combined\n"
79" images (see --comb_used).\n"
80"\n"
81"This recipe produces 6 to 11 files per rotation angle:\n"
82" The combined image (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
83" The contribution map (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
84" The combined image using only Nodding A frames (optional)\n"
85" (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
86" The contribution map using only Nodding A frames (optional)\n"
87" (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
88" The combined image using only Nodding B frames (optional)\n"
89" (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
90" The contribution map using only Nodding B frames (optional)\n"
91" (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
92" The table with the extracted spectrum\n"
93" (PRO TYPE = "CRIRES_PROTYPE_SPEC_WL")\n"
94" The profile image (PRO TYPE = "CRIRES_PROTYPE_PROFILE")\n"
95" The background map (PRO TYPE = "CRIRES_PROTYPE_BGD_MAP")\n"
96" The wavelength map (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n"
97" The wavelength map from the model (optional)\n"
98" (PRO TYPE = "CRIRES_PROTYPE_WL_MAP")\n" ;
99
100CRIRES_RECIPE_DEFINE(crires_spec_astro,
101 CRIRES_PARAM_WAVES |
102 CRIRES_PARAM_DISPLAY |
103 CRIRES_PARAM_REFINE |
104 CRIRES_PARAM_ONLYA |
105 CRIRES_PARAM_ONLYB |
106 CRIRES_PARAM_COMB_USED |
107 CRIRES_PARAM_BLIND |
108 CRIRES_PARAM_HOR_SIZE |
109 CRIRES_PARAM_SPEC_HSIZE |
110 CRIRES_PARAM_KAPPA |
111 CRIRES_PARAM_CLOSING_HSIZE |
112 CRIRES_PARAM_CLEAN_RATE |
113 CRIRES_PARAM_REJECT |
114 CRIRES_PARAM_Y_SPEC_ZONE_CHIP1 |
115 CRIRES_PARAM_Y_SPEC_ZONE_CHIP2 |
116 CRIRES_PARAM_Y_SPEC_ZONE_CHIP3 |
117 CRIRES_PARAM_Y_SPEC_ZONE_CHIP4 |
118 CRIRES_PARAM_WL_ERROR |
119 CRIRES_PARAM_XC_LIMIT |
120 CRIRES_PARAM_WL_LOG |
121 CRIRES_PARAM_WL_NOLIMIT |
122 CRIRES_PARAM_WL_NBSAMPLES |
123 CRIRES_PARAM_Y_POS_CHIP1 |
124 CRIRES_PARAM_Y_POS_CHIP2 |
125 CRIRES_PARAM_Y_POS_CHIP3 |
126 CRIRES_PARAM_Y_POS_CHIP4 |
127 CRIRES_PARAM_Y_WIDTH |
128 CRIRES_PARAM_DEGREE |
129 CRIRES_PARAM_WL_CLEAN,
130 "Astrometry recipe",
131 crires_spec_astro_description) ;
132
133/*-----------------------------------------------------------------------------
134 Static variables
135 -----------------------------------------------------------------------------*/
136
137static struct {
138 /* Inputs */
139 int comb_blind ;
140 int comb_refine ;
141 int comb_onlyA ;
142 int comb_onlyB ;
143 crires_comb_method comb_used ;
144 double wstart[CRIRES_NB_DETECTORS] ;
145 double wstop[CRIRES_NB_DETECTORS] ;
146 int wl_nolimit ;
147 int wl_log ;
148 const char * wl_ypos_c1 ;
149 const char * wl_ypos_c2 ;
150 const char * wl_ypos_c3 ;
151 const char * wl_ypos_c4 ;
152 int wl_width ;
153 double wl_fwhm ;
154 double wl_slitw ;
155 int wl_degree ;
156 double wl_err ;
157 int wl_samples ;
158 int wl_clean ;
159 double wl_xclimit ;
160 int wl_ppm ;
161 int extr_box_hor_size ;
162 int extr_spec_hsize ;
163 double extr_kappa ;
164 int extr_closing_hs ;
165 int extr_clean_rate ;
166 int extr_rej_left ;
167 int extr_rej_right ;
168 const char * extr_y_spec_zone_c1 ;
169 const char * extr_y_spec_zone_c2 ;
170 const char * extr_y_spec_zone_c3 ;
171 const char * extr_y_spec_zone_c4 ;
172 int extr_spec_stopy ;
173 int display ;
174 /* Outputs */
175 crires_illum_period period ;
176 int qc_specpos[CRIRES_NB_DETECTORS] ;
177 int qc_specwrec[CRIRES_NB_DETECTORS] ;
178 int qc_specwopt[CRIRES_NB_DETECTORS] ;
179 double qc_specoptmed[CRIRES_NB_DETECTORS] ;
180 double qc_s2nmed[CRIRES_NB_DETECTORS] ;
181 double qc_wlxc[CRIRES_NB_DETECTORS] ;
182 double qc_wlcent[CRIRES_NB_DETECTORS] ;
183 double qc_wldisp[CRIRES_NB_DETECTORS] ;
184 double qc_fwhm_comb_pix[CRIRES_NB_DETECTORS] ;
185 double qc_fwhm_comb_as[CRIRES_NB_DETECTORS] ;
186 double qc_fwhm_prof_pix[CRIRES_NB_DETECTORS] ;
187 double qc_fwhm_prof_as[CRIRES_NB_DETECTORS] ;
188 double qc_fwhm_diff[CRIRES_NB_DETECTORS] ;
189} crires_spec_astro_config ;
190
191/*-----------------------------------------------------------------------------
192 Functions code
193 -----------------------------------------------------------------------------*/
194
195/*----------------------------------------------------------------------------*/
202/*----------------------------------------------------------------------------*/
203static int crires_spec_astro(
204 cpl_frameset * frameset,
205 const cpl_parameterlist * parlist)
206{
207 cpl_frameset * raw_one ;
208 const char * sval ;
209 cpl_frameset * rawframes ;
210 const char * flat ;
211 const char * dark ;
212 const char * bpm ;
213 const char * detlin ;
214 const char * wavecal ;
215 const char * oh_cat ;
216 const char * hitran_cat ;
217 const char * cfg_model ;
218 cpl_size * labels ;
219 cpl_size nlabels ;
220 cpl_imagelist ** comblist ;
221 cpl_table * extr_tab[CRIRES_NB_DETECTORS] ;
222 cpl_imagelist * prof_list ;
223 cpl_imagelist * bgmap_list ;
224 cpl_imagelist * wl_map ;
225 cpl_imagelist * wl_map_model ;
226 int i, j ;
227
228 /* Needed for sscanf() */
229 setlocale(LC_NUMERIC, "C");
230
231 /* Initialise */
232 rawframes = NULL ;
233 crires_spec_astro_config.wl_ppm = 0 ;
234 crires_spec_astro_config.wl_slitw = 2.0 ;
235 crires_spec_astro_config.wl_fwhm = 2.0 ;
236
237 /* Retrieve input parameters */
238 crires_spec_astro_config.display = crires_parameterlist_get_int(parlist,
239 RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
240 crires_spec_astro_config.comb_refine = crires_parameterlist_get_bool(
241 parlist, RECIPE_STRING, CRIRES_PARAM_REFINE) ;
242 crires_spec_astro_config.comb_onlyA = crires_parameterlist_get_bool(
243 parlist, RECIPE_STRING, CRIRES_PARAM_ONLYA) ;
244 crires_spec_astro_config.comb_onlyB = crires_parameterlist_get_bool(
245 parlist, RECIPE_STRING, CRIRES_PARAM_ONLYB) ;
246 sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
247 CRIRES_PARAM_COMB_USED) ;
248 if (!strcmp(sval, "NODA"))
249 crires_spec_astro_config.comb_used = CRIRES_COMB_METHOD_NODA ;
250 else if (!strcmp(sval, "NODB"))
251 crires_spec_astro_config.comb_used = CRIRES_COMB_METHOD_NODB ;
252 else if (!strcmp(sval, "COMB"))
253 crires_spec_astro_config.comb_used = CRIRES_COMB_METHOD_COMB ;
254 else {
255 cpl_msg_error(__func__, "Invalid combination method specified");
256 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
257 return -1;
258 }
259 crires_spec_astro_config.comb_blind = crires_parameterlist_get_bool(
260 parlist, RECIPE_STRING, CRIRES_PARAM_BLIND) ;
261 sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
262 CRIRES_PARAM_WAVES) ;
263 if (sscanf(sval, "%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg",
264 &crires_spec_astro_config.wstart[0],
265 &crires_spec_astro_config.wstop[0],
266 &crires_spec_astro_config.wstart[1],
267 &crires_spec_astro_config.wstop[1],
268 &crires_spec_astro_config.wstart[2],
269 &crires_spec_astro_config.wstop[2],
270 &crires_spec_astro_config.wstart[3],
271 &crires_spec_astro_config.wstop[3])!=2*CRIRES_NB_DETECTORS){
272 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
273 return -1 ;
274 }
275 crires_spec_astro_config.wl_log = crires_parameterlist_get_bool(parlist,
276 RECIPE_STRING, CRIRES_PARAM_WL_LOG) ;
277 crires_spec_astro_config.wl_nolimit = crires_parameterlist_get_bool(
278 parlist, RECIPE_STRING, CRIRES_PARAM_WL_NOLIMIT) ;
279 crires_spec_astro_config.wl_degree = crires_parameterlist_get_int(parlist,
280 RECIPE_STRING, CRIRES_PARAM_DEGREE) ;
281 crires_spec_astro_config.wl_err = crires_parameterlist_get_double(parlist,
282 RECIPE_STRING, CRIRES_PARAM_WL_ERROR) ;
283 crires_spec_astro_config.wl_xclimit = crires_parameterlist_get_double(
284 parlist, RECIPE_STRING, CRIRES_PARAM_XC_LIMIT) ;
285 crires_spec_astro_config.wl_samples = crires_parameterlist_get_int(parlist,
286 RECIPE_STRING, CRIRES_PARAM_WL_NBSAMPLES) ;
287 crires_spec_astro_config.wl_clean = crires_parameterlist_get_bool(parlist,
288 RECIPE_STRING, CRIRES_PARAM_WL_CLEAN) ;
289 crires_spec_astro_config.wl_ypos_c1=(char*)crires_parameterlist_get_string(
290 parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP1) ;
291 crires_spec_astro_config.wl_ypos_c2=(char*)crires_parameterlist_get_string(
292 parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP2) ;
293 crires_spec_astro_config.wl_ypos_c3=(char*)crires_parameterlist_get_string(
294 parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP3) ;
295 crires_spec_astro_config.wl_ypos_c4=(char*)crires_parameterlist_get_string(
296 parlist, RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP4) ;
297 crires_spec_astro_config.wl_width= crires_parameterlist_get_int(parlist,
298 RECIPE_STRING, CRIRES_PARAM_Y_WIDTH) ;
299 crires_spec_astro_config.extr_box_hor_size = crires_parameterlist_get_int(
300 parlist, RECIPE_STRING, CRIRES_PARAM_HOR_SIZE) ;
301 crires_spec_astro_config.extr_spec_hsize = crires_parameterlist_get_int(
302 parlist, RECIPE_STRING, CRIRES_PARAM_SPEC_HSIZE) ;
303 crires_spec_astro_config.extr_kappa = crires_parameterlist_get_double(
304 parlist, RECIPE_STRING, CRIRES_PARAM_KAPPA) ;
305 crires_spec_astro_config.extr_closing_hs = crires_parameterlist_get_int(
306 parlist, RECIPE_STRING, CRIRES_PARAM_CLOSING_HSIZE) ;
307 crires_spec_astro_config.extr_clean_rate = crires_parameterlist_get_double(
308 parlist, RECIPE_STRING, CRIRES_PARAM_CLEAN_RATE) ;
309 sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
310 CRIRES_PARAM_REJECT) ;
311 if (sscanf(sval, "%d,%d",
312 &crires_spec_astro_config.extr_rej_left,
313 &crires_spec_astro_config.extr_rej_right)!=2) {
314 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
315 return -1 ;
316 }
317 crires_spec_astro_config.extr_y_spec_zone_c1 =
318 crires_parameterlist_get_string(parlist, RECIPE_STRING,
319 CRIRES_PARAM_Y_SPEC_ZONE_CHIP1) ;
320 crires_spec_astro_config.extr_y_spec_zone_c2 =
321 crires_parameterlist_get_string(parlist, RECIPE_STRING,
322 CRIRES_PARAM_Y_SPEC_ZONE_CHIP2) ;
323 crires_spec_astro_config.extr_y_spec_zone_c3 =
324 crires_parameterlist_get_string(parlist, RECIPE_STRING,
325 CRIRES_PARAM_Y_SPEC_ZONE_CHIP3) ;
326 crires_spec_astro_config.extr_y_spec_zone_c4 =
327 crires_parameterlist_get_string(parlist, RECIPE_STRING,
328 CRIRES_PARAM_Y_SPEC_ZONE_CHIP4) ;
329
330 /* Identify the RAW and CALIB frames in the input frameset */
331 if (crires_dfs_set_groups(frameset, "crires_spec_astro")) {
332 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
333 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
334 return -1 ;
335 }
336
337 /* Retrieve calibration data */
338 flat = crires_extract_filename(frameset, CRIRES_CALPRO_FLAT) ;
339 dark = crires_extract_filename(frameset, CRIRES_CALPRO_DARK) ;
340 bpm = crires_extract_filename(frameset, CRIRES_CALPRO_BPM) ;
341 detlin = crires_extract_filename(frameset, CRIRES_CALPRO_COEFFS_CUBE) ;
342 wavecal = crires_extract_filename(frameset, CRIRES_CALPRO_WAVE) ;
343 oh_cat = crires_extract_filename(frameset, CRIRES_CALPRO_OH_CAT) ;
344 hitran_cat = crires_extract_filename(frameset, CRIRES_CALPRO_HITRAN_CAT) ;
345 cfg_model = crires_extract_filename(frameset, CRIRES_CALPRO_MODEL_CONFIG);
346
347 /* Retrieve raw frames */
348 if ((rawframes = crires_extract_frameset(frameset,
349 CRIRES_SPEC_ASTRO_RAW)) == NULL) {
350 cpl_msg_error(__func__, "No raw frame in input") ;
351 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
352 return -1 ;
353 }
354
355 /* Checks on the parameters validity */
356 if ((crires_spec_astro_config.comb_used == CRIRES_COMB_METHOD_NODA)
357 && (crires_spec_astro_config.comb_onlyA == 0)) {
358 cpl_msg_warning(__func__,
359 "You forgot to require the NODA image to be produced !") ;
360 crires_spec_astro_config.comb_onlyA = 1 ;
361 }
362 if ((crires_spec_astro_config.comb_used == CRIRES_COMB_METHOD_NODB)
363 && (crires_spec_astro_config.comb_onlyB == 0)) {
364 cpl_msg_warning(__func__,
365 "You forgot to require the NODB image to be produced !") ;
366 crires_spec_astro_config.comb_onlyB = 1 ;
367 }
368
369 /* Get the detector illumination period */
370 crires_spec_astro_config.period =
371 crires_get_detector_illum_period(
372 cpl_frame_get_filename(cpl_frameset_get_position(rawframes, 0))) ;
373 if (crires_spec_astro_config.period == CRIRES_ILLUM_UNKNOWN) {
374 cpl_msg_error(__func__,
375 "Cannot determine the detector illumination period") ;
376 cpl_frameset_delete(rawframes) ;
377 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
378 return -1 ;
379 } else {
380 crires_display_detector_illum(crires_spec_astro_config.period) ;
381 }
382
383 /* Labelise the raw frames with the DROT POSANG */
384 if ((labels = cpl_frameset_labelise(rawframes, crires_spec_astro_compare,
385 &nlabels)) == NULL) {
386 cpl_msg_error(__func__, "Cannot labelise input frames") ;
387 cpl_frameset_delete(rawframes) ;
388 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
389 return -1 ;
390 }
391
392 /* Loop on the settings */
393 for (i=0 ; i<(int)nlabels ; i++) {
394
395 /* Initialise */
396 for (j=0 ; j<CRIRES_NB_DETECTORS ; j++) {
397 crires_spec_astro_config.qc_specpos[j] = -1 ;
398 crires_spec_astro_config.qc_specwrec[j] = -1 ;
399 crires_spec_astro_config.qc_specwopt[j] = -1 ;
400 crires_spec_astro_config.qc_specoptmed[j] = -1.0 ;
401 crires_spec_astro_config.qc_s2nmed[j] = -1.0 ;
402 crires_spec_astro_config.qc_wlxc[j] = -1.0 ;
403 crires_spec_astro_config.qc_wlcent[j] = -1.0 ;
404 crires_spec_astro_config.qc_wldisp[j] = -1.0 ;
405 crires_spec_astro_config.qc_fwhm_comb_pix[j] = -1.0 ;
406 crires_spec_astro_config.qc_fwhm_comb_as[j] = -1.0 ;
407 crires_spec_astro_config.qc_fwhm_prof_pix[j] = -1.0 ;
408 crires_spec_astro_config.qc_fwhm_prof_as[j] = -1.0 ;
409 crires_spec_astro_config.qc_fwhm_diff[j] = -1.0 ;
410 }
411
412 /* Get the frames for the current setting */
413 raw_one = cpl_frameset_extract(rawframes, labels, (cpl_size)i) ;
414
415 /* Reduce data set nb i */
416 cpl_msg_info(__func__, "Reduce data set %d / %"CPL_SIZE_FORMAT,
417 i+1, nlabels);
418 cpl_msg_indent_more() ;
419
420 /* Apply the reduction */
421 if ((comblist = crires_spec_astro_reduce(raw_one, flat, dark, bpm,
422 detlin, wavecal, oh_cat, hitran_cat, cfg_model,
423 &wl_map,
424 &wl_map_model,
425 &prof_list,
426 &bgmap_list,
427 &(extr_tab[0]),
428 &(extr_tab[1]),
429 &(extr_tab[2]),
430 &(extr_tab[3]))) == NULL) {
431 cpl_msg_error(__func__, "Cannot reduce setting") ;
432 cpl_frameset_delete(rawframes) ;
433 cpl_frameset_delete(raw_one) ;
434 cpl_free(labels) ;
435 cpl_msg_indent_less() ;
436 return -1 ;
437 }
438
439 /* Save the product */
440 cpl_msg_info(__func__, "Save the products") ;
441 cpl_msg_indent_more() ;
442 if (crires_spec_astro_save((const cpl_imagelist **)comblist,
443 prof_list, bgmap_list,
444 (const cpl_table **)extr_tab, wl_map, wl_map_model,
445 i+1, raw_one, parlist, frameset)) {
446 cpl_msg_error(__func__, "Cannot save the product") ;
447 cpl_imagelist_delete(comblist[0]) ;
448 cpl_imagelist_delete(comblist[1]) ;
449 if (crires_spec_astro_config.comb_onlyA) {
450 cpl_imagelist_delete(comblist[2]) ;
451 cpl_imagelist_delete(comblist[3]) ;
452 }
453 if (crires_spec_astro_config.comb_onlyB) {
454 cpl_imagelist_delete(comblist[4]) ;
455 cpl_imagelist_delete(comblist[5]) ;
456 }
457 cpl_free(comblist) ;
458 cpl_imagelist_delete(prof_list) ;
459 cpl_imagelist_delete(bgmap_list) ;
460 for (j=0 ; j<CRIRES_NB_DETECTORS ; j++)
461 if (extr_tab[j] != NULL) cpl_table_delete(extr_tab[j]) ;
462 cpl_imagelist_delete(wl_map) ;
463 if (wl_map_model) cpl_imagelist_delete(wl_map_model) ;
464 cpl_frameset_delete(raw_one) ;
465 cpl_frameset_delete(rawframes) ;
466 cpl_free(labels) ;
467 cpl_msg_indent_less() ;
468 return -1 ;
469 }
470 cpl_imagelist_delete(comblist[0]) ;
471 cpl_imagelist_delete(comblist[1]) ;
472 if (crires_spec_astro_config.comb_onlyA) {
473 cpl_imagelist_delete(comblist[2]) ;
474 cpl_imagelist_delete(comblist[3]) ;
475 }
476 if (crires_spec_astro_config.comb_onlyB) {
477 cpl_imagelist_delete(comblist[4]) ;
478 cpl_imagelist_delete(comblist[5]) ;
479 }
480 cpl_free(comblist) ;
481 cpl_imagelist_delete(prof_list) ;
482 cpl_imagelist_delete(bgmap_list) ;
483 for (j=0 ; j<CRIRES_NB_DETECTORS ; j++)
484 if (extr_tab[j] != NULL) cpl_table_delete(extr_tab[j]) ;
485 cpl_imagelist_delete(wl_map) ;
486 if (wl_map_model) cpl_imagelist_delete(wl_map_model) ;
487 cpl_frameset_delete(raw_one) ;
488 cpl_msg_indent_less() ;
489 }
490 cpl_frameset_delete(rawframes) ;
491 cpl_free(labels) ;
492
493 /* Here comes the postprocessing on the 180 degrees difference spectra */
494
495
496
497
498 /* Return */
499 if (cpl_error_get_code()) return -1 ;
500 else return 0 ;
501}
502
503/*----------------------------------------------------------------------------*/
508/*----------------------------------------------------------------------------*/
509static cpl_imagelist ** crires_spec_astro_reduce(
510 cpl_frameset * rawframes,
511 const char * flat,
512 const char * dark,
513 const char * bpm,
514 const char * detlin,
515 const char * wavecal,
516 const char * oh_cat,
517 const char * hitran_cat,
518 const char * cfg_model,
519 cpl_imagelist ** wl_map,
520 cpl_imagelist ** wl_map_model,
521 cpl_imagelist ** prof_list,
522 cpl_imagelist ** bgmap_list,
523 cpl_table ** extr_tab1,
524 cpl_table ** extr_tab2,
525 cpl_table ** extr_tab3,
526 cpl_table ** extr_tab4)
527{
528 cpl_frame * fr ;
529 const char * fname ;
530 const char * wl_ypos ;
531 const char * y_pos ;
532 cpl_propertylist * plist ;
533 double wmin, wmax ;
534 double tot_ndit ;
535 cpl_imagelist ** comblist ;
536 int comblist_offset ;
537 cpl_table * wave_tab[CRIRES_NB_DETECTORS] ;
538 cpl_image * profiles[CRIRES_NB_DETECTORS] ;
539 cpl_image * bg_maps[CRIRES_NB_DETECTORS] ;
540 cpl_imagelist * wl_map_loc ;
541 cpl_imagelist * wl_map_model_loc ;
542 cpl_imagelist * prof_list_loc ;
543 cpl_imagelist * bgmap_list_loc ;
544 cpl_table * extr_tab[CRIRES_NB_DETECTORS] ;
545 cpl_vector ** wavelengths ;
546 cpl_vector * wave_ypos ;
547 int pix ;
548 int extr_spec_stopy, extr_spec_starty ;
549 int i, j ;
550
551 /* Set comblist_offset */
552 if (crires_spec_astro_config.comb_used == CRIRES_COMB_METHOD_COMB)
553 comblist_offset = 0 ;
554 else if (crires_spec_astro_config.comb_used == CRIRES_COMB_METHOD_NODA)
555 comblist_offset = 1 ;
556 else if (crires_spec_astro_config.comb_used == CRIRES_COMB_METHOD_NODB)
557 comblist_offset = 2 ;
558
559 /* Get the total number of NDIT */
560 fr = cpl_frameset_get_position(rawframes, 0);
561 tot_ndit = crires_get_totndit(cpl_frame_get_filename(fr)) ;
562 if (tot_ndit < 0) {
563 cpl_msg_error(__func__, "Cannot get the total number of NDIT") ;
564 return NULL ;
565 }
566 tot_ndit *= cpl_frameset_get_size(rawframes) ;
567
568 /* Images recombination */
569 cpl_msg_info(__func__, "Images combination") ;
570 cpl_msg_indent_more() ;
571 if ((comblist = crires_combine_imagelist(rawframes, NULL,
572 crires_spec_astro_config.period,
573 flat, dark, bpm, detlin, 1,
574 crires_spec_astro_config.comb_blind,
575 crires_spec_astro_config.comb_refine,
576 crires_spec_astro_config.comb_onlyA,
577 crires_spec_astro_config.comb_onlyB)) == NULL) {
578 cpl_msg_error(__func__, "Cannot combine the images") ;
579 cpl_msg_indent_less() ;
580 return NULL ;
581 }
582 cpl_msg_indent_less() ;
583
584 /* Spectrum extraction */
585 cpl_msg_info(__func__, "Spectrum extraction") ;
586 cpl_msg_indent_more() ;
587 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
588 cpl_msg_info(__func__, "Chip number %d extraction", i+1) ;
589 cpl_msg_indent_more() ;
590
591 /* Where is the spectrum extraction zone ? */
592 y_pos = "" ;
593 if (i+1 == 1) y_pos = crires_spec_astro_config.extr_y_spec_zone_c1 ;
594 if (i+1 == 2) y_pos = crires_spec_astro_config.extr_y_spec_zone_c1 ;
595 if (i+1 == 3) y_pos = crires_spec_astro_config.extr_y_spec_zone_c3 ;
596 if (i+1 == 4) y_pos = crires_spec_astro_config.extr_y_spec_zone_c4 ;
597 if (sscanf(y_pos,"%d,%d", &extr_spec_starty, &extr_spec_stopy)!=2) {
598 cpl_msg_warning(__func__, "Wrong Spectral Zone specified: %s",
599 y_pos) ;
600 extr_spec_starty = extr_spec_stopy = -1 ;
601 }
602
603 /* Extraction */
604 if ((extr_tab[i] = crires_extract_spectrum(
605 cpl_imagelist_get(comblist[0+2*comblist_offset], i),
606 cpl_imagelist_get(comblist[1+2*comblist_offset], i),
607 crires_spec_astro_config.extr_box_hor_size,
608 crires_spec_astro_config.extr_spec_hsize,
609 crires_spec_astro_config.extr_kappa,
610 crires_spec_astro_config.extr_closing_hs,
611 crires_spec_astro_config.extr_clean_rate,
612 crires_spec_astro_config.extr_rej_left,
613 crires_spec_astro_config.extr_rej_right,
614 extr_spec_starty, extr_spec_stopy,
615 i+1,
616 tot_ndit,
617 crires_spec_astro_config.period,
618 &(crires_spec_astro_config.qc_specpos[i]),
619 &(crires_spec_astro_config.qc_specwrec[i]),
620 &(crires_spec_astro_config.qc_specwopt[i]),
621 &(crires_spec_astro_config.qc_specoptmed[i]),
622 &(crires_spec_astro_config.qc_s2nmed[i]),
623 &(profiles[i]),
624 &(bg_maps[i]))) == NULL) {
625 cpl_msg_error(__func__, "Cannot extract the spectrum") ;
626 cpl_msg_indent_less() ;
627 cpl_msg_indent_less() ;
628 for (j=0 ; j<i ; j++)
629 cpl_table_delete(extr_tab[j]) ;
630 for (j=0 ; j<i ; j++)
631 cpl_image_delete(profiles[j]) ;
632 for (j=0 ; j<i ; j++)
633 cpl_image_delete(bg_maps[j]) ;
634 cpl_imagelist_delete(comblist[0]) ;
635 cpl_imagelist_delete(comblist[1]) ;
636 if (crires_spec_astro_config.comb_onlyA) {
637 cpl_imagelist_delete(comblist[2]) ;
638 cpl_imagelist_delete(comblist[3]) ;
639 }
640 if (crires_spec_astro_config.comb_onlyB) {
641 cpl_imagelist_delete(comblist[4]) ;
642 cpl_imagelist_delete(comblist[5]) ;
643 }
644 cpl_free(comblist) ;
645 return NULL ;
646 }
647 cpl_msg_info(__func__, "Chip number %d FWHM Computation", i+1) ;
648 if (crires_extract_qc_fwhm(
649 cpl_imagelist_get(comblist[0+2*comblist_offset], i),
650 profiles[i],
651 &(crires_spec_astro_config.qc_fwhm_comb_pix[i]),
652 &(crires_spec_astro_config.qc_fwhm_comb_as[i]),
653 &(crires_spec_astro_config.qc_fwhm_prof_pix[i]),
654 &(crires_spec_astro_config.qc_fwhm_prof_as[i]),
655 &(crires_spec_astro_config.qc_fwhm_diff[i])) == -1) {
656 cpl_msg_warning(__func__, "Failed for FWHM computation") ;
657 crires_spec_astro_config.qc_fwhm_comb_pix[i] = -1.0 ;
658 crires_spec_astro_config.qc_fwhm_comb_as[i] = -1.0 ;
659 crires_spec_astro_config.qc_fwhm_prof_pix[i] = -1.0 ;
660 crires_spec_astro_config.qc_fwhm_prof_as[i] = -1.0 ;
661 crires_spec_astro_config.qc_fwhm_diff[i] = -1.0 ;
662 }
663 cpl_msg_indent_less() ;
664 }
665
666 /* Create the profile and bg maps */
667 prof_list_loc = cpl_imagelist_new() ;
668 bgmap_list_loc = cpl_imagelist_new() ;
669 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
670 cpl_imagelist_set(prof_list_loc, profiles[i], i) ;
671 cpl_imagelist_set(bgmap_list_loc, bg_maps[i], i) ;
672 }
673
674 /* Test that the spectrum is at the same place in all detectors */
675 for (i=1 ; i<CRIRES_NB_DETECTORS ; i++) {
676 if (crires_spec_astro_config.qc_specpos[i-1] > 0 &&
677 crires_spec_astro_config.qc_specpos[i] > 0 &&
678 fabs(crires_spec_astro_config.qc_specpos[i-1] -
679 crires_spec_astro_config.qc_specpos[i]) >
680 CRIRES_SPEC_POS_TOLERANCE) {
681 cpl_msg_warning(__func__,
682 "The spectrum positions in chip %d and chip %d are too different: %d -> %d",
683 i, i+1, crires_spec_astro_config.qc_specpos[i-1],
684 crires_spec_astro_config.qc_specpos[i]) ;
685 }
686 }
687 cpl_msg_indent_less() ;
688
689 /* Wavelength calibration */
690 cpl_msg_info(__func__, "Wavelength Calibration") ;
691 cpl_msg_indent_more() ;
692 if (wavecal != NULL) {
693 /* Wavelength solution is provided */
694 cpl_msg_info(__func__, "Use the provided solution") ;
695 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
696 if ((wave_tab[i] = crires_load_table_check(wavecal, i+1,
697 CRIRES_PROTYPE_WL_POLY, -1, -1, 0)) == NULL) {
698 cpl_msg_error(__func__, "Cannot load the wavelength table") ;
699 cpl_msg_indent_less() ;
700 cpl_imagelist_delete(comblist[0]) ;
701 cpl_imagelist_delete(comblist[1]) ;
702 if (crires_spec_astro_config.comb_onlyA) {
703 cpl_imagelist_delete(comblist[2]) ;
704 cpl_imagelist_delete(comblist[3]) ;
705 }
706 if (crires_spec_astro_config.comb_onlyB) {
707 cpl_imagelist_delete(comblist[4]) ;
708 cpl_imagelist_delete(comblist[5]) ;
709 }
710 cpl_free(comblist) ;
711 cpl_imagelist_delete(prof_list_loc) ;
712 cpl_imagelist_delete(bgmap_list_loc) ;
713 for (j=0 ; j<CRIRES_NB_DETECTORS ; j++)
714 cpl_table_delete(extr_tab[j]) ;
715 return NULL ;
716 }
717 }
718 } else {
719 /* Calibrate from the science */
720 cpl_msg_info(__func__, "Use the science frame sky to calibrate") ;
721
722 /* first raw frame */
723 fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
724
725 /* Get the Minimum and Maximum wavelengths */
726 if (crires_spec_astro_config.wl_nolimit == 0) {
727 plist = cpl_propertylist_load(fname, 0) ;
728 wmin = crires_pfits_get_wlen_min(plist) ;
729 wmax = crires_pfits_get_wlen_max(plist) ;
730 cpl_propertylist_delete(plist) ;
731 if (cpl_error_get_code()) {
732 wmin = wmax = -1.0 ;
733 cpl_error_reset() ;
734 }
735 } else {
736 wmin = wmax = -1.0 ;
737 }
738
739 /* Loop on detectors */
740 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
741 cpl_msg_info(__func__, "Calibrate chip number %d", i+1) ;
742 cpl_msg_indent_more() ;
743
744 /* Where Compute the wavelength from ? */
745 if (i+1 == 1) wl_ypos = crires_spec_astro_config.wl_ypos_c1 ;
746 if (i+1 == 2) wl_ypos = crires_spec_astro_config.wl_ypos_c2 ;
747 if (i+1 == 3) wl_ypos = crires_spec_astro_config.wl_ypos_c3 ;
748 if (i+1 == 4) wl_ypos = crires_spec_astro_config.wl_ypos_c4 ;
749
750 if (!strcmp(wl_ypos, "")) {
751 /* Use the spectrum position for the wavelength calibration */
752 cpl_msg_info(__func__,
753 "Compute the wavelength at the spectrum position: %d",
754 crires_spec_astro_config.qc_specpos[i]) ;
755 wave_ypos = cpl_vector_new(1) ;
756 cpl_vector_set(wave_ypos, 0,
757 (double)(crires_spec_astro_config.qc_specpos[i])) ;
758 } else {
759 cpl_msg_info(__func__,
760 "Use the Y positions provided on the command line") ;
761 if ((wave_ypos = crires_parse_y_positions(wl_ypos)) == NULL) {
762 cpl_msg_error(__func__,
763 "Cannot parse the y_pos value : %s - use %d",
764 wl_ypos, crires_spec_astro_config.qc_specpos[i]) ;
765 wave_ypos = cpl_vector_new(1) ;
766 cpl_vector_set(wave_ypos, 0,
767 (double)(crires_spec_astro_config.qc_specpos[i])) ;
768 }
769 }
770
771 /* Wavelength Calibration */
772 wave_tab[i] = crires_wlcalib_sky(fname,
773 crires_spec_astro_config.period,
774 oh_cat, hitran_cat, crires_spec_astro_config.wl_log,
775 flat, dark, bpm, detlin,
776 crires_spec_astro_config.wstart[i],
777 crires_spec_astro_config.wstop[i],
778 wmin, wmax, i+1,
779 wave_ypos,
780 crires_spec_astro_config.wl_width,
781 crires_spec_astro_config.wl_degree,
782 crires_spec_astro_config.wl_slitw,
783 crires_spec_astro_config.wl_fwhm,
784 crires_spec_astro_config.wl_err,
785 crires_spec_astro_config.wl_samples,
786 crires_spec_astro_config.wl_clean,
787 crires_spec_astro_config.wl_xclimit,
788 crires_spec_astro_config.wl_ppm,
789 (i+1==crires_spec_astro_config.display)) ;
790 cpl_msg_indent_less() ;
791
792 cpl_vector_delete(wave_ypos) ;
793 }
794 }
795
796 /* Create the wave map */
797 if ((wl_map_loc = crires_wlcalib_gen_wlmap((const cpl_table **)wave_tab))
798 == NULL) {
799 cpl_msg_error(__func__, "Cannot compute the Wavelength Map") ;
800 cpl_imagelist_delete(comblist[0]) ;
801 cpl_imagelist_delete(comblist[1]) ;
802 if (crires_spec_astro_config.comb_onlyA) {
803 cpl_imagelist_delete(comblist[2]) ;
804 cpl_imagelist_delete(comblist[3]) ;
805 }
806 if (crires_spec_astro_config.comb_onlyB) {
807 cpl_imagelist_delete(comblist[4]) ;
808 cpl_imagelist_delete(comblist[5]) ;
809 }
810 cpl_free(comblist) ;
811 cpl_imagelist_delete(prof_list_loc) ;
812 cpl_imagelist_delete(bgmap_list_loc) ;
813 for (j=0 ; j<CRIRES_NB_DETECTORS ; j++) {
814 cpl_table_delete(extr_tab[j]) ;
815 if (wave_tab[j] != NULL) cpl_table_delete(wave_tab[j]);
816 }
817 return NULL ;
818 }
819
820 /* Compute the QC parameters */
821 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
822 crires_spec_astro_config.qc_wlcent[i] =
823 cpl_image_get(cpl_imagelist_get(wl_map_loc, i),
824 512, crires_spec_astro_config.qc_specpos[i], &pix) ;
825 crires_spec_astro_config.qc_wldisp[i] =
826 ((cpl_image_get(cpl_imagelist_get(wl_map_loc, i), 1024,
827 crires_spec_astro_config.qc_specpos[i], &pix)) -
828 (cpl_image_get(cpl_imagelist_get(wl_map_loc, i), 1,
829 crires_spec_astro_config.qc_specpos[i], &pix)))
830 / 1023 ;
831 crires_spec_astro_config.qc_wlxc[i] =
832 crires_wlcalib_get_better_xc(wave_tab[i]) ;
833 }
834 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
835 if (wave_tab[i] != NULL) cpl_table_delete(wave_tab[i]);
836
837 /* Get the wl map from the model */
838 fname = cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)) ;
839 if ((cfg_model != NULL) && (!crires_model_off()) &&
840 (crires_model_config_check(cfg_model, fname) == 0)) {
841 cpl_msg_info(__func__, "Call the model to get the wavelength map") ;
842 cpl_msg_indent_more() ;
843 wl_map_model_loc = crires_model_wavpix(fname, cfg_model, -1) ;
844 if (wl_map_model_loc == NULL) {
845 cpl_msg_warning(__func__, "Model function returns NULL") ;
846 cpl_error_reset() ;
847 }
848 cpl_msg_indent_less() ;
849 } else {
850 wl_map_model_loc = NULL ;
851 }
852
853 /* Apply the wavelength */
854 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
855 cpl_table_new_column(extr_tab[i], CRIRES_COL_WAVELENGTH,
856 CPL_TYPE_DOUBLE) ;
857 for (j=0 ; j<cpl_table_get_nrow(extr_tab[i]) ; j++) {
858 cpl_table_set_double(extr_tab[i], CRIRES_COL_WAVELENGTH, j,
859 cpl_image_get(cpl_imagelist_get_const(wl_map_loc, i), j+1,
860 crires_spec_astro_config.qc_specpos[i], &pix));
861 }
862 }
863
864 /* Add the Model Wavelength and Call the model to fill it */
865 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
866 cpl_table_new_column(extr_tab[i], CRIRES_COL_WAVELENGTH_MODEL,
867 CPL_TYPE_DOUBLE) ;
868 cpl_table_fill_column_window_double(extr_tab[i],
869 CRIRES_COL_WAVELENGTH_MODEL, 0,
870 cpl_table_get_nrow(extr_tab[i]), -1.0) ;
871 }
872 if ((cfg_model != NULL) && (!crires_model_off()) && (1)) {
873 cpl_msg_info(__func__, "Call the model to get the wavelengths") ;
874 cpl_msg_indent_more() ;
875 wavelengths = crires_model_wavelengths(
876 cpl_frame_get_filename(cpl_frameset_get_position(rawframes,0)),
877 cfg_model, -1,
878 (double)(crires_spec_astro_config.qc_specpos[0]),
879 wl_map_model_loc) ;
880 if (wavelengths != NULL) {
881 /* Loop on the detectors */
882 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
883 /* Loop on the x values */
884 for (j=0 ; j<cpl_vector_get_size(wavelengths[i]) ; j++) {
885 cpl_table_set_double(extr_tab[i],
886 CRIRES_COL_WAVELENGTH_MODEL, j,
887 cpl_vector_get(wavelengths[i], j)) ;
888 }
889 }
890 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++)
891 cpl_vector_delete(wavelengths[i]) ;
892 cpl_free(wavelengths) ;
893 } else {
894 cpl_msg_warning(__func__, "Model function returns NULL") ;
895 cpl_error_reset() ;
896 }
897 cpl_msg_indent_less() ;
898 }
899
900 /* Return */
901 if (wl_map != NULL) *wl_map = wl_map_loc ;
902 else cpl_imagelist_delete(wl_map_loc) ;
903 if (wl_map_model != NULL) *wl_map_model = wl_map_model_loc ;
904 else cpl_imagelist_delete(wl_map_model_loc) ;
905 if (prof_list != NULL) *prof_list = prof_list_loc ;
906 else cpl_imagelist_delete(prof_list_loc) ;
907 if (bgmap_list != NULL) *bgmap_list = bgmap_list_loc ;
908 else cpl_imagelist_delete(bgmap_list_loc) ;
909 if (extr_tab1 != NULL) *extr_tab1 = extr_tab[0] ;
910 else cpl_table_delete(extr_tab[0]) ;
911 if (extr_tab2 != NULL) *extr_tab2 = extr_tab[1] ;
912 else cpl_table_delete(extr_tab[1]) ;
913 if (extr_tab3 != NULL) *extr_tab3 = extr_tab[2] ;
914 else cpl_table_delete(extr_tab[2]) ;
915 if (extr_tab4 != NULL) *extr_tab4 = extr_tab[3] ;
916 else cpl_table_delete(extr_tab[3]) ;
917 return comblist ;
918}
919
920/*----------------------------------------------------------------------------*/
936/*----------------------------------------------------------------------------*/
937static int crires_spec_astro_save(
938 const cpl_imagelist ** images,
939 const cpl_imagelist * prof,
940 const cpl_imagelist * bgmap,
941 const cpl_table ** extr_tab,
942 const cpl_imagelist * wl_map,
943 const cpl_imagelist * wl_map_model,
944 int setting,
945 const cpl_frameset * cur_set,
946 const cpl_parameterlist * parlist,
947 cpl_frameset * set)
948{
949 cpl_propertylist ** qclists ;
950 const cpl_frame * ref_frame ;
951 char * filename ;
952 cpl_propertylist * inputlist ;
953 const char * recipe_name = "crires_spec_astro" ;
954 int i ;
955
956 /* Get the reference frame */
957 ref_frame = irplib_frameset_get_first_from_group(cur_set,
958 CPL_FRAME_GROUP_RAW) ;
959
960 /* Create the QC lists */
961 qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
962 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
963 qclists[i] = cpl_propertylist_new() ;
964 cpl_propertylist_append_int(qclists[i], "ESO QC SPECPOS",
965 crires_spec_astro_config.qc_specpos[i]) ;
966 cpl_propertylist_append_int(qclists[i], "ESO QC SPECWREC",
967 crires_spec_astro_config.qc_specwrec[i]) ;
968 cpl_propertylist_append_int(qclists[i], "ESO QC SPECWOPT",
969 crires_spec_astro_config.qc_specwopt[i]) ;
970 cpl_propertylist_append_double(qclists[i], "ESO QC SIGNAL MED",
971 crires_spec_astro_config.qc_specoptmed[i]) ;
972 cpl_propertylist_append_double(qclists[i], "ESO QC S2NMED",
973 crires_spec_astro_config.qc_s2nmed[i]) ;
974 cpl_propertylist_append_double(qclists[i], "ESO QC XCORR",
975 crires_spec_astro_config.qc_wlxc[i]) ;
976 cpl_propertylist_append_double(qclists[i], "ESO QC CENTWL",
977 crires_spec_astro_config.qc_wlcent[i]) ;
978 cpl_propertylist_append_double(qclists[i], "ESO QC DISPWL",
979 crires_spec_astro_config.qc_wldisp[i]) ;
980 cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX COMBINED",
981 crires_spec_astro_config.qc_fwhm_comb_pix[i]) ;
982 cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC COMBINED",
983 crires_spec_astro_config.qc_fwhm_comb_as[i]) ;
984 cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX PROFILE",
985 crires_spec_astro_config.qc_fwhm_prof_pix[i]) ;
986 cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC PROFILE",
987 crires_spec_astro_config.qc_fwhm_prof_as[i]) ;
988 cpl_propertylist_append_double(qclists[i], "ESO QC FWHM DIFF",
989 crires_spec_astro_config.qc_fwhm_diff[i]) ;
990 /* Propagate some keywords from input raw frame extensions */
991 inputlist = cpl_propertylist_load_regexp(
992 cpl_frame_get_filename(ref_frame), i+1,
993 CRIRES_HEADER_EXT_FORWARD, 0) ;
994 cpl_propertylist_copy_property_regexp(qclists[i], inputlist,
995 CRIRES_HEADER_EXT_FORWARD, 0) ;
996 cpl_propertylist_delete(inputlist) ;
997 }
998
999 /* Write the combined image */
1000 filename = cpl_sprintf("%s_comb_set%02d.fits", recipe_name, setting) ;
1001 crires_image_save(set,
1002 parlist,
1003 cur_set,
1004 images[0],
1005 recipe_name,
1006 CRIRES_ASTRO_COMBINED_IMA,
1007 CRIRES_PROTYPE_COMBINED,
1008 crires_spec_astro_config.period,
1009 NULL,
1010 (const cpl_propertylist **)qclists,
1011 PACKAGE "/" PACKAGE_VERSION,
1012 filename) ;
1013 cpl_free(filename) ;
1014
1015 /* Write the contribution map */
1016 filename = cpl_sprintf("%s_contrib_set%02d.fits", recipe_name, setting) ;
1017 crires_image_save(set,
1018 parlist,
1019 cur_set,
1020 images[1],
1021 recipe_name,
1022 CRIRES_ASTRO_CONTRIBUTION_IMA,
1023 CRIRES_PROTYPE_CONTRIB,
1024 crires_spec_astro_config.period,
1025 NULL,
1026 (const cpl_propertylist **)qclists,
1027 PACKAGE "/" PACKAGE_VERSION,
1028 filename) ;
1029 cpl_free(filename) ;
1030
1031 /* Nodded A support */
1032 if (crires_spec_astro_config.comb_onlyA) {
1033 /* Write the combined image */
1034 filename = cpl_sprintf("%s_comb_noddedA_set%02d.fits",
1035 recipe_name, setting) ;
1036 crires_image_save(set,
1037 parlist,
1038 cur_set,
1039 images[2],
1040 recipe_name,
1041 CRIRES_ASTRO_COMBINED_IMA,
1042 CRIRES_PROTYPE_COMBINED,
1043 crires_spec_astro_config.period,
1044 NULL,
1045 (const cpl_propertylist **)qclists,
1046 PACKAGE "/" PACKAGE_VERSION,
1047 filename) ;
1048 cpl_free(filename) ;
1049
1050 /* Write the contribution map */
1051 filename = cpl_sprintf("%s_contrib_noddedA_set%02d.fits",
1052 recipe_name, setting) ;
1053 crires_image_save(set,
1054 parlist,
1055 cur_set,
1056 images[3],
1057 recipe_name,
1058 CRIRES_ASTRO_CONTRIBUTION_IMA,
1059 CRIRES_PROTYPE_CONTRIB,
1060 crires_spec_astro_config.period,
1061 NULL,
1062 (const cpl_propertylist **)qclists,
1063 PACKAGE "/" PACKAGE_VERSION,
1064 filename) ;
1065 cpl_free(filename) ;
1066 }
1067
1068 /* Nodded B support */
1069 if (crires_spec_astro_config.comb_onlyB) {
1070 /* Write the combined image */
1071 filename = cpl_sprintf("%s_comb_noddedB_set%02d.fits",
1072 recipe_name, setting) ;
1073 crires_image_save(set,
1074 parlist,
1075 cur_set,
1076 images[4],
1077 recipe_name,
1078 CRIRES_ASTRO_COMBINED_IMA,
1079 CRIRES_PROTYPE_COMBINED,
1080 crires_spec_astro_config.period,
1081 NULL,
1082 (const cpl_propertylist **)qclists,
1083 PACKAGE "/" PACKAGE_VERSION,
1084 filename) ;
1085 cpl_free(filename) ;
1086
1087 /* Write the contribution map */
1088 filename = cpl_sprintf("%s_contrib_noddedB_set%02d.fits",
1089 recipe_name, setting) ;
1090 crires_image_save(set,
1091 parlist,
1092 cur_set,
1093 images[5],
1094 recipe_name,
1095 CRIRES_ASTRO_CONTRIBUTION_IMA,
1096 CRIRES_PROTYPE_CONTRIB,
1097 crires_spec_astro_config.period,
1098 NULL,
1099 (const cpl_propertylist **)qclists,
1100 PACKAGE "/" PACKAGE_VERSION,
1101 filename) ;
1102 cpl_free(filename) ;
1103 }
1104
1105 /* Write the profile image */
1106 filename = cpl_sprintf("%s_prof_set%02d.fits", recipe_name, setting) ;
1107 crires_image_save(set,
1108 parlist,
1109 cur_set,
1110 prof,
1111 recipe_name,
1112 CRIRES_ASTRO_EXTRACT_PROFILE_IMA,
1113 CRIRES_PROTYPE_PROFILE,
1114 crires_spec_astro_config.period,
1115 NULL,
1116 (const cpl_propertylist **)qclists,
1117 PACKAGE "/" PACKAGE_VERSION,
1118 filename) ;
1119 cpl_free(filename) ;
1120
1121 /* Write the background image */
1122 filename = cpl_sprintf("%s_bgmap_set%02d.fits", recipe_name, setting) ;
1123 crires_image_save(set,
1124 parlist,
1125 cur_set,
1126 bgmap,
1127 recipe_name,
1128 CRIRES_ASTRO_EXTRACT_BGMAP_IMA,
1129 CRIRES_PROTYPE_BGD_MAP,
1130 crires_spec_astro_config.period,
1131 NULL,
1132 (const cpl_propertylist **)qclists,
1133 PACKAGE "/" PACKAGE_VERSION,
1134 filename) ;
1135 cpl_free(filename) ;
1136
1137 /* Write the map */
1138 filename = cpl_sprintf("%s_wlmap_set%02d.fits", recipe_name, setting) ;
1139 crires_image_save(set,
1140 parlist,
1141 cur_set,
1142 wl_map,
1143 recipe_name,
1144 CRIRES_ASTRO_WL_MAP_IMA,
1145 CRIRES_PROTYPE_WL_MAP,
1146 crires_spec_astro_config.period,
1147 NULL,
1148 (const cpl_propertylist **)qclists,
1149 PACKAGE "/" PACKAGE_VERSION,
1150 filename) ;
1151 cpl_free(filename) ;
1152
1153 if (wl_map_model != NULL) {
1154 /* Write the model map */
1155 filename = cpl_sprintf("%s_wlmap_model_set%02d.fits", recipe_name,
1156 setting) ;
1157 crires_image_save(set,
1158 parlist,
1159 cur_set,
1160 wl_map_model,
1161 recipe_name,
1162 CRIRES_ASTRO_WL_MAP_MODEL_IMA,
1163 CRIRES_PROTYPE_WL_MAP,
1164 crires_spec_astro_config.period,
1165 NULL,
1166 (const cpl_propertylist **)qclists,
1167 PACKAGE "/" PACKAGE_VERSION,
1168 filename) ;
1169 cpl_free(filename) ;
1170 }
1171
1172 /* Write the extracted spectra */
1173 filename = cpl_sprintf("%s_extracted_set%02d.fits", recipe_name, setting);
1174 crires_table_save(set,
1175 parlist,
1176 cur_set,
1177 extr_tab,
1178 recipe_name,
1179 CRIRES_ASTRO_EXTRACT_WL_TAB,
1180 CRIRES_PROTYPE_SPEC_WL,
1181 NULL,
1182 (const cpl_propertylist **)qclists,
1183 PACKAGE "/" PACKAGE_VERSION,
1184 filename) ;
1185 cpl_free(filename) ;
1186
1187 /* Free and return */
1188 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
1189 cpl_propertylist_delete(qclists[i]) ;
1190 }
1191 cpl_free(qclists) ;
1192 return 0;
1193}
1194
1195/*----------------------------------------------------------------------------*/
1202/*----------------------------------------------------------------------------*/
1203static int crires_spec_astro_compare(
1204 const cpl_frame * frame1,
1205 const cpl_frame * frame2)
1206{
1207 int comparison ;
1208 cpl_propertylist * plist1 ;
1209 cpl_propertylist * plist2 ;
1210 double dval1, dval2 ;
1211 int ival1, ival2 ;
1212
1213 /* Test entries */
1214 if (frame1==NULL || frame2==NULL) return -1 ;
1215
1216 /* Get property lists */
1217 if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),0))==NULL){
1218 cpl_msg_error(__func__, "getting header from reference frame");
1219 return -1 ;
1220 }
1221 if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),0))==NULL){
1222 cpl_msg_error(__func__, "getting header from reference frame");
1223 cpl_propertylist_delete(plist1) ;
1224 return -1 ;
1225 }
1226
1227 /* Test status */
1228 if (cpl_error_get_code()) {
1229 cpl_propertylist_delete(plist1) ;
1230 cpl_propertylist_delete(plist2) ;
1231 return -1 ;
1232 }
1233
1234 comparison = 1 ;
1235
1236 /* Compare the DROT POSANG used */
1237 dval1 = crires_pfits_get_dit(plist1) ;
1238 dval2 = crires_pfits_get_dit(plist2) ;
1239 if (cpl_error_get_code()) {
1240 cpl_msg_error(__func__, "Cannot get the POSANG");
1241 cpl_propertylist_delete(plist1) ;
1242 cpl_propertylist_delete(plist2) ;
1243 return -1 ;
1244 }
1245 if (fabs(dval1-dval2) > 1e-3) comparison = 0 ;
1246
1247 /* Check if the frames are consecutive */
1248 ival1 = crires_pfits_get_expno(plist1) ;
1249 ival2 = crires_pfits_get_expno(plist2) ;
1250 if (cpl_error_get_code()) {
1251 cpl_msg_error(__func__, "Cannot get the EXPNO");
1252 cpl_propertylist_delete(plist1) ;
1253 cpl_propertylist_delete(plist2) ;
1254 return -1 ;
1255 }
1256 if (fabs(ival2-ival1) != 1.0) comparison = 0 ;
1257
1258 cpl_propertylist_delete(plist1) ;
1259 cpl_propertylist_delete(plist2) ;
1260 return comparison ;
1261}