40 #include "irplib_utils.h"
42 #include "hawki_utils.h"
43 #include "hawki_image_stats.h"
44 #include "hawki_load.h"
45 #include "hawki_save.h"
46 #include "hawki_pfits.h"
47 #include "hawki_dfs.h"
53 static int hawki_cal_flat_create(cpl_plugin *) ;
54 static int hawki_cal_flat_exec(cpl_plugin *) ;
55 static int hawki_cal_flat_destroy(cpl_plugin *) ;
56 static int hawki_cal_flat(cpl_parameterlist *, cpl_frameset *) ;
58 static int hawki_cal_flat_retrieve_input_param
59 (cpl_parameterlist * parlist);
60 static cpl_imagelist ** hawki_cal_flat_reduce(
61 cpl_frameset * flatframes,
62 const char * dark_file,
63 cpl_table ** raw_flat_stats,
64 cpl_table ** raw_flat_odd_column_stats,
65 cpl_table ** raw_flat_even_column_stats,
66 cpl_table ** raw_flat_odd_row_stats,
67 cpl_table ** raw_flat_even_row_stats,
68 cpl_vector ** selected);
69 static int hawki_cal_flat_clean_outliers(cpl_image *, cpl_imagelist *,
70 cpl_imagelist *, cpl_vector *, cpl_image **) ;
71 static int hawki_cal_flat_save
72 (cpl_imagelist ** flat,
73 cpl_table ** raw_flat_stats,
74 cpl_table ** raw_flat_odd_column_stats,
75 cpl_table ** raw_flat_even_column_stats,
76 cpl_table ** raw_flat_odd_row_stats,
77 cpl_table ** raw_flat_even_row_stats,
78 cpl_vector ** raw_selected,
80 const cpl_frame * bpmdark,
81 cpl_frameset * flatframes,
82 cpl_frameset * calibframes,
83 cpl_parameterlist * parlist,
84 cpl_frameset * set_tot);
85 static int hawki_cal_flat_compare(
const cpl_frame *,
const cpl_frame *) ;
86 static cpl_imagelist * hawki_cal_flat_merge_bpms
87 (
const cpl_frame * bpm_orig,
88 cpl_imagelist * bpm_to_add);
89 static int hawki_cal_flat_select
98 cpl_vector * selection);
99 static cpl_vector * hawki_cal_flat_extract_vector(cpl_vector *,
114 double sigma_badres ;
119 int select_auto_max_bins;
120 double select_min_level[HAWKI_NB_DETECTORS];
121 double select_max_level[HAWKI_NB_DETECTORS];
122 double select_max_rms[HAWKI_NB_DETECTORS];
123 int select_min_nframes ;
125 } hawki_cal_flat_config ;
129 int nb_badpix[HAWKI_NB_DETECTORS];
130 double norm[HAWKI_NB_DETECTORS];
131 double med_stdev[HAWKI_NB_DETECTORS];
132 double med_avg[HAWKI_NB_DETECTORS];
133 double med_med[HAWKI_NB_DETECTORS];
134 double med_min[HAWKI_NB_DETECTORS];
135 double med_max[HAWKI_NB_DETECTORS];
136 } hawki_cal_flat_outputs;
138 static char hawki_cal_flat_description[] =
139 "hawki_cal_flat -- HAWKĪI imaging flat-field creation from twillight images.\n"
140 "The input of the recipe files listed in the Set Of Frames (sof-file)\n"
141 "must be tagged as:\n"
142 "raw-file.fits "HAWKI_CAL_FLAT_RAW
" or\n"
143 "Optional inputs are:\n"
144 "bpmdark-file.fits "HAWKI_CALPRO_BPM_HOT
"\n"
145 "dark-file.fits "HAWKI_CALPRO_DARK
"\n"
146 "dark_err-file.fits "HAWKI_CALPRO_DARK_ERR
"\n"
147 "The recipe creates as an output:\n"
148 "hawki_cal_flat_setxx.fits ("HAWKI_CALPRO_FLAT
"): Master flat for filter xx\n"
149 "hawki_cal_flat_err_setxx.fits ("HAWKI_CALPRO_FLAT_ERRMAP
"): Master flat residuals\n"
150 "hawki_cal_flat_bpmflat_setxx.fits ("HAWKI_CALPRO_BPM_COLD
"): BPM from the flat\n"
151 "hawki_cal_flat_stats_setxx.fits ("HAWKI_CALPRO_FLAT_STATS
"): Stats of the individual flats\n"
152 "Optionally it also creates:\n"
153 "hawki_cal_flat_bpm_setxx.fits ("HAWKI_CALPRO_BPM
"): Bad pixel mask combining bpm from dark and flat\n"
154 "hawki_cal_flat_stats_ec_setxx.fits ("HAWKI_CALPRO_FLAT_STATS_EVEN_COL
"): Stats of the individual flats for even columns\n"
155 "hawki_cal_flat_stats_oc_setxx.fits ("HAWKI_CALPRO_FLAT_STATS_ODD_COL
"): Stats of the individual flats for odd columns\n"
156 "hawki_cal_flat_stats_er_setxx.fits ("HAWKI_CALPRO_FLAT_STATS_EVEN_ROW
"): Stats of the individual flats for even rows\n"
157 "hawki_cal_flat_stats_or_setxx.fits ("HAWKI_CALPRO_FLAT_STATS_ODD_ROW
"): Stats of the individual flats for odd rows\n"
159 "esorex exits with an error code of 0 if the recipe completes successfully\n"
179 int cpl_plugin_get_info(cpl_pluginlist * list)
181 cpl_recipe * recipe = cpl_calloc(1,
sizeof(*recipe)) ;
182 cpl_plugin * plugin = &recipe->interface ;
184 cpl_plugin_init(plugin,
186 HAWKI_BINARY_VERSION,
187 CPL_PLUGIN_TYPE_RECIPE,
189 "Twillight flat recipe",
190 hawki_cal_flat_description,
191 "Cesar Enrique Garcia Dabo",
194 hawki_cal_flat_create,
196 hawki_cal_flat_destroy) ;
198 cpl_pluginlist_append(list, plugin) ;
213 static int hawki_cal_flat_create(cpl_plugin * plugin)
215 cpl_recipe * recipe ;
219 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
220 recipe = (cpl_recipe *)plugin ;
224 recipe->parameters = cpl_parameterlist_new() ;
228 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.zone",
231 "hawki.hawki_cal_flat",
233 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"zone") ;
234 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
235 cpl_parameterlist_append(recipe->parameters, p) ;
238 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.normalise",
239 CPL_TYPE_BOOL,
"Flag to apply the normalisation",
240 "hawki.hawki_cal_flat", FALSE) ;
241 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"normalise") ;
242 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
243 cpl_parameterlist_append(recipe->parameters, p) ;
246 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.second_pass",
247 CPL_TYPE_BOOL,
"Flag to apply a second pass computation",
248 "hawki.hawki_cal_flat", TRUE) ;
249 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"second_pass") ;
250 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
251 cpl_parameterlist_append(recipe->parameters, p) ;
254 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.sigma_badres",
255 CPL_TYPE_DOUBLE,
"sigma for detection of bad flat results",
256 "hawki.hawki_cal_flat", 1.0) ;
257 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sigma_badres") ;
258 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
259 cpl_parameterlist_append(recipe->parameters, p) ;
262 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.sigma_bpm",
263 CPL_TYPE_DOUBLE,
"sigma for detection of bad pixels",
264 "hawki.hawki_cal_flat", 10.0) ;
265 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"sigma_bpm") ;
266 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
267 cpl_parameterlist_append(recipe->parameters, p) ;
270 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.lowval_bpm",
271 CPL_TYPE_DOUBLE,
"values of the flat below this will be included "
272 "in the bpm. In units of final flat (normalised if normalise is on)",
273 "hawki.hawki_cal_flat", .1) ;
274 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lowval_bpm") ;
275 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
276 cpl_parameterlist_append(recipe->parameters, p) ;
279 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.highval_bpm",
280 CPL_TYPE_DOUBLE,
"values of the flat above this will be included "
281 "in the bpm. In units of final flat (normalized if normalise is on)",
282 "hawki.hawki_cal_flat", 10.0) ;
283 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"highval_bpm") ;
284 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
285 cpl_parameterlist_append(recipe->parameters, p) ;
288 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.select_auto",
289 CPL_TYPE_BOOL,
"Flag to automatically select the good input frames",
290 "hawki.hawki_cal_flat", TRUE);
291 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"select_auto") ;
292 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
293 cpl_parameterlist_append(recipe->parameters, p) ;
296 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.select_auto_max_bins",
297 CPL_TYPE_INT,
"Maximum number of frames requested",
298 "hawki.hawki_cal_flat", 10) ;
299 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"select_auto_max_bins");
300 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
301 cpl_parameterlist_append(recipe->parameters, p) ;
304 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.select_min_level",
305 CPL_TYPE_STRING,
"Minimum ADU level for frames selection",
306 "hawki.hawki_cal_flat",
"-1.0") ;
307 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"select_min_level") ;
308 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
309 cpl_parameterlist_append(recipe->parameters, p) ;
312 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.select_max_level",
313 CPL_TYPE_STRING,
"Maximum ADU level for frames selection",
314 "hawki.hawki_cal_flat",
"25000");
315 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"select_max_level");
316 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
317 cpl_parameterlist_append(recipe->parameters, p);
320 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.select_max_rms",
321 CPL_TYPE_STRING,
"Maximum RMS for frames selection",
322 "hawki.hawki_cal_flat",
"4000");
323 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"select_max_rms");
324 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
325 cpl_parameterlist_append(recipe->parameters, p);
328 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.select_min_nframes",
329 CPL_TYPE_INT,
"Minimum number of frames requested",
330 "hawki.hawki_cal_flat", 3);
331 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"select_min_nframes") ;
332 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
333 cpl_parameterlist_append(recipe->parameters, p) ;
336 p = cpl_parameter_new_value(
"hawki.hawki_cal_flat.extra_stats",
337 CPL_TYPE_BOOL,
"Request for even/odd column/rows statistics",
338 "hawki.hawki_cal_flat", FALSE) ;
339 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"extra_stats") ;
340 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
341 cpl_parameterlist_append(recipe->parameters, p) ;
354 static int hawki_cal_flat_exec(cpl_plugin * plugin)
356 cpl_recipe * recipe ;
359 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
360 recipe = (cpl_recipe *)plugin ;
366 return hawki_cal_flat(recipe->parameters, recipe->frames) ;
376 static int hawki_cal_flat_destroy(cpl_plugin * plugin)
378 cpl_recipe * recipe ;
381 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
382 recipe = (cpl_recipe *)plugin ;
385 cpl_parameterlist_delete(recipe->parameters) ;
397 static int hawki_cal_flat(
398 cpl_parameterlist * parlist,
399 cpl_frameset * framelist)
403 cpl_frameset * flatframes ;
406 const char * dark_err;
407 const cpl_frame * bpmdark ;
408 cpl_imagelist ** twflat ;
409 cpl_table ** raw_flat_stats;
410 cpl_table ** raw_flat_odd_column_stats = NULL;
411 cpl_table ** raw_flat_even_column_stats = NULL;
412 cpl_table ** raw_flat_odd_row_stats = NULL;
413 cpl_table ** raw_flat_even_row_stats = NULL;
414 cpl_vector ** raw_selected;
417 cpl_errorstate error_prevstate = cpl_errorstate_get();
420 if(hawki_cal_flat_retrieve_input_param(parlist))
422 cpl_msg_error(__func__,
"Wrong parameters");
428 cpl_msg_error(__func__,
"Cannot identify RAW and CALIB frames") ;
434 HAWKI_CAL_FLAT_RAW)) == NULL) {
435 cpl_msg_error(__func__,
"Cannot find flat frames in the input list (%s)",
441 bpmdark = cpl_frameset_find_const(framelist, HAWKI_CALPRO_BPM_HOT);
446 labels = cpl_frameset_labelise(flatframes, hawki_cal_flat_compare,
448 if (labels == NULL) {
449 cpl_msg_error(__func__,
"Cannot labelise input frames") ;
450 cpl_frameset_delete(flatframes);
455 for (i=0 ; i<nlabels ; i++)
457 cpl_frameset * this_filter_flats;
460 cpl_msg_info(__func__,
"Reduce data set no %d out of %d", i+1, nlabels);
461 cpl_msg_indent_more() ;
462 this_filter_flats = cpl_frameset_extract(flatframes, labels, i) ;
463 nflats = cpl_frameset_get_size(this_filter_flats);
466 raw_flat_stats = cpl_malloc(HAWKI_NB_DETECTORS*
sizeof(cpl_table*));
467 raw_selected = cpl_malloc(HAWKI_NB_DETECTORS*
sizeof(cpl_vector*));
468 for (j=0 ; j<HAWKI_NB_DETECTORS ; j++)
470 raw_selected[j] = cpl_vector_new(nflats);
471 raw_flat_stats[j] = cpl_table_new(nflats);
475 if(hawki_cal_flat_config.extra_stats)
477 raw_flat_odd_column_stats =
478 cpl_malloc(HAWKI_NB_DETECTORS*
sizeof(cpl_table*));
479 raw_flat_even_column_stats =
480 cpl_malloc(HAWKI_NB_DETECTORS*
sizeof(cpl_table*));
481 raw_flat_odd_row_stats =
482 cpl_malloc(HAWKI_NB_DETECTORS*
sizeof(cpl_table*));
483 raw_flat_even_row_stats =
484 cpl_malloc(HAWKI_NB_DETECTORS*
sizeof(cpl_table*));
485 for (j=0 ; j<HAWKI_NB_DETECTORS ; j++)
487 raw_flat_odd_column_stats[j] = cpl_table_new(nflats);
488 raw_flat_even_column_stats[j] = cpl_table_new(nflats);
489 raw_flat_odd_row_stats[j] = cpl_table_new(nflats);
490 raw_flat_even_row_stats[j] = cpl_table_new(nflats);
500 if ((twflat = hawki_cal_flat_reduce
504 raw_flat_odd_column_stats,
505 raw_flat_even_column_stats,
506 raw_flat_odd_row_stats,
507 raw_flat_even_row_stats,
508 raw_selected)) == NULL)
510 for (j=0 ; j<HAWKI_NB_DETECTORS ; j++)
512 cpl_table_delete(raw_flat_stats[j]);
513 cpl_vector_delete(raw_selected[j]);
515 cpl_free(raw_flat_stats);
516 cpl_free(raw_selected);
517 if(hawki_cal_flat_config.extra_stats)
519 for (j=0 ; j<HAWKI_NB_DETECTORS ; j++)
521 cpl_table_delete(raw_flat_odd_column_stats[j]);
522 cpl_table_delete(raw_flat_even_column_stats[j]);
523 cpl_table_delete(raw_flat_odd_row_stats[j]);
524 cpl_table_delete(raw_flat_even_row_stats[j]);
526 cpl_free(raw_flat_odd_column_stats);
527 cpl_free(raw_flat_even_column_stats);
528 cpl_free(raw_flat_odd_row_stats);
529 cpl_free(raw_flat_even_row_stats);
531 cpl_frameset_delete(this_filter_flats);
532 cpl_frameset_delete(flatframes);
534 cpl_msg_error(__func__,
"Cannot reduce set nb %d", i+1) ;
539 cpl_frameset * calib_frames;
541 cpl_msg_info(__func__,
"Save the products") ;
542 calib_frames = cpl_frameset_new();
544 cpl_frameset_insert(calib_frames, cpl_frame_duplicate(bpmdark));
546 cpl_frameset_insert(calib_frames,
547 cpl_frame_duplicate(cpl_frameset_find_const(framelist,
548 HAWKI_CALPRO_DARK)));
550 cpl_frameset_insert(calib_frames,
551 cpl_frame_duplicate(cpl_frameset_find_const(framelist,
552 HAWKI_CALPRO_DARK_ERR)));
554 (twflat, raw_flat_stats,
555 raw_flat_odd_column_stats,
556 raw_flat_even_column_stats,
557 raw_flat_odd_row_stats,
558 raw_flat_even_row_stats,
560 i+1, bpmdark, this_filter_flats, calib_frames,
562 cpl_imagelist_delete(twflat[0]);
563 cpl_imagelist_delete(twflat[1]);
564 cpl_imagelist_delete(twflat[2]);
565 if (hawki_cal_flat_config.second_pass)
566 cpl_imagelist_delete(twflat[3]);
568 for (j=0 ; j<HAWKI_NB_DETECTORS ; j++)
570 cpl_table_delete(raw_flat_stats[j]);
571 cpl_vector_delete(raw_selected[j]);
573 cpl_free(raw_flat_stats);
574 cpl_free(raw_selected);
575 if(hawki_cal_flat_config.extra_stats)
577 for (j=0 ; j<HAWKI_NB_DETECTORS ; j++)
579 cpl_table_delete(raw_flat_odd_column_stats[j]);
580 cpl_table_delete(raw_flat_even_column_stats[j]);
581 cpl_table_delete(raw_flat_odd_row_stats[j]);
582 cpl_table_delete(raw_flat_even_row_stats[j]);
584 cpl_free(raw_flat_odd_column_stats);
585 cpl_free(raw_flat_even_column_stats);
586 cpl_free(raw_flat_odd_row_stats);
587 cpl_free(raw_flat_even_row_stats);
589 cpl_frameset_delete(calib_frames);
591 cpl_msg_indent_less();
592 cpl_frameset_delete(this_filter_flats);
595 if(!cpl_errorstate_is_equal(error_prevstate))
596 cpl_msg_warning(__func__,
"Probably some data could not be saved. "
597 "Check permisions or disk space");
601 cpl_frameset_delete(flatframes);
605 if (cpl_error_get_code())
return -1 ;
621 static cpl_imagelist ** hawki_cal_flat_reduce(
622 cpl_frameset * flatframes,
623 const char * dark_file,
624 cpl_table ** raw_flat_stats,
625 cpl_table ** raw_flat_odd_column_stats,
626 cpl_table ** raw_flat_even_column_stats,
627 cpl_table ** raw_flat_odd_row_stats,
628 cpl_table ** raw_flat_even_row_stats,
629 cpl_vector ** selected)
632 cpl_image * ima_cur ;
633 cpl_image * big_ima ;
634 cpl_image * big_badres ;
635 cpl_vector * medians[HAWKI_NB_DETECTORS];
636 cpl_vector * stdevs[HAWKI_NB_DETECTORS];
637 cpl_vector * sub_medians ;
638 cpl_imagelist * in_quad ;
639 cpl_imagelist ** results ;
640 cpl_imagelist * res_quad[4] ;
641 cpl_image * err_quad[4] ;
642 cpl_image * badres_mask[4] ;
643 cpl_image * flat_image ;
645 cpl_propertylist * plist;
653 if (flatframes == NULL)
return NULL ;
656 nima = cpl_frameset_get_size(flatframes) ;
658 cpl_msg_error(__func__,
"Not enough frames (%d)", nima) ;
661 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
662 hawki_cal_flat_outputs.norm[idet] = 1.0 ;
665 cpl_msg_info(__func__,
"Compute statistics") ;
666 cpl_msg_indent_more() ;
668 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
672 cpl_msg_info(__func__,
"Chip number %d", idet+1) ;
673 cpl_msg_info(__func__,
"image min max med rms") ;
674 cpl_msg_info(__func__,
"--------------------------------------------") ;
675 medians[idet] = cpl_vector_new(nima);
676 stdevs[idet] = cpl_vector_new(nima);
677 for (j=0 ; j<nima ; j++)
686 hawki_cal_flat_config.llx,
687 hawki_cal_flat_config.lly,
688 hawki_cal_flat_config.urx,
689 hawki_cal_flat_config.ury,
693 cpl_msg_error(__func__,
"Cannot compute stats on image %d",j+1);
694 cpl_msg_indent_less() ;
695 cpl_image_delete(ima_cur);
696 for (k=0 ; k<=idet ; k++) cpl_vector_delete(medians[k]) ;
697 for (k=0 ; k<=idet ; k++) cpl_vector_delete(stdevs[k]) ;
701 if(hawki_cal_flat_config.extra_stats)
703 if(hawki_image_stats_odd_even_column_row_fill_from_image
704 (raw_flat_odd_column_stats,
705 raw_flat_even_column_stats,
706 raw_flat_odd_row_stats,
707 raw_flat_even_row_stats,
712 cpl_msg_error(__func__,
"Cannot compute extra stats");
713 cpl_msg_indent_less() ;
714 cpl_image_delete(ima_cur);
715 for (k=0 ; k<=idet ; k++) cpl_vector_delete(medians[k]) ;
716 for (k=0 ; k<=idet ; k++) cpl_vector_delete(stdevs[k]) ;
720 cpl_vector_set(medians[idet], j, cpl_table_get_double
721 (raw_flat_stats[idet],HAWKI_COL_STAT_MED,j,NULL )) ;
722 cpl_vector_set(stdevs[idet], j, cpl_table_get_double
723 (raw_flat_stats[idet],HAWKI_COL_STAT_RMS,j,NULL )) ;
724 cpl_msg_info(__func__,
"%02d %10.2f %10.2f %10.2f %10.2f",
726 cpl_table_get_double(raw_flat_stats[idet],
727 HAWKI_COL_STAT_MIN,j,NULL ),
728 cpl_table_get_double(raw_flat_stats[idet],
729 HAWKI_COL_STAT_MAX,j,NULL ),
730 cpl_table_get_double(raw_flat_stats[idet],
731 HAWKI_COL_STAT_MED,j,NULL ),
732 cpl_table_get_double(raw_flat_stats[idet],
733 HAWKI_COL_STAT_RMS,j,NULL ));
734 if (cpl_table_get_double
735 (raw_flat_stats[idet],HAWKI_COL_STAT_MED,j,NULL ) < 1e-6)
737 cpl_msg_error(__func__,
"image %d has negative flux: aborting",
739 cpl_msg_indent_less() ;
740 for (k=0 ; k<=idet ; k++) cpl_vector_delete(medians[k]) ;
741 for (k=0 ; k<=idet ; k++) cpl_vector_delete(stdevs[k]) ;
744 cpl_image_delete(ima_cur);
746 cpl_msg_info(__func__,
"--------------------------------------------") ;
749 hawki_cal_flat_outputs.med_min[idet] =
750 cpl_vector_get_min(medians[idet]);
751 hawki_cal_flat_outputs.med_max[idet] =
752 cpl_vector_get_max(medians[idet]);
753 hawki_cal_flat_outputs.med_avg[idet] =
754 cpl_vector_get_mean(medians[idet]);
755 hawki_cal_flat_outputs.med_med[idet] =
756 cpl_vector_get_median_const(medians[idet]);
757 hawki_cal_flat_outputs.med_stdev[idet] =
758 cpl_vector_get_stdev(medians[idet]);
761 gradient=fabs(hawki_cal_flat_outputs.med_max[idet]/
762 hawki_cal_flat_outputs.med_min[idet]) ;
763 if (gradient < 4.0) {
767 cpl_msg_indent_less() ;
770 results = cpl_malloc(4 *
sizeof(cpl_imagelist*)) ;
771 results[0] = cpl_imagelist_new() ;
772 results[1] = cpl_imagelist_new() ;
773 results[2] = cpl_imagelist_new() ;
774 if (hawki_cal_flat_config.second_pass) results[3] = cpl_imagelist_new() ;
775 else results[3] = NULL ;
777 cpl_msg_info(__func__,
"Compute the flat") ;
778 cpl_msg_indent_more() ;
780 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
781 cpl_msg_info(__func__,
"Chip number %d", idet+1) ;
782 cpl_msg_indent_more() ;
785 cpl_msg_info(__func__,
"Apply the frames selection");
786 if ((hawki_cal_flat_select(medians[idet],
788 hawki_cal_flat_config.select_auto,
789 hawki_cal_flat_config.select_auto_max_bins,
790 hawki_cal_flat_config.select_min_level[idet],
791 hawki_cal_flat_config.select_max_level[idet],
792 hawki_cal_flat_config.select_max_rms[idet],
793 hawki_cal_flat_config.select_min_nframes,
794 selected[idet])) == -1)
796 cpl_msg_error(__func__,
"Cannot apply the frames selection") ;
797 cpl_imagelist_delete(results[0]) ;
798 cpl_imagelist_delete(results[1]) ;
799 cpl_imagelist_delete(results[2]) ;
800 if (hawki_cal_flat_config.second_pass)
801 cpl_imagelist_delete(results[3]) ;
803 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
804 cpl_vector_delete(medians[k]) ;
805 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
806 cpl_vector_delete(stdevs[k]) ;
811 sub_medians = hawki_cal_flat_extract_vector
812 (medians[idet], selected[idet]) ;
815 for (j=0 ; j<4 ; j++) {
818 CPL_TYPE_FLOAT))==NULL) {
819 cpl_msg_error(__func__,
"Cannot load the raw quadrants") ;
820 cpl_imagelist_delete(results[0]) ;
821 cpl_imagelist_delete(results[1]) ;
822 cpl_imagelist_delete(results[2]) ;
823 if (hawki_cal_flat_config.second_pass)
824 cpl_imagelist_delete(results[3]) ;
826 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
827 cpl_vector_delete(medians[k]) ;
828 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
829 cpl_vector_delete(stdevs[k]) ;
830 cpl_vector_delete(sub_medians) ;
835 cpl_imagelist_erase(in_quad, selected[idet]);
839 if (j==0) cpl_msg_info(__func__,
"Subtracting dark") ;
842 idet+1, j+1, CPL_TYPE_FLOAT)) == NULL) {
843 cpl_msg_error(__func__,
"Cannot load the dark quadrants") ;
844 cpl_imagelist_delete(in_quad) ;
845 cpl_imagelist_delete(results[0]) ;
846 cpl_imagelist_delete(results[1]) ;
847 cpl_imagelist_delete(results[2]) ;
848 if (hawki_cal_flat_config.second_pass)
849 cpl_imagelist_delete(results[3]) ;
851 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
852 cpl_vector_delete(medians[k]) ;
853 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
854 cpl_vector_delete(stdevs[k]) ;
855 cpl_vector_delete(sub_medians) ;
860 if ((plist=cpl_propertylist_load
861 (cpl_frame_get_filename
862 (cpl_frameset_get_first_const(flatframes)), 0)) == NULL)
864 cpl_msg_error(__func__,
"Cannot get header from frame");
865 cpl_imagelist_delete(in_quad) ;
866 cpl_imagelist_delete(results[0]) ;
867 cpl_imagelist_delete(results[1]) ;
868 cpl_imagelist_delete(results[2]) ;
869 if (hawki_cal_flat_config.second_pass)
870 cpl_imagelist_delete(results[3]) ;
872 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
873 cpl_vector_delete(medians[k]) ;
874 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
875 cpl_vector_delete(stdevs[k]) ;
876 cpl_vector_delete(sub_medians) ;
877 cpl_image_delete(dark);
881 cpl_image_multiply_scalar(dark, flat_dit);
882 cpl_propertylist_delete(plist);
885 cpl_imagelist_subtract_image(in_quad, dark) ;
886 cpl_image_delete(dark) ;
887 if (cpl_error_get_code() != CPL_ERROR_NONE) {
888 cpl_msg_warning(__func__,
"Cannot subtract the dark frame");
894 err_quad[j] = cpl_image_duplicate(cpl_imagelist_get(in_quad, 0)) ;
895 res_quad[j] = cpl_fit_imagelist_polynomial(sub_medians, in_quad,
896 0, 1, CPL_FALSE, CPL_TYPE_FLOAT, err_quad[j]) ;
897 if (res_quad[j] == NULL) {
898 cpl_msg_error(__func__,
"Cannot create twilight flat-field") ;
899 cpl_imagelist_delete(results[0]) ;
900 cpl_imagelist_delete(results[1]) ;
901 cpl_imagelist_delete(results[2]) ;
902 if (hawki_cal_flat_config.second_pass)
903 cpl_imagelist_delete(results[3]) ;
905 cpl_imagelist_delete(in_quad) ;
906 for (k=0 ; k<j ; k++) cpl_imagelist_delete(res_quad[k]) ;
907 for (k=0 ; k<=j ; k++) cpl_image_delete(err_quad[k]) ;
908 for (k=0 ; k<j ; k++)
909 if (badres_mask[k]) cpl_image_delete(badres_mask[k]) ;
910 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
911 cpl_vector_delete(medians[k]) ;
912 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
913 cpl_vector_delete(stdevs[k]) ;
914 cpl_vector_delete(sub_medians) ;
919 badres_mask[j] = NULL ;
920 if (hawki_cal_flat_config.second_pass) {
921 if (j==0) cpl_msg_info(__func__,
922 "Second pass to clean the outliers") ;
923 if (hawki_cal_flat_clean_outliers(err_quad[j], res_quad[j],
924 in_quad, sub_medians, &(badres_mask[j])) == -1) {
925 cpl_msg_error(__func__,
"Cannot clean the outliers") ;
926 cpl_imagelist_delete(results[0]) ;
927 cpl_imagelist_delete(results[1]) ;
928 cpl_imagelist_delete(results[2]) ;
929 cpl_imagelist_delete(results[3]) ;
931 cpl_imagelist_delete(in_quad) ;
932 for (k=0 ; k<=j ; k++) cpl_imagelist_delete(res_quad[k]) ;
933 for (k=0 ; k<=j ; k++) cpl_image_delete(err_quad[k]) ;
934 for (k=0 ; k<=j ; k++) cpl_image_delete(badres_mask[k]) ;
935 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
936 cpl_vector_delete(medians[k]) ;
937 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
938 cpl_vector_delete(stdevs[k]) ;
939 cpl_vector_delete(sub_medians) ;
940 cpl_msg_indent_less() ;
944 cpl_imagelist_delete(in_quad) ;
946 cpl_vector_delete(sub_medians) ;
951 cpl_imagelist_get(res_quad[0],1),
952 cpl_imagelist_get(res_quad[1],1),
953 cpl_imagelist_get(res_quad[2],1),
954 cpl_imagelist_get(res_quad[3],1)) ;
955 for (j=0 ; j<4 ; j++) cpl_imagelist_delete(res_quad[j]) ;
956 cpl_imagelist_set(results[0], big_ima, idet) ;
957 if (big_ima == NULL) {
958 cpl_msg_error(__func__,
"Cannot rebuild the image") ;
959 cpl_imagelist_delete(results[0]) ;
960 cpl_imagelist_delete(results[1]) ;
961 cpl_imagelist_delete(results[2]) ;
962 if (hawki_cal_flat_config.second_pass)
963 cpl_imagelist_delete(results[3]) ;
965 for (j=0 ; j<4 ; j++) cpl_image_delete(err_quad[j]) ;
966 for (j=0 ; j<4 ; j++)
967 if (badres_mask[j]) cpl_image_delete(badres_mask[j]) ;
968 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
969 cpl_vector_delete(medians[k]) ;
970 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
971 cpl_vector_delete(stdevs[k]) ;
977 err_quad[2], err_quad[3]) ;
978 for (j=0 ; j<4 ; j++) cpl_image_delete(err_quad[j]) ;
979 if (big_ima == NULL) {
980 cpl_msg_error(__func__,
"Cannot rebuild the image") ;
981 cpl_imagelist_delete(results[0]) ;
982 cpl_imagelist_delete(results[1]) ;
983 cpl_imagelist_delete(results[2]) ;
984 if (hawki_cal_flat_config.second_pass)
985 cpl_imagelist_delete(results[3]) ;
987 for (j=0 ; j<4 ; j++)
988 if (badres_mask[j]) cpl_image_delete(badres_mask[j]) ;
989 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
990 cpl_vector_delete(medians[k]) ;
991 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
992 cpl_vector_delete(stdevs[k]) ;
995 cpl_imagelist_set(results[1], big_ima, idet) ;
999 badres_mask[2], badres_mask[3]) ;
1000 if (hawki_cal_flat_config.second_pass) {
1001 for (j=0 ; j<4 ; j++) cpl_image_delete(badres_mask[j]) ;
1002 cpl_imagelist_set(results[3], big_badres, idet) ;
1005 if (hawki_cal_flat_config.normalise) {
1007 cpl_msg_info(__func__,
"Normalise the flat") ;
1008 flat_image = cpl_imagelist_get(results[0], idet) ;
1009 hawki_cal_flat_outputs.norm[idet] =
1010 cpl_image_get_median(flat_image) ;
1011 cpl_image_divide_scalar
1012 (flat_image, hawki_cal_flat_outputs.norm[idet]);
1013 if (cpl_error_get_code()) {
1014 cpl_msg_error(__func__,
"Cannot normalise") ;
1015 cpl_imagelist_delete(results[0]) ;
1016 cpl_imagelist_delete(results[1]) ;
1017 cpl_imagelist_delete(results[2]) ;
1018 if (hawki_cal_flat_config.second_pass)
1019 cpl_imagelist_delete(results[3]) ;
1021 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
1022 cpl_vector_delete(medians[k]) ;
1023 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++)
1024 cpl_vector_delete(stdevs[k]) ;
1030 cpl_msg_info(__func__,
"Compute the BPM from the flat") ;
1032 hawki_cal_flat_config.sigma_bpm,
1033 hawki_cal_flat_config.lowval_bpm,
1034 hawki_cal_flat_config.highval_bpm);
1036 cpl_imagelist_set(results[2], bpmflat, idet) ;
1037 hawki_cal_flat_outputs.nb_badpix[idet]=
1038 (int)cpl_image_get_flux(bpmflat);
1040 cpl_msg_indent_less() ;
1042 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++) cpl_vector_delete(medians[k]) ;
1043 for (k=0 ; k<HAWKI_NB_DETECTORS ; k++) cpl_vector_delete(stdevs[k]) ;
1044 cpl_msg_indent_less() ;
1060 static int hawki_cal_flat_clean_outliers(
1062 cpl_imagelist * fit_res,
1063 cpl_imagelist * raw,
1064 cpl_vector * medians,
1065 cpl_image ** recomp_mask)
1067 cpl_mask * recompute ;
1068 cpl_binary * precompute ;
1069 double med, stdev, threshold1, threshold2 ;
1070 int nx, ny, pos, nbad, nima, out, ind, pix ;
1071 cpl_image * cur_ima ;
1073 double val, fit_val, a, b, max ;
1074 cpl_vector * z_pix ;
1076 cpl_image * onepix ;
1077 cpl_vector * med_purged ;
1078 cpl_imagelist * raw_purged ;
1079 cpl_imagelist * fit_one ;
1080 cpl_image * err_one ;
1084 if (error == NULL)
return -1 ;
1085 if (fit_res == NULL)
return -1 ;
1086 if (raw == NULL)
return -1 ;
1089 if (recomp_mask) *recomp_mask = NULL ;
1092 med = cpl_image_get_median_dev(error, &stdev) ;
1093 threshold1 = med - hawki_cal_flat_config.sigma_badres * stdev ;
1094 threshold2 = med + hawki_cal_flat_config.sigma_badres * stdev ;
1095 recompute = cpl_mask_threshold_image_create(error,threshold1,threshold2) ;
1096 cpl_mask_not(recompute) ;
1098 if ((nbad=cpl_mask_count(recompute)) == 0) {
1100 *recomp_mask = cpl_image_new_from_mask(recompute) ;
1101 cpl_mask_delete(recompute) ;
1104 nx = cpl_image_get_size_x(error) ;
1105 ny = cpl_image_get_size_y(error) ;
1106 nima = cpl_imagelist_get_size(raw) ;
1109 precompute = cpl_mask_get_data(recompute) ;
1110 for (j=0 ; j<ny ; j++) {
1111 for (i=0 ; i<nx ; i++) {
1114 if (precompute[pos] == CPL_BINARY_1) {
1116 z_pix = cpl_vector_new(nima) ;
1117 for (k=0 ; k<nima ; k++) {
1118 cur_ima = cpl_imagelist_get(fit_res, 0) ;
1119 pimaf = cpl_image_get_data_float(cur_ima) ;
1121 cur_ima = cpl_imagelist_get(fit_res, 1) ;
1122 pimaf = cpl_image_get_data_float(cur_ima) ;
1124 med = cpl_vector_get(medians, k) ;
1125 fit_val = a + b * med ;
1126 cur_ima = cpl_imagelist_get(raw, k) ;
1127 pimaf = cpl_image_get_data_float(cur_ima) ;
1128 cpl_vector_set(z_pix, k, (
double)(pimaf[pos]-fit_val)) ;
1134 pz_pix = cpl_vector_get_data(z_pix) ;
1135 for (k=0 ; k<nima ; k++) {
1136 if (fabs(pz_pix[k]) > max) {
1137 max = fabs(pz_pix[k]) ;
1141 cpl_vector_delete(z_pix) ;
1144 med_purged = cpl_vector_new(nima-1) ;
1145 raw_purged = cpl_imagelist_new() ;
1147 for (k=0 ; k<nima ; k++) {
1150 cur_ima = cpl_imagelist_get(raw, k) ;
1151 onepix=cpl_image_extract(cur_ima, i+1, j+1, i+1, j+1) ;
1152 cpl_imagelist_set(raw_purged, onepix, ind) ;
1154 cpl_vector_set(med_purged, ind,
1155 cpl_vector_get(medians, k)) ;
1161 err_one = cpl_image_duplicate(cpl_imagelist_get(raw_purged,0));
1162 fit_one = cpl_fit_imagelist_polynomial(med_purged, raw_purged,
1163 0, 1, CPL_FALSE, CPL_TYPE_FLOAT, err_one) ;
1164 if (fit_one == NULL) {
1165 cpl_msg_error(__func__,
"Cannot fit in second pass") ;
1166 cpl_mask_delete(recompute) ;
1167 cpl_vector_delete(med_purged) ;
1168 cpl_imagelist_delete(raw_purged) ;
1169 cpl_image_delete(err_one) ;
1172 cpl_vector_delete(med_purged) ;
1173 cpl_imagelist_delete(raw_purged) ;
1176 val = cpl_image_get(err_one, 1, 1, &pix) ;
1177 cpl_image_set(error, i+1, j+1, val) ;
1178 cpl_image_delete(err_one) ;
1180 cur_ima = cpl_imagelist_get(fit_one, 0) ;
1181 val = cpl_image_get(cur_ima, 1, 1, &pix) ;
1182 cur_ima = cpl_imagelist_get(fit_res, 0) ;
1183 cpl_image_set(cur_ima, i+1, j+1, val) ;
1185 cur_ima = cpl_imagelist_get(fit_one, 1) ;
1186 val = cpl_image_get(cur_ima, 1, 1, &pix) ;
1187 cur_ima = cpl_imagelist_get(fit_res, 1) ;
1188 cpl_image_set(cur_ima, i+1, j+1, val) ;
1189 cpl_imagelist_delete(fit_one) ;
1194 *recomp_mask = cpl_image_new_from_mask(recompute) ;
1195 cpl_mask_delete(recompute) ;
1198 if (cpl_error_get_code())
return -1 ;
1215 static int hawki_cal_flat_save
1216 (cpl_imagelist ** flat,
1217 cpl_table ** raw_flat_stats,
1218 cpl_table ** raw_flat_odd_column_stats,
1219 cpl_table ** raw_flat_even_column_stats,
1220 cpl_table ** raw_flat_odd_row_stats,
1221 cpl_table ** raw_flat_even_row_stats,
1222 cpl_vector ** raw_selected,
1224 const cpl_frame * bpmdark,
1225 cpl_frameset * flat_frames,
1226 cpl_frameset * calib_frames,
1227 cpl_parameterlist * parlist,
1228 cpl_frameset * set_tot)
1230 cpl_propertylist ** qclists ;
1231 cpl_imagelist * bpm ;
1232 const cpl_frame * ref_frame ;
1233 cpl_frameset * used_frames;
1235 cpl_propertylist * inputlist ;
1237 const char * recipe_name =
"hawki_cal_flat" ;
1245 ref_frame = irplib_frameset_get_first_from_group(flat_frames, CPL_FRAME_GROUP_RAW) ;
1248 qclists = cpl_malloc(HAWKI_NB_DETECTORS *
sizeof(cpl_propertylist*)) ;
1249 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
1250 qclists[i] = cpl_propertylist_new() ;
1253 nflat = cpl_vector_get_size(raw_selected[i]);
1255 for(iflat = 0; iflat < nflat; ++iflat)
1257 snprintf(key_name, 72,
"ESO QC RAW%02d USED", iflat + 1);
1258 cpl_propertylist_append_bool
1259 (qclists[i], key_name,
1260 (cpl_vector_get(raw_selected[i], iflat) + 1) / 2);
1262 (raw_flat_stats[i],HAWKI_COL_STAT_USED, iflat,
1263 cpl_vector_get(raw_selected[i], iflat));
1264 if(hawki_cal_flat_config.extra_stats)
1267 (raw_flat_odd_column_stats[i],HAWKI_COL_STAT_USED, iflat,
1268 cpl_vector_get(raw_selected[i], iflat));
1270 (raw_flat_even_column_stats[i],HAWKI_COL_STAT_USED, iflat,
1271 cpl_vector_get(raw_selected[i], iflat));
1273 (raw_flat_odd_row_stats[i],HAWKI_COL_STAT_USED, iflat,
1274 cpl_vector_get(raw_selected[i], iflat));
1276 (raw_flat_even_row_stats[i],HAWKI_COL_STAT_USED, iflat,
1277 cpl_vector_get(raw_selected[i], iflat));
1279 if(cpl_vector_get(raw_selected[i], iflat) == 1)
1284 cpl_propertylist_append_int(qclists[i],
"ESO QC FLAT NBADPIX",
1285 hawki_cal_flat_outputs.nb_badpix[i]);
1286 cpl_propertylist_append_double(qclists[i],
"ESO QC FLAT NORM",
1287 hawki_cal_flat_outputs.norm[i]) ;
1288 cpl_propertylist_append_double(qclists[i],
"ESO QC FLAT MEDMEAN",
1289 hawki_cal_flat_outputs.med_avg[i]) ;
1290 cpl_propertylist_append_double(qclists[i],
"ESO QC FLAT MEDMED",
1291 hawki_cal_flat_outputs.med_med[i]) ;
1292 cpl_propertylist_append_double(qclists[i],
"ESO QC FLAT MEDSTDEV",
1293 hawki_cal_flat_outputs.med_stdev[i]) ;
1294 cpl_propertylist_append_double(qclists[i],
"ESO QC FLAT MEDMIN",
1295 hawki_cal_flat_outputs.med_min[i]) ;
1296 cpl_propertylist_append_double(qclists[i],
"ESO QC FLAT MEDMAX",
1297 hawki_cal_flat_outputs.med_max[i]) ;
1298 cpl_propertylist_append_double(qclists[i],
"ESO QC FLAT MEDRANG",
1299 hawki_cal_flat_outputs.med_max[i] -
1300 hawki_cal_flat_outputs.med_min[i]);
1301 cpl_propertylist_append_double(qclists[i],
"ESO QC FLAT MEDNRANG",
1302 (hawki_cal_flat_outputs.med_max[i] -
1303 hawki_cal_flat_outputs.med_min[i]) /
1304 hawki_cal_flat_outputs.med_med[i]);
1305 cpl_propertylist_append_int(qclists[i],
"ESO QC DATANCOM",
1310 cpl_frame_get_filename(ref_frame), i+1);
1311 inputlist = cpl_propertylist_load_regexp(
1312 cpl_frame_get_filename(ref_frame), ext_nb,
1313 HAWKI_HEADER_EXT_FORWARD, 0) ;
1314 cpl_propertylist_append(qclists[i], inputlist) ;
1317 cpl_propertylist_delete(inputlist) ;
1323 used_frames = cpl_frameset_duplicate(flat_frames);
1324 for(i = 0; i< cpl_frameset_get_size(calib_frames); ++i)
1325 cpl_frameset_insert(used_frames,
1326 cpl_frame_duplicate(cpl_frameset_get_frame(calib_frames, i)));
1329 filename = cpl_sprintf(
"hawki_cal_flat_set%02d.fits", set_nb) ;
1338 (
const cpl_propertylist**)qclists,
1340 cpl_free(filename) ;
1343 filename = cpl_sprintf(
"hawki_cal_flat_err_set%02d.fits", set_nb) ;
1349 HAWKI_CALPRO_FLAT_ERRMAP,
1350 HAWKI_PROTYPE_ERRMAP,
1352 (
const cpl_propertylist**)qclists,
1354 cpl_free(filename) ;
1357 filename = cpl_sprintf(
"hawki_cal_flat_bpmflat_set%02d.fits", set_nb) ;
1363 HAWKI_CALPRO_BPM_COLD,
1366 (
const cpl_propertylist**)qclists,
1368 cpl_free(filename) ;
1370 if (flat[3] != NULL) {
1372 filename=cpl_sprintf(
"hawki_cal_flat_recomputed_set%02d.fits", set_nb) ;
1378 HAWKI_CALPRO_FLAT_RECOMPUTED,
1381 (
const cpl_propertylist**)qclists,
1383 cpl_free(filename) ;
1387 if (bpmdark != NULL) {
1388 if ((bpm = hawki_cal_flat_merge_bpms(bpmdark, flat[2])) == NULL) {
1389 cpl_msg_error(__func__,
"Cannot merge bad pixel maps") ;
1391 filename=cpl_sprintf(
"hawki_cal_flat_bpm_set%02d.fits", set_nb) ;
1401 (
const cpl_propertylist**)qclists,
1403 cpl_free(filename) ;
1404 cpl_imagelist_delete(bpm) ;
1407 cpl_frameset_delete(used_frames);
1410 used_frames = cpl_frameset_duplicate(flat_frames);
1413 filename = cpl_sprintf(
"hawki_cal_flat_stats_set%02d.fits", set_nb) ;
1417 (
const cpl_table **)raw_flat_stats,
1419 HAWKI_CALPRO_FLAT_STATS,
1420 HAWKI_PROTYPE_FLAT_STATS,
1422 (
const cpl_propertylist **)qclists,
1424 cpl_free(filename) ;
1426 if(hawki_cal_flat_config.extra_stats)
1428 filename = cpl_sprintf(
"hawki_cal_flat_stats_ec_set%02d.fits", set_nb);
1432 (
const cpl_table **)raw_flat_even_column_stats,
1434 HAWKI_CALPRO_FLAT_STATS_EVEN_COL,
1435 HAWKI_PROTYPE_FLAT_STATS_EVEN_COL,
1437 (
const cpl_propertylist **)qclists,
1439 cpl_free(filename) ;
1440 filename = cpl_sprintf(
"hawki_cal_flat_stats_oc_set%02d.fits", set_nb);
1444 (
const cpl_table **)raw_flat_odd_column_stats,
1446 HAWKI_CALPRO_FLAT_STATS_ODD_COL,
1447 HAWKI_PROTYPE_FLAT_STATS_ODD_COL,
1449 (
const cpl_propertylist **)qclists,
1451 cpl_free(filename) ;
1452 filename = cpl_sprintf(
"hawki_cal_flat_stats_er_set%02d.fits", set_nb);
1456 (
const cpl_table **)raw_flat_even_row_stats,
1458 HAWKI_CALPRO_FLAT_STATS_EVEN_ROW,
1459 HAWKI_PROTYPE_FLAT_STATS_EVEN_ROW,
1461 (
const cpl_propertylist **)qclists,
1463 cpl_free(filename) ;
1464 filename = cpl_sprintf(
"hawki_cal_flat_stats_or_set%02d.fits", set_nb);
1468 (
const cpl_table **)raw_flat_odd_row_stats,
1470 HAWKI_CALPRO_FLAT_STATS_ODD_ROW,
1471 HAWKI_PROTYPE_FLAT_STATS_ODD_ROW,
1473 (
const cpl_propertylist **)qclists,
1475 cpl_free(filename) ;
1477 cpl_frameset_delete(used_frames);
1480 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
1481 cpl_propertylist_delete(qclists[i]) ;
1484 if (cpl_error_get_code())
return -1 ;
1496 static int hawki_cal_flat_compare(
1497 const cpl_frame * frame1,
1498 const cpl_frame * frame2)
1501 cpl_propertylist * plist1 ;
1502 cpl_propertylist * plist2 ;
1505 double dval1, dval2 ;
1509 if (frame1==NULL || frame2==NULL)
return -1 ;
1512 if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),
1514 cpl_msg_error(__func__,
"getting header from reference frame");
1517 if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),
1519 cpl_msg_error(__func__,
"getting header from reference frame");
1520 cpl_propertylist_delete(plist1) ;
1525 if (cpl_error_get_code()) {
1526 cpl_propertylist_delete(plist1) ;
1527 cpl_propertylist_delete(plist2) ;
1536 if (cpl_error_get_code()) {
1537 cpl_msg_error(__func__,
"cannot get the filter");
1538 cpl_propertylist_delete(plist1) ;
1539 cpl_propertylist_delete(plist2) ;
1542 if (strcmp(sval1, sval2)) comparison = 0 ;
1547 if (cpl_error_get_code()) {
1548 cpl_msg_error(__func__,
"cannot get the DIT");
1549 cpl_propertylist_delete(plist1) ;
1550 cpl_propertylist_delete(plist2) ;
1553 if (fabs(dval1-dval2) > 1e-4) comparison = 0 ;
1555 cpl_propertylist_delete(plist1) ;
1556 cpl_propertylist_delete(plist2) ;
1568 static cpl_imagelist * hawki_cal_flat_merge_bpms
1569 (
const cpl_frame * bpm_orig,
1570 cpl_imagelist * bpm_to_merge)
1572 cpl_imagelist * merged ;
1573 cpl_imagelist * bpm_orig_im;
1578 if (bpm_orig==NULL || bpm_to_merge ==NULL)
return NULL ;
1581 merged = cpl_imagelist_new() ;
1585 if(bpm_orig_im == NULL)
1587 cpl_msg_error(__func__,
"Cannot read existing bpm %s",
1588 cpl_frame_get_filename(bpm_orig));
1589 cpl_imagelist_delete(merged);
1594 for (i=0 ; i<HAWKI_NB_DETECTORS ; i++) {
1597 tmp = cpl_image_add_create(cpl_imagelist_get(bpm_orig_im, i),
1598 cpl_imagelist_get(bpm_to_merge, i));
1599 cpl_image_multiply(cpl_imagelist_get(bpm_orig_im, i),
1600 cpl_imagelist_get(bpm_to_merge, i));
1601 cpl_image_subtract(tmp, cpl_imagelist_get(bpm_orig_im, i)) ;
1604 cpl_imagelist_set(merged, tmp, i) ;
1608 cpl_imagelist_delete(bpm_orig_im);
1624 static int hawki_cal_flat_select
1633 cpl_vector * selection)
1635 double * pselection ;
1640 double first_val, last_val, bin_val, dist, dist_min;
1643 int nbins, ind_closest ;
1648 if (meds == NULL)
return -1;
1649 if (rms == NULL)
return -1;
1650 if (selection == NULL)
return -1;
1651 if(cpl_vector_get_size(meds) != cpl_vector_get_size(selection))
1653 cpl_msg_error(__func__,
1654 "The meds and selection vectors have not the same size");
1659 nvals = cpl_vector_get_size(meds);
1660 pmeds = cpl_vector_get_data(meds);
1661 prms = cpl_vector_get_data(rms);
1662 cpl_vector_fill(selection, 1.0);
1665 pselection = cpl_vector_get_data(selection) ;
1668 if (min_level >= 0.0)
1670 for (ival=0 ; ival<nvals ; ival++)
1672 if (pmeds[ival] < min_level)
1673 pselection[ival] = -1.0 ;
1678 if (max_level >= 0.0)
1680 for (ival=0 ; ival<nvals ; ival++)
1682 if (pmeds[ival] > max_level)
1683 pselection[ival] = -1.0 ;
1690 for (ival=0 ; ival<nvals ; ival++)
1692 if (prms[ival] > max_rms)
1693 pselection[ival] = -1.0 ;
1701 cpl_vector * auto_selection;
1702 auto_selection = cpl_vector_new(nvals);
1703 cpl_vector_fill(auto_selection, -1.0);
1704 cpl_msg_info(__func__,
"Automatic dynamic range selection");
1709 if (auto_max_bins > 0 && auto_max_bins < nvals) nbins = auto_max_bins;
1710 for (ibin=0 ; ibin<nbins ; ibin++)
1713 bin_val = first_val + (last_val-first_val)*(ibin+1)/nbins ;
1714 else if(ibin == nbins - 1)
1715 bin_val = first_val + (last_val-first_val)*(ibin)/nbins ;
1717 bin_val = first_val + (last_val-first_val)*(ibin+0.5)/nbins ;
1718 bin_low_val = first_val + (last_val-first_val)*(ibin)/nbins ;
1719 bin_up_val = first_val + (last_val-first_val)*(ibin+1)/nbins ;
1722 dist_min = fabs(pmeds[0] - bin_val) ;
1724 for (ival=0 ; ival<nvals ; ival++)
1726 dist = fabs(pmeds[ival] - bin_val) ;
1727 if (dist < dist_min && pselection[ival] != -1)
1733 if(ind_closest != -1)
1734 cpl_vector_set(auto_selection, ind_closest, 1.0);
1737 cpl_vector_copy(selection, auto_selection);
1738 cpl_vector_delete(auto_selection);
1743 cpl_msg_indent_more();
1744 for (ival=0 ; ival<nvals ; ival++)
1746 if(pselection[ival] != -1)
1748 cpl_msg_info(__func__,
"Selected frame %d", ival+1) ;
1752 cpl_msg_indent_less();
1756 cpl_msg_error(__func__,
"No frame selected. Check selection criteria");
1759 if (min_nframes >= 0) {
1760 if (nsel < min_nframes) {
1761 cpl_msg_error(__func__,
"Not enough selected frames (%d < %d)",
1762 nsel, min_nframes) ;
1778 static cpl_vector * hawki_cal_flat_extract_vector(
1780 cpl_vector * selection)
1783 cpl_vector * selected ;
1785 double * pselection ;
1786 double * pselected ;
1791 if (in == NULL)
return NULL ;
1792 if (selection == NULL)
return NULL ;
1795 nvals = cpl_vector_get_size(in) ;
1797 pin = cpl_vector_get_data(in) ;
1798 pselection = cpl_vector_get_data(selection) ;
1801 if (nvals != cpl_vector_get_size(selection))
return NULL ;
1804 for (i=0 ; i<nvals ; i++) {
1805 if (pselection[i] > 0.0) nselected++ ;
1807 if (nselected == 0)
return NULL ;
1810 selected = cpl_vector_new(nselected) ;
1811 pselected = cpl_vector_get_data(selected) ;
1814 for (i=0 ; i<nvals ; i++) {
1815 if (pselection[i] > 0.0) {
1816 pselected[nselected] = pin[i] ;
1823 static int hawki_cal_flat_retrieve_input_param
1824 (cpl_parameterlist * parlist)
1827 cpl_parameter * par;
1832 for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
1833 hawki_cal_flat_outputs.nb_badpix[idet] = -1 ;
1834 hawki_cal_flat_outputs.med_stdev[idet] = -1.0 ;
1835 hawki_cal_flat_outputs.med_avg[idet] = -1.0 ;
1836 hawki_cal_flat_outputs.med_med[idet] = -1.0 ;
1837 hawki_cal_flat_outputs.med_min[idet] = -1.0 ;
1838 hawki_cal_flat_outputs.med_max[idet] = -1.0 ;
1842 par = cpl_parameterlist_find(parlist,
"hawki.hawki_cal_flat.zone") ;
1843 sval = cpl_parameter_get_string(par) ;
1844 if (sscanf(sval,
"%d,%d,%d,%d",
1845 &hawki_cal_flat_config.llx,
1846 &hawki_cal_flat_config.lly,
1847 &hawki_cal_flat_config.urx,
1848 &hawki_cal_flat_config.ury)!=4)
1852 par = cpl_parameterlist_find(parlist,
"hawki.hawki_cal_flat.sigma_badres") ;
1853 hawki_cal_flat_config.sigma_badres = cpl_parameter_get_double(par) ;
1854 par = cpl_parameterlist_find(parlist,
"hawki.hawki_cal_flat.sigma_bpm") ;
1855 hawki_cal_flat_config.sigma_bpm = cpl_parameter_get_double(par) ;
1856 par = cpl_parameterlist_find(parlist,
"hawki.hawki_cal_flat.lowval_bpm") ;
1857 hawki_cal_flat_config.lowval_bpm = cpl_parameter_get_double(par) ;
1858 par = cpl_parameterlist_find(parlist,
"hawki.hawki_cal_flat.highval_bpm") ;
1859 hawki_cal_flat_config.highval_bpm = cpl_parameter_get_double(par) ;
1860 par = cpl_parameterlist_find(parlist,
"hawki.hawki_cal_flat.normalise") ;
1861 hawki_cal_flat_config.normalise = cpl_parameter_get_bool(par) ;
1862 par = cpl_parameterlist_find(parlist,
"hawki.hawki_cal_flat.second_pass") ;
1863 hawki_cal_flat_config.second_pass = cpl_parameter_get_bool(par) ;
1864 par = cpl_parameterlist_find(parlist,
"hawki.hawki_cal_flat.select_auto") ;
1865 hawki_cal_flat_config.select_auto = cpl_parameter_get_bool(par) ;
1866 par = cpl_parameterlist_find(parlist,
1867 "hawki.hawki_cal_flat.select_auto_max_bins") ;
1868 hawki_cal_flat_config.select_auto_max_bins = cpl_parameter_get_int(par);
1869 par = cpl_parameterlist_find(parlist,
1870 "hawki.hawki_cal_flat.select_min_level") ;
1871 sval = cpl_parameter_get_string(par);
1872 if (sscanf(sval,
"%lf,%lf,%lf,%lf",
1873 &hawki_cal_flat_config.select_min_level[0],
1874 &hawki_cal_flat_config.select_min_level[1],
1875 &hawki_cal_flat_config.select_min_level[2],
1876 &hawki_cal_flat_config.select_min_level[3])!=4)
1878 if (sscanf(sval,
"%f", &hawki_cal_flat_config.select_min_level[0])!=1)
1884 hawki_cal_flat_config.select_min_level[1] =
1885 hawki_cal_flat_config.select_min_level[0];
1886 hawki_cal_flat_config.select_min_level[2] =
1887 hawki_cal_flat_config.select_min_level[0];
1888 hawki_cal_flat_config.select_min_level[3] =
1889 hawki_cal_flat_config.select_min_level[0];
1892 par = cpl_parameterlist_find(parlist,
1893 "hawki.hawki_cal_flat.select_max_level") ;
1894 sval = cpl_parameter_get_string(par);
1895 if (sscanf(sval,
"%lf,%lf,%lf,%lf",
1896 &hawki_cal_flat_config.select_max_level[0],
1897 &hawki_cal_flat_config.select_max_level[1],
1898 &hawki_cal_flat_config.select_max_level[2],
1899 &hawki_cal_flat_config.select_max_level[3])!=4)
1901 if (sscanf(sval,
"%f", &hawki_cal_flat_config.select_max_level[0])!=1)
1907 hawki_cal_flat_config.select_max_level[1] =
1908 hawki_cal_flat_config.select_max_level[0];
1909 hawki_cal_flat_config.select_max_level[2] =
1910 hawki_cal_flat_config.select_max_level[0];
1911 hawki_cal_flat_config.select_max_level[3] =
1912 hawki_cal_flat_config.select_max_level[0];
1915 par = cpl_parameterlist_find(parlist,
1916 "hawki.hawki_cal_flat.select_max_rms") ;
1917 sval = cpl_parameter_get_string(par);
1918 if (sscanf(sval,
"%lf,%lf,%lf,%lf",
1919 hawki_cal_flat_config.select_max_rms,
1920 hawki_cal_flat_config.select_max_rms+1,
1921 hawki_cal_flat_config.select_max_rms+2,
1922 hawki_cal_flat_config.select_max_rms+3)!=4)
1924 if (sscanf(sval,
"%f", &hawki_cal_flat_config.select_max_rms[0])!=1)
1930 hawki_cal_flat_config.select_max_rms[1] =
1931 hawki_cal_flat_config.select_max_rms[0];
1932 hawki_cal_flat_config.select_max_rms[2] =
1933 hawki_cal_flat_config.select_max_rms[0];
1934 hawki_cal_flat_config.select_max_rms[3] =
1935 hawki_cal_flat_config.select_max_rms[0];
1938 par = cpl_parameterlist_find(parlist,
1939 "hawki.hawki_cal_flat.select_min_nframes") ;
1940 hawki_cal_flat_config.select_min_nframes = cpl_parameter_get_int(par) ;
1941 par = cpl_parameterlist_find(parlist,
"hawki.hawki_cal_flat.extra_stats") ;
1942 hawki_cal_flat_config.extra_stats = cpl_parameter_get_bool(par) ;
1944 if(hawki_cal_flat_config.select_auto_max_bins != -1 &&
1945 !hawki_cal_flat_config.select_auto)
1947 cpl_msg_error(__func__,
"Max bins is only allowed with select_auto");