37#include "eris_utils.h"
38#include "eris_pfits.h"
39#include "eris_ifu_dfs.h"
40#include "eris_ifu_utils.h"
41#include "eris_ifu_functions.h"
42#include "eris_ifu_error.h"
43#include "eris_ifu_dark_static.h"
52static const char eris_ifu_dark_description[] =
"\
53This recipe performs ERIS/SPIFFIER dark frames data reduction.\n\
54It calculates the master dark frame and a bad pixel mask.\n\
56It is required to provide three or more dark exposures to produce a reasonable\n\
57master dark with associated noise.\n\
59Two different bad pixel mask are generated selected by\n\
60the –bpm.method recipe parameter:\n\
612D: For the 2D bad pixel mask the master dark image is searched for outliers.\n\
623D For the 3D bad pixel mask the provided dark exposures are stacked. Then\n\
63outliers in the variance of each pixel are determined.\n\
65-----------------------------------------------------------------------------\n\
67 DO CATG Explanation Required #Frames\n\
68 ------- ----------- -------- -------\n\
69 DARK Dark exposures Y 3-n \n\
72 DO CATG Explanation Product\n\
74 ------------------- ---------------------------------------------- -------\n\
75 MASTER_DARK_IFU Master dark frame (data, noise, DQI) PD_SCI\n\
76 eris_ifu_dark_master_dark.fits\n\
77 BPM_DARK Bad pixel mask PD_SCI\n\
78 eris_ifu_dark_bpm.fits\n\
79 DARK_BPM2D 2D bad pixel mask PD_AUX\n\
80 eris_ifu_dark_bpm2d.fits\n\
81 DARK_DBG_BPM3D 2D bad pixel mask PD_AUX\n\
82 eris_ifu_dark_bpm3d.fits\n\
83 DARK_CONTRIBMAP contribution map from image list collapse PD_ALL\n\
84 eris_ifu_dark_contribMap.fits\n\
85 master dark image (single FITS image) PD_DBG\n\
86 eris_ifu_dark_dbg_image.fits\n\
87 input dark images as stack & input reading BPM PD_DBG\n\
88 eris_ifu_dark_dbg_cube.fits\n\
89 Detailed output of 3D bad pixel detection PD_DBG\n\
90 eris_ifu_dark_dbg_3d.fits\n\
91-----------------------------------------------------------------------------\n\
94 QC.DARK.NBADPIX Total number of bad pixels but border pixels\n\
95 QC.DARK.BPIXFRAC Fraction of bad pixels to total number of pixels\n\
96 QC.DARK.NBADPIXSAT Saturated pixels count\n\
97 QC.DARK.NBADPIX2D Dark 2D bad pixels count\n\
98 QC.DARK.NBADPIX3D Dark 3D bad pixels count\n\
99 QC.DARK.BPIXFRAC2D Fraction of 2D bad pixel to total number of pixels\n\
100 QC.DARK.BPIXFRAC3D Fraction of 3D bad pixel to total number of pixels\n\
101 QC.MASTERDARK.MEAN Clean mean of master dark image\n\
102 QC.MASTERDARK.STDEV Clean stdev of master dark image\n\
103 QC.DARKMED.AVE Average of raw darks medians\n\
104 QC.DARKMED.STDEV Read Out Noise\n\
105 QC.DARKFPN Fixed Pattern Noise of combined frames\n\
106 QC.RON RMS on Read Out Noise\n\
107 QC.RONRMS STDEV of raw darks medians\n\
108 QC.RONi Read Out Noise\n\
109 qQC.NRONS Number of RON frames d \n\
116cpl_recipe_define(eris_ifu_dark, ERIS_BINARY_VERSION,
"Erich Wiezorrek",
117 PACKAGE_BUGREPORT,
"2017",
118 "This recipe perform dark data reduction",
119 eris_ifu_dark_description);
135static cpl_error_code eris_ifu_dark_fill_parameterlist(cpl_parameterlist *pl)
137 cpl_parameter *p = NULL;
138 cpl_error_code err = CPL_ERROR_NONE;
140 cpl_ensure_code(pl, CPL_ERROR_NULL_INPUT);
156 p = cpl_parameter_new_range(
"eris.eris_ifu_dark.qc_ron_xmin",
159 "eris.eris_ifu_dark",
160 9,1,ERIS_IFU_DETECTOR_SIZE-4));
162 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_ron_xmin"));
164 cpl_parameterlist_append(pl, p));
167 p = cpl_parameter_new_range(
"eris.eris_ifu_dark.qc_ron_xmax",
170 "eris.eris_ifu_dark",
171 2040,1,ERIS_IFU_DETECTOR_SIZE));
173 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_ron_xmax"));
175 cpl_parameterlist_append(pl, p));
178 p = cpl_parameter_new_range(
"eris.eris_ifu_dark.qc_ron_ymin",
181 "eris.eris_ifu_dark",
182 9,1,ERIS_IFU_DETECTOR_SIZE));
184 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_ron_ymin"));
186 cpl_parameterlist_append(pl, p));
189 p = cpl_parameter_new_range(
"eris.eris_ifu_dark.qc_ron_ymax",
192 "eris.eris_ifu_dark",
193 2040,1,ERIS_IFU_DETECTOR_SIZE));
195 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_ron_ymax"));
197 cpl_parameterlist_append(pl, p));
200 p = cpl_parameter_new_value(
"eris.eris_ifu_dark.qc_ron_hsize",
203 "eris.eris_ifu_dark",
206 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_ron_hsize"));
208 cpl_parameterlist_append(pl, p));
211 p = cpl_parameter_new_value(
"eris.eris_ifu_dark.qc_ron_nsamp",
214 "eris.eris_ifu_dark",
217 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_ron_nsamp"));
219 cpl_parameterlist_append(pl, p));
222 p = cpl_parameter_new_range(
"eris.eris_ifu_dark.qc_fpn_xmin",
225 "eris.eris_ifu_dark",
226 7,1,ERIS_IFU_DETECTOR_SIZE));
228 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_fpn_xmin"));
230 cpl_parameterlist_append(pl, p));
233 p = cpl_parameter_new_range(
"eris.eris_ifu_dark.qc_fpn_xmax",
236 "eris.eris_ifu_dark",
237 2042,1,ERIS_IFU_DETECTOR_SIZE));
239 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_fpn_xmax"));
241 cpl_parameterlist_append(pl, p));
244 p = cpl_parameter_new_range(
"eris.eris_ifu_dark.qc_fpn_ymin",
247 "eris.eris_ifu_dark",
248 7,1,ERIS_IFU_DETECTOR_SIZE));
250 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_fpn_ymin"));
252 cpl_parameterlist_append(pl, p));
255 p = cpl_parameter_new_range(
"eris.eris_ifu_dark.qc_fpn_ymax",
258 "eris.eris_ifu_dark",
259 2042,1,ERIS_IFU_DETECTOR_SIZE));
261 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_fpn_ymax"));
263 cpl_parameterlist_append(pl, p));
266 p = cpl_parameter_new_value(
"eris.eris_ifu_dark.qc_fpn_hsize",
269 "eris.eris_ifu_dark",
272 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_fpn_hsize"));
274 cpl_parameterlist_append(pl, p));
277 p = cpl_parameter_new_value(
"eris.eris_ifu_dark.qc_fpn_nsamp",
280 "eris.eris_ifu_dark",
283 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"qc_fpn_nsamp"));
285 cpl_parameterlist_append(pl, p));
290 err = cpl_error_get_code();
304static int eris_ifu_dark(cpl_frameset *frameset,
305 const cpl_parameterlist *parlist)
307 hdrl_parameter *pdarkcollapse = NULL;
308 const cpl_frame *rawframe = NULL;
309 cpl_propertylist *applist = NULL;
310 cpl_imagelist *darkImageList = NULL;
311 hdrl_imagelist *darkHdrlImageList = NULL;
312 hdrl_image *masterDarkHdrlImage = NULL;
313 cpl_image *contribMap = NULL,
317 *masterDarkImage = NULL,
319 *qualityImage = NULL;
320 cpl_mask *bpm2dMask = NULL,
322 productDepthType productDepth = PD_SCIENCE;
323 struct stdParamStruct stdParams = stdParamStructInit;
325 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
326 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
330 if (cpl_frameset_get_size(frameset) == 0) {
332 "Missing or empty SOF file");
337 if (cpl_frameset_count_tags(frameset, ERIS_IFU_RAW_DARK) < 3) {
339 "At least three dark frames (tagged as '"
341 "') must be provided in the SOF");
344 cpl_msg_info(cpl_func,
"Reading recipe parameters");
348 productDepth = stdParams.productDepth;
353 "eris.eris_ifu_dark.collapse"));
358 cpl_msg_info(cpl_func,
"Loading set of frames (SOF)");
360 rawframe = cpl_frameset_find_const(frameset, ERIS_IFU_RAW_DARK);
361 if (rawframe == NULL) {
364 return (
int) cpl_error_set_message(cpl_func,
365 CPL_ERROR_DATA_NOT_FOUND,
366 "SOF does not have any file tagged with %s",
372 ERIS_IFU_RAW_DARK, stdParams.rawImageCorrectionMask));
379 applist = cpl_propertylist_new());
384 darkHdrlImageList, pdarkcollapse,
385 &masterDarkHdrlImage, &qualityImage,
386 &bpMask, &contribMap,
387 &bpm2dMask, &bpm3dMask, applist));
389 masterDarkImage = cpl_image_duplicate(
392 if (masterDarkImage == NULL) {
393 return (
int) cpl_error_set_message(cpl_func, cpl_error_get_code(),
394 "Could not load the image");
400 cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG,
404 if (masterDarkImage != NULL)
412 cpl_propertylist_set_string(applist, CPL_DFS_PRO_CATG,
417 REC_NAME_DARK, applist, NULL,
418 ERIS_IFU_PRO_DARK_FN,
419 masterDarkImage, errorImage, rmse,
420 qualityImage, flag16bit, UNIT_ADU));
425 ERIS_IFU_PRO_DARK_BPM,
426 ERIS_IFU_PRO_DARK_BPM_FN,
431 if (bpm2dMask != NULL && productDepth >= PD_AUXILLIARY) {
432 BRK_IF_NULL(bpm2dImg = cpl_image_new_from_mask(bpm2dMask));
435 ERIS_IFU_PRO_DARK_DBG_BPM2D,
436 ERIS_IFU_PRO_DARK_DBG_BPM2D_FN,
440 if (bpm3dMask != NULL && productDepth >= PD_AUXILLIARY) {
441 BRK_IF_NULL(bpm3dImg = cpl_image_new_from_mask(bpm3dMask));
444 ERIS_IFU_PRO_DARK_DBG_BPM3D,
445 ERIS_IFU_PRO_DARK_DBG_BPM3D_FN,
452 if (contribMap != NULL && productDepth >= PD_ALL) {
455 ERIS_IFU_PRO_DARK_DBG_CONTRIBMAP,
456 ERIS_IFU_PRO_DARK_DBG_CONTRIBMAP_FN,
461 if (masterDarkImage != NULL && productDepth >= PD_DEBUG) {
464 ERIS_IFU_PRO_DARK_DBG_IMAGE_FN, TRUE, NULL));
467 if (darkImageList != NULL && productDepth >= PD_DEBUG) {
470 ERIS_IFU_PRO_DARK_DBG_CUBE_FN));
472 cpl_image *sbpm = cpl_image_new(2048,2048,CPL_TYPE_INT);
473 cpl_imagelist *cbpm = cpl_imagelist_new();
474 for (
int bx=0 ; bx<cpl_imagelist_get_size(darkImageList); bx++) {
475 cpl_mask *tmask = cpl_image_get_bpm(
476 cpl_imagelist_get(darkImageList, bx));
477 cpl_image *timg = cpl_image_new_from_mask(tmask);
478 cpl_imagelist_set(cbpm, timg, bx);
481 cpl_image_add(sbpm, timg);
483 cpl_imagelist_save(cbpm, ERIS_IFU_PRO_DARK_DBG_CUBE_FN
".fits",
484 CPL_TYPE_INT,NULL,CPL_IO_EXTEND);
485 cpl_image_save(sbpm, ERIS_IFU_PRO_DARK_DBG_CUBE_FN
".fits",
486 CPL_TYPE_INT,NULL,CPL_IO_EXTEND);
495 cpl_image_delete(sbpm);
496 cpl_imagelist_delete(cbpm);
518 if (cpl_memory_is_empty() == 0)
522 return (
int) cpl_error_get_code();
cpl_error_code eris_ifu_dark_static(const cpl_parameterlist *parlist, hdrl_imagelist *darkImageList, hdrl_parameter *pdarkcollapse, hdrl_image **masterDarkHdrlImg, cpl_image **qualityImage, cpl_image **masterBpm, cpl_image **contribMap, cpl_mask **bpm2dMask, cpl_mask **bpm3dMask, cpl_propertylist *qcParams)
Determine master dark and bad pixel maps.
cpl_error_code eris_ifu_dfs_set_groups(cpl_frameset *self)
Set the frame group (RAW, CALIB, or PRODUCT) for all frames in a frameset.
cpl_error_code eris_ifu_save_deq_image(cpl_frameset *allframes, cpl_propertylist *header, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_frame *inherit, const char *recipe, const cpl_propertylist *applist, const char *remregexp, const char *filename, const cpl_image *image, const cpl_image *error, deqErrorType errorType, const cpl_image *dataQualityMask, deqQualityType dataQualityType, const char *unit)
Save a DFS-compliant image product with data, error, and quality extensions.
#define BRK_IF_ERROR(function)
If function is or returns an error != CPL_ERROR_NONE, then the try-block is exited.
#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.
cpl_error_code eris_ifu_fetch_std_param(const cpl_parameterlist *parlist, const char *recipename, struct stdParamStruct *stdParams)
Fetch standard parameters from parameter list into structure.
void eris_ifu_free_std_param(struct stdParamStruct *stdParams)
Free memory allocated for stdParamStruct.
cpl_error_code eris_ifu_add_std_params(cpl_parameterlist *pl, const char *recipename)
Add standard recipe parameters to a parameter list.
cpl_error_code eris_parlist_config_add_bpm(cpl_parameterlist *pl, const char *recname)
Add bad pixel mask configuration parameters to parameter list.
cpl_error_code eris_ifu_save_cpl_image_dbg(const cpl_image *img, const char *name, int singlefile, const cpl_propertylist *pl)
Save CPL image with mask for debugging.
void eris_ifu_free_propertylist(cpl_propertylist **item)
Free memory and set pointer to null.
hdrl_imagelist * eris_ifu_get_hdrlimagelist_by_tag(cpl_frameset *frameset, const char *tag, int exposureCorrectionMode)
Return HDRL imagelist by searching tagged frames in frameset.
cpl_imagelist * eris_ifu_hdrl_get_imagelist(const hdrl_imagelist *hdrl_imglist, enum hdrl_t type)
Extract from an HDRL imagelist a specific CPL imagelist.
void eris_ifu_free_imagelist(cpl_imagelist **item)
Free memory and set pointer to null.
void eris_ifu_free_hdrl_imagelist(hdrl_imagelist **item)
Free memory and set pointer to null.
cpl_error_code eris_ifu_save_cpl_imagelist_dbg(const cpl_imagelist *imglist, const char *name)
Save CPL imagelist for debugging.
void eris_ifu_free_hdrl_image(hdrl_image **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.
cpl_error_code eris_ifu_save_image(cpl_frameset *fs, const cpl_propertylist *plist, const cpl_parameterlist *parlist, const char *recipe, const char *procatg, const char *filename, cpl_type type, const cpl_image *image)
Save image with DFS compliance.
void eris_ifu_free_hdrl_parameter(hdrl_parameter **item)
Free memory and set pointer to null.
hdrl_parameter * hdrl_collapse_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
parse parameterlist for imagelist reduction method
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