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