36 #include "naco_recipe.h"
42 #define RECIPE_STRING "naco_img_dark"
48 static cpl_error_code naco_img_dark_reduce(cpl_propertylist *,
49 const irplib_framelist *,
50 cpl_image **, cpl_mask **,
51 cpl_mask **, cpl_mask **);
53 static cpl_error_code naco_img_dark_qc(cpl_propertylist *,
55 const irplib_framelist *);
57 static cpl_error_code naco_img_dark_save(cpl_frameset *,
58 const cpl_parameterlist *,
59 const cpl_propertylist *,
60 const cpl_propertylist *,
61 const cpl_image *,
const cpl_mask *,
62 const cpl_mask *,
const cpl_mask *,
63 int,
const irplib_framelist *);
65 static char * naco_img_dark_make_tag(
const cpl_frame*,
66 const cpl_propertylist *,
int);
68 NACO_RECIPE_DEFINE(naco_img_dark,
76 "naco_img_dark -- NACO imaging dark recipe.\n"
77 "The files listed in the Set Of Frames (sof-file) "
79 "NACO-raw-file.fits " NACO_IMG_DARK_RAW
"\n");
96 } naco_img_dark_config;
117 static int naco_img_dark(cpl_frameset * framelist,
118 const cpl_parameterlist * parlist)
120 irplib_framelist* allframes = NULL;
121 irplib_framelist* rawframes = NULL;
122 const char ** taglist = NULL;
123 const char * rej_bord;
124 irplib_framelist* f_one = NULL;
125 cpl_imagelist * i_one = NULL;
126 cpl_image * avg = NULL;
127 cpl_mask * hot = NULL;
128 cpl_mask * cold = NULL;
129 cpl_mask * dev = NULL;
130 cpl_propertylist * qclist = cpl_propertylist_new();
131 cpl_propertylist * paflist = cpl_propertylist_new();
140 skip_if_ne(sscanf(rej_bord,
"%d %d %d %d",
141 &naco_img_dark_config.rej_left,
142 &naco_img_dark_config.rej_right,
143 &naco_img_dark_config.rej_bottom,
144 &naco_img_dark_config.rej_top), 4,
145 "number(s) in string parameter (%s): \"%s\"",
146 CPL_XSTRINGIFY(NACO_PARAM_REJBORD), rej_bord);
148 naco_img_dark_config.hot_thresh =
150 naco_img_dark_config.dev_thresh =
152 naco_img_dark_config.cold_thresh =
154 naco_img_dark_config.hsize =
156 naco_img_dark_config.nsamples =
164 allframes = irplib_framelist_cast(framelist);
165 skip_if(allframes == NULL);
167 rawframes = irplib_framelist_extract(allframes, NACO_IMG_DARK_RAW);
168 skip_if(rawframes == NULL);
169 irplib_framelist_empty(allframes);
171 skip_if(irplib_framelist_load_propertylist_all(rawframes, 0,
"^("
172 IRPLIB_PFITS_REGEXP_RECAL
"|"
173 NACO_PFITS_REGEXP_DARK
"|"
174 NACO_PFITS_REGEXP_DARK_PAF
178 skip_if(taglist == NULL);
180 cpl_msg_info(cpl_func,
"Identified %d setting(s) in %d frames",
181 nsets, irplib_framelist_get_size(rawframes));
184 for (i=0 ; i < nsets ; i++) {
187 f_one = irplib_framelist_extract(rawframes, taglist[i]);
190 skip_if(irplib_framelist_set_tag_all(f_one, NACO_IMG_DARK_RAW));
192 cpl_msg_info(cpl_func,
"Reducing frame set %d of %d (size=%d) with "
193 "setting: %s", i+1, nsets,
194 irplib_framelist_get_size(f_one), taglist[i]);
196 skip_if (f_one == NULL);
199 if (irplib_framelist_get_size(f_one) < 2) {
200 cpl_msg_warning(cpl_func,
"Setting %d skipped (Need at least 2 "
202 irplib_framelist_delete(f_one);
207 skip_if(naco_img_dark_reduce(qclist, f_one, &avg, &hot, &cold, &dev));
209 skip_if(naco_img_dark_qc(qclist, paflist, f_one));
212 skip_if (naco_img_dark_save(framelist, parlist, qclist, paflist,
213 avg, hot, cold, dev, i+1, f_one));
217 cpl_image_delete(avg);
218 cpl_mask_delete(hot);
219 cpl_mask_delete(cold);
220 cpl_mask_delete(dev);
221 irplib_framelist_delete(f_one);
222 cpl_propertylist_empty(qclist);
223 cpl_propertylist_empty(paflist);
231 skip_if (nb_good == 0);
235 cpl_imagelist_delete(i_one);
237 cpl_image_delete(avg);
238 cpl_mask_delete(hot);
239 cpl_mask_delete(cold);
240 cpl_mask_delete(dev);
241 irplib_framelist_delete(f_one);
242 irplib_framelist_delete(allframes);
243 irplib_framelist_delete(rawframes);
244 cpl_propertylist_delete(qclist);
245 cpl_propertylist_delete(paflist);
247 return cpl_error_get_code();
264 static cpl_error_code naco_img_dark_reduce(cpl_propertylist * qclist,
265 const irplib_framelist * f_one,
266 cpl_image ** pavg, cpl_mask ** phot,
267 cpl_mask ** pcold, cpl_mask ** pdev)
270 cpl_image * dark = NULL;
271 cpl_image * diff = NULL;
272 char * ron_key = NULL;
284 skip_if (f_one == NULL);
286 nfiles = irplib_framelist_get_size(f_one);
288 skip_if (nfiles < 2);
290 skip_if (irplib_framelist_contains(f_one,
"NAXIS1",
291 CPL_TYPE_INT, CPL_TRUE, 0.0));
293 skip_if (irplib_framelist_contains(f_one,
"NAXIS2",
294 CPL_TYPE_INT, CPL_TRUE, 0.0));
296 for (i=0 ; i < nfiles ; i++) {
297 const cpl_frame * frame = irplib_framelist_get_const(f_one, i);
298 const char * name = cpl_frame_get_filename(frame);
300 cpl_image_delete(diff);
302 irplib_check(dark = cpl_image_load(name, CPL_TYPE_FLOAT, 0, 0),
303 "Could not load FITS-image from %s", name);
306 const int nx = cpl_image_get_size_x(dark);
307 const int ny = cpl_image_get_size_y(dark);
309 zone[0] = naco_img_dark_config.rej_left+1;
310 zone[1] = nx - naco_img_dark_config.rej_right;
311 zone[2] = naco_img_dark_config.rej_bottom+1;
312 zone[3] = ny - naco_img_dark_config.rej_top;
314 *pavg = cpl_image_duplicate(dark);
315 skip_if(*pavg == NULL);
317 const cpl_propertylist * plist
318 = irplib_framelist_get_propertylist_const(f_one, i-1);
320 const char ron_format[] =
"ESO QC RON%d";
325 irplib_ensure(ndit > 0, CPL_ERROR_ILLEGAL_INPUT,
326 NACO_PFITS_INT_NDIT
" must be positive, not %d",
329 skip_if(cpl_image_subtract(diff, dark));
332 irplib_check(cpl_flux_get_noise_window(diff, zone,
333 naco_img_dark_config.hsize,
334 naco_img_dark_config.nsamples,
336 "Cannot compute the RON for difference between images "
337 "%d and %d", i, i+1);
340 ron = rms * sqrt(ndit/2.0);
344 ron_key = cpl_sprintf(ron_format, i);
346 bug_if(ron_key == NULL);
348 skip_if(cpl_propertylist_append_double(qclist, ron_key, ron));
351 skip_if(cpl_image_add(*pavg, dark));
356 cpl_image_delete(dark);
359 mean = cpl_image_get_mean(diff);
363 lower = mean - rms * naco_img_dark_config.dev_thresh;
364 upper = mean + rms * naco_img_dark_config.dev_thresh;
365 cpl_mask_delete(*pdev);
366 irplib_check(*pdev = cpl_mask_threshold_image_create(diff, lower, upper),
367 "Cannot compute the deviant pixel map");
368 cpl_image_delete(diff);
371 skip_if (cpl_mask_not(*pdev));
372 ndevpix = cpl_mask_count(*pdev);
376 skip_if(cpl_image_divide_scalar(*pavg, (
double)nfiles));
379 dark_med = cpl_image_get_median_window(*pavg, zone[0], zone[2], zone[1],
382 irplib_check (cpl_flux_get_noise_window(*pavg, zone,
383 naco_img_dark_config.hsize,
384 naco_img_dark_config.nsamples,
386 "Cannot compute the RON of the master dark");
388 lower = dark_med - rms * naco_img_dark_config.cold_thresh;
389 upper = dark_med + rms * naco_img_dark_config.hot_thresh;
392 cpl_mask_delete(*pcold);
393 irplib_check(*pcold = cpl_mask_threshold_image_create(*pavg, -FLT_MAX,
395 "Cannot compute the cold pixel map");
396 coldpix_nb = cpl_mask_count(*pcold);
400 cpl_mask_delete(*phot);
401 irplib_check(*phot = cpl_mask_threshold_image_create(*pavg, upper, DBL_MAX),
402 "Cannot compute the hot pixel map");
403 hotpix_nb = cpl_mask_count(*phot);
408 skip_if(cpl_propertylist_append_double(qclist,
"ESO QC DARKMED", dark_med));
409 skip_if(cpl_propertylist_append_int(qclist,
"ESO QC NBCOLPIX", coldpix_nb));
410 skip_if(cpl_propertylist_append_int(qclist,
"ESO QC NBHOTPIX", hotpix_nb));
411 skip_if(cpl_propertylist_append_int(qclist,
"ESO QC NBDEVPIX", ndevpix));
415 cpl_image_delete(dark);
416 cpl_image_delete(diff);
419 return cpl_error_get_code();
432 static cpl_error_code naco_img_dark_qc(cpl_propertylist * qclist,
433 cpl_propertylist * paflist,
434 const irplib_framelist * rawframes)
437 const cpl_propertylist * reflist
438 = irplib_framelist_get_propertylist_const(rawframes, 0);
439 const char pafcopy[] =
"^(" NACO_PFITS_REGEXP_DARK_PAF
")$";
444 bug_if (cpl_propertylist_copy_property_regexp(paflist, reflist, pafcopy,
446 bug_if (cpl_propertylist_append(paflist, qclist));
448 bug_if (cpl_propertylist_copy_property_regexp(qclist, reflist,
"^("
449 IRPLIB_PFITS_REGEXP_RECAL
454 return cpl_error_get_code();
473 static cpl_error_code naco_img_dark_save(cpl_frameset * set_tot,
474 const cpl_parameterlist * parlist,
475 const cpl_propertylist * qclist,
476 const cpl_propertylist * paflist,
477 const cpl_image * avg,
478 const cpl_mask * hot,
479 const cpl_mask * cold,
480 const cpl_mask * dev,
482 const irplib_framelist * f_one)
484 cpl_frameset * set_one = irplib_frameset_cast(f_one);
485 cpl_image * image = NULL;
486 char * filename = NULL;
492 filename = cpl_sprintf(RECIPE_STRING
"_set%02d_avg" CPL_DFS_FITS,
494 skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, avg,
495 CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
496 NACO_IMG_DARK_AVG, qclist, NULL, naco_pipe_id,
500 image = cpl_image_new_from_mask(hot);
504 filename = cpl_sprintf(RECIPE_STRING
"_set%02d_hotpix" CPL_DFS_FITS,
506 skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, image,
507 CPL_BPP_8_UNSIGNED, RECIPE_STRING, NACO_IMG_DARK_HOT,
508 qclist, NULL, naco_pipe_id, filename));
511 cpl_image_delete(image);
512 image = cpl_image_new_from_mask(cold);
516 filename = cpl_sprintf(RECIPE_STRING
"_set%02d_coldpix" CPL_DFS_FITS,
518 skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, image,
519 CPL_BPP_8_UNSIGNED, RECIPE_STRING,
520 NACO_IMG_DARK_COLD, qclist, NULL, naco_pipe_id,
524 cpl_image_delete(image);
525 image = cpl_image_new_from_mask(dev);
529 filename = cpl_sprintf(RECIPE_STRING
"_set%02d_devpix" CPL_DFS_FITS,
531 skip_if (irplib_dfs_save_image(set_tot, parlist, set_one, image,
532 CPL_BPP_8_UNSIGNED, RECIPE_STRING, NACO_IMG_DARK_DEV,
533 qclist, NULL, naco_pipe_id, filename));
534 cpl_image_delete(image);
541 bug_if(cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
545 filename = cpl_sprintf(RECIPE_STRING
"_set%02d" CPL_DFS_PAF, set_nb);
546 skip_if (cpl_dfs_save_paf(
"NACO", RECIPE_STRING, paflist, filename));
548 bug_if(paflist == NULL);
553 cpl_image_delete(image);
554 cpl_frameset_delete(set_one);
557 return cpl_error_get_code();
572 static char * naco_img_dark_make_tag(
const cpl_frame*
self,
573 const cpl_propertylist * plist,
int dummy)
583 skip_if (cpl_error_get_code());
585 skip_if(
self == NULL);
586 skip_if(plist == NULL);
591 skip_if(cpl_error_get_code());
595 skip_if(cpl_error_get_code());
600 skip_if(cpl_error_get_code());
604 skip_if(cpl_error_get_code());
606 tag = cpl_sprintf(
"%s:%s:%d:%.5f", name, mode, irom,
612 if (cpl_error_get_code()) {