31#include "cr2res_utils.h"
32#include "cr2res_calib.h"
33#include "cr2res_pfits.h"
34#include "cr2res_dfs.h"
35#include "cr2res_flat.h"
36#include "cr2res_bpm.h"
37#include "cr2res_trace.h"
38#include "cr2res_extract.h"
45#define RECIPE_STRING "cr2res_util_normflat"
51int cpl_plugin_get_info(cpl_pluginlist * list);
57static cpl_frameset * cr2res_util_normflat_find_RAW(
const cpl_frameset * in) ;
58static int cr2res_util_normflat_reduce(
59 const cpl_frameset * rawframes,
60 const cpl_frame * slitmodel_frame,
65 hdrl_image ** master_flat,
67 cpl_propertylist ** ext_plist) ;
68static int cr2res_util_normflat_compare(
69 const cpl_frame * frame1,
70 const cpl_frame * frame2) ;
71static int cr2res_util_normflat_create(cpl_plugin *);
72static int cr2res_util_normflat_exec(cpl_plugin *);
73static int cr2res_util_normflat_destroy(cpl_plugin *);
74static int cr2res_util_normflat(cpl_frameset *,
const cpl_parameterlist *);
80static char cr2res_util_normflat_description[] =
"\
82 The input RAW files are grouped by setting/decker and each group is \n\
83 reduced separately. For each group, a slit model file with matching \n\
84 setting/decker is expected. \n\
87 raw.fits " CR2RES_FLAT_RAW
" [1 to n] \n\
88 or " CR2RES_UTIL_CALIB_PROCATG
" \n\
89 slit_model.fits " CR2RES_CAL_FLAT_SLIT_MODEL_PROCATG
" [1 to m] \n\
90 or " CR2RES_UTIL_SLIT_MODEL_PROCATG
" \n\
91 or " CR2RES_OBS_NODDING_SLITMODELA_PROCATG
" \n\
92 or " CR2RES_OBS_NODDING_SLITMODELB_PROCATG
" \n\
95 cr2res_util_normflat_[setting]_[Decker]_bpm.fits "
96 CR2RES_UTIL_NORM_BPM_PROCATG
"\n\
97 cr2res_util_normflat_[setting]_[Decker]_master.fits "
98 CR2RES_UTIL_MASTER_FLAT_PROCATG
"\n\
101 group the input frames by different settings \n\
102 loop on groups g: \n\
103 group the input frames by different decker positions \n\
104 loop on decker positions p: \n\
105 loop on detectors d: \n\
106 cr2res_util_normflat_reduce() computes (master_flat,bpm)(g,p,d)\n\
107 Save master_flat(g,p) \n\
110 cr2res_util_normflat_reduce() \n\
111 Load the images list \n\
112 Average the images to avg \n\
113 Load the input slit_model with the proper setting/decker \n\
114 Compute the master flat with cr2res_master_flat(avg, \n\
115 slit_model, --bpm_low, --bpm_high, --bpm_lines_ratio) \n\
116 -> master_flat, bpm \n\
118Library functions used: \n\
119 cr2res_extract_frameset() \n\
120 cr2res_io_extract_decker_frameset() \n\
121 cr2res_io_find_SLIT_MODEL() \n\
122 cr2res_io_load_image_list_from_set() \n\
123 cr2res_io_load_SLIT_MODEL() \n\
124 cr2res_master_flat() \n\
125 cr2res_io_save_MASTER_FLAT() \n\
126 cr2res_io_save_BPM() \n\
144int cpl_plugin_get_info(cpl_pluginlist * list)
146 cpl_recipe * recipe = cpl_calloc(1,
sizeof *recipe );
147 cpl_plugin * plugin = &recipe->interface;
149 if (cpl_plugin_init(plugin,
151 CR2RES_BINARY_VERSION,
152 CPL_PLUGIN_TYPE_RECIPE,
154 "Flat Normalization utility",
155 cr2res_util_normflat_description,
156 CR2RES_PIPELINE_AUTHORS,
159 cr2res_util_normflat_create,
160 cr2res_util_normflat_exec,
161 cr2res_util_normflat_destroy)) {
162 cpl_msg_error(cpl_func,
"Plugin initialization failed");
163 (void)cpl_error_set_where(cpl_func);
167 if (cpl_pluginlist_append(list, plugin)) {
168 cpl_msg_error(cpl_func,
"Error adding plugin to list");
169 (void)cpl_error_set_where(cpl_func);
185static int cr2res_util_normflat_create(cpl_plugin * plugin)
187 cpl_recipe * recipe ;
191 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
192 recipe = (cpl_recipe *)plugin;
197 recipe->parameters = cpl_parameterlist_new();
200 p = cpl_parameter_new_value(
"cr2res.cr2res_util_normflat.bpm_low",
201 CPL_TYPE_DOUBLE,
"Low threshold for BPM detection",
202 "cr2res.cr2res_util_normflat", 0.5);
203 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"bpm_low");
204 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
205 cpl_parameterlist_append(recipe->parameters, p);
207 p = cpl_parameter_new_value(
"cr2res.cr2res_util_normflat.bpm_high",
208 CPL_TYPE_DOUBLE,
"High threshold for BPM detection",
209 "cr2res.cr2res_util_normflat", 2.0);
210 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"bpm_high");
211 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
212 cpl_parameterlist_append(recipe->parameters, p);
214 p = cpl_parameter_new_value(
"cr2res.cr2res_util_normflat.bpm_lines_ratio",
215 CPL_TYPE_DOUBLE,
"Maximum ratio of bad pixels per line",
216 "cr2res.cr2res_util_normflat", 0.5);
217 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"bpm_lines_ratio");
218 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
219 cpl_parameterlist_append(recipe->parameters, p);
222 p = cpl_parameter_new_value(
"cr2res.cr2res_util_normflat.detector",
223 CPL_TYPE_INT,
"Only reduce the specified detector",
224 "cr2res.cr2res_util_normflat", 0);
225 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"detector");
226 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
227 cpl_parameterlist_append(recipe->parameters, p);
239static int cr2res_util_normflat_exec(cpl_plugin * plugin)
244 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
245 recipe = (cpl_recipe *)plugin;
248 return cr2res_util_normflat(recipe->frames, recipe->parameters);
258static int cr2res_util_normflat_destroy(cpl_plugin * plugin)
263 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
264 recipe = (cpl_recipe *)plugin;
267 cpl_parameterlist_delete(recipe->parameters);
279static int cr2res_util_normflat(
280 cpl_frameset * frameset,
281 const cpl_parameterlist * parlist)
283 const cpl_parameter * param ;
285 double bpm_low, bpm_high, bpm_lines_ratio ;
286 cpl_frameset * rawframes ;
287 const char * used_tag ;
288 cpl_frameset * raw_one_setting_decker ;
291 cpl_frame * slitmodel_frame ;
292 hdrl_image * master_flat[CR2RES_NB_DETECTORS] ;
293 cpl_image * bpm[CR2RES_NB_DETECTORS] ;
294 cpl_propertylist * ext_plist[CR2RES_NB_DETECTORS] ;
299 cr2res_decker decker_values[CR2RES_NB_DECKER_POSITIONS] =
300 {CR2RES_DECKER_NONE, CR2RES_DECKER_1_3, CR2RES_DECKER_2_4} ;
301 char * decker_desc[CR2RES_NB_DECKER_POSITIONS] =
302 {
"Open",
"Decker1",
"Decker2"} ;
305 param = cpl_parameterlist_find_const(parlist,
306 "cr2res.cr2res_util_normflat.bpm_low");
307 bpm_low = cpl_parameter_get_double(param);
308 param = cpl_parameterlist_find_const(parlist,
309 "cr2res.cr2res_util_normflat.bpm_high");
310 bpm_high = cpl_parameter_get_double(param);
311 param = cpl_parameterlist_find_const(parlist,
312 "cr2res.cr2res_util_normflat.bpm_lines_ratio");
313 bpm_lines_ratio = cpl_parameter_get_double(param);
314 param = cpl_parameterlist_find_const(parlist,
315 "cr2res.cr2res_util_normflat.detector");
316 reduce_det = cpl_parameter_get_int(param);
320 cpl_msg_error(__func__,
"Cannot identify RAW and CALIB frames") ;
321 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
326 rawframes = cr2res_util_normflat_find_RAW(frameset) ;
327 if (rawframes==NULL || cpl_frameset_get_size(rawframes) <= 0) {
328 cpl_msg_error(__func__,
"Cannot find any RAW file") ;
329 cpl_error_set(__func__, CPL_ERROR_DATA_NOT_FOUND) ;
333 used_tag = cpl_frame_get_tag(cpl_frameset_get_position_const(rawframes,0));
336 if ((labels = cpl_frameset_labelise(rawframes, cr2res_util_normflat_compare,
337 &nlabels)) == NULL) {
338 cpl_msg_error(__func__,
"Cannot labelise input frames") ;
339 cpl_frameset_delete(rawframes) ;
340 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
345 for (l = 0; l < (int)nlabels; l++) {
346 cpl_propertylist *plist;
348 cpl_frameset *raw_one_setting;
350 raw_one_setting = cpl_frameset_extract(rawframes, labels, (cpl_size)l) ;
353 plist = cpl_propertylist_load(cpl_frame_get_filename(
354 cpl_frameset_get_position(raw_one_setting, 0)), 0) ;
357 cpl_propertylist_delete(plist) ;
359 cpl_msg_info(__func__,
"Process SETTING %s", setting_id) ;
360 cpl_msg_indent_more() ;
363 for (i=0 ; i<CR2RES_NB_DECKER_POSITIONS ; i++) {
366 raw_one_setting, used_tag, decker_values[i]) ;
367 if (raw_one_setting_decker == NULL) {
368 cpl_msg_info(__func__,
"No files for decker: %s",
372 cpl_msg_info(__func__,
"Reduce %s Frames", decker_desc[i]) ;
373 cpl_msg_indent_more() ;
377 setting_id, decker_values[i]);
380 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
382 master_flat[det_nr-1] = NULL ;
383 bpm[det_nr-1] = NULL ;
384 ext_plist[det_nr-1] = NULL ;
387 if (reduce_det != 0 && det_nr != reduce_det) continue ;
389 cpl_msg_info(__func__,
"Process Detector %d", det_nr) ;
390 cpl_msg_indent_more() ;
393 if (cr2res_util_normflat_reduce(raw_one_setting_decker,
394 slitmodel_frame, bpm_low, bpm_high,
395 bpm_lines_ratio, det_nr,
396 &(master_flat[det_nr-1]),
398 &(ext_plist[det_nr-1])) == -1) {
399 cpl_msg_warning(__func__,
400 "Failed to reduce detector %d of %s Frames",
401 det_nr, decker_desc[i]);
403 cpl_msg_indent_less() ;
405 cpl_msg_indent_less() ;
406 cpl_frame_delete(slitmodel_frame) ;
412 out_file = cpl_sprintf(
"%s_%s_master_flat.fits",
413 RECIPE_STRING, decker_desc[i]) ;
415 out_file = cpl_sprintf(
"%s_%s_%s_master_flat.fits",
416 RECIPE_STRING, setting_id, decker_desc[i]) ;
419 raw_one_setting_decker, parlist, master_flat, NULL,
420 ext_plist, CR2RES_UTIL_MASTER_FLAT_PROCATG,
426 out_file = cpl_sprintf(
"%s_%s_master_bpm.fits",
427 RECIPE_STRING, decker_desc[i]) ;
429 out_file = cpl_sprintf(
"%s_%s_%s_master_bpm.fits",
430 RECIPE_STRING, setting_id, decker_desc[i]) ;
433 raw_one_setting_decker, parlist, bpm, NULL,ext_plist,
434 CR2RES_UTIL_NORM_BPM_PROCATG, RECIPE_STRING) ;
438 cpl_frameset_delete(raw_one_setting_decker) ;
439 for (det_nr=1 ; det_nr<=CR2RES_NB_DETECTORS ; det_nr++) {
440 if (master_flat[det_nr-1] != NULL)
442 if (bpm[det_nr-1] != NULL)
443 cpl_image_delete(bpm[det_nr-1]) ;
444 if (ext_plist[det_nr-1] != NULL)
445 cpl_propertylist_delete(ext_plist[det_nr-1]) ;
448 cpl_msg_indent_less() ;
449 cpl_frameset_delete(raw_one_setting) ;
450 cpl_free(setting_id) ;
453 cpl_frameset_delete(rawframes) ;
454 return (
int)cpl_error_get_code();
471static int cr2res_util_normflat_reduce(
472 const cpl_frameset * rawframes,
473 const cpl_frame * slitmodel_frame,
478 hdrl_image ** master_flat,
480 cpl_propertylist ** ext_plist)
482 const char * first_file ;
483 hdrl_imagelist * imlist ;
484 hdrl_image * collapsed ;
485 hdrl_image * slit_model ;
486 cpl_image * contrib ;
487 cpl_image * bpm_flat ;
488 cpl_propertylist * plist ;
489 hdrl_image * master_flat_loc ;
493 if (rawframes == NULL)
return -1 ;
496 first_file = cpl_frame_get_filename(
497 cpl_frameset_get_position_const(rawframes, 0)) ;
501 plist = cpl_propertylist_load(first_file, ext_nr) ;
502 if (plist == NULL)
return -1 ;
506 if (imlist == NULL) {
507 cpl_msg_error(__func__,
"Failed to Load the images") ;
508 cpl_propertylist_delete(plist);
513 cpl_msg_info(__func__,
"Collapse the input images") ;
514 cpl_msg_indent_more() ;
517 cpl_msg_error(__func__,
"Failed to Collapse") ;
518 cpl_propertylist_delete(plist);
520 cpl_msg_indent_less() ;
524 cpl_image_delete(contrib) ;
525 cpl_msg_indent_less() ;
529 cpl_frame_get_filename(slitmodel_frame),
530 reduce_det)) == NULL) {
531 cpl_msg_error(__func__,
"Cannot load the slit model") ;
532 cpl_propertylist_delete(plist);
538 cpl_msg_info(__func__,
"Compute the master flat") ;
539 cpl_msg_indent_more() ;
541 bpm_high, bpm_linemax, &bpm_flat)) == NULL) {
542 cpl_msg_error(__func__,
"Failed compute the Master Flat") ;
543 cpl_propertylist_delete(plist);
546 cpl_msg_indent_less() ;
549 cpl_msg_indent_less() ;
554 *master_flat = master_flat_loc ;
568static int cr2res_util_normflat_compare(
569 const cpl_frame * frame1,
570 const cpl_frame * frame2)
573 cpl_propertylist * plist1 ;
574 cpl_propertylist * plist2 ;
579 if (frame1==NULL || frame2==NULL)
return -1 ;
582 if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),0))==NULL){
583 cpl_msg_error(__func__,
"getting header from reference frame");
586 if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),0))==NULL){
587 cpl_msg_error(__func__,
"getting header from reference frame");
588 cpl_propertylist_delete(plist1) ;
593 if (cpl_error_get_code()) {
594 cpl_propertylist_delete(plist1) ;
595 cpl_propertylist_delete(plist2) ;
604 if (cpl_error_get_code()) {
605 cpl_msg_error(__func__,
"Cannot get the reference wavelength");
606 cpl_propertylist_delete(plist1) ;
607 cpl_propertylist_delete(plist2) ;
610 if (strcmp(sval1, sval2)) comparison = 0 ;
612 cpl_propertylist_delete(plist1) ;
613 cpl_propertylist_delete(plist2) ;
626static cpl_frameset * cr2res_util_normflat_find_RAW(
const cpl_frameset * in)
631 if (in == NULL)
return NULL ;
cpl_error_code cr2res_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
hdrl_image * cr2res_master_flat(const hdrl_image *collapsed, const hdrl_image *model_master, double low, double high, double bad_per_line_limit, cpl_image **bpm)
Compute the Master Flat.
cpl_frame * cr2res_io_find_SLIT_MODEL(const cpl_frameset *in, const char *setting_id, cr2res_decker decker)
Get the first CR2RES_SLIT_MODEL_DRSTYPE frame from a frameset.
cpl_frameset * cr2res_io_extract_decker_frameset(const cpl_frameset *in, const char *tag, cr2res_decker decker)
Extract the frames with the given tag and Decker position.
hdrl_image * cr2res_io_load_SLIT_MODEL(const char *filename, int detector)
Load an hdrl image from a SLIT MODEL.
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_save_MASTER_FLAT(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, hdrl_image **master_flats, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a MASTER_FLAT.
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_BPM(const char *filename, cpl_frameset *allframes, cpl_frameset *inframes, const cpl_parameterlist *parlist, cpl_image **bpms, const cpl_propertylist *qc_list, cpl_propertylist **ext_plist, const char *procatg, const char *recipe)
Save a BPM.
const char * cr2res_pfits_get_wlen_id(const cpl_propertylist *plist)
find out the Setting
int cr2res_format_setting(char *setting_id)
Format the setting.
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.
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.