CRIRES Pipeline Reference Manual 2.3.17
crires_util_extract.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_extract.h"
32#include "irplib_utils.h"
33
34/*-----------------------------------------------------------------------------
35 Define
36 -----------------------------------------------------------------------------*/
37
38#define RECIPE_STRING "crires_util_extract"
39
40/*-----------------------------------------------------------------------------
41 Functions prototypes
42 -----------------------------------------------------------------------------*/
43
44static int crires_util_extract_save(const cpl_table **, const cpl_imagelist *,
45 const cpl_imagelist *, const cpl_parameterlist *, cpl_frameset *) ;
46
47static char crires_util_extract_description[] =
48"This recipe accepts 1 parameter (optionally a 2nd one):\n"
49"First parameter: the combined image.\n"
50" (PRO TYPE = "CRIRES_PROTYPE_COMBINED")\n"
51"Second parameter (optional): the contribution map.\n"
52" (PRO TYPE = "CRIRES_PROTYPE_CONTRIB")\n"
53"\n"
54"This recipe produces 3 files:\n"
55"First product: the image of the profile of the spectrum\n"
56" (PRO TYPE = "CRIRES_PROTYPE_PROFILE")\n"
57"Second product: the table of the extracted spectrum in pixels\n"
58" (PRO TYPE = "CRIRES_PROTYPE_SPEC_PIX")\n"
59"Third product: the maps of the background\n"
60" (PRO TYPE = "CRIRES_PROTYPE_BGD_MAP")\n" ;
61
62CRIRES_RECIPE_DEFINE(crires_util_extract,
63 CRIRES_PARAM_DISPLAY |
64 CRIRES_PARAM_EXTR_MODE |
65 CRIRES_PARAM_HOR_SIZE |
66 CRIRES_PARAM_SPEC_HSIZE |
67 CRIRES_PARAM_KAPPA |
68 CRIRES_PARAM_CLOSING_HSIZE |
69 CRIRES_PARAM_CLEAN_RATE |
70 CRIRES_PARAM_TOT_NDIT |
71 CRIRES_PARAM_Y_POS_CHIP1 |
72 CRIRES_PARAM_Y_POS_CHIP2 |
73 CRIRES_PARAM_Y_POS_CHIP3 |
74 CRIRES_PARAM_Y_POS_CHIP4 |
75 CRIRES_PARAM_Y_WIDTH |
76 CRIRES_PARAM_Y_SPEC_ZONE_CHIP1 |
77 CRIRES_PARAM_Y_SPEC_ZONE_CHIP2 |
78 CRIRES_PARAM_Y_SPEC_ZONE_CHIP3 |
79 CRIRES_PARAM_Y_SPEC_ZONE_CHIP4 |
80 CRIRES_PARAM_REJECT,
81 "Spectrum extraction routine",
82 crires_util_extract_description) ;
83
84/*-----------------------------------------------------------------------------
85 Static variables
86 -----------------------------------------------------------------------------*/
87
88static struct {
89 /* Inputs */
90 /* mode : 1=spec ; 2=lines */
91 int mode ;
92 double kappa ; /* mode = 1 */
93 int closing_hs ; /* mode = 1 */
94 double clean_rate ; /* mode = 1 */
95 double tot_ndit ; /* mode = 1 */
96 int box_hor_size ; /* mode = 1 */
97 int spec_hsize ; /* mode = 1 */
98 const char * y_spec_zone_c1 ;/* mode = 1 */
99 const char * y_spec_zone_c2 ;/* mode = 1 */
100 const char * y_spec_zone_c3 ;/* mode = 1 */
101 const char * y_spec_zone_c4 ;/* mode = 1 */
102 const char * y_pos_c1 ; /* mode = 2 */
103 const char * y_pos_c2 ; /* mode = 2 */
104 const char * y_pos_c3 ; /* mode = 2 */
105 const char * y_pos_c4 ; /* mode = 2 */
106 int y_width ; /* mode = 2 */
107 int rej_right ; /* All modes */
108 int rej_left ; /* All modes */
109 int display ; /* All modes */
110 /* Outputs */
111 int win_mode ;
112 crires_illum_period period ;
113 int qc_specpos[CRIRES_NB_DETECTORS] ;
114 int qc_specwrec[CRIRES_NB_DETECTORS] ;
115 int qc_specwopt[CRIRES_NB_DETECTORS] ;
116 double qc_specoptmed[CRIRES_NB_DETECTORS] ;
117 double qc_s2nmed[CRIRES_NB_DETECTORS] ;
118 double qc_fwhm_comb_pix[CRIRES_NB_DETECTORS] ;
119 double qc_fwhm_comb_as[CRIRES_NB_DETECTORS] ;
120 double qc_fwhm_prof_pix[CRIRES_NB_DETECTORS] ;
121 double qc_fwhm_prof_as[CRIRES_NB_DETECTORS] ;
122 double qc_fwhm_diff[CRIRES_NB_DETECTORS] ;
123} crires_util_extract_config ;
124
125/*-----------------------------------------------------------------------------
126 Functions code
127 -----------------------------------------------------------------------------*/
128
129/*----------------------------------------------------------------------------*/
136/*----------------------------------------------------------------------------*/
137static int crires_util_extract(
138 cpl_frameset * frameset,
139 const cpl_parameterlist * parlist)
140{
141 const char * sval ;
142 const char * y_pos ;
143 cpl_imagelist * imlist ;
144 cpl_propertylist * plist ;
145 cpl_imagelist * contrib ;
146 cpl_image * contribution_map ;
147 cpl_frame * fr ;
148 cpl_imagelist * profile ;
149 cpl_image * prof[CRIRES_NB_DETECTORS] ;
150 cpl_imagelist * bgmaps ;
151 cpl_image * bgmap[CRIRES_NB_DETECTORS] ;
152 cpl_table * ext[CRIRES_NB_DETECTORS] ;
153 cpl_vector * ext_vec ;
154 cpl_vector * ypos_vec ;
155 int ly, nexp, starty, stopy, extr_spec_starty,
156 extr_spec_stopy ;
157 int i, j ;
158
159 /* Needed for sscanf() */
160 setlocale(LC_NUMERIC, "C");
161
162 /* Initialise */
163 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
164 crires_util_extract_config.qc_specpos[i] = -1 ;
165 crires_util_extract_config.qc_specwrec[i] = -1 ;
166 crires_util_extract_config.qc_specwopt[i] = -1 ;
167 crires_util_extract_config.qc_specoptmed[i] = -1.0 ;
168 crires_util_extract_config.qc_s2nmed[i] = -1.0 ;
169 crires_util_extract_config.qc_fwhm_comb_pix[i] = -1.0 ;
170 crires_util_extract_config.qc_fwhm_comb_as[i] = -1.0 ;
171 crires_util_extract_config.qc_fwhm_prof_pix[i] = -1.0 ;
172 crires_util_extract_config.qc_fwhm_prof_as[i] = -1.0 ;
173 crires_util_extract_config.qc_fwhm_diff[i] = -1.0 ;
174 ext[i] = NULL ;
175 prof[i] = NULL ;
176 bgmap[i] = NULL ;
177 }
178 ly = -1 ;
179
180 /* Retrieve input parameters */
181 crires_util_extract_config.display = crires_parameterlist_get_int(parlist,
182 RECIPE_STRING, CRIRES_PARAM_DISPLAY) ;
183 crires_util_extract_config.mode = crires_parameterlist_get_int(parlist,
184 RECIPE_STRING, CRIRES_PARAM_EXTR_MODE) ;
185 crires_util_extract_config.box_hor_size = crires_parameterlist_get_int(
186 parlist, RECIPE_STRING, CRIRES_PARAM_HOR_SIZE) ;
187 crires_util_extract_config.spec_hsize = crires_parameterlist_get_int(
188 parlist, RECIPE_STRING, CRIRES_PARAM_SPEC_HSIZE) ;
189 crires_util_extract_config.kappa = crires_parameterlist_get_double(
190 parlist, RECIPE_STRING, CRIRES_PARAM_KAPPA) ;
191 crires_util_extract_config.closing_hs = crires_parameterlist_get_int(
192 parlist, RECIPE_STRING, CRIRES_PARAM_CLOSING_HSIZE) ;
193 crires_util_extract_config.clean_rate = crires_parameterlist_get_double(
194 parlist, RECIPE_STRING, CRIRES_PARAM_CLEAN_RATE) ;
195 crires_util_extract_config.tot_ndit = crires_parameterlist_get_double(
196 parlist, RECIPE_STRING, CRIRES_PARAM_TOT_NDIT) ;
197 crires_util_extract_config.y_pos_c1=crires_parameterlist_get_string(parlist,
198 RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP1) ;
199 crires_util_extract_config.y_pos_c2=crires_parameterlist_get_string(parlist,
200 RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP2) ;
201 crires_util_extract_config.y_pos_c3=crires_parameterlist_get_string(parlist,
202 RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP3) ;
203 crires_util_extract_config.y_pos_c4=crires_parameterlist_get_string(parlist,
204 RECIPE_STRING, CRIRES_PARAM_Y_POS_CHIP4) ;
205 crires_util_extract_config.y_width= crires_parameterlist_get_int(parlist,
206 RECIPE_STRING, CRIRES_PARAM_Y_WIDTH) ;
207 crires_util_extract_config.y_spec_zone_c1=crires_parameterlist_get_string(
208 parlist, RECIPE_STRING, CRIRES_PARAM_Y_SPEC_ZONE_CHIP1) ;
209 crires_util_extract_config.y_spec_zone_c2=crires_parameterlist_get_string(
210 parlist, RECIPE_STRING, CRIRES_PARAM_Y_SPEC_ZONE_CHIP2) ;
211 crires_util_extract_config.y_spec_zone_c3=crires_parameterlist_get_string(
212 parlist, RECIPE_STRING, CRIRES_PARAM_Y_SPEC_ZONE_CHIP3) ;
213 crires_util_extract_config.y_spec_zone_c4=crires_parameterlist_get_string(
214 parlist, RECIPE_STRING, CRIRES_PARAM_Y_SPEC_ZONE_CHIP4) ;
215
216 sval = crires_parameterlist_get_string(parlist, RECIPE_STRING,
217 CRIRES_PARAM_REJECT) ;
218 if (sscanf(sval, "%d,%d",
219 &crires_util_extract_config.rej_left,
220 &crires_util_extract_config.rej_right)!=2) {
221 return -1 ;
222 }
223
224 /* Identify the RAW and CALIB frames in the input frameset */
225 if (crires_dfs_set_groups(frameset, NULL)) {
226 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
227 return -1 ;
228 }
229
230 /* Get the detector illumination period */
231 fr = cpl_frameset_get_position(frameset, 0);
232 crires_util_extract_config.period =
233 crires_get_detector_illum_period(cpl_frame_get_filename(fr)) ;
234 if (crires_util_extract_config.period == CRIRES_ILLUM_UNKNOWN) {
235 cpl_msg_error(__func__,
236 "Cannot determine the detector illumination period") ;
237 return -1 ;
238 }
239
240 /* Windowing mode ? */
241 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(fr), 0)) == NULL)
242 return -1 ;
243 sval = crires_pfits_get_ncorrs(plist) ;
244 if (!strcmp(sval, "FowlerNsampGRstWin")) {
245 crires_util_extract_config.period = CRIRES_ILLUM_FULL_DETECTOR ;
246 crires_util_extract_config.win_mode = 1 ;
247 } else {
248 crires_util_extract_config.win_mode = 0 ;
249 }
250 cpl_propertylist_delete(plist) ;
251
252 /* Display the Detector illumination */
253 crires_display_detector_illum(crires_util_extract_config.period) ;
254
255 /* Load the first file in an image list */
256 cpl_msg_info(__func__, "Input image loading") ;
257 imlist = crires_load_file(cpl_frame_get_filename(fr),
258 crires_util_extract_config.period, CPL_TYPE_FLOAT) ;
259
260 /* Load the optional contribution map */
261 if (cpl_frameset_get_size(frameset) >= 2) {
262 fr = cpl_frameset_get_position(frameset, 1);
263 cpl_msg_info(__func__, "Contribution map specified: %s",
264 cpl_frame_get_filename(fr)) ;
265 contrib = crires_load_file(cpl_frame_get_filename(fr),
266 crires_util_extract_config.period, CPL_TYPE_INT) ;
267 } else contrib = NULL ;
268
269 if (crires_util_extract_config.mode == 1) {
270 /* Get the total ndit */
271 fr = cpl_frameset_get_position(frameset, 0);
272 if (crires_util_extract_config.tot_ndit < 0) {
273 crires_util_extract_config.tot_ndit =
274 crires_get_totndit(cpl_frame_get_filename(fr)) ;
275 if (crires_util_extract_config.tot_ndit < 0) {
276 cpl_msg_error(__func__,
277 "Cannot get the total number of NDIT*DIT") ;
278 cpl_imagelist_delete(imlist) ;
279 if (contrib != NULL) cpl_imagelist_delete(contrib) ;
280 return -1 ;
281 }
282 }
283 /* Get the number of exposures used for the frames combination */
284 plist=cpl_propertylist_load(cpl_frame_get_filename(fr), 0) ;
285 nexp = crires_pfits_get_datancom(plist) ;
286 cpl_propertylist_delete(plist) ;
287 if (cpl_error_get_code() != CPL_ERROR_NONE) {
288 cpl_msg_error(__func__,"No PRO DATANCOM information in the header");
289 cpl_imagelist_delete(imlist) ;
290 if (contrib != NULL) cpl_imagelist_delete(contrib) ;
291 return -1 ;
292 }
293 crires_util_extract_config.tot_ndit *= nexp ;
294 }
295
296 /* Extract chips */
297 cpl_msg_info(__func__, "Spectrum extraction") ;
298 cpl_msg_indent_more() ;
299 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
300 /* Skip some detectors in windowing mode */
301 if ((i==0 || i==CRIRES_NB_DETECTORS-1) &&
302 (crires_util_extract_config.win_mode == 1)) {
303 continue ;
304 }
305 cpl_msg_info(__func__, "Spectrum extraction from chip number %d", i+1) ;
306 cpl_msg_indent_more() ;
307 if (crires_util_extract_config.mode == 1) {
308 /* Where is the spectrum extraction zone ? */
309 y_pos = "" ;
310 if (i+1 == 1) y_pos = crires_util_extract_config.y_spec_zone_c1 ;
311 if (i+1 == 2) y_pos = crires_util_extract_config.y_spec_zone_c2 ;
312 if (i+1 == 3) y_pos = crires_util_extract_config.y_spec_zone_c3 ;
313 if (i+1 == 4) y_pos = crires_util_extract_config.y_spec_zone_c4 ;
314 if (sscanf(y_pos,"%d,%d", &extr_spec_starty, &extr_spec_stopy)!=2) {
315 cpl_msg_warning(__func__, "Wrong Spectral Zone specified: %s",
316 y_pos) ;
317 extr_spec_starty = extr_spec_stopy = -1 ;
318 }
319
320 /* Extract spectrum */
321 if (contrib != NULL)
322 contribution_map = cpl_imagelist_get(contrib, i) ;
323 else
324 contribution_map = NULL ;
325 ext[i] = crires_extract_spectrum(cpl_imagelist_get(imlist, i),
326 contribution_map,
327 crires_util_extract_config.box_hor_size,
328 crires_util_extract_config.spec_hsize,
329 crires_util_extract_config.kappa,
330 crires_util_extract_config.closing_hs,
331 crires_util_extract_config.clean_rate,
332 crires_util_extract_config.rej_left,
333 crires_util_extract_config.rej_right,
334 extr_spec_starty, extr_spec_stopy,
335 i+1,
336 crires_util_extract_config.tot_ndit,
337 crires_util_extract_config.period,
338 &(crires_util_extract_config.qc_specpos[i]),
339 &(crires_util_extract_config.qc_specwrec[i]),
340 &(crires_util_extract_config.qc_specwopt[i]),
341 &(crires_util_extract_config.qc_specoptmed[i]),
342 &(crires_util_extract_config.qc_s2nmed[i]),
343 &(prof[i]),
344 &(bgmap[i])) ;
345 cpl_msg_info(__func__, "Chip number %d FWHM Computation", i+1) ;
346 if (crires_extract_qc_fwhm(cpl_imagelist_get(imlist, i),
347 prof[i],
348 &(crires_util_extract_config.qc_fwhm_comb_pix[i]),
349 &(crires_util_extract_config.qc_fwhm_comb_as[i]),
350 &(crires_util_extract_config.qc_fwhm_prof_pix[i]),
351 &(crires_util_extract_config.qc_fwhm_prof_as[i]),
352 &(crires_util_extract_config.qc_fwhm_diff[i])) == -1) {
353 cpl_msg_warning(__func__, "Failed for FWHM computation") ;
354 crires_util_extract_config.qc_fwhm_comb_pix[i] = -1.0 ;
355 crires_util_extract_config.qc_fwhm_comb_as[i] = -1.0 ;
356 crires_util_extract_config.qc_fwhm_prof_pix[i] = -1.0 ;
357 crires_util_extract_config.qc_fwhm_prof_as[i] = -1.0 ;
358 crires_util_extract_config.qc_fwhm_diff[i] = -1.0 ;
359 }
360 } else if (crires_util_extract_config.mode == 2) {
361 /* Get the correction for the position */
362 if (i+1 == 1)
363 ly = crires_get_detector_ly1(crires_util_extract_config.period);
364 if (i+1 == 2)
365 ly = crires_get_detector_ly2(crires_util_extract_config.period);
366 if (i+1 == 3)
367 ly = crires_get_detector_ly3(crires_util_extract_config.period);
368 if (i+1 == 4)
369 ly = crires_get_detector_ly4(crires_util_extract_config.period);
370 /* If ly not found, use the bottom of the image */
371 if (ly < 0) ly = 1 ;
372
373 /* Where is the Y extraction zone ? */
374 y_pos = "" ;
375 if (i+1 == 1) y_pos = crires_util_extract_config.y_pos_c1 ;
376 if (i+1 == 2) y_pos = crires_util_extract_config.y_pos_c2 ;
377 if (i+1 == 3) y_pos = crires_util_extract_config.y_pos_c3 ;
378 if (i+1 == 4) y_pos = crires_util_extract_config.y_pos_c4 ;
379
380 /* Try to parse the user specified positions */
381 if (!strcmp(y_pos, "")) {
382 ypos_vec = NULL ;
383 } else {
384 if ((ypos_vec = crires_parse_y_positions(y_pos)) == NULL) {
385 cpl_msg_warning(__func__,
386 "Cannot parse the y_positions value : %s", y_pos) ;
387 ypos_vec = NULL ;
388 }
389 }
390
391 if (ypos_vec == NULL) {
392 cpl_msg_info(__func__, "Collapse the full image along Y") ;
393 starty = 1 ;
394 stopy = cpl_image_get_size_y(cpl_imagelist_get(imlist, i)) ;
395 } else {
396 cpl_msg_info(__func__, "Collapse the area around Y=%g",
397 cpl_vector_get(ypos_vec, 0)) ;
398 /* TODO : Only the first passed value is used */
399 starty = (int)cpl_vector_get(ypos_vec, 0) -
400 (int)(crires_util_extract_config.y_width/2.0) ;
401 stopy = (int)cpl_vector_get(ypos_vec, 0) +
402 (int)(crires_util_extract_config.y_width/2.0) ;
403 cpl_vector_delete(ypos_vec) ;
404 starty -= ly-1 ;
405 stopy -= ly-1 ;
406 }
407
408 /* Extract lines */
409 ext_vec = crires_extract_lines(cpl_imagelist_get(imlist, i),
410 starty, stopy,
411 crires_util_extract_config.rej_left,
412 crires_util_extract_config.rej_right) ;
413 if (ext_vec != NULL) {
414 ext[i] = crires_extract_gen_tab(ext_vec, NULL, NULL, NULL,
415 NULL, NULL, NULL) ;
416 crires_util_extract_config.qc_specpos[i] =
417 (starty+stopy)/2 + (ly-1) ;
418 crires_util_extract_config.qc_specwrec[i] = starty-stopy+1;
419 cpl_vector_delete(ext_vec) ;
420 }
421 } else {
422 cpl_msg_warning(__func__, "Unsuported mode: %d",
423 crires_util_extract_config.mode) ;
424 }
425
426 /* Plot the result if required */
427 if ((ext[i] != NULL) && (crires_util_extract_config.display == i+1)) {
428 ext_vec = cpl_vector_wrap(cpl_table_get_nrow(ext[i]),
429 cpl_table_get_data_double(ext[i], CRIRES_COL_EXTRACT_INT_RECT));
430 cpl_plot_vector(
431"set grid;set xlabel 'Position (pixels)';set ylabel 'Intensity RECT (ADU/sec)';",
432 "t 'Extracted Spectrum RECT' w lines", "", ext_vec) ;
433 cpl_vector_unwrap(ext_vec) ;
434 ext_vec = cpl_vector_wrap(cpl_table_get_nrow(ext[i]),
435 cpl_table_get_data_double(ext[i], CRIRES_COL_EXTRACT_INT_OPT)) ;
436 cpl_plot_vector(
437"set grid;set xlabel 'Position (pixels)';set ylabel 'Intensity OPT (ADU/sec)';",
438 "t 'Extracted Spectrum OPT' w lines", "", ext_vec) ;
439 cpl_vector_unwrap(ext_vec) ;
440 }
441 cpl_msg_indent_less() ;
442 }
443 cpl_imagelist_delete(imlist) ;
444 if (contrib != NULL) cpl_imagelist_delete(contrib) ;
445 cpl_msg_indent_less() ;
446
447 /* Reconstruct chips in windowing mode using detector 2 */
448 if (crires_util_extract_config.win_mode == 1) {
449 if (ext[1] != NULL) {
450 ext[0] = cpl_table_duplicate(ext[1]) ;
451 cpl_table_set_size(ext[0], 0) ;
452 ext[CRIRES_NB_DETECTORS-1] = cpl_table_duplicate(ext[0]) ;
453 }
454 if (prof[1] != NULL) {
455 prof[0] = cpl_image_duplicate(prof[1]) ;
456 cpl_image_multiply_scalar(prof[0], 0.0) ;
457 prof[CRIRES_NB_DETECTORS-1] = cpl_image_duplicate(prof[0]) ;
458 }
459 if (bgmap[1] != NULL) {
460 bgmap[0] = cpl_image_duplicate(bgmap[1]) ;
461 cpl_image_multiply_scalar(bgmap[0], 0.0) ;
462 bgmap[CRIRES_NB_DETECTORS-1] = cpl_image_duplicate(bgmap[0]) ;
463 }
464 }
465
466 /* Test that the spectrum is at the same place in all detectors */
467 for (i=1 ; i<CRIRES_NB_DETECTORS ; i++) {
468 /* Skip some detectors in windowing mode */
469 if ((i==1 || i==CRIRES_NB_DETECTORS-1) &&
470 (crires_util_extract_config.win_mode == 1)) {
471 continue ;
472 }
473 if (crires_util_extract_config.qc_specpos[i-1] > 0 &&
474 crires_util_extract_config.qc_specpos[i] > 0 &&
475 fabs(crires_util_extract_config.qc_specpos[i-1] -
476 crires_util_extract_config.qc_specpos[i]) >
477 CRIRES_SPEC_POS_TOLERANCE) {
478 cpl_msg_warning(__func__,
479 "The spectrum positions in chip %d and chip %d are too different: %d -> %d",
480 i, i+1, crires_util_extract_config.qc_specpos[i-1],
481 crires_util_extract_config.qc_specpos[i]) ;
482 }
483 }
484
485 /* Create the profile */
486 profile = cpl_imagelist_new() ;
487 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
488 if (prof[i] != NULL) cpl_imagelist_set(profile, prof[i], i) ;
489 else {
490 cpl_imagelist_delete(profile) ;
491 profile = NULL ;
492 for (j=i+1 ; j<CRIRES_NB_DETECTORS ; j++)
493 if (prof[j] != NULL) cpl_image_delete(prof[j]) ;
494 break ;
495 }
496 }
497
498 /* Create the bg maps */
499 bgmaps = cpl_imagelist_new() ;
500 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
501 if (bgmap[i] != NULL) cpl_imagelist_set(bgmaps, bgmap[i], i) ;
502 else {
503 cpl_imagelist_delete(bgmaps) ;
504 bgmaps = NULL ;
505 for (j=i+1 ; j<CRIRES_NB_DETECTORS ; j++)
506 if (bgmap[j] != NULL) cpl_image_delete(bgmap[j]) ;
507 break ;
508 }
509 }
510
511 /* Save the result */
512 cpl_msg_info(__func__, "Save the products") ;
513 cpl_msg_indent_more() ;
514 if (crires_util_extract_save((const cpl_table **)ext, profile, bgmaps,
515 parlist, frameset) == -1) {
516 cpl_msg_error(__func__, "Cannot save products") ;
517 cpl_msg_indent_less() ;
518 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
519 if (ext[i] != NULL) cpl_table_delete(ext[i]) ;
520 }
521 if (profile != NULL) cpl_imagelist_delete(profile) ;
522 if (bgmaps != NULL) cpl_imagelist_delete(bgmaps) ;
523 return -1 ;
524 }
525 cpl_msg_indent_less() ;
526
527 /* Deallocate */
528 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
529 if (ext[i] != NULL) cpl_table_delete(ext[i]) ;
530 }
531 if (profile != NULL) cpl_imagelist_delete(profile) ;
532 if (bgmaps != NULL) cpl_imagelist_delete(bgmaps) ;
533
534 /* Return */
535 if (cpl_error_get_code()) return -1 ;
536 else return 0 ;
537}
538
539/*----------------------------------------------------------------------------*/
549/*----------------------------------------------------------------------------*/
550static int crires_util_extract_save(
551 const cpl_table ** ext,
552 const cpl_imagelist * profile,
553 const cpl_imagelist * bgmaps,
554 const cpl_parameterlist * parlist,
555 cpl_frameset * set)
556{
557 cpl_propertylist ** qclists ;
558 const cpl_frame * ref_frame ;
559 cpl_propertylist * inputlist ;
560 const char * recipe_name = "crires_util_extract" ;
561 int i ;
562
563 /* Get the reference frame */
564 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
565
566 /* Create the QC lists */
567 qclists = cpl_malloc(CRIRES_NB_DETECTORS * sizeof(cpl_propertylist*)) ;
568 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
569 qclists[i] = cpl_propertylist_new() ;
570 cpl_propertylist_append_int(qclists[i], "ESO QC SPECPOS",
571 crires_util_extract_config.qc_specpos[i]) ;
572 cpl_propertylist_append_int(qclists[i], "ESO QC SPECWREC",
573 crires_util_extract_config.qc_specwrec[i]) ;
574 cpl_propertylist_append_int(qclists[i], "ESO QC SPECWOPT",
575 crires_util_extract_config.qc_specwopt[i]) ;
576 cpl_propertylist_append_double(qclists[i], "ESO QC SIGNAL MED",
577 crires_util_extract_config.qc_specoptmed[i]) ;
578 cpl_propertylist_append_double(qclists[i], "ESO QC S2NMED",
579 crires_util_extract_config.qc_s2nmed[i]) ;
580 cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX COMBINED",
581 crires_util_extract_config.qc_fwhm_comb_pix[i]) ;
582 cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC COMBINED",
583 crires_util_extract_config.qc_fwhm_comb_as[i]) ;
584 cpl_propertylist_append_double(qclists[i], "ESO QC FWHMPIX PROFILE",
585 crires_util_extract_config.qc_fwhm_prof_pix[i]) ;
586 cpl_propertylist_append_double(qclists[i], "ESO QC FWHMARC PROFILE",
587 crires_util_extract_config.qc_fwhm_prof_as[i]) ;
588 cpl_propertylist_append_double(qclists[i], "ESO QC FWHM DIFF",
589 crires_util_extract_config.qc_fwhm_diff[i]) ;
590
591 /* Propagate some keywords from input raw frame extensions */
592 inputlist = cpl_propertylist_load_regexp(
593 cpl_frame_get_filename(ref_frame), i+1,
594 CRIRES_HEADER_EXT_FORWARD, 0) ;
595 cpl_propertylist_copy_property_regexp(qclists[i], inputlist,
596 CRIRES_HEADER_EXT_FORWARD, 0) ;
597 cpl_propertylist_delete(inputlist) ;
598 }
599
600 if (profile != NULL) {
601 /* Write the image */
602 crires_image_save(set,
603 parlist,
604 set,
605 profile,
606 recipe_name,
607 CRIRES_OBS_EXTRACT_PROFILE_IMA,
608 CRIRES_PROTYPE_PROFILE,
609 crires_util_extract_config.period,
610 NULL,
611 (const cpl_propertylist**)qclists,
612 PACKAGE "/" PACKAGE_VERSION,
613 "crires_util_extract_profile.fits") ;
614 }
615
616 if (bgmaps!= NULL) {
617 /* Write the image */
618 crires_image_save(set,
619 parlist,
620 set,
621 bgmaps,
622 recipe_name,
623 CRIRES_OBS_EXTRACT_BGMAP_IMA,
624 CRIRES_PROTYPE_BGD_MAP,
625 crires_util_extract_config.period,
626 NULL,
627 (const cpl_propertylist**)qclists,
628 PACKAGE "/" PACKAGE_VERSION,
629 "crires_util_extract_bgmap.fits") ;
630 }
631
632 /* Write the table */
633 crires_table_save(set,
634 parlist,
635 set,
636 ext,
637 recipe_name,
638 CRIRES_EXTRACT_PIX_TAB,
639 CRIRES_PROTYPE_SPEC_PIX,
640 NULL,
641 (const cpl_propertylist**)qclists,
642 PACKAGE "/" PACKAGE_VERSION,
643 "crires_util_extract_extracted.fits") ;
644
645 /* Free and return */
646 for (i=0 ; i<CRIRES_NB_DETECTORS ; i++) {
647 cpl_propertylist_delete(qclists[i]) ;
648 }
649 cpl_free(qclists) ;
650 return 0;
651}
652