21#include "eris_ifu_detlin_static.h"
22#include "eris_ifu_error.h"
23#include "eris_ifu_utils.h"
24#include "eris_ifu_debug.h"
25#include "eris_ifu_dfs.h"
26#include "eris_utils.h"
27#include "eris_ifu_functions.h"
28#include "eris_pfits.h"
29#include "eris_utils.h"
33#define FILE_NAME_SZ 256
75 int exposureCorrectionMode,
76 hdrl_imagelist **hdrl_imglist_on,
77 hdrl_imagelist **hdrl_imglist_off,
78 cpl_vector **vec_dit_on,
79 cpl_vector **vec_dit_off)
81 cpl_error_code ret = CPL_ERROR_NONE;
82 const cpl_frame *fr = NULL;
83 const char *fn = NULL;
84 cpl_size nr_dit_on = 0,
87 hdrl_image *tmp_img = NULL;
88 cpl_propertylist *pl = NULL;
90 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
91 cpl_ensure_code(hdrl_imglist_on, CPL_ERROR_NULL_INPUT);
92 cpl_ensure_code(hdrl_imglist_off, CPL_ERROR_NULL_INPUT);
93 cpl_ensure_code(vec_dit_on, CPL_ERROR_NULL_INPUT);
94 cpl_ensure_code(vec_dit_off, CPL_ERROR_NULL_INPUT);
100 *vec_dit_on = cpl_vector_new(cpl_frameset_get_size(frameset));
101 *vec_dit_off = cpl_vector_new(cpl_frameset_get_size(frameset));
107 fr = cpl_frameset_find_const(frameset, ERIS_IFU_RAW_LIN);
109 fn = cpl_frame_get_filename(fr);
112 exposureCorrectionMode, NULL);
114 pl = cpl_propertylist_load(fn, 0);
120 cpl_vector_set(*vec_dit_on, nr_dit_on++, dit);
123 cpl_vector_set(*vec_dit_off, nr_dit_off++, dit);
127 fr = cpl_frameset_find_const(frameset, NULL);
130 cpl_vector_set_size(*vec_dit_on, nr_dit_on);
131 cpl_vector_set_size(*vec_dit_off, nr_dit_off);
136 if (nr_dit_on != 2*nr_dit_off) {
137 cpl_msg_warning(cpl_func,
"Found %lld on-frames and %lld off-frames, "
138 "but twice as many on-frmaes than off-frames are expected",
139 nr_dit_on, nr_dit_off);
145 ret = cpl_error_get_code();
176eris_detlin_qc_lin_log(hdrl_imagelist* fit_coef, cpl_image* chi2,
177 cpl_image* dof, cpl_mask* mask, cpl_propertylist* linc_qclist)
182 cpl_image* image = NULL;
183 cpl_image* error = NULL;
187 for(cpl_size deg = 0; deg < planes; deg++)
192 cpl_image_power(error, 2.);
193 cpl_image_multiply(error, chi2);
194 cpl_image_divide(error, dof);
195 cpl_image_power(error, 0.5);
197 bpm = cpl_image_set_bpm(image, mask);
198 const double coeff = cpl_image_get_median(image);
199 cpl_image_set_bpm(image, bpm);
201 name_o1 = cpl_sprintf(
"ESO QC LIN COEF%d", (
int)deg);
203 cpl_propertylist_append_double(linc_qclist, name_o1, coeff);
204 cpl_propertylist_set_comment(linc_qclist, name_o1, ERIS_QC_LIN_COEF_C);
209 name_o2 = cpl_sprintf(
"ESO QC LIN COEF%d ERR", (
int)deg);
211 bpm = cpl_image_set_bpm(error, mask);
212 const double coeff_err = cpl_image_get_median(error);
213 cpl_image_set_bpm(error, bpm);
215 cpl_propertylist_append_double(linc_qclist, name_o2, coeff_err);
216 cpl_propertylist_set_comment(linc_qclist, name_o2, ERIS_QC_LIN_COEF_ERR_C);
223 return cpl_error_get_code();
250 const cpl_parameterlist *parlist,
251 const hdrl_imagelist *imglist,
252 const cpl_vector *vec_dit,
253 cpl_propertylist* qclog)
255 hdrl_parameter *hp = NULL;
256 cpl_image *bpm_fit = NULL;
258 cpl_ensure(parlist, CPL_ERROR_NULL_INPUT, NULL);
259 cpl_ensure(imglist, CPL_ERROR_NULL_INPUT, NULL);
260 cpl_ensure(vec_dit, CPL_ERROR_NULL_INPUT, NULL);
263 nr_vec = cpl_vector_get_size(vec_dit);
264 cpl_ensure(nr_img == nr_vec, CPL_ERROR_ILLEGAL_INPUT, NULL);
274 cpl_size sx = cpl_image_get_size_x(bpm_fit);
275 cpl_size sy = cpl_image_get_size_y(bpm_fit);
276 cpl_mask* mask = cpl_mask_new(sx, sy);
277 int* pbpm = cpl_image_get_data(bpm_fit);
278 cpl_binary* pmsk = cpl_mask_get_data(mask);
279 for (cpl_size j = 0; j < sy; j++) {
280 for (cpl_size i = 0; i < sx; i++) {
281 if(pbpm[i+j*sx] != 0 ) {
282 pmsk[i+j*sx] = BAD_PIX;
294 cpl_image_reject_from_mask(image, mask);
296 cpl_image_reject_from_mask(error, mask);
300 cpl_image * out_chi2 = NULL, * out_dof = NULL;
301 hdrl_imagelist * out_coef = NULL;
304 &out_chi2, &out_dof);
307 eris_detlin_qc_lin_log(out_coef, out_chi2, out_dof, mask, qclog);
309 cpl_image_delete(out_chi2);
310 cpl_image_delete(out_dof);
311 cpl_mask_delete(mask);
344 const cpl_parameterlist *parlist)
346 cpl_mask *filtered = NULL;
347 const cpl_parameter *p = NULL;
350 const char *pfm = NULL;
351 cpl_filter_mode filter_mode = CPL_FILTER_CLOSING;
353 cpl_ensure(bpm, CPL_ERROR_NULL_INPUT, NULL);
354 cpl_ensure(parlist, CPL_ERROR_NULL_INPUT, NULL);
358 p = cpl_parameterlist_find_const(parlist,
359 REC_NAME_DETLIN
".post-filter-x");
360 pfx = cpl_parameter_get_int(p);
363 p = cpl_parameterlist_find_const(parlist,
364 REC_NAME_DETLIN
".post-filter-y");
365 pfy = cpl_parameter_get_int(p);
368 p = cpl_parameterlist_find_const(parlist,
369 REC_NAME_DETLIN
".post-filter-mode");
370 pfm = cpl_parameter_get_string(p);
372 if (!strcmp(pfm,
"closing")) {
373 filter_mode = CPL_FILTER_CLOSING ;
375 else if (!strcmp(pfm,
"dilation")) {
376 filter_mode = CPL_FILTER_DILATION ;
380 CPL_ERROR_ILLEGAL_INPUT,
381 "Filter mode can only be \"closing\" or \"dilation\" (not %s)",
386 if ((pfx > 0) && (pfy > 0)) {
424eris_get_clean_mean_window(cpl_image* img,
425 int llx,
int lly,
int urx,
int ury,
426 const int kappa,
const int nclip,
427 double* local_clean_mean,
434 cpl_image * tmp = NULL;
435 cpl_stats * stats = NULL;
438 tmp = cpl_image_extract(img, llx, lly, urx, ury);
439 cpl_image_accept_all(tmp);
440 for(i = 0; i < nclip; i++) {
442 cpl_stats_delete(stats);
443 stats = cpl_stats_new_from_image(tmp, CPL_STATS_MEAN | CPL_STATS_STDEV);
444 mean = cpl_stats_get_mean(stats);
445 stdev = cpl_stats_get_stdev(stats);
447 double threshold = kappa * stdev;
448 double lo_cut = mean - threshold;
449 double hi_cut = mean + threshold;
450 cpl_image_accept_all(tmp);
451 cpl_mask* mask = cpl_mask_threshold_image_create(tmp, lo_cut, hi_cut);
454 cpl_image_reject_from_mask(tmp, mask);
455 cpl_mask_delete(mask);
458 *local_clean_mean = mean;
459 *clean_stdev = stdev;
460 cpl_image_delete(tmp);
461 cpl_stats_delete(stats);
496 cpl_ensure(frameset,CPL_ERROR_NULL_INPUT, NULL);
498 cpl_frame* frm = NULL;
500 cpl_image* img_on1 = NULL;
501 cpl_image* img_on2 = NULL;
502 cpl_image* img_on_dif = NULL;
503 cpl_image* img_on_sub = NULL;
506 cpl_image* img_of1 = NULL;
507 cpl_image* img_of2 = NULL;
508 cpl_image* img_of_dif = NULL;
509 cpl_image* img_of_sub = NULL;
511 cpl_table* res_tbl = NULL;
512 cpl_vector* dit_on = NULL;
513 cpl_vector* dit_of = NULL;
514 cpl_vector* exptime_on = NULL;
515 cpl_vector* exptime_of = NULL;
516 cpl_propertylist* plist = NULL;
527 double sig_on_dif = 0;
528 double sig_of_dif = 0;
541 double exptime_ref = 0;
542 double exptime_tmp = 0;
547 cpl_size nff = cpl_frameset_get_size(frameset);
548 cpl_frameset* son = cpl_frameset_new();
549 cpl_frameset* sof = cpl_frameset_new();
553 for(i = 0; i < nff; i++) {
554 frm = cpl_frameset_get_position(frameset, i);
555 frm_dup = cpl_frame_duplicate(frm);
557 cpl_frameset_insert(son, frm_dup);
559 cpl_frameset_insert(sof, frm_dup);
563 non = cpl_frameset_get_size(son);
564 nof = cpl_frameset_get_size(sof);
565 nfr = (non <= nof) ? non : nof;
567 dit_on = cpl_vector_new(nfr);
568 dit_of = cpl_vector_new(nfr);
569 exptime_on = cpl_vector_new(nfr);
570 exptime_of = cpl_vector_new(nfr);
572 for(i = 0; i < nfr; i++) {
574 frm = cpl_frameset_get_position(son, i);
575 name = (
char*) cpl_frame_get_filename(frm);
576 plist = cpl_propertylist_load(name, 0);
578 exptime_ref = cpl_propertylist_get_double(plist,
"EXPTIME");
579 cpl_propertylist_delete(plist);
580 cpl_vector_set(dit_on, i, dit_ref);
581 cpl_vector_set(exptime_on, i, exptime_ref);
583 frm = cpl_frameset_get_position(sof, i);
584 name = (
char*) cpl_frame_get_filename(frm);
585 plist = cpl_propertylist_load(name, 0);
587 exptime_ref = cpl_propertylist_get_double(plist,
"EXPTIME");
588 cpl_propertylist_delete(plist);
589 cpl_vector_set(dit_of, i, dit_ref);
590 cpl_vector_set(exptime_of, i, exptime_ref);
594 res_tbl = cpl_table_new(nfr);
595 cpl_table_new_column(res_tbl,
"adu", CPL_TYPE_DOUBLE);
596 cpl_table_new_column(res_tbl,
"gain", CPL_TYPE_DOUBLE);
598 for(i = 0; i < nfr; i++) {
599 frm = cpl_frameset_get_position(son, i);
600 name = (
char*) cpl_frame_get_filename(frm);
601 img_on1 = cpl_image_load(name, CPL_TYPE_DOUBLE, 0, 0);
603 frm = cpl_frameset_get_position(sof, i);
604 name = (
char*) cpl_frame_get_filename(frm);
605 img_of1 = cpl_image_load(name, CPL_TYPE_DOUBLE, 0, 0);
608 dit_ref = cpl_vector_get(dit_on, i);
609 exptime_ref = cpl_vector_get(exptime_on, i);
611 for(m = 0; m < nfr; m++) {
613 frm = cpl_frameset_get_position(son, m);
614 name = (
char*) cpl_frame_get_filename(frm);
615 dit_tmp = cpl_vector_get(dit_on, m);
616 exptime_tmp = cpl_vector_get(exptime_on, m);
617 if(dit_tmp == dit_ref && exptime_tmp == exptime_ref) {
619 img_on2 = cpl_image_load(name, CPL_TYPE_DOUBLE, 0, 0);
620 frm = cpl_frameset_get_position(sof, m);
621 name = (
char*) cpl_frame_get_filename(frm);
622 img_of2 = cpl_image_load(name, CPL_TYPE_DOUBLE, 0, 0);
624 img_on_dif = cpl_image_subtract_create(img_on1, img_on2);
625 img_of_dif = cpl_image_subtract_create(img_of1, img_of2);
627 img_on_sub = cpl_image_extract(img_on_dif, llx, lly, urx, ury);
628 img_of_sub = cpl_image_extract(img_of_dif, llx, lly, urx, ury);
630 eris_get_clean_mean_window(img_on1, llx, lly, urx, ury, kappa,
631 nclip, &avg_on1, &std);
632 eris_get_clean_mean_window(img_on2, llx, lly, urx, ury, kappa,
633 nclip, &avg_on2, &std);
634 eris_get_clean_mean_window(img_of1, llx, lly, urx, ury, kappa,
635 nclip, &avg_of1, &std);
636 eris_get_clean_mean_window(img_of2, llx, lly, urx, ury, kappa,
637 nclip, &avg_of2, &std);
652 eris_get_clean_mean_window(img_on_dif, llx, lly, urx, ury, kappa,
653 nclip, ¢re, &sig_on_dif);
654 eris_get_clean_mean_window(img_of_dif, llx, lly, urx, ury, kappa,
655 nclip, ¢re, &sig_of_dif);
667 cpl_image_delete(img_on2);
668 cpl_image_delete(img_of2);
669 cpl_image_delete(img_on_dif);
670 cpl_image_delete(img_of_dif);
671 cpl_image_delete(img_on_sub);
672 cpl_image_delete(img_of_sub);
674 gain = ( (avg_on1 + avg_on2) - (avg_of1 + avg_of2) ) /
675 ( (sig_on_dif * sig_on_dif) - (sig_of_dif * sig_of_dif) );
677 cpl_table_set_double(res_tbl,
"gain", m, gain);
678 cpl_table_set_double(res_tbl,
"adu", m,
679 ( (avg_on1 + avg_on2) / 2 - (avg_of1 + avg_of2) / 2) );
690 cpl_image_delete(img_on1);
691 cpl_image_delete(img_of1);
702 cpl_vector_delete(dit_on);
703 cpl_vector_delete(dit_of);
704 cpl_vector_delete(exptime_on);
705 cpl_vector_delete(exptime_of);
706 cpl_frameset_delete(son);
707 cpl_frameset_delete(sof);
cpl_mask * eris_ifu_detlin_filter_mask(const cpl_mask *bpm, const cpl_parameterlist *parlist)
Apply morphological filtering to a bad pixel mask.
cpl_error_code eris_ifu_detlin_load_frames(const cpl_frameset *frameset, int exposureCorrectionMode, hdrl_imagelist **hdrl_imglist_on, hdrl_imagelist **hdrl_imglist_off, cpl_vector **vec_dit_on, cpl_vector **vec_dit_off)
Load linearity calibration frames from a frameset.
cpl_table * eris_compute_gain(cpl_frameset *frameset)
Compute detector gain from linearity frames.
cpl_image * eris_ifu_detlin_compute_linearity(const cpl_parameterlist *parlist, const hdrl_imagelist *imglist, const cpl_vector *vec_dit, cpl_propertylist *qclog)
Compute detector linearity bad pixel map.
float eris_ifu_get_dit(cpl_propertylist *header)
Get the detector integration time (DIT) from FITS header.
bool eris_ifu_frame_is_on(const cpl_frame *fr)
Determine if a frame has calibration lamps ON or OFF.
#define CHECK_ERROR_STATE(void)
Check the CPL error state, and exit the try-block if not CPL_ERROR_NONE.
#define BRK_WITH_ERROR_MSG(code,...)
Set a new CPL error, and exit the try-block.
#define TRY
Beginning of a TRY-block.
#define CATCH
End of a TRY-block, beginning of a CATCH-block.
#define BRK_IF_NULL(function)
If function is or returns a NULL pointer, then the try-block is exited.
#define CATCH_MSGS()
Displays an error message stack.
hdrl_image * eris_ifu_load_exposure_file(const char *filename, int exposureCorrectionMode, cpl_image *dqi)
Load a raw detector exposure from file with corrections and noise.
void eris_ifu_free_propertylist(cpl_propertylist **item)
Free memory and set pointer to null.
void eris_ifu_free_vector(cpl_vector **item)
Free memory and set pointer to null.
cpl_error_code eris_ifu_file_exists(const char *filename)
**
cpl_error_code eris_ifu_get_badpix_qc_from_ima(const cpl_image *image, cpl_propertylist *qc_list, const char *prefix)
compute QC keyword with number of bad pixels and fraction to total
void eris_ifu_free_hdrl_imagelist(hdrl_imagelist **item)
Free memory and set pointer to null.
void eris_ifu_free_image(cpl_image **item)
Free memory and set pointer to null.
void eris_ifu_free_mask(cpl_mask **item)
Free memory and set pointer to null.
void eris_ifu_free_hdrl_parameter(hdrl_parameter **item)
Free memory and set pointer to null.
double eris_pfits_get_dit(const cpl_propertylist *plist)
find out the DIT value
cpl_error_code eris_check_error_code(const char *func_id)
handle CPL errors
hdrl_parameter * hdrl_bpm_fit_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse a parameterlist to create input parameters for the BPM_FIT.
int hdrl_bpm_fit_parameter_get_degree(const hdrl_parameter *p)
get degree of polynomial fit of parameter
cpl_error_code hdrl_bpm_fit_compute(const hdrl_parameter *par, const hdrl_imagelist *data, const cpl_vector *sample_pos, cpl_image **out_mask)
compute bad pixel map based on fitting a stack of images
cpl_mask * hdrl_bpm_filter(const cpl_mask *input_mask, cpl_size kernel_nx, cpl_size kernel_ny, cpl_filter_mode filter)
Allows the growing and shrinking of bad pixel masks. It can be used to e.g. set pixels to bad if the ...
cpl_error_code hdrl_fit_polynomial_imagelist(const hdrl_imagelist *list, const cpl_vector *samplepos, const int degree, hdrl_imagelist **coef, cpl_image **chi2, cpl_image **dof)
weighted least squares polynomial fit of each pixel of a imagelist
cpl_image * hdrl_image_get_error(hdrl_image *himg)
get error as cpl image
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.