37#include "eris_utils.h"
38#include "eris_nix_utils.h"
39#include "eris_pfits.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"
53static const char eris_nix_flat_twilight_description[] =
54"This recipe reduces a set of twilight frames to produce a \n"
55ERIS_NIX_MASTER_FLAT_TWILIGHT_LOFREQ_PRO_CATG
" result.\n"
59" DO CATG Explanation Req. #Frames\n"
60" ------- ----------- --- -------\n"
61" "ERIS_NIX_RAW_FLAT_TWILIGHT_DO_CATG
62 " frames with a Y >min-frames\n"
63" range of twilight \n"
65" "ERIS_NIX_MASTER_DARK_IMG_PRO_CATG
66 " a MASTER_DARK with Y 1\n"
67" matching detector \n"
69" "ERIS_NIX_MASTER_BPM_LAMP_PRO_CATG
70 " a lamp MASTER_BPM Y 1\n"
71" "ERIS_NIX_GAIN_PRO_CATG
72 " DETMON gain information N 0 or 1\n"
74" detmon_ir_lg_gain_table.fits\n"
75" "ERIS_NIX_COEFFS_CUBE_PRO_CATG
76 " DETMON linearity curves N 0 or 1\n"
78" detmon_ir_coeffs_cube.fits\n"
79" "ERIS_NIX_NL_BPM_PRO_CATG
80 " DETMON non-linear bpm N 0 or 1\n"
82" detmon_ir_lg_bpm.fits\n"
86" DO CATG Explanation \n"
87" ------- ----------- \n"
88" "ERIS_NIX_MASTER_FLAT_TWILIGHT_LOFREQ_PRO_CATG
89 " The required LOFREQ twilight flatfield.\n"
91" The output will be a FITS file named 'master_flat_twilight_lofreq.fits',\n"
93" - DATA, with the flatfield data.\n"
94" - ERR, with the flatfield error plane.\n"
95" - DQ, with the flatfield data quality plane.\n"
96" - CONFIDENCE, with the flatfield confidence plane.\n"
98#define RECIPE_NAME "eris_nix_flat_twilight"
99#define CONTEXT "eris."RECIPE_NAME
104cpl_recipe_define(eris_nix_flat_twilight, ERIS_BINARY_VERSION,
106 PACKAGE_BUGREPORT,
"2017",
107 "Calculate a MASTER_FLAT_TWILIGHT_LOFREQ",
108 eris_nix_flat_twilight_description);
124static cpl_error_code eris_nix_flat_twilight_fill_parameterlist(
125 cpl_parameterlist *self) {
127 if (cpl_error_get_code() != CPL_ERROR_NONE)
return cpl_error_get_code();
129 cpl_parameterlist * bpm_parlist = NULL;
130 cpl_parameterlist * collapse_parlist = NULL;
131 hdrl_parameter * filter_defaults = NULL;
132 hdrl_parameter * flat_defaults = NULL;
133 cpl_parameterlist * flat_parlist = NULL;
134 hdrl_parameter * legendre_defaults = NULL;
135 hdrl_parameter * minmax_defaults = NULL;
136 hdrl_parameter * sigclip_defaults = NULL;
144 for (cpl_parameter * p = cpl_parameterlist_get_first(flat_parlist);
145 p != NULL; p = cpl_parameterlist_get_next(flat_parlist)) {
147 const char * pname = cpl_parameter_get_name(p);
148 if (strstr(pname,
"method")) {
149 cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
151 cpl_parameter * duplicate = cpl_parameter_duplicate(p);
152 cpl_parameterlist_append(self, duplicate);
155 cpl_parameter * cp = NULL;
156 cp = cpl_parameter_new_value(CONTEXT
".min_frames", CPL_TYPE_INT,
157 "minimum acceptable number of twilight "
158 "images", CONTEXT, 2);
159 cpl_parameter_set_alias(cp, CPL_PARAMETER_MODE_CLI,
"min-frames");
160 cpl_parameter_disable(cp, CPL_PARAMETER_MODE_ENV);
161 cpl_parameterlist_append(self, cp);
166 cp = cpl_parameter_new_value(CONTEXT
".x_probe", CPL_TYPE_INT,
167 "x coord of diagnostic pixel",
169 cpl_parameter_set_alias(cp, CPL_PARAMETER_MODE_CLI,
"x-probe");
170 cpl_parameter_disable(cp, CPL_PARAMETER_MODE_ENV);
171 cpl_parameterlist_append(self, cp);
173 cp = cpl_parameter_new_value(CONTEXT
".y_probe", CPL_TYPE_INT,
174 "y coord of diagnostic pixel",
176 cpl_parameter_set_alias(cp, CPL_PARAMETER_MODE_CLI,
"y-probe");
177 cpl_parameter_disable(cp, CPL_PARAMETER_MODE_ENV);
178 cpl_parameterlist_append(self, cp);
180 cp = cpl_parameter_new_value(CONTEXT
".threshold", CPL_TYPE_DOUBLE,
181 "positive saturation level (for QC)",
183 cpl_parameter_set_alias(cp, CPL_PARAMETER_MODE_CLI,
"threshold");
184 cpl_parameter_disable(cp, CPL_PARAMETER_MODE_ENV);
185 cpl_parameterlist_append(self, cp);
187 cp = cpl_parameter_new_value(CONTEXT
".saturation_neg", CPL_TYPE_DOUBLE,
188 "negative saturation level (for QC)", CONTEXT, -4.5e7);
189 cpl_parameter_set_alias(cp, CPL_PARAMETER_MODE_CLI,
"saturation_neg");
190 cpl_parameter_disable(cp, CPL_PARAMETER_MODE_ENV);
191 cpl_parameterlist_append(self, cp);
195 cpl_parameterlist_delete(bpm_parlist);
196 cpl_parameterlist_delete(collapse_parlist);
199 cpl_parameterlist_delete(flat_parlist);
220static hdrl_imagelist * eris_nix_reduce_twilight(
221 located_imagelist * twilight_limlist,
222 const master_dark * mdark,
223 const gain_linearity * gain_lin,
224 const master_bpm * master_bpm_lamp,
225 const cpl_size x_probe,
226 const cpl_size y_probe) {
228 cpl_ensure(twilight_limlist, CPL_ERROR_NULL_INPUT, NULL);
229 cpl_ensure(mdark, CPL_ERROR_NULL_INPUT, NULL);
231 cpl_imagelist * flat_fit = NULL;
232 cpl_image * flat_fit_error = NULL;
233 cpl_imagelist * twilight_imagelist = NULL;
234 cpl_vector * twilight_medians = NULL;
247 twilight_imagelist = cpl_imagelist_new();
248 twilight_medians = cpl_vector_new(twilight_limlist->size);
250 for (cpl_size i = 0; i < twilight_limlist->size; i++) {
255 flag_mask = ~flag_mask;
269 enu_check_error_code(
"error performing basic calibration of twilight "
275 twilight_limlist->limages[i]->himage), i);
276 cpl_vector_set(twilight_medians, i,
278 twilight_limlist->limages[i]->himage)));
280 flat_fit = cpl_fit_imagelist_polynomial(twilight_medians,
285 enu_check_error_code(
"error fitting twilight frames");
287 cpl_imagelist_get(flat_fit, 1), NULL), 0);
292 while (cpl_imagelist_get_size(twilight_imagelist) > 0) {
293 cpl_imagelist_unset(twilight_imagelist, 0);
297 if (cpl_error_get_code() != CPL_ERROR_NONE) {
301 cpl_imagelist_delete(flat_fit);
302 cpl_image_delete(flat_fit_error);
303 cpl_imagelist_delete(twilight_imagelist);
304 cpl_vector_delete(twilight_medians);
319static int eris_nix_flat_twilight(cpl_frameset * frameset,
320 const cpl_parameterlist * parlist) {
321 cpl_mask * bpm_mask = NULL;
322 hdrl_parameter * collapse_params = NULL;
323 cpl_image * confidence_lo = NULL;
324 hdrl_parameter * flat_params = NULL;
325 cpl_propertylist * flat_plist = NULL;
326 const gain_linearity * gain_lin = NULL;
327 master_bpm * master_bpm_lamp = NULL;
328 master_dark * mdark = NULL;
329 hdrl_image * master_flat_lofreq = NULL;
330 cpl_mask * old_mask = NULL;
331 const cpl_parameter * param = NULL;
332 located_imagelist * twilight_limlist = NULL;
333 hdrl_imagelist * twilight_reduced = NULL;
334 cpl_frameset * used_frameset = NULL;
336 enu_check_error_code(
"%s():%d: An error is already set: %s",
337 cpl_func, __LINE__, cpl_error_get_where());
341 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
342 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
346 cpl_msg_set_level_from_env();
347 cpl_msg_severity severity = cpl_msg_get_level();
348 cpl_msg_info(cpl_func,
"level %d", (
int) severity);
352 const char* required_tags[6] = {
353 ERIS_NIX_RAW_FLAT_TWILIGHT_DO_CATG,
354 ERIS_NIX_NL_BPM_PRO_CATG,
355 ERIS_NIX_COEFFS_CUBE_PRO_CATG,
356 ERIS_NIX_GAIN_PRO_CATG,
357 ERIS_NIX_MASTER_BPM_LAMP_PRO_CATG,
358 ERIS_NIX_MASTER_DARK_IMG_PRO_CATG
361 const int nopt_tags = 2;
362 const char* optional_tags[2] = {
363 ERIS_NIX_MASTER_FLAT_LAMP_HIFREQ_PRO_CATG,
364 ERIS_NIX_MASTER_FLAT_LAMP_LOFREQ_PRO_CATG
368 cpl_ensure_code(CPL_ERROR_NONE ==
369 eris_dfs_check_input_tags(frameset, required_tags, ntags, 1),
370 CPL_ERROR_ILLEGAL_INPUT);
371 eris_dfs_check_input_tags(frameset, optional_tags, nopt_tags, 0);
390 param = cpl_parameterlist_find_const(parlist, CONTEXT
".min_frames");
391 int min_frames = cpl_parameter_get_int(param);
395 param = cpl_parameterlist_find_const(parlist, CONTEXT
".x_probe");
396 cpl_size x_probe = (cpl_size) cpl_parameter_get_int(param);
397 param = cpl_parameterlist_find_const(parlist, CONTEXT
".y_probe");
398 cpl_size y_probe = (cpl_size) cpl_parameter_get_int(param);
399 enu_check_error_code(
"Could not retrieve input parameters");
404 enu_check_error_code(
"Could not identify RAW and CALIB frames");
406 used_frameset = cpl_frameset_new();
410 int required = CPL_FALSE;
411 gain_lin = engl_gain_linearity_load_from_frameset(frameset,
412 ERIS_NIX_GAIN_PRO_CATG, ERIS_NIX_COEFFS_CUBE_PRO_CATG,
413 ERIS_NIX_NL_BPM_PRO_CATG, required, used_frameset);
414 enu_check_error_code(
"failed to read gain/linearity information from SoF");
419 ERIS_NIX_MASTER_DARK_IMG_PRO_CATG, used_frameset);
420 enu_check_error_code(
"failed to read master dark from SoF");
424 master_bpm_lamp = en_master_bpm_load_from_frameset(frameset,
425 ERIS_NIX_MASTER_BPM_LAMP_PRO_CATG, used_frameset,
427 enu_check_error_code(
"failed to read master BPM from SoF");
432 ERIS_NIX_RAW_FLAT_TWILIGHT_DO_CATG, used_frameset);
433 cpl_msg_info(cpl_func,
"read %d "ERIS_NIX_RAW_FLAT_TWILIGHT_DO_CATG
434 " frames", (
int) twilight_limlist->size);
435 enu_check(twilight_limlist->size >= min_frames, CPL_ERROR_ILLEGAL_INPUT,
436 "%d or more "ERIS_NIX_RAW_FLAT_TWILIGHT_DO_CATG
437 " frames required", min_frames);
441 twilight_reduced = eris_nix_reduce_twilight(twilight_limlist,
447 enu_check_error_code(
"failed basic reduction of twilight data");
457 enu_check_error_code(
"failed to calculate LOFREQ flat");
463 master_flat_lofreq));
464 cpl_image_fill_rejected(confidence_lo, 0.0);
465 cpl_image_accept_all(confidence_lo);
467 enu_check_error_code(
"error computing LOFREQ confidence map");
470 const char* saturation_limit = cpl_propertylist_get_string(gain_lin->plist,
471 "ESO PRO REC1 PARAM25 VALUE");
472 double saturation = atof(saturation_limit);
475 gain_lin->bpm, parlist, CONTEXT, saturation, CPL_FALSE, CPL_TRUE);
485 "master_flat_twilight_lofreq.fits",
487 cpl_propertylist_delete(qclog);
488 enu_check_error_code(
"Failed to save LOFREQ flat");
491 cpl_mask_delete(bpm_mask);
493 cpl_image_delete(confidence_lo);
495 cpl_propertylist_delete(flat_plist);
496 engl_gain_linearity_delete((gain_linearity *) gain_lin);
500 cpl_mask_delete(old_mask);
503 cpl_frameset_delete(used_frameset);
505 return (
int)cpl_error_get_code();
cpl_error_code eris_nix_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
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.
hdrl_parameter * hdrl_collapse_sigclip_parameter_create(double kappa_low, double kappa_high, int niter)
create a parameter object for sigclipped mean
cpl_size hdrl_flat_parameter_get_filter_size_x(const hdrl_parameter *p)
Access the filter_size_x in the FLAT parameter.
hdrl_parameter * hdrl_flat_parameter_create(cpl_size filter_size_x, cpl_size filter_size_y, hdrl_flat_method method)
Creates FLAT Parameters object.
cpl_size hdrl_flat_parameter_get_filter_size_y(const hdrl_parameter *p)
Access the filter_size_y in the FLAT parameter.
hdrl_parameter * hdrl_flat_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse a parameterlist to create input parameters for the FLAT.
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.
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_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.
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter