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 <string.h>
00037 #include <math.h>
00038 #include <float.h>
00039 #include <cpl.h>
00040
00041 #include "irplib_plugin.h"
00042 #include "irplib_utils.h"
00043 #include "irplib_distortion.h"
00044
00045 #include "isaac_utils.h"
00046 #include "isaac_wavelength.h"
00047 #include "isaac_physicalmodel.h"
00048 #include "isaac_pfits.h"
00049 #include "isaac_dfs.h"
00050
00051
00052
00053
00054
00055 #define RECIPE_STRING "isaac_spc_arc"
00056
00057 #define ISAAC_ARC_SATURATION 20000
00058
00059
00060
00061
00062
00063 static int isaac_spc_arc_reduce_sw(cpl_frameset *, const cpl_parameterlist *,
00064 const char *, const char *, cpl_frameset *);
00065 static int isaac_spc_arc_reduce_lw(cpl_frameset *, const cpl_parameterlist *,
00066 const char *, const char *, cpl_frameset *);
00067 static cpl_table * isaac_spc_arc_compute(const cpl_image *, const char *,
00068 const char *, const char *, const char *, cpl_table **, cpl_image **);
00069 static int isaac_spc_arc_save(const cpl_table *, const cpl_table *,
00070 const cpl_image *, const char *, cpl_frameset *,
00071 const cpl_parameterlist *, cpl_frameset *);
00072 static int isaac_spc_arc_compare(const cpl_frame *, const cpl_frame *);
00073 static int * isaac_spc_arc_find_lamps(cpl_frameset *);
00074 static int isaac_is_xenon_lamp_active(const cpl_propertylist *);
00075 static int isaac_is_argon_lamp_active(const cpl_propertylist *);
00076
00077
00078 cpl_recipe_define(isaac_spc_arc, ISAAC_BINARY_VERSION,
00079 "Lars Lundin", PACKAGE_BUGREPORT, "2002, 2003, 2008",
00080 "ISAAC Spectro arc recipe",
00081 RECIPE_STRING " -- ISAAC Spectro arc recipe\n"
00082 "The files listed in the Set Of Frames (sof-file) "
00083 "must be tagged:\n"
00084 "raw-file.fits "ISAAC_SPC_ARC_RAW" or\n"
00085 "xe-cat.fits "ISAAC_CALPRO_XE_CAT" or\n"
00086 "ar-cat.fits "ISAAC_CALPRO_AR_CAT"\n");
00087
00088
00089
00090
00091
00092
00093 static struct {
00094
00095 int rej_left;
00096 int rej_right;
00097 int rej_bottom;
00098 int rej_top;
00099 int sub_dark;
00100 int arc_max_width;
00101 int max_offset;
00102 double arc_kappa;
00103 int out_corr;
00104
00105 int set_nb;
00106 int pair_nb;
00107 int nb_saturated;
00108 int arm;
00109 char resol;
00110 double disprel_cc;
00111 int disprel_clines;
00112 int disprel_dlines;
00113 double disprel_rms;
00114 double disprel_offset;
00115 double fwhm_med;
00116 int fwhm_good;
00117 } isaac_spc_arc_config;
00118
00119
00120
00121
00122
00123
00131
00132 static
00133 cpl_error_code isaac_spc_arc_fill_parameterlist(cpl_parameterlist * self)
00134 {
00135 const char * context = PACKAGE "." RECIPE_STRING;
00136 cpl_error_code err;
00137
00138 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
00139
00140
00141
00142
00143 err = irplib_parameterlist_set_string(self, PACKAGE, RECIPE_STRING,
00144 "rejected", "-1,-1,100,100", "rej",
00145 context,
00146 "left right bottom top rejections");
00147 cpl_ensure_code(!err, err);
00148
00149
00150 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00151 "subdark", CPL_FALSE, NULL, context,
00152 "Flag to subtract the dark");
00153 cpl_ensure_code(!err, err);
00154
00155
00156 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00157 "arc_max_w", 33, NULL, context,
00158 "Maximum arc width allowed in pixels");
00159 cpl_ensure_code(!err, err);
00160
00161
00162 err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00163 "max_offset", 50, NULL, context,
00164 "Maximum offset from the physical "
00165 "model allowed in pixels");
00166 cpl_ensure_code(!err, err);
00167
00168
00169 err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING,
00170 "arc_kappa", 0.33, NULL, context,
00171 "kappa for the threshold used for "
00172 "arcs detection");
00173 cpl_ensure_code(!err, err);
00174
00175
00176 err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00177 "out_corr", CPL_FALSE, NULL, context,
00178 "Flag to output corrected images");
00179 cpl_ensure_code(!err, err);
00180
00181 return CPL_ERROR_NONE;
00182 }
00183
00184
00191
00192 static int isaac_spc_arc(cpl_frameset * framelist,
00193 const cpl_parameterlist * parlist)
00194 {
00195 const char * sval;
00196 cpl_size * labels = NULL;
00197 cpl_size nlabels = 0;
00198 const char * xe;
00199 const char * ar;
00200 cpl_propertylist * plist = NULL;
00201 cpl_frameset * arcframes = NULL;
00202 cpl_frameset * arc_one = NULL;
00203 int i;
00204
00205
00206
00207 sval = irplib_parameterlist_get_string(parlist, PACKAGE, RECIPE_STRING,
00208 "rejected");
00209 skip_if(sval == NULL);
00210 error_if (sscanf(sval, "%d,%d,%d,%d",
00211 &isaac_spc_arc_config.rej_left,
00212 &isaac_spc_arc_config.rej_right,
00213 &isaac_spc_arc_config.rej_bottom,
00214 &isaac_spc_arc_config.rej_top) != 4,
00215 CPL_ERROR_DATA_NOT_FOUND, "Parameter not in format %s: %s",
00216 "%d,%d,%d,%d", sval);
00217
00218
00219 isaac_spc_arc_config.out_corr
00220 = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
00221 "out_corr");
00222
00223 isaac_spc_arc_config.sub_dark
00224 = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
00225 "subdark");
00226
00227
00228 isaac_spc_arc_config.arc_max_width
00229 = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00230 "arc_max_w");
00231
00232
00233 isaac_spc_arc_config.max_offset
00234 = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00235 "max_offset");
00236
00237 isaac_spc_arc_config.arc_kappa
00238 = irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING,
00239 "arc_kappa");
00240
00241
00242 skip_if (isaac_dfs_set_groups(framelist));
00243
00244
00245 arcframes = isaac_extract_frameset(framelist, ISAAC_SPC_ARC_RAW);
00246 error_if (arcframes == NULL, CPL_ERROR_DATA_NOT_FOUND,
00247 "No frames are tagged %s", ISAAC_SPC_ARC_RAW);
00248
00249
00250 xe = isaac_extract_filename(framelist, ISAAC_CALPRO_XE_CAT);
00251 error_if (xe == NULL, CPL_ERROR_DATA_NOT_FOUND,
00252 "Xe catalogue not found");
00253
00254 ar = isaac_extract_filename(framelist, ISAAC_CALPRO_AR_CAT);
00255 error_if (ar == NULL, CPL_ERROR_DATA_NOT_FOUND,
00256 "Ar catalogue not found");
00257
00258
00259 labels = cpl_frameset_labelise(arcframes, isaac_spc_arc_compare, &nlabels);
00260 any_if ("Could not labelise input frames (nlabels=%d)", (int)nlabels);
00261
00262
00263 for (i=0; i < nlabels; i++) {
00264 const cpl_frame * cur_frame;
00265 const char * filename;
00266 int error;
00267
00268
00269 cpl_msg_info(cpl_func, "Reducing data set %d of %d", i+1, (int)nlabels);
00270 isaac_spc_arc_config.set_nb = i+1;
00271 cpl_frameset_delete(arc_one);
00272 arc_one = cpl_frameset_extract(arcframes, labels, i);
00273
00274
00275 cur_frame = cpl_frameset_get_frame(arc_one, 0);
00276 filename = cpl_frame_get_filename(cur_frame);
00277 cpl_propertylist_delete(plist);
00278 plist = cpl_propertylist_load(filename, 0);
00279 sval = isaac_pfits_get_arm(plist);
00280 any_if ("Could not get the arm from %s in set %d of %d", filename,
00281 i+1, (int)nlabels);
00282
00283 if (sval[0] == 'S') {
00284 isaac_spc_arc_config.arm = 1;
00285 } else if (sval[0] == 'L') {
00286 isaac_spc_arc_config.arm = 2;
00287 } else {
00288 isaac_spc_arc_config.arm = 0;
00289 error_if(1, CPL_ERROR_UNSUPPORTED_MODE,
00290 "Unsupported arm in %s in set %d of %d: %s", filename,
00291 i+1, (int)nlabels, sval);
00292 }
00293
00294
00295 sval = isaac_pfits_get_resolution(plist);
00296 any_if ("Could not get the resolution from %s in set %d of %d",
00297 filename, i+1, (int)nlabels);
00298
00299 if (sval[0]=='L') isaac_spc_arc_config.resol = 'L';
00300 else if (sval[0]=='M') isaac_spc_arc_config.resol = 'M';
00301 else isaac_spc_arc_config.resol = 'U';
00302 cpl_propertylist_empty(plist);
00303
00304 error = isaac_spc_arc_config.arm == 1 ?
00305
00306 isaac_spc_arc_reduce_sw(arc_one, parlist, ar, xe, framelist) :
00307
00308 isaac_spc_arc_reduce_lw(arc_one, parlist, ar, xe, framelist);
00309
00310 error_if(error, cpl_error_get_code(),
00311 "Could not reduce set %d of %d", i+1, (int)nlabels);
00312 }
00313
00314 end_skip;
00315
00316 cpl_frameset_delete(arc_one);
00317 cpl_frameset_delete(arcframes);
00318 cpl_free(labels);
00319 cpl_propertylist_delete(plist);
00320
00321 return cpl_error_get_code();
00322 }
00323
00324
00334
00335 static int isaac_spc_arc_reduce_sw(
00336 cpl_frameset * arcframes,
00337 const cpl_parameterlist * parlist,
00338 const char * ar,
00339 const char * xe,
00340 cpl_frameset * set_tot)
00341 {
00342 int * lamps;
00343 int nframes;
00344 char lines_table[16];
00345 cpl_frame * cur_frame;
00346 const char * cur_fname;
00347 cpl_image * xenon;
00348 cpl_image * argon;
00349 cpl_image * xe_ar;
00350 cpl_image * dark;
00351 cpl_image * to_compute;
00352 cpl_table * arcs_fwhm;
00353 cpl_image * out_corr;
00354 cpl_table * out_table;
00355 int i;
00356
00357
00358 nframes = cpl_frameset_get_size(arcframes);
00359 isaac_spc_arc_config.pair_nb = 0;
00360 to_compute = NULL;
00361
00362
00363
00364
00365
00366
00367 if ((lamps=isaac_spc_arc_find_lamps(arcframes)) == NULL) {
00368 cpl_msg_error(cpl_func, "in finding the activated lamps");
00369 return -1;
00370 }
00371
00372
00373 xenon = argon = xe_ar = dark = NULL;
00374 for (i=0; i<nframes; i++) {
00375 cur_frame = cpl_frameset_get_frame(arcframes, i);
00376 cur_fname = cpl_frame_get_filename(cur_frame);
00377 if ((lamps[i] == 0) && (dark == NULL)) {
00378 cpl_msg_info(cpl_func, "Dark image: [%s]", cur_fname);
00379 dark = cpl_image_load(cur_fname, CPL_TYPE_FLOAT, 0, 0);
00380 } else if ((lamps[i] == 1) && (xenon == NULL)) {
00381 cpl_msg_info(cpl_func, "Xenon lamp: [%s]", cur_fname);
00382 xenon = cpl_image_load(cur_fname, CPL_TYPE_FLOAT, 0, 0);
00383 } else if ((lamps[i] == 2) && (argon == NULL)) {
00384 cpl_msg_info(cpl_func, "Argon lamp: [%s]", cur_fname);
00385 argon = cpl_image_load(cur_fname, CPL_TYPE_FLOAT, 0, 0);
00386 } else if ((lamps[i] == 3) && (xe_ar == NULL)) {
00387 cpl_msg_info(cpl_func, "Xenon+Argon lamp: [%s]", cur_fname);
00388 xe_ar = cpl_image_load(cur_fname, CPL_TYPE_FLOAT, 0, 0);
00389 }
00390 }
00391 cpl_free(lamps);
00392
00393
00394 if (!xenon && !argon && !xe_ar) {
00395 cpl_msg_error(cpl_func, "neither xenon nor argon lamp activated");
00396 if (dark) cpl_image_delete(dark);
00397 return -1;
00398 }
00399
00400
00401 cur_frame = cpl_frameset_get_frame(arcframes, 0);
00402 cur_fname = cpl_frame_get_filename(cur_frame);
00403
00404
00405 if (isaac_spc_arc_config.resol == 'L') {
00406 cpl_msg_info(cpl_func, "Low resolution");
00407
00408
00409 if (xenon) {
00410 if (dark) to_compute = cpl_image_subtract_create(xenon, dark);
00411 else to_compute = cpl_image_duplicate(xenon);
00412 cpl_image_delete(xenon);
00413 strcpy(lines_table, "Xe");
00414
00415
00416 cpl_msg_info(cpl_func, "Apply the reduction");
00417 isaac_spc_arc_config.pair_nb ++;
00418 cpl_msg_indent_more();
00419 if ((out_table = isaac_spc_arc_compute(to_compute, cur_fname,
00420 lines_table, ar, xe, &arcs_fwhm,
00421 &out_corr)) == NULL) {
00422 cpl_msg_error(cpl_func, "arc reduction computation failed");
00423 cpl_image_delete(to_compute);
00424 } else {
00425
00426 cpl_image_delete(to_compute);
00427 cpl_msg_info(cpl_func, "Save the products");
00428 isaac_spc_arc_save(out_table, arcs_fwhm, out_corr, lines_table,
00429 arcframes, parlist, set_tot);
00430 cpl_table_delete(out_table);
00431 if (arcs_fwhm) cpl_table_delete(arcs_fwhm);
00432 if (out_corr) cpl_image_delete(out_corr);
00433 }
00434 cpl_msg_indent_less();
00435 }
00436
00437
00438 if (argon) {
00439 if (dark) to_compute = cpl_image_subtract_create(argon, dark);
00440 else to_compute = cpl_image_duplicate(argon);
00441 cpl_image_delete(argon);
00442 strcpy(lines_table, "Ar");
00443
00444
00445 cpl_msg_info(cpl_func, "Apply the reduction");
00446 isaac_spc_arc_config.pair_nb ++;
00447 cpl_msg_indent_more();
00448 if ((out_table = isaac_spc_arc_compute(to_compute, cur_fname,
00449 lines_table, ar, xe, &arcs_fwhm,
00450 &out_corr)) == NULL) {
00451 cpl_msg_error(cpl_func, "arc reduction computation failed");
00452 cpl_image_delete(to_compute);
00453 } else {
00454
00455 cpl_image_delete(to_compute);
00456 cpl_msg_info(cpl_func, "Save the products");
00457 isaac_spc_arc_save(out_table, arcs_fwhm, out_corr, lines_table,
00458 arcframes, parlist, set_tot);
00459 cpl_table_delete(out_table);
00460 if (arcs_fwhm) cpl_table_delete(arcs_fwhm);
00461 if (out_corr) cpl_image_delete(out_corr);
00462 }
00463 cpl_msg_indent_less();
00464 }
00465
00466
00467 if (xe_ar) {
00468 if (dark) to_compute = cpl_image_subtract_create(xe_ar, dark);
00469 else to_compute = cpl_image_duplicate(xe_ar);
00470 cpl_image_delete(xe_ar);
00471 strcpy(lines_table, "Xe+Ar");
00472
00473
00474 cpl_msg_info(cpl_func, "Apply the reduction");
00475 isaac_spc_arc_config.pair_nb ++;
00476 cpl_msg_indent_more();
00477 if ((out_table = isaac_spc_arc_compute(to_compute, cur_fname,
00478 lines_table, ar, xe, &arcs_fwhm,
00479 &out_corr)) == NULL) {
00480 cpl_msg_error(cpl_func, "arc reduction computation failed");
00481 cpl_image_delete(to_compute);
00482 } else {
00483
00484 cpl_image_delete(to_compute);
00485 cpl_msg_info(cpl_func, "Save the products");
00486 isaac_spc_arc_save(out_table, arcs_fwhm, out_corr, lines_table,
00487 arcframes, parlist, set_tot);
00488 cpl_table_delete(out_table);
00489 if (arcs_fwhm) cpl_table_delete(arcs_fwhm);
00490 if (out_corr) cpl_image_delete(out_corr);
00491 }
00492 cpl_msg_indent_less();
00493 }
00494
00495 } else if (isaac_spc_arc_config.resol == 'M') {
00496 cpl_msg_info(cpl_func, "Medium resolution");
00497
00498 if (xenon && argon) {
00499 if (dark) {
00500 cpl_image_subtract(xenon, dark);
00501 cpl_image_subtract(argon, dark);
00502 to_compute = cpl_image_add_create(xenon, argon);
00503 } else to_compute = cpl_image_add_create(xenon, argon);
00504 cpl_image_delete(xenon);
00505 cpl_image_delete(argon);
00506 strcpy(lines_table, "Xe+Ar");
00507 } else if (xenon) {
00508 if (dark) to_compute = cpl_image_subtract_create(xenon, dark);
00509 else to_compute = cpl_image_duplicate(xenon);
00510 cpl_image_delete(xenon);
00511 strcpy(lines_table, "Xe");
00512 } else if (argon) {
00513 if (dark) to_compute = cpl_image_subtract_create(argon, dark);
00514 else to_compute = cpl_image_duplicate(argon);
00515 cpl_image_delete(argon);
00516 strcpy(lines_table, "Ar");
00517 } else if (xe_ar) {
00518 if (dark) to_compute = cpl_image_subtract_create(xe_ar, dark);
00519 else to_compute = cpl_image_duplicate(xe_ar);
00520 cpl_image_delete(xe_ar);
00521 strcpy(lines_table, "Xe+Ar");
00522 }
00523
00524
00525 cpl_msg_info(cpl_func, "Apply the reduction");
00526 isaac_spc_arc_config.pair_nb ++;
00527 cpl_msg_indent_more();
00528 if ((out_table = isaac_spc_arc_compute(to_compute, cur_fname,
00529 lines_table, ar, xe, &arcs_fwhm,
00530 &out_corr)) == NULL) {
00531 cpl_msg_error(cpl_func, "arc reduction computation failed");
00532 cpl_image_delete(to_compute);
00533 } else {
00534
00535 cpl_image_delete(to_compute);
00536 cpl_msg_info(cpl_func, "Save the products");
00537 isaac_spc_arc_save(out_table, arcs_fwhm, out_corr, lines_table,
00538 arcframes, parlist, set_tot);
00539 cpl_table_delete(out_table);
00540 if (arcs_fwhm) cpl_table_delete(arcs_fwhm);
00541 if (out_corr) cpl_image_delete(out_corr);
00542 }
00543 cpl_msg_indent_less();
00544 }
00545
00546 if (dark) cpl_image_delete(dark);
00547
00548 return 0;
00549 }
00550
00551
00561
00562 static int isaac_spc_arc_reduce_lw(
00563 cpl_frameset * arcframes,
00564 const cpl_parameterlist * parlist,
00565 const char * ar,
00566 const char * xe,
00567 cpl_frameset * set_tot)
00568 {
00569 int * lamps;
00570 int nframes;
00571 char lines_table[16];
00572 cpl_frame * cur_frame;
00573 const char * cur_fname;
00574 cpl_image * to_compute;
00575 cpl_image * dark;
00576 cpl_table * arcs_fwhm;
00577 cpl_image * out_corr;
00578 cpl_table * out_table;
00579 cpl_boolean did_reduce = CPL_FALSE;
00580 int i;
00581
00582
00583 nframes = cpl_frameset_get_size(arcframes);
00584
00585
00586 if (nframes % 2) {
00587 cpl_msg_error(cpl_func, "An even nb of frames expected in input %d",
00588 nframes);
00589 return -1;
00590 }
00591
00592
00593
00594
00595
00596
00597 if ((lamps=isaac_spc_arc_find_lamps(arcframes)) == NULL) {
00598 cpl_msg_error(cpl_func, "in finding the activated lamps");
00599 return -1;
00600 }
00601
00602
00603 for (i=0; i<nframes/2; i++) {
00604 isaac_spc_arc_config.pair_nb = i+1;
00605
00606 cur_frame = cpl_frameset_get_frame(arcframes, 2*i);
00607 cur_fname = cpl_frame_get_filename(cur_frame);
00608 if ((to_compute = cpl_image_load(cur_fname,CPL_TYPE_FLOAT,0,0))==NULL){
00609 cpl_msg_error(cpl_func, "Could not load frame %s", cur_fname);
00610 cpl_free(lamps);
00611 }
00612 cpl_msg_info(cpl_func, "Pair %d: Lamp and dark identification", i+1);
00613 switch (lamps[2*i]) {
00614
00615 case 1:
00616 strcpy(lines_table, "Xe");
00617 cpl_msg_info(cpl_func, "Xenon lamp: [%s]", cur_fname);
00618 break;
00619
00620 case 2:
00621 strcpy(lines_table, "Ar");
00622 cpl_msg_info(cpl_func, "Argon lamp: [%s]", cur_fname);
00623 break;
00624
00625 case 3:
00626 strcpy(lines_table, "Xe+Ar");
00627 cpl_msg_info(cpl_func, "Xenon+Argon lamp: [%s]", cur_fname);
00628 break;
00629 default:
00630 cpl_image_delete(to_compute);
00631 cpl_msg_info(cpl_func, "Lamps are off. Next pair...");
00632 continue;
00633 }
00634
00635
00636 if (lamps[2*i+1] == 0) {
00637 cur_frame = cpl_frameset_get_frame(arcframes, 2*i+1);
00638 cur_fname = cpl_frame_get_filename(cur_frame);
00639 dark = cpl_image_load(cur_fname, CPL_TYPE_FLOAT, 0, 0);
00640 cpl_image_subtract(to_compute, dark);
00641 cpl_image_delete(dark);
00642 cpl_msg_info(cpl_func, "Dark frame : [%s]", cur_fname);
00643 } else {
00644 cpl_msg_info(cpl_func, "No dark frame");
00645 }
00646
00647
00648 cur_frame = cpl_frameset_get_frame(arcframes, 2*i);
00649 cur_fname = cpl_frame_get_filename(cur_frame);
00650
00651
00652 cpl_msg_info(cpl_func, "Apply the reduction");
00653 cpl_msg_indent_more();
00654 if ((out_table = isaac_spc_arc_compute(to_compute, cur_fname,
00655 lines_table, ar, xe, &arcs_fwhm,
00656 &out_corr)) == NULL) {
00657 cpl_msg_error(cpl_func, "arc reduction computation failed");
00658 cpl_image_delete(to_compute);
00659 } else {
00660
00661 cpl_image_delete(to_compute);
00662 cpl_msg_info(cpl_func, "Save the products");
00663 isaac_spc_arc_save(out_table, arcs_fwhm, out_corr, lines_table,
00664 arcframes, parlist, set_tot);
00665 cpl_table_delete(out_table);
00666 if (arcs_fwhm) cpl_table_delete(arcs_fwhm);
00667 if (out_corr) cpl_image_delete(out_corr);
00668 if (!cpl_error_get_code()) did_reduce = CPL_TRUE;
00669 }
00670 cpl_msg_indent_less();
00671 }
00672
00673
00674 cpl_free(lamps);
00675 cpl_ensure_code(did_reduce, CPL_ERROR_ILLEGAL_INPUT);
00676
00677 return cpl_error_set_where(cpl_func);
00678 }
00679
00680
00693
00694 static cpl_table * isaac_spc_arc_compute(
00695 const cpl_image * in,
00696 const char * in_name,
00697 const char * lines_table,
00698 const char * ar,
00699 const char * xe,
00700 cpl_table ** arcs_fwhm,
00701 cpl_image ** out_corr)
00702 {
00703 cpl_table * out_tab;
00704 int xmin, ymin, xmax, ymax;
00705 int nx, ny;
00706 cpl_mask * saturation_map;
00707 double slit_width;
00708 int order;
00709 cpl_polynomial * distor_poly;
00710 cpl_polynomial * poly2d_id;
00711 cpl_vector * profile;
00712 cpl_image * in_corr;
00713 cpl_apertures * arcs;
00714 double * phdisprel;
00715 computed_disprel * disprel;
00716 cpl_size power[2];
00717 double fwhm_x, fwhm_y;
00718 cpl_vector * fwhm_valid;
00719 int i;
00720
00721
00722 nx = cpl_image_get_size_x(in);
00723 ny = cpl_image_get_size_y(in);
00724 *arcs_fwhm = NULL;
00725 *out_corr = NULL;
00726
00727
00728 xmin = 1;
00729 xmax = nx;
00730 ymin = isaac_spc_arc_config.rej_bottom + 1;
00731 ymax = ny - isaac_spc_arc_config.rej_top;
00732
00733
00734 saturation_map = cpl_mask_threshold_image_create(in, ISAAC_ARC_SATURATION,
00735 DBL_MAX);
00736 if (saturation_map != NULL) {
00737 isaac_spc_arc_config.nb_saturated = cpl_mask_count(saturation_map);
00738 cpl_mask_delete(saturation_map);
00739 } else {
00740 isaac_spc_arc_config.nb_saturated = 0;
00741 }
00742
00743
00744 cpl_msg_info(cpl_func, "Estimate the distortion");
00745 cpl_msg_indent_more();
00746 if ((distor_poly = irplib_distortion_estimate(in, xmin, ymin, xmax, ymax,
00747 isaac_spc_arc_config.sub_dark, ISAAC_ARC_SATURATION,
00748 isaac_spc_arc_config.arc_max_width,
00749 isaac_spc_arc_config.arc_kappa, 2, &arcs)) == NULL) {
00750 cpl_msg_error(cpl_func, "Could not estimage distortion");
00751 cpl_msg_indent_less();
00752 return NULL;
00753 }
00754 cpl_msg_indent_less();
00755
00756
00757 cpl_msg_info(cpl_func, "Correct the distortion");
00758 cpl_msg_indent_more();
00759 in_corr = cpl_image_duplicate(in);
00760
00761
00762 poly2d_id = cpl_polynomial_new(2);
00763 power[0] = 0; power[1] = 1;
00764 cpl_polynomial_set_coeff(poly2d_id, power, 1.0);
00765
00766
00767 profile = cpl_vector_new(CPL_KERNEL_DEF_SAMPLES);
00768 cpl_vector_fill_kernel_profile(profile, CPL_KERNEL_DEFAULT,
00769 CPL_KERNEL_DEF_WIDTH);
00770
00771
00772 if (cpl_image_warp_polynomial(in_corr, in, distor_poly,
00773 poly2d_id, profile, CPL_KERNEL_DEF_WIDTH, profile,
00774 CPL_KERNEL_DEF_WIDTH) != CPL_ERROR_NONE) {
00775 cpl_msg_error(cpl_func, "Could not correct the distortion");
00776 cpl_image_delete(in_corr);
00777 cpl_polynomial_delete(poly2d_id);
00778 cpl_polynomial_delete(distor_poly);
00779 cpl_vector_delete(profile);
00780 cpl_msg_indent_less();
00781 return NULL;
00782 }
00783 cpl_polynomial_delete(poly2d_id);
00784 cpl_vector_delete(profile);
00785 cpl_msg_indent_less();
00786
00787
00788 cpl_msg_info(cpl_func, "Compute the FWHM of the detected arcs");
00789
00790 *arcs_fwhm = cpl_table_new(cpl_apertures_get_size(arcs));
00791 cpl_table_new_column(*arcs_fwhm, "XPOS", CPL_TYPE_DOUBLE);
00792 cpl_table_new_column(*arcs_fwhm, "FWHM", CPL_TYPE_DOUBLE);
00793 cpl_table_new_column(*arcs_fwhm, "FLUX", CPL_TYPE_DOUBLE);
00794
00795 isaac_spc_arc_config.fwhm_good = 0;
00796 for (i=0; i<cpl_apertures_get_size(arcs); i++) {
00797 cpl_table_set_double(*arcs_fwhm, "XPOS", i,
00798 cpl_apertures_get_centroid_x(arcs, i+1));
00799 cpl_table_set_double(*arcs_fwhm, "FLUX", i,
00800 cpl_apertures_get_flux(arcs, i+1));
00801 if (cpl_image_get_fwhm(in_corr, cpl_apertures_get_centroid_x(arcs, i+1),
00802 512, &fwhm_x, &fwhm_y) != CPL_ERROR_NONE) {
00803 cpl_msg_warning(cpl_func, "Could not get the FWHM");
00804 cpl_error_reset();
00805 }
00806 cpl_table_set_double(*arcs_fwhm, "FWHM", i, fwhm_x);
00807 if (fwhm_x > 0) isaac_spc_arc_config.fwhm_good ++;
00808 }
00809 cpl_apertures_delete(arcs);
00810
00811
00812 if (isaac_spc_arc_config.fwhm_good > 0) {
00813 fwhm_valid = cpl_vector_new(isaac_spc_arc_config.fwhm_good);
00814 isaac_spc_arc_config.fwhm_good = 0;
00815 for (i=0; i<cpl_table_get_nrow(*arcs_fwhm); i++) {
00816 fwhm_x = cpl_table_get_double(*arcs_fwhm, "FWHM", i, NULL);
00817 if (fwhm_x > 0) {
00818 cpl_vector_set(fwhm_valid, isaac_spc_arc_config.fwhm_good,
00819 fwhm_x);
00820 isaac_spc_arc_config.fwhm_good ++;
00821 }
00822 }
00823 isaac_spc_arc_config.fwhm_med = cpl_vector_get_median_const(fwhm_valid);
00824 cpl_vector_delete(fwhm_valid);
00825 } else isaac_spc_arc_config.fwhm_med = 0.0;
00826
00827
00828
00829
00830 if ((slit_width = isaac_get_slitwidth(in_name)) == -1) {
00831 cpl_msg_error(cpl_func, "Could not get the slit width");
00832 cpl_polynomial_delete(distor_poly);
00833 cpl_image_delete(in_corr);
00834 cpl_table_delete(*arcs_fwhm);
00835 *arcs_fwhm = NULL;
00836 return NULL;
00837 }
00838
00839
00840 if ((order = isaac_find_order(in_name)) == -1) {
00841 cpl_msg_error(cpl_func, "Could not get the order");
00842 cpl_polynomial_delete(distor_poly);
00843 cpl_image_delete(in_corr);
00844 cpl_table_delete(*arcs_fwhm);
00845 *arcs_fwhm = NULL;
00846 return NULL;
00847 }
00848
00849
00850 cpl_msg_info(cpl_func, "Compute the physical model");
00851 cpl_msg_indent_more();
00852 if ((phdisprel = isaac_get_disprel_estimate(in_name, 3)) == NULL) {
00853 cpl_msg_error(cpl_func, "Could not estimate the dispersion relation");
00854 cpl_polynomial_delete(distor_poly);
00855 cpl_image_delete(in_corr);
00856 cpl_table_delete(*arcs_fwhm);
00857 *arcs_fwhm = NULL;
00858 cpl_msg_indent_less();
00859 return NULL;
00860 }
00861 cpl_msg_info(cpl_func, "f(x)=%g + %g*x + %g*x^2 + %g*x^3",
00862 phdisprel[0], phdisprel[1], phdisprel[2], phdisprel[3]);
00863 cpl_msg_indent_less();
00864
00865
00866 cpl_msg_info(cpl_func, "Compute the dispersion relation");
00867 cpl_msg_indent_more();
00868 if ((disprel = spectro_compute_disprel(in_corr,
00869 isaac_spc_arc_config.rej_bottom,
00870 isaac_spc_arc_config.rej_top,
00871 isaac_spc_arc_config.rej_left,
00872 isaac_spc_arc_config.rej_right,
00873 isaac_spc_arc_config.max_offset,
00874 isaac_has_thermal(in_name) > 0,
00875 lines_table, NULL, ar, xe, slit_width, order,
00876 (int)(cpl_msg_get_level() == CPL_MSG_DEBUG),
00877 phdisprel)) == NULL) {
00878 cpl_msg_error(cpl_func, "Could not compute the dispersion relation");
00879 cpl_polynomial_delete(distor_poly);
00880 cpl_image_delete(in_corr);
00881 cpl_free(phdisprel);
00882 cpl_table_delete(*arcs_fwhm);
00883 *arcs_fwhm = NULL;
00884 cpl_msg_indent_less();
00885 return NULL;
00886 }
00887 if (isaac_spc_arc_config.out_corr) {
00888 *out_corr = in_corr;
00889 in_corr = NULL;
00890 } else {
00891 cpl_image_delete(in_corr);
00892 }
00893 cpl_free(phdisprel);
00894 cpl_msg_info(cpl_func, "Cross correlation factor: %g", disprel->cc);
00895 cpl_msg_info(cpl_func, "f(x)=%g + %g*x + %g*x^2 + %g*x^3",
00896 disprel->poly[0], disprel->poly[1], disprel->poly[2],
00897 disprel->poly[3]);
00898 cpl_msg_indent_less();
00899
00900
00901 out_tab = cpl_table_new(6);
00902
00903
00904 cpl_table_new_column(out_tab, "Degree_of_x", CPL_TYPE_INT);
00905 cpl_table_new_column(out_tab, "Degree_of_y", CPL_TYPE_INT);
00906 cpl_table_new_column(out_tab, "poly2d_coef", CPL_TYPE_DOUBLE);
00907 power[0] = 0; power[1] = 0;
00908 cpl_table_set_int(out_tab, "Degree_of_x", 0, power[0]);
00909 cpl_table_set_int(out_tab, "Degree_of_y", 0, power[1]);
00910 cpl_table_set_double(out_tab, "poly2d_coef", 0,
00911 cpl_polynomial_get_coeff(distor_poly, power));
00912 power[0] = 1; power[1] = 0;
00913 cpl_table_set_int(out_tab, "Degree_of_x", 1, power[0]);
00914 cpl_table_set_int(out_tab, "Degree_of_y", 1, power[1]);
00915 cpl_table_set_double(out_tab, "poly2d_coef", 1,
00916 cpl_polynomial_get_coeff(distor_poly, power));
00917 power[0] = 0; power[1] = 1;
00918 cpl_table_set_int(out_tab, "Degree_of_x", 2, power[0]);
00919 cpl_table_set_int(out_tab, "Degree_of_y", 2, power[1]);
00920 cpl_table_set_double(out_tab, "poly2d_coef", 2,
00921 cpl_polynomial_get_coeff(distor_poly, power));
00922 power[0] = 1; power[1] = 1;
00923 cpl_table_set_int(out_tab, "Degree_of_x", 3, power[0]);
00924 cpl_table_set_int(out_tab, "Degree_of_y", 3, power[1]);
00925 cpl_table_set_double(out_tab, "poly2d_coef", 3,
00926 cpl_polynomial_get_coeff(distor_poly, power));
00927 power[0] = 2; power[1] = 0;
00928 cpl_table_set_int(out_tab, "Degree_of_x", 4, power[0]);
00929 cpl_table_set_int(out_tab, "Degree_of_y", 4, power[1]);
00930 cpl_table_set_double(out_tab, "poly2d_coef", 4,
00931 cpl_polynomial_get_coeff(distor_poly, power));
00932 power[0] = 0; power[1] = 2;
00933 cpl_table_set_int(out_tab, "Degree_of_x", 5, power[0]);
00934 cpl_table_set_int(out_tab, "Degree_of_y", 5, power[1]);
00935 cpl_table_set_double(out_tab, "poly2d_coef", 5,
00936 cpl_polynomial_get_coeff(distor_poly, power));
00937
00938
00939 cpl_table_new_column(out_tab, "WL_coefficients", CPL_TYPE_DOUBLE);
00940 cpl_table_set_double(out_tab, "WL_coefficients", 0, disprel->poly[0]);
00941 cpl_table_set_double(out_tab, "WL_coefficients", 1, disprel->poly[1]);
00942 cpl_table_set_double(out_tab, "WL_coefficients", 2, disprel->poly[2]);
00943 cpl_table_set_double(out_tab, "WL_coefficients", 3, disprel->poly[3]);
00944 cpl_table_set_double(out_tab, "WL_coefficients", 4, 0.0);
00945 cpl_table_set_double(out_tab, "WL_coefficients", 5, 0.0);
00946 isaac_spc_arc_config.disprel_cc = disprel->cc;
00947 isaac_spc_arc_config.disprel_clines = disprel->clines;
00948 isaac_spc_arc_config.disprel_dlines = disprel->dlines;
00949 isaac_spc_arc_config.disprel_rms = disprel->rms;
00950 isaac_spc_arc_config.disprel_offset = disprel->offset;
00951
00952
00953 cpl_polynomial_delete(distor_poly);
00954 if (disprel->poly != NULL) cpl_free(disprel->poly);
00955 cpl_free(disprel);
00956 return out_tab;
00957 }
00958
00959
00971
00972 static int isaac_spc_arc_save(
00973 const cpl_table * tab,
00974 const cpl_table * fwhms,
00975 const cpl_image * corr,
00976 const char * lines_table,
00977 cpl_frameset * set,
00978 const cpl_parameterlist * parlist,
00979 cpl_frameset * set_tot)
00980 {
00981 cpl_propertylist * plist;
00982 cpl_propertylist * qclist;
00983 cpl_propertylist * paflist;
00984 const cpl_frame * ref_frame;
00985 const char * sval;
00986 char qc_str[128];
00987 const char * procat = isaac_spc_arc_config.arm == 1
00988 ? ISAAC_SPC_ARC_SW_RES : ISAAC_SPC_ARC_LW_RES;
00989 char * filename;
00990 int i;
00991
00992
00993
00994 qclist = cpl_propertylist_new();
00995
00996
00997 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00998 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00999 0)) == NULL) {
01000 cpl_msg_error(cpl_func, "getting header from reference frame");
01001 cpl_propertylist_delete(qclist);
01002 return -1;
01003 }
01004
01005 if (cpl_error_get_code()) {
01006 cpl_propertylist_delete(qclist);
01007 cpl_propertylist_delete(plist);
01008 return -1;
01009 }
01010 sval = isaac_pfits_get_filter(plist);
01011 if (cpl_error_get_code()) cpl_error_reset();
01012 else cpl_propertylist_append_string(qclist, "ESO QC FILTER OBS", sval);
01013 cpl_propertylist_delete(plist);
01014 cpl_propertylist_append_string(qclist, "ESO QC LAMP", lines_table);
01015 cpl_propertylist_append_double(qclist, "ESO QC DISP XCORR",
01016 isaac_spc_arc_config.disprel_cc);
01017 cpl_propertylist_append_int(qclist, "ESO QC DISP NUMCAT",
01018 isaac_spc_arc_config.disprel_clines);
01019 cpl_propertylist_append_int(qclist, "ESO QC DISP NUMMATCH",
01020 isaac_spc_arc_config.disprel_dlines);
01021 cpl_propertylist_append_double(qclist, "ESO QC DISP STDEV",
01022 isaac_spc_arc_config.disprel_rms);
01023 cpl_propertylist_append_double(qclist, "ESO QC DISP OFFSET",
01024 isaac_spc_arc_config.disprel_offset);
01025 cpl_propertylist_append_double(qclist, "ESO QC DISPCO1",
01026 cpl_table_get_double(tab, "WL_coefficients", 0, NULL));
01027 cpl_propertylist_append_double(qclist, "ESO QC DISPCO2",
01028 cpl_table_get_double(tab, "WL_coefficients", 1, NULL));
01029 cpl_propertylist_append_double(qclist, "ESO QC DISPCO3",
01030 cpl_table_get_double(tab, "WL_coefficients", 2, NULL));
01031 cpl_propertylist_append_double(qclist, "ESO QC DISPCO4",
01032 cpl_table_get_double(tab, "WL_coefficients", 3, NULL));
01033 cpl_propertylist_append_double(qclist, "ESO QC DIST1",
01034 cpl_table_get_double(tab, "poly2d_coef", 0, NULL));
01035 cpl_propertylist_append_double(qclist, "ESO QC DISTX",
01036 cpl_table_get_double(tab, "poly2d_coef", 1, NULL));
01037 cpl_propertylist_append_double(qclist, "ESO QC DISTY",
01038 cpl_table_get_double(tab, "poly2d_coef", 2, NULL));
01039 cpl_propertylist_append_double(qclist, "ESO QC DISTXY",
01040 cpl_table_get_double(tab, "poly2d_coef", 3, NULL));
01041 cpl_propertylist_append_double(qclist, "ESO QC DISTXX",
01042 cpl_table_get_double(tab, "poly2d_coef", 4, NULL));
01043 cpl_propertylist_append_double(qclist, "ESO QC DISTYY",
01044 cpl_table_get_double(tab, "poly2d_coef", 5, NULL));
01045 cpl_propertylist_append_int(qclist, "ESO QC SATUR NBPIX",
01046 isaac_spc_arc_config.nb_saturated);
01047 cpl_propertylist_append_double(qclist, "ESO QC WLEN",
01048 (double)(cpl_table_get_double(tab, "WL_coefficients", 0, NULL) +
01049 512*cpl_table_get_double(tab, "WL_coefficients", 1, NULL) +
01050 512*512*cpl_table_get_double(tab, "WL_coefficients", 2, NULL) +
01051 512*512*512*cpl_table_get_double(tab, "WL_coefficients", 3, NULL)));
01052
01053 if (fwhms) {
01054 cpl_propertylist_append_int(qclist, "ESO QC ARCS NUM",
01055 cpl_table_get_nrow(fwhms));
01056 for(i=0; i<cpl_table_get_nrow(fwhms); i++) {
01057 sprintf(qc_str, "ESO QC ARCS%d XPOS", i+1);
01058 cpl_propertylist_append_double(qclist, qc_str,
01059 cpl_table_get_double(fwhms, "XPOS", i, NULL));
01060 sprintf(qc_str, "ESO QC ARCS%d FWHM", i+1);
01061 cpl_propertylist_append_double(qclist, qc_str,
01062 cpl_table_get_double(fwhms, "FWHM", i, NULL));
01063 sprintf(qc_str, "ESO QC ARCS%d FLUX", i+1);
01064 cpl_propertylist_append_double(qclist, qc_str,
01065 cpl_table_get_double(fwhms, "FLUX", i, NULL));
01066 }
01067 cpl_propertylist_append_int(qclist, "ESO QC ARCS NUMGOOD",
01068 isaac_spc_arc_config.fwhm_good);
01069 cpl_propertylist_append_double(qclist, "ESO QC FWHM MED",
01070 isaac_spc_arc_config.fwhm_med);
01071 }
01072
01073
01074
01075 filename = cpl_sprintf("isaac_spc_arc_set%d_pair%d.fits",
01076 isaac_spc_arc_config.set_nb, isaac_spc_arc_config.pair_nb);
01077 irplib_dfs_save_table(set_tot,
01078 parlist,
01079 set,
01080 tab,
01081 NULL,
01082 "isaac_spc_arc",
01083 procat,
01084 qclist,
01085 NULL,
01086 PACKAGE "/" PACKAGE_VERSION,
01087 filename);
01088 cpl_free(filename);
01089
01090
01091 if (corr) {
01092 const char * procatc = isaac_spc_arc_config.arm == 1
01093 ? ISAAC_SPC_ARC_SW_CORR : ISAAC_SPC_ARC_LW_CORR;
01094 filename = cpl_sprintf("isaac_spc_arc_set%d_pair%d_corr.fits",
01095 isaac_spc_arc_config.set_nb, isaac_spc_arc_config.pair_nb);
01096 irplib_dfs_save_image(set_tot,
01097 parlist,
01098 set,
01099 corr,
01100 CPL_BPP_IEEE_FLOAT,
01101 "isaac_spc_arc",
01102 procatc,
01103 qclist,
01104 NULL,
01105 PACKAGE "/" PACKAGE_VERSION,
01106 filename);
01107 cpl_free(filename);
01108 }
01109
01110
01111 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
01112
01113
01114 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
01115 0)) == NULL) {
01116 cpl_msg_error(cpl_func, "getting header from reference frame");
01117 cpl_propertylist_delete(qclist);
01118 return -1;
01119 }
01120
01121
01122 paflist = cpl_propertylist_new();
01123 cpl_propertylist_copy_property_regexp(paflist, plist,
01124 "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
01125 "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME|"
01126 "ESO INS GRAT WLEN|ESO INS GRAT ORDER|ESO INS MODE|"
01127 "ESO INS OPTI1 ID)$", 0);
01128 cpl_propertylist_delete(plist);
01129
01130
01131 cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0);
01132 cpl_propertylist_delete(qclist);
01133
01134
01135 cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG, procat);
01136
01137
01138 filename = cpl_sprintf("isaac_spc_arc_set%d_pair%d.paf",
01139 isaac_spc_arc_config.set_nb, isaac_spc_arc_config.pair_nb);
01140 cpl_dfs_save_paf("ISAAC",
01141 "isaac_spc_arc",
01142 paflist,
01143 filename);
01144 cpl_free(filename);
01145 cpl_propertylist_delete(paflist);
01146 return 0;
01147 }
01148
01149
01156
01157 static int isaac_spc_arc_compare(const cpl_frame * frame1,
01158 const cpl_frame * frame2)
01159 {
01160 int comparison = 1;
01161 const char * file1 = cpl_frame_get_filename(frame1);
01162 const char * file2 = cpl_frame_get_filename(frame2);
01163 cpl_propertylist * plist1 = NULL;
01164 cpl_propertylist * plist2 = NULL;
01165 const char * sval1,
01166 * sval2;
01167 double dval1, dval2;
01168
01169 bug_if(frame1 == NULL);
01170 bug_if(frame2 == NULL);
01171
01172
01173 plist1 = cpl_propertylist_load(file1, 0);
01174 any_if("Could not load header from 1st frame %s", file1);
01175
01176 plist2 = cpl_propertylist_load(file2, 0);
01177 any_if("Could not load header from 2nd frame %s", file2);
01178
01179
01180 sval1 = isaac_pfits_get_opti1_id(plist1);
01181 any_if("Could not get slit from 1st frame %s", file1);
01182
01183 sval2 = isaac_pfits_get_opti1_id(plist2);
01184 any_if("Could not get slit from 2nd frame %s", file2);
01185
01186 if (strcmp(sval1, sval2)) comparison = 0;
01187
01188
01189 sval1 = isaac_pfits_get_resolution(plist1);
01190 any_if("Could not get resolution from 1st frame %s", file1);
01191
01192 sval2 = isaac_pfits_get_resolution(plist2);
01193 any_if("Could not get resolution from 2nd frame %s", file2);
01194
01195 if (strcmp(sval1, sval2)) comparison = 0;
01196
01197
01198 dval1 = isaac_pfits_get_wlen(plist1);
01199 any_if("Could not get wavelength from 1st frame %s", file1);
01200
01201 dval2 = isaac_pfits_get_wlen(plist2);
01202 any_if("Could not get wavelength from 2nd frame %s", file2);
01203
01204 if (fabs(dval1-dval2) > 1e-4) comparison = 0;
01205
01206 end_skip;
01207
01208 cpl_propertylist_delete(plist1);
01209 cpl_propertylist_delete(plist2);
01210
01211 return cpl_error_get_code() ? -1 : comparison;
01212 }
01213
01214
01221
01222 static int * isaac_spc_arc_find_lamps(cpl_frameset * fset)
01223 {
01224 int * lamps;
01225 int nframes;
01226 cpl_frame * cur_frame;
01227 cpl_propertylist * plist;
01228 int xenon, argon;
01229 int i;
01230
01231
01232 if (fset == NULL) return NULL;
01233
01234
01235 nframes = cpl_frameset_get_size(fset);
01236 xenon = argon = 0;
01237
01238
01239 lamps = cpl_malloc(nframes * sizeof(int));
01240
01241 for (i=0; i<nframes; i++) {
01242 cur_frame = cpl_frameset_get_frame(fset, i);
01243 plist=cpl_propertylist_load(cpl_frame_get_filename(cur_frame), 0);
01244 xenon = isaac_is_xenon_lamp_active(plist);
01245 argon = isaac_is_argon_lamp_active(plist);
01246 cpl_propertylist_delete(plist);
01247 if ((argon != 0 && argon != 1) || (xenon != 0 && xenon != 1)) {
01248 cpl_msg_error(cpl_func, "Could not check which lamp is on");
01249 cpl_free(lamps);
01250 return NULL;
01251 }
01252 if (xenon == 1) {
01253 if (argon == 1) lamps[i] = 3;
01254 else if (argon == 0) lamps[i] = 1;
01255 } else if (xenon == 0 ) {
01256 if (argon == 1) lamps[i] = 2;
01257 else if (argon == 0) lamps[i] = 0;
01258 }
01259 }
01260
01261
01262 return lamps;
01263 }
01264
01265
01271
01272 static int isaac_is_argon_lamp_active(const cpl_propertylist * plist)
01273 {
01274 int status1, status2;
01275
01276
01277 if (cpl_error_get_code()) return -1;
01278 status1 = isaac_pfits_get_lamp1_status(plist);
01279 if (cpl_error_get_code()) return -1;
01280 if (status1 == 1) {
01281
01282 status2 = isaac_pfits_get_calshut_status(plist);
01283 if (cpl_error_get_code()) {
01284 cpl_error_reset();
01285 return 1;
01286 }
01287 if (status2 == 1) return 1;
01288 }
01289 return 0;
01290 }
01291
01292
01298
01299 static int isaac_is_xenon_lamp_active(const cpl_propertylist * plist)
01300 {
01301 int status1, status2;
01302
01303
01304 if (cpl_error_get_code()) return -1;
01305 status1 = isaac_pfits_get_lamp2_status(plist);
01306 if (cpl_error_get_code()) return -1;
01307 if (status1 == 1) {
01308
01309 status2 = isaac_pfits_get_calshut_status(plist);
01310 if (cpl_error_get_code()) {
01311 cpl_error_reset();
01312 return 1;
01313 }
01314 if (status2 == 1) return 1;
01315 }
01316 return 0;
01317 }
01318
01319