34#include "cr2res_utils.h"
35#include "cr2res_calib.h"
36#include "cr2res_pfits.h"
37#include "cr2res_dfs.h"
38#include "cr2res_flat.h"
39#include "cr2res_trace.h"
40#include "cr2res_extract.h"
47#define RECIPE_STRING "cr2res_util_calib"
53int cpl_plugin_get_info(cpl_pluginlist * list);
59static cpl_frameset * cr2res_util_calib_find_RAW(
const cpl_frameset * in) ;
60static int cr2res_util_calib_create(cpl_plugin *);
61static int cr2res_util_calib_exec(cpl_plugin *);
62static int cr2res_util_calib_destroy(cpl_plugin *);
63static int cr2res_util_calib(cpl_frameset *,
const cpl_parameterlist *);
69static char cr2res_util_calib_description[] =
"\
71 Each input file is corrected with BPM / Dark / Flat / Det.Lin. / Cosmics\n\
74 raw.fits " CR2RES_FLAT_RAW
" [1 to n] \n\
75 or " CR2RES_WAVE_UNE_RAW
" \n\
76 or " CR2RES_WAVE_FPET_RAW
" \n\
77 or " CR2RES_CAL_NODDING_OTHER_RAW
" \n\
78 or " CR2RES_CAL_NODDING_JITTER_RAW
" \n\
79 or " CR2RES_OBS_NODDING_OTHER_RAW
" \n\
80 or " CR2RES_OBS_NODDING_JITTER_RAW
" \n\
81 or " CR2RES_OBS_ASTROMETRY_OTHER_RAW
" \n\
82 or " CR2RES_OBS_ASTROMETRY_JITTER_RAW
" \n\
83 or " CR2RES_OBS_STARING_OTHER_RAW
" \n\
84 or " CR2RES_OBS_STARING_JITTER_RAW
" \n\
85 or " CR2RES_OBS_STARING_WAVE_SKY_RAW
" \n\
86 or " CR2RES_OBS_POLARIMETRY_OTHER_RAW
" \n\
87 or " CR2RES_OBS_2D_OBJECT_RAW
" \n\
88 or " CR2RES_OBS_2D_SKY_RAW
" \n\
89 detlin.fits " CR2RES_CAL_DETLIN_COEFFS_PROCATG
" [0 to 1] \n\
90 bpm.fits " CR2RES_CAL_DARK_BPM_PROCATG
" [0 to 1] \n\
91 or " CR2RES_CAL_FLAT_BPM_PROCATG
" \n\
92 or " CR2RES_CAL_DETLIN_BPM_PROCATG
" \n\
93 or " CR2RES_UTIL_BPM_MERGE_PROCATG
" \n\
94 or " CR2RES_UTIL_BPM_SPLIT_PROCATG
" \n\
95 master_dark.fits " CR2RES_CAL_DARK_MASTER_PROCATG
" [0 to 1] \n\
96 master_flat.fits " CR2RES_CAL_FLAT_MASTER_PROCATG
" [0 to 1] \n\
99 <input_name>_calibrated.fits " CR2RES_UTIL_CALIB_PROCATG
" \n\
101 <input_name>_calibrated_collapsed.fits " CR2RES_UTIL_CALIB_PROCATG
"\n\
104 loop on detectors d: \n\
105 Call cr2res_calib_imagelist()() to calibrate cosmics, \n\
106 detlin, bpm, dark, flat \n\
108 Collapse the calibrated image list to collapsed(d) \n\
109 if (collapse) save collapsed \n\
110 else save every individual calibrated frame \n\
111 Library functions used: \n\
112 cr2res_io_load_image() \n\
113 cr2res_calib_imagelist() \n\
114 cr2res_io_save_CALIBRATED() \n\
132int cpl_plugin_get_info(cpl_pluginlist * list)
134 cpl_recipe * recipe = cpl_calloc(1,
sizeof *recipe );
135 cpl_plugin * plugin = &recipe->interface;
137 if (cpl_plugin_init(plugin,
139 CR2RES_BINARY_VERSION,
140 CPL_PLUGIN_TYPE_RECIPE,
142 "Calibration utility",
143 cr2res_util_calib_description,
144 CR2RES_PIPELINE_AUTHORS,
147 cr2res_util_calib_create,
148 cr2res_util_calib_exec,
149 cr2res_util_calib_destroy)) {
150 cpl_msg_error(cpl_func,
"Plugin initialization failed");
151 (void)cpl_error_set_where(cpl_func);
155 if (cpl_pluginlist_append(list, plugin)) {
156 cpl_msg_error(cpl_func,
"Error adding plugin to list");
157 (void)cpl_error_set_where(cpl_func);
173static int cr2res_util_calib_create(cpl_plugin * plugin)
175 cpl_recipe * recipe ;
179 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
180 recipe = (cpl_recipe *)plugin;
185 recipe->parameters = cpl_parameterlist_new();
188 p = cpl_parameter_new_value(
"cr2res.cr2res_util_calib.detector",
189 CPL_TYPE_INT,
"Only reduce the specified detector",
190 "cr2res.cr2res_util_calib", 0);
191 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"detector");
192 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
193 cpl_parameterlist_append(recipe->parameters, p);
195 p = cpl_parameter_new_value(
"cr2res.cr2res_util_calib.clean_bad",
196 CPL_TYPE_BOOL,
"Apply the cleaning to the bad pixels",
197 "cr2res.cr2res_util_calib", FALSE);
198 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"clean_bad");
199 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
200 cpl_parameterlist_append(recipe->parameters, p);
202 p = cpl_parameter_new_value(
203 "cr2res.cr2res_util_calib.subtract_nolight_rows",
205 "Subtract median row from baffled region at detector bottom",
206 "cr2res.cr2res_util_calib", FALSE);
207 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"subtract_nolight_rows");
208 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
209 cpl_parameterlist_append(recipe->parameters, p);
211 p = cpl_parameter_new_value(
212 "cr2res.cr2res_util_calib.subtract_interorder_column",
214 "Subtract column-by-column fit to the pixel values between"
216 "cr2res.cr2res_util_calib", TRUE);
217 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
218 "subtract_interorder_column");
219 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
220 cpl_parameterlist_append(recipe->parameters, p);
222 p = cpl_parameter_new_value(
"cr2res.cr2res_util_calib.cosmics",
223 CPL_TYPE_BOOL,
"Find and mark cosmic rays hits as bad",
224 "cr2res.cr2res_util_calib", FALSE);
225 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"cosmics");
226 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
227 cpl_parameterlist_append(recipe->parameters, p);
229 p = cpl_parameter_new_value(
"cr2res.cr2res_util_calib.collapse",
230 CPL_TYPE_STRING,
"Collapse the input (NONE, SUM, MEAN or MEDIAN)",
231 "cr2res.cr2res_util_calib",
"NONE");
232 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"collapse");
233 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
234 cpl_parameterlist_append(recipe->parameters, p);
246static int cr2res_util_calib_exec(cpl_plugin * plugin)
251 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
252 recipe = (cpl_recipe *)plugin;
255 return cr2res_util_calib(recipe->frames, recipe->parameters);
265static int cr2res_util_calib_destroy(cpl_plugin * plugin)
270 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
271 recipe = (cpl_recipe *)plugin;
274 cpl_parameterlist_delete(recipe->parameters);
286static int cr2res_util_calib(
287 cpl_frameset * frameset,
288 const cpl_parameterlist * parlist)
290 const cpl_parameter * param ;
291 int clean_bad, cosmics, reduce_det,
292 subtract_nolight_rows, subtract_interorder_column ;
293 cr2res_collapse collapse ;
295 cpl_frameset * rawframes ;
296 const cpl_frame * detlin_frame ;
297 const cpl_frame * master_dark_frame ;
298 const cpl_frame * master_flat_frame ;
299 const cpl_frame * bpm_frame ;
302 cpl_vector * ndsamples ;
303 hdrl_imagelist * in ;
304 cpl_image * contrib ;
305 const cpl_frame * cur_frame ;
306 const char * cur_fname ;
307 hdrl_image * collapsed_ima[CR2RES_NB_DETECTORS] ;
308 hdrl_image * calibrated_one[CR2RES_NB_DETECTORS] ;
309 hdrl_imagelist * calibrated[CR2RES_NB_DETECTORS] ;
310 cpl_propertylist * ext_plist[CR2RES_NB_DETECTORS] ;
311 hdrl_value mul_factor ;
316 setlocale(LC_NUMERIC,
"C");
320 collapse = CR2RES_COLLAPSE_UNSPECIFIED ;
323 param = cpl_parameterlist_find_const(parlist,
324 "cr2res.cr2res_util_calib.detector");
325 reduce_det = cpl_parameter_get_int(param);
326 param = cpl_parameterlist_find_const(parlist,
327 "cr2res.cr2res_util_calib.clean_bad");
328 clean_bad = cpl_parameter_get_bool(param);
329 param = cpl_parameterlist_find_const(parlist,
330 "cr2res.cr2res_util_calib.subtract_nolight_rows");
331 subtract_nolight_rows = cpl_parameter_get_bool(param);
332 param = cpl_parameterlist_find_const(parlist,
333 "cr2res.cr2res_util_calib.subtract_interorder_column");
334 subtract_interorder_column = cpl_parameter_get_bool(param);
335 param = cpl_parameterlist_find_const(parlist,
336 "cr2res.cr2res_util_calib.cosmics");
337 cosmics = cpl_parameter_get_bool(param);
338 param = cpl_parameterlist_find_const(parlist,
339 "cr2res.cr2res_util_calib.collapse");
340 sval = cpl_parameter_get_string(param);
341 if (!strcmp(sval,
"NONE")) collapse = CR2RES_COLLAPSE_NONE ;
342 else if (!strcmp(sval,
"SUM")) collapse = CR2RES_COLLAPSE_SUM ;
343 else if (!strcmp(sval,
"MEAN")) collapse = CR2RES_COLLAPSE_MEAN ;
344 else if (!strcmp(sval,
"MEDIAN")) collapse = CR2RES_COLLAPSE_MEDIAN ;
345 if (collapse == CR2RES_COLLAPSE_UNSPECIFIED) {
346 cpl_msg_error(__func__,
"Cannot understand the collapse method") ;
347 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
353 cpl_msg_error(__func__,
"Cannot identify RAW and CALIB frames") ;
354 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
359 detlin_frame = cpl_frameset_find_const(frameset,
360 CR2RES_CAL_DETLIN_COEFFS_PROCATG);
361 master_dark_frame = cpl_frameset_find_const(frameset,
362 CR2RES_CAL_DARK_MASTER_PROCATG) ;
363 master_flat_frame = cpl_frameset_find_const(frameset,
364 CR2RES_CAL_FLAT_MASTER_PROCATG) ;
368 rawframes = cr2res_util_calib_find_RAW(frameset) ;
369 if (rawframes==NULL || cpl_frameset_get_size(rawframes) <= 0) {
370 cpl_msg_error(__func__,
"Cannot find any RAW file") ;
371 cpl_error_set(__func__, CPL_ERROR_DATA_NOT_FOUND) ;
372 if (rawframes!= NULL) cpl_frameset_delete(rawframes) ;
377 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
379 collapsed_ima[det_nr-1] = NULL ;
380 calibrated[det_nr-1] = NULL ;
383 if (reduce_det != 0 && det_nr != reduce_det) continue ;
385 cpl_msg_info(__func__,
"Process Detector %d", det_nr) ;
386 cpl_msg_indent_more() ;
391 if (cpl_msg_get_level() == CPL_MSG_DEBUG && dits != NULL)
392 cpl_vector_dump(dits, stdout) ;
396 cpl_msg_info(__func__,
"Load the input frames") ;
399 cpl_msg_warning(__func__,
"Cannot load images") ;
400 if (dits != NULL) cpl_vector_delete(dits) ;
401 if (ndits != NULL) cpl_vector_delete(ndits) ;
402 cpl_msg_indent_less() ;
406 cpl_msg_error(__func__,
"Inconsistent number of loaded images") ;
407 if (dits != NULL) cpl_vector_delete(dits) ;
408 if (ndits != NULL) cpl_vector_delete(ndits) ;
410 cpl_msg_indent_less() ;
415 cpl_msg_info(__func__,
"Calibrate the input images") ;
418 clean_bad, subtract_nolight_rows,
419 subtract_interorder_column, cosmics,
421 master_dark_frame, bpm_frame, detlin_frame,
422 dits, ndits, ndsamples) ;
423 cpl_vector_delete(ndsamples) ;
424 if (calibrated[det_nr-1] == NULL) {
425 cpl_msg_warning(__func__,
"Failed to apply the calibrations") ;
427 if (dits != NULL) cpl_vector_delete(dits) ;
428 if (ndits != NULL) cpl_vector_delete(ndits) ;
430 cpl_msg_indent_less() ;
434 if (dits != NULL) cpl_vector_delete(dits) ;
435 if (ndits != NULL) cpl_vector_delete(ndits) ;
438 if (collapse == CR2RES_COLLAPSE_MEAN) {
439 cpl_msg_info(__func__,
"Collapse (Mean) the calibrated images") ;
440 cpl_msg_indent_more() ;
442 &(collapsed_ima[det_nr-1]), &contrib) ;
443 }
else if (collapse == CR2RES_COLLAPSE_SUM) {
444 cpl_msg_info(__func__,
"Collapse (Sum) the calibrated images") ;
445 cpl_msg_indent_more() ;
447 &(collapsed_ima[det_nr-1]), &contrib) ;
452 }
else if (collapse == CR2RES_COLLAPSE_MEDIAN) {
453 cpl_msg_info(__func__,
"Collapse (Median) the calibrated images") ;
454 cpl_msg_indent_more() ;
456 &(collapsed_ima[det_nr-1]), &contrib) ;
458 if (contrib != NULL) {
459 cpl_image_delete(contrib) ;
462 if (cpl_error_get_code() != CPL_ERROR_NONE) {
463 collapsed_ima[det_nr-1] = NULL ;
464 cpl_msg_warning(__func__,
"Failed to Collapse") ;
465 cpl_msg_indent_less() ;
466 cpl_msg_indent_less() ;
470 cpl_msg_indent_less() ;
471 cpl_msg_indent_less() ;
475 if (collapse == CR2RES_COLLAPSE_NONE) {
479 for (i = 0; i < cpl_frameset_get_size(rawframes); i++) {
480 cpl_frameset *cur_fset;
482 cur_frame = cpl_frameset_get_position(rawframes, i) ;
483 cur_fname = cpl_frame_get_filename(cur_frame) ;
486 out_file=cpl_sprintf(
"%s_calibrated.fits",
488 cur_fset = cpl_frameset_new() ;
489 cpl_frameset_insert(cur_fset, cpl_frame_duplicate(cur_frame)) ;
491 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
493 ext_plist[det_nr-1] = NULL ;
494 calibrated_one[det_nr-1] = NULL ;
497 if (reduce_det != 0 && det_nr != reduce_det) continue ;
499 ext_plist[det_nr-1] = cpl_propertylist_load(cur_fname,
505 calibrated_one, NULL, ext_plist, CR2RES_UTIL_CALIB_PROCATG,
507 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
508 if (ext_plist[det_nr-1] != NULL)
509 cpl_propertylist_delete(ext_plist[det_nr-1]) ;
510 if (calibrated_one[det_nr-1] != NULL)
513 cpl_frameset_delete(cur_fset) ;
519 cur_frame = cpl_frameset_get_position(rawframes, 0) ;
520 cur_fname = cpl_frame_get_filename(cur_frame) ;
521 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
523 ext_plist[det_nr-1] = NULL ;
526 if (reduce_det != 0 && det_nr != reduce_det) continue ;
528 ext_plist[det_nr-1] = cpl_propertylist_load(cur_fname,
531 out_file=cpl_sprintf(
"%s_calibrated_collapsed.fits", RECIPE_STRING) ;
533 collapsed_ima, NULL, ext_plist, CR2RES_UTIL_CALIB_PROCATG,
535 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
536 if (ext_plist[det_nr-1] != NULL)
537 cpl_propertylist_delete(ext_plist[det_nr-1]) ;
543 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
544 if (collapsed_ima[det_nr-1] != NULL)
546 if (calibrated[det_nr-1] != NULL)
549 cpl_frameset_delete(rawframes) ;
550 return (
int)cpl_error_get_code();
575static cpl_frameset * cr2res_util_calib_find_RAW(
const cpl_frameset * in)
582 if (in == NULL)
return NULL ;
586 tags = cpl_malloc(ntags *
sizeof(
char *)) ;
587 tags[0] = cpl_sprintf(CR2RES_FLAT_RAW) ;
588 tags[1] = cpl_sprintf(CR2RES_WAVE_UNE_RAW) ;
589 tags[2] = cpl_sprintf(CR2RES_WAVE_FPET_RAW) ;
590 tags[3] = cpl_sprintf(CR2RES_CAL_NODDING_OTHER_RAW) ;
591 tags[4] = cpl_sprintf(CR2RES_CAL_NODDING_JITTER_RAW) ;
592 tags[5] = cpl_sprintf(CR2RES_OBS_NODDING_OTHER_RAW) ;
593 tags[6] = cpl_sprintf(CR2RES_OBS_NODDING_JITTER_RAW) ;
594 tags[7] = cpl_sprintf(CR2RES_OBS_ASTROMETRY_OTHER_RAW) ;
595 tags[8] = cpl_sprintf(CR2RES_OBS_ASTROMETRY_JITTER_RAW) ;
596 tags[9] = cpl_sprintf(CR2RES_OBS_STARING_OTHER_RAW) ;
597 tags[10] = cpl_sprintf(CR2RES_OBS_STARING_JITTER_RAW) ;
598 tags[11] = cpl_sprintf(CR2RES_OBS_STARING_WAVE_SKY_RAW) ;
599 tags[12] = cpl_sprintf(CR2RES_OBS_POLARIMETRY_OTHER_RAW) ;
600 tags[13] = cpl_sprintf(CR2RES_OBS_2D_OBJECT_RAW) ;
601 tags[14] = cpl_sprintf(CR2RES_OBS_2D_SKY_RAW) ;
606 for (i=0 ; i<ntags ; i++) cpl_free(tags[i]) ;
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, const cpl_vector *ndsamples)
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.
const cpl_frame * cr2res_io_find_BPM(const cpl_frameset *in)
Get the first CR2RES_BPM_DRSTYPE frame from a frameset.
cpl_vector * cr2res_io_read_ndsamples(const cpl_frameset *in)
Get the NDSAMPLES from a frame set.
cpl_vector * cr2res_io_read_dits(const cpl_frameset *in)
Get the DITS from a frame set.
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.
int cr2res_io_save_CALIBRATED(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, hdrl_image **calib_collapsed, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a CALIBRATED frame.
cpl_vector * cr2res_io_read_ndits(const cpl_frameset *in)
Get the NDITs from a frame set.
char * cr2res_get_root_name(const char *filename)
Find out the root part of a basename (name without extension).
cpl_frameset * cr2res_extract_frameset_several_tags(const cpl_frameset *in, const char **tags, int ntags)
Extract the frames whose tag is within a list from a frameset.
char * cr2res_get_base_name(const char *filename)
Find out the base name of a file (i.e. without prefix path)
const char * cr2res_get_license(void)
Get the pipeline copyright and license.
cpl_error_code hdrl_image_mul_scalar(hdrl_image *self, hdrl_value value)
Elementwise multiplication of an image with a scalar.
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_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.
const hdrl_image * hdrl_imagelist_get_const(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of 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.