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
35cpl_error_code eris_ifu_detlin_load_frames(
const cpl_frameset *frameset,
36 int exposureCorrectionMode,
37 hdrl_imagelist **hdrl_imglist_on,
38 hdrl_imagelist **hdrl_imglist_off,
39 cpl_vector **vec_dit_on,
40 cpl_vector **vec_dit_off)
42 cpl_error_code ret = CPL_ERROR_NONE;
43 const cpl_frame *fr = NULL;
44 const char *fn = NULL;
45 cpl_size nr_dit_on = 0,
48 hdrl_image *tmp_img = NULL;
49 cpl_propertylist *pl = NULL;
51 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
52 cpl_ensure_code(hdrl_imglist_on, CPL_ERROR_NULL_INPUT);
53 cpl_ensure_code(hdrl_imglist_off, CPL_ERROR_NULL_INPUT);
54 cpl_ensure_code(vec_dit_on, CPL_ERROR_NULL_INPUT);
55 cpl_ensure_code(vec_dit_off, CPL_ERROR_NULL_INPUT);
61 *vec_dit_on = cpl_vector_new(cpl_frameset_get_size(frameset));
62 *vec_dit_off = cpl_vector_new(cpl_frameset_get_size(frameset));
68 fr = cpl_frameset_find_const(frameset, ERIS_IFU_RAW_LIN);
70 fn = cpl_frame_get_filename(fr);
71 eris_ifu_file_exists(fn);
73 exposureCorrectionMode, NULL);
75 pl = cpl_propertylist_load(fn, 0);
81 cpl_vector_set(*vec_dit_on, nr_dit_on++, dit);
84 cpl_vector_set(*vec_dit_off, nr_dit_off++, dit);
88 fr = cpl_frameset_find_const(frameset, NULL);
91 cpl_vector_set_size(*vec_dit_on, nr_dit_on);
92 cpl_vector_set_size(*vec_dit_off, nr_dit_off);
97 if (nr_dit_on != 2*nr_dit_off) {
98 cpl_msg_warning(cpl_func,
"Found %lld on-frames and %lld off-frames, "
99 "but twice as many on-frmaes than off-frames are expected",
100 nr_dit_on, nr_dit_off);
106 ret = cpl_error_get_code();
227eris_detlin_qc_lin_log(hdrl_imagelist* fit_coef, cpl_image* chi2,
228 cpl_image* dof, cpl_mask* mask, cpl_propertylist* linc_qclist)
233 cpl_image* image = NULL;
234 cpl_image* error = NULL;
238 for(cpl_size deg = 0; deg < planes; deg++)
243 cpl_image_power(error, 2.);
244 cpl_image_multiply(error, chi2);
245 cpl_image_divide(error, dof);
246 cpl_image_power(error, 0.5);
248 bpm = cpl_image_set_bpm(image, mask);
249 const double coeff = cpl_image_get_median(image);
250 cpl_image_set_bpm(image, bpm);
252 name_o1 = cpl_sprintf(
"ESO QC LIN COEF%d", (
int)deg);
254 cpl_propertylist_append_double(linc_qclist, name_o1, coeff);
255 cpl_propertylist_set_comment(linc_qclist, name_o1, ERIS_QC_LIN_COEF_C);
260 name_o2 = cpl_sprintf(
"ESO QC LIN COEF%d ERR", (
int)deg);
262 bpm = cpl_image_set_bpm(error, mask);
263 const double coeff_err = cpl_image_get_median(error);
264 cpl_image_set_bpm(error, bpm);
266 cpl_propertylist_append_double(linc_qclist, name_o2, coeff_err);
267 cpl_propertylist_set_comment(linc_qclist, name_o2, ERIS_QC_LIN_COEF_ERR_C);
274 return cpl_error_get_code();
276cpl_image* eris_ifu_detlin_compute_linearity(
277 const cpl_parameterlist *parlist,
278 const hdrl_imagelist *imglist,
279 const cpl_vector *vec_dit,
280 cpl_propertylist* qclog)
282 hdrl_parameter *hp = NULL;
283 cpl_image *bpm_fit = NULL;
285 cpl_ensure(parlist, CPL_ERROR_NULL_INPUT, NULL);
286 cpl_ensure(imglist, CPL_ERROR_NULL_INPUT, NULL);
287 cpl_ensure(vec_dit, CPL_ERROR_NULL_INPUT, NULL);
290 nr_vec = cpl_vector_get_size(vec_dit);
291 cpl_ensure(nr_img == nr_vec, CPL_ERROR_ILLEGAL_INPUT, NULL);
301 cpl_size sx = cpl_image_get_size_x(bpm_fit);
302 cpl_size sy = cpl_image_get_size_y(bpm_fit);
303 cpl_mask* mask = cpl_mask_new(sx, sy);
304 int* pbpm = cpl_image_get_data(bpm_fit);
305 cpl_binary* pmsk = cpl_mask_get_data(mask);
306 for (cpl_size j = 0; j < sy; j++) {
307 for (cpl_size i = 0; i < sx; i++) {
308 if(pbpm[i+j*sx] != 0 ) {
309 pmsk[i+j*sx] = BAD_PIX;
321 cpl_image_reject_from_mask(image, mask);
323 cpl_image_reject_from_mask(error, mask);
327 cpl_image * out_chi2 = NULL, * out_dof = NULL;
328 hdrl_imagelist * out_coef = NULL;
331 &out_chi2, &out_dof);
334 eris_detlin_qc_lin_log(out_coef, out_chi2, out_dof, mask, qclog);
336 cpl_image_delete(out_chi2);
337 cpl_image_delete(out_dof);
338 cpl_mask_delete(mask);
351cpl_mask* eris_ifu_detlin_filter_mask(
const cpl_mask *bpm,
352 const cpl_parameterlist *parlist)
354 cpl_mask *filtered = NULL;
355 const cpl_parameter *p = NULL;
358 const char *pfm = NULL;
359 cpl_filter_mode filter_mode = CPL_FILTER_CLOSING;
361 cpl_ensure(bpm, CPL_ERROR_NULL_INPUT, NULL);
362 cpl_ensure(parlist, CPL_ERROR_NULL_INPUT, NULL);
366 p = cpl_parameterlist_find_const(parlist,
367 REC_NAME_DETLIN
".post-filter-x");
368 pfx = cpl_parameter_get_int(p);
371 p = cpl_parameterlist_find_const(parlist,
372 REC_NAME_DETLIN
".post-filter-y");
373 pfy = cpl_parameter_get_int(p);
376 p = cpl_parameterlist_find_const(parlist,
377 REC_NAME_DETLIN
".post-filter-mode");
378 pfm = cpl_parameter_get_string(p);
380 if (!strcmp(pfm,
"closing")) {
381 filter_mode = CPL_FILTER_CLOSING ;
383 else if (!strcmp(pfm,
"dilation")) {
384 filter_mode = CPL_FILTER_DILATION ;
388 CPL_ERROR_ILLEGAL_INPUT,
389 "Filter mode can only be \"closing\" or \"dilation\" (not %s)",
394 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);
472cpl_table* eris_compute_gain(cpl_frameset* frameset)
475 cpl_ensure(frameset,CPL_ERROR_NULL_INPUT, NULL);
477 cpl_frame* frm = NULL;
479 cpl_image* img_on1 = NULL;
480 cpl_image* img_on2 = NULL;
481 cpl_image* img_on_dif = NULL;
482 cpl_image* img_on_sub = NULL;
485 cpl_image* img_of1 = NULL;
486 cpl_image* img_of2 = NULL;
487 cpl_image* img_of_dif = NULL;
488 cpl_image* img_of_sub = NULL;
490 cpl_table* res_tbl = NULL;
491 cpl_vector* dit_on = NULL;
492 cpl_vector* dit_of = NULL;
493 cpl_vector* exptime_on = NULL;
494 cpl_vector* exptime_of = NULL;
495 cpl_propertylist* plist = NULL;
506 double sig_on_dif = 0;
507 double sig_of_dif = 0;
520 double exptime_ref = 0;
521 double exptime_tmp = 0;
526 cpl_size nff = cpl_frameset_get_size(frameset);
527 cpl_frameset* son = cpl_frameset_new();
528 cpl_frameset* sof = cpl_frameset_new();
532 for(i = 0; i < nff; i++) {
533 frm = cpl_frameset_get_position(frameset, i);
534 frm_dup = cpl_frame_duplicate(frm);
536 cpl_frameset_insert(son, frm_dup);
538 cpl_frameset_insert(sof, frm_dup);
542 non = cpl_frameset_get_size(son);
543 nof = cpl_frameset_get_size(sof);
544 nfr = (non <= nof) ? non : nof;
546 dit_on = cpl_vector_new(nfr);
547 dit_of = cpl_vector_new(nfr);
548 exptime_on = cpl_vector_new(nfr);
549 exptime_of = cpl_vector_new(nfr);
551 for(i = 0; i < nfr; i++) {
553 frm = cpl_frameset_get_position(son, i);
554 name = (
char*) cpl_frame_get_filename(frm);
555 plist = cpl_propertylist_load(name, 0);
557 exptime_ref = cpl_propertylist_get_double(plist,
"EXPTIME");
558 cpl_propertylist_delete(plist);
559 cpl_vector_set(dit_on, i, dit_ref);
560 cpl_vector_set(exptime_on, i, exptime_ref);
562 frm = cpl_frameset_get_position(sof, i);
563 name = (
char*) cpl_frame_get_filename(frm);
564 plist = cpl_propertylist_load(name, 0);
566 exptime_ref = cpl_propertylist_get_double(plist,
"EXPTIME");
567 cpl_propertylist_delete(plist);
568 cpl_vector_set(dit_of, i, dit_ref);
569 cpl_vector_set(exptime_of, i, exptime_ref);
573 res_tbl = cpl_table_new(nfr);
574 cpl_table_new_column(res_tbl,
"adu", CPL_TYPE_DOUBLE);
575 cpl_table_new_column(res_tbl,
"gain", CPL_TYPE_DOUBLE);
577 for(i = 0; i < nfr; i++) {
578 frm = cpl_frameset_get_position(son, i);
579 name = (
char*) cpl_frame_get_filename(frm);
580 img_on1 = cpl_image_load(name, CPL_TYPE_DOUBLE, 0, 0);
582 frm = cpl_frameset_get_position(sof, i);
583 name = (
char*) cpl_frame_get_filename(frm);
584 img_of1 = cpl_image_load(name, CPL_TYPE_DOUBLE, 0, 0);
587 dit_ref = cpl_vector_get(dit_on, i);
588 exptime_ref = cpl_vector_get(exptime_on, i);
590 for(m = 0; m < nfr; m++) {
592 frm = cpl_frameset_get_position(son, m);
593 name = (
char*) cpl_frame_get_filename(frm);
594 dit_tmp = cpl_vector_get(dit_on, m);
595 exptime_tmp = cpl_vector_get(exptime_on, m);
596 if(dit_tmp == dit_ref && exptime_tmp == exptime_ref) {
598 img_on2 = cpl_image_load(name, CPL_TYPE_DOUBLE, 0, 0);
599 frm = cpl_frameset_get_position(sof, m);
600 name = (
char*) cpl_frame_get_filename(frm);
601 img_of2 = cpl_image_load(name, CPL_TYPE_DOUBLE, 0, 0);
603 img_on_dif = cpl_image_subtract_create(img_on1, img_on2);
604 img_of_dif = cpl_image_subtract_create(img_of1, img_of2);
606 img_on_sub = cpl_image_extract(img_on_dif, llx, lly, urx, ury);
607 img_of_sub = cpl_image_extract(img_of_dif, llx, lly, urx, ury);
609 eris_get_clean_mean_window(img_on1, llx, lly, urx, ury, kappa,
610 nclip, &avg_on1, &std);
611 eris_get_clean_mean_window(img_on2, llx, lly, urx, ury, kappa,
612 nclip, &avg_on2, &std);
613 eris_get_clean_mean_window(img_of1, llx, lly, urx, ury, kappa,
614 nclip, &avg_of1, &std);
615 eris_get_clean_mean_window(img_of2, llx, lly, urx, ury, kappa,
616 nclip, &avg_of2, &std);
631 eris_get_clean_mean_window(img_on_dif, llx, lly, urx, ury, kappa,
632 nclip, ¢re, &sig_on_dif);
633 eris_get_clean_mean_window(img_of_dif, llx, lly, urx, ury, kappa,
634 nclip, ¢re, &sig_of_dif);
646 cpl_image_delete(img_on2);
647 cpl_image_delete(img_of2);
648 cpl_image_delete(img_on_dif);
649 cpl_image_delete(img_of_dif);
650 cpl_image_delete(img_on_sub);
651 cpl_image_delete(img_of_sub);
653 gain = ( (avg_on1 + avg_on2) - (avg_of1 + avg_of2) ) /
654 ( (sig_on_dif * sig_on_dif) - (sig_of_dif * sig_of_dif) );
656 cpl_table_set_double(res_tbl,
"gain", m, gain);
657 cpl_table_set_double(res_tbl,
"adu", m,
658 ( (avg_on1 + avg_on2) / 2 - (avg_of1 + avg_of2) / 2) );
669 cpl_image_delete(img_on1);
670 cpl_image_delete(img_of1);
681 cpl_vector_delete(dit_on);
682 cpl_vector_delete(dit_of);
683 cpl_vector_delete(exptime_on);
684 cpl_vector_delete(exptime_of);
685 cpl_frameset_delete(son);
686 cpl_frameset_delete(sof);
float eris_ifu_get_dit(cpl_propertylist *header)
Determine if a frame is a Sky frame or not.
bool eris_ifu_frame_is_on(const cpl_frame *fr)
Determine if a frame is obtained with 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)
Read a raw detector exposure, perform some correction, add noise data.
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_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.