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 #include <stdlib.h>
00033
00034 #include <cxstring.h>
00035 #include <cxslist.h>
00036 #include <cxstrutils.h>
00037
00038 #include <cpl_propertylist.h>
00039 #include <cpl_msg.h>
00040 #include <cpl_error.h>
00041
00042 #include "gialias.h"
00043 #include "gierror.h"
00044 #include "giframe.h"
00045 #include "gitable.h"
00046 #include "gimessages.h"
00047 #include "giutils.h"
00048 #include "gifiberutils.h"
00049
00050
00059 inline static cxint
00060 _giraffe_compare_int(cxcptr first, cxcptr second)
00061 {
00062
00063 cxint *_first = (cxint *)first;
00064 cxint *_second = (cxint *)second;
00065
00066 return *_first - *_second;
00067
00068 }
00069
00070
00091 cpl_table *
00092 giraffe_fiberlist_create(const cxchar *filename, cxint nspec,
00093 const cxint *spectra)
00094 {
00095
00096 const cxchar *const fctid = "giraffe_fiberlist_create";
00097
00098
00099 cxbool calsim;
00100
00101 cxint i;
00102 cxint status = 0;
00103
00104 cxint nfibers;
00105 cxint nbuttons;
00106
00107 cx_string *slit_name = NULL;
00108
00109 cpl_table *fibers = NULL;
00110 cpl_table *_slits;
00111 cpl_table *_ozpoz;
00112
00113 cpl_propertylist *properties = NULL;
00114 cpl_propertylist *sorting_order = NULL;
00115
00116 GiTable *slits = NULL;
00117 GiTable *ozpoz = NULL;
00118
00119 GiInstrumentMode mode;
00120
00121
00122
00123 if (!filename) {
00124 return NULL;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 properties = cpl_propertylist_load(filename, 0);
00134
00135 if (properties == NULL) {
00136 cpl_msg_error(fctid, "Cannot load properies of data set 0 "
00137 "from `%s'!", filename);
00138 cpl_propertylist_delete(properties);
00139 return NULL;
00140 }
00141 else {
00142
00143 if (!cpl_propertylist_has(properties, GIALIAS_STSCFF) &&
00144 !cpl_propertylist_has(properties, GIALIAS_STSCTAL)) {
00145 cpl_msg_warning(fctid, "%s: Properties (%s, %s) not found! "
00146 "Simultaneous calibration lamps assumed to "
00147 "be off!", filename, GIALIAS_STSCFF,
00148 GIALIAS_STSCTAL);
00149 calsim = FALSE;
00150 }
00151 else {
00152
00153 cxint scff = cpl_propertylist_get_bool(properties,
00154 GIALIAS_STSCFF);
00155 cxint sctal= cpl_propertylist_get_bool(properties,
00156 GIALIAS_STSCTAL);
00157
00158
00159 if (scff || sctal) {
00160 cpl_msg_info(fctid, "Simultaneous calibration lamps "
00161 "are on.");
00162 calsim = TRUE;
00163 }
00164 else {
00165 cpl_msg_info(fctid, "Simultaneous calibration lamps "
00166 "are off.");
00167 calsim = FALSE;
00168 }
00169
00170 }
00171
00172
00173 slit_name =
00174 cx_string_create(cpl_propertylist_get_string(properties,
00175 GIALIAS_SLITNAME));
00176 if (!slit_name) {
00177 cpl_msg_error(fctid, "%s: Property (%s) not found!", filename,
00178 GIALIAS_SLITNAME);
00179 cpl_propertylist_delete(properties);
00180 return NULL;
00181 }
00182 else {
00183 cx_string_strip(slit_name);
00184 }
00185
00186 mode = giraffe_get_mode(properties);
00187
00188 if (mode == GIMODE_NONE) {
00189 cpl_msg_error(fctid, "Invalid instrument mode!");
00190
00191 cx_string_delete(slit_name);
00192 cpl_propertylist_delete(properties);
00193
00194 return NULL;
00195 }
00196
00197 cpl_propertylist_delete(properties);
00198 }
00199
00200
00201
00202
00203
00204
00205 ozpoz = giraffe_table_new();
00206 cx_assert(ozpoz != NULL);
00207
00208 giraffe_error_push();
00209
00210 status = giraffe_table_load(ozpoz, filename, GIOZPOZ_EXTENSION,
00211 GIOZPOZ_MAGIC);
00212
00213 if (status) {
00214 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
00215 cpl_msg_error(fctid, "Data set %d in `%s' is not an "
00216 "OzPoz table!", GIOZPOZ_EXTENSION, filename);
00217 giraffe_table_delete(ozpoz);
00218 cpl_table_delete(fibers);
00219
00220 return NULL;
00221 }
00222 else {
00223 if (status != 2) {
00224 cpl_msg_error(fctid, "No OzPoz table found in `%s'!",
00225 filename);
00226 giraffe_table_delete(ozpoz);
00227 return NULL;
00228 }
00229
00230 cpl_msg_warning(fctid, "Empty OzPoz table found in `%s'.",
00231 filename);
00232
00233 }
00234 }
00235
00236 giraffe_error_pop();
00237
00238 _ozpoz = giraffe_table_get(ozpoz);
00239
00240
00241
00242
00243
00244
00245 slits = giraffe_table_new();
00246 cx_assert(slits != NULL);
00247
00248 giraffe_error_push();
00249
00250 if (giraffe_table_load(slits, filename, GIFIBER_EXTENSION,
00251 GIFIBER_MAGIC)) {
00252 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
00253 cpl_msg_error(fctid, "Data set %d in `%s' is not a fiber table!",
00254 GIFIBER_EXTENSION, filename);
00255 giraffe_table_delete(slits);
00256 return NULL;
00257 }
00258 else {
00259 cpl_msg_error(fctid, "Cannot load data set %d (fiber table) "
00260 "from `%s'!", GIFIBER_EXTENSION, filename);
00261 giraffe_table_delete(slits);
00262 return NULL;
00263 }
00264 }
00265
00266 giraffe_error_pop();
00267
00268 _slits = giraffe_table_get(slits);
00269
00270
00271
00272
00273
00274
00275 cpl_table_select_all(_slits);
00276 cpl_table_and_selected_string(_slits, "Slit", CPL_NOT_EQUAL_TO,
00277 cx_string_get(slit_name));
00278
00279 giraffe_error_push();
00280
00281 cpl_table_erase_selected(_slits);
00282
00283 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00284 cpl_msg_error(fctid, "Invalid slit `%s' selected. No fibers found.",
00285 cx_string_get(slit_name));
00286
00287 cx_string_delete(slit_name);
00288 slit_name = NULL;
00289
00290 giraffe_table_delete(slits);
00291 slits = NULL;
00292
00293 return NULL;
00294 }
00295
00296 giraffe_error_pop();
00297
00298 cx_string_delete(slit_name);
00299 slit_name = NULL;
00300
00301
00302
00303
00304
00305
00306
00307 nfibers = cpl_table_get_nrow(_slits);
00308 fibers = cpl_table_new(nfibers);
00309
00310 giraffe_error_push();
00311
00312 cpl_table_new_column(fibers, "INDEX", CPL_TYPE_INT);
00313 cpl_table_new_column(fibers, "FPS", CPL_TYPE_INT);
00314 cpl_table_new_column(fibers, "SSN", CPL_TYPE_INT);
00315 cpl_table_new_column(fibers, "PSSN", CPL_TYPE_INT);
00316 cpl_table_new_column(fibers, "RP", CPL_TYPE_INT);
00317
00318 for (i = 0; i < nfibers; i++) {
00319
00320 cxchar *s;
00321
00322 cxint fps = strtol(cpl_table_get_string(_slits, "FPS", i), NULL, 10);
00323 cxint ssn = strtol(cpl_table_get_string(_slits, "SSN", i), NULL, 10);
00324 cxint pssn = strtol(cpl_table_get_string(_slits, "PSSN", i),
00325 NULL, 10);
00326 cxint rp = -1;
00327
00328
00329 s = (cxchar*) cpl_table_get_string(_slits, "RP", i);
00330
00331 if (s != NULL) {
00332 rp = strtol(s, NULL, 10);
00333 }
00334 else {
00335 if (mode == GIMODE_ARGUS) {
00336
00337 const cxchar *rpid = cpl_table_get_string(_slits,
00338 "Retractor", i);
00339
00340 if (cx_strncasecmp(rpid, "Cal", 3) != 0) {
00341 rp = 0;
00342 }
00343
00344 }
00345 }
00346
00347 cpl_table_set_int(fibers, "FPS", i, fps);
00348 cpl_table_set_int(fibers, "SSN", i, ssn);
00349 cpl_table_set_int(fibers, "PSSN", i, pssn);
00350 cpl_table_set_int(fibers, "RP", i, rp);
00351
00352 }
00353
00354 if (mode == GIMODE_IFU || mode == GIMODE_ARGUS) {
00355
00356 if (cpl_table_has_column(_slits, "X") &&
00357 cpl_table_has_column(_slits, "Y")) {
00358
00359 cpl_table_new_column(fibers, "X", CPL_TYPE_INT);
00360 cpl_table_new_column(fibers, "Y", CPL_TYPE_INT);
00361
00362 for (i = 0; i < nfibers; i++) {
00363 const cxchar *s;
00364
00365 cxint x = 0;
00366 cxint y = 0;
00367
00368
00369 s = cpl_table_get_string(_slits, "X", i);
00370
00371 if (s != NULL) {
00372 x = strtol(s, NULL, 10);
00373 }
00374
00375 s = cpl_table_get_string(_slits, "Y", i);
00376
00377 if (s != NULL) {
00378 y = strtol(s, NULL, 10);
00379 }
00380
00381 cpl_table_set_int(fibers, "X", i, x);
00382 cpl_table_set_int(fibers, "Y", i, y);
00383 }
00384
00385 }
00386
00387 }
00388
00389 cpl_table_move_column(fibers, "Retractor", _slits);
00390
00391 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00392 cpl_msg_error(fctid, "Data set %d in `%s' is not a valid "
00393 "fiber table!", GIFIBER_EXTENSION, filename);
00394 giraffe_table_delete(slits);
00395 cpl_table_delete(fibers);
00396
00397 return NULL;
00398 }
00399
00400 giraffe_error_pop();
00401
00402 giraffe_table_delete(slits);
00403
00404
00405
00406
00407
00408
00409
00410 if (mode == GIMODE_ARGUS) {
00411
00412 sorting_order = cpl_propertylist_new();
00413
00414 cpl_propertylist_append_bool(sorting_order, "FPS", 1);
00415 cpl_table_sort(fibers, sorting_order);
00416
00417 cpl_propertylist_delete(sorting_order);
00418 sorting_order = NULL;
00419
00420 }
00421
00422
00423
00424
00425
00426
00427 for (i = 0; i < nfibers; i++) {
00428
00429 const cxchar *s = cpl_table_get_string(fibers, "Retractor", i);
00430
00431
00432 if (strstr(s, "Calibration")) {
00433 cpl_table_set_int(fibers, "RP", i, -1);
00434 }
00435
00436 cpl_table_set_int(fibers, "INDEX", i, i + 1);
00437
00438 }
00439
00440 if (!cpl_table_has_column(fibers, "FPD")) {
00441 cpl_table_duplicate_column(fibers, "FPD", fibers, "INDEX");
00442 }
00443
00444 cpl_table_new_column(fibers, "OBJECT", CPL_TYPE_STRING);
00445 cpl_table_new_column(fibers, "R", CPL_TYPE_DOUBLE);
00446 cpl_table_new_column(fibers, "THETA", CPL_TYPE_DOUBLE);
00447 cpl_table_new_column(fibers, "ORIENT", CPL_TYPE_DOUBLE);
00448 cpl_table_new_column(fibers, "TYPE", CPL_TYPE_STRING);
00449
00450 cpl_table_fill_column_window_double(fibers, "R", 0, nfibers, 0.);
00451 cpl_table_fill_column_window_double(fibers, "THETA", 0, nfibers, 0.);
00452 cpl_table_fill_column_window_double(fibers, "ORIENT", 0, nfibers, 0.);
00453
00454 if (_ozpoz != NULL) {
00455 if (cpl_table_has_column(_ozpoz, "RA")) {
00456 cpl_table_new_column(fibers, "RA", CPL_TYPE_DOUBLE);
00457 cpl_table_fill_column_window_double(fibers, "RA", 0,
00458 nfibers, 0.);
00459 }
00460
00461 if (cpl_table_has_column(_ozpoz, "DEC")) {
00462 cpl_table_new_column(fibers, "DEC", CPL_TYPE_DOUBLE);
00463 cpl_table_fill_column_window_double(fibers, "DEC", 0,
00464 nfibers, 0.);
00465 }
00466
00467 if (cpl_table_has_column(_ozpoz, "MAGNITUDE")) {
00468 cpl_table_new_column(fibers, "MAGNITUDE", CPL_TYPE_DOUBLE);
00469 cpl_table_fill_column_window_double(fibers, "MAGNITUDE", 0,
00470 nfibers, 0.);
00471 }
00472
00473 if (cpl_table_has_column(_ozpoz, "B_V")) {
00474 cpl_table_new_column(fibers, "B_V", CPL_TYPE_DOUBLE);
00475 cpl_table_fill_column_window_double(fibers, "B_V", 0,
00476 nfibers, 0.);
00477 }
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 nbuttons = _ozpoz == NULL ? 0 : cpl_table_get_nrow(_ozpoz);
00490
00491 cpl_table_select_all(fibers);
00492
00493 for (i = 0; i < nfibers; i++) {
00494
00495 cxbool missing = TRUE;
00496
00497 cxint fiber = cpl_table_get_int(fibers, "RP", i, NULL);
00498
00499
00500
00501
00502
00503
00504
00505
00506 if (fiber == -1 && calsim == TRUE) {
00507 cpl_table_set_string(fibers, "OBJECT", i, "CALSIM");
00508 cpl_table_unselect_row(fibers, i);
00509 missing = FALSE;
00510 }
00511 else if (fiber == 0 && mode == GIMODE_ARGUS) {
00512 cpl_table_unselect_row(fibers, i);
00513 missing = FALSE;
00514 }
00515 else {
00516
00517 register cxint j;
00518
00519
00520 for (j = 0; j < nbuttons; j++) {
00521
00522 cxint button = cpl_table_get_int(_ozpoz, "BUTTON", j, NULL);
00523
00524
00525 if (fiber == button) {
00526 const cxchar *object;
00527 const cxchar *otype;
00528
00529 cxdouble r, theta, orient;
00530
00531 cxdouble ra = 0.;
00532 cxdouble dec = 0.;
00533 cxdouble mag = 0.;
00534 cxdouble b_v = 0.;
00535
00536
00537 object = cpl_table_get_string(_ozpoz, "OBJECT", j);
00538 otype = cpl_table_get_string(_ozpoz, "TYPE", j);
00539
00540 r = cpl_table_get_double(_ozpoz, "R", j, NULL);
00541 theta = cpl_table_get_double(_ozpoz, "THETA", j, NULL);
00542 orient = cpl_table_get_double(_ozpoz, "ORIENT", j, NULL);
00543
00544 if (cpl_table_has_column(_ozpoz, "RA")) {
00545 ra = cpl_table_get_double(_ozpoz, "RA", j, NULL);
00546 }
00547
00548 if (cpl_table_has_column(_ozpoz, "DEC")) {
00549 dec = cpl_table_get_double(_ozpoz, "DEC", j, NULL);
00550 }
00551
00552 if (cpl_table_has_column(_ozpoz, "MAGNITUDE")) {
00553 mag = cpl_table_get_float(_ozpoz, "MAGNITUDE", j,
00554 NULL);
00555 }
00556
00557 if (cpl_table_has_column(_ozpoz, "B_V")) {
00558 b_v = cpl_table_get_double(_ozpoz, "B_V", j, NULL);
00559 b_v = CX_CLAMP(b_v, -5., 5.);
00560 }
00561
00562 cpl_table_set_string(fibers, "OBJECT", i, object);
00563 cpl_table_set_string(fibers, "TYPE", i, otype);
00564
00565 cpl_table_set_double(fibers, "R", i, r);
00566 cpl_table_set_double(fibers, "THETA", i, theta);
00567 cpl_table_set_double(fibers, "ORIENT", i, orient);
00568
00569 if (cpl_table_has_column(fibers, "RA")) {
00570 cpl_table_set_double(fibers, "RA", i, ra);
00571 }
00572
00573 if (cpl_table_has_column(fibers, "DEC")) {
00574 cpl_table_set_double(fibers, "DEC", i, dec);
00575 }
00576
00577 if (cpl_table_has_column(fibers, "MAGNITUDE")) {
00578 cpl_table_set_double(fibers, "MAGNITUDE", i, mag);
00579 }
00580
00581 if (cpl_table_has_column(fibers, "B_V")) {
00582 cpl_table_set_double(fibers, "B_V", i, b_v);
00583 }
00584
00585 cpl_table_unselect_row(fibers, i);
00586 missing = FALSE;
00587 break;
00588 }
00589 }
00590 }
00591
00592 if (missing == TRUE) {
00593
00594 cxint _fps = cpl_table_get_int(fibers, "FPS", i, NULL);
00595 cpl_msg_debug(fctid, "Fiber at FPS = %d is not used", _fps);
00596
00597 }
00598
00599 }
00600
00601
00602 giraffe_error_push();
00603
00604 cpl_table_erase_selected(fibers);
00605
00606 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00607 cpl_table_delete(fibers);
00608 return NULL;
00609 }
00610
00611 giraffe_error_pop();
00612
00613 giraffe_table_delete(ozpoz);
00614 ozpoz = NULL;
00615
00616
00617
00618
00619
00620
00621
00622
00623 if (spectra && nspec > 0) {
00624
00625 register cxint rows = cpl_table_get_nrow(fibers);
00626
00627
00628 cx_assert(cpl_table_get_column_type(fibers, "FPD") == CPL_TYPE_INT);
00629
00630 cpl_table_select_all(fibers);
00631
00632 for (i = 0; i < rows; i++) {
00633
00634 register cxint j;
00635 register cxint selected = 0;
00636 register cxint idx = cpl_table_get_int(fibers, "FPD", i, NULL);
00637
00638
00639 for (j = 0; j < nspec; j++) {
00640 if (idx == spectra[j]) {
00641 selected = 1;
00642 break;
00643 }
00644 }
00645
00646 if (selected) {
00647 cpl_table_unselect_row(fibers, i);
00648 }
00649 else {
00650 cpl_table_select_row(fibers, i);
00651 }
00652
00653 }
00654
00655 giraffe_error_push();
00656
00657 cpl_table_erase_selected(fibers);
00658
00659 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00660 cpl_table_delete(fibers);
00661 return NULL;
00662 }
00663
00664 giraffe_error_pop();
00665
00666 }
00667
00668
00669
00670
00671
00672
00673 for (i = 0; i < cpl_table_get_nrow(fibers); i++) {
00674 cpl_table_set_int(fibers, "INDEX", i, i + 1);
00675 }
00676
00677
00678
00679
00680
00681
00682 cx_assert(sorting_order == NULL);
00683
00684 sorting_order = cpl_propertylist_new();
00685 cpl_propertylist_append_bool(sorting_order, "INDEX", 0);
00686
00687 cpl_table_sort(fibers, sorting_order);
00688
00689 cpl_propertylist_delete(sorting_order);
00690 sorting_order = NULL;
00691
00692
00693 return fibers;
00694
00695 }
00696
00697
00721 GiTable *
00722 giraffe_fiberlist_load(const cxchar *filename, cxint dataset,
00723 const cxchar *tag)
00724 {
00725
00726 const cxchar *fctid = "giraffe_fiberlist_load";
00727
00728
00729 GiTable *fibers = giraffe_table_new();
00730
00731
00732 cx_assert(fibers != NULL);
00733
00734 giraffe_error_push();
00735
00736 if (giraffe_table_load(fibers, filename, dataset, tag)) {
00737 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
00738 cpl_msg_error(fctid, "Data set %d in `%s' is not a fiber table!",
00739 dataset, filename);
00740 giraffe_table_delete(fibers);
00741 return NULL;
00742 }
00743 else {
00744 cpl_msg_error(fctid, "Cannot load data set %d (fiber table) "
00745 "from `%s'!", dataset, filename);
00746 giraffe_table_delete(fibers);
00747 return NULL;
00748 }
00749 }
00750
00751 giraffe_error_pop();
00752
00753 return fibers;
00754
00755 }
00756
00757
00774 cxint
00775 giraffe_fiberlist_save(GiTable *fibers, const cxchar *filename)
00776 {
00777
00778 const cxchar *fctid = "giraffe_fiberlist_save";
00779
00780 cxbool created = FALSE;
00781
00782 cxint code;
00783
00784 cpl_propertylist *properties = NULL;
00785 cpl_table *table = NULL;
00786
00787
00788 if (fibers == NULL || filename == NULL) {
00789 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00790 return 1;
00791 }
00792
00793 table = giraffe_table_get(fibers);
00794
00795 if (table == NULL) {
00796 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00797 return 1;
00798 }
00799
00800 properties = giraffe_table_get_properties(fibers);
00801
00802 if (properties == NULL) {
00803 properties = cpl_propertylist_new();
00804
00805 cpl_propertylist_append_string(properties, GIALIAS_EXTNAME,
00806 GIFRAME_FIBER_SETUP);
00807 created = TRUE;
00808
00809 giraffe_table_set_properties(fibers, properties);
00810 }
00811 else {
00812 if (cpl_propertylist_has(properties, GIALIAS_EXTNAME)) {
00813 cpl_propertylist_set_string(properties, GIALIAS_EXTNAME,
00814 GIFRAME_FIBER_SETUP);
00815 }
00816 else {
00817 cpl_propertylist_append_string(properties, GIALIAS_EXTNAME,
00818 GIFRAME_FIBER_SETUP);
00819 }
00820 }
00821 cpl_propertylist_set_comment(properties, GIALIAS_EXTNAME,
00822 "FITS Extension name");
00823
00824 code = cpl_table_save(table, NULL, properties, filename, CPL_IO_EXTEND);
00825
00826 if (created == TRUE) {
00827 cpl_propertylist_delete(properties);
00828 }
00829
00830 return code == CPL_ERROR_NONE ? 0 : 1;
00831
00832 }
00833
00834
00851 cxint
00852 giraffe_fiberlist_attach(cpl_frame *frame, GiTable *fibers)
00853 {
00854
00855 const cxchar *fctid = "giraffe_fiberlist_attach";
00856
00857
00858 cxbool created = FALSE;
00859
00860 cxint status = 0;
00861
00862 cpl_propertylist *properties = NULL;
00863
00864 GiTable *_fibers = NULL;
00865
00866
00867 if (frame == NULL || fibers == NULL) {
00868 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00869 return 1;
00870 }
00871
00872 _fibers = giraffe_table_duplicate(fibers);
00873
00874 properties = giraffe_table_get_properties(_fibers);
00875
00876 if (properties == NULL) {
00877 properties = cpl_propertylist_new();
00878 giraffe_table_set_properties(_fibers, properties);
00879 created = TRUE;
00880 }
00881
00882 if (cpl_table_has_column(giraffe_table_get(_fibers), "RINDEX")) {
00883 cpl_table_erase_column(giraffe_table_get(_fibers), "RINDEX");
00884 }
00885
00886 status = giraffe_frame_attach_table(frame, _fibers, GIFRAME_FIBER_SETUP,
00887 TRUE);
00888
00889 if (created == TRUE) {
00890 cpl_propertylist_delete(properties);
00891 }
00892
00893 properties = NULL;
00894
00895 giraffe_table_delete(_fibers);
00896 _fibers = NULL;
00897
00898 return status;
00899
00900 }
00901
00902
00920 cxint giraffe_fiberlist_compare(const GiTable *fibers,
00921 const GiTable *reference)
00922 {
00923
00924 register cxint i;
00925 cxint equal = 1;
00926
00927 cpl_table *_fibers = giraffe_table_get(fibers);
00928 cpl_table *_reference = giraffe_table_get(reference);
00929
00930
00931 if (_fibers == NULL || _reference == NULL) {
00932 return -1;
00933 }
00934
00935 if (!cpl_table_has_column(_fibers, "FPS") ||
00936 !cpl_table_has_column(_reference, "FPS")) {
00937 return -2;
00938 }
00939
00940
00941 for (i = 0; i < cpl_table_get_nrow(_reference); i++) {
00942
00943 cxbool found = FALSE;
00944
00945 cxint j;
00946 cxint fps = cpl_table_get_int(_reference, "FPS", i, NULL);
00947
00948 for (j = 0; j < cpl_table_get_nrow(_fibers); j++) {
00949 cxint _fps = cpl_table_get_int(_fibers, "FPS", j, NULL);
00950
00951 if (fps == _fps) {
00952 found = TRUE;
00953 break;
00954 }
00955 }
00956
00957 if (found == FALSE) {
00958 equal = 0;
00959 break;
00960 }
00961
00962 }
00963
00964 return equal;
00965
00966 }
00967
00968
00989 cxint
00990 giraffe_fiberlist_associate(GiTable *fibers, const GiTable *reference)
00991 {
00992
00993 const cxchar *fctid = "giraffe_fiberlist_associate";
00994
00995 register cxint i;
00996
00997 cxint nf = 0;
00998 cxint nr = 0;
00999
01000 cpl_table *_fibers = NULL;
01001 cpl_table *_reference = NULL;
01002
01003
01004 if (fibers == NULL) {
01005 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
01006 return 1;
01007 }
01008
01009 if (reference == NULL) {
01010 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
01011 return 1;
01012 }
01013
01014 _fibers = giraffe_table_get(fibers);
01015 _reference = giraffe_table_get(reference);
01016
01017 if (!cpl_table_has_column(_fibers, "FPS")) {
01018 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
01019 return 1;
01020 }
01021
01022 if (!cpl_table_has_column(_reference, "FPS")) {
01023 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
01024 return 1;
01025 }
01026
01027
01028
01029
01030
01031
01032
01033
01034 if (!cpl_table_has_column(_fibers, "RINDEX")) {
01035
01036 cxint size = cpl_table_get_nrow(_fibers);
01037
01038 cxint status = cpl_table_duplicate_column(_fibers, "RINDEX",
01039 _fibers, "INDEX");
01040
01041 if (status != CPL_ERROR_NONE) {
01042 return 2;
01043 }
01044
01045 status = cpl_table_fill_column_window_int(_fibers, "RINDEX", 0,
01046 size, -1);
01047
01048 if (status != CPL_ERROR_NONE) {
01049 return 2;
01050 }
01051
01052 }
01053
01054
01055
01056
01057
01058
01059
01060
01061 nf = cpl_table_get_nrow(_fibers);
01062 nr = cpl_table_get_nrow(_reference);
01063
01064 cpl_table_unselect_all(_fibers);
01065
01066 for (i = 0; i < nf; i++) {
01067
01068 register cxint j;
01069
01070 cxint fps = cpl_table_get_int(_fibers, "FPS", i, NULL);
01071
01072
01073 for (j = 0; j < nr; j++) {
01074
01075 cxint _fps = cpl_table_get_int(_reference, "FPS", j, NULL);
01076
01077
01078 if (fps == _fps) {
01079
01080 cxint ridx = cpl_table_get_int(_reference, "INDEX", j, NULL);
01081
01082 cpl_table_set_int(_fibers, "RINDEX", i, ridx);
01083 cpl_table_select_row(_fibers, i);
01084
01085 break;
01086 }
01087 }
01088 }
01089
01090
01091
01092
01093
01094
01095
01096
01097 _fibers = cpl_table_extract_selected(_fibers);
01098
01099
01100
01101
01102
01103
01104 for (i = 0; i < cpl_table_get_nrow(_fibers); i++) {
01105 cpl_table_set_int(_fibers, "INDEX", i, i + 1);
01106 }
01107
01108
01109 giraffe_table_set(fibers, _fibers);
01110
01111 cpl_table_delete(_fibers);
01112
01113 return 0;
01114
01115 }
01116
01117
01131 cxint
01132 giraffe_fiberlist_clear_index(GiTable* fibers)
01133 {
01134
01135 cpl_table* _fibers = NULL;
01136
01137 if (fibers == NULL) {
01138 return -1;
01139 }
01140
01141 _fibers = giraffe_table_get(fibers);
01142
01143 if (_fibers == NULL) {
01144 return 1;
01145 }
01146
01147 giraffe_error_push();
01148
01149 if (cpl_table_has_column(_fibers, "RINDEX") == TRUE) {
01150 cpl_table_erase_column(_fibers, "RINDEX");
01151 }
01152
01153 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01154 return 2;
01155 }
01156
01157 giraffe_error_pop();
01158
01159 return 0;
01160
01161 }
01177 const cxchar *
01178 giraffe_fiberlist_query_index(const cpl_table *fibers)
01179 {
01180
01181 const cxchar *names[] = {"RINDEX", "INDEX", NULL};
01182 const cxchar **idx = names;
01183
01184
01185 while (*idx != NULL) {
01186
01187 if (cpl_table_has_column((cpl_table *)fibers, *idx) != 0) {
01188 break;
01189 }
01190
01191 ++idx;
01192 }
01193
01194 return *idx;
01195
01196 }
01197
01198
01214 cpl_array*
01215 giraffe_fiberlist_get_subslits(const cpl_table* fibers)
01216 {
01217
01218 cxint nfibers = 0;
01219
01220 cpl_array* subslits = NULL;
01221
01222
01223 cx_assert(fibers != NULL);
01224
01225 nfibers = cpl_table_get_nrow(fibers);
01226
01227
01228 if (nfibers > 0) {
01229
01230 cxint i = 0;
01231 cxint nss = 0;
01232 cxint* ssn = NULL;
01233
01234
01235 subslits = cpl_array_new(nfibers, CPL_TYPE_INT);
01236 cpl_array_fill_window(subslits, 0, nfibers, 0);
01237
01238 ssn = cpl_array_get_data_int(subslits);
01239
01240
01241
01242
01243
01244
01245 for (i = 0; i < nfibers; ++i) {
01246 ssn[i] = cpl_table_get_int(fibers, "SSN", i, NULL);
01247 }
01248
01249 qsort(ssn, nfibers, sizeof(cxint), _giraffe_compare_int);
01250
01251
01252
01253
01254
01255
01256 for (i = 1; i < nfibers; ++i) {
01257 if (ssn[i] != ssn[nss]) {
01258 ssn[++nss] = ssn[i];
01259 }
01260 }
01261
01262 ++nss;
01263 cpl_array_set_size(subslits, nss);
01264
01265 }
01266
01267 return subslits;
01268
01269 }
01270
01271
01301 cxint *
01302 giraffe_parse_spectrum_selection(const cxchar *selection, cxint *nspec)
01303 {
01304
01305 cxchar **lists = NULL;
01306 cxchar **ranges = NULL;
01307
01308 cxint i;
01309 cxint first = 0;
01310 cxint nfibers = 0;
01311 cxint *fibers = NULL;
01312 cxint *_fibers = NULL;
01313
01314 cx_slist *fl = NULL;
01315
01316 cx_slist_iterator pos;
01317
01318
01319 *nspec = 0;
01320
01321 lists = cx_strsplit(selection, ";", 2);
01322
01323 if (lists == NULL) {
01324 return NULL;
01325 }
01326
01327 if (lists[1] != NULL) {
01328 gi_warning("Usage of fiber exclusion lists is not supported! "
01329 "The given exclusion list is ignored!");
01330 }
01331
01332 ranges = cx_strsplit(lists[0], ",", -1);
01333
01334 if (ranges == NULL) {
01335 cx_strfreev(lists);
01336 return NULL;
01337 }
01338
01339 i = 0;
01340 while (ranges[i] != NULL) {
01341
01342 cxchar **bounds = cx_strsplit(ranges[i], "-", 2);
01343
01344 cxint j;
01345
01346
01347 if (bounds == NULL) {
01348 cx_strfreev(ranges);
01349 cx_strfreev(lists);
01350
01351 if (fibers) {
01352 cx_free(fibers);
01353 }
01354
01355 return NULL;
01356 }
01357 else {
01358
01359 cxchar *last;
01360
01361 cxlong lower = -1;
01362 cxlong upper = -1;
01363
01364
01365 lower = strtol(bounds[0], &last, 10);
01366
01367 if (*last != '\0') {
01368 cx_strfreev(bounds);
01369 cx_strfreev(ranges);
01370 cx_strfreev(lists);
01371
01372 if (fibers) {
01373 cx_free(fibers);
01374 }
01375
01376 return NULL;
01377 }
01378
01379 if (bounds[1] != NULL) {
01380
01381 upper = strtol(bounds[1], &last, 10);
01382
01383 if (*last != '\0') {
01384 cx_strfreev(bounds);
01385 cx_strfreev(ranges);
01386 cx_strfreev(lists);
01387
01388 if (fibers) {
01389 cx_free(fibers);
01390 }
01391
01392 return NULL;
01393 }
01394 }
01395
01396 upper = upper > 0 ? upper : lower;
01397
01398 if (lower <= 0 || upper <= 0 || upper < lower) {
01399 cx_strfreev(bounds);
01400 cx_strfreev(ranges);
01401 cx_strfreev(lists);
01402
01403 if (fibers) {
01404 cx_free(fibers);
01405 }
01406
01407 return NULL;
01408 }
01409
01410 ++nfibers;
01411
01412 if (upper > lower) {
01413 nfibers += upper - lower;
01414 }
01415
01416 fibers = cx_realloc(fibers, nfibers * sizeof(cxint));
01417
01418 for (j = first; j < nfibers; j++) {
01419 fibers[j] = lower + j - first;
01420 }
01421
01422 first = nfibers;
01423
01424 }
01425
01426 cx_strfreev(bounds);
01427 bounds = NULL;
01428
01429 ++i;
01430
01431 }
01432
01433 cx_strfreev(ranges);
01434 cx_strfreev(lists);
01435
01436 qsort(fibers, nfibers, sizeof(cxint), _giraffe_compare_int);
01437
01438
01439
01440
01441
01442
01443 fl = cx_slist_new();
01444
01445 for (i = 0; i < nfibers; i++) {
01446 cx_slist_push_back(fl, fibers + i);
01447 }
01448
01449 cx_slist_unique(fl, _giraffe_compare_int);
01450
01451 nfibers = cx_slist_size(fl);
01452 _fibers = cx_malloc(nfibers * sizeof(cxint));
01453
01454 i = 0;
01455
01456 pos = cx_slist_begin(fl);
01457 while (pos != cx_slist_end(fl)) {
01458
01459 cxint *fn = cx_slist_get(fl, pos);
01460
01461 cx_assert(fn != NULL);
01462 _fibers[i] = *fn;
01463
01464 pos = cx_slist_next(fl, pos);
01465 ++i;
01466 }
01467 cx_slist_delete(fl);
01468 cx_free(fibers);
01469
01470 *nspec = nfibers;
01471 return _fibers;
01472
01473 }