00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include "visir_recipe.h"
00037
00038
00039
00040
00041
00042 #define RECIPE_STRING "visir_img_dark"
00043
00044
00045
00046
00047
00048
00049 static cpl_error_code visir_img_dark_reduce(cpl_propertylist *,
00050 const irplib_framelist *,
00051 cpl_image **, cpl_mask **,
00052 cpl_mask **, cpl_mask **);
00053
00054 static cpl_error_code visir_img_dark_save(cpl_frameset *,
00055 const cpl_parameterlist *,
00056 const cpl_propertylist *,
00057 const cpl_image *, const cpl_mask *,
00058 const cpl_mask *, const cpl_mask *,
00059 int, const irplib_framelist *);
00060
00061 static char * visir_img_dark_make_tag(const cpl_frame*,
00062 const cpl_propertylist *, int);
00063
00064 VISIR_RECIPE_DEFINE(visir_img_dark,
00065 VISIR_PARAM_REJBORD |
00066 VISIR_PARAM_HOT_LIM |
00067 VISIR_PARAM_COLD_LIM |
00068 VISIR_PARAM_DEV_LIM |
00069 VISIR_PARAM_NSAMPLES |
00070 VISIR_PARAM_HALFSIZE,
00071 "Dark recipe",
00072 "This recipe computes the dark.\n"
00073 "The files listed in the Set Of Frames (sof-file) must be "
00074 "tagged either\n"
00075 "VISIR-dark-image-raw-file.fits " VISIR_IMG_DARK_RAW " or\n"
00076 "VISIR-dark-spectro-raw-file.fits " VISIR_SPC_DARK_RAW "\n"
00077 "\n"
00078 "The corresponding four products will each have a FITS "
00079 "card\n'HIERARCH ESO PRO CATG' with values (for imaging)\n"
00080 VISIR_IMG_DARK_AVG_PROCATG "\n"
00081 VISIR_IMG_DARK_HOT_PROCATG "\n"
00082 VISIR_IMG_DARK_COLD_PROCATG "\n"
00083 VISIR_IMG_DARK_DEV_PROCATG "\n"
00084 " or (for spectroscopy)\n"
00085 VISIR_SPC_DARK_AVG_PROCATG "\n"
00086 VISIR_SPC_DARK_HOT_PROCATG "\n"
00087 VISIR_SPC_DARK_COLD_PROCATG "\n"
00088 VISIR_SPC_DARK_DEV_PROCATG "\n");
00089
00090
00091
00092
00093
00094 enum _visir_dark_mode_ {
00095 visir_dark_none = 0,
00096 visir_dark_img,
00097 visir_dark_spc
00098 };
00099
00100 typedef enum _visir_dark_mode_ visir_dark_mode;
00101
00102 static struct {
00103
00104 visir_dark_mode mode;
00105 int rej_left;
00106 int rej_right;
00107 int rej_bottom;
00108 int rej_top;
00109 double hot_thresh;
00110 double cold_thresh;
00111 double dev_thresh;
00112 int hsize;
00113 int nsamples;
00114 } visir_img_dark_config;
00115
00116
00120
00121
00122
00123
00124
00125
00126
00127
00134
00135 static int visir_img_dark(cpl_frameset * framelist,
00136 const cpl_parameterlist * parlist)
00137 {
00138 irplib_framelist* allframes = NULL;
00139 irplib_framelist* rawframes = NULL;
00140 const char ** taglist = NULL;
00141 const char * rej_bord;
00142 const char * orgtag = NULL;
00143 irplib_framelist* f_one = NULL;
00144 cpl_imagelist * i_one = NULL;
00145 cpl_image * avg = NULL;
00146 cpl_mask * hot = NULL;
00147 cpl_mask * cold = NULL;
00148 cpl_mask * dev = NULL;
00149 cpl_propertylist * qclist = cpl_propertylist_new();
00150 int nsets;
00151 int i;
00152 int nb_good = 0;
00153
00154
00155
00156 rej_bord = visir_parameterlist_get_string(parlist, RECIPE_STRING,
00157 VISIR_PARAM_REJBORD);
00158 skip_if (0);
00159 skip_if (sscanf(rej_bord, "%d %d %d %d",
00160 &visir_img_dark_config.rej_left,
00161 &visir_img_dark_config.rej_right,
00162 &visir_img_dark_config.rej_bottom,
00163 &visir_img_dark_config.rej_top) != 4);
00164
00165 visir_img_dark_config.hot_thresh =
00166 visir_parameterlist_get_double(parlist, RECIPE_STRING,
00167 VISIR_PARAM_HOT_LIM);
00168 visir_img_dark_config.dev_thresh =
00169 visir_parameterlist_get_double(parlist, RECIPE_STRING,
00170 VISIR_PARAM_DEV_LIM);
00171 visir_img_dark_config.cold_thresh =
00172 visir_parameterlist_get_double(parlist, RECIPE_STRING,
00173 VISIR_PARAM_COLD_LIM);
00174 visir_img_dark_config.hsize =
00175 visir_parameterlist_get_int(parlist, RECIPE_STRING, VISIR_PARAM_HALFSIZE);
00176 visir_img_dark_config.nsamples =
00177 visir_parameterlist_get_int(parlist, RECIPE_STRING, VISIR_PARAM_NSAMPLES);
00178
00179 skip_if (0);
00180
00181
00182 skip_if (visir_dfs_set_groups(framelist));
00183
00184 allframes = irplib_framelist_cast(framelist);
00185 skip_if(allframes == NULL);
00186
00187 rawframes = irplib_framelist_extract_regexp(allframes,
00188 "^(" VISIR_IMG_DARK_RAW
00189 "|" VISIR_SPC_DARK_RAW ")$",
00190 CPL_FALSE);
00191 skip_if(rawframes == NULL);
00192
00193
00194 visir_img_dark_config.mode = visir_dark_none;
00195 if (cpl_frameset_find(framelist, VISIR_IMG_DARK_RAW)) {
00196 visir_img_dark_config.mode = visir_dark_img;
00197 orgtag = VISIR_IMG_DARK_RAW;
00198 }
00199 if (cpl_frameset_find(framelist, VISIR_SPC_DARK_RAW)) {
00200 skip_if (visir_img_dark_config.mode);
00201 visir_img_dark_config.mode = visir_dark_spc;
00202 orgtag = VISIR_SPC_DARK_RAW;
00203 }
00204
00205 bug_if(visir_img_dark_config.mode == visir_dark_none);
00206
00207 skip_if(irplib_framelist_load_propertylist_all(rawframes, 0, "^("
00208 VISIR_PFITS_REGEXP_DARK "|"
00209 VISIR_PFITS_REGEXP_DARK_PAF
00210 ")$", CPL_FALSE));
00211
00212 skip_if(visir_dfs_check_framelist_tag(rawframes));
00213
00214 taglist = visir_framelist_set_tag(rawframes, visir_img_dark_make_tag, &nsets);
00215 skip_if(taglist == NULL);
00216
00217 cpl_msg_info(cpl_func, "Identified %d setting(s) in %d frames",
00218 nsets, irplib_framelist_get_size(rawframes));
00219
00220
00221 for (i=0 ; i < nsets ; i++) {
00222
00223
00224 f_one = irplib_framelist_extract(rawframes, taglist[i]);
00225
00226
00227 skip_if(irplib_framelist_set_tag_all(f_one, orgtag));
00228
00229 cpl_msg_info(cpl_func, "Reducing frame set %d of %d (size=%d) with "
00230 "setting: %s", i+1, nsets,
00231 irplib_framelist_get_size(f_one), taglist[i]);
00232
00233 skip_if (f_one == NULL);
00234
00235
00236 if (irplib_framelist_get_size(f_one) < 2) {
00237 cpl_msg_warning(cpl_func, "Setting %d skipped (Need at least 2 "
00238 "frames)", i+1);
00239 irplib_framelist_delete(f_one);
00240 f_one = NULL;
00241 continue;
00242 }
00243
00244 skip_if(visir_img_dark_reduce(qclist, f_one, &avg, &hot, &cold, &dev));
00245
00246
00247 skip_if (visir_img_dark_save(framelist, parlist, qclist, avg, hot,
00248 cold, dev, i+1, f_one));
00249
00250 nb_good++;
00251
00252 cpl_image_delete(avg);
00253 cpl_mask_delete(hot);
00254 cpl_mask_delete(cold);
00255 cpl_mask_delete(dev);
00256 irplib_framelist_delete(f_one);
00257 cpl_propertylist_empty(qclist);
00258 avg = NULL;
00259 cold = NULL;
00260 hot = NULL;
00261 dev = NULL;
00262 f_one = NULL;
00263 }
00264
00265 skip_if (nb_good == 0);
00266
00267 end_skip;
00268
00269 cpl_imagelist_delete(i_one);
00270 cpl_free(taglist);
00271 cpl_image_delete(avg);
00272 cpl_mask_delete(hot);
00273 cpl_mask_delete(cold);
00274 cpl_mask_delete(dev);
00275 irplib_framelist_delete(f_one);
00276 irplib_framelist_delete(allframes);
00277 irplib_framelist_delete(rawframes);
00278 cpl_propertylist_delete(qclist);
00279
00280 return cpl_error_get_code();
00281 }
00282
00283
00296
00297 static cpl_error_code visir_img_dark_reduce(cpl_propertylist * qclist,
00298 const irplib_framelist * f_one,
00299 cpl_image ** pavg, cpl_mask ** phot,
00300 cpl_mask ** pcold, cpl_mask ** pdev)
00301 {
00302
00303 cpl_image * dark = NULL;
00304 cpl_image * diff = NULL;
00305 char * ron_key = NULL;
00306 double rms;
00307 double lower, upper;
00308 double dark_med;
00309 double mean;
00310 int ndevpix;
00311 cpl_size zone[4];
00312 int coldpix_nb;
00313 int hotpix_nb;
00314 int nfiles;
00315 int i;
00316
00317 skip_if (f_one == NULL);
00318
00319 nfiles = irplib_framelist_get_size(f_one);
00320
00321 skip_if (nfiles < 2);
00322
00323 skip_if (irplib_framelist_contains(f_one, "NAXIS1",
00324 CPL_TYPE_INT, CPL_TRUE, 0.0));
00325
00326 skip_if (irplib_framelist_contains(f_one, "NAXIS2",
00327 CPL_TYPE_INT, CPL_TRUE, 0.0));
00328
00329 for (i=0 ; i < nfiles ; i++) {
00330 const cpl_frame * frame = irplib_framelist_get_const(f_one, i);
00331 const char * name = cpl_frame_get_filename(frame);
00332
00333 cpl_image_delete(diff);
00334 diff = dark;
00335 irplib_check(dark = cpl_image_load(name, CPL_TYPE_FLOAT, 0, 0),
00336 "Could not load FITS-image from %s", name);
00337
00338 if (i == 0) {
00339 const int nx = cpl_image_get_size_x(dark);
00340 const int ny = cpl_image_get_size_y(dark);
00341
00342 zone[0] = visir_img_dark_config.rej_left+1;
00343 zone[1] = nx - visir_img_dark_config.rej_right;
00344 zone[2] = visir_img_dark_config.rej_bottom+1;
00345 zone[3] = ny - visir_img_dark_config.rej_top;
00346
00347 *pavg = cpl_image_duplicate(dark);
00348 skip_if(*pavg == NULL);
00349 } else {
00350 const cpl_propertylist * plist
00351 = irplib_framelist_get_propertylist_const(f_one, i-1);
00352 const int ndit = visir_pfits_get_ndit(plist);
00353 const char ron_format[] = "ESO QC RON%d";
00354 double ron;
00355
00356 skip_if(0);
00357
00358 irplib_ensure(ndit > 0, CPL_ERROR_ILLEGAL_INPUT,
00359 VISIR_PFITS_INT_NDIT " must be positive, not %d",
00360 ndit);
00361
00362 skip_if(cpl_image_subtract(diff, dark));
00363
00364
00365 irplib_check(cpl_flux_get_noise_window(diff, zone,
00366 visir_img_dark_config.hsize,
00367 visir_img_dark_config.nsamples,
00368 &rms, NULL),
00369 "Cannot compute the RON for difference between images "
00370 "%d and %d", i, i+1);
00371
00372
00373 ron = rms * sqrt(ndit/2.0);
00374
00375
00376 cpl_free(ron_key);
00377 ron_key = cpl_sprintf(ron_format, i);
00378
00379 bug_if(ron_key == NULL);
00380
00381 skip_if(cpl_propertylist_append_double(qclist, ron_key, ron));
00382
00383
00384 skip_if(cpl_image_add(*pavg, dark));
00385
00386 }
00387
00388 }
00389 cpl_image_delete(dark);
00390 dark = NULL;
00391
00392 mean = cpl_image_get_mean(diff);
00393
00394
00395
00396 lower = mean - rms * visir_img_dark_config.dev_thresh;
00397 upper = mean + rms * visir_img_dark_config.dev_thresh;
00398 cpl_mask_delete(*pdev);
00399 irplib_check(*pdev = cpl_mask_threshold_image_create(diff, lower, upper),
00400 "Cannot compute the deviant pixel map");
00401 cpl_image_delete(diff);
00402 diff = NULL;
00403
00404 skip_if (cpl_mask_not(*pdev));
00405 ndevpix = cpl_mask_count(*pdev);
00406 skip_if (0);
00407
00408
00409 skip_if(cpl_image_divide_scalar(*pavg, (double)nfiles));
00410
00411
00412 dark_med = cpl_image_get_median_window(*pavg, zone[0], zone[2], zone[1],
00413 zone[3]);
00414
00415 irplib_check (cpl_flux_get_noise_window(*pavg, zone,
00416 visir_img_dark_config.hsize,
00417 visir_img_dark_config.nsamples,
00418 &rms, NULL),
00419 "Cannot compute the RON of the master dark");
00420
00421 lower = dark_med - rms * visir_img_dark_config.cold_thresh;
00422 upper = dark_med + rms * visir_img_dark_config.hot_thresh;
00423
00424
00425 cpl_mask_delete(*pcold);
00426 irplib_check(*pcold = cpl_mask_threshold_image_create(*pavg, -FLT_MAX,
00427 lower),
00428 "Cannot compute the cold pixel map");
00429 coldpix_nb = cpl_mask_count(*pcold);
00430 skip_if (0);
00431
00432
00433 cpl_mask_delete(*phot);
00434 irplib_check(*phot = cpl_mask_threshold_image_create(*pavg, upper, DBL_MAX),
00435 "Cannot compute the hot pixel map");
00436 hotpix_nb = cpl_mask_count(*phot);
00437 skip_if (0);
00438
00439
00440
00441 skip_if(cpl_propertylist_append_double(qclist, "ESO QC DARKMED", dark_med));
00442 skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBCOLPIX", coldpix_nb));
00443 skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBHOTPIX", hotpix_nb));
00444 skip_if(cpl_propertylist_append_int(qclist, "ESO QC NBDEVPIX", ndevpix));
00445
00446 end_skip;
00447
00448 cpl_image_delete(dark);
00449 cpl_image_delete(diff);
00450 cpl_free(ron_key);
00451
00452 return cpl_error_get_code();
00453 }
00454
00455
00469
00470 static cpl_error_code visir_img_dark_save(cpl_frameset * set_tot,
00471 const cpl_parameterlist * parlist,
00472 const cpl_propertylist * qclist,
00473 const cpl_image * avg,
00474 const cpl_mask * hot,
00475 const cpl_mask * cold,
00476 const cpl_mask * dev,
00477 int set_nb,
00478 const irplib_framelist * f_one)
00479 {
00480 cpl_frameset * set = irplib_frameset_cast(f_one);
00481 const cpl_propertylist * plist
00482 = irplib_framelist_get_propertylist_const(f_one, 0);
00483 cpl_propertylist * paflist = cpl_propertylist_new();
00484 cpl_image * image = NULL;
00485 const char pafcopy[] = "^(" VISIR_PFITS_REGEXP_DARK_PAF ")$";
00486 char * filename = NULL;
00487 const char * procatg_avg;
00488 const char * procatg_dev;
00489 const char * procatg_hot;
00490 const char * procatg_cold;
00491
00492
00493
00494 skip_if (0);
00495
00496
00497 switch (visir_img_dark_config.mode) {
00498 case visir_dark_img:
00499 procatg_avg = VISIR_IMG_DARK_AVG_PROCATG;
00500 procatg_dev = VISIR_IMG_DARK_DEV_PROCATG;
00501 procatg_hot = VISIR_IMG_DARK_HOT_PROCATG;
00502 procatg_cold = VISIR_IMG_DARK_COLD_PROCATG;
00503 break;
00504 case visir_dark_spc:
00505 procatg_avg = VISIR_SPC_DARK_AVG_PROCATG;
00506 procatg_dev = VISIR_SPC_DARK_DEV_PROCATG;
00507 procatg_hot = VISIR_SPC_DARK_HOT_PROCATG;
00508 procatg_cold = VISIR_SPC_DARK_COLD_PROCATG;
00509 break;
00510 default:
00511 bug_if(1);
00512 }
00513
00514
00515
00516 filename = cpl_sprintf(RECIPE_STRING "_set%02d_avg" CPL_DFS_FITS,
00517 set_nb);
00518 skip_if (irplib_dfs_save_image(set_tot, parlist, set, avg, CPL_BPP_IEEE_FLOAT,
00519 RECIPE_STRING, procatg_avg, qclist, NULL,
00520 visir_pipe_id, filename));
00521
00522
00523 image = cpl_image_new_from_mask(hot);
00524 skip_if(0);
00525
00526 cpl_free(filename);
00527 filename = cpl_sprintf(RECIPE_STRING "_set%02d_hotpix" CPL_DFS_FITS,
00528 set_nb);
00529 skip_if (irplib_dfs_save_image(set_tot, parlist, set, image, CPL_BPP_32_SIGNED,
00530 RECIPE_STRING, procatg_hot, qclist, NULL,
00531 visir_pipe_id, filename));
00532 cpl_image_delete(image);
00533 image = NULL;
00534
00535
00536 image = cpl_image_new_from_mask(cold);
00537 skip_if(0);
00538
00539 cpl_free(filename);
00540 filename = cpl_sprintf(RECIPE_STRING "_set%02d_coldpix" CPL_DFS_FITS,
00541 set_nb);
00542 skip_if (irplib_dfs_save_image(set_tot, parlist, set, image, CPL_BPP_32_SIGNED,
00543 RECIPE_STRING, procatg_cold, qclist, NULL,
00544 visir_pipe_id, filename));
00545 cpl_image_delete(image);
00546 image = NULL;
00547
00548
00549 image = cpl_image_new_from_mask(dev);
00550 skip_if(0);
00551
00552 cpl_free(filename);
00553 filename = cpl_sprintf(RECIPE_STRING "_set%02d_devpix" CPL_DFS_FITS,
00554 set_nb);
00555 skip_if (irplib_dfs_save_image(set_tot, parlist, set, image,
00556 CPL_BPP_32_SIGNED, RECIPE_STRING,
00557 procatg_dev, qclist, NULL, visir_pipe_id,
00558 filename));
00559 cpl_image_delete(image);
00560 image = NULL;
00561
00562 #ifdef VISIR_SAVE_PAF
00563
00564
00565 skip_if (cpl_propertylist_copy_property_regexp(paflist, plist, pafcopy, 0));
00566 skip_if (cpl_propertylist_append(paflist, qclist));
00567
00568
00569 bug_if (cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
00570 procatg_avg));
00571
00572 cpl_free(filename);
00573 filename = cpl_sprintf(RECIPE_STRING "_set%02d" CPL_DFS_PAF, set_nb);
00574 skip_if (cpl_dfs_save_paf("VISIR", RECIPE_STRING, paflist, filename));
00575 #else
00576 bug_if(paflist == NULL);
00577 bug_if(plist == NULL);
00578 bug_if(pafcopy == NULL);
00579 #endif
00580
00581 end_skip;
00582
00583 cpl_image_delete(image);
00584 cpl_frameset_delete(set);
00585 cpl_propertylist_delete(paflist);
00586 cpl_free(filename);
00587
00588 return cpl_error_get_code();
00589 }
00590
00591
00592
00602
00603 static char * visir_img_dark_make_tag(const cpl_frame* self,
00604 const cpl_propertylist * plist, int dummy)
00605 {
00606
00607 char * tag = NULL;
00608 double etime;
00609
00610
00611 skip_if (0);
00612
00613 skip_if(self == NULL);
00614 skip_if(plist == NULL);
00615 skip_if(dummy < 0);
00616
00617
00618 etime = visir_pfits_get_exptime(plist);
00619 skip_if(0);
00620
00621 tag = cpl_sprintf("%.5f", etime);
00622 bug_if(tag == NULL);
00623
00624 end_skip;
00625
00626 if (cpl_error_get_code()) {
00627 cpl_free(tag);
00628 tag = NULL;
00629 }
00630
00631 return tag;
00632
00633 }
00634