35#include "cr2res_utils.h"
36#include "cr2res_calib.h"
37#include "cr2res_pfits.h"
38#include "cr2res_dfs.h"
41#include "cr2res_slit_curv.h"
42#include "cr2res_extract.h"
43#include "cr2res_trace.h"
44#include "cr2res_wave.h"
50#define RECIPE_STRING "cr2res_cal_wave"
51#define CRIRES_PI 3.1415926535897932384626433832795029L
57int cpl_plugin_get_info(cpl_pluginlist * list);
63static int cr2res_cal_wave_qc_une_flux(
64 const cpl_table ** extracted,
65 const cpl_propertylist ** ext_plist,
67 cpl_propertylist * plist) ;
68static int cr2res_cal_wave_qc_fpi(
69 const cpl_table ** extracted,
70 const cpl_table ** tw,
71 const cpl_propertylist ** ext_plist,
73 cpl_propertylist * plist) ;
74static int cr2res_cal_wave_qc_tilt(
75 const cpl_table ** tws,
77 cpl_propertylist * plist) ;
78static int cr2res_cal_wave_reduce(
79 const cpl_frameset * rawframes_une,
80 const cpl_frameset * rawframes_fpet,
81 const cpl_frame * detlin_frame,
82 const cpl_frame * master_dark_frame,
83 const cpl_frame * master_flat_frame,
84 const cpl_frame * bpm_frame,
85 const cpl_frame * trace_wave_frame,
86 const cpl_frame * lines_frame,
91 int subtract_nolight_rows,
93 cr2res_collapse collapse,
97 double ext_smooth_slit,
98 double ext_smooth_spec,
99 cr2res_wavecal_type wavecal_type,
106 int fallback_input_wavecal_flag,
107 int keep_higher_degrees_flag,
112 cpl_table ** out_trace_wave_une,
113 cpl_table ** lines_diagnostics_une,
114 cpl_table ** out_extracted_une,
115 hdrl_image ** out_wave_map_une,
116 cpl_propertylist ** ext_plist_une,
117 cpl_table ** out_trace_wave_fpet,
118 cpl_table ** lines_diagnostics_fpet,
119 cpl_table ** out_extracted_fpet,
120 hdrl_image ** out_wave_map_fpet,
121 cpl_propertylist ** ext_plist_fpet) ;
122static int cr2res_cal_wave_create(cpl_plugin *);
123static int cr2res_cal_wave_exec(cpl_plugin *);
124static int cr2res_cal_wave_destroy(cpl_plugin *);
125static int cr2res_cal_wave(cpl_frameset *,
const cpl_parameterlist *);
131static char cr2res_cal_wave_description[] =
"\
132Spectrum Extraction and Wavelength Calibration \n\
133 This recipe performs the extraction of the various orders along \n\
134 the provided traces, and the wavelength calibration of these \n\
135 extracted spectra. \n\
136 It can support different methods (--wl_method parameter): \n\
137 XCORR: Cross Correlation with a emission lines catalog (default) \n\
138 LINE1D: Line identification and fitting for each 1D spectra \n\
139 LINE2D: Line identification and fitting for all 1D spectra at once \n\
142 raw.fits " CR2RES_WAVE_UNE_RAW
" [1 to n] \n\
143 or " CR2RES_WAVE_FPET_RAW
" [0 to n] \n\
144 trace.fits " CR2RES_CAL_FLAT_TW_PROCATG
" [1] \n\
145 or " CR2RES_CAL_FLAT_TW_MERGED_PROCATG
" \n\
146 or " CR2RES_UTIL_TRACE_TW_PROCATG
" \n\
147 or " CR2RES_UTIL_WAVE_TW_PROCATG
" \n\
148 or " CR2RES_CAL_WAVE_TW_PROCATG
" \n\
149 or " CR2RES_UTIL_SLIT_CURV_TW_PROCATG
" \n\
150 detlin.fits " CR2RES_CAL_DETLIN_COEFFS_PROCATG
" [0 to 1] \n\
151 bpm.fits " CR2RES_CAL_DARK_BPM_PROCATG
" [0 to 1] \n\
152 or " CR2RES_CAL_FLAT_BPM_PROCATG
" \n\
153 or " CR2RES_CAL_DETLIN_BPM_PROCATG
" \n\
154 or " CR2RES_UTIL_BPM_MERGE_PROCATG
" \n\
155 or " CR2RES_UTIL_BPM_SPLIT_PROCATG
" \n\
156 master_dark.fits " CR2RES_CAL_DARK_MASTER_PROCATG
" [0 to 1] \n\
157 master_flat.fits " CR2RES_CAL_FLAT_MASTER_PROCATG
" [0 to 1] \n\
158 lines.fits " CR2RES_EMISSION_LINES_PROCATG
" [0 to 1] \n\
161 cr2res_cal_wave_tw.fits " CR2RES_CAL_WAVE_TW_PROCATG
" \n\
162 cr2res_cal_wave_wave_map.fits " CR2RES_CAL_WAVE_MAP_PROCATG
" \n\
163 cr2res_cal_wave_lines_diagnostics.fits "
164 CR2RES_CAL_WAVE_LINES_DIAGNOSTICS_PROCATG
"\n\
165 cr2res_cal_wave_extracted.fits " CR2RES_CAL_WAVE_EXTRACT_1D_PROCATG
"\n\
168 loop on detectors d: \n\
169 Call cr2res_cal_wave_reduce() \n\
170 -> out_trace_wave[une|fpet](d) \n\
171 -> lines_diagnostics[une|fpet](d) \n\
172 -> out_extracted[une|fpet](d) \n\
173 -> out_wave_map[une|fpet](d) \n\
174 Save out_trace_wave[une|fpet] \n\
175 Save lines_diagnostics[une|fpet] \n\
176 Save out_extracted[une|fpet] \n\
177 Save out_wave_map[une|fpet] \n\
179 cr2res_cal_wave_reduce(): \n\
180 If FPET RAW frame is present, compute the slit_curvature from it, \n\
181 use it in the following, and store it in the out_trace_wave_fpet. \n\
183 Successively for UNE and FPET RAW frames: \n\
184 Load the raw image list \n\
185 Apply the calibrations to the image list \n\
186 Collapse the image list \n\
187 Extract along the traces from the collapsed image \n\
188 Compute the Wavelength with cr2res_wave_apply() \n\
189 -> out_trace_wave \n\
190 -> lines_diagnostics \n\
192 Compute the Wavelength map \n\
195 cr2res_wave_apply() \n\
196 loop on the traces t: \n\
198 Get the Initial guess \n\
199 Switch on the required method: \n\
200 CR2RES_LINE2D: cr2res_wave_2d() \n\
201 CR2RES_LINE1D: cr2res_wave_line_fitting() \n\
202 CR2RES_ETALON: cr2res_wave_etalon() \n\
203 CR2RES_XCORR: cr2res_wave_xcorr() \n\
205 Library Functions used \n\
206 cr2res_io_find_TRACE_WAVE() \n\
207 cr2res_io_find_BPM() \n\
208 cr2res_io_read_dits() \n\
209 cr2res_io_load_image_list_from_set() \n\
210 cr2res_calib_imagelist() \n\
211 cr2res_io_load_TRACE_WAVE() \n\
212 cr2res_extract_traces() \n\
213 cr2res_wave_apply() \n\
214 cr2res_extract_EXTRACT1D_get_spectrum() \n\
215 cr2res_wave_estimate_compute() \n\
217 cr2res_wave_line_fitting() \n\
218 cr2res_wave_etalon() \n\
219 cr2res_wave_xcorr() \n\
220 cr2res_wave_gen_wave_map() \n\
221 cr2res_io_save_TRACE_WAVE() \n\
222 cr2res_io_save_WAVE_MAP() \n\
223 cr2res_io_save_LINES_DIAGNOSTICS() \n\
224 cr2res_io_save_EXTRACT_1D() \n\
242int cpl_plugin_get_info(cpl_pluginlist * list)
244 cpl_recipe * recipe = cpl_calloc(1,
sizeof *recipe );
245 cpl_plugin * plugin = &recipe->interface;
247 if (cpl_plugin_init(plugin,
249 CR2RES_BINARY_VERSION,
250 CPL_PLUGIN_TYPE_RECIPE,
252 "Wavelength Calibration",
253 cr2res_cal_wave_description,
254 CR2RES_PIPELINE_AUTHORS,
257 cr2res_cal_wave_create,
258 cr2res_cal_wave_exec,
259 cr2res_cal_wave_destroy)) {
260 cpl_msg_error(cpl_func,
"Plugin initialization failed");
261 (void)cpl_error_set_where(cpl_func);
265 if (cpl_pluginlist_append(list, plugin)) {
266 cpl_msg_error(cpl_func,
"Error adding plugin to list");
267 (void)cpl_error_set_where(cpl_func);
283static int cr2res_cal_wave_create(cpl_plugin * plugin)
289 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
290 recipe = (cpl_recipe *)plugin;
295 recipe->parameters = cpl_parameterlist_new();
298 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.detector",
299 CPL_TYPE_INT,
"Only reduce the specified detector",
300 "cr2res.cr2res_cal_wave", 0);
301 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"detector");
302 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
303 cpl_parameterlist_append(recipe->parameters, p);
305 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.order",
306 CPL_TYPE_INT,
"Only reduce the specified order",
307 "cr2res.cr2res_cal_wave", -1);
308 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"order");
309 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
310 cpl_parameterlist_append(recipe->parameters, p);
312 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.trace_nb",
313 CPL_TYPE_INT,
"Only reduce the specified trace number",
314 "cr2res.cr2res_cal_wave", -1);
315 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"trace_nb");
316 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
317 cpl_parameterlist_append(recipe->parameters, p);
319 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.slit_degree",
320 CPL_TYPE_INT,
"Slit fitting Polynomial degree (1 or 2)",
321 "cr2res.cr2res_cal_wave", 2);
322 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"slit_degree");
323 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
324 cpl_parameterlist_append(recipe->parameters, p);
326 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.subtract_nolight_rows",
327 CPL_TYPE_BOOL,
"Subtract the no-light rows.",
328 "cr2res.cr2res_cal_wave", FALSE);
329 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"subtract_nolight_rows");
330 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
331 cpl_parameterlist_append(recipe->parameters, p);
333 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.cosmics",
334 CPL_TYPE_BOOL,
"Find and mark cosmic rays hits as bad",
335 "cr2res.cr2res_cal_wave", FALSE);
336 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"cosmics");
337 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
338 cpl_parameterlist_append(recipe->parameters, p);
340 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.collapse_method",
341 CPL_TYPE_STRING,
"Collapse the input images (MEAN or MEDIAN)",
342 "cr2res.cr2res_cal_wave",
"MEDIAN");
343 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"collapse_method");
344 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
345 cpl_parameterlist_append(recipe->parameters, p);
347 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.extract_oversample",
348 CPL_TYPE_INT,
"factor by which to oversample the extraction",
349 "cr2res.cr2res_cal_wave", 7);
350 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_oversample");
351 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
352 cpl_parameterlist_append(recipe->parameters, p);
354 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.extract_swath_width",
355 CPL_TYPE_INT,
"The swath width",
"cr2res.cr2res_cal_wave", 2048);
356 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_swath_width");
357 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
358 cpl_parameterlist_append(recipe->parameters, p);
360 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.extract_height",
361 CPL_TYPE_INT,
"Extraction height",
362 "cr2res.cr2res_cal_wave", 160);
363 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_height");
364 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
365 cpl_parameterlist_append(recipe->parameters, p);
367 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.extract_smooth_slit",
368 CPL_TYPE_DOUBLE,
"Smoothing along the slit",
369 "cr2res.cr2res_cal_wave", 15.0);
370 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_smooth_slit");
371 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
372 cpl_parameterlist_append(recipe->parameters, p);
374 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.extract_smooth_spec",
375 CPL_TYPE_DOUBLE,
"Smoothing along the spectrum",
376 "cr2res.cr2res_cal_wave", 2.0E-7);
377 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_smooth_spec");
378 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
379 cpl_parameterlist_append(recipe->parameters, p);
381 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.wl_method",
383 "Wavelength Method (XCORR / LINE1D / LINE2D)",
384 "cr2res.cr2res_cal_wave",
"XCORR");
385 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wl_method");
386 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
387 cpl_parameterlist_append(recipe->parameters, p);
389 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.wl_shift",
390 CPL_TYPE_DOUBLE,
"Wavelength shift (nm) to apply to the guess",
391 "cr2res.cr2res_cal_wave", 0.0);
392 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wl_shift");
393 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
394 cpl_parameterlist_append(recipe->parameters, p);
396 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.wl_est",
397 CPL_TYPE_STRING,
"Estimated wavelength start and end",
398 "cr2res.cr2res_cal_wave",
"-1.0, -1.0");
399 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wl_est");
400 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
401 cpl_parameterlist_append(recipe->parameters, p);
403 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.wl_err",
404 CPL_TYPE_DOUBLE,
"Estimated wavelength error (in nm)",
405 "cr2res.cr2res_cal_wave", 0.04);
406 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wl_err");
407 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
408 cpl_parameterlist_append(recipe->parameters, p);
410 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.wl_degree",
411 CPL_TYPE_INT,
"Wavelength Polynomial degree",
412 "cr2res.cr2res_cal_wave", 0);
413 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wl_degree");
414 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
415 cpl_parameterlist_append(recipe->parameters, p);
417 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.log",
418 CPL_TYPE_BOOL,
"Flag for taking the Log() value of the lines",
419 "cr2res.cr2res_cal_wave", FALSE);
420 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"log");
421 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
422 cpl_parameterlist_append(recipe->parameters, p);
424 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.fallback_input_wavecal",
425 CPL_TYPE_BOOL,
"Flag for using the input WL when no computation",
426 "cr2res.cr2res_cal_wave", FALSE);
427 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"fallback");
428 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
429 cpl_parameterlist_append(recipe->parameters, p);
431 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.keep_higher_degrees",
433 "Flag for re-using higher degrees of first guess in Cross-Corr.",
434 "cr2res.cr2res_cal_wave", TRUE);
435 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"keep");
436 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
437 cpl_parameterlist_append(recipe->parameters, p);
439 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.save_intermediate",
441 "Flag to save UNE results (if UNE and FPET are used as inputs)",
442 "cr2res.cr2res_cal_wave", FALSE);
443 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"save");
444 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
445 cpl_parameterlist_append(recipe->parameters, p);
447 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.clean_spectrum",
448 CPL_TYPE_BOOL,
"Flag to automatically clean the missing lines",
449 "cr2res.cr2res_cal_wave", TRUE);
450 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"clean_spectrum");
451 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
452 cpl_parameterlist_append(recipe->parameters, p);
454 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.display",
455 CPL_TYPE_BOOL,
"Flag for display",
456 "cr2res.cr2res_cal_wave", FALSE);
457 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"display");
458 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
459 cpl_parameterlist_append(recipe->parameters, p);
461 p = cpl_parameter_new_value(
"cr2res.cr2res_cal_wave.display_range",
463 "Wavelength range to display [start, end] (in nm)",
464 "cr2res.cr2res_cal_wave",
"-1.0, -1.0");
465 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"display_range");
466 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
467 cpl_parameterlist_append(recipe->parameters, p);
479static int cr2res_cal_wave_exec(cpl_plugin * plugin)
484 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
485 recipe = (cpl_recipe *)plugin;
488 return cr2res_cal_wave(recipe->frames, recipe->parameters);
498static int cr2res_cal_wave_destroy(cpl_plugin * plugin)
503 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
504 recipe = (cpl_recipe *)plugin;
507 cpl_parameterlist_delete(recipe->parameters);
519static int cr2res_cal_wave(
520 cpl_frameset * frameset,
521 const cpl_parameterlist * parlist)
523 const cpl_parameter * param;
524 int reduce_det, reduce_order, reduce_trace,
525 slit_degree, ext_oversample, ext_swath_width,
526 ext_height, wl_degree, display, log_flag,
527 fallback_input_wavecal_flag,
528 save_intermediate_flag, keep_higher_degrees_flag,
529 clean_spectrum, subtract_nolight_rows,
531 double ext_smooth_slit, ext_smooth_spec, wl_start, wl_end,
532 wl_err, wl_shift, display_wmin,
533 display_wmax, central_wlen;
534 cr2res_collapse collapse ;
535 cr2res_wavecal_type wavecal_type ;
537 cpl_frameset * rawframes_une ;
538 cpl_frameset * rawframes_fpet ;
539 const cpl_frame * detlin_frame ;
540 const cpl_frame * master_dark_frame ;
541 const cpl_frame * master_flat_frame ;
542 const cpl_frame * bpm_frame ;
543 const cpl_frame * trace_wave_frame ;
544 const cpl_frame * lines_frame ;
545 cpl_propertylist * plist ;
547 cpl_table * out_trace_wave_une[CR2RES_NB_DETECTORS] ;
548 cpl_table * lines_diagnostics_une[CR2RES_NB_DETECTORS] ;
549 cpl_table * out_extracted_une[CR2RES_NB_DETECTORS] ;
550 hdrl_image * out_wave_map_une[CR2RES_NB_DETECTORS] ;
551 cpl_propertylist * ext_plist_une[CR2RES_NB_DETECTORS] ;
552 cpl_table * out_trace_wave_fpet[CR2RES_NB_DETECTORS] ;
553 cpl_table * lines_diagnostics_fpet[CR2RES_NB_DETECTORS] ;
554 cpl_table * out_extracted_fpet[CR2RES_NB_DETECTORS] ;
555 hdrl_image * out_wave_map_fpet[CR2RES_NB_DETECTORS] ;
556 cpl_propertylist * ext_plist_fpet[CR2RES_NB_DETECTORS] ;
557 cpl_propertylist * qc_main ;
561 setlocale(LC_NUMERIC,
"C");
564 wl_start = wl_end = -1.0 ;
566 collapse = CR2RES_COLLAPSE_UNSPECIFIED ;
567 display_wmin = display_wmax = -1.0 ;
569 int qc_sizes[] = {CR2RES_NB_DETECTORS,CR2RES_NB_DETECTORS};
570 cpl_propertylist** qc_plists[] = {ext_plist_une, ext_plist_fpet} ;
571 cpl_propertylist** qc_plists_une[] = {ext_plist_une} ;
574 param = cpl_parameterlist_find_const(parlist,
575 "cr2res.cr2res_cal_wave.detector");
576 reduce_det = cpl_parameter_get_int(param);
577 param = cpl_parameterlist_find_const(parlist,
578 "cr2res.cr2res_cal_wave.order");
579 reduce_order = cpl_parameter_get_int(param);
580 param = cpl_parameterlist_find_const(parlist,
581 "cr2res.cr2res_cal_wave.trace_nb");
582 reduce_trace = cpl_parameter_get_int(param);
583 param = cpl_parameterlist_find_const(parlist,
584 "cr2res.cr2res_cal_wave.slit_degree");
585 slit_degree = cpl_parameter_get_int(param);
586 param = cpl_parameterlist_find_const(parlist,
587 "cr2res.cr2res_cal_wave.subtract_nolight_rows");
588 subtract_nolight_rows = cpl_parameter_get_bool(param) ;
589 param = cpl_parameterlist_find_const(parlist,
590 "cr2res.cr2res_cal_wave.cosmics");
591 cosmics = cpl_parameter_get_bool(param);
592 param = cpl_parameterlist_find_const(parlist,
593 "cr2res.cr2res_cal_wave.collapse_method");
594 sval = cpl_parameter_get_string(param);
595 if (!strcmp(sval,
"MEAN")) collapse = CR2RES_COLLAPSE_MEAN ;
596 else if (!strcmp(sval,
"MEDIAN")) collapse = CR2RES_COLLAPSE_MEDIAN ;
597 if (collapse!=CR2RES_COLLAPSE_MEAN && collapse!=CR2RES_COLLAPSE_MEDIAN) {
598 cpl_msg_error(__func__,
"Unsupported collapse method") ;
599 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
602 param = cpl_parameterlist_find_const(parlist,
603 "cr2res.cr2res_cal_wave.extract_oversample");
604 ext_oversample = cpl_parameter_get_int(param);
605 param = cpl_parameterlist_find_const(parlist,
606 "cr2res.cr2res_cal_wave.extract_swath_width");
607 ext_swath_width = cpl_parameter_get_int(param);
608 param = cpl_parameterlist_find_const(parlist,
609 "cr2res.cr2res_cal_wave.extract_height");
610 ext_height = cpl_parameter_get_int(param);
611 param = cpl_parameterlist_find_const(parlist,
612 "cr2res.cr2res_cal_wave.extract_smooth_slit");
613 ext_smooth_slit = cpl_parameter_get_double(param);
614 param = cpl_parameterlist_find_const(parlist,
615 "cr2res.cr2res_cal_wave.extract_smooth_spec");
616 ext_smooth_spec = cpl_parameter_get_double(param);
617 param = cpl_parameterlist_find_const(parlist,
618 "cr2res.cr2res_cal_wave.wl_method");
619 sval = cpl_parameter_get_string(param) ;
620 if (!strcmp(sval,
"XCORR")) wavecal_type = CR2RES_XCORR ;
621 else if (!strcmp(sval,
"LINE1D")) wavecal_type = CR2RES_LINE1D ;
622 else if (!strcmp(sval,
"LINE2D")) wavecal_type = CR2RES_LINE2D ;
624 cpl_msg_error(__func__,
"Invalid Method specified");
625 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
628 param = cpl_parameterlist_find_const(parlist,
629 "cr2res.cr2res_cal_wave.wl_shift");
630 wl_shift = cpl_parameter_get_double(param) ;
631 param = cpl_parameterlist_find_const(parlist,
632 "cr2res.cr2res_cal_wave.wl_est");
633 sval = cpl_parameter_get_string(param) ;
634 if (sscanf(sval,
"%lg,%lg", &wl_start, &wl_end) != 2) {
637 param = cpl_parameterlist_find_const(parlist,
638 "cr2res.cr2res_cal_wave.wl_err");
639 wl_err = cpl_parameter_get_double(param) ;
640 param = cpl_parameterlist_find_const(parlist,
641 "cr2res.cr2res_cal_wave.wl_degree");
642 wl_degree = cpl_parameter_get_int(param);
643 param = cpl_parameterlist_find_const(parlist,
644 "cr2res.cr2res_cal_wave.log");
645 log_flag = cpl_parameter_get_bool(param) ;
646 param = cpl_parameterlist_find_const(parlist,
647 "cr2res.cr2res_cal_wave.fallback_input_wavecal");
648 fallback_input_wavecal_flag = cpl_parameter_get_bool(param) ;
649 param = cpl_parameterlist_find_const(parlist,
650 "cr2res.cr2res_cal_wave.keep_higher_degrees");
651 keep_higher_degrees_flag = cpl_parameter_get_bool(param) ;
652 param = cpl_parameterlist_find_const(parlist,
653 "cr2res.cr2res_cal_wave.save_intermediate");
654 save_intermediate_flag = cpl_parameter_get_bool(param) ;
655 param = cpl_parameterlist_find_const(parlist,
656 "cr2res.cr2res_cal_wave.clean_spectrum");
657 clean_spectrum = cpl_parameter_get_bool(param) ;
658 param = cpl_parameterlist_find_const(parlist,
659 "cr2res.cr2res_cal_wave.display");
660 display = cpl_parameter_get_bool(param) ;
661 param = cpl_parameterlist_find_const(parlist,
662 "cr2res.cr2res_cal_wave.display_range");
663 sval = cpl_parameter_get_string(param) ;
664 if (sscanf(sval,
"%lg,%lg", &display_wmin, &display_wmax) != 2) {
669 if (display==TRUE && (reduce_order==-1 || reduce_det==0)){
670 cpl_msg_warning(__func__,
671 "Option --display can only be used with --order"
676 cpl_msg_error(__func__,
"The degree needs to be >= 0");
677 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
680 if (wl_degree == 0 && !keep_higher_degrees_flag) {
681 cpl_msg_error(__func__,
"The degree 0 can only be used with --keep");
682 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
685 if (slit_degree != 1 && slit_degree != 2) {
686 cpl_msg_error(__func__,
"The slit fit degree must be 1 or 2");
687 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
693 cpl_msg_error(__func__,
"Cannot identify RAW and CALIB frames") ;
694 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
700 if (trace_wave_frame == NULL) {
701 cpl_msg_error(__func__,
"Could not find TRACE_WAVE frame") ;
704 detlin_frame = cpl_frameset_find_const(frameset,
705 CR2RES_CAL_DETLIN_COEFFS_PROCATG);
706 master_dark_frame = cpl_frameset_find_const(frameset,
707 CR2RES_CAL_DARK_MASTER_PROCATG) ;
708 master_flat_frame = cpl_frameset_find_const(frameset,
709 CR2RES_CAL_FLAT_MASTER_PROCATG) ;
711 lines_frame = cpl_frameset_find_const(frameset,
712 CR2RES_EMISSION_LINES_PROCATG) ;
717 if (rawframes_une == NULL && rawframes_fpet == NULL) {
718 cpl_msg_error(__func__,
"Could not find RAW frames") ;
721 if (lines_frame == NULL && rawframes_une != NULL) {
722 cpl_frameset_delete(rawframes_une) ;
723 if (rawframes_fpet!=NULL) cpl_frameset_delete(rawframes_fpet) ;
724 cpl_msg_error(__func__,
"The emission lines catalog is needed");
725 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
728 if (reduce_order > -1 && wavecal_type == CR2RES_LINE2D) {
729 if (rawframes_une !=NULL) cpl_frameset_delete(rawframes_une) ;
730 if (rawframes_fpet!=NULL) cpl_frameset_delete(rawframes_fpet) ;
731 cpl_msg_error(__func__,
"Limiting to one order with LINE2D impossible");
732 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
735 if (reduce_order > -1 && wavecal_type == CR2RES_ETALON) {
736 if (rawframes_une !=NULL) cpl_frameset_delete(rawframes_une) ;
737 if (rawframes_fpet!=NULL) cpl_frameset_delete(rawframes_fpet) ;
738 cpl_msg_error(__func__,
"Limiting to one order with ETALON impossible");
739 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
744 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
747 out_trace_wave_une[det_nr-1] = NULL ;
748 lines_diagnostics_une[det_nr-1] = NULL ;
749 out_extracted_une[det_nr-1] = NULL ;
750 out_wave_map_une[det_nr-1] = NULL ;
751 ext_plist_une[det_nr-1] = NULL ;
753 out_trace_wave_fpet[det_nr-1] = NULL ;
754 lines_diagnostics_fpet[det_nr-1] = NULL ;
755 out_extracted_fpet[det_nr-1] = NULL ;
756 out_wave_map_fpet[det_nr-1] = NULL ;
757 ext_plist_fpet[det_nr-1] = NULL ;
760 if (reduce_det != 0 && det_nr != reduce_det) {
763 if (rawframes_une != NULL)
765 cpl_frame_get_filename(trace_wave_frame), det_nr) ;
766 if (rawframes_fpet != NULL)
768 cpl_frame_get_filename(trace_wave_frame), det_nr) ;
772 if (!fallback_input_wavecal_flag) {
774 if (rawframes_une != NULL) {
775 cpl_table_erase_column(out_trace_wave_une[det_nr-1],
776 CR2RES_COL_WAVELENGTH) ;
777 cpl_table_new_column_array(out_trace_wave_une[det_nr-1],
778 CR2RES_COL_WAVELENGTH, CPL_TYPE_DOUBLE, 2) ;
779 cpl_table_erase_column(out_trace_wave_une[det_nr-1],
780 CR2RES_COL_WAVELENGTH_ERROR) ;
781 cpl_table_new_column_array(out_trace_wave_une[det_nr-1],
782 CR2RES_COL_WAVELENGTH_ERROR, CPL_TYPE_DOUBLE, 2) ;
784 if (rawframes_fpet != NULL) {
785 cpl_table_erase_column(out_trace_wave_fpet[det_nr-1],
786 CR2RES_COL_WAVELENGTH) ;
787 cpl_table_new_column_array(out_trace_wave_fpet[det_nr-1],
788 CR2RES_COL_WAVELENGTH, CPL_TYPE_DOUBLE, 2) ;
789 cpl_table_erase_column(out_trace_wave_fpet[det_nr-1],
790 CR2RES_COL_WAVELENGTH_ERROR) ;
791 cpl_table_new_column_array(out_trace_wave_fpet[det_nr-1],
792 CR2RES_COL_WAVELENGTH_ERROR, CPL_TYPE_DOUBLE, 2) ;
798 cpl_msg_info(__func__,
"Process detector number %d", det_nr) ;
799 cpl_msg_indent_more() ;
803 out_trace_wave_une[det_nr-1] =
805"/home/yjung/P_cr2res/test_cr2res_cal_wave/res/cr2res_cal_wave_tw_une.fits",
808"/home/yjung/P_cr2res/test_cr2res_cal_wave/res/cr2res_cal_wave_extracted_une.fits",
810 ext_plist_une[det_nr-1] = cpl_propertylist_load(
811"/home/yjung/P_cr2res/test_cr2res_cal_wave/res/cr2res_cal_wave_extracted_une.fits",
813 out_trace_wave_fpet[det_nr-1] =
815"/home/yjung/P_cr2res/test_cr2res_cal_wave/res/cr2res_cal_wave_tw_fpet.fits",
817 out_extracted_fpet[det_nr-1] =
819"/home/yjung/P_cr2res/test_cr2res_cal_wave/res/cr2res_cal_wave_extracted_fpet.fits",
821 ext_plist_fpet[det_nr-1] =
822 cpl_propertylist_load(
823"/home/yjung/P_cr2res/test_cr2res_cal_wave/res/cr2res_cal_wave_extracted_fpet.fits",
825 lines_diagnostics_une[det_nr-1] = NULL ;
826 out_wave_map_une[det_nr-1] = NULL ;
827 out_wave_map_fpet[det_nr-1] = NULL ;
828 lines_diagnostics_fpet[det_nr-1] = NULL ;
832 if (cr2res_cal_wave_reduce(rawframes_une, rawframes_fpet, detlin_frame,
833 master_dark_frame, master_flat_frame, bpm_frame,
834 trace_wave_frame, lines_frame, det_nr, reduce_order,
835 reduce_trace, slit_degree, subtract_nolight_rows, cosmics,
836 collapse, ext_height, ext_swath_width, ext_oversample,
837 ext_smooth_slit, ext_smooth_spec, wavecal_type, wl_degree,
838 wl_start, wl_end, wl_err, wl_shift, log_flag,
839 fallback_input_wavecal_flag, keep_higher_degrees_flag,
840 clean_spectrum, display, display_wmin,
842 &(out_trace_wave_une[det_nr-1]),
843 &(lines_diagnostics_une[det_nr-1]),
844 &(out_extracted_une[det_nr-1]),
845 &(out_wave_map_une[det_nr-1]),
846 &(ext_plist_une[det_nr-1]),
847 &(out_trace_wave_fpet[det_nr-1]),
848 &(lines_diagnostics_fpet[det_nr-1]),
849 &(out_extracted_fpet[det_nr-1]),
850 &(out_wave_map_fpet[det_nr-1]),
851 &(ext_plist_fpet[det_nr-1])) == -1) {
852 cpl_msg_warning(__func__,
"Failed to reduce detector %d", det_nr);
857 cpl_msg_indent_less() ;
861 qc_main = cpl_propertylist_new() ;
863 cr2res_qc_calculate_mean_and_rmsd(qc_plists, 2, qc_sizes,
864 CR2RES_HEADER_QC_WAVE_CENTWL, qc_main,
865 CR2RES_HEADER_QC_WAVE_CENTWL_AVG, CR2RES_HEADER_QC_WAVE_CENTWL_RMS);
867 cr2res_qc_calculate_mean_and_rmsd(qc_plists, 2, qc_sizes,
868 CR2RES_HEADER_QC_WAVE_DISPWL, qc_main,
869 CR2RES_HEADER_QC_WAVE_DISPWL_AVG, CR2RES_HEADER_QC_WAVE_DISPWL_RMS);
871 char* qc_une_keywords[] = {
872 CR2RES_HEADER_QC_WAVE_LAMP_EFFIC,
873 CR2RES_HEADER_QC_WAVE_RESOL,
874 CR2RES_HEADER_QC_WAVE_RESOL_FWHM,
875 CR2RES_HEADER_QC_WAVE_POS,
876 CR2RES_HEADER_QC_WAVE_BESTXCORR,
877 CR2RES_HEADER_QC_OVEREXPOSED
881 int qc_une_keywords_size =
sizeof(qc_une_keywords) /
sizeof(qc_une_keywords[0]);
883 if (rawframes_une != NULL) {
884 plist = cpl_propertylist_load(cpl_frame_get_filename(
885 cpl_frameset_get_position_const(rawframes_une, 0)), 0) ;
887 cpl_propertylist_delete(plist);
890 if (cr2res_cal_wave_qc_une_flux(
891 (
const cpl_table **)out_extracted_une,
892 (
const cpl_propertylist **)ext_plist_une,
893 central_wlen, qc_main)) {
894 cpl_msg_warning(__func__,
"QC.UNE.FLUX Computation failed") ;
900 int min_order = INT_MAX;
901 int max_order = INT_MIN;
902 int current_min, current_max;
904 for (
int qc_i = 0; qc_i < CR2RES_NB_DETECTORS; qc_i++) {
905 if (out_trace_wave_une[qc_i] == NULL) {
908 current_min = cpl_table_get_column_min(out_trace_wave_une[qc_i],
"Order");
909 if (cpl_error_get_code() != CPL_ERROR_NONE) {
912 if (current_min < min_order) {
913 min_order = current_min;
916 current_max = cpl_table_get_column_max(out_trace_wave_une[qc_i],
"Order");
917 if (cpl_error_get_code() != CPL_ERROR_NONE) {
920 if (current_max > max_order) {
921 max_order = current_max;
926 for (qc_j=0; qc_j<qc_une_keywords_size ; qc_j++) {
927 for (
int order_id=min_order ; order_id<=max_order ; order_id++) {
929 int qc_sizes_une[] = {CR2RES_NB_DETECTORS};
930 char * qc_ref, * qc_res_avg, * qc_res_rmsd ;
932 if(strcmp(qc_une_keywords[qc_j], CR2RES_HEADER_QC_OVEREXPOSED)==0) {
933 qc_ref = cpl_sprintf(
"%s%02d",
934 qc_une_keywords[qc_j], order_id);
935 qc_res_avg = cpl_sprintf(
"%s%02d %s",
936 qc_une_keywords[qc_j], order_id,
"AVG");
937 qc_res_rmsd = cpl_sprintf(
"%s%02d %s",
938 qc_une_keywords[qc_j], order_id,
"RMS");;
941 qc_ref = cpl_sprintf(
"%s-%02d-%02d",
942 qc_une_keywords[qc_j], order_id, 1);
943 qc_res_avg = cpl_sprintf(
"%s-%02d-%02d %s",
944 qc_une_keywords[qc_j], order_id, 1,
"AVG");
945 qc_res_rmsd = cpl_sprintf(
"%s-%02d-%02d %s",
946 qc_une_keywords[qc_j], order_id, 1,
"RMS");
949 cr2res_qc_calculate_mean_and_rmsd(qc_plists_une, 1, qc_sizes_une,
951 qc_res_avg, qc_res_rmsd);
954 cpl_free(qc_res_avg);
955 cpl_free(qc_res_rmsd);
959 if (cpl_error_get_code() != CPL_ERROR_NONE) {
960 cpl_msg_error(__func__,
"Failed to set QC params for UNE: %s",
961 cpl_error_get_message_default ( cpl_error_get_code())) ;
967 if (rawframes_fpet != NULL) {
968 plist = cpl_propertylist_load(cpl_frame_get_filename(
969 cpl_frameset_get_position_const(rawframes_fpet, 0)), 0) ;
971 cpl_propertylist_delete(plist);
974 if (cr2res_cal_wave_qc_tilt((
const cpl_table **)out_trace_wave_fpet,
975 central_wlen, qc_main)) {
976 cpl_msg_warning(__func__,
"QC.TILT Computation failed") ;
979 if (cr2res_cal_wave_qc_fpi(
980 (
const cpl_table **)out_extracted_fpet,
981 (
const cpl_table **)out_trace_wave_fpet,
982 (
const cpl_propertylist **)ext_plist_fpet,
983 central_wlen, qc_main)) {
984 cpl_msg_warning(__func__,
"QC.FPI Computation failed") ;
992 if (rawframes_une != NULL &&
993 (rawframes_fpet == NULL ||
994 save_intermediate_flag)) {
995 out_file = cpl_sprintf(
"%s_tw_une.fits", RECIPE_STRING) ;
997 out_trace_wave_une, qc_main, ext_plist_une,
998 CR2RES_CAL_WAVE_TW_PROCATG, RECIPE_STRING) ;
1001 out_file = cpl_sprintf(
"%s_wave_map_une.fits", RECIPE_STRING) ;
1003 out_wave_map_une, qc_main, ext_plist_une,
1004 CR2RES_CAL_WAVE_MAP_PROCATG, RECIPE_STRING) ;
1007 out_file = cpl_sprintf(
"%s_extracted_une.fits", RECIPE_STRING) ;
1009 out_extracted_une, qc_main, ext_plist_une,
1010 CR2RES_CAL_WAVE_EXTRACT_1D_PROCATG, RECIPE_STRING) ;
1013 out_file = cpl_sprintf(
"%s_lines_diagnostics_une.fits",
1016 parlist, lines_diagnostics_une, qc_main, ext_plist_une,
1017 CR2RES_CAL_WAVE_LINES_DIAGNOSTICS_PROCATG, RECIPE_STRING) ;
1021 if (rawframes_fpet != NULL) {
1023 out_file = cpl_sprintf(
"%s_tw_fpet.fits", RECIPE_STRING) ;
1025 out_trace_wave_fpet, qc_main, ext_plist_fpet,
1026 CR2RES_CAL_WAVE_TW_PROCATG, RECIPE_STRING) ;
1029 out_file = cpl_sprintf(
"%s_wave_map_fpet.fits", RECIPE_STRING) ;
1031 out_wave_map_fpet, qc_main, ext_plist_fpet,
1032 CR2RES_CAL_WAVE_MAP_PROCATG, RECIPE_STRING) ;
1035 out_file = cpl_sprintf(
"%s_extracted_fpet.fits", RECIPE_STRING) ;
1037 out_extracted_fpet, qc_main, ext_plist_fpet,
1038 CR2RES_CAL_WAVE_EXTRACT_1D_PROCATG, RECIPE_STRING) ;
1041 out_file = cpl_sprintf(
"%s_lines_diagnostics_fpet.fits",
1044 lines_diagnostics_fpet, qc_main, ext_plist_fpet,
1045 CR2RES_CAL_WAVE_LINES_DIAGNOSTICS_PROCATG, RECIPE_STRING) ;
1050 cpl_propertylist_delete(qc_main) ;
1051 cpl_frameset_delete(rawframes_une) ;
1052 if (rawframes_fpet!=NULL) cpl_frameset_delete(rawframes_fpet) ;
1053 for (i=0 ; i<CR2RES_NB_DETECTORS ; i++) {
1054 if (ext_plist_une[i] != NULL)
1055 cpl_propertylist_delete(ext_plist_une[i]) ;
1056 if (out_trace_wave_une[i] != NULL)
1057 cpl_table_delete(out_trace_wave_une[i]) ;
1058 if (lines_diagnostics_une[i] != NULL)
1059 cpl_table_delete(lines_diagnostics_une[i]) ;
1060 if (out_extracted_une[i] != NULL)
1061 cpl_table_delete(out_extracted_une[i]) ;
1062 if (out_wave_map_une[i] != NULL)
1064 if (ext_plist_fpet[i] != NULL)
1065 cpl_propertylist_delete(ext_plist_fpet[i]) ;
1066 if (out_trace_wave_fpet[i] != NULL)
1067 cpl_table_delete(out_trace_wave_fpet[i]) ;
1068 if (lines_diagnostics_fpet[i] != NULL)
1069 cpl_table_delete(lines_diagnostics_fpet[i]) ;
1070 if (out_extracted_fpet[i] != NULL)
1071 cpl_table_delete(out_extracted_fpet[i]) ;
1072 if (out_wave_map_fpet[i] != NULL)
1075 return (
int)cpl_error_get_code();
1128static int cr2res_cal_wave_reduce(
1129 const cpl_frameset * rawframes_une,
1130 const cpl_frameset * rawframes_fpet,
1131 const cpl_frame * detlin_frame,
1132 const cpl_frame * master_dark_frame,
1133 const cpl_frame * master_flat_frame,
1134 const cpl_frame * bpm_frame,
1135 const cpl_frame * trace_wave_frame,
1136 const cpl_frame * lines_frame,
1141 int subtract_nolight_rows,
1143 cr2res_collapse collapse,
1145 int ext_swath_width,
1147 double ext_smooth_slit,
1148 double ext_smooth_spec,
1149 cr2res_wavecal_type wavecal_type,
1156 int fallback_input_wavecal_flag,
1157 int keep_higher_degrees_flag,
1160 double display_wmin,
1161 double display_wmax,
1162 cpl_table ** out_trace_wave_une,
1163 cpl_table ** lines_diagnostics_une,
1164 cpl_table ** out_extracted_une,
1165 hdrl_image ** out_wave_map_une,
1166 cpl_propertylist ** ext_plist_une,
1167 cpl_table ** out_trace_wave_fpet,
1168 cpl_table ** lines_diagnostics_fpet,
1169 cpl_table ** out_extracted_fpet,
1170 hdrl_image ** out_wave_map_fpet,
1171 cpl_propertylist ** ext_plist_fpet)
1173 cpl_vector * ndits_fpet ;
1174 hdrl_imagelist * in_fpet ;
1175 hdrl_imagelist * in_fpet_calib ;
1176 hdrl_image * collapsed_une ;
1177 hdrl_image * collapsed_fpet ;
1178 cpl_image * contrib ;
1180 cpl_table * extracted_une ;
1181 cpl_table * slit_func_une ;
1182 hdrl_image * model_master_une ;
1183 cpl_table * extracted_fpet ;
1184 cpl_table * slit_func_fpet ;
1185 hdrl_image * model_master_fpet ;
1186 hdrl_image * wl_map_une_out ;
1187 cpl_table * tw_une_out ;
1188 cpl_table * lines_diagnostics_une_out ;
1189 cpl_table * extracted_une_out ;
1190 cpl_propertylist * qcs_une_out ;
1191 cpl_propertylist * plist_une_out ;
1192 hdrl_image * wl_map_fpet_out ;
1193 cpl_table * tw_fpet_out ;
1194 cpl_table * lines_diagnostics_fpet_out ;
1195 cpl_table * extracted_fpet_out ;
1196 cpl_propertylist * qcs_fpet_out ;
1197 cpl_propertylist * plist_fpet_out ;
1198 cpl_propertylist * plist ;
1199 const char * first_file ;
1200 cpl_polynomial * slit_polya ;
1201 cpl_polynomial * slit_polyb ;
1202 cpl_polynomial * slit_polyc ;
1203 double gain, error_factor ;
1204 int i, order, trace_id, ext_nr,
1205 zp_order_fpet, nb_traces,
1209 int extract_niter = 10;
1210 double extract_kappa = 10;
1213 if (rawframes_fpet==NULL && rawframes_une==NULL)
return -1 ;
1214 if (trace_wave_frame==NULL || out_trace_wave_une==NULL ||
1215 out_trace_wave_fpet==NULL || lines_diagnostics_une == NULL ||
1216 lines_diagnostics_fpet == NULL || out_extracted_une == NULL ||
1217 out_extracted_fpet == NULL || out_wave_map_une == NULL ||
1218 out_wave_map_fpet == NULL || ext_plist_une == NULL ||
1219 ext_plist_fpet == NULL)
return -1 ;
1220 if (collapse!=CR2RES_COLLAPSE_MEAN && collapse!=CR2RES_COLLAPSE_MEDIAN)
1224 if (reduce_det == 1) gain = CR2RES_GAIN_CHIP1 ;
1225 else if (reduce_det == 2) gain = CR2RES_GAIN_CHIP2 ;
1226 else if (reduce_det == 3) gain = CR2RES_GAIN_CHIP3 ;
1228 cpl_msg_error(__func__,
"Failed to get the Gain value") ;
1235 if (rawframes_fpet != NULL) {
1237 const cpl_frame * fpet_frame ;
1238 const char * fpet_fname ;
1239 hdrl_image * fpet_image ;
1241 fpet_frame = cpl_frameset_get_position_const(rawframes_fpet, 0) ;
1242 fpet_fname = cpl_frame_get_filename(fpet_frame) ;
1243 cpl_msg_info(__func__,
1244 "Compute the Slit Curvature from the first FPET frame %s",
1246 cpl_msg_indent_more() ;
1249 cpl_msg_info(__func__,
"Load the TRACE WAVE") ;
1251 trace_wave_frame), reduce_det)) == NULL) {
1252 cpl_msg_error(__func__,
"Failed to Load the traces file") ;
1253 cpl_msg_indent_less() ;
1258 cpl_msg_info(__func__,
"Load the FPET image") ;
1260 cpl_msg_error(__func__,
"Failed to load image") ;
1261 cpl_table_delete(tw_in) ;
1262 cpl_msg_indent_less() ;
1267 nb_traces = cpl_table_get_nrow(tw_in) ;
1268 for (i=0 ; i<nb_traces ; i++) {
1270 order = cpl_table_get(tw_in, CR2RES_COL_ORDER, i, NULL) ;
1271 trace_id = cpl_table_get(tw_in, CR2RES_COL_TRACENB, i, NULL) ;
1274 if (reduce_order > -1 && order != reduce_order) continue ;
1277 if (reduce_trace > -1 && trace_id != reduce_trace) continue ;
1279 cpl_msg_info(__func__,
"Process Order %d/Trace %d",order,trace_id) ;
1280 cpl_msg_indent_more() ;
1286 int change_degree = 1;
1288 trace_id, height, window, change_degree, slit_degree,
1289 &slit_polya, &slit_polyb, &slit_polyc)) {
1290 cpl_msg_error(__func__,
"Failed to compute slit curvature") ;
1291 cpl_table_delete(tw_in) ;
1293 cpl_msg_indent_less() ;
1297 cpl_array * slit_array ;
1300 cpl_polynomial_delete(slit_polya) ;
1301 cpl_table_set_array(tw_in, CR2RES_COL_SLIT_CURV_A, i, slit_array) ;
1302 cpl_array_delete(slit_array) ;
1304 cpl_polynomial_delete(slit_polyb) ;
1305 cpl_table_set_array(tw_in, CR2RES_COL_SLIT_CURV_B, i, slit_array) ;
1306 cpl_array_delete(slit_array) ;
1308 cpl_polynomial_delete(slit_polyc) ;
1309 cpl_table_set_array(tw_in, CR2RES_COL_SLIT_CURV_C, i, slit_array) ;
1310 cpl_array_delete(slit_array) ;
1312 cpl_msg_indent_less() ;
1315 cpl_msg_indent_less() ;
1324 if (rawframes_une != NULL) {
1326 cpl_vector * dits_une ;
1327 cpl_vector * ndits_une ;
1328 hdrl_imagelist * in_une ;
1329 hdrl_imagelist * in_une_calib ;
1330 hdrl_image * first_image ;
1331 int zp_order_une, grat1_order_une ;
1333 cpl_msg_info(__func__,
"Reduce %"CPL_SIZE_FORMAT
" UNE Frames",
1334 cpl_frameset_get_size(rawframes_une)) ;
1335 cpl_msg_indent_more() ;
1338 if (master_dark_frame != NULL)
1342 if (cpl_msg_get_level() == CPL_MSG_DEBUG && dits_une != NULL)
1343 cpl_vector_dump(dits_une, stdout) ;
1349 error_factor = gain * cpl_vector_get(ndits_une, 0) *
1350 cpl_frameset_get_size(rawframes_une) ;
1352 for (i=0; i<cpl_vector_get_size(ndits_une); i++){
1353 if (cpl_vector_get(ndits_une,i) != cpl_vector_get(ndits_une, 0))
1354 cpl_msg_warning(__func__,
"UNE raw frames have different NDIT! "
1355 "Error spectrum will likely be scaled incorrectly.");
1360 reduce_det)) == NULL) {
1361 cpl_msg_error(__func__,
"Cannot load images") ;
1362 if (dits_une != NULL) cpl_vector_delete(dits_une) ;
1363 if (tw_in != NULL) cpl_table_delete(tw_in);
1364 cpl_msg_indent_less() ;
1368 cpl_frameset_get_size(rawframes_une)) {
1369 cpl_msg_error(__func__,
"Inconsistent number of loaded images") ;
1370 if (dits_une != NULL) cpl_vector_delete(dits_une) ;
1372 if (tw_in != NULL) cpl_table_delete(tw_in);
1373 cpl_msg_indent_less() ;
1378 subtract_nolight_rows, 1, cosmics, master_flat_frame,
1379 master_dark_frame, bpm_frame, detlin_frame,
1380 dits_une, ndits_une)) == NULL) {
1381 cpl_msg_error(__func__,
"Failed to apply the calibrations") ;
1382 if (dits_une != NULL) cpl_vector_delete(dits_une) ;
1383 if (ndits_une != NULL) cpl_vector_delete(ndits_une) ;
1385 if (tw_in != NULL) cpl_table_delete(tw_in);
1386 cpl_msg_indent_less() ;
1390 if (dits_une != NULL) cpl_vector_delete(dits_une) ;
1391 if (ndits_une != NULL) cpl_vector_delete(ndits_une) ;
1395 if (collapse == CR2RES_COLLAPSE_MEAN) {
1396 cpl_msg_info(__func__,
"Collapse (Mean) the input UNE frames") ;
1397 cpl_msg_indent_more() ;
1400 cpl_msg_indent_less() ;
1401 }
else if (collapse == CR2RES_COLLAPSE_MEDIAN) {
1402 cpl_msg_info(__func__,
"Collapse (Median) the input UNE frames") ;
1403 cpl_msg_indent_more() ;
1406 cpl_msg_indent_less() ;
1409 collapsed_une = NULL ;
1413 if (contrib != NULL) cpl_image_delete(contrib) ;
1414 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1415 cpl_msg_error(__func__,
"Failed Collapse: %d",
1416 cpl_error_get_code());
1417 cpl_msg_indent_less() ;
1418 if (tw_in != NULL) cpl_table_delete(tw_in);
1423 cpl_msg_info(__func__,
"Load the TRACE WAVE") ;
1426 trace_wave_frame), reduce_det)) == NULL) {
1427 cpl_msg_error(__func__,
"Failed to Load the traces file") ;
1429 cpl_msg_indent_less() ;
1434 cpl_msg_info(__func__,
"Spectra Extraction UNE") ;
1435 cpl_msg_indent_more() ;
1437 reduce_order, reduce_trace, CR2RES_EXTR_OPT_CURV,
1438 ext_height, ext_swath_width, ext_oversample,
1439 ext_smooth_slit, ext_smooth_spec,
1440 extract_niter, extract_kappa, error_factor, 0, 0, 0,
1441 &extracted_une, &slit_func_une, &model_master_une) == -1) {
1442 cpl_msg_error(__func__,
"Failed to extract");
1444 cpl_table_delete(tw_in) ;
1445 cpl_msg_indent_less() ;
1446 cpl_msg_indent_less() ;
1449 cpl_msg_indent_less() ;
1450 cpl_table_delete(slit_func_une) ;
1455 first_file = cpl_frame_get_filename(
1456 cpl_frameset_get_position_const(rawframes_une, 0)) ;
1457 plist = cpl_propertylist_load(first_file, 0) ;
1458 zp_order_une = cr2res_pfits_get_order_zp(plist) ;
1459 grat1_order_une = cr2res_pfits_get_order(plist) ;
1460 cpl_propertylist_delete(plist);
1462 cpl_msg_info(__func__,
"Compute the Wavelength for UNE") ;
1463 cpl_msg_indent_more() ;
1465 reduce_trace, wavecal_type, wl_degree, -1,
1467 wl_err, wl_shift, log_flag, fallback_input_wavecal_flag,
1468 keep_higher_degrees_flag, clean_spectrum,
1469 display, display_wmin, display_wmax, zp_order_une,
1472 &lines_diagnostics_une_out,
1474 &tw_une_out) || cpl_error_get_code()) {
1475 cpl_msg_error(__func__,
"Failed to calibrate");
1476 cpl_table_delete(tw_in) ;
1477 cpl_table_delete(extracted_une) ;
1478 cpl_msg_indent_less() ;
1479 cpl_msg_indent_less() ;
1482 cpl_msg_indent_less() ;
1483 cpl_table_delete(extracted_une) ;
1489 first_file = cpl_frame_get_filename(
1490 cpl_frameset_get_position_const(rawframes_une, 0)) ;
1492 plist_une_out = cpl_propertylist_load(first_file, ext_nr) ;
1493 if (plist_une_out == NULL) {
1494 cpl_propertylist_delete(qcs_une_out) ;
1495 cpl_table_delete(tw_in) ;
1496 cpl_table_delete(tw_une_out) ;
1497 cpl_table_delete(lines_diagnostics_une_out) ;
1498 cpl_table_delete(extracted_une_out) ;
1500 cpl_msg_error(__func__,
"Failed to load the plist") ;
1501 cpl_msg_indent_less() ;
1510 nb_traces = cpl_table_get_nrow(tw_in) ;
1511 for (i=0 ; i<nb_traces ; i++) {
1513 order = cpl_table_get(tw_in, CR2RES_COL_ORDER, i, NULL) ;
1514 trace_id = cpl_table_get(tw_in, CR2RES_COL_TRACENB, i, NULL) ;
1517 if (reduce_order > -1 && order != reduce_order) continue ;
1520 if (reduce_trace > -1 && trace_id != reduce_trace) continue ;
1522 double qc_overexposed;
1525 char * qc_name = cpl_sprintf(
"%s%02d",
1526 CR2RES_HEADER_QC_OVEREXPOSED, order) ;
1527 if (qcs_une_out == NULL) qcs_une_out = cpl_propertylist_new() ;
1528 cpl_propertylist_append_double(qcs_une_out, qc_name,qc_overexposed);
1533 if (qcs_une_out != NULL) {
1534 cpl_propertylist_append(plist_une_out, qcs_une_out) ;
1535 cpl_propertylist_delete(qcs_une_out) ;
1537 cpl_msg_indent_less() ;
1540 lines_diagnostics_une_out = NULL ;
1541 extracted_une_out = NULL ;
1542 wl_map_une_out = NULL ;
1543 plist_une_out = NULL ;
1552 if (rawframes_fpet != NULL && reduce_order != -1){
1553 cpl_msg_warning(__func__,
1554 "Etalon wavecal requires all orders to be used, skipping it.");
1555 if (tw_in != NULL) cpl_table_delete(tw_in);
1556 tw_fpet_out = NULL ;
1557 lines_diagnostics_fpet_out = NULL ;
1558 extracted_fpet_out = NULL ;
1559 wl_map_fpet_out = NULL ;
1560 plist_fpet_out = NULL ;
1561 }
else if (rawframes_fpet != NULL) {
1562 cpl_msg_info(__func__,
"Reduce %"CPL_SIZE_FORMAT
" FPET Frames",
1563 cpl_frameset_get_size(rawframes_fpet)) ;
1564 cpl_msg_indent_more() ;
1568 reduce_det)) == NULL) {
1569 cpl_msg_error(__func__,
"Cannot load images") ;
1570 cpl_msg_indent_less() ;
1571 if (plist_une_out != NULL) cpl_propertylist_delete(plist_une_out) ;
1572 if (tw_une_out != NULL) cpl_table_delete(tw_une_out) ;
1573 if (lines_diagnostics_une_out != NULL)
1574 cpl_table_delete(lines_diagnostics_une_out) ;
1575 if (extracted_une_out != NULL) cpl_table_delete(extracted_une_out) ;
1580 cpl_frameset_get_size(rawframes_fpet)) {
1581 cpl_msg_error(__func__,
"Inconsistent number of loaded images") ;
1582 cpl_msg_indent_less() ;
1584 if (plist_une_out != NULL) cpl_propertylist_delete(plist_une_out) ;
1585 if (tw_une_out != NULL) cpl_table_delete(tw_une_out) ;
1586 if (lines_diagnostics_une_out != NULL)
1587 cpl_table_delete(lines_diagnostics_une_out) ;
1588 if (extracted_une_out != NULL) cpl_table_delete(extracted_une_out) ;
1597 error_factor = gain * cpl_vector_get(ndits_fpet, 0) *
1598 cpl_frameset_get_size(rawframes_une) ;
1600 for (i=0; i<cpl_vector_get_size(ndits_fpet); i++){
1601 if (cpl_vector_get(ndits_fpet,i) != cpl_vector_get(ndits_fpet, 0))
1602 cpl_msg_warning(__func__,
"FPET raw frames have different NDIT! "
1603 "Error spectrum will likely be scaled incorrectly.");
1608 subtract_nolight_rows, 0, cosmics, master_flat_frame,
1609 NULL, bpm_frame, detlin_frame, NULL,
1610 ndits_fpet)) == NULL) {
1611 cpl_msg_error(__func__,
"Failed to apply the calibrations") ;
1612 cpl_msg_indent_less() ;
1614 if (plist_une_out != NULL) cpl_propertylist_delete(plist_une_out) ;
1615 if (tw_une_out != NULL) cpl_table_delete(tw_une_out) ;
1616 if (lines_diagnostics_une_out != NULL)
1617 cpl_table_delete(lines_diagnostics_une_out) ;
1618 if (extracted_une_out != NULL) cpl_table_delete(extracted_une_out) ;
1620 if (ndits_fpet != NULL) cpl_vector_delete(ndits_fpet) ;
1624 if (ndits_fpet != NULL) cpl_vector_delete(ndits_fpet) ;
1628 if (collapse == CR2RES_COLLAPSE_MEAN) {
1629 cpl_msg_info(__func__,
"Collapse (Mean) the input FPET frames") ;
1630 cpl_msg_indent_more() ;
1633 cpl_msg_indent_less() ;
1634 }
else if (collapse == CR2RES_COLLAPSE_MEDIAN) {
1635 cpl_msg_info(__func__,
"Collapse (Median) the input FPET frames") ;
1636 cpl_msg_indent_more() ;
1639 cpl_msg_indent_less() ;
1642 collapsed_fpet = NULL ;
1646 if (contrib != NULL) cpl_image_delete(contrib) ;
1647 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1648 cpl_msg_error(__func__,
1649 "Failed Collapse: %d", cpl_error_get_code()) ;
1651 if (plist_une_out != NULL) cpl_propertylist_delete(plist_une_out) ;
1652 if (tw_une_out != NULL) cpl_table_delete(tw_une_out) ;
1653 if (lines_diagnostics_une_out != NULL)
1654 cpl_table_delete(lines_diagnostics_une_out) ;
1655 if (extracted_une_out != NULL) cpl_table_delete(extracted_une_out) ;
1657 cpl_msg_indent_less() ;
1662 if (tw_une_out != NULL) {
1663 cpl_msg_info(__func__,
"Use the UNE output TRACE WAVE") ;
1664 if (tw_in != NULL) cpl_table_delete(tw_in);
1665 tw_in = cpl_table_duplicate(tw_une_out) ;
1667 cpl_msg_info(__func__,
"Load the TRACE WAVE") ;
1670 trace_wave_frame), reduce_det)) == NULL) {
1671 cpl_msg_error(__func__,
"Failed to Load the traces file") ;
1672 if (collapsed_fpet != NULL)
1674 if (plist_une_out != NULL)
1675 cpl_propertylist_delete(plist_une_out) ;
1676 if (tw_une_out != NULL) cpl_table_delete(tw_une_out) ;
1677 if (lines_diagnostics_une_out != NULL)
1678 cpl_table_delete(lines_diagnostics_une_out) ;
1679 if (extracted_une_out != NULL)
1680 cpl_table_delete(extracted_une_out) ;
1681 if (wl_map_une_out != NULL)
1683 cpl_msg_indent_less() ;
1689 cpl_msg_info(__func__,
"Spectra Extraction FPET") ;
1690 cpl_msg_indent_more() ;
1692 reduce_order, reduce_trace, CR2RES_EXTR_OPT_CURV,
1693 ext_height, ext_swath_width, ext_oversample,
1694 ext_smooth_slit, ext_smooth_spec,
1695 extract_niter, extract_kappa, error_factor, 0, 0, 0,
1696 &extracted_fpet, &slit_func_fpet, &model_master_fpet)==-1) {
1697 cpl_msg_error(__func__,
"Failed to extract");
1698 cpl_table_delete(tw_in) ;
1700 if (plist_une_out != NULL) cpl_propertylist_delete(plist_une_out) ;
1701 if (tw_une_out != NULL) cpl_table_delete(tw_une_out) ;
1702 if (lines_diagnostics_une_out != NULL)
1703 cpl_table_delete(lines_diagnostics_une_out) ;
1704 if (extracted_une_out != NULL) cpl_table_delete(extracted_une_out) ;
1706 cpl_msg_indent_less() ;
1707 cpl_msg_indent_less() ;
1710 cpl_msg_indent_less() ;
1711 cpl_table_delete(slit_func_fpet) ;
1716 first_file = cpl_frame_get_filename(
1717 cpl_frameset_get_position_const(rawframes_fpet, 0)) ;
1718 plist = cpl_propertylist_load(first_file, 0) ;
1719 zp_order_fpet = cr2res_pfits_get_order_zp(plist) ;
1720 grat1_order_fpet = cr2res_pfits_get_order(plist) ;
1721 cpl_propertylist_delete(plist);
1723 cpl_msg_info(__func__,
"Compute the Wavelength for FPET") ;
1724 cpl_msg_indent_more() ;
1725 cpl_msg_info(__func__,
"Running FPET with degrees=4,6") ;
1728 reduce_trace, CR2RES_ETALON, 4, 6, wl_start, wl_end,
1729 wl_err, wl_shift, log_flag, fallback_input_wavecal_flag,
1732 display, display_wmin, display_wmax, zp_order_fpet,
1735 &lines_diagnostics_fpet_out,
1736 &extracted_fpet_out,
1737 &tw_fpet_out) || cpl_error_get_code()) {
1738 cpl_msg_error(__func__,
"Failed to calibrate");
1739 cpl_table_delete(extracted_fpet) ;
1740 cpl_table_delete(tw_in) ;
1741 if (plist_une_out != NULL) cpl_propertylist_delete(plist_une_out) ;
1742 if (tw_une_out != NULL) cpl_table_delete(tw_une_out) ;
1743 if (lines_diagnostics_une_out != NULL)
1744 cpl_table_delete(lines_diagnostics_une_out) ;
1745 if (extracted_une_out != NULL) cpl_table_delete(extracted_une_out) ;
1747 cpl_msg_indent_less() ;
1748 cpl_msg_indent_less() ;
1751 cpl_msg_indent_less() ;
1752 cpl_table_delete(tw_in) ;
1753 cpl_table_delete(extracted_fpet) ;
1759 first_file = cpl_frame_get_filename(
1760 cpl_frameset_get_position_const(rawframes_fpet, 0)) ;
1762 plist_fpet_out = cpl_propertylist_load(first_file, ext_nr) ;
1763 if (plist_fpet_out == NULL) {
1764 cpl_propertylist_delete(qcs_fpet_out) ;
1765 cpl_table_delete(tw_fpet_out) ;
1766 cpl_table_delete(lines_diagnostics_fpet_out) ;
1767 cpl_table_delete(extracted_fpet_out) ;
1769 if (plist_une_out != NULL) cpl_propertylist_delete(plist_une_out) ;
1770 if (tw_une_out != NULL) cpl_table_delete(tw_une_out) ;
1771 if (lines_diagnostics_une_out != NULL)
1772 cpl_table_delete(lines_diagnostics_une_out) ;
1773 if (extracted_une_out != NULL) cpl_table_delete(extracted_une_out) ;
1775 cpl_msg_indent_less() ;
1776 cpl_msg_error(__func__,
"Failed to load the plist") ;
1779 if (qcs_fpet_out != NULL) {
1780 cpl_propertylist_append(plist_fpet_out, qcs_fpet_out) ;
1781 cpl_propertylist_delete(qcs_fpet_out) ;
1783 cpl_msg_indent_less() ;
1785 if (tw_in != NULL) cpl_table_delete(tw_in);
1786 tw_fpet_out = NULL ;
1787 lines_diagnostics_fpet_out = NULL ;
1788 extracted_fpet_out = NULL ;
1789 wl_map_fpet_out = NULL ;
1790 plist_fpet_out = NULL ;
1794 *out_trace_wave_une = tw_une_out ;
1795 *lines_diagnostics_une = lines_diagnostics_une_out ;
1796 *out_extracted_une = extracted_une_out ;
1797 *out_wave_map_une = wl_map_une_out ;
1798 *ext_plist_une = plist_une_out ;
1800 *out_trace_wave_fpet = tw_fpet_out ;
1801 *lines_diagnostics_fpet = lines_diagnostics_fpet_out ;
1802 *out_extracted_fpet = extracted_fpet_out ;
1803 *out_wave_map_fpet = wl_map_fpet_out ;
1804 *ext_plist_fpet = plist_fpet_out ;
1825static int cr2res_cal_wave_qc_une_flux(
1826 const cpl_table ** extracted,
1827 const cpl_propertylist ** ext_plist,
1829 cpl_propertylist * plist)
1831 const cpl_table * ref_extr ;
1832 const cpl_propertylist * ref_plist ;
1833 cpl_bivector * spec ;
1834 cpl_bivector * spec_err ;
1835 cpl_bivector * intensities ;
1837 double qc_flux, min_intens, max_intens;
1838 int ref_det, corder_idx ;
1842 if (extracted==NULL || ext_plist == NULL)
return -1 ;
1843 for (k=0 ; k< CR2RES_NB_DETECTORS ; k++) {
1844 if (extracted[k] == NULL)
return -1 ;
1845 if (ext_plist[k] == NULL)
return -1 ;
1850 min_intens = 1000.0 ;
1851 max_intens = 37000.0 ;
1854 if (cwlen <= 1100.0) ref_det = 0 ;
1856 ref_extr = extracted[ref_det] ;
1858 ref_plist = ext_plist[ref_det] ;
1862 CR2RES_DETECTOR_SIZE/2.0) ;
1864 cpl_msg_debug(__func__,
"Central wl: %g / Cent. Order IDX: %d",
1865 cwlen, corder_idx) ;
1870 cpl_bivector_delete(spec_err) ;
1873 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1874 cpl_errorstate status;
1875 status = cpl_errorstate_get();
1877 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Intensity';",
1878 "t 'UNE Spectrum' w lines",
"",
1881 cpl_errorstate_set(status);
1886 cpl_msg_warning(__func__,
"Cannot get the lines statistics") ;
1889 cpl_size nintensities, nval;
1891 nintensities = cpl_bivector_get_size(intensities) ;
1892 pintens = cpl_bivector_get_x_data(intensities) ;
1893 pbgs = cpl_bivector_get_y_data(intensities) ;
1896 for (k=0 ; k<nintensities ; k++) {
1898 val = pintens[k] - pbgs[k] ;
1899 if (val < max_intens && val > min_intens) {
1904 if (nval > 0) qc_flux /= nval ;
1905 cpl_bivector_delete(intensities) ;
1907 cpl_bivector_delete(spec) ;
1910 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_UNE_FLUX,
1939static int cr2res_cal_wave_qc_fpi(
1940 const cpl_table ** extracted,
1941 const cpl_table ** tw,
1942 const cpl_propertylist ** ext_plist,
1944 cpl_propertylist * plist)
1946 const cpl_table * ref_extr ;
1947 const cpl_table * ref_tw ;
1948 const cpl_propertylist * ref_plist ;
1949 double qc_contrast, qc_flux, qc_separation;
1950 int corder_idx, ref_det, first_fringe_idx,
1951 last_fringe_idx, nb_fringes_between ;
1952 cpl_bivector * spec ;
1953 cpl_bivector * spec_err ;
1954 cpl_vector * xpeaks ;
1955 cpl_vector * lpeaks ;
1956 cpl_vector * fpeaks ;
1957 cpl_vector * xmins ;
1958 cpl_vector * fmins ;
1959 cpl_vector * lmins ;
1960 cpl_vector * tmp_vec ;
1961 cpl_vector * flux_vec ;
1962 cpl_polynomial * wlpoly ;
1963 cpl_size k, npeaks, end_val_search;
1968 if (extracted==NULL || ext_plist == NULL)
return -1 ;
1969 for (k=0 ; k< CR2RES_NB_DETECTORS ; k++) {
1970 if (extracted[k] == NULL)
return -1 ;
1971 if (ext_plist[k] == NULL)
return -1 ;
1975 if (cwlen <= 1100.0) ref_det = 0 ;
1977 ref_extr = extracted[ref_det] ;
1978 ref_tw = tw[ref_det] ;
1979 ref_plist = ext_plist[ref_det] ;
1983 CR2RES_DETECTOR_SIZE/2.0) ;
1985 cpl_msg_debug(__func__,
"Central wl: %g / Cent. Order IDX: %d",
1986 cwlen, corder_idx) ;
1991 cpl_bivector_delete(spec_err) ;
1994 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1995 cpl_errorstate status;
1997 status = cpl_errorstate_get();
1999 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Intensity';",
2000 "t 'FPI Spectrum' w lines",
"",
2003 cpl_errorstate_set(status);
2007 if ((xpeaks=cr2res_wave_etalon_measure_fringes(cpl_bivector_get_y(spec)))
2009 cpl_msg_warning(__func__,
"Cannot identify the peaks") ;
2010 cpl_bivector_delete(spec) ;
2013 npeaks = cpl_vector_get_size(xpeaks) ;
2015 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
2016 cpl_vector_dump(xpeaks, stdout) ;
2022 if (wlpoly == NULL) {
2023 cpl_msg_warning(__func__,
"Cannot get the wavelength") ;
2024 cpl_bivector_delete(spec) ;
2025 cpl_vector_delete(xpeaks) ;
2033 xmins = cpl_vector_new(npeaks) ;
2034 fpeaks = cpl_vector_new(npeaks);
2035 fmins = cpl_vector_new(npeaks);
2036 for (k=0 ; k<npeaks ; k++) {
2037 cpl_size start_val_search, xminpos;
2040 start_val_search = (int)cpl_vector_get(xpeaks, k) ;
2041 if (k == npeaks-1) {
2042 end_val_search = start_val_search ;
2044 end_val_search = (int)cpl_vector_get(xpeaks, k+1) ;
2046 tmp_vec = cpl_vector_extract(cpl_bivector_get_y(spec),
2047 start_val_search-1, end_val_search-1, 1) ;
2048 xminpos = cpl_vector_get_minpos(tmp_vec) ;
2049 cpl_vector_set(fpeaks,k,cpl_vector_get(tmp_vec,0));
2050 cpl_vector_set(fmins,k,cpl_vector_get(tmp_vec,xminpos));
2051 cpl_vector_delete(tmp_vec) ;
2053 cpl_vector_set(xmins, k, start_val_search + xminpos) ;
2058 cpl_polynomial_delete(wlpoly) ;
2060 for (k=0 ; k<npeaks ; k++) {
2061 cpl_msg_debug(__func__,
2062 "Peak #%"CPL_SIZE_FORMAT
" Pos: %g / WL: %g / Val :%g",
2064 cpl_vector_get(xpeaks, k),
2065 cpl_vector_get(lpeaks, k),
2066 cpl_vector_get(cpl_bivector_get_y(spec),
2067 (
int)cpl_vector_get(xpeaks, k))) ;
2068 cpl_msg_debug(__func__,
2069 " Min Pos: %g / WL: %g / Val :%g",
2070 cpl_vector_get(xmins, k),
2071 cpl_vector_get(lmins, k),
2072 cpl_vector_get(cpl_bivector_get_y(spec),
2073 (
int)cpl_vector_get(xmins, k))) ;
2075 cpl_bivector_delete(spec) ;
2076 cpl_vector_delete(xpeaks) ;
2077 cpl_vector_delete(xmins) ;
2081 tmp_vec = cpl_vector_new(npeaks-2) ;
2082 flux_vec = cpl_vector_new(npeaks-2) ;
2083 for (k=1 ; k<npeaks-1 ; k++) {
2084 double fpeak, fmin, contrast_val ;
2085 fpeak = cpl_vector_get(fpeaks, k) ;
2086 fmin = cpl_vector_get(fmins, k) ;
2087 contrast_val = (fpeak-fmin) / (fmin+fpeak) ;
2088 cpl_vector_set(tmp_vec, k-1, contrast_val) ;
2089 cpl_vector_set(flux_vec, k-1, fpeak) ;
2091 qc_contrast = cpl_vector_get_mean(tmp_vec) ;
2092 qc_flux = cpl_vector_get_mean(flux_vec) ;
2093 cpl_vector_delete(tmp_vec) ;
2094 cpl_vector_delete(flux_vec) ;
2095 cpl_vector_delete(lmins) ;
2098 first_fringe_idx = 1 ;
2099 last_fringe_idx = npeaks-2 ;
2100 nb_fringes_between = last_fringe_idx - first_fringe_idx + 1 - 2 ;
2102 qc_separation = (cpl_vector_get(lpeaks, last_fringe_idx) -
2103 cpl_vector_get(lpeaks, first_fringe_idx)) /
2104 nb_fringes_between ;
2106 cpl_vector_delete(lpeaks) ;
2107 cpl_vector_delete(fpeaks) ;
2108 cpl_vector_delete(fmins) ;
2111 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_FPI_CONTRAST,
2113 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_FPI_FLUX,
2115 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_FPI_SEPARATION,
2139static int cr2res_cal_wave_qc_tilt(
2140 const cpl_table ** tws,
2142 cpl_propertylist * plist)
2144 const cpl_table * ref_tw ;
2150 if (tws==NULL)
return -1 ;
2151 for (k=0 ; k< CR2RES_NB_DETECTORS ; k++)
2152 if (tws[k] == NULL)
return -1 ;
2160 if (cwlen <= 1100.0) ref_tw = tws[0] ;
2161 else ref_tw = tws[1] ;
2163 nrows = cpl_table_get_nrow(ref_tw) ;
2166 for (k=0 ; k<nrows ; k++) {
2168 const cpl_array * tmp_array ;
2169 cpl_polynomial * slit_poly_a ;
2170 cpl_polynomial * slit_poly_b ;
2171 cpl_polynomial * slit_poly_c ;
2172 cpl_polynomial * upper_poly ;
2173 cpl_polynomial * lower_poly ;
2174 cpl_polynomial * slit_curv_poly ;
2176 double top_x, top_y, bot_x, bot_y;
2180 cur_order = cpl_table_get(ref_tw, CR2RES_COL_ORDER, k, NULL) ;
2183 tmp_array = cpl_table_get_array(ref_tw, CR2RES_COL_SLIT_CURV_A, k) ;
2185 tmp_array = cpl_table_get_array(ref_tw, CR2RES_COL_SLIT_CURV_B, k) ;
2187 tmp_array = cpl_table_get_array(ref_tw, CR2RES_COL_SLIT_CURV_C, k) ;
2191 tmp_array = cpl_table_get_array(ref_tw, CR2RES_COL_UPPER, k) ;
2195 tmp_array = cpl_table_get_array(ref_tw, CR2RES_COL_LOWER, k) ;
2200 slit_poly_b, slit_poly_c, ref_x) ;
2201 cpl_polynomial_delete(slit_poly_a) ;
2202 cpl_polynomial_delete(slit_poly_b) ;
2203 cpl_polynomial_delete(slit_poly_c) ;
2205 top_y = cpl_polynomial_eval_1d(upper_poly, ref_x, NULL) ;
2206 bot_y = cpl_polynomial_eval_1d(lower_poly, ref_x, NULL) ;
2207 cpl_polynomial_delete(upper_poly) ;
2208 cpl_polynomial_delete(lower_poly) ;
2210 top_x = cpl_polynomial_eval_1d(slit_curv_poly, top_y, NULL) ;
2211 bot_x = cpl_polynomial_eval_1d(slit_curv_poly, bot_y, NULL) ;
2212 cpl_polynomial_delete(slit_curv_poly) ;
2215 tilt = atan((top_x-bot_x)/(top_y-bot_y))*180.0/CRIRES_PI;
2216 cpl_msg_debug(__func__,
2217 "TILT : %g / Upper (x,y)=(%g,%g) Lower (x,y)=(%g,%g)",
2218 tilt, top_x, top_y, bot_x, bot_y) ;
2221 qc_name = cpl_sprintf(CR2RES_HEADER_QC_TILT, cur_order) ;
2222 cpl_propertylist_append_double(plist, qc_name, tilt) ;
2232 cpl_msg_debug(__func__,
"TILT GLOBAL: %g", tilt_avg/ntilt) ;
2233 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_TILT_GLOBAL,
hdrl_imagelist * cr2res_calib_imagelist(const hdrl_imagelist *in, int chip, int clean_bad, int subtract_nolight_rows, int subtract_interorder_column, int cosmics_corr, const cpl_frame *flat, const cpl_frame *dark, const cpl_frame *bpm, const cpl_frame *detlin, const cpl_vector *dits, const cpl_vector *ndits)
The images calibration routine for a given chip on a list.
cpl_error_code cr2res_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
cpl_table * cr2res_io_load_EXTRACT_1D(const char *filename, int detector)
Load a table from a EXTRACT_1D.
const cpl_frame * cr2res_io_find_BPM(const cpl_frameset *in)
Get the first CR2RES_BPM_DRSTYPE frame from a frameset.
const cpl_frame * cr2res_io_find_TRACE_WAVE(const cpl_frameset *in)
Get the first CR2RES_TW_DRSTYPE frame from a frameset.
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.
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.
cpl_vector * cr2res_io_read_dits(const cpl_frameset *in)
Get the DITS from a frame set.
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.
hdrl_imagelist * cr2res_io_load_image_list_from_set(const cpl_frameset *in, int detector)
Load an hdrl image list from an images frameset.
int cr2res_io_get_ext_idx(const char *filename, int detector, int data)
Get the wished extension number for a detector.
hdrl_image * cr2res_io_load_image(const char *in, int detector)
Load an hdrl image from a image file.
cpl_table * cr2res_io_load_TRACE_WAVE(const char *filename, int detector)
Load a table from a TRACE_WAVE.
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.
cpl_vector * cr2res_io_read_ndits(const cpl_frameset *in)
Get the NDITs from a frame set.
int cr2res_pfits_get_order_idx(const cpl_propertylist *plist, double yposition)
find out the order_idx closest to the passed y position
double cr2res_pfits_get_cwlen(const cpl_propertylist *plist)
find out the CWLEN value
double cr2res_qc_overexposed(const cpl_image *ima, const cpl_table *tw, int order_idx)
Computes the Overexposed fraction.
cpl_bivector * cr2res_qc_lines_intens_bgd(const cpl_bivector *spec)
Computes the lines intensities / background.
int cr2res_slit_curv_compute_order_trace(const hdrl_image *img, const cpl_table *trace_wave, const int order, const int trace, const int height, const int window, const cpl_size change_degree, const int slit_degree, cpl_polynomial **slit_poly_a, cpl_polynomial **slit_poly_b, cpl_polynomial **slit_poly_c)
Get the slit curvature directly from the image.
cpl_polynomial * cr2res_slit_curv_build_poly(cpl_polynomial *slit_poly_a, cpl_polynomial *slit_poly_b, cpl_polynomial *slit_poly_c, cpl_size x)
Create the slit curvature polynomial for x position.
cpl_polynomial * cr2res_get_trace_wave_poly(const cpl_table *trace_wave, const char *poly_column, int order_idx, int trace_nb)
Get a polynomial from a TRACE_WAVE table.
cpl_polynomial * cr2res_convert_array_to_poly(const cpl_array *arr)
Convert an array to polynomial.
cpl_vector * cr2res_polynomial_eval_vector(const cpl_polynomial *poly, const cpl_vector *vec)
Evaluate a polynomial on a vector.
cpl_array * cr2res_convert_poly_to_array(const cpl_polynomial *poly, int size)
Convert a polynomial to array.
cpl_frameset * cr2res_extract_frameset(const cpl_frameset *in, const char *tag)
Extract the frames with the given tag from a frameset.
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.
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.
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
cpl_error_code hdrl_imagelist_collapse_mean(const hdrl_imagelist *himlist, hdrl_image **out, cpl_image **contrib)
Mean collapsing of image list.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
cpl_error_code hdrl_imagelist_collapse_median(const hdrl_imagelist *himlist, hdrl_image **out, cpl_image **contrib)
Median collapsing of image list.