36 #include "omega_recipe.h"
38 #include "omega_background.h"
39 #include "omega_bpm.h"
40 #include "omega_flats.h"
41 #include <cpl_errorstate.h>
76 static int omega_mflat_create(cpl_plugin *) ;
77 static int omega_mflat_exec(cpl_plugin *) ;
78 static int omega_mflat_destroy(cpl_plugin *) ;
79 static int omega_mflat(cpl_frameset *,cpl_parameterlist *);
85 static void omega_mflat_init(
void);
86 static void omega_mflat_tidy(
void);
116 const cpl_frame *cframe;
117 const cpl_frame *hframe;
118 const cpl_frame *mbframe;
119 const cpl_frame *mdomefr;
120 const cpl_frame *nskyfr;
121 const cpl_frame *bpframe;
123 cpl_frameset *flatlist;
124 cpl_propertylist *eh;
126 omega_fits *firstflat;
131 cpl_image *mtwilight;
140 #define RECIPE "omega_mflat"
157 cpl_recipe * recipe = cpl_calloc(1,
sizeof(*recipe)) ;
158 cpl_plugin * plugin = &recipe->interface ;
160 cpl_plugin_init(plugin,
162 OMEGA_BINARY_VERSION,
163 CPL_PLUGIN_TYPE_RECIPE,
165 "OMEGA - Create Master Twilight and Master Flat for each chip",
166 "This recipe is used to derive a valid twilight flat frame (Calfile 543, 546) \n"
167 "for one particular chip and filter. The recipe always takes as input \n"
168 "a list of raw twilight flat frames, a master bias and an optional master \n"
169 "dome flat to be used in creating a final Master Flat Field. In addition, a hot \n"
170 "pixel map (and a cold pixel map can be provided, which will be used to create a \n"
171 "bad pixels map. Optionally, an overscan correction mode \n"
172 "can be set. The default is to apply no overscan correction.\n\n"
173 "The raw twilight flats are trimmed and overscan corrected. The data are then \n"
174 "normalized, averaged, and the result is normalized again. Image statistics \n"
175 "are computed for the resulting frames.",
181 omega_mflat_destroy) ;
183 cpl_pluginlist_append(list, plugin) ;
191 static int omega_mflat_create(cpl_plugin * plugin)
198 if (cpl_error_get_code() != CPL_ERROR_NONE) {
199 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
200 cpl_func, __LINE__, cpl_error_get_where());
201 return (
int)cpl_error_get_code();
204 if (plugin == NULL) {
205 cpl_msg_error(cpl_func,
"Null plugin");
206 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
210 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
211 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
212 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
216 recipe = (cpl_recipe *)plugin;
219 recipe->parameters = cpl_parameterlist_new() ;
220 if (recipe->parameters == NULL) {
221 cpl_msg_error(cpl_func,
"Parameter list allocation failed");
222 cpl_ensure_code(0, (
int)CPL_ERROR_ILLEGAL_OUTPUT);
229 p = cpl_parameter_new_value(
"omega.omega_mflat.ExtensionNumber",
231 "FITS extension number to load (1 to 32). (-1 = all)",
235 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ext") ;
236 cpl_parameterlist_append(recipe->parameters, p) ;
239 p = cpl_parameter_new_range(
"omega.omega_mflat.OverscanMethod",
241 "Overscan Correction Method",
245 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"oc-meth") ;
246 cpl_parameterlist_append(recipe->parameters, p) ;
248 p = cpl_parameter_new_value(
"omega.omega_mflat.PAF",
250 "Boolean value to create PAF files. 1(Yes), 0(No)",
254 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"paf") ;
255 cpl_parameterlist_append(recipe->parameters, p) ;
257 p = cpl_parameter_new_value(
"omega.omega_mflat.SigmaClip",
259 "Sigma Clipping Threshold",
263 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"sig-clip") ;
264 cpl_parameterlist_append(recipe->parameters, p) ;
269 path = cpl_sprintf(
"%s", OMEGA_BIN_PATH);
270 p = cpl_parameter_new_value(
"omega.omega_mflat.BinPath",
272 "Path to any external executable program.",
276 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"bin-path");
277 cpl_parameterlist_append(recipe->parameters, p);
280 p = cpl_parameter_new_value(
"omega.omega_mflat.GaussianFiltSize",
282 "Standard deviation of Gaussian Fourier filter size",
286 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"gau_filt_sz") ;
287 cpl_parameterlist_append(recipe->parameters, p) ;
289 p = cpl_parameter_new_value(
"omega.omega_mflat.MirrorXpix",
291 "Width of X region for mirroring edges (FFT continuity)",
295 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"mr_xpix") ;
296 cpl_parameterlist_append(recipe->parameters, p) ;
298 p = cpl_parameter_new_value(
"omega.omega_mflat.MirrorYpix",
300 "Width of Y region for mirroring edges (FFT continuity)",
304 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"mr_ypix") ;
305 cpl_parameterlist_append(recipe->parameters, p) ;
308 p = cpl_parameter_new_range(
"omega.omega_mflat.LowThre",
310 "Low flagging threshold for cold pixels map",
314 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"low") ;
315 cpl_parameterlist_append(recipe->parameters, p) ;
317 p = cpl_parameter_new_range(
"omega.omega_mflat.HighThre",
319 "High flagging threshold for cold pixels map",
323 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"high") ;
324 cpl_parameterlist_append(recipe->parameters, p) ;
332 static int omega_mflat_exec(cpl_plugin * plugin)
338 if (cpl_error_get_code() != CPL_ERROR_NONE) {
339 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
340 cpl_func, __LINE__, cpl_error_get_where());
341 return (
int)cpl_error_get_code();
344 if (plugin == NULL) {
345 cpl_msg_error(cpl_func,
"Null plugin");
346 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
350 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
351 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
352 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
356 recipe = (cpl_recipe *)plugin;
359 if (recipe->parameters == NULL) {
360 cpl_msg_error(cpl_func,
"Recipe invoked with NULL parameter list");
361 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
363 if (recipe->frames == NULL) {
364 cpl_msg_error(cpl_func,
"Recipe invoked with NULL frame set");
365 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
369 recipe_status = omega_mflat(recipe->frames, recipe->parameters);
372 if (cpl_dfs_update_product_header(recipe->frames)) {
373 if (!recipe_status) recipe_status = (int)cpl_error_get_code();
376 return recipe_status;
382 static int omega_mflat_destroy(cpl_plugin * plugin)
386 if (plugin == NULL) {
387 cpl_msg_error(cpl_func,
"Null plugin");
388 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
392 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
393 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
394 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
398 recipe = (cpl_recipe *)plugin;
400 cpl_parameterlist_delete(recipe->parameters) ;
408 static int omega_mflat(cpl_frameset *set, cpl_parameterlist *pars)
418 const char *_id =
"omega_mflat";
420 char *outtwilight = NULL;
421 char *outmflat = NULL;
422 const cpl_frame *firstframe;
423 const cpl_frame *refframe;
424 cpl_frame *prframe_twil = NULL;
425 cpl_frame *prframe_mflat = NULL;
426 cpl_frame *prframe_bpm = NULL;
428 cpl_propertylist *qclist;
429 cpl_propertylist *alist;
430 cpl_stats *diffstats = NULL;
431 cpl_errorstate prestate = cpl_errorstate_get();
437 cpl_msg_error (_id,
"Parameters list not found");
441 if (cpl_frameset_is_empty(set) == 1) {
442 cpl_msg_error (_id,
"Frameset not found");
447 par = cpl_parameterlist_find(pars,
"omega.omega_mflat.ExtensionNumber") ;
448 omega_mflat_config.extnum = cpl_parameter_get_int(par) ;
450 par = cpl_parameterlist_find(pars,
"omega.omega_mflat.OverscanMethod") ;
451 omega_mflat_config.oc = cpl_parameter_get_int(par) ;
453 par = cpl_parameterlist_find(pars,
"omega.omega_mflat.SigmaClip") ;
454 omega_mflat_config.sigma = cpl_parameter_get_double(par) ;
456 par = cpl_parameterlist_find(pars,
"omega.omega_mflat.PAF") ;
457 omega_mflat_config.paf = cpl_parameter_get_bool(par) ;
460 if (oc_dfs_set_groups(set)) {
461 cpl_msg_error(_id,
"Cannot identify RAW and CALIB frames") ;
471 cpl_msg_error(_id,
"Cannot labelise the input frameset");
476 MTWIL_RAW)) == NULL) {
477 cpl_msg_error(_id,
"Cannot find twilight flats in input frameset");
481 nflats = cpl_frameset_count_tags (ps.flatlist, MTWIL_RAW);
483 cpl_msg_error (_id,
"Need at least 2 (%s) frames to run "
484 "this recipe", MTWIL_RAW);
489 cpl_msg_info (_id,
"There are %d %s frames in frame set",nflats, MTWIL_RAW);
493 ps.mbframe = cpl_frameset_find_const(set, OMEGA_CALIB_BIAS);
494 if (ps.mbframe == NULL) {
495 cpl_msg_error(cpl_func,
"Cannot find OMEGA_CALIB_BIAS input in frame set");
499 cpl_msg_info(_id,
"Using %s %s",OMEGA_CALIB_BIAS, cpl_frame_get_filename(ps.mbframe));
502 ps.cframe = cpl_frameset_find_const(set, OMEGA_CALIB_CPM);
503 if(ps.cframe == NULL){
504 cpl_msg_error(cpl_func,
"Cannot find %s input in frame set",OMEGA_CALIB_CPM);
508 cpl_msg_info(_id,
"Using %s %s",OMEGA_CALIB_CPM, cpl_frame_get_filename(ps.cframe));
511 ps.hframe = cpl_frameset_find_const(set, OMEGA_CALIB_HPM);
512 if(ps.hframe == NULL){
513 cpl_msg_error(cpl_func,
"Cannot find %s input in frame set",OMEGA_CALIB_HPM);
517 cpl_msg_info(_id,
"Using %s %s",OMEGA_CALIB_HPM, cpl_frame_get_filename(ps.hframe));
520 ps.mdomefr = cpl_frameset_find_const(set, OMEGA_CALIB_DOME);
521 if(ps.mdomefr != NULL) {
522 cpl_msg_info(_id,
"Using %s %s", OMEGA_CALIB_DOME, cpl_frame_get_filename(ps.mdomefr));
526 ps.nskyfr = cpl_frameset_find_const(set, OMEGA_CALIB_NSKY);
527 if(ps.nskyfr != NULL) {
528 cpl_msg_info(_id,
"Using %s %s", OMEGA_CALIB_NSKY, cpl_frame_get_filename(ps.nskyfr));
532 refframe = cpl_frameset_find_const(set, REFMFLAT);
533 if (refframe != NULL)
534 cpl_msg_info(cpl_func,
"Using %s for comparison",cpl_frame_get_filename(refframe));
538 firstframe = cpl_frameset_get_position(ps.flatlist, 0);
542 if(omega_mflat_config.extnum == 0){
543 cpl_msg_error(cpl_func,
"Unsupported extension request, %d",omega_mflat_config.extnum);
548 for (j = jst; j <= jfn; j++) {
550 isfirst = (j == jst);
551 cpl_msg_info(_id,
"Beginning work on extension %d",j);
553 omega_mflat_config.bpm = 0;
554 omega_mflat_config.Mean = 0.0;
555 omega_mflat_config.Median = 0.0;
556 omega_mflat_config.Stdev = 0.0;
557 omega_mflat_config.RawMin = 0.0;
558 omega_mflat_config.RawMax = 0.0;
559 omega_mflat_config.RawMean = 0.0;
560 omega_mflat_config.RawMedian = 0.0;
561 omega_mflat_config.RawStdev = 0.0;
564 if(ps.mbframe != NULL){
566 if(oscan1 != omega_mflat_config.oc) {
567 cpl_msg_warning (_id,
"Overscan correction mode for Master Bias (oc = %d) differs from "
568 "the one used here (oc = %d)", oscan1, omega_mflat_config.oc);
580 cpl_msg_warning(_id,
"Image detector is not live");
582 freefits(ps.firstflat);
586 else if(status == -1){
587 cpl_msg_error(_id,
"Cannot combine images");
589 freespace(outtwilight);
597 qclist = cpl_propertylist_new();
601 if(refframe != NULL){
603 cpl_msg_warning(cpl_func,
"Cannot compare with reference frame");
606 cpl_propertylist_append_double(qclist,
"ESO QC DIFF REFMFLAT MEAN",
607 cpl_stats_get_mean(diffstats));
608 cpl_propertylist_set_comment(qclist,
"ESO QC DIFF REFMFLAT MEAN",
609 "Mean of difference with reference");
610 cpl_propertylist_append_double(qclist,
"ESO QC DIFF REFMFLAT MEDIAN",
611 cpl_stats_get_median(diffstats));
612 cpl_propertylist_set_comment(qclist,
"ESO QC DIFF REFMFLAT MEDIAN",
613 "Median of difference with reference");
614 cpl_propertylist_append_double(qclist,
"ESO QC DIFF REFMFLAT STDEV",
615 cpl_stats_get_stdev(diffstats));
616 cpl_propertylist_set_comment(qclist,
"ESO QC DIFF REFMFLAT STDEV",
617 "Stdev of difference with reference");
619 freestats(diffstats);
625 ps.stats = cpl_stats_new_from_image(ps.mflat, CPL_STATS_ALL);
626 if(ps.stats != NULL) {
627 omega_mflat_config.Mean = cpl_stats_get_mean(ps.stats);
628 omega_mflat_config.Median = cpl_stats_get_median(ps.stats);
629 omega_mflat_config.Stdev = cpl_stats_get_stdev(ps.stats);
634 cpl_propertylist_append_double(qclist,
"ESO QC MASTER FLAT MEAN",
635 omega_mflat_config.Mean) ;
636 cpl_propertylist_set_comment(qclist,
"ESO QC MASTER FLAT MEAN",
637 "Mean value of master flat");
638 cpl_propertylist_append_double(qclist,
"ESO QC MASTER FLAT MEDIAN",
639 omega_mflat_config.Median) ;
640 cpl_propertylist_set_comment(qclist,
"ESO QC MASTER FLAT MEDIAN",
641 "Median value of master flat");
642 cpl_propertylist_append_double(qclist,
"ESO QC MASTER FLAT STDEV",
643 omega_mflat_config.Stdev) ;
644 cpl_propertylist_set_comment(qclist,
"ESO QC MASTER FLAT STDEV",
645 "Standard deviation value of master flat");
649 outmflat = cpl_sprintf(
"%s_%s.fits", INSTRUME,MFLAT_PROCATG);
654 alist = cpl_propertylist_new();
655 cpl_propertylist_append_string(alist,
"EXTNAME",
656 cpl_propertylist_get_string(ps.eh,
"EXTNAME"));
657 cpl_propertylist_set_comment(alist,
"EXTNAME",
"Extension name");
659 cpl_propertylist_copy_property_regexp(alist, ps.eh, WCS_KEYS, 0);
662 cpl_propertylist_update_int(alist,
"ESO DRS OVERSCAN METHOD", omega_mflat_config.oc);
663 cpl_propertylist_set_comment(alist,
"ESO DRS OVERSCAN METHOD",
"overscan correction method");
665 if(
omega_save_image(ps.mflat,set,pars,alist,qclist,CPL_BPP_IEEE_FLOAT,outmflat,
666 RECIPE,prframe_mflat,NULL,isfirst) == -1){
667 cpl_msg_error(_id,
"Cannot save product %s", MFLAT_PROCATG);
671 freespace(outtwilight);
684 ps.stats = cpl_stats_new_from_image(ps.mtwilight, CPL_STATS_ALL);
685 if(ps.stats != NULL) {
686 omega_mflat_config.Mean = cpl_stats_get_mean(ps.stats);
687 omega_mflat_config.Median = cpl_stats_get_median(ps.stats);
688 omega_mflat_config.Stdev = cpl_stats_get_stdev(ps.stats);
693 qclist = cpl_propertylist_new();
694 cpl_propertylist_append_double(qclist,
"ESO QC MASTER TWILIGHT MEAN",
695 omega_mflat_config.Mean) ;
696 cpl_propertylist_set_comment(qclist,
"ESO QC MASTER TWILIGHT MEAN",
697 "Mean value of master twilight flat");
698 cpl_propertylist_append_double(qclist,
"ESO QC MASTER TWILIGHT MEDIAN",
699 omega_mflat_config.Median) ;
700 cpl_propertylist_set_comment(qclist,
"ESO QC MASTER TWILIGHT MEDIAN",
701 "Median value of master twilight flat");
702 cpl_propertylist_append_double(qclist,
"ESO QC MASTER TWILIGHT STDEV",
703 omega_mflat_config.Stdev) ;
704 cpl_propertylist_set_comment(qclist,
"ESO QC MASTER TWILIGHT STDEV",
705 "Standard deviation value of master twilight flat");
707 cpl_propertylist_append_double(qclist,
"ESO QC RAW TWILIGHT MIN",
708 omega_mflat_config.RawMin);
709 cpl_propertylist_append_double(qclist,
"ESO QC RAW TWILIGHT MAX",
710 omega_mflat_config.RawMax);
711 cpl_propertylist_append_double(qclist,
"ESO QC RAW TWILIGHT MEAN",
712 omega_mflat_config.RawMean);
713 cpl_propertylist_append_double(qclist,
"ESO QC RAW TWILIGHT MEDIAN",
714 omega_mflat_config.RawMedian);
715 cpl_propertylist_append_double(qclist,
"ESO QC RAW TWILIGHT STDEV",
716 omega_mflat_config.RawStdev);
718 cpl_propertylist_set_comment(qclist,
"ESO QC RAW TWILIGHT MIN",
719 "median value of the raw flat flat having the lowest flux");
720 cpl_propertylist_set_comment(qclist,
"ESO QC RAW TWILIGHT MAX",
721 "median value of the raw flat flat having the highest flux");
722 cpl_propertylist_set_comment(qclist,
"ESO QC RAW TWILIGHT MEAN",
723 "mean value of all input raw flat flats (ADU)");
724 cpl_propertylist_set_comment(qclist,
"ESO QC RAW TWILIGHT MEDIAN",
725 "median value of all input raw flat flats (ADU)");
726 cpl_propertylist_set_comment(qclist,
"ESO QC RAW TWILIGHT STDEV",
727 "standard deviation of all input raw flat flats (ADU)");
731 outtwilight = cpl_sprintf(
"%s_%s.fits", INSTRUME,MTWIL_PROCATG);
735 if(
omega_save_image(ps.mtwilight,set,pars,alist,qclist,CPL_BPP_IEEE_FLOAT,outtwilight,
736 RECIPE,prframe_twil,NULL,isfirst) == -1){
737 cpl_msg_error(_id,
"Cannot save product %s", MTWIL_PROCATG);
740 freespace(outtwilight);
748 freeimage(ps.mtwilight);
753 qclist = cpl_propertylist_new();
754 cpl_propertylist_append_int(qclist,
"ESO QC NUMBER BAD PIXELS",omega_mflat_config.bpm);
755 cpl_propertylist_set_comment(qclist,
"ESO QC NUMBER BAD PIXELS",
756 "Number of bad pixels");
759 outbpm = cpl_sprintf(
"%s_%s.fits", INSTRUME,BPM_PROCATG);
763 if(
omega_save_image(ps.bpixels,set,pars,alist,qclist,CPL_BPP_16_SIGNED,outbpm,
764 RECIPE,prframe_bpm,NULL,isfirst) == -1){
765 cpl_msg_error(_id,
"Cannot save product %s", BPM_PROCATG);
769 freespace(outtwilight);
777 freeimage(ps.bpixels);
778 freefits(ps.firstflat);
786 freespace(outtwilight);
790 if(!cpl_errorstate_is_equal(prestate)){
791 cpl_errorstate_dump(prestate,CPL_FALSE,NULL);
812 int i,nflats,live, naxis1, naxis2;
816 double threshold = 0.0;
818 const char *_id =
"omega_mflat_combine";
821 const cpl_frame *flatfr;
823 cpl_vector *median_vector = NULL;
824 cpl_image *trim_raw,*dev,*good_float,*good_int,*median_all,*new_image;
825 cpl_image *sum_data,*sum_good;
830 cpl_imagelist *ilist;
833 nflats = cpl_frameset_get_size(ps.flatlist);
843 if(ps.mbframe != NULL){
844 mbias = cpl_image_load(cpl_frame_get_filename(ps.mbframe), CPL_TYPE_FLOAT,0,xn);
846 cpl_msg_warning(_id,
"Cannot load image %s", OMEGA_CALIB_BIAS);
851 bpm_map =
makebpm(ps.hframe, ps.cframe, xn);
854 omega_mflat_config.bpm = cpl_mask_count(bpm_map);
857 scales = cpl_vector_new(nflats);
858 data_scales = cpl_vector_get_data(scales);
860 median_vector = cpl_vector_new (nflats);
861 cpl_vector_fill(median_vector,0.0);
863 ilist = cpl_imagelist_new();
864 cpl_msg_info (_id,
"Doing trim and overscan correction on images");
867 for (i=0; i< nflats; i++)
869 flatfr = cpl_frameset_get_position(ps.flatlist, i);
873 if(trim_raw == NULL){
875 freevector(median_vector);
883 cpl_image_subtract(trim_raw, mbias);
885 cpl_image_subtract_scalar(trim_raw, bias);
887 if (bpm_map == NULL) {
888 ps.stats = cpl_stats_new_from_image(trim_raw, CPL_STATS_ALL);
889 median = cpl_stats_get_median(ps.stats);
892 cpl_image_reject_from_mask(trim_raw, bpm_map);
893 ps.stats = cpl_stats_new_from_image(trim_raw, CPL_STATS_ALL);
894 median = cpl_stats_get_median(ps.stats);
897 cpl_vector_set(median_vector, i, median);
899 data_scales[i] = (double)1.0/median;
900 cpl_image_divide_scalar(trim_raw, median);
902 cpl_imagelist_set(ilist, trim_raw, i);
908 omega_mflat_config.RawMin = cpl_vector_get_min(median_vector);
909 omega_mflat_config.RawMax = cpl_vector_get_max(median_vector);
910 omega_mflat_config.RawMean = cpl_vector_get_mean(median_vector);
911 omega_mflat_config.RawMedian = cpl_vector_get_median(median_vector);
912 omega_mflat_config.RawStdev = cpl_vector_get_stdev(median_vector);
914 freevector(median_vector);
920 cpl_msg_error(_id,
"Error in image list <%s>",cpl_error_get_message());
942 cpl_msg_info(_id,
"Using default value for gain");
947 cpl_msg_info(_id,
"Gain value from images is %g", gain);
950 cpl_msg_info (_id,
"Computing the median of all images...");
951 median_all = cpl_imagelist_collapse_median_create(ilist);
953 if (median_all == NULL) {
954 cpl_msg_error (_id,
"Cannot take median of imset <%s>",cpl_error_get_message());
961 naxis1 = cpl_image_get_size_x(median_all);
962 naxis2 = cpl_image_get_size_y(median_all);
964 sum_data = cpl_image_new(naxis1,naxis2,CPL_TYPE_FLOAT);
965 sum_good = cpl_image_new(naxis1,naxis2,CPL_TYPE_FLOAT);
968 for (i=0; i< nflats; i++)
970 trim_raw = cpl_imagelist_get(ilist, i);
971 new_image = cpl_image_duplicate(trim_raw);
977 cpl_image_threshold(trim_raw, 0, FLT_MAX, 0, 2e20);
979 dev = cpl_image_subtract_create(median_all, trim_raw);
981 code = cpl_image_power(trim_raw, 0.5);
982 if(code != CPL_ERROR_NONE) {
983 cpl_msg_error(_id,
"Error in SQRT operation <%s>",cpl_error_get_message());
986 freeimage(median_all);
989 freeimage(new_image);
995 cpl_image_divide(dev, trim_raw);
997 threshold = omega_mflat_config.sigma * (sqrt(gain * data_scales[i]));
999 good = cpl_mask_threshold_image_create(dev, -threshold, threshold);
1002 good_int = cpl_image_new_from_mask(good) ;
1005 good_float = cpl_image_cast(good_int, CPL_TYPE_FLOAT);
1006 freeimage(good_int);
1008 cpl_image_multiply(new_image, good_float);
1009 cpl_image_add(sum_data, new_image);
1011 cpl_image_add(sum_good, good_float);
1013 freeimage(new_image);
1014 freeimage(good_float);
1018 freeimage(median_all);
1023 cpl_image_threshold(sum_good, FLT_EPSILON, FLT_MAX, FLT_EPSILON, FLT_MAX);
1024 ps.mtwilight = cpl_image_divide_create(sum_data, sum_good);
1025 if (ps.mtwilight == NULL) {
1026 cpl_msg_error(_id,
"Error in division %s <%s>",MTWIL_PROCATG, cpl_error_get_message());
1028 freeimage(sum_data);
1029 freeimage(sum_good);
1034 freeimage(sum_data);
1035 freeimage(sum_good);
1040 if(ps.mdomefr != NULL){
1042 mdome = cpl_image_load(cpl_frame_get_filename(ps.mdomefr), CPL_TYPE_FLOAT,0,xn);
1044 cpl_msg_warning(_id,
"Cannot load image %s", OMEGA_CALIB_DOME);
1045 ps.mflat = cpl_image_duplicate(ps.mtwilight);
1049 if(ps.mflat == NULL){
1050 cpl_msg_warning(_id,
"Cannot calculate Master Flat Field");
1051 ps.mflat = cpl_image_duplicate(ps.mtwilight);
1057 cpl_msg_warning(_id,
"There is no Master Dome Flat in frame set");
1058 ps.mflat = cpl_image_duplicate(ps.mtwilight);
1062 if (ps.nskyfr != NULL) {
1063 nsky = cpl_image_load(cpl_frame_get_filename(ps.nskyfr), CPL_TYPE_FLOAT,0,xn);
1065 cpl_msg_warning(_id,
"Cannot load image %s", OMEGA_CALIB_NSKY);
1068 cpl_image_multiply (ps.mflat, nsky);
1077 ps.bpixels = cpl_image_new_from_mask(bpm_map);
1079 omega_mflat_config.bpm = cpl_mask_count(bpm_map);
1086 static void omega_mflat_init(
void) {
1090 ps.firstflat = NULL;
1097 ps.mtwilight = NULL;
1103 static void omega_mflat_tidy(
void) {
1104 freefits(ps.firstflat);
1105 freeframeset(ps.flatlist);
1106 freeimage(ps.bpixels);
1107 freeimage(ps.mflat);
1108 freeimage(ps.mtwilight);
1109 freespace(ps.labels);
1110 freestats(ps.stats);
int omega_pfits_get_overscan(const cpl_frame *frame, int xn)
Get the DRS keyword of the overscan method used to reduce the image.
cpl_image * omega_make_mflat(cpl_image *dome, cpl_image *twil, cpl_mask *bpmmap, cpl_parameterlist *pars)
It creates a master flat field.
int omega_pfits_get_detlive(const cpl_propertylist *plist, int *detlive)
Get the value of DET_LIVE.
void omega_extensions(const cpl_frame *frame, int inexten, int *out1, int *out2)
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
void omega_pfits_get_conad(cpl_propertylist *plist, double *conad)
Get the value of the keyword CONAD.
int omega_mflat_combine(cpl_parameterlist *pars, int xn)
Process the twilight flats.
cpl_image * TrimOscanCorrect(const cpl_frame *frame, int oscan, int extn)
This method loads a raw image, trims it and (optionally) performs an overscan correction, using the statistics of the pre and overscan regions. This can be done with a single value for the whole image or on a per-row basis.
int omega_compare_tags(const cpl_frame *frame1, const cpl_frame *frame2)
cpl_mask * makebpm(const cpl_frame *hot, const cpl_frame *cold, int cxn)
Create a bad pixels map.
omega_fits * omega_fits_load(const cpl_frame *inframe, cpl_type type, int extnum)
const char * omega_get_license(void)
Get the pipeline copyright and license.
cpl_frame * omega_product_frame(const char *filename, const char *tag, cpl_frame_type type)
Setup a frame to save a product.
int omega_compare_reference(const cpl_image *master, const cpl_frame *refframe, int ext, cpl_stats **diffstats)
cpl_propertylist * omega_fits_get_ehu(omega_fits *p)
cpl_frameset * omega_frameset_subgroup(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
int omega_save_image(const cpl_image *img, cpl_frameset *set, const cpl_parameterlist *pars, cpl_propertylist *alist, const cpl_propertylist *qclist, cpl_type_bpp bpp, const char *name, const char *recipe, cpl_frame *frame, const cpl_frame *inherit, int isfirst)
Save an image as a DFS compliant product.
void omega_pfits_get_gain(cpl_propertylist *plist, double *gain)
Read the gain value from an image.