39 #include "irplib_utils.h"
41 #include "sofi_utils.h"
42 #include "sofi_pfits.h"
49 static int sofi_img_dark_create(cpl_plugin *);
50 static int sofi_img_dark_exec(cpl_plugin *);
51 static int sofi_img_dark_destroy(cpl_plugin *);
52 static int sofi_img_dark(cpl_parameterlist *, cpl_frameset *);
54 static int sofi_img_dark_avg_reduce(cpl_frameset *, cpl_image **);
55 static cpl_matrix * sofi_img_dark_ron_reduce(cpl_frameset *);
56 static int sofi_img_dark_compare(
const cpl_frame *,
const cpl_frame *);
57 static int sofi_img_dark_save(cpl_image *, cpl_matrix *,
int, cpl_frameset *,
58 cpl_parameterlist *, cpl_frameset *);
71 } sofi_img_dark_config;
73 static char sofi_img_dark_description[] =
74 "sofi_img_dark -- SOFI imaging dark recipe.\n"
75 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
76 "raw-file.fits "SOFI_IMG_DARK_RAW
"\n";
91 int cpl_plugin_get_info(cpl_pluginlist * list)
93 cpl_recipe * recipe = cpl_calloc(1,
sizeof(*recipe));
94 cpl_plugin * plugin = &recipe->interface;
96 cpl_plugin_init(plugin,
99 CPL_PLUGIN_TYPE_RECIPE,
102 sofi_img_dark_description,
106 sofi_img_dark_create,
108 sofi_img_dark_destroy);
110 cpl_pluginlist_append(list, plugin);
125 static int sofi_img_dark_create(cpl_plugin * plugin)
131 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
132 recipe = (cpl_recipe *)plugin;
133 else return CPL_ERROR_UNSPECIFIED;
136 recipe->parameters = cpl_parameterlist_new();
140 p = cpl_parameter_new_value(
"sofi.sofi_img_dark.nsamples",
141 CPL_TYPE_INT,
"number of samples for RON computation",
142 "sofi.sofi_img_dark", 100);
143 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"nsamples");
144 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
145 cpl_parameterlist_append(recipe->parameters, p);
147 p = cpl_parameter_new_value(
"sofi.sofi_img_dark.hsize",
148 CPL_TYPE_INT,
"half size of the window for RON computation",
149 "sofi.sofi_img_dark", 6);
150 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"hsize");
151 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
152 cpl_parameterlist_append(recipe->parameters, p);
165 static int sofi_img_dark_exec(cpl_plugin * plugin)
170 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
171 recipe = (cpl_recipe *)plugin;
172 else return CPL_ERROR_UNSPECIFIED;
174 return sofi_img_dark(recipe->parameters, recipe->frames);
184 static int sofi_img_dark_destroy(cpl_plugin * plugin)
189 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
190 recipe = (cpl_recipe *)plugin;
191 else return CPL_ERROR_UNSPECIFIED;
193 cpl_parameterlist_delete(recipe->parameters);
205 static int sofi_img_dark(
206 cpl_parameterlist * parlist,
207 cpl_frameset * framelist)
211 cpl_size * selection;
212 cpl_frameset * f_one;
218 par = cpl_parameterlist_find(parlist,
"sofi.sofi_img_dark.hsize");
219 sofi_img_dark_config.hsize = cpl_parameter_get_int(par);
220 par = cpl_parameterlist_find(parlist,
"sofi.sofi_img_dark.nsamples");
221 sofi_img_dark_config.nsamples = cpl_parameter_get_int(par);
225 cpl_msg_error(cpl_func,
"Cannot identify RAW and CALIB frames");
226 return CPL_ERROR_UNSPECIFIED;
230 cpl_msg_info(cpl_func,
"Identify the different settings");
231 selection=cpl_frameset_labelise(framelist, sofi_img_dark_compare, &nsets);
232 if (selection == NULL) {
233 cpl_msg_error(cpl_func,
"Cannot labelise input frames");
234 return CPL_ERROR_UNSPECIFIED;
238 for (i=0; i<nsets; i++) {
240 sofi_img_dark_config.dark_med = -1.0;
241 sofi_img_dark_config.dark_stdev = -1.0;
245 cpl_msg_info(cpl_func,
"Reduce data set no %d out of %d", i+1,
247 cpl_msg_indent_more();
248 f_one = cpl_frameset_extract(framelist, selection, i);
251 if (cpl_frameset_get_size(f_one) < 2) {
252 cpl_msg_warning(cpl_func,
"Setting %d skipped (not enough frames)",
254 cpl_frameset_delete(f_one);
255 return CPL_ERROR_UNSPECIFIED;
258 cpl_msg_info(cpl_func,
"Compute the master dark");
259 cpl_msg_indent_more();
260 if (sofi_img_dark_avg_reduce(f_one, &avg)) {
261 cpl_msg_warning(cpl_func,
"Cannot reduce set number %d", i+1);
263 cpl_msg_indent_less();
265 cpl_msg_info(cpl_func,
"Compute the read-out noise");
266 cpl_msg_indent_more();
267 if ((rons = sofi_img_dark_ron_reduce(f_one)) == NULL) {
268 cpl_msg_warning(cpl_func,
"Cannot reduce set number %d", i+1);
270 cpl_msg_indent_less();
272 if (sofi_img_dark_save(avg, rons, i+1, f_one, parlist,
274 cpl_msg_error(cpl_func,
"Cannot save the products");
275 if (avg) cpl_image_delete(avg);
276 if (rons) cpl_matrix_delete(rons);
277 cpl_frameset_delete(f_one);
278 return CPL_ERROR_UNSPECIFIED;
280 if (rons) cpl_matrix_delete(rons);
282 if (avg) cpl_image_delete(avg);
283 cpl_frameset_delete(f_one);
284 cpl_msg_indent_less();
300 static int sofi_img_dark_avg_reduce(
301 cpl_frameset * framelist,
304 cpl_imagelist * iset;
305 cpl_vector * medians;
310 if (framelist == NULL)
return CPL_ERROR_UNSPECIFIED;
313 if ((iset = cpl_imagelist_load_frameset(framelist, CPL_TYPE_FLOAT, 1,
315 cpl_msg_error(cpl_func,
"Cannot load the data");
316 return CPL_ERROR_UNSPECIFIED;
320 if ((*avg = cpl_imagelist_collapse_create(iset)) == NULL) {
321 cpl_msg_error(cpl_func,
"Cannot average the data set");
322 cpl_imagelist_delete(iset);
323 return CPL_ERROR_UNSPECIFIED;
327 medians = cpl_vector_new(cpl_imagelist_get_size(iset));
328 for (i=0; i<cpl_imagelist_get_size(iset); i++) {
329 image = cpl_imagelist_get(iset, i);
330 cpl_vector_set(medians, i, cpl_image_get_median(image));
332 cpl_imagelist_delete(iset);
333 sofi_img_dark_config.dark_med = cpl_vector_get_mean(medians);
334 sofi_img_dark_config.dark_stdev = cpl_vector_get_stdev(medians);
337 cpl_vector_delete(medians);
353 static cpl_matrix * sofi_img_dark_ron_reduce(cpl_frameset * framelist)
355 cpl_frame * cur_frame;
356 cpl_propertylist * plist;
357 cpl_imagelist * iset;
363 cpl_size zone_def[4];
367 if (framelist == NULL)
return NULL;
370 if ((iset = cpl_imagelist_load_frameset(framelist, CPL_TYPE_FLOAT, 1,
372 cpl_msg_error(cpl_func,
"Cannot load the data");
377 rons = cpl_matrix_new(cpl_imagelist_get_size(iset)-1, 4);
380 for (i=0; i<cpl_imagelist_get_size(iset)-1; i++) {
381 cpl_msg_info(cpl_func,
"Pair number %d", i+1);
383 if (cpl_error_get_code()) {
384 cpl_matrix_delete(rons);
385 cpl_imagelist_delete(iset);
388 cur_frame = cpl_frameset_get_position(framelist, i);
389 plist = cpl_propertylist_load(cpl_frame_get_filename(cur_frame),
392 cpl_propertylist_delete(plist);
393 if (cpl_error_get_code()) {
394 cpl_msg_error(cpl_func,
"Cannot get the NDIT");
395 cpl_matrix_delete(rons);
396 cpl_imagelist_delete(iset);
403 if ((tmp_im = cpl_image_subtract_create(
404 cpl_imagelist_get(iset, i),
405 cpl_imagelist_get(iset, i+1))) == NULL) {
406 cpl_msg_error(cpl_func,
"Cannot subtract the images");
407 cpl_imagelist_delete(iset);
408 cpl_matrix_delete(rons);
414 zone_def[1] = cpl_image_get_size_x(tmp_im)/2;
416 zone_def[3] = cpl_image_get_size_y(tmp_im)/2;
417 cpl_flux_get_noise_window(tmp_im, zone_def,
418 sofi_img_dark_config.hsize,
419 sofi_img_dark_config.nsamples, &rms, NULL);
420 cpl_matrix_set(rons, i, 0, rms * norm);
421 cpl_msg_info(cpl_func,
"RON in LL quadrant: %g", rms * norm);
424 zone_def[0] = cpl_image_get_size_x(tmp_im)/2 + 1;
425 zone_def[1] = cpl_image_get_size_x(tmp_im);
427 zone_def[3] = cpl_image_get_size_y(tmp_im)/2;
428 cpl_flux_get_noise_window(tmp_im, zone_def,
429 sofi_img_dark_config.hsize,
430 sofi_img_dark_config.nsamples, &rms, NULL);
431 cpl_matrix_set(rons, i, 1, rms * norm);
432 cpl_msg_info(cpl_func,
"RON in LR quadrant: %g", rms * norm);
436 zone_def[1] = cpl_image_get_size_x(tmp_im)/2;
437 zone_def[2] = cpl_image_get_size_y(tmp_im)/2 + 1;
438 zone_def[3] = cpl_image_get_size_y(tmp_im);
439 cpl_flux_get_noise_window(tmp_im, zone_def,
440 sofi_img_dark_config.hsize,
441 sofi_img_dark_config.nsamples, &rms, NULL);
442 cpl_matrix_set(rons, i, 2, rms * norm);
443 cpl_msg_info(cpl_func,
"RON in UL quadrant: %g", rms * norm);
446 zone_def[0] = cpl_image_get_size_x(tmp_im)/2 + 1;
447 zone_def[1] = cpl_image_get_size_x(tmp_im);
448 zone_def[2] = cpl_image_get_size_y(tmp_im)/2 + 1;
449 zone_def[3] = cpl_image_get_size_y(tmp_im);
450 cpl_flux_get_noise_window(tmp_im, zone_def,
451 sofi_img_dark_config.hsize,
452 sofi_img_dark_config.nsamples, &rms, NULL);
453 cpl_matrix_set(rons, i, 3, rms * norm);
454 cpl_msg_info(cpl_func,
"RON in UR quadrant: %g", rms * norm);
455 cpl_image_delete(tmp_im);
459 cpl_imagelist_delete(iset);
475 static int sofi_img_dark_save(
480 cpl_parameterlist * parlist,
481 cpl_frameset * set_tot)
483 cpl_propertylist * plist;
484 cpl_propertylist * qclist;
485 cpl_propertylist * paflist;
486 const cpl_frame * ref_frame;
492 qclist = cpl_propertylist_new();
493 cpl_propertylist_append_double(qclist,
"ESO QC DARKMED",
494 sofi_img_dark_config.dark_med);
495 cpl_propertylist_append_double(qclist,
"ESO QC DARKSTDEV",
496 sofi_img_dark_config.dark_stdev);
498 for (i=0; i<cpl_matrix_get_nrow(rons); i++) {
499 sprintf(qc_str,
"ESO QC LL RON%d", i+1);
500 cpl_propertylist_append_double(qclist, qc_str,
501 cpl_matrix_get(rons, i, 0));
502 sprintf(qc_str,
"ESO QC LR RON%d", i+1);
503 cpl_propertylist_append_double(qclist, qc_str,
504 cpl_matrix_get(rons, i, 1));
505 sprintf(qc_str,
"ESO QC UL RON%d", i+1);
506 cpl_propertylist_append_double(qclist, qc_str,
507 cpl_matrix_get(rons, i, 2));
508 sprintf(qc_str,
"ESO QC UR RON%d", i+1);
509 cpl_propertylist_append_double(qclist, qc_str,
510 cpl_matrix_get(rons, i, 3));
515 filename = cpl_sprintf(
"sofi_img_dark_set%02d_avg.fits", set_nb);
516 irplib_dfs_save_image(set_tot,
525 PACKAGE
"/" PACKAGE_VERSION,
530 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
533 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
535 cpl_msg_error(cpl_func,
"getting header from reference frame");
536 cpl_propertylist_delete(qclist);
537 return CPL_ERROR_UNSPECIFIED;
541 paflist = cpl_propertylist_new();
542 cpl_propertylist_copy_property_regexp(paflist, plist,
543 "^(ARCFILE|MJD-OBS|ESO TPL ID|ESO DPR TECH|DATE-OBS|ESO DET DIT|"
544 "ESO DET NDIT|ESO DET NCORRS|ESO DET NDSAMPLES|ESO DET MODE NAME)$", 0);
545 cpl_propertylist_delete(plist);
548 cpl_propertylist_copy_property_regexp(paflist, qclist,
".", 0);
549 cpl_propertylist_delete(qclist);
552 filename = cpl_sprintf(
"sofi_img_dark_set%02d.paf", set_nb);
553 cpl_dfs_save_paf(
"SOFI",
558 cpl_propertylist_delete(paflist);
570 static int sofi_img_dark_compare(
571 const cpl_frame * frame1,
572 const cpl_frame * frame2)
575 cpl_propertylist * plist1;
576 cpl_propertylist * plist2;
581 if (frame1==NULL || frame2==NULL)
return CPL_ERROR_UNSPECIFIED;
584 if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),
586 cpl_msg_error(cpl_func,
"getting header from reference frame");
587 return CPL_ERROR_UNSPECIFIED;
589 if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),
591 cpl_msg_error(cpl_func,
"getting header from reference frame");
592 cpl_propertylist_delete(plist1);
593 return CPL_ERROR_UNSPECIFIED;
597 if (cpl_error_get_code()) {
598 cpl_propertylist_delete(plist1);
599 cpl_propertylist_delete(plist2);
600 return CPL_ERROR_UNSPECIFIED;
607 if (cpl_error_get_code()) {
608 cpl_msg_error(cpl_func,
"cannot get exposure time");
609 cpl_propertylist_delete(plist1);
610 cpl_propertylist_delete(plist2);
611 return CPL_ERROR_UNSPECIFIED;
613 if (fabs(dval1-dval2) > 1e-5) comparison = 0;
618 if (cpl_error_get_code()) {
619 cpl_msg_error(cpl_func,
"cannot get NDIT");
620 cpl_propertylist_delete(plist1);
621 cpl_propertylist_delete(plist2);
622 return CPL_ERROR_UNSPECIFIED;
624 if (ival1 != ival2) comparison = 0;
629 if (cpl_error_get_code()) {
630 cpl_msg_error(cpl_func,
"cannot get read-out mode");
631 cpl_propertylist_delete(plist1);
632 cpl_propertylist_delete(plist2);
633 return CPL_ERROR_UNSPECIFIED;
635 if (ival1 != ival2) comparison = 0;
638 cpl_propertylist_delete(plist1);
639 cpl_propertylist_delete(plist2);