34 #include <cxmessages.h>
38 #include <cpl_recipe.h>
39 #include <cpl_plugininfo.h>
40 #include <cpl_parameterlist.h>
41 #include <cpl_frameset.h>
42 #include <cpl_propertylist.h>
43 #include <cpl_vector.h>
54 #include "gistacking.h"
59 static cxint gimasterdark(cpl_parameterlist*, cpl_frameset*);
60 static cxint giqcmasterdark(cpl_frameset*);
64 _giraffe_clean_badpixels(GiImage* image, GiImage* bpixel)
73 cxint* _bpixel = NULL;
75 cxdouble* _image = NULL;
77 cpl_propertylist* properties = NULL;
80 cx_assert(image != NULL);
81 cx_assert(bpixel != NULL);
89 shift = cpl_propertylist_get_int(properties, GIALIAS_PRSCX);
94 for (i = 0; i < nx_image; i++) {
98 for (j = 0; j < ny_image; j++) {
100 if (_bpixel[i * ny_mask + j + shift] != 0) {
101 _image[i * ny_image + j] = 0.;
119 gimasterdark_create(cpl_plugin* plugin)
122 cpl_parameter* p = NULL;
124 cpl_recipe* recipe = (cpl_recipe*)plugin;
127 giraffe_error_init();
136 recipe->parameters = cpl_parameterlist_new();
137 cx_assert(recipe->parameters != NULL);
146 p = cpl_parameterlist_find(recipe->parameters,
"giraffe.stacking.method");
149 cpl_parameter_set_default_string(p,
"median");
165 gimasterdark_exec(cpl_plugin* plugin)
168 cpl_recipe* recipe = (cpl_recipe*)plugin;
173 if (recipe->parameters == NULL || recipe->frames == NULL) {
177 status = gimasterdark(recipe->parameters, recipe->frames);
183 status = giqcmasterdark(recipe->frames);
195 gimasterdark_destroy(cpl_plugin* plugin)
198 cpl_recipe* recipe = (cpl_recipe*)plugin;
207 cpl_parameterlist_delete(recipe->parameters);
209 giraffe_error_clear();
221 gimasterdark(cpl_parameterlist* config, cpl_frameset*
set)
224 const cxchar*
const _id =
"gimasterdark";
230 cxdouble exptotal = 0.;
232 cx_list* darks = NULL;
234 cx_list_const_iterator position = NULL;
236 cpl_matrix* bias_areas = NULL;
238 cpl_frame* dark_frame = NULL;
239 cpl_frame* mbias_frame = NULL;
240 cpl_frame* bpixel_frame = NULL;
241 cpl_frame* mdark_frame = NULL;
243 cpl_image* _dark = NULL;
245 cpl_propertylist* properties = NULL;
248 GiImage* result = NULL;
249 GiImage* mbias = NULL;
250 GiImage* bpixel = NULL;
251 GiImage** stack = NULL;
253 GiBiasConfig* bias_config = NULL;
255 GiStackingConfig* stack_config = NULL;
257 GiRecipeInfo info = {(cxchar*)_id, 1, NULL};
259 GiGroupInfo groups[] = {
260 {GIFRAME_DARK, CPL_FRAME_GROUP_RAW},
261 {GIFRAME_BIAS_MASTER, CPL_FRAME_GROUP_CALIB},
262 {GIFRAME_BADPIXEL_MAP, CPL_FRAME_GROUP_CALIB},
263 {NULL, CPL_FRAME_GROUP_NONE}
272 status = giraffe_frameset_set_groups(
set, groups);
275 cpl_msg_error(_id,
"Setting frame group information failed!");
284 count = cpl_frameset_count_tags(
set, GIFRAME_DARK);
287 cpl_msg_error(_id,
"No raw dark frames found in frameset! "
297 mbias_frame = cpl_frameset_find(
set, GIFRAME_BIAS_MASTER);
300 cpl_msg_error(_id,
"No master bias present in frame set. "
305 bpixel_frame = cpl_frameset_find(
set, GIFRAME_BADPIXEL_MAP);
308 cpl_msg_info(_id,
"No bad pixel map present in frame set.");
316 cpl_msg_info(_id,
"Loading dark frames ...");
318 darks = cx_list_new();
319 dark_frame = cpl_frameset_find(
set, GIFRAME_DARK);
323 while ((dark_frame != NULL ) && (i < count)) {
325 const cxchar*
const filename = cpl_frame_get_filename(dark_frame);
333 cpl_msg_error(_id,
"Cannot load dark from '%s'. Aborting ...",
342 cx_list_push_back(darks, dark);
344 dark_frame = cpl_frameset_find(
set, NULL);
349 cx_assert(i == count);
362 if (bias_config->method == GIBIAS_METHOD_MASTER ||
363 bias_config->method == GIBIAS_METHOD_ZMASTER) {
365 if (mbias_frame == NULL) {
366 cpl_msg_error(_id,
"Missing master bias frame! Selected bias "
367 "removal method requires a master bias frame!");
379 const cxchar* filename = cpl_frame_get_filename(mbias_frame);
386 cpl_msg_error(_id,
"Cannot load master bias from '%s'. "
387 "Aborting ...", filename);
411 const cxchar* filename = cpl_frame_get_filename(bpixel_frame);
418 cpl_msg_error(_id,
"Cannot load bad pixel map from '%s'. "
419 "Aborting ...", filename);
442 for (i = 0; i < count; i++) {
444 GiImage* dark = cx_list_pop_front(darks);
453 cx_list_push_front(darks, dark);
476 cx_list_push_back(darks, rdark);
494 position = cx_list_begin(darks);
496 while (position != cx_list_end(darks)) {
498 cxdouble exptime = 0.;
500 GiImage* dark = cx_list_get(darks, position);
503 exptime = cpl_propertylist_get_double(properties, GIALIAS_EXPTIME);
508 cpl_propertylist_update_double(properties, GIALIAS_EXPTIME, 1.);
510 position = cx_list_next(darks, position);
522 count = cx_list_size(darks);
524 if (count < stack_config->min_nr_frames) {
526 cpl_msg_error(_id,
"Not enough frames (%d). Stacking method '%d' "
527 "requires at least %d frames! Aborting...", count,
528 stack_config->stackmethod, stack_config->min_nr_frames);
542 cpl_msg_info(_id,
"Combining %d of %d dark frames.", i, count);
544 stack = cx_calloc(count + 1,
sizeof(GiImage*));
547 position = cx_list_begin(darks);
549 while (position != cx_list_end(darks)) {
550 stack[i] = cx_list_get(darks, position);
551 position = cx_list_next(darks, position);
557 if (result == NULL) {
559 cpl_msg_error(_id,
"Frame combination failed! Aborting ...");
594 status = _giraffe_clean_badpixels(result, bpixel);
598 cpl_msg_error(_id,
"Bad pixel cleaning on master dark frame "
621 cpl_msg_info(_id,
"Writing master dark image ...");
624 cx_assert(properties != NULL);
626 cpl_propertylist_update_double(properties, GIALIAS_CRPIX1, 1.);
628 cpl_propertylist_update_double(properties, GIALIAS_EXPTTOT, exptotal);
629 cpl_propertylist_update_int(properties, GIALIAS_DATANCOM, count);
633 cpl_propertylist_update_double(properties, GIALIAS_DARKVALUE,
634 cpl_image_get_mean(_dark));
635 cpl_propertylist_set_comment(properties, GIALIAS_DARKVALUE,
636 "Dark current in ADU/s");
638 cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
645 CPL_FRAME_LEVEL_FINAL,
648 if (mdark_frame == NULL) {
650 cpl_msg_error(_id,
"Cannot create local file! Aborting ...");
652 if (result != NULL) {
660 cpl_frameset_insert(
set, mdark_frame);
663 if (result != NULL) {
677 giqcmasterdark(cpl_frameset*
set)
680 const cxchar*
const fctid =
"giqcmasterdark";
685 cxdouble exptime = 1.;
691 cpl_propertylist* properties = NULL;
692 cpl_propertylist* qclog = NULL;
695 cpl_image* _mdark = NULL;
697 cpl_frame* rframe = NULL;
698 cpl_frame* pframe = NULL;
702 GiImage* mdark = NULL;
703 GiImage* dark = NULL;
705 GiWindow w = {10, 200, 2038, 3000};
708 cpl_msg_info(fctid,
"Computing QC1 parameters ...");
710 qc = giraffe_qclog_open(0);
713 cpl_msg_error(fctid,
"Cannot create QC1 log!");
717 qclog = giraffe_paf_get_properties(qc);
718 cx_assert(qclog != NULL);
726 CPL_FRAME_GROUP_PRODUCT);
728 if (pframe == NULL) {
729 cpl_msg_error(fctid,
"Missing product frame (%s)",
730 GIFRAME_DARK_MASTER);
732 giraffe_paf_delete(qc);
738 cpl_msg_info(fctid,
"Processing product frame '%s' (%s)",
739 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
745 cpl_msg_error(fctid,
"Could not load master dark '%s'! Aborting ...",
746 cpl_frame_get_filename(pframe));
751 giraffe_paf_delete(qc);
762 rframe = cpl_frameset_find(
set, GIFRAME_DARK);
764 if (rframe == NULL) {
765 cpl_msg_error(fctid,
"Missing raw frame (%s)", GIFRAME_DARK);
770 giraffe_paf_delete(qc);
780 cpl_msg_error(fctid,
"Could not load dark '%s'!",
781 cpl_frame_get_filename(rframe));
789 giraffe_paf_delete(qc);
797 cx_assert(properties != NULL);
802 cpl_propertylist_update_string(qclog,
"PRO.CATG",
803 cpl_frame_get_tag(pframe));
804 cpl_propertylist_set_comment(qclog,
"PRO.CATG",
805 "Pipeline product category");
808 cx_assert(properties != NULL);
824 if (cpl_propertylist_has(properties, GIALIAS_EXPTIME) == TRUE) {
826 exptime = cpl_propertylist_get_double(properties, GIALIAS_EXPTIME);
830 exptime = 3600. / exptime;
841 mean = cpl_image_get_mean_window(_mdark, w.x0, w.y0, w.x1, w.y1);
844 cpl_propertylist_update_double(properties, GIALIAS_QCMDARKAVG,
846 cpl_propertylist_set_comment(properties, GIALIAS_QCMDARKAVG,
847 "Mean master dark current (ADU/hr)");
861 gflux = cpl_image_get_flux_window(_mdark, w.x0, w.y0, w.x1, w.y1);
863 cpl_image_get_maxpos_window(_mdark, w.x0, w.y0, w.x1, w.y1, &gpx, &gpy);
866 cpl_propertylist_update_double(properties, GIALIAS_QCGLOWFLX, gflux);
867 cpl_propertylist_set_comment(properties, GIALIAS_QCGLOWFLX,
868 "Total flux of glow feature (ADU/s)");
870 cpl_propertylist_update_int(properties, GIALIAS_QCGLOWX, (cxint)gpx);
871 cpl_propertylist_set_comment(properties, GIALIAS_QCGLOWX,
872 "X position of glow feature (pxl)");
874 cpl_propertylist_update_int(properties, GIALIAS_QCGLOWY, (cxint)gpy);
875 cpl_propertylist_set_comment(properties, GIALIAS_QCGLOWY,
876 "X position of glow feature (pxl)");
894 giraffe_qclog_close(qc);
908 cpl_plugin_get_info(cpl_pluginlist* list)
911 cpl_recipe* recipe = cx_calloc(1,
sizeof *recipe);
912 cpl_plugin* plugin = &recipe->interface;
915 cpl_plugin_init(plugin,
917 GIRAFFE_BINARY_VERSION,
918 CPL_PLUGIN_TYPE_RECIPE,
920 "Creates a master dark image from a set of raw dark "
922 "For detailed information please refer to the "
923 "GIRAFFE pipeline user manual.\nIt is available at "
924 "http://www.eso.org/pipelines.",
930 gimasterdark_destroy);
932 cpl_pluginlist_append(list, plugin);