40 #include "gravi_calib.h"
41 #include "gravi_utils.h"
42 #include "gravi_pfits.h"
43 #include "gravi_dfs.h"
45 #include "gravi_data.h"
52 static int gravi_all_flat_create(cpl_plugin *);
53 static int gravi_all_flat_exec(cpl_plugin *);
54 static int gravi_all_flat_destroy(cpl_plugin *);
55 static int gravi_all_flat(cpl_frameset *,
const cpl_parameterlist *);
61 static char gravi_all_flat_description[] =
62 "It produces the master flat containing : \n"
63 " - the profile of each spectrum of the SC beam combiner,\n"
64 " - the mean spectrum for SC and FT.\n"
65 "This recipe also produces a bad pixel map, where each pixels where \n"
66 "Dark_rms > rms(Dark_rms_i)*bad-dark-threshold are flag as 1.\n"
68 "Description DO category\n"
70 " Raw flat file (4 files) " GRAVI_FLAT
"\n"
71 " Raw dark file " GRAVI_DARK
"\n"
73 " Master dark " DARK
"\n"
74 " Bad pixel map " BAD
"\n"
76 " Profile map " FLAT
"\n"
77 " Bad pixel map " BAD
"\n"
95 int cpl_plugin_get_info(cpl_pluginlist * list)
97 cpl_recipe * recipe = cpl_calloc(1,
sizeof *recipe );
98 cpl_plugin * plugin = &recipe->interface;
100 if (cpl_plugin_init(plugin,
102 GRAVI_BINARY_VERSION,
103 CPL_PLUGIN_TYPE_RECIPE,
105 "This recipe is used to reduce the flat data.",
106 gravi_all_flat_description,
107 "Firstname Lastname",
110 gravi_all_flat_create,
112 gravi_all_flat_destroy)) {
113 cpl_msg_error(cpl_func,
"Plugin initialization failed");
114 (void)cpl_error_set_where(cpl_func);
118 if (cpl_pluginlist_append(list, plugin)) {
119 cpl_msg_error(cpl_func,
"Error adding plugin to list");
120 (void)cpl_error_set_where(cpl_func);
136 static int gravi_all_flat_create(cpl_plugin * plugin)
142 if (cpl_error_get_code() != CPL_ERROR_NONE) {
143 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
144 cpl_func, __LINE__, cpl_error_get_where());
145 return (
int)cpl_error_get_code();
148 if (plugin == NULL) {
149 cpl_msg_error(cpl_func,
"Null plugin");
150 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
154 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
155 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
156 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
160 recipe = (cpl_recipe *)plugin;
163 recipe->parameters = cpl_parameterlist_new();
164 if (recipe->parameters == NULL) {
165 cpl_msg_error(cpl_func,
"Parameter list allocation failed");
166 cpl_ensure_code(0, (
int)CPL_ERROR_ILLEGAL_OUTPUT);
171 p = cpl_parameter_new_value(
"gravi.gravi_all_flat."
172 "profile_width", CPL_TYPE_INT,
"Width on which the "
173 "spectral element is fitted (High Resolution mode)",
174 "gravi.gravi_all_flat", 6);
175 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"profile-width");
176 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
177 cpl_parameterlist_append(recipe->parameters, p);
179 p = cpl_parameter_new_value(
"gravi."
180 "flat_param.Bad_dark_threshold", CPL_TYPE_INT,
"Rms noise "
181 "factor for bad pixel detection",
"gravi.gravi_all_flat", 10);
182 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"bad-dark-threshold");
183 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
184 cpl_parameterlist_append(recipe->parameters, p);
197 static int gravi_all_flat_exec(cpl_plugin * plugin)
202 cpl_errorstate initial_errorstate = cpl_errorstate_get();
205 if (cpl_error_get_code() != CPL_ERROR_NONE) {
206 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
207 cpl_func, __LINE__, cpl_error_get_where());
208 return (
int)cpl_error_get_code();
211 if (plugin == NULL) {
212 cpl_msg_error(cpl_func,
"Null plugin");
213 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
217 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
218 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
219 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
223 recipe = (cpl_recipe *)plugin;
226 if (recipe->parameters == NULL) {
227 cpl_msg_error(cpl_func,
"Recipe invoked with NULL parameter list");
228 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
230 if (recipe->frames == NULL) {
231 cpl_msg_error(cpl_func,
"Recipe invoked with NULL frame set");
232 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
236 recipe_status = gravi_all_flat(recipe->frames, recipe->parameters);
239 if (cpl_dfs_update_product_header(recipe->frames)) {
240 if (!recipe_status) recipe_status = (int)cpl_error_get_code();
243 if (!cpl_errorstate_is_equal(initial_errorstate)) {
246 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
249 return recipe_status;
259 static int gravi_all_flat_destroy(cpl_plugin * plugin)
263 if (plugin == NULL) {
264 cpl_msg_error(cpl_func,
"Null plugin");
265 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
269 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
270 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
271 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
275 recipe = (cpl_recipe *)plugin;
277 cpl_parameterlist_delete(recipe->parameters);
291 static int gravi_all_flat(cpl_frameset * frameset,
292 const cpl_parameterlist * parlist)
294 cpl_frameset * flat_frameset, * dark_frameset, * darkcalib_frameset, * badpix_frameset;
295 cpl_propertylist * applist, * primary_hdr, * bad_primary_hdr;
296 cpl_frame * frame, *_frame;
297 const char * filename, * filename_, * temp;
299 gravi_data * profile_map, * dark_file, * dark_map, * bad_map;
300 gravi_data ** flat_data;
301 double gain_ft, gain_sc;
305 cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
306 cpl_error_get_code()) ;
309 flat_frameset = gravi_frameset_extract_flat(frameset);
310 darkcalib_frameset = gravi_frameset_extract_dark_file(frameset);
311 dark_frameset = gravi_frameset_extract_dark(frameset);
312 badpix_frameset = gravi_frameset_extract_badpix(frameset);
313 if (cpl_frameset_is_empty(flat_frameset) ||
314 ((cpl_frameset_is_empty(dark_frameset)) &&
315 cpl_frameset_is_empty(darkcalib_frameset))) {
318 cpl_frameset_delete(flat_frameset);
319 cpl_frameset_delete(dark_frameset);
320 cpl_frameset_delete(darkcalib_frameset);
321 cpl_frameset_delete(badpix_frameset);
322 return (
int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
323 "No dark or flat frame on the inputs frameset") ;
353 nb_frame = cpl_frameset_get_size(flat_frameset);
356 cpl_frameset_delete(flat_frameset);
357 cpl_frameset_delete(dark_frameset);
358 cpl_frameset_delete(darkcalib_frameset);
359 cpl_frameset_delete(badpix_frameset);
360 return (
int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
361 "The number of flat frames must be more than 4");
365 if (!cpl_frameset_is_empty(dark_frameset)){
366 _frame = cpl_frameset_get_position(dark_frameset, 0);
367 filename_ = cpl_frame_get_filename(_frame);
368 temp = strrchr(filename_,
'/');
369 filename = temp ? temp + 1 : filename_;
370 cpl_msg_info (cpl_func,
"This file %s is a dark file", filename);
372 dark_file = gravi_data_load(filename_);
373 dark_map = gravi_compute_dark(dark_file);
375 gravi_data_delete(dark_file);
377 else if (!cpl_frameset_is_empty(darkcalib_frameset)){
378 _frame = cpl_frameset_get_position(darkcalib_frameset, 0);
379 cpl_frameset_insert (dark_frameset, cpl_frame_duplicate (_frame));
380 filename_ = cpl_frame_get_filename(_frame);
381 temp = strrchr(filename_,
'/');
382 filename = temp ? temp + 1 : filename_;
384 cpl_msg_info (cpl_func,
"This file %s is a dark file already "
385 "computed", filename);
386 dark_map = gravi_data_load(filename_);
389 cpl_frameset_delete(flat_frameset);
390 cpl_frameset_delete(dark_frameset);
391 cpl_frameset_delete(darkcalib_frameset);
392 cpl_frameset_delete(badpix_frameset);
394 gravi_data_delete(dark_map);
395 return (
int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
396 "No dark frames in the frameset");
400 if (!cpl_frameset_is_empty(badpix_frameset)){
401 _frame = cpl_frameset_get_position(badpix_frameset, 0);
402 filename_ = cpl_frame_get_filename(_frame);
403 temp = strrchr(filename_,
'/');
404 filename = temp ? temp + 1 : filename_;
405 cpl_msg_info (cpl_func,
"This file %s is a bad pixel map", filename);
407 bad_map = gravi_data_load(filename_);
412 cpl_msg_info (cpl_func,
"This file %s is a bad pixel map", filename);
413 bad_map = gravi_compute_badpix(dark_map, parlist);
415 if (cpl_error_get_code()) {
416 gravi_data_delete(dark_map);
417 gravi_data_delete(bad_map);
419 cpl_frameset_delete(flat_frameset);
420 cpl_frameset_delete(dark_frameset);
421 cpl_frameset_delete(darkcalib_frameset);
422 cpl_frameset_delete(badpix_frameset);
423 return (
int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
424 "Error while computing the bad pixel map");
428 bad_primary_hdr = gravi_data_get_propertylist (bad_map,
429 GRAVI_PRIMARY_HDR_NAME_EXT);
430 applist = gravi_propertylist_get_qc (bad_primary_hdr);
432 cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, BAD);
434 frame = cpl_frameset_get_position (dark_frameset, 0);
435 temp = strrchr(filename,
'/');
436 filename = temp?temp+1:filename;
439 output = gravi_data_product_name (filename,
"badpix");
441 if (gravi_data_save (bad_map, frameset, output, parlist,
442 dark_frameset, frame,
"gravi_all_flat", applist)
445 gravi_data_delete(bad_map);
447 gravi_data_delete(dark_map);
448 cpl_frameset_delete(flat_frameset);
449 cpl_frameset_delete(dark_frameset);
450 cpl_frameset_delete(darkcalib_frameset);
451 cpl_propertylist_delete(applist);
452 cpl_frameset_delete(badpix_frameset);
453 return (
int) cpl_error_set_message(cpl_func,
454 CPL_ERROR_ILLEGAL_OUTPUT,
"Could not save the bad pixel map");
456 cpl_propertylist_delete (applist);
463 flat_data = cpl_malloc(nb_frame *
sizeof(gravi_data *));
465 for(i = 0; i < nb_frame; i++){
466 frame = cpl_frameset_get_position(flat_frameset, i);
467 filename = cpl_frame_get_filename(frame);
469 flat_data[i] = gravi_data_load(filename);
476 profile_map = gravi_compute_profile(flat_data, dark_map, bad_map,
479 if (profile_map == NULL) {
481 gravi_data_delete(dark_map);
482 gravi_data_delete(profile_map);
483 for(i = 0; i < 4; i++){
484 gravi_data_delete(flat_data[i]);
487 cpl_frameset_delete(flat_frameset);
488 cpl_frameset_delete(dark_frameset);
489 cpl_frameset_delete(darkcalib_frameset);
490 cpl_frameset_delete(badpix_frameset);
491 return (
int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
492 "Error while computing the profile map");
498 gain_ft = gravi_compute_gain(flat_data, nb_frame, dark_map, bad_map,
499 GRAVI_IMAGING_DATA_FT_EXT);
500 cpl_msg_info (cpl_func,
"QC_MEANGAIN_FT = %e", gain_ft);
502 gain_sc = gravi_compute_gain(flat_data, nb_frame, dark_map, bad_map,
503 GRAVI_IMAGING_DATA_SC_EXT);
504 cpl_msg_info (cpl_func,
"QC_MEANGAIN_SC = %e", gain_sc);
506 printf (
"Execution time gravi_compute_gain : %f\n", (end - start) / (
double)CLOCKS_PER_SEC);
508 gravi_data_delete(bad_map);
510 for(i = 0; i < nb_frame; i++){
511 gravi_data_delete(flat_data[i]);
514 if (cpl_error_get_code()) {
515 gravi_data_delete(dark_map);
516 gravi_data_delete(profile_map);
517 cpl_frameset_delete(flat_frameset);
518 cpl_frameset_delete(dark_frameset);
519 cpl_frameset_delete(darkcalib_frameset);
520 cpl_frameset_delete(badpix_frameset);
521 return (
int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
522 "Error while computing the gain map");
525 primary_hdr = gravi_data_get_propertylist(profile_map,
526 GRAVI_PRIMARY_HDR_NAME_EXT);
529 cpl_propertylist_append_double (primary_hdr, QC_MEANGAIN_SC, gain_sc);
530 cpl_propertylist_set_comment( primary_hdr, QC_MEANGAIN_SC,
"[ADU/e-] Mean gain of SC detector" );
531 cpl_propertylist_append_double (primary_hdr, QC_MEANGAIN_FT, gain_ft);
532 cpl_propertylist_set_comment( primary_hdr, QC_MEANGAIN_FT,
"[ADU/e-] Mean gain of FT detector" );
536 applist = gravi_propertylist_get_qc(primary_hdr);
537 cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, FLAT);
539 frame = cpl_frameset_get_position (flat_frameset, 0);
541 temp = strrchr(filename,
'/');
544 output = gravi_data_product_name (filename,
"flat");
545 if (gravi_data_save (profile_map, frameset, output, parlist,
546 frameset, frame,
"gravi_all_flat", applist)
549 gravi_data_delete(profile_map);
550 gravi_data_delete(dark_map);
551 cpl_frameset_delete(flat_frameset);
552 cpl_frameset_delete(dark_frameset);
553 cpl_frameset_delete(darkcalib_frameset);
554 cpl_frameset_delete(badpix_frameset);
555 cpl_propertylist_delete(applist);
556 return (
int) cpl_error_set_message(cpl_func,
557 CPL_ERROR_ILLEGAL_OUTPUT,
"Could not save the profile_map");
559 cpl_propertylist_delete(applist);
565 gravi_data_delete(profile_map);
566 gravi_data_delete(dark_map);
567 cpl_frameset_delete(flat_frameset);
568 cpl_frameset_delete(badpix_frameset);
569 cpl_frameset_delete(darkcalib_frameset);
570 cpl_frameset_delete(dark_frameset);
572 return (
int)cpl_error_get_code();