ERIS Pipeline Reference Manual 1.9.2
eris_ifu_dark_static.c
1/* $Id$
2 *
3 * This file is part of the ERIS Pipeline
4 * Copyright (C) 2002,2003 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#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
25#include "eris_ifu_error.h"
26#include "eris_ifu_utils.h"
27#include "eris_ifu_functions.h"
28#include "eris_ifu_dark_static.h"
29#include "eris_ifu_dfs.h"
30#include "eris_utils.h"
31
32/*----------------------------------------------------------------------------*/
45/*----------------------------------------------------------------------------*/
46
49/*----------------------------------------------------------------------------*/
74/*----------------------------------------------------------------------------*/
75cpl_error_code eris_ifu_dark_static(const cpl_parameterlist *parlist,
76 hdrl_imagelist *darkImageList,
77 hdrl_parameter *pdarkcollapse,
78 hdrl_image **masterDarkHdrlImg,
79 cpl_image **qualityImage,
80 cpl_image **masterBpm,
81 cpl_image **contribMap,
82 cpl_mask **bpm2dMask,
83 cpl_mask **bpm3dMask,
84 cpl_propertylist *qcParams)
85{
86 cpl_error_code retVal = CPL_ERROR_NONE;
87 cpl_image *noiseImage = NULL;
88 cpl_image *masterBpmImg = NULL;
89 cpl_mask *borderSaturatedMask = NULL;
90 const cpl_mask *masterBpmMask = NULL;
91 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
92 cpl_ensure_code(darkImageList, CPL_ERROR_NULL_INPUT);
93 cpl_ensure_code(pdarkcollapse, CPL_ERROR_NULL_INPUT);
94 cpl_ensure_code(masterDarkHdrlImg, CPL_ERROR_NULL_INPUT);
95 cpl_ensure_code(qualityImage, CPL_ERROR_NULL_INPUT);
96 cpl_ensure_code(masterBpm, CPL_ERROR_NULL_INPUT);
97 cpl_ensure_code(contribMap, CPL_ERROR_NULL_INPUT);
98 cpl_ensure_code(bpm2dMask, CPL_ERROR_NULL_INPUT);
99 cpl_ensure_code(bpm3dMask, CPL_ERROR_NULL_INPUT);
100 cpl_ensure_code(qcParams, CPL_ERROR_NULL_INPUT);
101
102 TRY
103 {
104 cpl_msg_info(cpl_func, "Generate master dark image");
105 hdrl_image *tmpHdrlImg = NULL;
106 hdrl_imagelist_collapse(darkImageList, pdarkcollapse,
107 &tmpHdrlImg, contribMap);
108
109 cpl_msg_info(cpl_func, "Generate noise image");
110 noiseImage = eris_ifu_dark_noise(darkImageList);
111 *masterDarkHdrlImg = hdrl_image_create(
112 hdrl_image_get_image_const(tmpHdrlImg), noiseImage);
113 eris_ifu_free_hdrl_image(&tmpHdrlImg);
114
115 // fetch bad-pix-image: border pixels and saturated pixels are
116 // set up-to-now
117 borderSaturatedMask = cpl_mask_duplicate(
118 hdrl_image_get_mask_const(*masterDarkHdrlImg));
119
120
121 /* Create & apply bad-pixel-mask */
122 eris_ifu_calc_bpm(parlist,
123 REC_NAME_DARK,
124 *masterDarkHdrlImg, // needed for 2dbpm
125 darkImageList, // needed for 3dbpm
126 bpm2dMask, bpm3dMask); // return values
127
128 // create quality type image
129 (*qualityImage) = eris_ifu_dark_get_dqi(
130 borderSaturatedMask, *bpm2dMask, *bpm3dMask);
131
132 // fetch bad-pix-image: bpm2dMask and bpm3dMask are added now
133 masterBpmMask = hdrl_image_get_mask_const(*masterDarkHdrlImg);
134
135 masterBpmImg = cpl_image_new_from_mask(masterBpmMask);
136
137 if (qcParams != NULL) {
138 cpl_msg_info(cpl_func, "Generate QC parameters");
139 eris_ifu_dark_qc(parlist, *masterDarkHdrlImg, darkImageList,
140 masterBpmMask, *qualityImage, qcParams);
141 }
142 }
143 CATCH
144 {
145 retVal = cpl_error_get_code();
146 eris_ifu_free_mask(bpm2dMask);
147 eris_ifu_free_mask(bpm3dMask);
148 }
149
150 (*masterBpm) = masterBpmImg;
151 eris_ifu_free_image(&noiseImage);
152 eris_ifu_free_mask(&borderSaturatedMask);
153 eris_check_error_code("eris_ifu_dark_static");
154 return retVal;
155}
156
157/*----------------------------------------------------------------------------*/
170/*----------------------------------------------------------------------------*/
171cpl_image *eris_ifu_dark_noise(hdrl_imagelist* imageList)
172{
173 cpl_image *noiseImage = NULL;
174 cpl_size xDim,yDim,zDim;
175 cpl_vector *data;
176 int rejected;
177
178 TRY
179 {
180 xDim = hdrl_imagelist_get_size_x(imageList);
181 yDim = hdrl_imagelist_get_size_y(imageList);
182 zDim = hdrl_imagelist_get_size(imageList);
183 noiseImage = cpl_image_new(xDim, yDim, CPL_TYPE_DOUBLE);
184 data = cpl_vector_new(zDim);
185 for (int x = 1; x <= xDim; x++)
186 {
187 for (int y = 1; y <= yDim; y++)
188 {
189 for (int z = 0; z < zDim; z++)
190 {
191 cpl_vector_set(data, z, cpl_image_get(
193 hdrl_imagelist_get(imageList,z)), x, y, &rejected));
194 }
195 cpl_image_set(noiseImage, x, y, cpl_vector_get_stdev(data));
196 }
197 }
198 }
199 CATCH
200 {
201 }
203 eris_check_error_code("eris_ifu_dark_noise");
204 return noiseImage;
205}
206
207/*----------------------------------------------------------------------------*/
234/*----------------------------------------------------------------------------*/
235cpl_error_code eris_ifu_dark_qc(
236 const cpl_parameterlist *parlist,
237 hdrl_image *masterDarkHdrlImg,
238 hdrl_imagelist* darkImageList,
239 const cpl_mask *masterBpm,
240 const cpl_image *qualityImage,
241 cpl_propertylist *qcParams)
242{
243 cpl_error_code retVal = CPL_ERROR_NONE;
244 hdrl_image *qcMasterDarkHdrlImg = NULL;
245 const cpl_image *masterDarkImage = NULL;
246 cpl_image *tmpImg = NULL;
247 cpl_vector *qcMedian = NULL;
248 cpl_size nBadPixels = 0;
249 cpl_size frameCnt;
250 hdrl_value mean;
251 double stdev;
252 cpl_size zone_def[4];
253 cpl_size hsize, nsamp;
254 double qc_ron_val, qc_ron_err, qc_fpn_val;
255 char *paramName;
256 cpl_size sx = 0;
257 cpl_size sy = 0;
258 cpl_size npix = 0;
259 double fracBadPix = 0;
260 const int *qiData = NULL;
261 cpl_size imgDim = 0;
262 int satCnt = 0;
263 int bp2dCnt = 0;
264 int bp3dCnt = 0;
265
266 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
267 cpl_ensure_code(masterDarkHdrlImg, CPL_ERROR_NULL_INPUT);
268 cpl_ensure_code(darkImageList, CPL_ERROR_NULL_INPUT);
269 cpl_ensure_code(masterBpm, CPL_ERROR_NULL_INPUT);
270 cpl_ensure_code(qcParams, CPL_ERROR_NULL_INPUT);
271
272 TRY
273 {
274
275 // count bad pixels but subtract "masked" border pixels
276 nBadPixels = cpl_mask_count(masterBpm) - (2048*8 + 2040*8);
277
278 //exit(0);
279 sx = cpl_mask_get_size_x(masterBpm);
280 sy = cpl_mask_get_size_y(masterBpm);
281
282 npix = sx * sy;
283 fracBadPix = (double) ((int) nBadPixels) / (int) npix;
284
285 eris_ifu_append_qc_int(qcParams,"DARK NBADPIX", (int) nBadPixels,
286 "Total number of bad pixels but border pixels");
287 eris_ifu_append_qc_float(qcParams, "DARK BPIXFRAC", fracBadPix,
288 "Fraction of bad pixels to total");
289
290 qiData = cpl_image_get_data_const(qualityImage);
291 imgDim = cpl_image_get_size_x(qualityImage) *
292 cpl_image_get_size_y(qualityImage);
293 satCnt = 0;
294 bp2dCnt = 0;
295 bp3dCnt = 0;
296 for (cpl_size ix=0; ix<imgDim; ix++) {
297 if (qiData[ix] & ERIS_DQI_SAT) {
298 satCnt++;
299 }
300 if (qiData[ix] & ERIS_DQI_BP_BPM2D) {
301 bp2dCnt++;
302 }
303 if (qiData[ix] & ERIS_DQI_BP_BPM3D) {
304 bp3dCnt++;
305 }
306 }
307 eris_ifu_append_qc_int(qcParams,"DARK NBADPIXSAT", satCnt,
308 "Saturated pixels");
309 eris_ifu_append_qc_int(qcParams,"DARK NBADPIX2D", bp2dCnt,
310 "Dark 2D bad pixels");
311
312 eris_ifu_append_qc_int(qcParams,"DARK NBADPIX3D", bp3dCnt,
313 "Dark 3D bad pixels");
314 eris_ifu_append_qc_double(qcParams, "DARK BPIXFRAC2D",
315 (double) ((int) bp2dCnt) / (int) npix,
316 "Fraction of 2D bad pixels to total");
317
318 eris_ifu_append_qc_double(qcParams, "DARK BPIXFRAC3D",
319 (double) ((int) bp3dCnt) / (int) npix,
320 "Fraction of 3D bad pixels to total");
321
322
323 qcMasterDarkHdrlImg = hdrl_image_duplicate(masterDarkHdrlImg);
324
325 eris_ifu_hdrl_image_reject_mask(qcMasterDarkHdrlImg, masterBpm);
326
327 mean = hdrl_image_get_mean(qcMasterDarkHdrlImg);
328 stdev = hdrl_image_get_stdev(qcMasterDarkHdrlImg);
329 eris_ifu_free_hdrl_image(&qcMasterDarkHdrlImg);
331 eris_ifu_append_qc_double(qcParams, "MASTERDARK MEAN", mean.data,
332 "[ADU] Clean mean of master dark image");
333
334 // eris_ifu_append_qc_double(qcParams, "MASTERDARK ERR", mean.error,
335 // "Clean error of master dark image");
336 eris_ifu_append_qc_double(qcParams, "MASTERDARK STDEV", stdev,
337 "[ADU] Clean stdev of master dark image");
338
339 frameCnt = hdrl_imagelist_get_size(darkImageList);
340
341 qcMedian = cpl_vector_new(frameCnt);
342 for (int i=0; i<frameCnt; i++) {
343 cpl_vector_set(qcMedian, i,
344 cpl_image_get_median(
346 hdrl_imagelist_get(darkImageList,i))));
347 }
348
349 eris_ifu_append_qc_double(qcParams,"DARKMED AVE",
350 cpl_vector_get_mean(qcMedian), "[ADU] Average of raw darks medians");
351
352 eris_ifu_append_qc_double(qcParams,"DARKMED STDEV",
353 cpl_vector_get_stdev(qcMedian), "[ADU] Stdev Read Out Noise");
354 eris_ifu_free_vector(&qcMedian);
355
356 masterDarkImage = hdrl_image_get_image_const(masterDarkHdrlImg);
357 /* -- FPN */
358 zone_def[0] = cpl_parameter_get_int(
359 cpl_parameterlist_find_const(parlist,
360 "eris.eris_ifu_dark.qc_fpn_xmin"));
361 zone_def[1] = cpl_parameter_get_int(
362 cpl_parameterlist_find_const(parlist,
363 "eris.eris_ifu_dark.qc_fpn_xmax"));
364 zone_def[2] = cpl_parameter_get_int(
365 cpl_parameterlist_find_const(parlist,
366 "eris.eris_ifu_dark.qc_fpn_ymin"));
367 zone_def[3] = cpl_parameter_get_int(
368 cpl_parameterlist_find_const(parlist,
369 "eris.eris_ifu_dark.qc_fpn_ymax"));
370 hsize = cpl_parameter_get_int(
371 cpl_parameterlist_find_const(parlist,
372 "eris.eris_ifu_dark.qc_fpn_hsize"));
373 nsamp = cpl_parameter_get_int(
374 cpl_parameterlist_find_const(parlist,
375 "eris.eris_ifu_dark.qc_fpn_nsamp"));
377
378 cpl_flux_get_noise_window(masterDarkImage, zone_def, hsize, nsamp,
379 &qc_fpn_val, NULL);
380 eris_ifu_append_qc_double(qcParams,"DARKFPN", qc_fpn_val,
381 "Fixed Pattern Noise of combined frames");
382
383 /* -- RON */
384 zone_def[0] = cpl_parameter_get_int(
385 cpl_parameterlist_find_const(parlist,
386 "eris.eris_ifu_dark.qc_ron_xmin"));
387 zone_def[1] = cpl_parameter_get_int(
388 cpl_parameterlist_find_const(parlist,
389 "eris.eris_ifu_dark.qc_ron_xmax"));
390 zone_def[2] = cpl_parameter_get_int(
391 cpl_parameterlist_find_const(parlist,
392 "eris.eris_ifu_dark.qc_ron_ymin"));
393 zone_def[3] = cpl_parameter_get_int(
394 cpl_parameterlist_find_const(parlist,
395 "eris.eris_ifu_dark.qc_ron_ymax"));
396 hsize = cpl_parameter_get_int(
397 cpl_parameterlist_find_const(parlist,
398 "eris.eris_ifu_dark.qc_ron_hsize"));
399 nsamp = cpl_parameter_get_int(
400 cpl_parameterlist_find_const(parlist,
401 "eris.eris_ifu_dark.qc_ron_nsamp"));
403
404 cpl_flux_get_noise_window(masterDarkImage, zone_def, hsize,
405 nsamp, &qc_ron_val, &qc_ron_err);
406 eris_ifu_append_qc_double(qcParams,"RON", qc_ron_val,
407 "[ADU] Read Out Noise");
408 eris_ifu_append_qc_double(qcParams,"RONRMS", qc_ron_err,
409 "[ADU] Error of Read Out Noise");
410 /* --RONn */
411 for (int i=0 ; i<frameCnt-1 ; i++) {
412 tmpImg = cpl_image_subtract_create(
414 hdrl_imagelist_get(darkImageList,i)),
416 hdrl_imagelist_get(darkImageList,i+1)) );
417
418 cpl_flux_get_noise_window(tmpImg, zone_def, hsize, nsamp,
419 &qc_ron_val, NULL);
420 qc_ron_val *= sqrt(1./2.);
421
422 paramName = cpl_sprintf("RON%d",i+1);
423 eris_ifu_append_qc_double(qcParams,paramName, qc_ron_val,
424 "[ADU] Read Out Noise");
425
426 eris_ifu_free_image(&tmpImg);
427 eris_ifu_free_string(&paramName);
428 }
429 eris_ifu_append_qc_int(qcParams,"NRONS", (int) frameCnt-1,
430 "Number of RON frames");
431
432 }
433 CATCH
434 {
435 retVal = cpl_error_get_code();
436 }
437 eris_check_error_code("eris_ifu_dark_qc");
438 return retVal;
439}
440
441/*----------------------------------------------------------------------------*/
461/*----------------------------------------------------------------------------*/
463 const cpl_mask* masterBpmMask,
464 const cpl_mask* bpm2dMask,
465 const cpl_mask* bpm3dMask ) {
466
467 cpl_image *dqi = NULL;
468 cpl_image *tmpImg = NULL;
469
470 TRY {
471 dqi = cpl_image_new_from_mask(masterBpmMask);
472 cpl_image_multiply_scalar(dqi, ERIS_DQI_SAT);
473 for (cpl_size ix=1; ix <= ERIS_IFU_DETECTOR_SIZE; ix++) {
474 for (cpl_size iy=1; iy <= 4; iy ++) {
475 cpl_image_set(dqi,ix, iy, ERIS_DQI_BP);
476 }
477 for (cpl_size iy=ERIS_IFU_DETECTOR_SIZE-3;
478 iy <= ERIS_IFU_DETECTOR_SIZE; iy ++) {
479 cpl_image_set(dqi,ix, iy, ERIS_DQI_BP);
480 }
481 }
482 for (cpl_size iy=1; iy <= ERIS_IFU_DETECTOR_SIZE; iy++) {
483 for (cpl_size ix=1; ix <= 4; ix ++) {
484 cpl_image_set(dqi,ix, iy, ERIS_DQI_BP);
485 }
486 for (cpl_size ix=ERIS_IFU_DETECTOR_SIZE-3;
487 ix <= ERIS_IFU_DETECTOR_SIZE; ix ++) {
488 cpl_image_set(dqi,ix, iy, ERIS_DQI_BP);
489 }
490 }
491
492 tmpImg = cpl_image_new_from_mask(bpm2dMask);
493 cpl_image_multiply_scalar(tmpImg, ERIS_DQI_BP_BPM2D);
494 cpl_image_add(dqi, tmpImg);
495 eris_ifu_free_image(&tmpImg);
496
497 tmpImg = cpl_image_new_from_mask(bpm3dMask);
498 cpl_image_multiply_scalar(tmpImg, ERIS_DQI_BP_BPM3D);
499 cpl_image_add(dqi, tmpImg);
500 eris_ifu_free_image(&tmpImg);
501
502 }
503 CATCH
504 {
505 }
506 eris_check_error_code("eris_ifu_dark_get_dqi");
507 return dqi;
508}
509
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_dark_qc(const cpl_parameterlist *parlist, hdrl_image *masterDarkHdrlImg, hdrl_imagelist *darkImageList, const cpl_mask *masterBpm, const cpl_image *qualityImage, cpl_propertylist *qcParams)
Determine quality control parameters for master dark.
cpl_image * eris_ifu_dark_get_dqi(const cpl_mask *masterBpmMask, const cpl_mask *bpm2dMask, const cpl_mask *bpm3dMask)
Create a data quality indicator (DQI) image from bad pixel masks.
cpl_image * eris_ifu_dark_noise(hdrl_imagelist *imageList)
Determine dark noise image from standard deviation across frames.
cpl_error_code eris_ifu_append_qc_float(cpl_propertylist *pl, const char *name, float val, const char *comment)
Append a QC parameter of type FLOAT to a property list.
cpl_error_code eris_ifu_append_qc_double(cpl_propertylist *pl, const char *name, double val, const char *comment)
Append a QC parameter of type DOUBLE to a property list.
cpl_error_code eris_ifu_append_qc_int(cpl_propertylist *pl, const char *name, int val, const char *comment)
Append a QC parameter of type INT to a property list.
#define CHECK_ERROR_STATE(void)
Check the CPL error state, and exit the try-block if not CPL_ERROR_NONE.
#define TRY
Beginning of a TRY-block.
#define CATCH
End of a TRY-block, beginning of a CATCH-block.
cpl_error_code eris_ifu_calc_bpm(const cpl_parameterlist *pl, const char *recipe_name, hdrl_image *master_img, const hdrl_imagelist *imglist_on, cpl_mask **bpm2dMask, cpl_mask **bpm3dMask)
Create 2D and/or 3D bad pixel masks using HDRL algorithms.
void eris_ifu_free_string(char **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_hdrl_image_reject_mask(hdrl_image *img, const cpl_mask *mask)
Add mask to HDRL image (reject masked pixels)
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_check_error_code(const char *func_id)
handle CPL errors
Definition: eris_utils.c:56
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
Definition: hdrl_image.c:391
double hdrl_image_get_stdev(const hdrl_image *self)
computes the standard deviation of the data of an image
hdrl_value hdrl_image_get_mean(const hdrl_image *self)
computes mean pixel value and associated error of an image.
const cpl_mask * hdrl_image_get_mask_const(const hdrl_image *himg)
get cpl bad pixel mask from image
Definition: hdrl_image.c:175
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
Definition: hdrl_image.c:295
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:118
cpl_size hdrl_imagelist_get_size_y(const hdrl_imagelist *himlist)
Get number of rows of images in the imagelist.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
cpl_error_code hdrl_imagelist_collapse(const hdrl_imagelist *himlist, const hdrl_parameter *param, hdrl_image **out, cpl_image **contrib)
collapsing of image list
cpl_size hdrl_imagelist_get_size_x(const hdrl_imagelist *himlist)
Get number of colums of images in the imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.