ERIS Pipeline Reference Manual 1.8.15
eris_nix_flat_lamp.c
1/* $Id$
2 *
3 * This file is part of the ERIS Pipeline
4 * Copyright (C) 2017 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/*
22 * $Author$
23 * $Date$
24 * $Revision$
25 */
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30
31/*-----------------------------------------------------------------------------
32 Includes
33 -----------------------------------------------------------------------------*/
34
35#include <string.h>
36#include <stdlib.h>
37#include "eris_utils.h"
38#include "eris_nix_utils.h"
39#include "eris_pfits.h"
40#include "eris_dfs.h"
41#include "eris_nix_dfs.h"
42#include "eris_nix_master_bpm.h"
43#include "eris_nix_master_dark.h"
44#include "eris_nix_gain_linearity.h"
45#include <hdrl.h>
46
47#include <cpl.h>
48
49/*-----------------------------------------------------------------------------
50 Static variables
51 -----------------------------------------------------------------------------*/
52
53static const char eris_nix_flat_lamp_description[] =
54"This recipe reduces a set of calibration lamp frames to produce \n"
55ERIS_NIX_MASTER_FLAT_LAMP_HIFREQ_PRO_CATG", "
56ERIS_NIX_MASTER_FLAT_LAMP_LOFREQ_PRO_CATG" and\n"
57ERIS_NIX_MASTER_BPM_LAMP_PRO_CATG" results.\n"
58"\n"
59"Input files:\n"
60" The recipe works either with a set of lamp-on/lamp-off pairs:\n"
61"\n"
62" DO CATG Explanation Req. #Frames\n"
63" ------- ----------- --- -------\n"
64" "ERIS_NIX_RAW_FLAT_LAMP_ON_DO_CATG
65 " lamp-on frames Y >min-coadds\n"
66" "ERIS_NIX_RAW_FLAT_LAMP_OFF_DO_CATG
67 " lamp-off frames Y = #lamp-on\n"
68" "ERIS_NIX_MASTER_DARK_IMG_PRO_CATG
69 " a MASTER_DARK with Y 1\n"
70" matching detector \n"
71" configuration\n"
72" "ERIS_NIX_GAIN_PRO_CATG
73 " DETMON gain N 0 or 1\n"
74" information e.g. in\n"
75" file \n"
76" detmon_ir_lg_gain_table.fits\n"
77" "ERIS_NIX_COEFFS_CUBE_PRO_CATG
78 " DETMON linearity N 0 or 1\n"
79" curves e.g. in file \n"
80" detmon_ir_coeffs_cube.fits\n"
81" "ERIS_NIX_NL_BPM_PRO_CATG
82 " DETMON non-linear bpm N 0 or 1\n"
83" e.g. in file \n"
84" detmon_ir_lg_bpm.fits\n"
85"\n"
86" or with a series of lamp-on frames:\n"
87"\n"
88" "ERIS_NIX_RAW_FLAT_LAMP_ON_DO_CATG
89 " lamp-on frames Y >min-coadds\n"
90" "ERIS_NIX_MASTER_DARK_IMG_PRO_CATG
91 " a MASTER_DARK with Y 1\n"
92" matching detector \n"
93" configuration\n"
94" "ERIS_NIX_GAIN_PRO_CATG
95 " DETMON gain info N 0 or 1\n"
96" e.g. in file \n"
97" detmon_ir_lg_gain_table.fits\n"
98" "ERIS_NIX_COEFFS_CUBE_PRO_CATG
99 " DETMON linearity N 0 or 1\n"
100" curves e.g. in file \n"
101" detmon_ir_coeffs_cube.fits\n"
102" "ERIS_NIX_NL_BPM_PRO_CATG
103 " DETMON non-linear bpm N 0 or 1\n"
104" e.g. in file \n"
105" detmon_ir_lg_bpm.fits\n"
106"\n"
107"Output files:\n"
108"\n"
109" DO CATG Explanation \n"
110" ------- ----------- \n"
111" "ERIS_NIX_MASTER_FLAT_LAMP_HIFREQ_PRO_CATG
112 " The required HIFREQ flatfield.\n"
113" "ERIS_NIX_MASTER_FLAT_LAMP_LOFREQ_PRO_CATG
114 " The required LOFREQ flatfield.\n"
115"\n"
116" "ERIS_NIX_MASTER_BPM_LAMP_PRO_CATG
117 " The required master BPM flatfield.\n"
118"\n"
119" The HIFREQ output will be a FITS file named \n"
120" 'master_flat_lamp_hifreq.fits', with extensions:\n"
121" - DATA, with the flatfield data.\n"
122" - ERR, with the flatfield error plane.\n"
123" - DQ, with the flatfield data quality plane.\n"
124" - COLD_BPM, with a bpm for the 'cold' pixels.\n"
125" - CONFIDENCE, with the flatfield confidence plane.\n"
126"\n"
127" The LOFREQ output will be a FITS file named \n"
128" 'master_flat_lamp_lofreq.fits', with extensions:\n"
129" - DATA, with the flatfield data.\n"
130" - ERR, with the flatfield error plane.\n"
131" - DQ, with the flatfield data quality plane.\n"
132" - CONFIDENCE, with the flatfield confidence plane.\n"
133"\n"
134" The master BPM output will be a FITS file named \n"
135" 'master_bpm_lamp.fits'. Common pixel values are:\n"
136" - 512, 'hot' pixel.\n"
137" - 1024, 'cold' pixel.\n"
138" - 32768, 'non-linear' pixel.\n"
139"\n";
140
141#define RECIPE_NAME "eris_nix_flat_lamp"
142#define CONTEXT "eris."RECIPE_NAME
143/*-----------------------------------------------------------------------------
144 Private function prototypes
145 -----------------------------------------------------------------------------*/
146
147cpl_recipe_define(eris_nix_flat_lamp, ERIS_BINARY_VERSION, "John Lightfoot",
148 PACKAGE_BUGREPORT, "2017", "Calculate a "
149 ERIS_NIX_MASTER_FLAT_LAMP_HIFREQ_PRO_CATG", "
150 ERIS_NIX_MASTER_FLAT_LAMP_LOFREQ_PRO_CATG" and "
151 ERIS_NIX_MASTER_BPM_LAMP_PRO_CATG,
152 eris_nix_flat_lamp_description);
153
154/*-----------------------------------------------------------------------------
155 Function code
156 -----------------------------------------------------------------------------*/
157
158/*----------------------------------------------------------------------------*/
166/*----------------------------------------------------------------------------*/
167
168static cpl_error_code eris_nix_flat_lamp_fill_parameterlist(
169 cpl_parameterlist *self) {
170
171 if (cpl_error_get_code() != CPL_ERROR_NONE) return cpl_error_get_code();
172
173 cpl_parameterlist * bpm_parlist = NULL;
174 cpl_parameterlist * collapse_parlist = NULL;
175 hdrl_parameter * filter_defaults = NULL;
176 hdrl_parameter * flat_defaults = NULL;
177 cpl_parameterlist * flat_parlist = NULL;
178 hdrl_parameter * legendre_defaults = NULL;
179 hdrl_parameter * minmax_defaults = NULL;
180 hdrl_parameter * sigclip_defaults = NULL;
181
182 /* generate the general parameter list for the collapse */
183 hdrl_parameter * mode_def =
184 hdrl_collapse_mode_parameter_create(10., 1., 0., HDRL_MODE_MEDIAN, 0);
185 sigclip_defaults = hdrl_collapse_sigclip_parameter_create(10.0, 10.0, 3);
186 minmax_defaults = hdrl_collapse_minmax_parameter_create(50, 50);
187 collapse_parlist = hdrl_collapse_parameter_create_parlist(CONTEXT,
188 "collapse", "MEDIAN", sigclip_defaults,
189 minmax_defaults,mode_def);
190
191 /* add the subset of parameters to be used, i.e. leave out 'minmax' */
192
193 for (const cpl_parameter * p =
194 cpl_parameterlist_get_first_const(collapse_parlist);
195 p != NULL;
196 p = cpl_parameterlist_get_next_const(collapse_parlist)) {
197
198 const char * pname = cpl_parameter_get_name(p);
199 if (strstr(pname, "minmax") == NULL) {
200 cpl_parameter * duplicate = cpl_parameter_duplicate(p);
201 cpl_parameterlist_append(self, duplicate);
202 }
203 }
204
205 /* generate the general parameter list for the flat-field calculation */
206
207 flat_defaults = hdrl_flat_parameter_create(21, 21, HDRL_FLAT_FREQ_HIGH);
208 flat_parlist = hdrl_flat_parameter_create_parlist(CONTEXT, "flat",
209 flat_defaults);
210
211 for (const cpl_parameter * p =
212 cpl_parameterlist_get_first(flat_parlist);
213 p != NULL;
214 p = cpl_parameterlist_get_next(flat_parlist)) {
215 cpl_parameter * duplicate = cpl_parameter_duplicate(p);
216 cpl_parameterlist_append(self, duplicate);
217 }
218
219 /* Get the general parameter list for the cold-pixel bpm */
220
221 filter_defaults = hdrl_bpm_2d_parameter_create_filtersmooth(5.0, 20.0, 3,
222 CPL_FILTER_MEDIAN, CPL_BORDER_NOP, 21, 21);
223 legendre_defaults = hdrl_bpm_2d_parameter_create_legendresmooth(4, 5, 6,
224 20, 21, 11, 12, 2, 10);
225 bpm_parlist = hdrl_bpm_2d_parameter_create_parlist(CONTEXT, "coldpix",
226 "FILTER", filter_defaults, legendre_defaults);
227
228 for (const cpl_parameter * p =
229 cpl_parameterlist_get_first_const(bpm_parlist);
230 p != NULL;
231 p = cpl_parameterlist_get_next_const(bpm_parlist)) {
232 cpl_parameter * duplicate = cpl_parameter_duplicate(p);
233 cpl_parameterlist_append(self, duplicate);
234 }
235
236 /* the minimum number of lamp_on - lamp_off images acceptable for the
237 calculation of the flat */
238
239 cpl_parameter * cp = NULL;
240 cp = cpl_parameter_new_value(CONTEXT".min_coadds", CPL_TYPE_INT,
241 "minimum acceptable number of (lamp_on - "
242 "lamp_off) images", CONTEXT, 1);
243 cpl_parameter_set_alias(cp, CPL_PARAMETER_MODE_CLI, "min-coadds");
244 cpl_parameter_disable(cp, CPL_PARAMETER_MODE_ENV);
245 cpl_parameterlist_append(self, cp);
246
247 /* coords of pixel whose value to be used for diagnostics during
248 reduction */
249
250 cp = cpl_parameter_new_value(CONTEXT".x_probe", CPL_TYPE_INT,
251 "x coord of diagnostic pixel",
252 CONTEXT, -1);
253 cpl_parameter_set_alias(cp, CPL_PARAMETER_MODE_CLI, "x-probe");
254 cpl_parameter_disable(cp, CPL_PARAMETER_MODE_ENV);
255 cpl_parameterlist_append(self, cp);
256
257 cp = cpl_parameter_new_value(CONTEXT".y_probe", CPL_TYPE_INT,
258 "y coord of diagnostic pixel",
259 CONTEXT, -1);
260 cpl_parameter_set_alias(cp, CPL_PARAMETER_MODE_CLI, "y-probe");
261 cpl_parameter_disable(cp, CPL_PARAMETER_MODE_ENV);
262 cpl_parameterlist_append(self, cp);
263
264 cp = cpl_parameter_new_value(CONTEXT".saturation_pos", CPL_TYPE_DOUBLE,
265 "positive saturation level (for QC). If -1 uses the value "
266 "of the parameter saturation_limit from the input GAIN_INFO table."
267 "Else uses the value set by the user. Recommended values are:"
268 "15000 for slow readout mode; 46500 for fast readout mode.",
269 CONTEXT, -1.0);
270 cpl_parameter_set_alias(cp, CPL_PARAMETER_MODE_CLI, "saturation_pos");
271 cpl_parameter_disable(cp, CPL_PARAMETER_MODE_ENV);
272 cpl_parameterlist_append(self, cp);
273
274 cp = cpl_parameter_new_value(CONTEXT".saturation_neg", CPL_TYPE_DOUBLE,
275 "negative saturation level (for QC)", CONTEXT, -4.5e7);
276 cpl_parameter_set_alias(cp, CPL_PARAMETER_MODE_CLI, "saturation_neg");
277 cpl_parameter_disable(cp, CPL_PARAMETER_MODE_ENV);
278 cpl_parameterlist_append(self, cp);
279
280
281 /* cleanup */
282
283 cpl_parameterlist_delete(bpm_parlist);
284 cpl_parameterlist_delete(collapse_parlist);
285 hdrl_parameter_delete(filter_defaults);
286 hdrl_parameter_delete(flat_defaults);
287 cpl_parameterlist_delete(flat_parlist);
288 hdrl_parameter_delete(legendre_defaults);
289 hdrl_parameter_delete(minmax_defaults);
290 hdrl_parameter_delete(sigclip_defaults);
291 hdrl_parameter_delete(mode_def);
292 return 0;
293}
294
295
296/*----------------------------------------------------------------------------*/
306/*----------------------------------------------------------------------------*/
307
308static hdrl_imagelist * eris_nix_reduce_lamp_on(
309 located_imagelist * lamp_on_limlist,
310 const master_dark * master_drk,
311 const gain_linearity * gain_lin,
312 const cpl_size x_probe,
313 const cpl_size y_probe) {
314
315 cpl_ensure(lamp_on_limlist, CPL_ERROR_NULL_INPUT, NULL);
316 cpl_ensure(master_drk, CPL_ERROR_NULL_INPUT, NULL);
317
318 hdrl_imagelist * result = hdrl_imagelist_new();
319
320 cpl_msg_info(cpl_func, "basic calibration of lamp-on data");
321
322 for (int i = 0; i < lamp_on_limlist->size; i++) {
323 enu_basic_calibrate(lamp_on_limlist->limages[i],
324 CPL_TRUE,
325 NULL,
326 master_drk,
327 gain_lin,
328 NULL,
329 NULL,
330 NULL,
331 0,
332 "noop",
333 0.0 ,
334 x_probe,
335 y_probe);
336
337 enu_check_error_code("error performing basic calibration of lamp-on "
338 "frames");
339
340 hdrl_imagelist_set(result,
341 hdrl_image_duplicate(lamp_on_limlist->
342 limages[i]->himage),
344 }
345
346 cleanup:
347 if (cpl_error_get_code() != CPL_ERROR_NONE) {
348 hdrl_imagelist_delete(result);
349 result = NULL;
350 }
351 return result;
352}
353
354
355/*----------------------------------------------------------------------------*/
366/*----------------------------------------------------------------------------*/
367
368static hdrl_imagelist * eris_nix_reduce_lamp_on_off(
369 located_imagelist * lamp_on_limlist,
370 located_imagelist * lamp_off_limlist,
371 const master_dark * master_drk,
372 const gain_linearity * gain_lin,
373 const cpl_size x_probe,
374 const cpl_size y_probe) {
375
376 cpl_ensure(lamp_on_limlist, CPL_ERROR_NULL_INPUT, NULL);
377 cpl_ensure(lamp_off_limlist, CPL_ERROR_NULL_INPUT, NULL);
378 cpl_ensure(master_drk, CPL_ERROR_NULL_INPUT, NULL);
379
380 hdrl_imagelist * result = hdrl_imagelist_new();
381
382 const int debug = x_probe > 0 &&
383 x_probe <= hdrl_image_get_size_x(
384 lamp_on_limlist->limages[0]->himage) &&
385 y_probe > 0 &&
386 y_probe <= hdrl_image_get_size_y(
387 lamp_on_limlist->limages[0]->himage);
388
389 if (debug) {
390 cpl_msg_info(cpl_func, ".. ON (err) DQ OFF (err) DQ ON-OFF (err) DQ");
391 }
392
393 enu_check(lamp_on_limlist->size == lamp_off_limlist->size,
394 CPL_ERROR_INCOMPATIBLE_INPUT,
395 "different number of lamp-on and lamp-off frames");
396
397 for (int i = 0; i < lamp_on_limlist->size; i++) {
398
399 /* do basic calibration: linearize, calculate error plane */
400
401 enu_basic_calibrate(lamp_on_limlist->limages[i],
402 CPL_TRUE,
403 NULL,
404 master_drk,
405 gain_lin,
406 NULL,
407 NULL,
408 NULL,
409 0,
410 "noop",
411 0.0,
412 x_probe,
413 y_probe);
414 enu_basic_calibrate(lamp_off_limlist->limages[i],
415 CPL_TRUE,
416 NULL,
417 master_drk,
418 gain_lin,
419 NULL,
420 NULL,
421 NULL,
422 0,
423 "noop",
424 0.0,
425 x_probe,
426 y_probe);
427 enu_check_error_code("error performing basic calibration of lamp-on/off "
428 "frames");
429
430 /* difference the on and off images and 'or' the bad pixel map with
431 that of the master dark */
432
433 hdrl_value hon = {0.0, 0.0};
434 int ron = 0;
435 hdrl_value hoff = {0.0, 0.0};
436 int roff = 0;
437 hdrl_value hres = {0.0, 0.0};
438 int rres = 0;
439 if (debug) {
440 hon = hdrl_image_get_pixel(lamp_on_limlist->limages[i]->himage,
441 x_probe, y_probe, &ron);
442 hoff = hdrl_image_get_pixel(lamp_off_limlist->limages[i]->himage,
443 x_probe, y_probe, &roff);
444 }
445
446 hdrl_image_sub_image(lamp_on_limlist->limages[i]->himage,
447 lamp_off_limlist->limages[i]->himage);
448 cpl_mask_or(hdrl_image_get_mask(lamp_on_limlist->limages[i]->
449 himage), master_drk->hot_bpm);
450 hdrl_imagelist_set(result,
451 hdrl_image_duplicate(lamp_on_limlist->
452 limages[i]->himage),
454
455 if (debug) {
456 hres = hdrl_image_get_pixel(lamp_on_limlist->limages[i]->
457 himage, x_probe, y_probe, &rres);
458 cpl_msg_info(cpl_func, ".. %8.2f(%5.2f) %d %8.2f(%5.2f) %d "
459 "%8.2f(%5.2f) %d",
460 hon.data, hon.error, ron,
461 hoff.data, hoff.error, roff,
462 hres.data, hres.error, rres);
463 }
464 }
465
466 cleanup:
467 if (cpl_error_get_code() != CPL_ERROR_NONE) {
468 hdrl_imagelist_delete(result);
469 result = NULL;
470 }
471 return result;
472}
473/*
474static cpl_error_code
475eris_lamp_flat_get_qc_sat(cpl_frameset* frameset, cpl_propertylist* qclog)
476{
477 cpl_frameset* raws = cpl_frameset_new();
478
479 eris_dfs_extract_raw_frames(frameset, raws);
480
481 cpl_frame* frm_mdark = cpl_frameset_find(frameset,
482 ERIS_NIX_MASTER_DARK_IMG_PRO_CATG);
483
484 double saturation_negative = - 4.5e7;
485 double saturation = 15000;
486 const char* frame_name;
487 saturation=3000;
488 cpl_size size = cpl_frameset_get_size(raws);
489 for(cpl_size i = 0; i < size; i++) {
490
491 cpl_frame* frame = cpl_frameset_get_position(raws, i);
492
493 frame_name = cpl_frame_get_filename(frame);
494 eris_get_sat_pix_qc_for_image(frame_name, frm_mdark, saturation,
495 saturation_negative, i, qclog);
496
497 }
498
499 cpl_frameset_delete(raws);
500
501 return cpl_error_get_code();
502}
503*/
504/*----------------------------------------------------------------------------*/
511/*----------------------------------------------------------------------------*/
512
513static int eris_nix_flat_lamp(cpl_frameset * frameset,
514 const cpl_parameterlist * parlist) {
515 cpl_mask * bpm_mask = NULL;
516 hdrl_parameter * bpm_params = NULL;
517 cpl_propertylist * bpm_plist = NULL;
518 cpl_mask * cold_bpm = NULL;
519 hdrl_parameter * collapse_params = NULL;
520 cpl_image * confidence_hi = NULL;
521 cpl_image * confidence_lo = NULL;
522 hdrl_parameter * flat_params = NULL;
523 cpl_propertylist * flat_plist = NULL;
524 const gain_linearity * gain_lin = NULL;
525 hdrl_image * illumination_flat = NULL;
526 located_imagelist * lamp_off_limlist = NULL;
527 located_imagelist * lamp_on_limlist = NULL;
528 hdrl_imagelist * lamp_reduced_data = NULL;
529 master_bpm * master_bad_pix_map = NULL;
530 master_dark * master_drk = NULL;
531 hdrl_image * master_flat_hifreq = NULL;
532 hdrl_image * master_flat_lofreq = NULL;
533 cpl_mask * old_mask = NULL;
534 const cpl_parameter * param = NULL;
535 cpl_mask * un_illum = NULL;
536 cpl_frameset * used_frameset = NULL;
537
538 enu_check_error_code("%s():%d: An error is already set: %s",
539 cpl_func, __LINE__, cpl_error_get_where());
540
541 /* check input parameters */
542
543 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
544 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
545
546 /* set the msg verbosity level from environment variable CPL_MSG_LEVEL */
547
548 cpl_msg_set_level_from_env();
549 cpl_msg_severity severity = cpl_msg_get_level();
550 cpl_msg_info(cpl_func, "level %d", (int) severity);
551
552 /* check required input tags are present */
553 const int ntags = 5;
554 const char* required_tags[5] = {ERIS_NIX_RAW_FLAT_LAMP_ON_DO_CATG,
555 ERIS_NIX_NL_BPM_PRO_CATG,
556 ERIS_NIX_COEFFS_CUBE_PRO_CATG,
557 ERIS_NIX_GAIN_PRO_CATG,
558 ERIS_NIX_MASTER_DARK_IMG_PRO_CATG
559 };
560 const int nopt_tags = 1;
561 const char* optional_tags[1] = {ERIS_NIX_RAW_FLAT_LAMP_OFF_DO_CATG,
562 };
563
564 cpl_ensure_code(CPL_ERROR_NONE ==
565 eris_dfs_check_input_tags(frameset, required_tags, ntags, 1),
566 CPL_ERROR_ILLEGAL_INPUT);
567
568 eris_dfs_check_input_tags(frameset, optional_tags, nopt_tags, 0);
569
570
571
572 /* retrieve input parameters for collapse */
573
574 collapse_params = hdrl_collapse_parameter_parse_parlist(parlist,
575 CONTEXT".collapse");
576
577 /* retrieve input filter parameters for HI and LO flat-field */
578
579 flat_params = hdrl_flat_parameter_parse_parlist(parlist,
580 CONTEXT".flat");
581 cpl_size filter_size_x = hdrl_flat_parameter_get_filter_size_x(
582 flat_params);
583 cpl_size filter_size_y = hdrl_flat_parameter_get_filter_size_y(
584 flat_params);
585
586 /* retrieve input parameters for 'cold-pixel' bpm */
587
588 bpm_params = hdrl_bpm_2d_parameter_parse_parlist(parlist,
589 CONTEXT".coldpix");
590
591
592 /* retrieve minimum acceptable number of coadds */
593
594 param = cpl_parameterlist_find_const(parlist, CONTEXT".min_coadds");
595 int min_coadds = cpl_parameter_get_int(param);
596
597 /* retrieve probe pixel coords */
598
599 param = cpl_parameterlist_find_const(parlist, CONTEXT".x_probe");
600 cpl_size x_probe = (cpl_size) cpl_parameter_get_int(param);
601 param = cpl_parameterlist_find_const(parlist, CONTEXT".y_probe");
602 cpl_size y_probe = (cpl_size) cpl_parameter_get_int(param);
603
604 enu_check_error_code("Could not retrieve input parameters");
605
606 /* identify the RAW and CALIB frames in the input frameset */
607
608 eris_nix_dfs_set_groups(frameset);
609 enu_check_error_code("Could not identify RAW and CALIB frames");
610
611 used_frameset = cpl_frameset_new();
612
613 /* read the gain and linearity information, if available */
614
615 int required = CPL_FALSE;
616 gain_lin = engl_gain_linearity_load_from_frameset(frameset,
617 ERIS_NIX_GAIN_PRO_CATG, ERIS_NIX_COEFFS_CUBE_PRO_CATG,
618 ERIS_NIX_NL_BPM_PRO_CATG, required, used_frameset);
619 enu_check_error_code("failed to read gain/linearity information from SoF");
620
621 /* read the master_dark */
622
623 master_drk = en_master_dark_load_from_frameset(frameset,
624 ERIS_NIX_MASTER_DARK_IMG_PRO_CATG, used_frameset);
625 enu_check_error_code("failed to read master dark from SoF");
626
627 /* see what data the sof contains */
628
629 lamp_on_limlist = enu_limlist_load_from_frameset(frameset,
630 ERIS_NIX_RAW_FLAT_LAMP_ON_DO_CATG, used_frameset);
631 lamp_off_limlist = enu_limlist_load_from_frameset(frameset,
632 ERIS_NIX_RAW_FLAT_LAMP_OFF_DO_CATG, used_frameset);
633
634 double saturation = 0;
635
636
637 param = cpl_parameterlist_find_const(parlist, CONTEXT".saturation_pos");
638
639 if(eris_param_has_changed(param)) {
640 saturation = cpl_parameter_get_double(param);
641 } else {
642 const char* sat_limit = cpl_propertylist_get_string(gain_lin->plist,
643 "ESO PRO REC1 PARAM25 VALUE");
644 saturation = atof(sat_limit);
645 }
646 /* QC on FLAT_ON frames not using information from pixels of master_bad_pix_map */
647 cpl_propertylist* qclog = enu_raw_flats_qc(lamp_on_limlist, gain_lin->bpm,
648 parlist, CONTEXT, saturation,
649 CPL_TRUE, CPL_FALSE);
650
651 //eris_lamp_flat_get_qc_sat(frameset, qclog);
652
653
654 /* reduce raw data to get input to flatfield calculation */
655
656 if (lamp_on_limlist->size > 0 && lamp_off_limlist->size > 0) {
657 lamp_reduced_data = eris_nix_reduce_lamp_on_off(lamp_on_limlist,
658 lamp_off_limlist,
659 master_drk,
660 gain_lin,
661 x_probe,
662 y_probe);
663 } else if (lamp_on_limlist->size > 0 && lamp_off_limlist->size == 0) {
664 lamp_reduced_data = eris_nix_reduce_lamp_on(lamp_on_limlist,
665 master_drk,
666 gain_lin,
667 x_probe,
668 y_probe);
669 }
670 enu_check_error_code("error doing basic calibration");
671
672 /* get a basic flatfield for use in detecting an illumination mask */
673
674 cpl_msg_info(cpl_func, "measuring illumination...");
675 hdrl_imagelist * duplicate_list = hdrl_imagelist_duplicate(
676 lamp_reduced_data);
677 illumination_flat = enu_calc_flat(lamp_reduced_data,
678 min_coadds,
679 collapse_params,
680 5, 5, HDRL_FLAT_FREQ_LOW);
681 hdrl_imagelist_delete(duplicate_list);
682
683 /* compute the 'bad-illumination' BPM and reject affected pixels in
684 the lamp data, otherwise will get nasty edge effects in the lofreq
685 flat */
686
687 un_illum = cpl_mask_threshold_image_create(hdrl_image_get_image(
688 illumination_flat),
689 -1000.0, 0.5);
690 enu_check_error_code("error computing un-illuminated bpm");
691
692 for (cpl_size i = 0; i < hdrl_imagelist_get_size(lamp_reduced_data); i++) {
693 hdrl_image * temp = hdrl_imagelist_get(lamp_reduced_data, i);
694 cpl_image * data = hdrl_image_get_image(temp);
695 cpl_mask * data_mask = cpl_image_get_bpm(data);
696 cpl_binary * data_mask_data = cpl_mask_get_data(data_mask);
697 cpl_image * error = hdrl_image_get_error(temp);
698 cpl_mask * error_mask = cpl_image_get_bpm(error);
699 cpl_binary * error_mask_data = cpl_mask_get_data(error_mask);
700
701 cpl_binary * illum_mask_data = cpl_mask_get_data(un_illum);
702
703 cpl_size nx = cpl_image_get_size_x(data);
704 cpl_size ny = cpl_image_get_size_y(data);
705
706 for (cpl_size p = 0; p < nx * ny; p++) {
707 if (illum_mask_data[p] == CPL_BINARY_1) {
708 data_mask_data[p] = CPL_BINARY_1;
709 error_mask_data[p] = CPL_BINARY_1;
710 }
711 }
712 }
713
714 /* get the HI freq flatfield - duplicate imagelist as it gets
715 overwritten */
716
717 duplicate_list = hdrl_imagelist_duplicate(lamp_reduced_data);
718 master_flat_hifreq = enu_calc_flat(duplicate_list,
719 min_coadds,
720 collapse_params,
721 filter_size_x,
722 filter_size_y,
723 HDRL_FLAT_FREQ_HIGH);
724 hdrl_imagelist_delete(duplicate_list);
725
726 /* compute the 'cold-pixel' BPM, the output will not include
727 pixels already set bad in the input image */
728
729 cold_bpm = hdrl_bpm_2d_compute(master_flat_hifreq, bpm_params);
730 enu_check_error_code("error computing cold-pixel bpm");
731
732 /* construct the MASTER_BPM */
733
734 master_bad_pix_map = en_master_bpm_create("eris_nix_flat_lamp", cold_bpm,
735 BPM_DARK, NULL);
736 en_master_bpm_set(master_bad_pix_map, master_drk->hot_bpm, BPM_HOT);
737 en_master_bpm_set(master_bad_pix_map, un_illum, BPM_UNILLUMINATED);
738 if (gain_lin) {
739 en_master_bpm_set(master_bad_pix_map, gain_lin->bpm, BPM_NON_LINEAR);
740 }
741
742 /* create a bpm mask, find how many bad pixels overall */
743 //bpm_plist = cpl_propertylist_new();
744 //eris_nix_get_badpix_qc_from_ima(master_bad_pix_map, bpm_plist, "FLATLAMP");
745
746 int flag_mask = 0;
747 flag_mask = ~flag_mask;
748 bpm_mask = en_master_bpm_get_mask(master_bad_pix_map, flag_mask);
749 bpm_plist = cpl_propertylist_new();
750 int nbad = cpl_mask_count(bpm_mask);
751 cpl_propertylist_append_int(bpm_plist, "ESO QC NUMBER BAD PIXELS", nbad);
752 cpl_size sx = cpl_mask_get_size_x(bpm_mask);
753 cpl_size sy = cpl_mask_get_size_y(bpm_mask);
754 double fraction = (double) nbad / (sx * sy);
755 cpl_propertylist_append_double(bpm_plist, "ESO QC FRACTION BAD PIXELS",fraction);
756 /* and save it */
757
758 enu_dfs_save_bpm(ERIS_NIX_MASTER_BPM_LAMP_PRO_CATG,
759 frameset, parlist, used_frameset, master_bad_pix_map,
760 RECIPE_NAME, bpm_plist, PACKAGE "/" PACKAGE_VERSION,
761 "master_bpm_lamp.fits");
762 enu_check_error_code("Failed to save MASTER_BPM");
763
764
765
766 /* create a HIFREQ confidence array, essentially the flat field with
767 bad pixels set to 0 and median pixel value normalised to 100 */
768
769 confidence_hi = cpl_image_duplicate(hdrl_image_get_image_const(
770 master_flat_hifreq));
771 cpl_image_fill_rejected(confidence_hi, 0.0);
772 cpl_image_accept_all(confidence_hi);
773 enu_normalise_confidence(confidence_hi);
774 enu_check_error_code("error computing HIFREQ confidence map");
775
776 /* now save the HIFREQ flat */
777
778 enu_flat_save(ERIS_NIX_MASTER_FLAT_LAMP_HIFREQ_PRO_CATG,
779 master_flat_hifreq,
780 confidence_hi,
781 cold_bpm,
782 frameset,
783 parlist,
784 "master_flat_lamp_hifreq.fits",
785 RECIPE_NAME,
786 qclog);
787 cpl_propertylist_delete(qclog);
788 enu_check_error_code("Failed to save HIFREQ flat");
789
790 /* similar for LOFREQ flat */
791
792 /* except reject pixels flagged by the master bpm first */
793
794 for (cpl_size i = 0; i < hdrl_imagelist_get_size(lamp_reduced_data); i++) {
795 cpl_mask * current_mask = hdrl_image_get_mask(
796 hdrl_imagelist_get(lamp_reduced_data, i));
797 cpl_mask_or(current_mask, bpm_mask);
798 }
799
800 /* get the LO freq flatfield */
801
802 duplicate_list = hdrl_imagelist_duplicate(lamp_reduced_data);
803 master_flat_lofreq = enu_calc_flat(duplicate_list,
804 min_coadds,
805 collapse_params,
806 filter_size_x,
807 filter_size_y,
808 HDRL_FLAT_FREQ_LOW);
809 hdrl_imagelist_delete(duplicate_list);
810
811 confidence_lo = cpl_image_duplicate(hdrl_image_get_image_const(
812 master_flat_lofreq));
813 cpl_image_fill_rejected(confidence_lo, 0.0);
814 cpl_image_accept_all(confidence_lo);
815 enu_normalise_confidence(confidence_lo);
816 enu_check_error_code("error computing LOFREQ confidence map");
817
818 enu_flat_save(ERIS_NIX_MASTER_FLAT_LAMP_LOFREQ_PRO_CATG,
819 master_flat_lofreq,
820 confidence_lo,
821 NULL,
822 frameset,
823 parlist,
824 "master_flat_lamp_lofreq.fits",
825 RECIPE_NAME,
826 NULL);
827 enu_check_error_code("Failed to save LOFREQ flat");
828
829cleanup:
830 cpl_mask_delete(bpm_mask);
831 cpl_propertylist_delete(bpm_plist);
832 hdrl_parameter_delete(bpm_params);
833 cpl_mask_delete(cold_bpm);
834 hdrl_parameter_delete(collapse_params);
835 cpl_image_delete(confidence_hi);
836 cpl_image_delete(confidence_lo);
837 hdrl_parameter_delete(flat_params);
838 cpl_propertylist_delete(flat_plist);
839 engl_gain_linearity_delete((gain_linearity *) gain_lin);
840 hdrl_image_delete(illumination_flat);
841 enu_located_imagelist_delete(lamp_off_limlist);
842 enu_located_imagelist_delete(lamp_on_limlist);
843 hdrl_imagelist_delete(lamp_reduced_data);
844 en_master_bpm_delete(master_bad_pix_map);
845 en_master_dark_delete(master_drk);
846 hdrl_image_delete(master_flat_hifreq);
847 hdrl_image_delete(master_flat_lofreq);
848 cpl_mask_delete(old_mask);
849 cpl_mask_delete(un_illum);
850 cpl_frameset_delete(used_frameset);
851
852 return (int)cpl_error_get_code();
853}
cpl_error_code eris_nix_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: eris_nix_dfs.c:58
cpl_error_code enu_dfs_save_bpm(const char *procat, cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const master_bpm *mbad_pix_map, const char *recipe, const cpl_propertylist *applist, const char *pipe_id, const char *filename)
Save a master_bpm as a DFS-compliant pipeline product.
Definition: eris_nix_dfs.c:218
void en_master_bpm_delete(master_bpm *target)
Delete a 'master_bpm' struct.
master_dark * en_master_dark_load_from_frameset(const cpl_frameset *frameset, const char *tag, cpl_frameset *used)
Load a 'master_dark' struct from a frameset.
void en_master_dark_delete(master_dark *target)
Delete a 'master_dark' struct.
void enu_located_imagelist_delete(located_imagelist *limlist)
Delete a located_imagelist and its contents.
cpl_propertylist * enu_raw_flats_qc(located_imagelist *lamp_on_limlist, cpl_mask *bp_map_nl_mask, const cpl_parameterlist *parlist, const char *context, const double threshold_pos, const cpl_boolean verbose, const cpl_boolean rescale_by_dit)
Compute QC on input raw flats.
cpl_error_code enu_flat_save(const char *pro_catg, const hdrl_image *flat, const cpl_image *confidence, const cpl_mask *cold_bpm, cpl_frameset *frameset, const cpl_parameterlist *parlist, const char *filename, const char *recipe_name, const cpl_propertylist *qclog)
Save a flatfield result.
hdrl_image * enu_calc_flat(hdrl_imagelist *himlist, const int min_coadds, const hdrl_parameter *collapse_params, const cpl_size filter_size_x, const cpl_size filter_size_y, const hdrl_flat_method method)
Calculate a flatfield result.
cpl_error_code enu_basic_calibrate(located_image *limage, const int read_offsets, const cpl_table *refine_wcs, const master_dark *mdark, const gain_linearity *gain_lin, const master_flat *flatfield_1, const master_flat *flatfield_2, const master_bpm *mbad_pix_map, const int flag_mask, const char *fill_rejected, const double fill_value, const cpl_size x_probe, const cpl_size y_probe)
Do basic calibration of located_image (single or cube)
located_imagelist * enu_limlist_load_from_frameset(cpl_frameset *frameset, const char *tag, cpl_frameset *used)
Load tagged data from a frameset into a located_imagelist.
cpl_error_code enu_normalise_confidence(cpl_image *confidence)
Normalise confidence array so that mean of good pixels is 100.
cpl_boolean eris_param_has_changed(const cpl_parameter *p)
verify if a parameter value has been changed (from command line or or rc file by a user)
Definition: eris_utils.c:809
cpl_mask * hdrl_bpm_2d_compute(const hdrl_image *img_in, const hdrl_parameter *params)
Detect bad pixels on a single image with an iterative process.
Definition: hdrl_bpm_2d.c:1136
hdrl_parameter * hdrl_bpm_2d_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse parameter list to create input parameters for the BPM_2D.
Definition: hdrl_bpm_2d.c:896
hdrl_parameter * hdrl_bpm_2d_parameter_create_filtersmooth(double kappa_low, double kappa_high, int maxiter, cpl_filter_mode filter, cpl_border_mode border, int smooth_x, int smooth_y)
Creates BPM_2D Parameters object for HDRL_BPM_2D_FILTERSMOOTH.
Definition: hdrl_bpm_2d.c:137
cpl_parameterlist * hdrl_bpm_2d_parameter_create_parlist(const char *base_context, const char *prefix, const char *method_def, const hdrl_parameter *filtersmooth_def, const hdrl_parameter *legendresmooth_def)
Create parameter list for the BPM_2D computation.
Definition: hdrl_bpm_2d.c:798
hdrl_parameter * hdrl_bpm_2d_parameter_create_legendresmooth(double kappa_low, double kappa_high, int maxiter, int steps_x, int steps_y, int filter_size_x, int filter_size_y, int order_x, int order_y)
Creates BPM_2D Parameters object for HDRL_BPM_2D_LEGENDRESMOOTH.
Definition: hdrl_bpm_2d.c:191
hdrl_parameter * hdrl_collapse_sigclip_parameter_create(double kappa_low, double kappa_high, int niter)
create a parameter object for sigclipped mean
hdrl_parameter * hdrl_collapse_mode_parameter_create(double histo_min, double histo_max, double bin_size, hdrl_mode_type mode_method, cpl_size error_niter)
create a parameter object for the mode
cpl_parameterlist * hdrl_collapse_parameter_create_parlist(const char *base_context, const char *prefix, const char *method_def, hdrl_parameter *sigclip_def, hdrl_parameter *minmax_def, hdrl_parameter *mode_def)
Create parameters for the collapse.
hdrl_parameter * hdrl_collapse_minmax_parameter_create(double nlow, double nhigh)
create a parameter object for min-max rejected mean
hdrl_parameter * hdrl_collapse_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
parse parameterlist for imagelist reduction method
cpl_size hdrl_flat_parameter_get_filter_size_x(const hdrl_parameter *p)
Access the filter_size_x in the FLAT parameter.
Definition: hdrl_flat.c:209
hdrl_parameter * hdrl_flat_parameter_create(cpl_size filter_size_x, cpl_size filter_size_y, hdrl_flat_method method)
Creates FLAT Parameters object.
Definition: hdrl_flat.c:173
cpl_size hdrl_flat_parameter_get_filter_size_y(const hdrl_parameter *p)
Access the filter_size_y in the FLAT parameter.
Definition: hdrl_flat.c:223
hdrl_parameter * hdrl_flat_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse a parameterlist to create input parameters for the FLAT.
Definition: hdrl_flat.c:331
cpl_parameterlist * hdrl_flat_parameter_create_parlist(const char *base_context, const char *prefix, const hdrl_parameter *defaults)
Create a parameter list for the FLAT computation.
Definition: hdrl_flat.c:258
hdrl_value hdrl_image_get_pixel(const hdrl_image *self, cpl_size xpos, cpl_size ypos, int *pis_rejected)
get pixel values of hdrl_image
Definition: hdrl_image.c:559
cpl_error_code hdrl_image_sub_image(hdrl_image *self, const hdrl_image *other)
Subtract two images, store the result in the first image.
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
Definition: hdrl_image.c:391
cpl_mask * hdrl_image_get_mask(hdrl_image *himg)
get cpl bad pixel mask from image
Definition: hdrl_image.c:157
cpl_image * hdrl_image_get_error(hdrl_image *himg)
get error as cpl image
Definition: hdrl_image.c:131
cpl_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
Definition: hdrl_image.c:540
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
Definition: hdrl_image.c:525
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:105
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:118
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379
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_imagelist * hdrl_imagelist_duplicate(const hdrl_imagelist *himlist)
Duplicate an image list.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter
double fraction(double x, double y, double r_out)
Fraction of pixel bounded.