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 <cpl.h>
00037 #include <math.h>
00038
00039 #include "irplib_utils.h"
00040
00041 #include "sofi_utils.h"
00042 #include "sofi_pfits.h"
00043 #include "sofi_dfs.h"
00044
00045
00046
00047
00048
00049 static int sofi_img_dark_create(cpl_plugin *);
00050 static int sofi_img_dark_exec(cpl_plugin *);
00051 static int sofi_img_dark_destroy(cpl_plugin *);
00052 static int sofi_img_dark(cpl_parameterlist *, cpl_frameset *);
00053
00054 static int sofi_img_dark_avg_reduce(cpl_frameset *, cpl_image **);
00055 static cpl_matrix * sofi_img_dark_ron_reduce(cpl_frameset *);
00056 static int sofi_img_dark_compare(const cpl_frame *, const cpl_frame *);
00057 static int sofi_img_dark_save(cpl_image *, cpl_matrix *, int, cpl_frameset *,
00058 cpl_parameterlist *, cpl_frameset *);
00059
00060
00061
00062
00063
00064 static struct {
00065
00066 int hsize;
00067 int nsamples;
00068
00069 double dark_med;
00070 double dark_stdev;
00071 } sofi_img_dark_config;
00072
00073 static char sofi_img_dark_description[] =
00074 "sofi_img_dark -- SOFI imaging dark recipe.\n"
00075 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00076 "raw-file.fits "SOFI_IMG_DARK_RAW"\n";
00077
00078
00079
00080
00081
00082
00090
00091 int cpl_plugin_get_info(cpl_pluginlist * list)
00092 {
00093 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe));
00094 cpl_plugin * plugin = &recipe->interface;
00095
00096 cpl_plugin_init(plugin,
00097 CPL_PLUGIN_API,
00098 SOFI_BINARY_VERSION,
00099 CPL_PLUGIN_TYPE_RECIPE,
00100 "sofi_img_dark",
00101 "Dark recipe",
00102 sofi_img_dark_description,
00103 "Yves Jung",
00104 "yjung@eso.org",
00105 sofi_get_license(),
00106 sofi_img_dark_create,
00107 sofi_img_dark_exec,
00108 sofi_img_dark_destroy);
00109
00110 cpl_pluginlist_append(list, plugin);
00111
00112 return 0;
00113 }
00114
00115
00124
00125 static int sofi_img_dark_create(cpl_plugin * plugin)
00126 {
00127 cpl_recipe * recipe;
00128 cpl_parameter * p;
00129
00130
00131 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00132 recipe = (cpl_recipe *)plugin;
00133 else return -1;
00134
00135
00136 recipe->parameters = cpl_parameterlist_new();
00137
00138
00139
00140 p = cpl_parameter_new_value("sofi.sofi_img_dark.nsamples",
00141 CPL_TYPE_INT, "number of samples for RON computation",
00142 "sofi.sofi_img_dark", 100);
00143 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nsamples");
00144 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00145 cpl_parameterlist_append(recipe->parameters, p);
00146
00147 p = cpl_parameter_new_value("sofi.sofi_img_dark.hsize",
00148 CPL_TYPE_INT, "half size of the window for RON computation",
00149 "sofi.sofi_img_dark", 6);
00150 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "hsize");
00151 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00152 cpl_parameterlist_append(recipe->parameters, p);
00153
00154
00155 return 0;
00156 }
00157
00158
00164
00165 static int sofi_img_dark_exec(cpl_plugin * plugin)
00166 {
00167 cpl_recipe * recipe;
00168
00169
00170 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00171 recipe = (cpl_recipe *)plugin;
00172 else return -1;
00173
00174 return sofi_img_dark(recipe->parameters, recipe->frames);
00175 }
00176
00177
00183
00184 static int sofi_img_dark_destroy(cpl_plugin * plugin)
00185 {
00186 cpl_recipe * recipe;
00187
00188
00189 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00190 recipe = (cpl_recipe *)plugin;
00191 else return -1;
00192
00193 cpl_parameterlist_delete(recipe->parameters);
00194 return 0;
00195 }
00196
00197
00204
00205 static int sofi_img_dark(
00206 cpl_parameterlist * parlist,
00207 cpl_frameset * framelist)
00208 {
00209 cpl_parameter * par;
00210 cpl_size nsets;
00211 cpl_size * selection;
00212 cpl_frameset * f_one;
00213 cpl_image * avg;
00214 cpl_matrix * rons;
00215 int i;
00216
00217
00218 par = cpl_parameterlist_find(parlist, "sofi.sofi_img_dark.hsize");
00219 sofi_img_dark_config.hsize = cpl_parameter_get_int(par);
00220 par = cpl_parameterlist_find(parlist, "sofi.sofi_img_dark.nsamples");
00221 sofi_img_dark_config.nsamples = cpl_parameter_get_int(par);
00222
00223
00224 if (sofi_dfs_set_groups(framelist)) {
00225 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
00226 return -1;
00227 }
00228
00229
00230 cpl_msg_info(cpl_func, "Identify the different settings");
00231 selection=cpl_frameset_labelise(framelist, sofi_img_dark_compare, &nsets);
00232 if (selection == NULL) {
00233 cpl_msg_error(cpl_func, "Cannot labelise input frames");
00234 return -1;
00235 }
00236
00237
00238 for (i=0; i<nsets; i++) {
00239
00240 sofi_img_dark_config.dark_med = -1.0;
00241 sofi_img_dark_config.dark_stdev = -1.0;
00242 avg = NULL;
00243
00244
00245 cpl_msg_info(cpl_func, "Reduce data set no %d out of %d", i+1,
00246 (int)nsets);
00247 cpl_msg_indent_more();
00248 f_one = cpl_frameset_extract(framelist, selection, i);
00249
00250
00251 if (cpl_frameset_get_size(f_one) < 2) {
00252 cpl_msg_warning(cpl_func, "Setting %d skipped (not enough frames)",
00253 i+1);
00254 } else {
00255
00256 cpl_msg_info(cpl_func, "Compute the master dark");
00257 cpl_msg_indent_more();
00258 if (sofi_img_dark_avg_reduce(f_one, &avg)) {
00259 cpl_msg_warning(cpl_func, "Cannot reduce set number %d", i+1);
00260 }
00261 cpl_msg_indent_less();
00262
00263 cpl_msg_info(cpl_func, "Compute the read-out noise");
00264 cpl_msg_indent_more();
00265 if ((rons = sofi_img_dark_ron_reduce(f_one)) == NULL) {
00266 cpl_msg_warning(cpl_func, "Cannot reduce set number %d", i+1);
00267 }
00268 cpl_msg_indent_less();
00269
00270 if (sofi_img_dark_save(avg, rons, i+1, f_one, parlist,
00271 framelist) !=0 ){
00272 cpl_msg_error(cpl_func, "Cannot save the products");
00273 if (avg) cpl_image_delete(avg);
00274 if (rons) cpl_matrix_delete(rons);
00275 return -1;
00276 }
00277 if (rons) cpl_matrix_delete(rons);
00278 }
00279 if (avg) cpl_image_delete(avg);
00280 cpl_frameset_delete(f_one);
00281 cpl_msg_indent_less();
00282 }
00283
00284
00285 cpl_free(selection);
00286 return 0;
00287 }
00288
00289
00296
00297 static int sofi_img_dark_avg_reduce(
00298 cpl_frameset * framelist,
00299 cpl_image ** avg)
00300 {
00301 cpl_imagelist * iset;
00302 cpl_vector * medians;
00303 cpl_image * image;
00304 int i;
00305
00306
00307 if (framelist == NULL) return -1;
00308
00309
00310 if ((iset = cpl_imagelist_load_frameset(framelist, CPL_TYPE_FLOAT, 1,
00311 0)) == NULL) {
00312 cpl_msg_error(cpl_func, "Cannot load the data");
00313 return -1;
00314 }
00315
00316
00317 if ((*avg = cpl_imagelist_collapse_create(iset)) == NULL) {
00318 cpl_msg_error(cpl_func, "Cannot average the data set");
00319 cpl_imagelist_delete(iset);
00320 return -1;
00321 }
00322
00323
00324 medians = cpl_vector_new(cpl_imagelist_get_size(iset));
00325 for (i=0; i<cpl_imagelist_get_size(iset); i++) {
00326 image = cpl_imagelist_get(iset, i);
00327 cpl_vector_set(medians, i, cpl_image_get_median(image));
00328 }
00329 cpl_imagelist_delete(iset);
00330 sofi_img_dark_config.dark_med = cpl_vector_get_mean(medians);
00331 sofi_img_dark_config.dark_stdev = cpl_vector_get_stdev(medians);
00332
00333
00334 cpl_vector_delete(medians);
00335 return 0;
00336 }
00337
00338
00349
00350 static cpl_matrix * sofi_img_dark_ron_reduce(cpl_frameset * framelist)
00351 {
00352 cpl_frame * cur_frame;
00353 cpl_propertylist * plist;
00354 cpl_imagelist * iset;
00355 cpl_matrix * rons;
00356 cpl_image * tmp_im;
00357 double rms;
00358 double norm;
00359 int ndit;
00360 cpl_size zone_def[4];
00361 int i;
00362
00363
00364 if (framelist == NULL) return NULL;
00365
00366
00367 if ((iset = cpl_imagelist_load_frameset(framelist, CPL_TYPE_FLOAT, 1,
00368 0)) == NULL) {
00369 cpl_msg_error(cpl_func, "Cannot load the data");
00370 return NULL;
00371 }
00372
00373
00374 rons = cpl_matrix_new(cpl_imagelist_get_size(iset)-1, 4);
00375
00376
00377 for (i=0; i<cpl_imagelist_get_size(iset)-1; i++) {
00378 cpl_msg_info(cpl_func, "Pair number %d", i+1);
00379
00380 if (cpl_error_get_code()) {
00381 cpl_matrix_delete(rons);
00382 cpl_imagelist_delete(iset);
00383 return NULL;
00384 }
00385 cur_frame = cpl_frameset_get_frame(framelist, i);
00386 plist = cpl_propertylist_load(cpl_frame_get_filename(cur_frame),
00387 0);
00388 ndit = sofi_pfits_get_ndit(plist);
00389 cpl_propertylist_delete(plist);
00390 if (cpl_error_get_code()) {
00391 cpl_msg_error(cpl_func, "Cannot get the NDIT");
00392 cpl_matrix_delete(rons);
00393 cpl_imagelist_delete(iset);
00394 return NULL;
00395 }
00396 norm = 0.5 * ndit;
00397 norm = sqrt(norm);
00398
00399
00400 if ((tmp_im = cpl_image_subtract_create(
00401 cpl_imagelist_get(iset, i),
00402 cpl_imagelist_get(iset, i+1))) == NULL) {
00403 cpl_msg_error(cpl_func, "Cannot subtract the images");
00404 cpl_imagelist_delete(iset);
00405 cpl_matrix_delete(rons);
00406 return NULL;
00407 }
00408
00409
00410 zone_def[0] = 1;
00411 zone_def[1] = cpl_image_get_size_x(tmp_im)/2;
00412 zone_def[2] = 1;
00413 zone_def[3] = cpl_image_get_size_y(tmp_im)/2;
00414 cpl_flux_get_noise_window(tmp_im, zone_def,
00415 sofi_img_dark_config.hsize,
00416 sofi_img_dark_config.nsamples, &rms, NULL);
00417 cpl_matrix_set(rons, i, 0, rms * norm);
00418 cpl_msg_info(cpl_func, "RON in LL quadrant: %g", rms * norm);
00419
00420
00421 zone_def[0] = cpl_image_get_size_x(tmp_im)/2 + 1;
00422 zone_def[1] = cpl_image_get_size_x(tmp_im);
00423 zone_def[2] = 1;
00424 zone_def[3] = cpl_image_get_size_y(tmp_im)/2;
00425 cpl_flux_get_noise_window(tmp_im, zone_def,
00426 sofi_img_dark_config.hsize,
00427 sofi_img_dark_config.nsamples, &rms, NULL);
00428 cpl_matrix_set(rons, i, 1, rms * norm);
00429 cpl_msg_info(cpl_func, "RON in LR quadrant: %g", rms * norm);
00430
00431
00432 zone_def[0] = 1;
00433 zone_def[1] = cpl_image_get_size_x(tmp_im)/2;
00434 zone_def[2] = cpl_image_get_size_y(tmp_im)/2 + 1;
00435 zone_def[3] = cpl_image_get_size_y(tmp_im);
00436 cpl_flux_get_noise_window(tmp_im, zone_def,
00437 sofi_img_dark_config.hsize,
00438 sofi_img_dark_config.nsamples, &rms, NULL);
00439 cpl_matrix_set(rons, i, 2, rms * norm);
00440 cpl_msg_info(cpl_func, "RON in UL quadrant: %g", rms * norm);
00441
00442
00443 zone_def[0] = cpl_image_get_size_x(tmp_im)/2 + 1;
00444 zone_def[1] = cpl_image_get_size_x(tmp_im);
00445 zone_def[2] = cpl_image_get_size_y(tmp_im)/2 + 1;
00446 zone_def[3] = cpl_image_get_size_y(tmp_im);
00447 cpl_flux_get_noise_window(tmp_im, zone_def,
00448 sofi_img_dark_config.hsize,
00449 sofi_img_dark_config.nsamples, &rms, NULL);
00450 cpl_matrix_set(rons, i, 3, rms * norm);
00451 cpl_msg_info(cpl_func, "RON in UR quadrant: %g", rms * norm);
00452 cpl_image_delete(tmp_im);
00453 }
00454
00455
00456 cpl_imagelist_delete(iset);
00457 return rons;
00458 }
00459
00460
00471
00472 static int sofi_img_dark_save(
00473 cpl_image * avg,
00474 cpl_matrix * rons,
00475 int set_nb,
00476 cpl_frameset * set,
00477 cpl_parameterlist * parlist,
00478 cpl_frameset * set_tot)
00479 {
00480 cpl_propertylist * plist;
00481 cpl_propertylist * qclist;
00482 cpl_propertylist * paflist;
00483 const cpl_frame * ref_frame;
00484 char qc_str[128];
00485 char * filename;
00486 int i;
00487
00488
00489 qclist = cpl_propertylist_new();
00490 cpl_propertylist_append_double(qclist, "ESO QC DARKMED",
00491 sofi_img_dark_config.dark_med);
00492 cpl_propertylist_append_double(qclist, "ESO QC DARKSTDEV",
00493 sofi_img_dark_config.dark_stdev);
00494 if (rons != NULL) {
00495 for (i=0; i<cpl_matrix_get_nrow(rons); i++) {
00496 sprintf(qc_str, "ESO QC LL RON%d", i+1);
00497 cpl_propertylist_append_double(qclist, qc_str,
00498 cpl_matrix_get(rons, i, 0));
00499 sprintf(qc_str, "ESO QC LR RON%d", i+1);
00500 cpl_propertylist_append_double(qclist, qc_str,
00501 cpl_matrix_get(rons, i, 1));
00502 sprintf(qc_str, "ESO QC UL RON%d", i+1);
00503 cpl_propertylist_append_double(qclist, qc_str,
00504 cpl_matrix_get(rons, i, 2));
00505 sprintf(qc_str, "ESO QC UR RON%d", i+1);
00506 cpl_propertylist_append_double(qclist, qc_str,
00507 cpl_matrix_get(rons, i, 3));
00508 }
00509 }
00510
00511
00512 filename = cpl_sprintf("sofi_img_dark_set%02d_avg.fits", set_nb);
00513 irplib_dfs_save_image(set_tot,
00514 parlist,
00515 set,
00516 avg,
00517 CPL_BPP_IEEE_FLOAT,
00518 "sofi_img_dark",
00519 SOFI_IMG_DARK_AVG,
00520 qclist,
00521 NULL,
00522 PACKAGE "/" PACKAGE_VERSION,
00523 filename);
00524 cpl_free(filename);
00525
00526
00527 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00528
00529
00530 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00531 0)) == NULL) {
00532 cpl_msg_error(cpl_func, "getting header from reference frame");
00533 cpl_propertylist_delete(qclist);
00534 return -1;
00535 }
00536
00537
00538 paflist = cpl_propertylist_new();
00539 cpl_propertylist_copy_property_regexp(paflist, plist,
00540 "^(ARCFILE|MJD-OBS|ESO TPL ID|ESO DPR TECH|DATE-OBS|ESO DET DIT|"
00541 "ESO DET NDIT|ESO DET NCORRS|ESO DET NDSAMPLES|ESO DET MODE NAME)$", 0);
00542 cpl_propertylist_delete(plist);
00543
00544
00545 cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0);
00546 cpl_propertylist_delete(qclist);
00547
00548
00549 filename = cpl_sprintf("sofi_img_dark_set%02d.paf", set_nb);
00550 cpl_dfs_save_paf("SOFI",
00551 "sofi_img_dark",
00552 paflist,
00553 filename);
00554 cpl_free(filename);
00555 cpl_propertylist_delete(paflist);
00556 return 0;
00557 }
00558
00559
00566
00567 static int sofi_img_dark_compare(
00568 const cpl_frame * frame1,
00569 const cpl_frame * frame2)
00570 {
00571 int comparison;
00572 cpl_propertylist * plist1;
00573 cpl_propertylist * plist2;
00574 double dval1, dval2;
00575 int ival1, ival2;
00576
00577
00578 if (frame1==NULL || frame2==NULL) return -1;
00579
00580
00581 if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),
00582 0)) == NULL) {
00583 cpl_msg_error(cpl_func, "getting header from reference frame");
00584 return -1;
00585 }
00586 if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),
00587 0)) == NULL) {
00588 cpl_msg_error(cpl_func, "getting header from reference frame");
00589 cpl_propertylist_delete(plist1);
00590 return -1;
00591 }
00592
00593
00594 if (cpl_error_get_code()) {
00595 cpl_propertylist_delete(plist1);
00596 cpl_propertylist_delete(plist2);
00597 return -1;
00598 }
00599
00600
00601 comparison = 1;
00602 dval1 = sofi_pfits_get_dit(plist1);
00603 dval2 = sofi_pfits_get_dit(plist2);
00604 if (cpl_error_get_code()) {
00605 cpl_msg_error(cpl_func, "cannot get exposure time");
00606 cpl_propertylist_delete(plist1);
00607 cpl_propertylist_delete(plist2);
00608 return -1;
00609 }
00610 if (fabs(dval1-dval2) > 1e-5) comparison = 0;
00611
00612
00613 ival1 = sofi_pfits_get_ndit(plist1);
00614 ival2 = sofi_pfits_get_ndit(plist2);
00615 if (cpl_error_get_code()) {
00616 cpl_msg_error(cpl_func, "cannot get NDIT");
00617 cpl_propertylist_delete(plist1);
00618 cpl_propertylist_delete(plist2);
00619 return -1;
00620 }
00621 if (ival1 != ival2) comparison = 0;
00622
00623
00624 ival1 = sofi_pfits_get_rom(plist1);
00625 ival2 = sofi_pfits_get_rom(plist2);
00626 if (cpl_error_get_code()) {
00627 cpl_msg_error(cpl_func, "cannot get read-out mode");
00628 cpl_propertylist_delete(plist1);
00629 cpl_propertylist_delete(plist2);
00630 return -1;
00631 }
00632 if (ival1 != ival2) comparison = 0;
00633
00634
00635 cpl_propertylist_delete(plist1);
00636 cpl_propertylist_delete(plist2);
00637 return comparison;
00638 }
00639