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 <math.h>
00037 #include <cpl.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_detlin_create(cpl_plugin *) ;
00050 static int sofi_img_detlin_exec(cpl_plugin *) ;
00051 static int sofi_img_detlin_destroy(cpl_plugin *) ;
00052 static int sofi_img_detlin(cpl_parameterlist *, cpl_frameset *) ;
00053
00054 static cpl_imagelist * sofi_img_detlin_load(cpl_frameset *, cpl_frameset *,
00055 cpl_vector **) ;
00056 static int sofi_img_detlin_save(cpl_imagelist *, cpl_parameterlist *,
00057 cpl_frameset *) ;
00058
00059
00060
00061
00062
00063 static struct {
00064
00065 int force_flag ;
00066
00067
00068 double lamp_stability ;
00069 } sofi_img_detlin_config ;
00070
00071 static char sofi_img_detlin_description[] =
00072 "sofi_img_detlin -- SOFI imaging detector linearity recipe.\n"
00073 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00074 "raw-file.fits "SOFI_IMG_DETLIN_LAMP_RAW" or\n"
00075 "raw-file.fits "SOFI_IMG_DETLIN_DARK_RAW"\n";
00076
00077
00078
00079
00080
00081
00089
00090 int cpl_plugin_get_info(cpl_pluginlist * list)
00091 {
00092 cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ;
00093 cpl_plugin * plugin = &recipe->interface ;
00094
00095 cpl_plugin_init(plugin,
00096 CPL_PLUGIN_API,
00097 SOFI_BINARY_VERSION,
00098 CPL_PLUGIN_TYPE_RECIPE,
00099 "sofi_img_detlin",
00100 "Detector linearity recipe",
00101 sofi_img_detlin_description,
00102 "Yves Jung",
00103 "yjung@eso.org",
00104 sofi_get_license(),
00105 sofi_img_detlin_create,
00106 sofi_img_detlin_exec,
00107 sofi_img_detlin_destroy) ;
00108
00109 cpl_pluginlist_append(list, plugin) ;
00110
00111 return 0;
00112 }
00113
00114
00123
00124 static int sofi_img_detlin_create(cpl_plugin * plugin)
00125 {
00126 cpl_recipe * recipe ;
00127 cpl_parameter * p ;
00128
00129
00130 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00131 recipe = (cpl_recipe *)plugin ;
00132 else return -1 ;
00133
00134
00135 recipe->parameters = cpl_parameterlist_new() ;
00136
00137
00138
00139 p = cpl_parameter_new_value("sofi.sofi_img_detlin.force", CPL_TYPE_BOOL,
00140 "flag to force th computation", "sofi.sofi_img_detlin",
00141 FALSE) ;
00142 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "force") ;
00143 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV) ;
00144 cpl_parameterlist_append(recipe->parameters, p) ;
00145
00146
00147 return 0;
00148 }
00149
00150
00156
00157 static int sofi_img_detlin_exec(cpl_plugin * plugin)
00158 {
00159 cpl_recipe * recipe ;
00160
00161
00162 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00163 recipe = (cpl_recipe *)plugin ;
00164 else return -1 ;
00165
00166 return sofi_img_detlin(recipe->parameters, recipe->frames) ;
00167 }
00168
00169
00175
00176 static int sofi_img_detlin_destroy(cpl_plugin * plugin)
00177 {
00178 cpl_recipe * recipe ;
00179
00180
00181 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00182 recipe = (cpl_recipe *)plugin ;
00183 else return -1 ;
00184
00185 cpl_parameterlist_delete(recipe->parameters) ;
00186 return 0 ;
00187 }
00188
00189
00196
00197 static int sofi_img_detlin(
00198 cpl_parameterlist * parlist,
00199 cpl_frameset * framelist)
00200 {
00201 cpl_parameter * par ;
00202 cpl_frameset * darkframes ;
00203 cpl_frameset * lampframes ;
00204 cpl_imagelist * iset ;
00205 cpl_vector * ditval ;
00206 cpl_imagelist * fitres ;
00207 cpl_image * error_im ;
00208 int degree ;
00209
00210
00211 par = NULL ;
00212 degree = 2 ;
00213
00214
00215
00216 par = cpl_parameterlist_find(parlist, "sofi.sofi_img_detlin.force") ;
00217 sofi_img_detlin_config.force_flag = cpl_parameter_get_bool(par) ;
00218
00219
00220 if (sofi_dfs_set_groups(framelist)) {
00221 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames") ;
00222 return -1 ;
00223 }
00224
00225
00226 if ((lampframes = sofi_extract_frameset(framelist,
00227 SOFI_IMG_DETLIN_LAMP_RAW)) == NULL) {
00228 cpl_msg_error(cpl_func, "Cannot find any lamp frame in input");
00229 return -1 ;
00230 }
00231 if ((darkframes = sofi_extract_frameset(framelist,
00232 SOFI_IMG_DETLIN_DARK_RAW)) == NULL) {
00233 cpl_msg_error(cpl_func, "Cannot find any dark frame in input");
00234 cpl_frameset_delete(lampframes) ;
00235 return -1 ;
00236 }
00237
00238
00239 cpl_msg_info(cpl_func, "Load the data") ;
00240 cpl_msg_indent_more() ;
00241 if ((iset = sofi_img_detlin_load(lampframes, darkframes, &ditval))==NULL) {
00242 cpl_msg_error(cpl_func, "Cannot load the data") ;
00243 cpl_frameset_delete(lampframes) ;
00244 cpl_frameset_delete(darkframes) ;
00245 cpl_msg_indent_less() ;
00246 return -1 ;
00247 }
00248 cpl_frameset_delete(lampframes) ;
00249 cpl_frameset_delete(darkframes) ;
00250 cpl_msg_indent_less() ;
00251
00252
00253 error_im = cpl_image_duplicate(cpl_imagelist_get(iset, 0)) ;
00254
00255
00256 cpl_msg_info(cpl_func, "Compute the linearity coefficients") ;
00257 cpl_msg_indent_more() ;
00258 if ((fitres = cpl_fit_imagelist_polynomial(ditval, iset, 0, degree,
00259 CPL_FALSE, CPL_TYPE_FLOAT, error_im)) == NULL) {
00260 cpl_msg_error(cpl_func, "Cannot compute the linearity coefficients") ;
00261 cpl_imagelist_delete(iset) ;
00262 cpl_vector_delete(ditval) ;
00263 cpl_image_delete(error_im) ;
00264 cpl_msg_indent_less() ;
00265 return -1 ;
00266 }
00267 cpl_msg_indent_less() ;
00268 cpl_vector_delete(ditval) ;
00269 cpl_imagelist_delete(iset) ;
00270
00271
00272 cpl_imagelist_set(fitres, error_im, degree+1) ;
00273
00274
00275 cpl_msg_info(cpl_func, "Save the products") ;
00276 cpl_msg_indent_more() ;
00277 if (sofi_img_detlin_save(fitres, parlist, framelist)==-1) {
00278 cpl_msg_error(cpl_func, "Cannot save the products") ;
00279 cpl_imagelist_delete(fitres) ;
00280 cpl_msg_indent_less() ;
00281 return -1 ;
00282 }
00283 cpl_msg_indent_less() ;
00284
00285
00286 cpl_imagelist_delete(fitres) ;
00287 return 0 ;
00288 }
00289
00290
00298
00299 static cpl_imagelist * sofi_img_detlin_load(
00300 cpl_frameset * lamps,
00301 cpl_frameset * darks,
00302 cpl_vector ** ditvals)
00303 {
00304 int nb_lamps ;
00305 cpl_vector * selection ;
00306 cpl_frame * frame ;
00307 cpl_propertylist * propertylist ;
00308 double dit_lamp, dit_dark ;
00309 int dit_stab ;
00310 cpl_imagelist * lamps_data ;
00311 cpl_imagelist * darks_data ;
00312 double * stab_levels ;
00313 cpl_vector * dit_purged ;
00314 double * pditvals ;
00315 double * pdit_purged ;
00316 int i, j ;
00317
00318
00319 if ((nb_lamps = cpl_frameset_get_size(lamps)) < 3) return NULL ;
00320 if (cpl_frameset_get_size(darks) != nb_lamps) return NULL ;
00321
00322
00323 cpl_msg_info(cpl_func, "Checking DIT consistency") ;
00324 selection = cpl_vector_new(nb_lamps) ;
00325 *ditvals = cpl_vector_new(nb_lamps) ;
00326 pditvals = cpl_vector_get_data(*ditvals) ;
00327 dit_stab = 0 ;
00328 for (i=0 ; i<nb_lamps ; i++) {
00329
00330 if (cpl_error_get_code()) {
00331 cpl_vector_delete(selection) ;
00332 cpl_vector_delete(*ditvals) ;
00333 return NULL ;
00334 }
00335
00336 frame = cpl_frameset_get_frame(lamps, i) ;
00337 propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0) ;
00338 dit_lamp = (double)sofi_pfits_get_dit(propertylist) ;
00339 cpl_propertylist_delete(propertylist) ;
00340 if (cpl_error_get_code()) {
00341 cpl_msg_error(cpl_func, "Cannot get DIT") ;
00342 cpl_vector_delete(selection) ;
00343 cpl_vector_delete(*ditvals) ;
00344 return NULL ;
00345 }
00346
00347 frame = cpl_frameset_get_frame(darks, i) ;
00348 propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0) ;
00349 dit_dark = (double)sofi_pfits_get_dit(propertylist) ;
00350 cpl_propertylist_delete(propertylist) ;
00351 if (cpl_error_get_code()) {
00352 cpl_msg_error(cpl_func, "Cannot get DIT") ;
00353 cpl_vector_delete(selection) ;
00354 cpl_vector_delete(*ditvals) ;
00355 return NULL ;
00356 }
00357
00358 if (fabs(dit_dark-dit_lamp) > 1e-3) {
00359 cpl_msg_error(cpl_func, "DIT not consistent between LAMP and DARK");
00360 cpl_vector_delete(selection) ;
00361 cpl_vector_delete(*ditvals) ;
00362 return NULL ;
00363 }
00364 pditvals[i] = dit_lamp ;
00365
00366 if (i==0) {
00367 cpl_vector_set(selection, i, -1.0) ;
00368 dit_stab ++ ;
00369 } else {
00370 if (fabs(dit_lamp - pditvals[0]) < 1e-5) {
00371 cpl_vector_set(selection, i, -1.0) ;
00372 dit_stab ++ ;
00373 } else {
00374 cpl_vector_set(selection, i, 1.0) ;
00375 }
00376 }
00377 }
00378
00379
00380 if (dit_stab < 2) {
00381 cpl_msg_error(cpl_func, "Not enough frames for stability check") ;
00382 cpl_vector_delete(selection) ;
00383 cpl_vector_delete(*ditvals) ;
00384 return NULL ;
00385 }
00386
00387
00388 cpl_msg_info(cpl_func, "Compute the differences lamp - dark") ;
00389 lamps_data = cpl_imagelist_load_frameset(lamps, CPL_TYPE_FLOAT, 1, 0) ;
00390 darks_data = cpl_imagelist_load_frameset(darks, CPL_TYPE_FLOAT, 1, 0) ;
00391 if (cpl_imagelist_subtract(lamps_data,darks_data) != CPL_ERROR_NONE) {
00392 cpl_msg_error(cpl_func, "Cannot subtract the 2 image lists") ;
00393 cpl_vector_delete(selection) ;
00394 cpl_vector_delete(*ditvals) ;
00395 if (lamps_data) cpl_imagelist_delete(lamps_data) ;
00396 if (darks_data) cpl_imagelist_delete(darks_data) ;
00397 return NULL ;
00398 }
00399 cpl_imagelist_delete(darks_data) ;
00400
00401
00402 cpl_msg_info(cpl_func, "Check the lamp stability") ;
00403 stab_levels = cpl_malloc(dit_stab * sizeof(double)) ;
00404 j = 0 ;
00405 for (i=0 ; i<nb_lamps ; i++) {
00406 if (cpl_vector_get(selection, i) < 0) {
00407 stab_levels[j] =
00408 cpl_image_get_mean(cpl_imagelist_get(lamps_data, i)) ;
00409 j++ ;
00410 }
00411 }
00412
00413
00414 sofi_img_detlin_config.lamp_stability = 0.0 ;
00415 for (i=1 ; i<dit_stab ; i++) {
00416 if ((fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0]) >
00417 sofi_img_detlin_config.lamp_stability)
00418 sofi_img_detlin_config.lamp_stability =
00419 fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0] ;
00420 }
00421 cpl_free(stab_levels) ;
00422
00423
00424 if (sofi_img_detlin_config.lamp_stability > 0.01) {
00425 if (sofi_img_detlin_config.force_flag == 1) {
00426 cpl_msg_warning(cpl_func,
00427 "level difference #%d too high - proceed anyway",i+1);
00428 } else {
00429 cpl_msg_error(cpl_func, "level difference #%d too high", i+1);
00430 cpl_vector_delete(selection) ;
00431 cpl_vector_delete(*ditvals) ;
00432 cpl_imagelist_delete(lamps_data) ;
00433 return NULL ;
00434 }
00435 }
00436
00437
00438 if (cpl_imagelist_erase(lamps_data, selection) != CPL_ERROR_NONE) {
00439 cpl_msg_error(cpl_func, "cannot discard stability frames") ;
00440 cpl_vector_delete(selection) ;
00441 cpl_vector_delete(*ditvals) ;
00442 cpl_imagelist_delete(lamps_data) ;
00443 return NULL ;
00444 }
00445 dit_purged = cpl_vector_new(cpl_imagelist_get_size(lamps_data)) ;
00446 pdit_purged = cpl_vector_get_data(dit_purged) ;
00447 j = 0 ;
00448 for (i=0 ; i<nb_lamps ; i++) {
00449 if (cpl_vector_get(selection, i) > 0) {
00450 pdit_purged[j] = pditvals[i] ;
00451 j++ ;
00452 }
00453 }
00454 cpl_vector_delete(*ditvals) ;
00455 *ditvals = dit_purged ;
00456
00457
00458 cpl_vector_delete(selection) ;
00459 return lamps_data ;
00460 }
00461
00462
00470
00471 static int sofi_img_detlin_save(
00472 cpl_imagelist * fitres,
00473 cpl_parameterlist * parlist,
00474 cpl_frameset * set)
00475 {
00476 const cpl_frame * ref_frame;
00477 cpl_propertylist * plist ;
00478 cpl_propertylist * qclist ;
00479 cpl_propertylist * paflist ;
00480 double qc_meda, qc_medb, qc_medc, qc_medq ;
00481
00482
00483 qc_meda = cpl_image_get_median(cpl_imagelist_get(fitres, 0)) ;
00484 qc_medb = cpl_image_get_median(cpl_imagelist_get(fitres, 1)) ;
00485 qc_medc = cpl_image_get_median(cpl_imagelist_get(fitres, 2)) ;
00486 qc_medq = cpl_image_get_median(cpl_imagelist_get(fitres, 3)) ;
00487
00488
00489 qclist = cpl_propertylist_new() ;
00490 cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDA", qc_meda) ;
00491 cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDB", qc_medb) ;
00492 cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDC", qc_medc) ;
00493 cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDQ", qc_medq) ;
00494 cpl_propertylist_append_double(qclist, "ESO QC DETLIN LAMP",
00495 sofi_img_detlin_config.lamp_stability ) ;
00496
00497
00498 irplib_dfs_save_image(set,
00499 parlist,
00500 set,
00501 cpl_imagelist_get(fitres, 0),
00502 CPL_BPP_IEEE_FLOAT,
00503 "sofi_img_detlin",
00504 SOFI_IMG_DETLIN_A,
00505 qclist,
00506 NULL,
00507 PACKAGE "/" PACKAGE_VERSION,
00508 "sofi_img_detlin_A.fits") ;
00509
00510
00511 irplib_dfs_save_image(set,
00512 parlist,
00513 set,
00514 cpl_imagelist_get(fitres, 1),
00515 CPL_BPP_IEEE_FLOAT,
00516 "sofi_img_detlin",
00517 SOFI_IMG_DETLIN_B,
00518 qclist,
00519 NULL,
00520 PACKAGE "/" PACKAGE_VERSION,
00521 "sofi_img_detlin_B.fits") ;
00522
00523
00524 irplib_dfs_save_image(set,
00525 parlist,
00526 set,
00527 cpl_imagelist_get(fitres, 2),
00528 CPL_BPP_IEEE_FLOAT,
00529 "sofi_img_detlin",
00530 SOFI_IMG_DETLIN_C,
00531 qclist,
00532 NULL,
00533 PACKAGE "/" PACKAGE_VERSION,
00534 "sofi_img_detlin_C.fits") ;
00535
00536
00537 irplib_dfs_save_image(set,
00538 parlist,
00539 set,
00540 cpl_imagelist_get(fitres, 3),
00541 CPL_BPP_IEEE_FLOAT,
00542 "sofi_img_detlin",
00543 SOFI_IMG_DETLIN_Q,
00544 qclist,
00545 NULL,
00546 PACKAGE "/" PACKAGE_VERSION,
00547 "sofi_img_detlin_Q.fits") ;
00548
00549
00550 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW) ;
00551
00552
00553 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00554 0)) == NULL) {
00555 cpl_msg_error(cpl_func, "getting header from reference frame");
00556 cpl_propertylist_delete(qclist) ;
00557 return -1 ;
00558 }
00559
00560
00561 paflist = cpl_propertylist_new() ;
00562 cpl_propertylist_copy_property_regexp(paflist, plist,
00563 "^(ARCFILE|MJD-OBS|ESO TPL ID|DATE-OBS|ESO DET DIT|"
00564 "ESO DET NDIT|ESO DET NCORRS|ESO DET MODE NAME)$", 0) ;
00565 cpl_propertylist_delete(plist) ;
00566
00567
00568 cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0) ;
00569 cpl_propertylist_delete(qclist) ;
00570
00571
00572 cpl_dfs_save_paf("SOFI",
00573 "sofi_img_detlin",
00574 paflist,
00575 "sofi_img_detlin_QC.paf") ;
00576 cpl_propertylist_delete(paflist) ;
00577 return 0;
00578 }
00579