229 #include <uves_mbias_impl.h>
231 #include <uves_utils.h>
232 #include <uves_corrbadpix.h>
233 #include <uves_parameters.h>
235 #include <uves_dfs.h>
236 #include <uves_pfits.h>
237 #include <uves_qclog.h>
238 #include <uves_recipe.h>
239 #include <uves_utils_wrappers.h>
240 #include <uves_error.h>
241 #include <irplib_mkmaster.h>
242 #include <uves_msg.h>
253 static void uves_mbias_qclog(
const cpl_imagelist* raw_imgs,
256 const cpl_image* mbia,
263 uves_mbias_qc_ron_raw(
const cpl_image* rbia,
272 uves_mbias_define_parameters(cpl_parameterlist *parameters);
277 #define cpl_plugin_get_info uves_mbias_get_info
279 UVES_MBIAS_ID, UVES_MBIAS_DOM,
282 uves_mbias_define_parameters,
283 "Jonas M. Larsen",
"cpl@eso.org",
284 "Creates the master bias frame",
285 "This recipe creates a master bias frame by computing the median of all input\n"
286 "bias frames. All input frames must have same tag and size and must be either\n"
287 "BIAS_BLUE or BIAS_RED.\n"
288 "On blue input the recipe computes one master bias frame; on red input a \n"
289 "master bias frame for each chip is produced. The average, standard deviation\n"
290 "and median of the master bias image(s) are written to the FITS header(s)");
306 int uves_mbias_define_parameters_body(cpl_parameterlist *parameters,
307 const char *recipe_id)
313 if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
322 if (uves_corr_traps_define_parameters(parameters,recipe_id)
332 if (uves_master_stack_define_parameters(parameters,recipe_id)
338 return (cpl_error_get_code() != CPL_ERROR_NONE);
351 uves_mbias_define_parameters(cpl_parameterlist *parameters)
353 return uves_mbias_define_parameters_body(parameters, make_str(UVES_MBIAS_ID));
379 uves_mbias_process_chip(
const cpl_imagelist *raw_images,
385 const char* STACK_METHOD,
386 const double STACK_KLOW,
387 const double STACK_KHIGH,
388 const int STACK_NITER)
390 cpl_image *master_bias = NULL;
391 double exposure_time = 0;
392 int badpixels_cleaned;
395 bool red_ccd_is_new=
false;
396 cpl_vector* bias_levels=NULL;
399 uves_msg(
"Calculating master bias...");
403 if(strcmp(STACK_METHOD,
"MEDIAN")==0) {
413 nraw=cpl_imagelist_get_size(raw_images);
414 for (i = 0; i < nraw; i++)
417 "Error reading exposure time");
419 exposure_time /= nraw;
424 "Error setting master bias exposure time");
426 check( badpixels_cleaned =
428 chip, binx, biny,
false,red_ccd_is_new),
429 "Error replacing bad pixels");
431 uves_msg(
"%d bad pixels replaced", badpixels_cleaned);
435 if (cpl_error_get_code() != CPL_ERROR_NONE)
437 uves_free_image(&master_bias);
452 UVES_CONCAT2X(UVES_MBIAS_ID,exe)(cpl_frameset *frames,
453 const cpl_parameterlist *parameters,
454 const char *starttime)
456 uves_mbias_exe_body(frames, parameters, starttime, make_str(UVES_MBIAS_ID));
473 uves_mbias_exe_body(cpl_frameset *frames,
474 const cpl_parameterlist *parameters,
475 const char *starttime,
476 const char *recipe_id)
479 cpl_imagelist *raw_images[2] = {NULL, NULL};
482 cpl_table* qclog[2] = {NULL, NULL};
486 cpl_image *master_bias = NULL;
487 cpl_stats *mbias_stats = NULL;
490 char *product_filename = NULL;
494 const char* PROCESS_CHIP=NULL;
499 const char* STACK_METHOD=NULL;
501 double STACK_KHIGH=0;
506 check( uves_load_raw_imagelist(frames,
508 UVES_BIAS(
true), UVES_BIAS(
false),
510 raw_images, raw_headers, product_header,
511 &blue),
"Error loading raw frames");
515 "Could not get raw frame x-binning");
517 "Could not get raw frame y-binning");
518 check( uves_get_parameter(parameters, NULL,
"uves",
"process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
519 "Could not read parameter");
522 check( uves_get_parameter(parameters, NULL, recipe_id,
"clean_traps", CPL_TYPE_BOOL, &CLEAN_TRAPS),
523 "Could not read parameter");
525 check( uves_get_parameter(parameters, NULL, recipe_id,
"stack_method", CPL_TYPE_STRING, &STACK_METHOD),
526 "Could not read parameter");
529 check( uves_get_parameter(parameters, NULL, recipe_id,
"klow", CPL_TYPE_DOUBLE, &STACK_KLOW),
530 "Could not read parameter");
531 check( uves_get_parameter(parameters, NULL, recipe_id,
"khigh", CPL_TYPE_DOUBLE, &STACK_KHIGH),
532 "Could not read parameter");
533 check( uves_get_parameter(parameters, NULL, recipe_id,
"niter", CPL_TYPE_INT, &STACK_NITER),
534 "Could not read parameter");
538 chip != UVES_CHIP_INVALID;
541 if(strcmp(PROCESS_CHIP,
"REDU") == 0) {
552 uves_free_image(&master_bias);
553 check( master_bias = uves_mbias_process_chip(raw_images[raw_index],
554 raw_headers[raw_index],
555 product_header[raw_index],
562 "Error processing chip");
565 cpl_free(product_filename);
566 check( product_filename = uves_masterbias_filename(chip),
567 "Error getting filename");
570 uves_msg(
"Calculating QC parameters");
573 check(uves_mbias_qclog(raw_images[raw_index],
574 raw_headers[raw_index],
578 qclog[0]),
"error computing qclog");
583 check( uves_frameset_insert(frames,
585 CPL_FRAME_GROUP_PRODUCT,
586 CPL_FRAME_TYPE_IMAGE,
587 CPL_FRAME_LEVEL_INTERMEDIATE,
589 UVES_MASTER_BIAS(chip),
590 raw_headers[raw_index][0],
591 product_header[raw_index],
595 PACKAGE
"/" PACKAGE_VERSION,qclog,
598 "Could not add master bias %s to frameset", product_filename);
600 uves_msg(
"Master bias '%s' added to frameset", product_filename);
602 if(strcmp(PROCESS_CHIP,
"REDL") == 0) {
611 if (raw_images[0] != NULL)
614 for (i = 0; i < cpl_imagelist_get_size(raw_images[0]); i++)
616 if (raw_headers[0] != NULL) uves_free_propertylist(&raw_headers[0][i]);
617 if (raw_headers[1] != NULL) uves_free_propertylist(&raw_headers[1][i]);
619 cpl_free(raw_headers[0]); raw_headers[0] = NULL;
620 cpl_free(raw_headers[1]); raw_headers[1] = NULL;
622 uves_free_imagelist(&raw_images[0]);
623 uves_free_imagelist(&raw_images[1]);
627 uves_free_image(&master_bias);
628 uves_free_propertylist(&product_header[0]);
629 uves_free_propertylist(&product_header[1]);
630 cpl_free(product_filename);
631 uves_free_stats(&mbias_stats);
639 count_good(
const cpl_image *image)
642 cpl_image_get_size_x(image) * cpl_image_get_size_y(image) -
643 cpl_image_count_rejected(image);
654 reject_lo_hi(cpl_image *image,
double min,
double max)
656 cpl_mask *mask_lo = NULL;
657 cpl_mask *mask_hi = NULL;
659 mask_lo = cpl_mask_threshold_image_create(image, -DBL_MAX, min);
660 mask_hi = cpl_mask_threshold_image_create(image, max, DBL_MAX);
664 cpl_mask_or(mask_lo, mask_hi);
666 cpl_image_reject_from_mask(image, mask_lo);
669 uves_free_mask(&mask_lo);
670 uves_free_mask(&mask_hi);
684 static void uves_mbias_qclog(
const cpl_imagelist* raw_imgs,
687 const cpl_image* mbia,
707 double upp_threshold= 0.0;
708 double low_threshold= 0.0;
710 double qc_ron_master= 0.0;
712 double master_median=0.0;
718 double struct_col=0.0;
719 double struct_row=0.0;
721 double time_s=+9999999.0;
722 double time_e=-9999999.0;
724 double qc_duty_cycle=0.;
725 double exposure_time=0;
729 const cpl_image* rbia=NULL;
730 cpl_image* tima=NULL;
731 cpl_image* avg_col=NULL;
732 cpl_image* avg_row=NULL;
736 "Test-on-Master-Bias",
740 uves_msg(
"Computing duty cycle...");
744 nraw = cpl_imagelist_get_size(raw_imgs);
748 "Number of frames combined",
752 for (i = 0; i < nraw; i++)
755 "Error reading exposure time");
756 if(exposure_time >= time_e) time_e = exposure_time;
757 if(exposure_time <= time_s) time_s = exposure_time;
760 qc_duty_cycle = (time_e-time_s)/ (nraw-1);
770 "Time to store a frame",
783 nx_pix = cpl_image_get_size_x(mbia);
784 ny_pix = cpl_image_get_size_y(mbia);
787 x_cent_s = (nx_pix - sample_x)/2;
788 x_cent_e = (nx_pix + sample_x)/2;
789 y_cent_s = (ny_pix - sample_y)/2;
790 y_cent_e = (ny_pix + sample_y)/2;
794 cpl_image_get_median_window(mbia,
798 y_cent_e)*(1 + extra));
800 cpl_image_get_median_window(mbia,
804 y_cent_e)*(1 - extra));
812 rbia = cpl_imagelist_get_const(raw_imgs,0);
814 x_cent_s,x_cent_e,y_cent_s,y_cent_e,qclog));
822 check_nomsg( reject_lo_hi(tima, low_threshold, upp_threshold) );
823 if (count_good(tima) >= 2)
825 check_nomsg(master_median = cpl_image_get_median(tima));
826 check_nomsg(qc_ron_master = cpl_image_get_stdev(tima));
832 uves_msg_warning(
"Only %d good pixels in image. Setting QC parameters to -1",
835 uves_free_image(&tima);
840 "Median of pixel values",
843 sprintf(key_name,
"QC OUT%d RON MASTER", pn);
847 "Read noise frame in ADU",
864 if (chip != UVES_CHIP_BLUE) {
874 check_nomsg(avg_col = cpl_image_collapse_create(tima,1));
875 check_nomsg(cpl_image_divide_scalar(avg_col,cpl_image_get_size_x(tima)));
878 min = cpl_image_get_mean(avg_col) - 2;
879 max = cpl_image_get_mean(avg_col) + 2;
885 if (count_good(avg_col) >= 2)
887 check_nomsg(struct_col = cpl_image_get_stdev(avg_col));
892 uves_msg_warning(
"Only %d good pixels in image. Setting QC parameter to -1",
893 count_good(avg_col));
896 sprintf(key_name,
"%s%d%s",
"QC OUT",pn,
" STRUCTY");
900 "structure in Y (bias slope)",
905 check_nomsg(avg_row = cpl_image_collapse_create(tima,0));
906 check_nomsg(cpl_image_divide_scalar(avg_row,cpl_image_get_size_y(tima)));
909 min = cpl_image_get_mean(avg_row) - 2;
910 max = cpl_image_get_mean(avg_row) + 2;
916 if (count_good(avg_row) >= 2)
918 check_nomsg(struct_row = cpl_image_get_stdev(avg_row));
923 uves_msg_warning(
"Only %d good pixels in image. Setting QC parameter to -1",
924 count_good(avg_row));
928 sprintf(key_name,
"%s%d%s",
"QC OUT",pn,
" STRUCTX");
932 "structure in X (bias slope)",
939 uves_free_image(&avg_col);
940 uves_free_image(&avg_row);
941 uves_free_image(&tima);
960 uves_mbias_qc_ron_raw(
const cpl_image* rbia,
969 double qc_ron_raw=0.0;
970 double upp_threshold=0.0;
971 double low_threshold=0.0;
975 cpl_image* tima=NULL;
982 cpl_image_get_median_window(rbia,
986 y_cent_e)*(1 + extra));
989 cpl_image_get_median_window(rbia,
993 y_cent_e)*(1 - extra));
1002 check_nomsg( reject_lo_hi(tima, low_threshold, upp_threshold) );
1003 if (count_good(tima) >= 2)
1005 check_nomsg(qc_ron_raw = cpl_image_get_stdev(tima));
1010 uves_msg_warning(
"Only %d good pixels in image. Setting QC parameter to -1",
1021 sprintf(key_name,
"%s%d%s",
"QC OUT",pn,
" RON RAW");
1025 "Read noise frame in ADU",
1029 uves_free_image(&tima);
#define uves_msg_warning(...)
Print an warning message.
int uves_qclog_add_string(cpl_table *table, const char *key_name, const char *value, const char *key_help, const char *format)
Add string key to QC-LOG table.
int uves_qclog_delete(cpl_table **table)
delete QC-LOG table
int uves_qclog_add_double(cpl_table *table, const char *key_name, const double value, const char *key_help, const char *format)
Add double key to QC-LOG table.
int uves_qclog_add_int(cpl_table *table, const char *key_name, const int value, const char *key_help, const char *format)
Add integer key to QC-LOG table.
int uves_pfits_get_binx(const uves_propertylist *plist)
Find out the x binning factor.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
double uves_pfits_get_mjdobs(const uves_propertylist *plist)
Find out the modified julian observation date.
int uves_pfits_get_biny(const uves_propertylist *plist)
Find out the y binning factor.
bool uves_ccd_is_new(const uves_propertylist *plist)
Find out if CCD header is new.
double uves_pfits_get_exptime(const uves_propertylist *plist)
Find out the exposure time in seconds.
int uves_chip_get_index(enum uves_chip chip)
Convert to integer.
enum uves_chip uves_chip_get_first(bool blue)
Get first chip for blue or red arm.
cpl_error_code uves_pfits_set_extname(uves_propertylist *plist, const char *extname)
Write the EXTNAME keyword.
cpl_error_code uves_pfits_set_exptime(uves_propertylist *plist, double exptime)
Write the exposure time.
enum uves_chip uves_chip_get_next(enum uves_chip chip)
Get next chip.
#define uves_msg_debug(...)
Print a debug message.
const char * uves_chip_tostring_upper(enum uves_chip chip)
Convert to string.
int uves_correct_badpix_all(cpl_image *master_bias, uves_propertylist *mbias_header, enum uves_chip chip, int binx, int biny, int mark_bad, bool red_ccd_new)
Correct all bad pixels on a chip.
const char * uves_string_toupper(char *s)
Convert all lowercase characters in a string into uppercase characters.
cpl_table * uves_qclog_init(const uves_propertylist *raw_header, enum uves_chip chip)
Init QC-LOG table.
cpl_image * irplib_mkmaster_median(cpl_imagelist *images, const double kappa, const int nclip, const double tolerance)
Computes master frame by clean stack median of the input imagelist.
cpl_image * irplib_mkmaster_mean(cpl_imagelist *images, const double kappa, const int nclip, const double tolerance, const double klow, const double khigh, const int niter)
Computes master frame by clean stack mean of the input imagelist.