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 "isaac_utils.h"
00042 #include "isaac_pfits.h"
00043 #include "isaac_dfs.h"
00044 #include "isaac_fit.h"
00045
00046
00047
00048
00049
00050 static int isaac_img_detlin_create(cpl_plugin *);
00051 static int isaac_img_detlin_exec(cpl_plugin *);
00052 static int isaac_img_detlin_destroy(cpl_plugin *);
00053 static int isaac_img_detlin(cpl_parameterlist *, cpl_frameset *);
00054
00055 static cpl_imagelist * isaac_img_detlin_load(cpl_frameset *, cpl_frameset *,
00056 double **);
00057 static int isaac_img_detlin_save(cpl_imagelist *, cpl_parameterlist *,
00058 cpl_frameset *);
00059
00060
00061
00062
00063
00064 static struct {
00065
00066 int force_flag;
00067
00068
00069 double lamp_stability;
00070 } isaac_img_detlin_config;
00071
00072 static char isaac_img_detlin_description[] =
00073 "isaac_img_detlin -- ISAAC imaging detector linearity recipe.\n"
00074 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00075 "raw-file.fits "ISAAC_IMG_DETLIN_LAMP_RAW" or\n"
00076 "raw-file.fits "ISAAC_IMG_DETLIN_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 ISAAC_BINARY_VERSION,
00099 CPL_PLUGIN_TYPE_RECIPE,
00100 "isaac_img_detlin",
00101 "Detector linearity recipe",
00102 isaac_img_detlin_description,
00103 "Lars Lundin",
00104 PACKAGE_BUGREPORT,
00105 isaac_get_license(),
00106 isaac_img_detlin_create,
00107 isaac_img_detlin_exec,
00108 isaac_img_detlin_destroy);
00109
00110 cpl_pluginlist_append(list, plugin);
00111
00112 return 0;
00113 }
00114
00115
00124
00125 static int isaac_img_detlin_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("isaac.isaac_img_detlin.force", CPL_TYPE_BOOL,
00141 "flag to force th computation", "isaac.isaac_img_detlin",
00142 FALSE);
00143 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "force");
00144 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00145 cpl_parameterlist_append(recipe->parameters, p);
00146
00147
00148 return 0;
00149 }
00150
00151
00157
00158 static int isaac_img_detlin_exec(cpl_plugin * plugin)
00159 {
00160 cpl_recipe * recipe;
00161
00162
00163 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00164 recipe = (cpl_recipe *)plugin;
00165 else return -1;
00166
00167 return isaac_img_detlin(recipe->parameters, recipe->frames);
00168 }
00169
00170
00176
00177 static int isaac_img_detlin_destroy(cpl_plugin * plugin)
00178 {
00179 cpl_recipe * recipe;
00180
00181
00182 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00183 recipe = (cpl_recipe *)plugin;
00184 else return -1;
00185
00186 cpl_parameterlist_delete(recipe->parameters);
00187 return 0;
00188 }
00189
00190
00197
00198 static int isaac_img_detlin(
00199 cpl_parameterlist * parlist,
00200 cpl_frameset * framelist)
00201 {
00202 cpl_parameter * par;
00203 cpl_frameset * darkframes;
00204 cpl_frameset * lampframes;
00205 cpl_imagelist * iset;
00206 double * ditval;
00207 cpl_imagelist * fitres;
00208
00209
00210 par = NULL;
00211
00212
00213
00214 par = cpl_parameterlist_find(parlist, "isaac.isaac_img_detlin.force");
00215 isaac_img_detlin_config.force_flag = cpl_parameter_get_bool(par);
00216
00217
00218 if (isaac_dfs_set_groups(framelist)) {
00219 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
00220 return -1;
00221 }
00222
00223
00224 if ((lampframes = isaac_extract_frameset(framelist,
00225 ISAAC_IMG_DETLIN_LAMP_RAW)) == NULL) {
00226 cpl_msg_error(cpl_func, "Cannot find any lamp frame in input");
00227 return -1;
00228 }
00229 if ((darkframes = isaac_extract_frameset(framelist,
00230 ISAAC_IMG_DETLIN_DARK_RAW)) == NULL) {
00231 cpl_msg_error(cpl_func, "Cannot find any dark frame in input");
00232 cpl_frameset_delete(lampframes);
00233 return -1;
00234 }
00235
00236
00237 cpl_msg_info(cpl_func, "Load the data");
00238 cpl_msg_indent_more();
00239 if ((iset = isaac_img_detlin_load(lampframes, darkframes, &ditval))==NULL) {
00240 cpl_msg_error(cpl_func, "Cannot load the data");
00241 cpl_frameset_delete(lampframes);
00242 cpl_frameset_delete(darkframes);
00243 cpl_msg_indent_less();
00244 return -1;
00245 }
00246 cpl_frameset_delete(lampframes);
00247 cpl_frameset_delete(darkframes);
00248 cpl_msg_indent_less();
00249
00250
00251 cpl_msg_info(cpl_func, "Compute the linearity coefficients");
00252 cpl_msg_indent_more();
00253 if ((fitres = isaac_imagelist_fit_polynomial(iset, ditval, 3)) == NULL) {
00254 cpl_msg_error(cpl_func, "Cannot compute the linearity coefficients");
00255 cpl_imagelist_delete(iset);
00256 cpl_free(ditval);
00257 cpl_msg_indent_less();
00258 return -1;
00259 }
00260 cpl_msg_indent_less();
00261 cpl_free(ditval);
00262 cpl_imagelist_delete(iset);
00263
00264
00265 cpl_msg_info(cpl_func, "Save the products");
00266 cpl_msg_indent_more();
00267 if (isaac_img_detlin_save(fitres, parlist, framelist)==-1) {
00268 cpl_msg_error(cpl_func, "Cannot save the products");
00269 cpl_imagelist_delete(fitres);
00270 cpl_msg_indent_less();
00271 return -1;
00272 }
00273 cpl_msg_indent_less();
00274
00275
00276 cpl_imagelist_delete(fitres);
00277 return 0;
00278 }
00279
00280
00288
00289 static cpl_imagelist * isaac_img_detlin_load(
00290 cpl_frameset * lamps,
00291 cpl_frameset * darks,
00292 double ** ditvals)
00293 {
00294 int nb_lamps;
00295 cpl_vector * selection;
00296 cpl_frame * frame;
00297 cpl_propertylist * propertylist;
00298 double dit_lamp, dit_dark;
00299 int dit_stab;
00300 cpl_imagelist * lamps_data;
00301 cpl_imagelist * darks_data;
00302 double * stab_levels;
00303 double * dit_purged;
00304 int i, j;
00305
00306
00307 if ((nb_lamps = cpl_frameset_get_size(lamps)) < 3) return NULL;
00308 if (cpl_frameset_get_size(darks) != nb_lamps) return NULL;
00309
00310
00311 cpl_msg_info(cpl_func, "Checking DIT consistency");
00312 selection = cpl_vector_new(nb_lamps);
00313 *ditvals = cpl_malloc(nb_lamps * sizeof(double));
00314 dit_stab = 0;
00315 for (i=0; i<nb_lamps; i++) {
00316
00317 if (cpl_error_get_code()) {
00318 cpl_vector_delete(selection);
00319 cpl_free(*ditvals);
00320 return NULL;
00321 }
00322
00323 frame = cpl_frameset_get_frame(lamps, i);
00324 propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
00325 dit_lamp = (double)isaac_pfits_get_dit(propertylist);
00326 cpl_propertylist_delete(propertylist);
00327 if (cpl_error_get_code()) {
00328 cpl_msg_error(cpl_func, "Cannot get DIT");
00329 cpl_vector_delete(selection);
00330 cpl_free(*ditvals);
00331 return NULL;
00332 }
00333
00334 frame = cpl_frameset_get_frame(darks, i);
00335 propertylist=cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
00336 dit_dark = (double)isaac_pfits_get_dit(propertylist);
00337 cpl_propertylist_delete(propertylist);
00338 if (cpl_error_get_code()) {
00339 cpl_msg_error(cpl_func, "Cannot get DIT");
00340 cpl_vector_delete(selection);
00341 cpl_free(*ditvals);
00342 return NULL;
00343 }
00344
00345 if (fabs(dit_dark-dit_lamp) > 1e-3) {
00346 cpl_msg_error(cpl_func, "DIT not consistent between LAMP and DARK");
00347 cpl_vector_delete(selection);
00348 cpl_free(*ditvals);
00349 return NULL;
00350 }
00351 (*ditvals)[i] = dit_lamp;
00352
00353 if (i==0) {
00354 cpl_vector_set(selection, i, -1.0);
00355 dit_stab ++;
00356 } else {
00357 if (fabs(dit_lamp - (*ditvals)[0]) < 1e-5) {
00358 cpl_vector_set(selection, i, -1.0);
00359 dit_stab ++;
00360 } else {
00361 cpl_vector_set(selection, i, 1.0);
00362 }
00363 }
00364 }
00365
00366
00367 if (dit_stab < 2) {
00368 cpl_msg_error(cpl_func, "Not enough frames for stability check");
00369 cpl_vector_delete(selection);
00370 cpl_free(*ditvals);
00371 return NULL;
00372 }
00373
00374
00375 cpl_msg_info(cpl_func, "Compute the differences lamp - dark");
00376 lamps_data = cpl_imagelist_load_frameset(lamps, CPL_TYPE_FLOAT, 1, 0);
00377 darks_data = cpl_imagelist_load_frameset(darks, CPL_TYPE_FLOAT, 1, 0);
00378 if (cpl_imagelist_subtract(lamps_data,darks_data) != CPL_ERROR_NONE) {
00379 cpl_msg_error(cpl_func, "Cannot subtract the 2 image lists");
00380 cpl_vector_delete(selection);
00381 cpl_free(*ditvals);
00382 if (lamps_data) cpl_imagelist_delete(lamps_data);
00383 if (darks_data) cpl_imagelist_delete(darks_data);
00384 return NULL;
00385 }
00386 cpl_imagelist_delete(darks_data);
00387
00388
00389 cpl_msg_info(cpl_func, "Check the lamp stability");
00390 stab_levels = cpl_malloc(dit_stab * sizeof(double));
00391 j = 0;
00392 for (i=0; i<nb_lamps; i++) {
00393 if (cpl_vector_get(selection, i) < 0) {
00394 stab_levels[j] =
00395 cpl_image_get_mean(cpl_imagelist_get(lamps_data, i));
00396 j++;
00397 }
00398 }
00399
00400
00401 isaac_img_detlin_config.lamp_stability = 0.0;
00402 for (i=1; i<dit_stab; i++) {
00403 if ((fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0]) >
00404 isaac_img_detlin_config.lamp_stability)
00405 isaac_img_detlin_config.lamp_stability =
00406 fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0];
00407 }
00408 cpl_free(stab_levels);
00409
00410
00411 if (isaac_img_detlin_config.lamp_stability > 0.01) {
00412 if (isaac_img_detlin_config.force_flag == 1) {
00413 cpl_msg_warning(cpl_func,
00414 "level difference #%d too high - proceed anyway",i+1);
00415 } else {
00416 cpl_msg_error(cpl_func, "level difference #%d too high", i+1);
00417 cpl_vector_delete(selection);
00418 cpl_free(*ditvals);
00419 cpl_imagelist_delete(lamps_data);
00420 return NULL;
00421 }
00422 }
00423
00424
00425 if (cpl_imagelist_erase(lamps_data, selection) != CPL_ERROR_NONE) {
00426 cpl_msg_error(cpl_func, "cannot discard stability frames");
00427 cpl_vector_delete(selection);
00428 cpl_free(*ditvals);
00429 cpl_imagelist_delete(lamps_data);
00430 return NULL;
00431 }
00432 dit_purged = cpl_malloc(cpl_imagelist_get_size(lamps_data)*sizeof(double));
00433 j = 0;
00434 for (i=0; i<nb_lamps; i++) {
00435 if (cpl_vector_get(selection, i) > 0) {
00436 dit_purged[j] = (*ditvals)[i];
00437 j++;
00438 }
00439 }
00440 cpl_free(*ditvals);
00441 *ditvals = dit_purged;
00442
00443
00444 cpl_vector_delete(selection);
00445 return lamps_data;
00446 }
00447
00448
00456
00457 static int isaac_img_detlin_save(
00458 cpl_imagelist * fitres,
00459 cpl_parameterlist * parlist,
00460 cpl_frameset * set)
00461 {
00462 const cpl_frame * ref_frame;
00463 cpl_propertylist * plist;
00464 cpl_propertylist * qclist;
00465 cpl_propertylist * paflist;
00466 double qc_meda, qc_medb, qc_medc, qc_medq;
00467
00468
00469 qc_meda = cpl_image_get_median(cpl_imagelist_get(fitres, 0));
00470 qc_medb = cpl_image_get_median(cpl_imagelist_get(fitres, 1));
00471 qc_medc = cpl_image_get_median(cpl_imagelist_get(fitres, 2));
00472 qc_medq = cpl_image_get_median(cpl_imagelist_get(fitres, 3));
00473
00474
00475 qclist = cpl_propertylist_new();
00476 cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDA", qc_meda);
00477 cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDB", qc_medb);
00478 cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDC", qc_medc);
00479 cpl_propertylist_append_double(qclist, "ESO QC DETLIN MEDQ", qc_medq);
00480 cpl_propertylist_append_double(qclist, "ESO QC DETLIN LAMP",
00481 isaac_img_detlin_config.lamp_stability );
00482
00483
00484 irplib_dfs_save_image(set,
00485 parlist,
00486 set,
00487 cpl_imagelist_get(fitres, 0),
00488 CPL_BPP_IEEE_FLOAT,
00489 "isaac_img_detlin",
00490 ISAAC_IMG_DETLIN_A,
00491 qclist,
00492 NULL,
00493 PACKAGE "/" PACKAGE_VERSION,
00494 "isaac_img_detlin_A.fits");
00495
00496
00497 irplib_dfs_save_image(set,
00498 parlist,
00499 set,
00500 cpl_imagelist_get(fitres, 1),
00501 CPL_BPP_IEEE_FLOAT,
00502 "isaac_img_detlin",
00503 ISAAC_IMG_DETLIN_B,
00504 qclist,
00505 NULL,
00506 PACKAGE "/" PACKAGE_VERSION,
00507 "isaac_img_detlin_B.fits");
00508
00509
00510 irplib_dfs_save_image(set,
00511 parlist,
00512 set,
00513 cpl_imagelist_get(fitres, 2),
00514 CPL_BPP_IEEE_FLOAT,
00515 "isaac_img_detlin",
00516 ISAAC_IMG_DETLIN_C,
00517 qclist,
00518 NULL,
00519 PACKAGE "/" PACKAGE_VERSION,
00520 "isaac_img_detlin_C.fits");
00521
00522
00523 irplib_dfs_save_image(set,
00524 parlist,
00525 set,
00526 cpl_imagelist_get(fitres, 3),
00527 CPL_BPP_IEEE_FLOAT,
00528 "isaac_img_detlin",
00529 ISAAC_IMG_DETLIN_Q,
00530 qclist,
00531 NULL,
00532 PACKAGE "/" PACKAGE_VERSION,
00533 "isaac_img_detlin_Q.fits");
00534
00535
00536 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00537
00538
00539 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00540 0)) == NULL) {
00541 cpl_msg_error(cpl_func, "getting header from reference frame");
00542 cpl_propertylist_delete(qclist);
00543 return -1;
00544 }
00545
00546
00547 paflist = cpl_propertylist_new();
00548 cpl_propertylist_copy_property_regexp(paflist, plist,
00549 "^(ARCFILE|MJD-OBS|ESO TPL ID|DATE-OBS|ESO DET DIT|"
00550 "ESO DET NDIT|ESO DET NCORRS|ESO DET MODE NAME)$", 0);
00551 cpl_propertylist_delete(plist);
00552
00553
00554 cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0);
00555 cpl_propertylist_delete(qclist);
00556
00557
00558 cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG,
00559 ISAAC_IMG_DETLIN_A);
00560
00561
00562 cpl_dfs_save_paf("ISAAC",
00563 "isaac_img_detlin",
00564 paflist,
00565 "isaac_img_detlin_QC.paf");
00566 cpl_propertylist_delete(paflist);
00567 return 0;
00568 }
00569