36 #include "visir_recipe.h"
42 #define RECIPE_STRING "visir_img_dark"
49 static cpl_error_code visir_img_dark_reduce(cpl_propertylist *,
50 const irplib_framelist *,
51 cpl_image **, cpl_mask **,
52 cpl_mask **, cpl_mask **);
54 static cpl_error_code visir_img_dark_save(cpl_frameset *,
55 const cpl_parameterlist *,
56 const cpl_propertylist *,
57 const cpl_image *,
const cpl_mask *,
58 const cpl_mask *,
const cpl_mask *,
59 int,
const irplib_framelist *);
61 static char * visir_img_dark_make_tag(
const cpl_frame*,
62 const cpl_propertylist *,
int);
64 VISIR_RECIPE_DEFINE(visir_img_dark,
67 VISIR_PARAM_COLD_LIM |
69 VISIR_PARAM_NSAMPLES |
72 "This recipe computes the dark.\n"
73 "The files listed in the Set Of Frames (sof-file) must be "
75 "VISIR-dark-image-raw-file.fits " VISIR_IMG_DARK_RAW
" or\n"
76 "VISIR-dark-spectro-raw-file.fits " VISIR_SPC_DARK_RAW
"\n"
78 "The corresponding four products will each have a FITS "
79 "card\n'HIERARCH ESO PRO CATG' with values (for imaging)\n"
80 VISIR_IMG_DARK_AVG_PROCATG
"\n"
81 VISIR_IMG_DARK_HOT_PROCATG
"\n"
82 VISIR_IMG_DARK_COLD_PROCATG
"\n"
83 VISIR_IMG_DARK_DEV_PROCATG
"\n"
84 " or (for spectroscopy)\n"
85 VISIR_SPC_DARK_AVG_PROCATG
"\n"
86 VISIR_SPC_DARK_HOT_PROCATG
"\n"
87 VISIR_SPC_DARK_COLD_PROCATG
"\n"
88 VISIR_SPC_DARK_DEV_PROCATG
"\n");
94 enum _visir_dark_mode_ {
100 typedef enum _visir_dark_mode_ visir_dark_mode;
104 visir_dark_mode mode;
114 } visir_img_dark_config;
135 static int visir_img_dark(cpl_frameset * framelist,
136 const cpl_parameterlist * parlist)
138 irplib_framelist* allframes = NULL;
139 irplib_framelist* rawframes = NULL;
140 const char ** taglist = NULL;
141 const char * rej_bord;
142 const char * orgtag = NULL;
143 irplib_framelist* f_one = NULL;
144 cpl_imagelist * i_one = NULL;
145 cpl_image * avg = NULL;
146 cpl_mask * hot = NULL;
147 cpl_mask * cold = NULL;
148 cpl_mask * dev = NULL;
149 cpl_propertylist * qclist = cpl_propertylist_new();
157 VISIR_PARAM_REJBORD);
159 skip_if (sscanf(rej_bord,
"%d %d %d %d",
160 &visir_img_dark_config.rej_left,
161 &visir_img_dark_config.rej_right,
162 &visir_img_dark_config.rej_bottom,
163 &visir_img_dark_config.rej_top) != 4);
165 visir_img_dark_config.hot_thresh =
167 VISIR_PARAM_HOT_LIM);
168 visir_img_dark_config.dev_thresh =
170 VISIR_PARAM_DEV_LIM);
171 visir_img_dark_config.cold_thresh =
173 VISIR_PARAM_COLD_LIM);
174 visir_img_dark_config.hsize =
176 visir_img_dark_config.nsamples =
185 skip_if(allframes == NULL);
188 "^(" VISIR_IMG_DARK_RAW
189 "|" VISIR_SPC_DARK_RAW
")$",
191 skip_if(rawframes == NULL);
194 visir_img_dark_config.mode = visir_dark_none;
195 if (cpl_frameset_find(framelist, VISIR_IMG_DARK_RAW)) {
196 visir_img_dark_config.mode = visir_dark_img;
197 orgtag = VISIR_IMG_DARK_RAW;
199 if (cpl_frameset_find(framelist, VISIR_SPC_DARK_RAW)) {
200 skip_if (visir_img_dark_config.mode);
201 visir_img_dark_config.mode = visir_dark_spc;
202 orgtag = VISIR_SPC_DARK_RAW;
205 bug_if(visir_img_dark_config.mode == visir_dark_none);
208 VISIR_PFITS_REGEXP_DARK
"|"
209 VISIR_PFITS_REGEXP_DARK_PAF
214 taglist = visir_framelist_set_tag(rawframes, visir_img_dark_make_tag, &nsets);
215 skip_if(taglist == NULL);
217 cpl_msg_info(cpl_func,
"Identified %d setting(s) in %d frames",
221 for (i=0 ; i < nsets ; i++) {
229 cpl_msg_info(cpl_func,
"Reducing frame set %d of %d (size=%d) with "
230 "setting: %s", i+1, nsets,
233 skip_if (f_one == NULL);
237 cpl_msg_warning(cpl_func,
"Setting %d skipped (Need at least 2 "
244 skip_if(visir_img_dark_reduce(qclist, f_one, &avg, &hot, &cold, &dev));
247 skip_if (visir_img_dark_save(framelist, parlist, qclist, avg, hot,
248 cold, dev, i+1, f_one));
252 cpl_image_delete(avg);
253 cpl_mask_delete(hot);
254 cpl_mask_delete(cold);
255 cpl_mask_delete(dev);
257 cpl_propertylist_empty(qclist);
265 skip_if (nb_good == 0);
269 cpl_imagelist_delete(i_one);
271 cpl_image_delete(avg);
272 cpl_mask_delete(hot);
273 cpl_mask_delete(cold);
274 cpl_mask_delete(dev);
278 cpl_propertylist_delete(qclist);
280 return cpl_error_get_code();
297 static cpl_error_code visir_img_dark_reduce(cpl_propertylist * qclist,
298 const irplib_framelist * f_one,
299 cpl_image ** pavg, cpl_mask ** phot,
300 cpl_mask ** pcold, cpl_mask ** pdev)
303 cpl_image * dark = NULL;
304 cpl_image * diff = NULL;
305 char * ron_key = NULL;
317 skip_if (f_one == NULL);
321 skip_if (nfiles < 2);
323 for (i=0 ; i < nfiles ; i++) {
325 const char * name = cpl_frame_get_filename(frame);
326 cpl_size next = cpl_frame_get_nextensions(frame);
328 cpl_image_delete(diff);
330 irplib_check(dark = cpl_image_load(name, CPL_TYPE_FLOAT, 0, next),
331 "Could not load FITS-image from %s", name);
334 const int nx = cpl_image_get_size_x(dark);
335 const int ny = cpl_image_get_size_y(dark);
337 zone[0] = visir_img_dark_config.rej_left+1;
338 zone[1] = nx - visir_img_dark_config.rej_right;
339 zone[2] = visir_img_dark_config.rej_bottom+1;
340 zone[3] = ny - visir_img_dark_config.rej_top;
342 *pavg = cpl_image_duplicate(dark);
343 skip_if(*pavg == NULL);
345 const cpl_propertylist * plist
348 const char ron_format[] =
"ESO QC RON%d";
353 irplib_ensure(ndit > 0, CPL_ERROR_ILLEGAL_INPUT,
354 VISIR_PFITS_INT_NDIT
" must be positive, not %d",
357 skip_if(cpl_image_subtract(diff, dark));
360 irplib_check(cpl_flux_get_noise_window(diff, zone,
361 visir_img_dark_config.hsize,
362 visir_img_dark_config.nsamples,
364 "Cannot compute the RON for difference between images "
365 "%d and %d", i, i+1);
368 ron = rms * sqrt(ndit/2.0);
372 ron_key = cpl_sprintf(ron_format, i);
374 bug_if(ron_key == NULL);
376 skip_if(cpl_propertylist_append_double(qclist, ron_key, ron));
379 skip_if(cpl_image_add(*pavg, dark));
384 cpl_image_delete(dark);
387 mean = cpl_image_get_mean(diff);
391 lower = mean - rms * visir_img_dark_config.dev_thresh;
392 upper = mean + rms * visir_img_dark_config.dev_thresh;
393 cpl_mask_delete(*pdev);
394 irplib_check(*pdev = cpl_mask_threshold_image_create(diff, lower, upper),
395 "Cannot compute the deviant pixel map");
396 cpl_image_delete(diff);
399 skip_if (cpl_mask_not(*pdev));
400 ndevpix = cpl_mask_count(*pdev);
404 skip_if(cpl_image_divide_scalar(*pavg, (
double)nfiles));
407 dark_med = cpl_image_get_median_window(*pavg, zone[0], zone[2], zone[1],
410 irplib_check (cpl_flux_get_noise_window(*pavg, zone,
411 visir_img_dark_config.hsize,
412 visir_img_dark_config.nsamples,
414 "Cannot compute the RON of the master dark");
416 lower = dark_med - rms * visir_img_dark_config.cold_thresh;
417 upper = dark_med + rms * visir_img_dark_config.hot_thresh;
420 cpl_mask_delete(*pcold);
421 irplib_check(*pcold = cpl_mask_threshold_image_create(*pavg, -FLT_MAX,
423 "Cannot compute the cold pixel map");
424 coldpix_nb = cpl_mask_count(*pcold);
428 cpl_mask_delete(*phot);
429 irplib_check(*phot = cpl_mask_threshold_image_create(*pavg, upper, DBL_MAX),
430 "Cannot compute the hot pixel map");
431 hotpix_nb = cpl_mask_count(*phot);
436 skip_if(cpl_propertylist_append_double(qclist,
"ESO QC DARKMED", dark_med));
437 skip_if(cpl_propertylist_append_int(qclist,
"ESO QC NBCOLPIX", coldpix_nb));
438 skip_if(cpl_propertylist_append_int(qclist,
"ESO QC NBHOTPIX", hotpix_nb));
439 skip_if(cpl_propertylist_append_int(qclist,
"ESO QC NBDEVPIX", ndevpix));
443 cpl_image_delete(dark);
444 cpl_image_delete(diff);
447 return cpl_error_get_code();
465 static cpl_error_code visir_img_dark_save(cpl_frameset * set_tot,
466 const cpl_parameterlist * parlist,
467 const cpl_propertylist * qclist,
468 const cpl_image * avg,
469 const cpl_mask * hot,
470 const cpl_mask * cold,
471 const cpl_mask * dev,
473 const irplib_framelist * f_one)
476 const cpl_propertylist * plist
478 cpl_propertylist * paflist = cpl_propertylist_new();
479 cpl_image * image = NULL;
480 const char pafcopy[] =
"^(" VISIR_PFITS_REGEXP_DARK_PAF
")$";
481 char * filename = NULL;
482 const char * procatg_avg;
483 const char * procatg_dev;
484 const char * procatg_hot;
485 const char * procatg_cold;
492 switch (visir_img_dark_config.mode) {
494 procatg_avg = VISIR_IMG_DARK_AVG_PROCATG;
495 procatg_dev = VISIR_IMG_DARK_DEV_PROCATG;
496 procatg_hot = VISIR_IMG_DARK_HOT_PROCATG;
497 procatg_cold = VISIR_IMG_DARK_COLD_PROCATG;
500 procatg_avg = VISIR_SPC_DARK_AVG_PROCATG;
501 procatg_dev = VISIR_SPC_DARK_DEV_PROCATG;
502 procatg_hot = VISIR_SPC_DARK_HOT_PROCATG;
503 procatg_cold = VISIR_SPC_DARK_COLD_PROCATG;
511 filename = cpl_sprintf(RECIPE_STRING
"_set%02d_avg" CPL_DFS_FITS,
514 RECIPE_STRING, procatg_avg, qclist, NULL,
515 visir_pipe_id, filename));
518 image = cpl_image_new_from_mask(hot);
522 filename = cpl_sprintf(RECIPE_STRING
"_set%02d_hotpix" CPL_DFS_FITS,
525 RECIPE_STRING, procatg_hot, qclist, NULL,
526 visir_pipe_id, filename));
527 cpl_image_delete(image);
531 image = cpl_image_new_from_mask(cold);
535 filename = cpl_sprintf(RECIPE_STRING
"_set%02d_coldpix" CPL_DFS_FITS,
538 RECIPE_STRING, procatg_cold, qclist, NULL,
539 visir_pipe_id, filename));
540 cpl_image_delete(image);
544 image = cpl_image_new_from_mask(dev);
548 filename = cpl_sprintf(RECIPE_STRING
"_set%02d_devpix" CPL_DFS_FITS,
551 CPL_BPP_32_SIGNED, RECIPE_STRING,
552 procatg_dev, qclist, NULL, visir_pipe_id,
554 cpl_image_delete(image);
557 #ifdef VISIR_SAVE_PAF
560 skip_if (cpl_propertylist_copy_property_regexp(paflist, plist, pafcopy, 0));
561 skip_if (cpl_propertylist_append(paflist, qclist));
564 bug_if (cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
568 filename = cpl_sprintf(RECIPE_STRING
"_set%02d" CPL_DFS_PAF, set_nb);
569 skip_if (cpl_dfs_save_paf(
"VISIR", RECIPE_STRING, paflist, filename));
571 bug_if(paflist == NULL);
572 bug_if(plist == NULL);
573 bug_if(pafcopy == NULL);
578 cpl_image_delete(image);
579 cpl_frameset_delete(set);
580 cpl_propertylist_delete(paflist);
583 return cpl_error_get_code();
598 static char * visir_img_dark_make_tag(
const cpl_frame*
self,
599 const cpl_propertylist * plist,
int dummy)
608 skip_if(
self == NULL);
609 skip_if(plist == NULL);
616 tag = cpl_sprintf(
"%.5f", etime);
621 if (cpl_error_get_code()) {
double visir_parameterlist_get_double(const cpl_parameterlist *self, const char *recipe, visir_parameter bitmask)
Retrieve the value of a VISIR parameter of type double.
cpl_frameset * irplib_frameset_cast(const irplib_framelist *self)
Create a CPL frameset from an irplib_framelist.
cpl_error_code visir_dfs_check_framelist_tag(const irplib_framelist *self)
Check the tags in a frameset (group raw only)
cpl_error_code irplib_framelist_set_tag_all(irplib_framelist *self, const char *tag)
Set the tag of all frames in the list.
int visir_parameterlist_get_int(const cpl_parameterlist *self, const char *recipe, visir_parameter bitmask)
Retrieve the value of a VISIR integer parameter.
irplib_framelist * irplib_framelist_extract_regexp(const irplib_framelist *self, const char *regexp, cpl_boolean invert)
Extract the frames with the given tag from a framelist.
const cpl_propertylist * irplib_framelist_get_propertylist_const(const irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the framelist.
double visir_pfits_get_exptime(const cpl_propertylist *self)
The exposure time.
cpl_error_code irplib_dfs_save_image(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_image *image, cpl_type_bpp bpp, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save an image as a DFS-compliant pipeline product.
cpl_error_code irplib_framelist_load_propertylist_all(irplib_framelist *self, int ind, const char *regexp, cpl_boolean invert)
Load the propertylists of all frames in the framelist.
const char * visir_parameterlist_get_string(const cpl_parameterlist *self, const char *recipe, visir_parameter bitmask)
Retrieve the value of a VISIR string parameter.
int visir_pfits_get_ndit(const cpl_propertylist *self)
The NDIT keyword.
irplib_framelist * irplib_framelist_extract(const irplib_framelist *self, const char *tag)
Extract the frames with the given tag from a framelist.
int visir_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
const cpl_frame * irplib_framelist_get_const(const irplib_framelist *self, int pos)
Get the specified frame from the framelist.
void irplib_framelist_delete(irplib_framelist *self)
Deallocate an irplib_framelist with its frames and properties.
irplib_framelist * irplib_framelist_cast(const cpl_frameset *frameset)
Create an irplib_framelist from a cpl_framelist.
int irplib_framelist_get_size(const irplib_framelist *self)
Get the size of a framelist.