ERIS Pipeline Reference Manual 1.8.10
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"
44cpl_error_code eris_ifu_dark_static(const cpl_parameterlist *parlist,
45 hdrl_imagelist *darkImageList,
46 hdrl_parameter *pdarkcollapse,
47 hdrl_image **masterDarkHdrlImg,
48 cpl_image **qualityImage,
49 cpl_image **masterBpm,
50 cpl_image **contribMap,
51 cpl_mask **bpm2dMask,
52 cpl_mask **bpm3dMask,
53 cpl_propertylist *qcParams)
54{
55 cpl_error_code retVal = CPL_ERROR_NONE;
56 cpl_image *noiseImage = NULL;
57 cpl_image *masterBpmImg = NULL;
58 cpl_mask *borderSaturatedMask = NULL;
59 const cpl_mask *masterBpmMask = NULL;
60 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
61 cpl_ensure_code(darkImageList, CPL_ERROR_NULL_INPUT);
62 cpl_ensure_code(pdarkcollapse, CPL_ERROR_NULL_INPUT);
63 cpl_ensure_code(masterDarkHdrlImg, CPL_ERROR_NULL_INPUT);
64 cpl_ensure_code(qualityImage, CPL_ERROR_NULL_INPUT);
65 cpl_ensure_code(masterBpm, CPL_ERROR_NULL_INPUT);
66 cpl_ensure_code(contribMap, CPL_ERROR_NULL_INPUT);
67 cpl_ensure_code(bpm2dMask, CPL_ERROR_NULL_INPUT);
68 cpl_ensure_code(bpm3dMask, CPL_ERROR_NULL_INPUT);
69 cpl_ensure_code(qcParams, CPL_ERROR_NULL_INPUT);
70
71 TRY
72 {
73 cpl_msg_info(cpl_func, "Generate master dark image");
74 hdrl_image *tmpHdrlImg = NULL;
75 hdrl_imagelist_collapse(darkImageList, pdarkcollapse,
76 &tmpHdrlImg, contribMap);
77
78 cpl_msg_info(cpl_func, "Generate noise image");
79 noiseImage = eris_ifu_dark_noise(darkImageList);
80 *masterDarkHdrlImg = hdrl_image_create(
81 hdrl_image_get_image_const(tmpHdrlImg), noiseImage);
82 eris_ifu_free_hdrl_image(&tmpHdrlImg);
83
84 // fetch bad-pix-image: border pixels and saturated pixels are
85 // set up-to-now
86 borderSaturatedMask = cpl_mask_duplicate(
87 hdrl_image_get_mask_const(*masterDarkHdrlImg));
88
89
90 /* Create & apply bad-pixel-mask */
91 eris_ifu_calc_bpm(parlist,
92 REC_NAME_DARK,
93 *masterDarkHdrlImg, // needed for 2dbpm
94 darkImageList, // needed for 3dbpm
95 bpm2dMask, bpm3dMask); // return values
96
97 // create quality type image
98 (*qualityImage) = eris_ifu_dark_get_dqi(
99 borderSaturatedMask, *bpm2dMask, *bpm3dMask);
100
101 // fetch bad-pix-image: bpm2dMask and bpm3dMask are added now
102 masterBpmMask = hdrl_image_get_mask_const(*masterDarkHdrlImg);
103
104 masterBpmImg = cpl_image_new_from_mask(masterBpmMask);
105
106 if (qcParams != NULL) {
107 cpl_msg_info(cpl_func, "Generate QC parameters");
108 eris_ifu_dark_qc(parlist, *masterDarkHdrlImg, darkImageList,
109 masterBpmMask, *qualityImage, qcParams);
110 }
111 }
112 CATCH
113 {
114 retVal = cpl_error_get_code();
115 eris_ifu_free_mask(bpm2dMask);
116 eris_ifu_free_mask(bpm3dMask);
117 }
118
119 (*masterBpm) = masterBpmImg;
120 eris_ifu_free_image(&noiseImage);
121 eris_ifu_free_mask(&borderSaturatedMask);
122 eris_check_error_code("eris_ifu_dark_static");
123 return retVal;
124}
125
131cpl_image *eris_ifu_dark_noise(hdrl_imagelist* imageList)
132{
133 cpl_image *noiseImage = NULL;
134 cpl_size xDim,yDim,zDim;
135 cpl_vector *data;
136 int rejected;
137
138 TRY
139 {
140 xDim = hdrl_imagelist_get_size_x(imageList);
141 yDim = hdrl_imagelist_get_size_y(imageList);
142 zDim = hdrl_imagelist_get_size(imageList);
143 noiseImage = cpl_image_new(xDim, yDim, CPL_TYPE_DOUBLE);
144 data = cpl_vector_new(zDim);
145 for (int x = 1; x <= xDim; x++)
146 {
147 for (int y = 1; y <= yDim; y++)
148 {
149 for (int z = 0; z < zDim; z++)
150 {
151 cpl_vector_set(data, z, cpl_image_get(
153 hdrl_imagelist_get(imageList,z)), x, y, &rejected));
154 }
155 cpl_image_set(noiseImage, x, y, cpl_vector_get_stdev(data));
156 }
157 }
158 }
159 CATCH
160 {
161 }
163 eris_check_error_code("eris_ifu_dark_noise");
164 return noiseImage;
165}
175cpl_error_code eris_ifu_dark_qc(
176 const cpl_parameterlist *parlist,
177 hdrl_image *masterDarkHdrlImg,
178 hdrl_imagelist* darkImageList,
179 const cpl_mask *masterBpm,
180 const cpl_image *qualityImage,
181 cpl_propertylist *qcParams)
182{
183 cpl_error_code retVal = CPL_ERROR_NONE;
184 hdrl_image *qcMasterDarkHdrlImg = NULL;
185 const cpl_image *masterDarkImage = NULL;
186 cpl_image *tmpImg = NULL;
187 cpl_vector *qcMedian = NULL;
188 cpl_size nBadPixels = 0;
189 cpl_size frameCnt;
190 hdrl_value mean;
191 double stdev;
192 cpl_size zone_def[4];
193 cpl_size hsize, nsamp;
194 double qc_ron_val, qc_ron_err, qc_fpn_val;
195 char *paramName;
196 cpl_size sx = 0;
197 cpl_size sy = 0;
198 cpl_size npix = 0;
199 double fracBadPix = 0;
200 const int *qiData = NULL;
201 cpl_size imgDim = 0;
202 int satCnt = 0;
203 int bp2dCnt = 0;
204 int bp3dCnt = 0;
205
206 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
207 cpl_ensure_code(masterDarkHdrlImg, CPL_ERROR_NULL_INPUT);
208 cpl_ensure_code(darkImageList, CPL_ERROR_NULL_INPUT);
209 cpl_ensure_code(masterBpm, CPL_ERROR_NULL_INPUT);
210 cpl_ensure_code(qcParams, CPL_ERROR_NULL_INPUT);
211
212 TRY
213 {
214
215 // count bad pixels but subtract "masked" border pixels
216 nBadPixels = cpl_mask_count(masterBpm) - (2048*8 + 2040*8);
217
218 //exit(0);
219 sx = cpl_mask_get_size_x(masterBpm);
220 sy = cpl_mask_get_size_y(masterBpm);
221
222 npix = sx * sy;
223 fracBadPix = (double) ((int) nBadPixels) / (int) npix;
224
225 eris_ifu_append_qc_int(qcParams,"DARK NBADPIX", (int) nBadPixels,
226 "Total number of bad pixels but border pixels");
227 eris_ifu_append_qc_float(qcParams, "DARK BPIXFRAC", fracBadPix,
228 "Fraction of bad pixels to total");
229
230 qiData = cpl_image_get_data_const(qualityImage);
231 imgDim = cpl_image_get_size_x(qualityImage) *
232 cpl_image_get_size_y(qualityImage);
233 satCnt = 0;
234 bp2dCnt = 0;
235 bp3dCnt = 0;
236 for (cpl_size ix=0; ix<imgDim; ix++) {
237 if (qiData[ix] & ERIS_DQI_SAT) {
238 satCnt++;
239 }
240 if (qiData[ix] & ERIS_DQI_BP_BPM2D) {
241 bp2dCnt++;
242 }
243 if (qiData[ix] & ERIS_DQI_BP_BPM3D) {
244 bp3dCnt++;
245 }
246 }
247 eris_ifu_append_qc_int(qcParams,"DARK NBADPIXSAT", satCnt,
248 "Saturated pixels");
249 eris_ifu_append_qc_int(qcParams,"DARK NBADPIX2D", bp2dCnt,
250 "Dark 2D bad pixels");
251
252 eris_ifu_append_qc_int(qcParams,"DARK NBADPIX3D", bp3dCnt,
253 "Dark 3D bad pixels");
254 eris_ifu_append_qc_double(qcParams, "DARK BPIXFRAC2D",
255 (double) ((int) bp2dCnt) / (int) npix,
256 "Fraction of 2D bad pixels to total");
257
258 eris_ifu_append_qc_double(qcParams, "DARK BPIXFRAC3D",
259 (double) ((int) bp3dCnt) / (int) npix,
260 "Fraction of 3D bad pixels to total");
261
262
263 qcMasterDarkHdrlImg = hdrl_image_duplicate(masterDarkHdrlImg);
264
265 eris_ifu_hdrl_image_reject_mask(qcMasterDarkHdrlImg, masterBpm);
266
267 mean = hdrl_image_get_mean(qcMasterDarkHdrlImg);
268 stdev = hdrl_image_get_stdev(qcMasterDarkHdrlImg);
269 eris_ifu_free_hdrl_image(&qcMasterDarkHdrlImg);
271 eris_ifu_append_qc_double(qcParams, "MASTERDARK MEAN", mean.data,
272 "[ADU] Clean mean of master dark image");
273
274 // eris_ifu_append_qc_double(qcParams, "MASTERDARK ERR", mean.error,
275 // "Clean error of master dark image");
276 eris_ifu_append_qc_double(qcParams, "MASTERDARK STDEV", stdev,
277 "[ADU] Clean stdev of master dark image");
278
279 frameCnt = hdrl_imagelist_get_size(darkImageList);
280
281 qcMedian = cpl_vector_new(frameCnt);
282 for (int i=0; i<frameCnt; i++) {
283 cpl_vector_set(qcMedian, i,
284 cpl_image_get_median(
286 hdrl_imagelist_get(darkImageList,i))));
287 }
288
289 eris_ifu_append_qc_double(qcParams,"DARKMED AVE",
290 cpl_vector_get_mean(qcMedian), "[ADU] Average of raw darks medians");
291
292 eris_ifu_append_qc_double(qcParams,"DARKMED STDEV",
293 cpl_vector_get_stdev(qcMedian), "[ADU] Stdev Read Out Noise");
294 eris_ifu_free_vector(&qcMedian);
295
296 masterDarkImage = hdrl_image_get_image_const(masterDarkHdrlImg);
297 /* -- FPN */
298 zone_def[0] = cpl_parameter_get_int(
299 cpl_parameterlist_find_const(parlist,
300 "eris.eris_ifu_dark.qc_fpn_xmin"));
301 zone_def[1] = cpl_parameter_get_int(
302 cpl_parameterlist_find_const(parlist,
303 "eris.eris_ifu_dark.qc_fpn_xmax"));
304 zone_def[2] = cpl_parameter_get_int(
305 cpl_parameterlist_find_const(parlist,
306 "eris.eris_ifu_dark.qc_fpn_ymin"));
307 zone_def[3] = cpl_parameter_get_int(
308 cpl_parameterlist_find_const(parlist,
309 "eris.eris_ifu_dark.qc_fpn_ymax"));
310 hsize = cpl_parameter_get_int(
311 cpl_parameterlist_find_const(parlist,
312 "eris.eris_ifu_dark.qc_fpn_hsize"));
313 nsamp = cpl_parameter_get_int(
314 cpl_parameterlist_find_const(parlist,
315 "eris.eris_ifu_dark.qc_fpn_nsamp"));
317
318 cpl_flux_get_noise_window(masterDarkImage, zone_def, hsize, nsamp,
319 &qc_fpn_val, NULL);
320 eris_ifu_append_qc_double(qcParams,"DARKFPN", qc_fpn_val,
321 "Fixed Pattern Noise of combined frames");
322
323 /* -- RON */
324 zone_def[0] = cpl_parameter_get_int(
325 cpl_parameterlist_find_const(parlist,
326 "eris.eris_ifu_dark.qc_ron_xmin"));
327 zone_def[1] = cpl_parameter_get_int(
328 cpl_parameterlist_find_const(parlist,
329 "eris.eris_ifu_dark.qc_ron_xmax"));
330 zone_def[2] = cpl_parameter_get_int(
331 cpl_parameterlist_find_const(parlist,
332 "eris.eris_ifu_dark.qc_ron_ymin"));
333 zone_def[3] = cpl_parameter_get_int(
334 cpl_parameterlist_find_const(parlist,
335 "eris.eris_ifu_dark.qc_ron_ymax"));
336 hsize = cpl_parameter_get_int(
337 cpl_parameterlist_find_const(parlist,
338 "eris.eris_ifu_dark.qc_ron_hsize"));
339 nsamp = cpl_parameter_get_int(
340 cpl_parameterlist_find_const(parlist,
341 "eris.eris_ifu_dark.qc_ron_nsamp"));
343
344 cpl_flux_get_noise_window(masterDarkImage, zone_def, hsize,
345 nsamp, &qc_ron_val, &qc_ron_err);
346 eris_ifu_append_qc_double(qcParams,"RON", qc_ron_val,
347 "[ADU] Read Out Noise");
348 eris_ifu_append_qc_double(qcParams,"RONRMS", qc_ron_err,
349 "[ADU] Error of Read Out Noise");
350 /* --RONn */
351 for (int i=0 ; i<frameCnt-1 ; i++) {
352 tmpImg = cpl_image_subtract_create(
354 hdrl_imagelist_get(darkImageList,i)),
356 hdrl_imagelist_get(darkImageList,i+1)) );
357
358 cpl_flux_get_noise_window(tmpImg, zone_def, hsize, nsamp,
359 &qc_ron_val, NULL);
360 qc_ron_val *= sqrt(1./2.);
361
362 paramName = cpl_sprintf("RON%d",i+1);
363 eris_ifu_append_qc_double(qcParams,paramName, qc_ron_val,
364 "[ADU] Read Out Noise");
365
366 eris_ifu_free_image(&tmpImg);
367 eris_ifu_free_string(&paramName);
368 }
369 eris_ifu_append_qc_int(qcParams,"NRONS", (int) frameCnt-1,
370 "Number of RON frames");
371
372 }
373 CATCH
374 {
375 retVal = cpl_error_get_code();
376 }
377 eris_check_error_code("eris_ifu_dark_qc");
378 return retVal;
379}
380
381cpl_image* eris_ifu_dark_get_dqi(
382 const cpl_mask* masterBpmMask,
383 const cpl_mask* bpm2dMask,
384 const cpl_mask* bpm3dMask ) {
385
386 cpl_image *dqi = NULL;
387 cpl_image *tmpImg = NULL;
388
389 TRY {
390 dqi = cpl_image_new_from_mask(masterBpmMask);
391 cpl_image_multiply_scalar(dqi, ERIS_DQI_SAT);
392 for (cpl_size ix=1; ix <= ERIS_IFU_DETECTOR_SIZE; ix++) {
393 for (cpl_size iy=1; iy <= 4; iy ++) {
394 cpl_image_set(dqi,ix, iy, ERIS_DQI_BP);
395 }
396 for (cpl_size iy=ERIS_IFU_DETECTOR_SIZE-3;
397 iy <= ERIS_IFU_DETECTOR_SIZE; iy ++) {
398 cpl_image_set(dqi,ix, iy, ERIS_DQI_BP);
399 }
400 }
401 for (cpl_size iy=1; iy <= ERIS_IFU_DETECTOR_SIZE; iy++) {
402 for (cpl_size ix=1; ix <= 4; ix ++) {
403 cpl_image_set(dqi,ix, iy, ERIS_DQI_BP);
404 }
405 for (cpl_size ix=ERIS_IFU_DETECTOR_SIZE-3;
406 ix <= ERIS_IFU_DETECTOR_SIZE; ix ++) {
407 cpl_image_set(dqi,ix, iy, ERIS_DQI_BP);
408 }
409 }
410
411 tmpImg = cpl_image_new_from_mask(bpm2dMask);
412 cpl_image_multiply_scalar(tmpImg, ERIS_DQI_BP_BPM2D);
413 cpl_image_add(dqi, tmpImg);
414 eris_ifu_free_image(&tmpImg);
415
416 tmpImg = cpl_image_new_from_mask(bpm3dMask);
417 cpl_image_multiply_scalar(tmpImg, ERIS_DQI_BP_BPM3D);
418 cpl_image_add(dqi, tmpImg);
419 eris_ifu_free_image(&tmpImg);
420
421 }
422 CATCH
423 {
424 }
425 eris_check_error_code("eris_ifu_dark_get_dqi");
426 return dqi;
427}
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 and apply 2D and/or 3D Badpixel-Mask based on parameter.
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' the mask to the image
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.