30#include "cr2res_utils.h"
31#include "cr2res_idp.h"
32#include "cr2res_calib.h"
33#include "cr2res_pfits.h"
34#include "cr2res_dfs.h"
35#include "cr2res_bpm.h"
36#include "cr2res_trace.h"
37#include "cr2res_extract.h"
45#define RECIPE_STRING "cr2res_obs_staring"
51int cpl_plugin_get_info(cpl_pluginlist * list);
57static cpl_frameset * cr2res_obs_staring_find_RAW(
58 const cpl_frameset * in) ;
59static int cr2res_obs_staring_check_inputs_validity(
60 const cpl_frameset * rawframes) ;
61static int cr2res_obs_staring_reduce(
62 const cpl_frameset * rawframes,
63 const cpl_frame * trace_wave_frame,
64 const cpl_frame * detlin_frame,
65 const cpl_frame * master_dark_frame,
66 const cpl_frame * master_flat_frame,
67 const cpl_frame * bpm_frame,
68 const cpl_frame * blaze_frame,
69 const cpl_array * slit_frac,
70 int subtract_nolight_rows,
71 int subtract_interorder_column,
73 int extract_oversample,
74 int extract_swath_width,
76 double extract_smooth_slit,
77 double extract_smooth_spec,
79 hdrl_image ** combined,
81 cpl_table ** slitfunc,
83 cpl_propertylist ** ext_plist) ;
84static int cr2res_obs_staring_create(cpl_plugin *);
85static int cr2res_obs_staring_exec(cpl_plugin *);
86static int cr2res_obs_staring_destroy(cpl_plugin *);
87static int cr2res_obs_staring(cpl_frameset *,
const cpl_parameterlist *);
93static char cr2res_obs_staring_description[] =
"\
94Staring Observation \n\
95 This recipe handles staring observations. \n\
98 raw.fits " CR2RES_OBS_STARING_OTHER_RAW
" [1 to n] \n\
99 or " CR2RES_OBS_STARING_JITTER_RAW
" [1 to n] \n\
100 or " CR2RES_OBS_STARING_WAVE_SKY_RAW
" [1 to n] \n\
101 trace.fits " CR2RES_CAL_FLAT_TW_PROCATG
" [1] \n\
102 or " CR2RES_CAL_FLAT_TW_MERGED_PROCATG
" \n\
103 or " CR2RES_UTIL_TRACE_TW_PROCATG
" \n\
104 or " CR2RES_UTIL_WAVE_TW_PROCATG
" \n\
105 or " CR2RES_CAL_WAVE_TW_PROCATG
" \n\
106 or " CR2RES_UTIL_SLIT_CURV_TW_PROCATG
" \n\
107 detlin.fits " CR2RES_CAL_DETLIN_COEFFS_PROCATG
" [0 to 1] \n\
108 bpm.fits " CR2RES_CAL_DARK_BPM_PROCATG
" [0 to 1] \n\
109 or " CR2RES_CAL_FLAT_BPM_PROCATG
" \n\
110 or " CR2RES_CAL_DETLIN_BPM_PROCATG
" \n\
111 or " CR2RES_UTIL_BPM_MERGE_PROCATG
" \n\
112 or " CR2RES_UTIL_BPM_SPLIT_PROCATG
" \n\
113 master_dark.fits " CR2RES_CAL_DARK_MASTER_PROCATG
" [0 to 1] \n\
114 master_flat.fits " CR2RES_CAL_FLAT_MASTER_PROCATG
" [0 to 1] \n\
115 blaze.fits " CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG
" [0 to 1] \n\
118 cr2res_obs_staring_slitfunc.fits "
119 CR2RES_OBS_STARING_SLITFUNC_PROCATG
"\n\
120 cr2res_obs_staring_model.fits "
121 CR2RES_OBS_STARING_SLITMODEL_PROCATG
"\n\
122 cr2res_obs_staring_extracted.fits "
123 CR2RES_OBS_STARING_EXTRACT_PROCATG
"\n\
126 loop on detectors d: \n\
127 call cr2res_obs_staring_reduce() \n\
136 cr2res_obs_staring_reduce() \n\
137 Load the input raw frames in an image list \n\
138 Apply the calibrations to the image list \n\
139 Collapse the image list \n\
140 Load the input trace wave \n\
141 Recompute a new trace wave with the specified slit fraction \n\
142 (--slit_frac) if needed \n\
143 Extract the spectra from the collapsed image \n\
148 Compute QC parameters \n\
150 Library functions used \n\
151 cr2res_io_find_TRACE_WAVE() \n\
152 cr2res_io_find_BPM() \n\
153 cr2res_obs_staring_reduce() \n\
154 cr2res_io_read_dits() \n\
155 cr2res_io_load_image_list_from_set() \n\
156 cr2res_calib_imagelist() \n\
157 cr2res_io_load_TRACE_WAVE() \n\
158 cr2res_extract_traces() \n\
159 cr2res_io_save_COMBINED() \n\
160 cr2res_io_save_EXTRACT_1D() \n\
161 cr2res_io_save_SLIT_FUNC() \n\
179int cpl_plugin_get_info(cpl_pluginlist * list)
181 cpl_recipe * recipe = cpl_calloc(1,
sizeof *recipe );
182 cpl_plugin * plugin = &recipe->interface;
184 if (cpl_plugin_init(plugin,
186 CR2RES_BINARY_VERSION,
187 CPL_PLUGIN_TYPE_RECIPE,
189 "Staring Observation recipe",
190 cr2res_obs_staring_description,
191 CR2RES_PIPELINE_AUTHORS,
194 cr2res_obs_staring_create,
195 cr2res_obs_staring_exec,
196 cr2res_obs_staring_destroy)) {
197 cpl_msg_error(cpl_func,
"Plugin initialization failed");
198 (void)cpl_error_set_where(cpl_func);
202 if (cpl_pluginlist_append(list, plugin)) {
203 cpl_msg_error(cpl_func,
"Error adding plugin to list");
204 (void)cpl_error_set_where(cpl_func);
220static int cr2res_obs_staring_create(cpl_plugin * plugin)
222 cpl_recipe * recipe ;
226 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
227 recipe = (cpl_recipe *)plugin;
232 recipe->parameters = cpl_parameterlist_new();
236 p = cpl_parameter_new_value(
237 "cr2res.cr2res_obs_staring.subtract_nolight_rows",
239 "Subtract median row from baffled region at detector bottom",
240 "cr2res.cr2res_obs_staring", FALSE);
241 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"subtract_nolight_rows");
242 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
243 cpl_parameterlist_append(recipe->parameters, p);
245 p = cpl_parameter_new_value(
246 "cr2res.cr2res_obs_staring.subtract_interorder_column",
248 "Subtract column-by-column fit to the pixel values between"
250 "cr2res.cr2res_obs_staring", TRUE);
251 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
252 "subtract_interorder_column");
253 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
254 cpl_parameterlist_append(recipe->parameters, p);
256 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_staring.cosmics",
257 CPL_TYPE_BOOL,
"Find and mark cosmic rays hits as bad",
258 "cr2res.cr2res_obs_staring", FALSE);
259 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"cosmics");
260 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
261 cpl_parameterlist_append(recipe->parameters, p);
263 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_staring.slit_frac",
264 CPL_TYPE_STRING,
"Wished slit fraction",
265 "cr2res.cr2res_obs_staring",
"-1.0, -1.0");
266 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"slit_frac");
267 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
268 cpl_parameterlist_append(recipe->parameters, p);
270 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_staring.extract_oversample",
271 CPL_TYPE_INT,
"factor by which to oversample the extraction",
272 "cr2res.cr2res_obs_staring", 5);
273 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_oversample");
274 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
275 cpl_parameterlist_append(recipe->parameters, p);
277 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_staring.extract_swath_width",
278 CPL_TYPE_INT,
"The swath width",
"cr2res.cr2res_obs_staring", 2048);
279 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_swath_width");
280 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
281 cpl_parameterlist_append(recipe->parameters, p);
283 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_staring.extract_height",
284 CPL_TYPE_INT,
"Extraction height",
285 "cr2res.cr2res_obs_staring", -1);
286 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_height");
287 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
288 cpl_parameterlist_append(recipe->parameters, p);
290 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_staring.extract_smooth_slit",
292 "Smoothing along the slit (1 for high S/N, 5 for low)",
293 "cr2res.cr2res_obs_staring", 2.0);
294 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_smooth_slit");
295 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
296 cpl_parameterlist_append(recipe->parameters, p);
298 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_staring.extract_smooth_spec",
299 CPL_TYPE_DOUBLE,
"Smoothing along the spectrum",
300 "cr2res.cr2res_obs_staring", 0.0);
301 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extract_smooth_spec");
302 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
303 cpl_parameterlist_append(recipe->parameters, p);
305 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_staring.detector",
306 CPL_TYPE_INT,
"Only reduce the specified detector",
307 "cr2res.cr2res_obs_staring", 0);
308 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"detector");
309 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
310 cpl_parameterlist_append(recipe->parameters, p);
312 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_staring.create_idp",
313 CPL_TYPE_BOOL,
"Flag to produce IDP files",
314 "cr2res.cr2res_obs_staring", FALSE);
315 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"idp");
316 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
317 cpl_parameterlist_append(recipe->parameters, p);
319 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_staring.display_order",
320 CPL_TYPE_INT,
"Apply the display for the specified order",
321 "cr2res.cr2res_obs_staring", 0);
322 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"display_order");
323 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
324 cpl_parameterlist_append(recipe->parameters, p);
326 p = cpl_parameter_new_value(
"cr2res.cr2res_obs_staring.display_trace",
327 CPL_TYPE_INT,
"Apply the display for the specified trace",
328 "cr2res.cr2res_obs_staring", 0);
329 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"display_trace");
330 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
331 cpl_parameterlist_append(recipe->parameters, p);
343static int cr2res_obs_staring_exec(cpl_plugin * plugin)
348 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
349 recipe = (cpl_recipe *)plugin;
352 return cr2res_obs_staring(recipe->frames, recipe->parameters);
362static int cr2res_obs_staring_destroy(cpl_plugin * plugin)
367 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
368 recipe = (cpl_recipe *)plugin;
371 cpl_parameterlist_delete(recipe->parameters);
383static int cr2res_obs_staring(
384 cpl_frameset * frameset,
385 const cpl_parameterlist * parlist)
387 const cpl_parameter * param ;
388 int subtract_nolight_rows, subtract_interorder_column,
389 extract_oversample, create_idp, cosmics,
390 extract_swath_width, extract_height, reduce_det;
391 double extract_smooth_slit, extract_smooth_spec,
394 cpl_array * slit_frac ;
395 cpl_frameset * rawframes ;
396 const cpl_frame * trace_wave_frame ;
397 const cpl_frame * detlin_frame ;
398 const cpl_frame * master_dark_frame ;
399 const cpl_frame * master_flat_frame ;
400 const cpl_frame * bpm_frame ;
401 const cpl_frame * blaze_frame ;
403 hdrl_image * combined[CR2RES_NB_DETECTORS] ;
404 cpl_table * extract[CR2RES_NB_DETECTORS] ;
405 cpl_table * slitfunc[CR2RES_NB_DETECTORS] ;
406 hdrl_image * model[CR2RES_NB_DETECTORS] ;
407 cpl_propertylist * qc_main ;
408 cpl_propertylist * ext_plist[CR2RES_NB_DETECTORS] ;
410 cpl_table * eop_table ;
414 param = cpl_parameterlist_find_const(parlist,
415 "cr2res.cr2res_obs_staring.subtract_nolight_rows");
416 subtract_nolight_rows = cpl_parameter_get_bool(param);
417 param = cpl_parameterlist_find_const(parlist,
418 "cr2res.cr2res_obs_staring.subtract_interorder_column");
419 subtract_interorder_column = cpl_parameter_get_bool(param);
420 param = cpl_parameterlist_find_const(parlist,
421 "cr2res.cr2res_obs_staring.cosmics");
422 cosmics = cpl_parameter_get_bool(param);
423 param = cpl_parameterlist_find_const(parlist,
424 "cr2res.cr2res_obs_staring.extract_oversample");
425 extract_oversample = cpl_parameter_get_int(param);
426 param = cpl_parameterlist_find_const(parlist,
427 "cr2res.cr2res_obs_staring.extract_swath_width");
428 extract_swath_width = cpl_parameter_get_int(param);
429 param = cpl_parameterlist_find_const(parlist,
430 "cr2res.cr2res_obs_staring.extract_height");
431 extract_height = cpl_parameter_get_int(param);
432 param = cpl_parameterlist_find_const(parlist,
433 "cr2res.cr2res_obs_staring.extract_smooth_slit");
434 extract_smooth_slit = cpl_parameter_get_double(param);
435 param = cpl_parameterlist_find_const(parlist,
436 "cr2res.cr2res_obs_staring.extract_smooth_spec");
437 extract_smooth_spec = cpl_parameter_get_double(param);
438 param = cpl_parameterlist_find_const(parlist,
439 "cr2res.cr2res_obs_staring.detector");
440 reduce_det = cpl_parameter_get_int(param);
441 param = cpl_parameterlist_find_const(parlist,
442 "cr2res.cr2res_obs_staring.create_idp");
443 create_idp = cpl_parameter_get_bool(param);
450 param = cpl_parameterlist_find_const(parlist,
451 "cr2res.cr2res_obs_staring.slit_frac");
452 sval = cpl_parameter_get_string(param) ;
453 if (sscanf(sval,
"%lg,%lg", &slit_low, &slit_up) != 2) {
454 cpl_msg_error(__func__,
"Invalid Slit Fraction specified");
455 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
460 if (slit_low >= 0.0 && slit_up >= 0.0 && slit_low <= 1.0 && slit_up <= 1.0
461 && slit_up > slit_low) {
462 slit_frac = cpl_array_new(3, CPL_TYPE_DOUBLE) ;
463 cpl_array_set(slit_frac, 0, slit_low) ;
464 cpl_array_set(slit_frac, 1, (slit_low+slit_up)/2.0) ;
465 cpl_array_set(slit_frac, 2, slit_up) ;
472 if (slit_frac != NULL) cpl_array_delete(slit_frac) ;
473 cpl_msg_error(__func__,
"Cannot identify RAW and CALIB frames") ;
474 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
480 if (trace_wave_frame == NULL) {
481 if (slit_frac != NULL) cpl_array_delete(slit_frac) ;
482 cpl_msg_error(__func__,
"Could not find TRACE_WAVE frame") ;
485 detlin_frame = cpl_frameset_find_const(frameset,
486 CR2RES_CAL_DETLIN_COEFFS_PROCATG);
487 master_dark_frame = cpl_frameset_find_const(frameset,
488 CR2RES_CAL_DARK_MASTER_PROCATG) ;
489 master_flat_frame = cpl_frameset_find_const(frameset,
490 CR2RES_CAL_FLAT_MASTER_PROCATG) ;
492 blaze_frame = cpl_frameset_find_const(frameset,
493 CR2RES_CAL_FLAT_EXTRACT_1D_PROCATG) ;
496 rawframes = cr2res_obs_staring_find_RAW(frameset) ;
497 if (rawframes == NULL) {
498 if (slit_frac != NULL) cpl_array_delete(slit_frac) ;
499 cpl_msg_error(__func__,
"Could not find RAW frames") ;
504 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
506 combined[det_nr-1] = NULL ;
507 extract[det_nr-1] = NULL ;
508 slitfunc[det_nr-1] = NULL ;
509 model[det_nr-1] = NULL ;
510 ext_plist[det_nr-1] = NULL ;
513 if (reduce_det != 0 && det_nr != reduce_det) continue ;
515 cpl_msg_info(__func__,
"Process Detector %d", det_nr) ;
516 cpl_msg_indent_more() ;
519 if (cr2res_obs_staring_reduce(rawframes,
520 trace_wave_frame, detlin_frame, master_dark_frame,
521 master_flat_frame, bpm_frame, blaze_frame, slit_frac,
522 subtract_nolight_rows, subtract_interorder_column,
523 cosmics, extract_oversample,
524 extract_swath_width, extract_height, extract_smooth_slit,
525 extract_smooth_spec, det_nr,
526 &(combined[det_nr-1]),
527 &(extract[det_nr-1]),
528 &(slitfunc[det_nr-1]),
530 &(ext_plist[det_nr-1])) == -1) {
531 cpl_msg_warning(__func__,
"Failed to reduce detector %d", det_nr);
533 cpl_msg_indent_less() ;
535 cpl_msg_indent_less() ;
537 if (slit_frac != NULL) cpl_array_delete(slit_frac) ;
542 qc_main = cpl_propertylist_new();
543 cpl_propertylist_append_double(qc_main,
544 CR2RES_HEADER_DRS_TMID,
549 if (eop_table != NULL) {
550 double ra, dec, mjd_obs, geolon, geolat, geoelev;
551 cpl_propertylist *plist;
552 plist=cpl_propertylist_load(cpl_frame_get_filename(
553 cpl_frameset_get_position_const(rawframes, 0)), 0) ;
555 ra = cpl_propertylist_get_double(plist,
"RA") ;
556 dec = cpl_propertylist_get_double(plist,
"DEC") ;
557 mjd_obs = cpl_propertylist_get_double(plist,
"MJD-OBS") ;
558 geolon = cpl_propertylist_get_double(plist,
"ESO TEL GEOLON") ;
559 geolat = cpl_propertylist_get_double(plist,
"ESO TEL GEOLAT") ;
560 geoelev = cpl_propertylist_get_double(plist,
"ESO TEL GEOELEV") ;
562 cpl_propertylist_delete(plist) ;
565 if (!cpl_error_get_code()) {
569 (mjd_cen-mjd_obs)*24*3600, geolon, geolat, geoelev,
570 0.0, 0.0, 0.0, 0.0, &barycorr);
572 cpl_msg_info(__func__,
"Barycentric correction: %g m/s",
576 cpl_msg_info(__func__,
"Cannot derive Barycentric correction");
579 cpl_table_delete(eop_table) ;
580 cpl_propertylist_append_double(qc_main, CR2RES_HEADER_DRS_BARYCORR,
585 cpl_propertylist_append_int(qc_main,
586 CR2RES_HEADER_QC_NUMSAT,
590 if (trace_wave_frame != NULL)
591 cpl_frameset_insert(rawframes,
592 cpl_frame_duplicate(trace_wave_frame)) ;
593 if (detlin_frame != NULL)
594 cpl_frameset_insert(rawframes,
595 cpl_frame_duplicate(detlin_frame)) ;
596 if (master_dark_frame != NULL)
597 cpl_frameset_insert(rawframes,
598 cpl_frame_duplicate(master_dark_frame)) ;
599 if (master_flat_frame!= NULL)
600 cpl_frameset_insert(rawframes,
601 cpl_frame_duplicate(master_flat_frame)) ;
602 if (bpm_frame!= NULL)
603 cpl_frameset_insert(rawframes,
604 cpl_frame_duplicate(bpm_frame)) ;
605 if (blaze_frame!= NULL)
606 cpl_frameset_insert(rawframes,
607 cpl_frame_duplicate(blaze_frame)) ;
609 out_file = cpl_sprintf(
"%s_combined.fits", RECIPE_STRING) ;
611 combined, qc_main, ext_plist,
612 CR2RES_OBS_STARING_COMBINED_PROCATG, RECIPE_STRING) ;
615 out_file = cpl_sprintf(
"%s_slitfunc.fits", RECIPE_STRING) ;
617 slitfunc, qc_main, ext_plist, CR2RES_OBS_STARING_SLITFUNC_PROCATG,
621 out_file = cpl_sprintf(
"%s_model.fits", RECIPE_STRING) ;
623 model, qc_main, ext_plist, CR2RES_OBS_STARING_SLITMODEL_PROCATG,
627 out_file = cpl_sprintf(
"%s_extracted.fits", RECIPE_STRING) ;
629 qc_main, ext_plist, CR2RES_OBS_STARING_EXTRACT_PROCATG,
633 extract, qc_main, ext_plist,
634 CR2RES_OBS_STARING_IDP_PROCATG,
638 cpl_frameset_delete(rawframes) ;
641 cpl_propertylist_delete(qc_main) ;
642 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
643 if (combined[det_nr-1] != NULL)
645 if (extract[det_nr-1] != NULL)
646 cpl_table_delete(extract[det_nr-1]) ;
647 if (slitfunc[det_nr-1] != NULL)
648 cpl_table_delete(slitfunc[det_nr-1]) ;
649 if (model[det_nr-1] != NULL)
651 if (ext_plist[det_nr-1] != NULL)
652 cpl_propertylist_delete(ext_plist[det_nr-1]) ;
655 return (
int)cpl_error_get_code();
684static int cr2res_obs_staring_reduce(
685 const cpl_frameset * rawframes,
686 const cpl_frame * trace_wave_frame,
687 const cpl_frame * detlin_frame,
688 const cpl_frame * master_dark_frame,
689 const cpl_frame * master_flat_frame,
690 const cpl_frame * bpm_frame,
691 const cpl_frame * blaze_frame,
692 const cpl_array * slit_frac,
693 int subtract_nolight_rows,
694 int subtract_interorder_column,
696 int extract_oversample,
697 int extract_swath_width,
699 double extract_smooth_slit,
700 double extract_smooth_spec,
702 hdrl_image ** combined,
703 cpl_table ** extract,
704 cpl_table ** slitfunc,
706 cpl_propertylist ** ext_plist)
708 hdrl_imagelist * in ;
709 hdrl_imagelist * in_calib ;
712 cpl_table * blaze_table ;
713 cpl_table * trace_wave ;
714 cpl_table * trace_wave_new ;
715 hdrl_image * collapsed ;
716 cpl_image * contrib ;
717 cpl_propertylist * plist ;
719 hdrl_image * model_master ;
720 cpl_table * slit_func ;
721 cpl_table * extracted ;
722 int * order_idx_values ;
724 cpl_array * fwhm_array ;
726 const char * first_fname ;
727 double qc_signal, qc_fwhm, gain, error_factor, blaze_norm ;
728 int order_zp, nb_order_idx_values,
729 order_idx, order_idxp ;
732 if (combined == NULL || extract == NULL || ext_plist == NULL ||
733 rawframes == NULL || trace_wave_frame == NULL)
return -1 ;
736 if (reduce_det == 1) gain = CR2RES_GAIN_CHIP1 ;
737 else if (reduce_det == 2) gain = CR2RES_GAIN_CHIP2 ;
738 else if (reduce_det == 3) gain = CR2RES_GAIN_CHIP3 ;
740 cpl_msg_error(__func__,
"Failed to get the Gain value") ;
745 if (cr2res_obs_staring_check_inputs_validity(rawframes) != 1) {
746 cpl_msg_error(__func__,
"Invalid Inputs") ;
751 first_fname = cpl_frame_get_filename(
752 cpl_frameset_get_position_const(rawframes, 0)) ;
755 if ((plist = cpl_propertylist_load(cpl_frame_get_filename(trace_wave_frame),
757 cpl_msg_error(__func__,
"Cannot read the ORDER_ZP from the input TW") ;
760 order_zp = cr2res_pfits_get_order_zp(plist) ;
761 cpl_propertylist_delete(plist) ;
762 if (cpl_error_get_code()) {
763 cpl_msg_error(__func__,
"Missing ORDER_ZP in the header - Skip") ;
772 if (cpl_msg_get_level() == CPL_MSG_DEBUG && dits != NULL)
773 cpl_vector_dump(dits, stdout) ;
780 reduce_det)) == NULL) {
781 cpl_msg_error(__func__,
"Cannot load images") ;
782 if (dits != NULL) cpl_vector_delete(dits) ;
786 cpl_msg_error(__func__,
"Inconsistent number of loaded images") ;
787 if (dits != NULL) cpl_vector_delete(dits) ;
793 error_factor = gain * cpl_vector_get(ndits, 0) *
794 cpl_frameset_get_size(rawframes) ;
796 for (i=0; i<cpl_vector_get_size(ndits); i++){
797 if (cpl_vector_get(ndits,i) != cpl_vector_get(ndits, 0))
798 cpl_msg_warning(__func__,
"Raw frames have different NDIT! "
799 "Error spectrum will likely be scaled incorrectly.");
804 subtract_nolight_rows, subtract_interorder_column, cosmics,
805 master_flat_frame, master_dark_frame, bpm_frame, detlin_frame,
806 dits, ndits))==NULL) {
807 cpl_msg_error(__func__,
"Failed to apply the calibrations") ;
808 if (dits != NULL) cpl_vector_delete(dits) ;
809 if (ndits != NULL) cpl_vector_delete(ndits) ;
814 if (dits != NULL) cpl_vector_delete(dits) ;
815 if (ndits != NULL) cpl_vector_delete(ndits) ;
818 cpl_msg_info(__func__,
"Collapse") ;
819 cpl_msg_indent_more() ;
822 cpl_msg_error(__func__,
"Failed to Collapse") ;
824 cpl_msg_indent_less() ;
827 cpl_image_delete(contrib) ;
829 cpl_msg_indent_less() ;
832 cpl_msg_info(__func__,
"Load the TRACE WAVE") ;
834 trace_wave_frame), reduce_det)) == NULL) {
835 cpl_msg_error(__func__,
"Failed to Load the traces file") ;
841 if (slit_frac != NULL) {
843 trace_wave, slit_frac)) == NULL) {
844 cpl_msg_warning(__func__,
845 "Failed to compute the traces for user specified slit fraction") ;
848 cpl_table_delete(trace_wave) ;
849 trace_wave = trace_wave_new ;
850 trace_wave_new = NULL ;
857 if (blaze_frame != NULL) {
858 cpl_msg_info(__func__,
"Load the BLAZE") ;
860 blaze_frame), reduce_det)) == NULL) {
861 cpl_msg_error(__func__,
"Failed to Load the Blaze file") ;
863 cpl_table_delete(trace_wave) ;
866 cpl_propertylist * blaze_plist ;
867 blaze_plist = cpl_propertylist_load_regexp(cpl_frame_get_filename(
868 blaze_frame),0,CR2RES_HEADER_QC_BLAZE_NORM,0);
869 if(cpl_propertylist_get_size(blaze_plist)>0){
870 blaze_norm = cpl_propertylist_get_double(blaze_plist, CR2RES_HEADER_QC_BLAZE_NORM);
874 cpl_msg_warning(__func__,
"QC BLAZE NORM value not found, reverting to per trace normalization") ;
876 if(blaze_plist!=NULL){
877 cpl_propertylist_delete(blaze_plist);
882 int extract_niter = 10;
883 double extract_kappa = 10;
886 cpl_msg_info(__func__,
"Spectra Extraction") ;
888 CR2RES_EXTR_OPT_CURV, extract_height, extract_swath_width,
889 extract_oversample, extract_smooth_slit, extract_smooth_spec,
890 extract_niter, extract_kappa, error_factor,
891 0, 0, 0, &extracted, &slit_func, &model_master) == -1) {
892 cpl_msg_error(__func__,
"Failed to extract");
894 cpl_table_delete(trace_wave) ;
897 if (blaze_table != NULL) cpl_table_delete(blaze_table) ;
900 plist = cpl_propertylist_load(first_fname,
905 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_SIGNAL, qc_signal) ;
908 qc_snrs =
cr2res_qc_snr(trace_wave, extracted, &order_idx_values,
909 &nb_order_idx_values) ;
910 for (i=0 ; i<nb_order_idx_values ; i++) {
911 order_idx = order_idx_values[i] ;
913 key_name = cpl_sprintf(CR2RES_HEADER_QC_SNR, order_idxp) ;
914 cpl_propertylist_append_double(plist, key_name, qc_snrs[i]) ;
917 cpl_free(order_idx_values) ;
922 &nb_order_idx_values);
925 fwhm_array = cpl_array_new(nb_order_idx_values, CPL_TYPE_DOUBLE);
926 for (i=0 ; i<nb_order_idx_values ; i++) {
927 order_idx = order_idx_values[i] ;
932 key_name = cpl_sprintf(CR2RES_HEADER_QC_SLITFWHM_ORDER, order_idxp) ;
933 cpl_propertylist_append_double(plist, key_name, qc_fwhm) ;
935 cpl_array_set(fwhm_array, i, qc_fwhm) ;
937 cpl_free(order_idx_values) ;
938 qc_fwhm = cpl_array_get_median(fwhm_array);
939 cpl_propertylist_append_double(plist, CR2RES_HEADER_QC_SLITFWHM_MED,
942 cpl_msg_warning(__func__,
"Median FWHM of the PSF along the slit "
943 "is %gpix, i.e. below the slit width. This means the slit "
944 "is likely not evenly filled with light "
945 "in the spectral direction. This can result in a "
946 "wavelength offset between different positions along the slit,"
947 " and with respect to calibrations."
951 cpl_array_delete(fwhm_array) ;
957 &nb_order_idx_values);
960 for (i = 0; i < nb_order_idx_values; i++) {
962 order_idx = order_idx_values[i] ;
965 key_name = cpl_sprintf(CR2RES_HEADER_QC_REAL_ORDER, order_idxp) ;
966 cpl_propertylist_append_int(plist, key_name, order_real) ;
969 cpl_free(order_idx_values) ;
971 cpl_table_delete(trace_wave) ;
974 *combined = collapsed ;
975 *extract = extracted ;
976 *slitfunc = slit_func ;
977 *model = model_master ;
990static int cr2res_obs_staring_check_inputs_validity(
991 const cpl_frameset * rawframes)
994 if (rawframes == NULL)
return -1 ;
1008static cpl_frameset * cr2res_obs_staring_find_RAW(
1009 const cpl_frameset * in)
1011 cpl_frameset * out ;
1014 if (in == NULL)
return NULL ;
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.
int cr2res_idp_save(const char *filename, cpl_frameset *allframes, cpl_frameset *rawframes, const cpl_parameterlist *parlist, cpl_table **tables, cpl_propertylist *main_qc_plist, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save an IDP file.
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.
int cr2res_io_save_SLIT_MODEL(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 SLIT_MODEL.
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_convert_order_idx_to_idxp(int order_idx)
Convert the order_idx to the order_idxp.
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.
cpl_table * cr2res_io_get_eop_table()
Get the eop_table.
int cr2res_io_get_ext_idx(const char *filename, int detector, int data)
Get the wished extension number for a detector.
int cr2res_io_save_SLIT_FUNC(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, cpl_table **slit_func, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a SLIT_FUNC.
int cr2res_io_save_COMBINED(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 COMBINED.
cpl_table * cr2res_io_load_TRACE_WAVE(const char *filename, int detector)
Load a table from a TRACE_WAVE.
cpl_vector * cr2res_io_read_ndits(const cpl_frameset *in)
Get the NDITs from a frame set.
int cr2res_qc_numsat(const cpl_frameset *frameset)
Calculate the number of saturated pixels.
double cr2res_qc_obs_nodding_signal(const cpl_table *extracted)
Computes the integrated flux over part of the spectrum.
double * cr2res_qc_snr(const cpl_table *tw, const cpl_table *extracted, int **out_order_idx_values, int *out_nb_order_idx_values)
Computes the SNR of several spectra.
double cr2res_qc_obs_slit_psf(const cpl_table *slitfu, int order_idxp, int oversample)
Computes the FWHM of the PSF along the slit for a given order.
cpl_table * cr2res_trace_new_slit_fraction(const cpl_table *traces, const cpl_array *new_slit_fraction)
Recompute the traces at a newly specified slit fraction.
int * cr2res_trace_get_order_idx_values(const cpl_table *trace, int *nb_order_idx_values)
Count and return the different order_idx values from a TW table.
int cr2res_order_idx_to_real(int order_idx, int order_zp)
Convert the order_idx into order_real.
double cr2res_utils_get_center_mjd(const cpl_frameset *frameset)
Calculate the middle of the exposures in the frameset.
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.
cpl_error_code hdrl_barycorr_compute(double ra, double dec, const cpl_table *eop_table, double mjdobs, double time_to_mid_exposure, double longitude, double latitude, double elevation, double pressure, double temperature, double humidity, double wavelength, double *barycorr)
Derives the barycentric correction using the erfa function eraApco13(). The latter For a terrestrial ...
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.