CR2RE Pipeline Reference Manual 1.6.8
cr2res_util_wave.c
1/*
2 * This file is part of the CR2RES 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., 51 Franklin St, Fifth Floor, 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 <string.h>
30
31#include <cpl.h>
32#include <math.h>
33#include "hdrl.h"
34
35#include "cr2res_utils.h"
36#include "cr2res_pfits.h"
37#include "cr2res_dfs.h"
38#include "cr2res_io.h"
39#include "cr2res_extract.h"
40#include "cr2res_trace.h"
41#include "cr2res_wave.h"
42
43/*-----------------------------------------------------------------------------
44 Define
45 -----------------------------------------------------------------------------*/
46
47#define RECIPE_STRING "cr2res_util_wave"
48
49/*-----------------------------------------------------------------------------
50 Plugin registration
51 -----------------------------------------------------------------------------*/
52
53int cpl_plugin_get_info(cpl_pluginlist * list);
54
55/*-----------------------------------------------------------------------------
56 Private function prototypes
57 -----------------------------------------------------------------------------*/
58
59static int cr2res_util_wave_create(cpl_plugin *);
60static int cr2res_util_wave_exec(cpl_plugin *);
61static int cr2res_util_wave_destroy(cpl_plugin *);
62static int cr2res_util_wave(cpl_frameset *, const cpl_parameterlist *);
63
64/*-----------------------------------------------------------------------------
65 Static variables
66 -----------------------------------------------------------------------------*/
67
68static char cr2res_util_wave_description[] = "\
69Wavelength Calibration \n\
70 This utility performs the wavelength calibration on already extracted \n\
71 spectra. It can support different methods (--wl_method parameter): \n\
72 XCORR: Cross Correlation with a emission lines catalog (default) \n\
73 LINE1D: Line identification and fitting for each 1D spectra \n\
74 LINE2D: Line identification and fitting for all 1D spectra at once \n\
75 ETALON: Does not require any static calibration file \n\
76 AUTO: Guess the Method from the input file header \n\
77 \n\
78 Inputs \n\
79 raw.fits " CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG " [1 to n] \n\
80 or " CR2RES_UTIL_EXTRACT_1D_PROCATG " \n\
81 or " CR2RES_UTIL_WAVE_EXTRACT_1D_PROCATG " \n\
82 or " CR2RES_CAL_WAVE_EXTRACT_1D_PROCATG " \n\
83 or " CR2RES_OBS_NODDING_EXTRACTA_PROCATG " \n\
84 or " CR2RES_OBS_NODDING_EXTRACTB_PROCATG " \n\
85 or " CR2RES_OBS_NODDING_EXTRACTC_PROCATG " \n\
86 or " CR2RES_OBS_STARING_EXTRACT_PROCATG " \n\
87 trace.fits " CR2RES_CAL_FLAT_TW_PROCATG " [1] \n\
88 or " CR2RES_CAL_FLAT_TW_MERGED_PROCATG " \n\
89 or " CR2RES_UTIL_TRACE_TW_PROCATG " \n\
90 or " CR2RES_UTIL_WAVE_TW_PROCATG " \n\
91 or " CR2RES_CAL_WAVE_TW_PROCATG " \n\
92 or " CR2RES_UTIL_SLIT_CURV_TW_PROCATG " \n\
93 lines.fits " CR2RES_EMISSION_LINES_PROCATG " [0 to 1] \n\
94 \n\
95 Outputs \n\
96 <input_name>_tw.fits "
97 CR2RES_UTIL_WAVE_TW_PROCATG"\n\
98 <input_name>_wave_map.fits "
99 CR2RES_UTIL_WAVE_MAP_PROCATG "\n\
100 <input_name>_lines_diagnostics.fits "
101 CR2RES_UTIL_WAVE_LINES_DIAGNOSTICS_PROCATG "\n\
102 <input_name>_extracted.fits "
103 CR2RES_UTIL_WAVE_EXTRACT_1D_PROCATG "\n\
104 \n\
105 Algorithm \n\
106 loop on raw frames f: \n\
107 loop on detectors d: \n\
108 Load the trace wave tw(f,d) \n\
109 Load the extracted spectra table ext(f,d) \n\
110 Call cr2res_wave_apply(tw(f,d),ext(f,d),emission_lines) \n\
111 -> lines diagnostics(f,d) \n\
112 -> updated_extracted(f,d) \n\
113 -> trace_wave_out(f,d) \n\
114 Create the wavelength map wave_map(f,d) \n\
115 Save lines diagnostics(f) \n\
116 Save updated_extracted(f) \n\
117 Save wave_map(f) \n\
118 Save trace_wave_out(f) \n\
119 \n\
120 cr2res_wave_apply() \n\
121 loop on the traces t: \n\
122 Get the spectrum \n\
123 Get the Initial guess \n\
124 Switch on the required method: \n\
125 CR2RES_LINE2D: cr2res_wave_2d() \n\
126 CR2RES_LINE1D: cr2res_wave_line_fitting() \n\
127 CR2RES_ETALON: cr2res_wave_etalon() \n\
128 CR2RES_XCORR: cr2res_wave_xcorr() \n\
129 \n\
130 Library Functions used \n\
131 cr2res_io_find_TRACE_WAVE() \n\
132 cr2res_io_load_TRACE_WAVE() \n\
133 cr2res_io_load_EXTRACT_1D() \n\
134 cr2res_wave_apply() \n\
135 cr2res_extract_EXTRACT1D_get_spectrum() \n\
136 cr2res_wave_estimate_compute() \n\
137 cr2res_wave_2d() \n\
138 cr2res_wave_line_fitting() \n\
139 cr2res_wave_etalon() \n\
140 cr2res_wave_xcorr() \n\
141 cr2res_wave_gen_wave_map() \n\
142 cr2res_io_save_TRACE_WAVE() \n\
143 cr2res_io_save_WAVE_MAP() \n\
144 cr2res_io_save_LINES_DIAGNOSTICS() \n\
145 cr2res_io_save_EXTRACT_1D() \n\
146" ;
147
148/*-----------------------------------------------------------------------------
149 Function code
150 -----------------------------------------------------------------------------*/
151
152/*----------------------------------------------------------------------------*/
162/*----------------------------------------------------------------------------*/
163int cpl_plugin_get_info(cpl_pluginlist * list)
164{
165 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
166 cpl_plugin * plugin = &recipe->interface;
167
168 if (cpl_plugin_init(plugin,
169 CPL_PLUGIN_API,
170 CR2RES_BINARY_VERSION,
171 CPL_PLUGIN_TYPE_RECIPE,
172 RECIPE_STRING,
173 "Wavelength Calibration",
174 cr2res_util_wave_description,
175 CR2RES_PIPELINE_AUTHORS,
176 PACKAGE_BUGREPORT,
178 cr2res_util_wave_create,
179 cr2res_util_wave_exec,
180 cr2res_util_wave_destroy)) {
181 cpl_msg_error(cpl_func, "Plugin initialization failed");
182 (void)cpl_error_set_where(cpl_func);
183 return 1;
184 }
185
186 if (cpl_pluginlist_append(list, plugin)) {
187 cpl_msg_error(cpl_func, "Error adding plugin to list");
188 (void)cpl_error_set_where(cpl_func);
189 return 1;
190 }
191
192 return 0;
193}
194
195/*----------------------------------------------------------------------------*/
203/*----------------------------------------------------------------------------*/
204static int cr2res_util_wave_create(cpl_plugin * plugin)
205{
206 cpl_recipe * recipe;
207 cpl_parameter * p;
208
209 /* Check that the plugin is part of a valid recipe */
210 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
211 recipe = (cpl_recipe *)plugin;
212 else
213 return -1;
214
215 /* Create the parameters list in the cpl_recipe object */
216 recipe->parameters = cpl_parameterlist_new();
217
218 /* Fill the parameters list */
219 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.detector",
220 CPL_TYPE_INT, "Only reduce the specified detector",
221 "cr2res.cr2res_util_wave", 0);
222 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "detector");
223 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
224 cpl_parameterlist_append(recipe->parameters, p);
225
226 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.order",
227 CPL_TYPE_INT, "Only reduce the specified order",
228 "cr2res.cr2res_util_wave", -1);
229 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "order");
230 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
231 cpl_parameterlist_append(recipe->parameters, p);
232
233 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.trace_nb",
234 CPL_TYPE_INT, "Only reduce the specified trace number",
235 "cr2res.cr2res_util_wave", -1);
236 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "trace_nb");
237 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
238 cpl_parameterlist_append(recipe->parameters, p);
239
240 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.wl_method",
241 CPL_TYPE_STRING,
242 "Wavelength Method (XCORR / LINE1D / LINE2D / ETALON)",
243 "cr2res.cr2res_util_wave", "UNSPECIFIED");
244 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wl_method");
245 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
246 cpl_parameterlist_append(recipe->parameters, p);
247
248 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.wl_shift",
249 CPL_TYPE_DOUBLE, "Wavelength shift (nm) to apply to the guess",
250 "cr2res.cr2res_util_wave", 0.0);
251 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wl_shift");
252 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
253 cpl_parameterlist_append(recipe->parameters, p);
254
255 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.wl_est",
256 CPL_TYPE_STRING,
257 "Estimated wavelength [start, end] (in nm)",
258 "cr2res.cr2res_util_wave", "-1.0, -1.0");
259 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wl_est");
260 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
261 cpl_parameterlist_append(recipe->parameters, p);
262
263 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.wl_err",
264 CPL_TYPE_DOUBLE, "Estimated wavelength error (in nm)",
265 "cr2res.cr2res_util_wave", -1.0);
266 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wl_err");
267 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
268 cpl_parameterlist_append(recipe->parameters, p);
269
270 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.wl_degree",
271 CPL_TYPE_INT, "Wavelength Polynomial degree, main dispersion",
272 "cr2res.cr2res_util_wave", 5);
273 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wl_degree");
274 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
275 cpl_parameterlist_append(recipe->parameters, p);
276
277 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.wl_xdegree",
278 CPL_TYPE_INT, "Wavelength Polynomial degree, cross-dispersion",
279 "cr2res.cr2res_util_wave", 5);
280 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wl_xdegree");
281 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
282 cpl_parameterlist_append(recipe->parameters, p);
283
284 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.log",
285 CPL_TYPE_BOOL, "Flag for taking the Log() value of the lines",
286 "cr2res.cr2res_util_wave", FALSE);
287 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "log");
288 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
289 cpl_parameterlist_append(recipe->parameters, p);
290
291 p =cpl_parameter_new_value("cr2res.cr2res_util_wave.fallback_input_wavecal",
292 CPL_TYPE_BOOL, "Flag for using the input WL when no computation",
293 "cr2res.cr2res_util_wave", FALSE);
294 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fallback");
295 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
296 cpl_parameterlist_append(recipe->parameters, p);
297
298 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.keep_higher_degrees",
299 CPL_TYPE_BOOL,
300 "Flag for re-using higher degrees of first guess in Cross-Corr.",
301 "cr2res.cr2res_util_wave", FALSE);
302 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "keep");
303 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
304 cpl_parameterlist_append(recipe->parameters, p);
305
306 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.clean_spectrum",
307 CPL_TYPE_BOOL, "Clean spectrum to use only around catalogue lines",
308 "cr2res.cr2res_util_wave", TRUE);
309 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "clean_spectrum");
310 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
311 cpl_parameterlist_append(recipe->parameters, p);
312
313 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.display",
314 CPL_TYPE_BOOL, "Flag for display",
315 "cr2res.cr2res_util_wave", FALSE);
316 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "display");
317 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
318 cpl_parameterlist_append(recipe->parameters, p);
319
320 p = cpl_parameter_new_value("cr2res.cr2res_util_wave.display_range",
321 CPL_TYPE_STRING,
322 "Wavelength range to display [start, end] (in nm)",
323 "cr2res.cr2res_util_wave", "-1.0, -1.0");
324 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "display_range");
325 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
326 cpl_parameterlist_append(recipe->parameters, p);
327
328 return 0;
329}
330
331/*----------------------------------------------------------------------------*/
337/*----------------------------------------------------------------------------*/
338static int cr2res_util_wave_exec(cpl_plugin * plugin)
339{
340 cpl_recipe *recipe;
341
342 /* Get the recipe out of the plugin */
343 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
344 recipe = (cpl_recipe *)plugin;
345 else return -1;
346
347 return cr2res_util_wave(recipe->frames, recipe->parameters);
348}
349
350/*----------------------------------------------------------------------------*/
356/*----------------------------------------------------------------------------*/
357static int cr2res_util_wave_destroy(cpl_plugin * plugin)
358{
359 cpl_recipe *recipe;
360
361 /* Get the recipe out of the plugin */
362 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
363 recipe = (cpl_recipe *)plugin;
364 else return -1 ;
365
366 cpl_parameterlist_delete(recipe->parameters);
367 return 0 ;
368}
369
370/*----------------------------------------------------------------------------*/
377/*----------------------------------------------------------------------------*/
378static int cr2res_util_wave(
379 cpl_frameset * frameset,
380 const cpl_parameterlist * parlist)
381{
382 const cpl_parameter * param;
383 int reduce_det, reduce_order, reduce_trace,
384 wl_degree, wl_xdegree, display, log_flag,
385 fallback_input_wavecal_flag,
386 keep_higher_degrees_flag, clean_spectrum ;
387 double wl_start, wl_end, wl_err, wl_shift, display_wmin,
388 display_wmax ;
389 cr2res_wavecal_type wavecal_type ;
390 const char * sval ;
391 cpl_frameset * rawframes ;
392 cpl_frameset * cur_fset ;
393 const cpl_frame * trace_wave_frame ;
394 const cpl_frame * lines_frame ;
395 cpl_table * trace_wave ;
396 cpl_table * extracted_table ;
397 char * out_file;
398 cpl_table * out_trace_wave[CR2RES_NB_DETECTORS] ;
399 cpl_table * lines_diagnostics[CR2RES_NB_DETECTORS] ;
400 cpl_table * updated_extracted_table[CR2RES_NB_DETECTORS] ;
401 hdrl_image * out_wave_map[CR2RES_NB_DETECTORS] ;
402 cpl_propertylist * ext_plist[CR2RES_NB_DETECTORS] ;
403 cpl_propertylist * qcs_plist ;
404 cpl_propertylist * plist ;
405 const char * first_file;
406 int det_nr, i, j, zp_order, grat1_order ;
407
408 /* Needed for sscanf() */
409 setlocale(LC_NUMERIC, "C");
410
411 /* Initialise */
412 wl_start = wl_end = -1.0 ; // wl_err
413 //wl_shift = 0.0 ;
414 display_wmin = display_wmax = -1.0 ;
415
416 /* RETRIEVE INPUT PARAMETERS */
417 param = cpl_parameterlist_find_const(parlist,
418 "cr2res.cr2res_util_wave.detector");
419 reduce_det = cpl_parameter_get_int(param);
420 param = cpl_parameterlist_find_const(parlist,
421 "cr2res.cr2res_util_wave.order");
422 reduce_order = cpl_parameter_get_int(param);
423 param = cpl_parameterlist_find_const(parlist,
424 "cr2res.cr2res_util_wave.trace_nb");
425 reduce_trace = cpl_parameter_get_int(param);
426 param = cpl_parameterlist_find_const(parlist,
427 "cr2res.cr2res_util_wave.wl_method");
428 sval = cpl_parameter_get_string(param) ;
429 if (!strcmp(sval, "XCORR")) wavecal_type = CR2RES_XCORR ;
430 else if (!strcmp(sval, "LINE1D")) wavecal_type = CR2RES_LINE1D ;
431 else if (!strcmp(sval, "LINE2D")) wavecal_type = CR2RES_LINE2D ;
432 else if (!strcmp(sval, "ETALON")) wavecal_type = CR2RES_ETALON ;
433 else {
434 cpl_msg_error(__func__, "Invalid Method specified");
435 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
436 return -1;
437 }
438 param = cpl_parameterlist_find_const(parlist,
439 "cr2res.cr2res_util_wave.wl_shift");
440 wl_shift = cpl_parameter_get_double(param) ;
441 param = cpl_parameterlist_find_const(parlist,
442 "cr2res.cr2res_util_wave.wl_est");
443 sval = cpl_parameter_get_string(param) ;
444 if (sscanf(sval, "%lg,%lg", &wl_start, &wl_end) != 2) {
445 return -1 ;
446 }
447 param = cpl_parameterlist_find_const(parlist,
448 "cr2res.cr2res_util_wave.wl_err");
449 wl_err = cpl_parameter_get_double(param) ;
450 param = cpl_parameterlist_find_const(parlist,
451 "cr2res.cr2res_util_wave.wl_degree");
452 wl_degree = cpl_parameter_get_int(param);
453 param = cpl_parameterlist_find_const(parlist,
454 "cr2res.cr2res_util_wave.wl_xdegree");
455 wl_xdegree = cpl_parameter_get_int(param);
456 param = cpl_parameterlist_find_const(parlist,
457 "cr2res.cr2res_util_wave.log");
458 log_flag = cpl_parameter_get_bool(param) ;
459 param = cpl_parameterlist_find_const(parlist,
460 "cr2res.cr2res_util_wave.fallback_input_wavecal");
461 fallback_input_wavecal_flag = cpl_parameter_get_bool(param) ;
462 param = cpl_parameterlist_find_const(parlist,
463 "cr2res.cr2res_util_wave.keep_higher_degrees");
464 keep_higher_degrees_flag = cpl_parameter_get_bool(param) ;
465 param = cpl_parameterlist_find_const(parlist,
466 "cr2res.cr2res_util_wave.clean_spectrum");
467 clean_spectrum = cpl_parameter_get_bool(param) ;
468 param = cpl_parameterlist_find_const(parlist,
469 "cr2res.cr2res_util_wave.display");
470 display = cpl_parameter_get_bool(param) ;
471 param = cpl_parameterlist_find_const(parlist,
472 "cr2res.cr2res_util_wave.display_range");
473 sval = cpl_parameter_get_string(param) ;
474 if (sscanf(sval, "%lg,%lg", &display_wmin, &display_wmax) != 2) {
475 return -1 ;
476 }
477
478 /* Check Parameters */
479 if (display==TRUE && (reduce_order==-1 || reduce_det==0)){
480 cpl_msg_warning(__func__,
481 "Option --display can only be used with --order"
482 " and --detector");
483 display=FALSE;
484 }
485 if (wl_degree < 0) {
486 cpl_msg_error(__func__, "The degree needs to be >= 0");
487 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
488 return -1 ;
489 }
490 if (wl_degree == 0 && !keep_higher_degrees_flag) {
491 cpl_msg_error(__func__, "The degree 0 can only be used with --keep");
492 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
493 return -1 ;
494 }
495
496 /* Identify the RAW and CALIB frames in the input frameset */
497 if (cr2res_dfs_set_groups(frameset) != CPL_ERROR_NONE) {
498 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
499 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
500 return -1 ;
501 }
502
503 /* Retrieve calibration data */
504 trace_wave_frame = cr2res_io_find_TRACE_WAVE(frameset) ;
505 if (trace_wave_frame == NULL) {
506 cpl_msg_error(__func__, "Could not find TRACE_WAVE frame") ;
507 return -1 ;
508 }
509 lines_frame = cpl_frameset_find_const(frameset,
510 CR2RES_EMISSION_LINES_PROCATG) ;
511 if (wavecal_type != CR2RES_ETALON && lines_frame == NULL) {
512 cpl_msg_error(__func__,
513 "The catalog file is needed for XCORR/LINE1D/LINE2D");
514 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
515 return -1 ;
516 }
517
518 /* Get the RAW Frames */
519 rawframes = cr2res_io_find_EXTRACT_1D_all(frameset) ;
520 if (rawframes == NULL) {
521 cpl_msg_error(__func__, "Could not find RAW frames") ;
522 return -1 ;
523 }
524
525 first_file = cpl_frame_get_filename(
526 cpl_frameset_get_position_const(rawframes, 0)) ;
527 plist = cpl_propertylist_load(first_file, 0) ;
528 zp_order = cr2res_pfits_get_order_zp(plist) ;
529 grat1_order = cr2res_pfits_get_order(plist) ;
530 cpl_propertylist_delete(plist);
531
532 /* Loop on the RAW frames */
533 for (i=0 ; i<cpl_frameset_get_size(rawframes) ; i++) {
534 const cpl_frame * cur_frame ;
535 const char * cur_fname ;
536 /* Get the Current Frame */
537 cur_frame = cpl_frameset_get_position(rawframes, i) ;
538 cur_fname = cpl_frame_get_filename(cur_frame) ;
539 cpl_msg_info(__func__, "Reduce Frame %s", cur_fname) ;
540 cpl_msg_indent_more() ;
541
542 /* Guess the method to be used from the RAW frames header */
543 if (reduce_order > -1 && wavecal_type == CR2RES_LINE2D) {
544 cpl_msg_error(__func__,
545 "Limiting to one order with LINE2D impossible");
546 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
547 return -1 ;
548 }
549
550 /* Loop over the detectors */
551 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
552
553 /* Initialise */
554 out_trace_wave[det_nr-1] = NULL ;
555 lines_diagnostics[det_nr-1] = NULL ;
556 updated_extracted_table[det_nr-1] = NULL ;
557 out_wave_map[det_nr-1] = NULL ;
558
559 /* Store the extension header for product saving */
560 ext_plist[det_nr-1] = cpl_propertylist_load(cur_fname,
561 cr2res_io_get_ext_idx(cur_fname, det_nr, 1)) ;
562
563 /* Compute only one detector */
564 if (reduce_det != 0 && det_nr != reduce_det) {
565 /* This Detector will not be processed here */
566 /* The output trace wave contains the input one ... */
567 out_trace_wave[det_nr-1] = cr2res_io_load_TRACE_WAVE(
568 cpl_frame_get_filename(trace_wave_frame),
569 det_nr) ;
570 /* ... without the WL / WL_ERR */
571 /* ... unless fallback_input_wavecal_flag is set */
572 if (!fallback_input_wavecal_flag) {
573 /* Reset WL / WL_ERR */
574 cpl_table_erase_column(out_trace_wave[det_nr-1],
575 CR2RES_COL_WAVELENGTH) ;
576 cpl_table_new_column_array(out_trace_wave[det_nr-1],
577 CR2RES_COL_WAVELENGTH, CPL_TYPE_DOUBLE, 2) ;
578 cpl_table_erase_column(out_trace_wave[det_nr-1],
579 CR2RES_COL_WAVELENGTH_ERROR) ;
580 cpl_table_new_column_array(out_trace_wave[det_nr-1],
581 CR2RES_COL_WAVELENGTH_ERROR, CPL_TYPE_DOUBLE, 2) ;
582 }
583 continue ;
584 }
585
586 cpl_msg_info(__func__, "Process detector number %d", det_nr) ;
587 cpl_msg_indent_more() ;
588
589 /* Load the TRACE_WAVE table of this detector */
590 cpl_msg_info(__func__, "Load the TRACE_WAVE table") ;
591 if ((trace_wave = cr2res_io_load_TRACE_WAVE(
592 cpl_frame_get_filename(trace_wave_frame),
593 det_nr)) == NULL) {
594 cpl_msg_error(__func__,"Failed to load table - skip detector");
595 cpl_error_reset() ;
596 cpl_msg_indent_less() ;
597 continue ;
598 }
599
600 /* Load the EXTRACT1D table of this detector */
601 cpl_msg_info(__func__, "Load the EXTRACT1D table") ;
602 if ((extracted_table = cr2res_io_load_EXTRACT_1D(cur_fname,
603 det_nr)) == NULL) {
604 cpl_msg_error(__func__,"Failed to load table - skip detector");
605 cpl_table_delete(trace_wave) ;
606 cpl_error_reset() ;
607 cpl_msg_indent_less() ;
608 continue ;
609 }
610
611 /* Compute the Wavelength Calibration */
612 cpl_msg_info(__func__, "Compute the Wavelength") ;
613 if (cr2res_wave_apply(trace_wave, extracted_table,
614 lines_frame, reduce_order, reduce_trace, wavecal_type,
615 wl_degree, wl_xdegree,
616 wl_start, wl_end, wl_err, wl_shift, log_flag,
617 fallback_input_wavecal_flag, keep_higher_degrees_flag,
618 clean_spectrum, display, display_wmin, display_wmax,
619 zp_order, grat1_order,
620 &qcs_plist,
621 &(lines_diagnostics[det_nr-1]),
622 &(updated_extracted_table[det_nr-1]),
623 &(out_trace_wave[det_nr-1]))) {
624 cpl_msg_error(__func__, "Failed to calibrate - skip detector");
625 cpl_table_delete(trace_wave) ;
626 cpl_table_delete(extracted_table) ;
627 cpl_error_reset() ;
628 cpl_msg_indent_less() ;
629 continue ;
630 }
631 cpl_table_delete(trace_wave) ;
632 cpl_table_delete(extracted_table) ;
633
634 /* Store the QC parameters in the plist */
635 if (qcs_plist != NULL) {
636 cpl_propertylist_append(ext_plist[det_nr-1], qcs_plist) ;
637 cpl_propertylist_delete(qcs_plist) ;
638 }
639
640 /* Generate the Wave Map */
641 out_wave_map[det_nr-1] =
642 cr2res_wave_gen_wave_map(out_trace_wave[det_nr-1]) ;
643 cpl_msg_indent_less() ;
644 }
645
646 /* Generate the currently used frameset */
647 /* TODO : add calibrations */
648 cur_fset = cpl_frameset_new() ;
649 cpl_frameset_insert(cur_fset, cpl_frame_duplicate(cur_frame)) ;
650
651 /* Save the new trace_wave table */
652 out_file = cpl_sprintf("%s_tw.fits",
654 cr2res_io_save_TRACE_WAVE(out_file, frameset, cur_fset, parlist,
655 out_trace_wave, NULL, ext_plist, CR2RES_UTIL_WAVE_TW_PROCATG,
656 RECIPE_STRING) ;
657 cpl_free(out_file);
658
659 /* Save the Wave Map */
660 out_file = cpl_sprintf("%s_wave_map.fits",
662 cr2res_io_save_WAVE_MAP(out_file, frameset, cur_fset, parlist,
663 out_wave_map, NULL, ext_plist,
664 CR2RES_UTIL_WAVE_MAP_PROCATG, RECIPE_STRING) ;
665 cpl_free(out_file);
666
667 /* Save the Extracted */
668 out_file = cpl_sprintf("%s_extracted.fits",
670 cr2res_io_save_EXTRACT_1D(out_file, frameset, cur_fset, parlist,
671 updated_extracted_table, NULL, ext_plist,
672 CR2RES_UTIL_WAVE_EXTRACT_1D_PROCATG, RECIPE_STRING) ;
673 cpl_free(out_file);
674
675 /* Save the Lines Diagnostics */
676 out_file = cpl_sprintf("%s_lines_diagnostics.fits",
678 cr2res_io_save_LINES_DIAGNOSTICS(out_file, frameset, cur_fset,
679 parlist, lines_diagnostics, NULL, ext_plist,
680 CR2RES_UTIL_WAVE_LINES_DIAGNOSTICS_PROCATG, RECIPE_STRING) ;
681 cpl_free(out_file);
682 cpl_frameset_delete(cur_fset) ;
683
684 /* Free and return */
685 for (j=0 ; j<CR2RES_NB_DETECTORS ; j++) {
686 if (ext_plist[j] != NULL)
687 cpl_propertylist_delete(ext_plist[j]) ;
688 if (out_trace_wave[j] != NULL)
689 cpl_table_delete(out_trace_wave[j]) ;
690 if (lines_diagnostics[j] != NULL)
691 cpl_table_delete(lines_diagnostics[j]) ;
692 if (updated_extracted_table[j] != NULL)
693 cpl_table_delete(updated_extracted_table[j]) ;
694 if (out_wave_map[j] != NULL)
695 hdrl_image_delete(out_wave_map[j]) ;
696 }
697 cpl_msg_indent_less() ;
698 }
699 cpl_frameset_delete(rawframes) ;
700 return (int)cpl_error_get_code();
701}
cpl_error_code cr2res_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: cr2res_dfs.c:53
cpl_table * cr2res_io_load_EXTRACT_1D(const char *filename, int detector)
Load a table from a EXTRACT_1D.
Definition: cr2res_io.c:1296
const cpl_frame * cr2res_io_find_TRACE_WAVE(const cpl_frameset *in)
Get the first CR2RES_TW_DRSTYPE frame from a frameset.
Definition: cr2res_io.c:231
int cr2res_io_save_WAVE_MAP(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, hdrl_image **data, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a WAVE_MAP.
Definition: cr2res_io.c:1916
int cr2res_io_save_TRACE_WAVE(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, cpl_table **tables, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a TRACE_WAVE.
Definition: cr2res_io.c:1670
int cr2res_io_save_EXTRACT_1D(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, cpl_table **tables, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a 1D extracted spectrum.
Definition: cr2res_io.c:1732
int cr2res_io_get_ext_idx(const char *filename, int detector, int data)
Get the wished extension number for a detector.
Definition: cr2res_io.c:644
cpl_frameset * cr2res_io_find_EXTRACT_1D_all(const cpl_frameset *in)
Get the CR2RES_EXTRACT_1D_DRSTYPE frames from a frameset.
Definition: cr2res_io.c:331
cpl_table * cr2res_io_load_TRACE_WAVE(const char *filename, int detector)
Load a table from a TRACE_WAVE.
Definition: cr2res_io.c:1109
int cr2res_io_save_LINES_DIAGNOSTICS(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, cpl_table **tables, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a LINES_DIAGNOSTICS.
Definition: cr2res_io.c:1701
char * cr2res_get_root_name(const char *filename)
Find out the root part of a basename (name without extension).
char * cr2res_get_base_name(const char *filename)
Find out the base name of a file (i.e. without prefix path)
const char * cr2res_get_license(void)
Get the pipeline copyright and license.
hdrl_image * cr2res_wave_gen_wave_map(const cpl_table *trace_wave)
Compute the wavelength map from the trace_wave table.
Definition: cr2res_wave.c:1608
int cr2res_wave_apply(cpl_table *tw_in, cpl_table *spectra_tab, const cpl_frame *catalog_frame, int reduce_order, int reduce_trace, cr2res_wavecal_type wavecal_type, int degree, int xdegree, double wl_start, double wl_end, double wl_err, double wl_shift, int log_flag, int fallback_input_wavecal_flag, int keep_higher_degrees_flag, int clean_spectrum, int display, double display_wmin, double display_wmax, int zp_order, int grat1_order, cpl_propertylist **qcs, cpl_table **lines_diagnostics, cpl_table **extracted_out, cpl_table **trace_wave_out)
Apply the Wavelength Calibration.
Definition: cr2res_wave.c:150
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379