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
00449 cpl_table_fill_column_window_double(fibers, "R", 0, nfibers, 0.);
00450 cpl_table_fill_column_window_double(fibers, "THETA", 0, nfibers, 0.);
00451 cpl_table_fill_column_window_double(fibers, "ORIENT", 0, nfibers, 0.);
00452
00453 if (_ozpoz != NULL) {
00454 if (cpl_table_has_column(_ozpoz, "RA")) {
00455 cpl_table_new_column(fibers, "RA", CPL_TYPE_DOUBLE);
00456 cpl_table_fill_column_window_double(fibers, "RA", 0,
00457 nfibers, 0.);
00458 }
00459
00460 if (cpl_table_has_column(_ozpoz, "DEC")) {
00461 cpl_table_new_column(fibers, "DEC", CPL_TYPE_DOUBLE);
00462 cpl_table_fill_column_window_double(fibers, "DEC", 0,
00463 nfibers, 0.);
00464 }
00465
00466 if (cpl_table_has_column(_ozpoz, "MAGNITUDE")) {
00467 cpl_table_new_column(fibers, "MAGNITUDE", CPL_TYPE_DOUBLE);
00468 cpl_table_fill_column_window_double(fibers, "MAGNITUDE", 0,
00469 nfibers, 0.);
00470 }
00471
00472 if (cpl_table_has_column(_ozpoz, "B_V")) {
00473 cpl_table_new_column(fibers, "B_V", CPL_TYPE_DOUBLE);
00474 cpl_table_fill_column_window_double(fibers, "B_V", 0,
00475 nfibers, 0.);
00476 }
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 nbuttons = _ozpoz == NULL ? 0 : cpl_table_get_nrow(_ozpoz);
00489
00490 cpl_table_select_all(fibers);
00491
00492 for (i = 0; i < nfibers; i++) {
00493
00494 cxint fiber = cpl_table_get_int(fibers, "RP", i, NULL);
00495
00496
00497
00498
00499
00500
00501
00502
00503 if (fiber == -1 && calsim == TRUE) {
00504 cpl_table_set_string(fibers, "OBJECT", i, "CALSIM");
00505 cpl_table_unselect_row(fibers, i);
00506 }
00507 else if (fiber == 0 && mode == GIMODE_ARGUS) {
00508 cpl_table_unselect_row(fibers, i);
00509 }
00510 else {
00511
00512 register cxint j;
00513
00514
00515 for (j = 0; j < nbuttons; j++) {
00516
00517 cxint button = cpl_table_get_int(_ozpoz, "BUTTON", j, NULL);
00518
00519
00520 if (fiber == button) {
00521 const cxchar *object;
00522
00523 cxdouble r, theta, orient;
00524
00525 cxdouble ra = 0.;
00526 cxdouble dec = 0.;
00527 cxdouble mag = 0.;
00528 cxdouble b_v = 0.;
00529
00530
00531 object = cpl_table_get_string(_ozpoz, "OBJECT", j);
00532
00533 r = cpl_table_get_double(_ozpoz, "R", j, NULL);
00534 theta = cpl_table_get_double(_ozpoz, "THETA", j, NULL);
00535 orient = cpl_table_get_double(_ozpoz, "ORIENT", j, NULL);
00536
00537 if (cpl_table_has_column(_ozpoz, "RA")) {
00538 ra = cpl_table_get_double(_ozpoz, "RA", j, NULL);
00539 }
00540
00541 if (cpl_table_has_column(_ozpoz, "DEC")) {
00542 dec = cpl_table_get_double(_ozpoz, "DEC", j, NULL);
00543 }
00544
00545 if (cpl_table_has_column(_ozpoz, "MAGNITUDE")) {
00546 mag = cpl_table_get_float(_ozpoz, "MAGNITUDE", j,
00547 NULL);
00548 }
00549
00550 if (cpl_table_has_column(_ozpoz, "B_V")) {
00551 b_v = cpl_table_get_double(_ozpoz, "B_V", j, NULL);
00552 b_v = CX_CLAMP(b_v, -5., 5.);
00553 }
00554
00555 cpl_table_set_string(fibers, "OBJECT", i, object);
00556
00557 cpl_table_set_double(fibers, "R", i, r);
00558 cpl_table_set_double(fibers, "THETA", i, theta);
00559 cpl_table_set_double(fibers, "ORIENT", i, orient);
00560
00561 if (cpl_table_has_column(fibers, "RA")) {
00562 cpl_table_set_double(fibers, "RA", i, ra);
00563 }
00564
00565 if (cpl_table_has_column(fibers, "DEC")) {
00566 cpl_table_set_double(fibers, "DEC", i, dec);
00567 }
00568
00569 if (cpl_table_has_column(fibers, "MAGNITUDE")) {
00570 cpl_table_set_double(fibers, "MAGNITUDE", i, mag);
00571 }
00572
00573 if (cpl_table_has_column(fibers, "B_V")) {
00574 cpl_table_set_double(fibers, "B_V", i, b_v);
00575 }
00576
00577 cpl_table_unselect_row(fibers, i);
00578 break;
00579 }
00580 }
00581 }
00582 }
00583
00584
00585 giraffe_error_push();
00586
00587 cpl_table_erase_selected(fibers);
00588
00589 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00590 cpl_table_delete(fibers);
00591 return NULL;
00592 }
00593
00594 giraffe_error_pop();
00595
00596 giraffe_table_delete(ozpoz);
00597 ozpoz = NULL;
00598
00599
00600
00601
00602
00603
00604
00605
00606 if (spectra && nspec > 0) {
00607
00608 register cxint rows = cpl_table_get_nrow(fibers);
00609
00610
00611 cx_assert(cpl_table_get_column_type(fibers, "FPD") == CPL_TYPE_INT);
00612
00613 cpl_table_select_all(fibers);
00614
00615 for (i = 0; i < rows; i++) {
00616
00617 register cxint j;
00618 register cxint selected = 0;
00619 register cxint idx = cpl_table_get_int(fibers, "FPD", i, NULL);
00620
00621
00622 for (j = 0; j < nspec; j++) {
00623 if (idx == spectra[j]) {
00624 selected = 1;
00625 break;
00626 }
00627 }
00628
00629 if (selected) {
00630 cpl_table_unselect_row(fibers, i);
00631 }
00632 else {
00633 cpl_table_select_row(fibers, i);
00634 }
00635
00636 }
00637
00638 giraffe_error_push();
00639
00640 cpl_table_erase_selected(fibers);
00641
00642 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00643 cpl_table_delete(fibers);
00644 return NULL;
00645 }
00646
00647 giraffe_error_pop();
00648
00649 }
00650
00651
00652
00653
00654
00655
00656 for (i = 0; i < cpl_table_get_nrow(fibers); i++) {
00657 cpl_table_set_int(fibers, "INDEX", i, i + 1);
00658 }
00659
00660
00661
00662
00663
00664
00665 cx_assert(sorting_order == NULL);
00666
00667 sorting_order = cpl_propertylist_new();
00668 cpl_propertylist_append_bool(sorting_order, "INDEX", 0);
00669
00670 cpl_table_sort(fibers, sorting_order);
00671
00672 cpl_propertylist_delete(sorting_order);
00673 sorting_order = NULL;
00674
00675
00676 return fibers;
00677
00678 }
00679
00680
00704 GiTable *
00705 giraffe_fiberlist_load(const cxchar *filename, cxint dataset,
00706 const cxchar *tag)
00707 {
00708
00709 const cxchar *fctid = "giraffe_fiberlist_load";
00710
00711
00712 GiTable *fibers = giraffe_table_new();
00713
00714
00715 cx_assert(fibers != NULL);
00716
00717 giraffe_error_push();
00718
00719 if (giraffe_table_load(fibers, filename, dataset, tag)) {
00720 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
00721 cpl_msg_error(fctid, "Data set %d in `%s' is not a fiber table!",
00722 dataset, filename);
00723 giraffe_table_delete(fibers);
00724 return NULL;
00725 }
00726 else {
00727 cpl_msg_error(fctid, "Cannot load data set %d (fiber table) "
00728 "from `%s'!", dataset, filename);
00729 giraffe_table_delete(fibers);
00730 return NULL;
00731 }
00732 }
00733
00734 giraffe_error_pop();
00735
00736 return fibers;
00737
00738 }
00739
00740
00757 cxint
00758 giraffe_fiberlist_save(GiTable *fibers, const cxchar *filename)
00759 {
00760
00761 const cxchar *fctid = "giraffe_fiberlist_save";
00762
00763 cxbool created = FALSE;
00764
00765 cxint code;
00766
00767 cpl_propertylist *properties = NULL;
00768 cpl_table *table = NULL;
00769
00770
00771 if (fibers == NULL || filename == NULL) {
00772 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00773 return 1;
00774 }
00775
00776 table = giraffe_table_get(fibers);
00777
00778 if (table == NULL) {
00779 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00780 return 1;
00781 }
00782
00783 properties = giraffe_table_get_properties(fibers);
00784
00785 if (properties == NULL) {
00786 properties = cpl_propertylist_new();
00787
00788 cpl_propertylist_append_string(properties, GIALIAS_EXTNAME,
00789 GIFRAME_FIBER_SETUP);
00790 created = TRUE;
00791
00792 giraffe_table_set_properties(fibers, properties);
00793 }
00794 else {
00795 if (cpl_propertylist_has(properties, GIALIAS_EXTNAME)) {
00796 cpl_propertylist_set_string(properties, GIALIAS_EXTNAME,
00797 GIFRAME_FIBER_SETUP);
00798 }
00799 else {
00800 cpl_propertylist_append_string(properties, GIALIAS_EXTNAME,
00801 GIFRAME_FIBER_SETUP);
00802 }
00803 }
00804 cpl_propertylist_set_comment(properties, GIALIAS_EXTNAME,
00805 "FITS Extension name");
00806
00807 code = cpl_table_save(table, NULL, properties, (cxchar *)filename, 1);
00808
00809 if (created == TRUE) {
00810 cpl_propertylist_delete(properties);
00811 }
00812
00813 return code == CPL_ERROR_NONE ? 0 : 1;
00814
00815 }
00816
00817
00834 cxint
00835 giraffe_fiberlist_attach(cpl_frame *frame, GiTable *fibers)
00836 {
00837
00838 const cxchar *fctid = "giraffe_fiberlist_attach";
00839
00840
00841 cxbool created = FALSE;
00842
00843 cxint status = 0;
00844
00845 cpl_propertylist *properties = NULL;
00846
00847 GiTable *_fibers = NULL;
00848
00849
00850 if (frame == NULL || fibers == NULL) {
00851 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00852 return 1;
00853 }
00854
00855 _fibers = giraffe_table_duplicate(fibers);
00856
00857 properties = giraffe_table_get_properties(_fibers);
00858
00859 if (properties == NULL) {
00860 properties = cpl_propertylist_new();
00861 giraffe_table_set_properties(_fibers, properties);
00862 created = TRUE;
00863 }
00864
00865 if (cpl_table_has_column(giraffe_table_get(_fibers), "RINDEX")) {
00866 cpl_table_erase_column(giraffe_table_get(_fibers), "RINDEX");
00867 }
00868
00869 status = giraffe_frame_attach_table(frame, _fibers, GIFRAME_FIBER_SETUP,
00870 TRUE);
00871
00872 if (created == TRUE) {
00873 cpl_propertylist_delete(properties);
00874 }
00875
00876 properties = NULL;
00877
00878 giraffe_table_delete(_fibers);
00879 _fibers = NULL;
00880
00881 return status;
00882
00883 }
00884
00885
00903 cxint giraffe_fiberlist_compare(const GiTable *fibers,
00904 const GiTable *reference)
00905 {
00906
00907 register cxint i;
00908 cxint equal = 1;
00909
00910 cpl_table *_fibers = giraffe_table_get(fibers);
00911 cpl_table *_reference = giraffe_table_get(reference);
00912
00913
00914 if (_fibers == NULL || _reference == NULL) {
00915 return -1;
00916 }
00917
00918 if (!cpl_table_has_column(_fibers, "FPS") ||
00919 !cpl_table_has_column(_reference, "FPS")) {
00920 return -2;
00921 }
00922
00923
00924 for (i = 0; i < cpl_table_get_nrow(_reference); i++) {
00925
00926 cxbool found = FALSE;
00927
00928 cxint j;
00929 cxint fps = cpl_table_get_int(_reference, "FPS", i, NULL);
00930
00931 for (j = 0; j < cpl_table_get_nrow(_fibers); j++) {
00932 cxint _fps = cpl_table_get_int(_fibers, "FPS", j, NULL);
00933
00934 if (fps == _fps) {
00935 found = TRUE;
00936 break;
00937 }
00938 }
00939
00940 if (found == FALSE) {
00941 equal = 0;
00942 break;
00943 }
00944
00945 }
00946
00947 return equal;
00948
00949 }
00950
00951
00972 cxint
00973 giraffe_fiberlist_associate(GiTable *fibers, const GiTable *reference)
00974 {
00975
00976 const cxchar *fctid = "giraffe_fiberlist_associate";
00977
00978 register cxint i;
00979
00980 cxint nf;
00981 cxint nr;
00982
00983 cpl_table *_fibers = NULL;
00984 cpl_table *_reference = NULL;
00985
00986
00987 if (fibers == NULL) {
00988 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00989 return 1;
00990 }
00991
00992 if (reference == NULL) {
00993 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00994 return 1;
00995 }
00996
00997 _fibers = giraffe_table_get(fibers);
00998 _reference = giraffe_table_get(reference);
00999
01000 if (!cpl_table_has_column(_fibers, "FPS")) {
01001 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
01002 return 1;
01003 }
01004
01005 if (!cpl_table_has_column(_reference, "FPS")) {
01006 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
01007 return 1;
01008 }
01009
01010
01011
01012
01013
01014
01015
01016
01017 if (!cpl_table_has_column(_fibers, "RINDEX")) {
01018
01019 cxint size = cpl_table_get_nrow(_fibers);
01020
01021 cxint status = cpl_table_duplicate_column(_fibers, "RINDEX",
01022 _fibers, "INDEX");
01023
01024 if (status != CPL_ERROR_NONE) {
01025 return 1;
01026 }
01027
01028 status = cpl_table_fill_column_window_int(_fibers, "RINDEX", 0,
01029 size, -1);
01030
01031 if (status != CPL_ERROR_NONE) {
01032 return 1;
01033 }
01034
01035 }
01036
01037
01038
01039
01040
01041
01042
01043
01044 nf = cpl_table_get_nrow(_fibers);
01045 nr = cpl_table_get_nrow(_reference);
01046
01047 cpl_table_unselect_all(_fibers);
01048
01049 for (i = 0; i < nf; i++) {
01050
01051 register cxint j;
01052
01053 cxint fps = cpl_table_get_int(_fibers, "FPS", i, NULL);
01054
01055
01056 for (j = 0; j < nr; j++) {
01057
01058 cxint _fps = cpl_table_get_int(_reference, "FPS", j, NULL);
01059
01060
01061 if (fps == _fps) {
01062
01063 cxint ridx = cpl_table_get_int(_reference, "INDEX", j, NULL);
01064
01065 cpl_table_set_int(_fibers, "RINDEX", i, ridx);
01066 cpl_table_select_row(_fibers, i);
01067
01068 break;
01069 }
01070 }
01071 }
01072
01073
01074
01075
01076
01077
01078
01079
01080 _fibers = cpl_table_extract_selected(_fibers);
01081
01082
01083
01084
01085
01086
01087 for (i = 0; i < cpl_table_get_nrow(_fibers); i++) {
01088 cpl_table_set_int(_fibers, "INDEX", i, i + 1);
01089 }
01090
01091
01092 giraffe_table_set(fibers, _fibers);
01093
01094 cpl_table_delete(_fibers);
01095
01096 return 0;
01097
01098 }
01099
01100
01116 const cxchar *
01117 giraffe_fiberlist_query_index(const cpl_table *fibers)
01118 {
01119
01120 const cxchar *names[] = {"RINDEX", "INDEX", NULL};
01121 const cxchar **idx = names;
01122
01123
01124 while (*idx != NULL) {
01125
01126 if (cpl_table_has_column((cpl_table *)fibers, *idx) != 0) {
01127 break;
01128 }
01129
01130 ++idx;
01131 }
01132
01133 return *idx;
01134
01135 }
01136
01137
01167 cxint *
01168 giraffe_parse_spectrum_selection(const cxchar *selection, cxint *nspec)
01169 {
01170
01171 cxchar **lists = NULL;
01172 cxchar **ranges = NULL;
01173
01174 cxint i;
01175 cxint first = 0;
01176 cxint nfibers = 0;
01177 cxint *fibers = NULL;
01178 cxint *_fibers = NULL;
01179
01180 cx_slist *fl = NULL;
01181
01182 cx_slist_iterator pos;
01183
01184
01185 *nspec = 0;
01186
01187 lists = cx_strsplit(selection, ";", 2);
01188
01189 if (lists == NULL) {
01190 return NULL;
01191 }
01192
01193 if (lists[1] != NULL) {
01194 gi_warning("Usage of fiber exclusion lists is not supported! "
01195 "The given exclusion list is ignored!");
01196 }
01197
01198 ranges = cx_strsplit(lists[0], ",", -1);
01199
01200 if (ranges == NULL) {
01201 cx_strfreev(lists);
01202 return NULL;
01203 }
01204
01205 i = 0;
01206 while (ranges[i] != NULL) {
01207
01208 cxchar **bounds = cx_strsplit(ranges[i], "-", 2);
01209
01210 cxint j;
01211
01212
01213 if (bounds == NULL) {
01214 cx_strfreev(ranges);
01215 cx_strfreev(lists);
01216
01217 if (fibers) {
01218 cx_free(fibers);
01219 }
01220
01221 return NULL;
01222 }
01223 else {
01224
01225 cxchar *last;
01226
01227 cxlong lower = -1;
01228 cxlong upper = -1;
01229
01230
01231 lower = strtol(bounds[0], &last, 10);
01232
01233 if (*last != '\0') {
01234 cx_strfreev(bounds);
01235 cx_strfreev(ranges);
01236 cx_strfreev(lists);
01237
01238 if (fibers) {
01239 cx_free(fibers);
01240 }
01241
01242 return NULL;
01243 }
01244
01245 if (bounds[1] != NULL) {
01246
01247 upper = strtol(bounds[1], &last, 10);
01248
01249 if (*last != '\0') {
01250 cx_strfreev(bounds);
01251 cx_strfreev(ranges);
01252 cx_strfreev(lists);
01253
01254 if (fibers) {
01255 cx_free(fibers);
01256 }
01257
01258 return NULL;
01259 }
01260 }
01261
01262 upper = upper > 0 ? upper : lower;
01263
01264 if (lower <= 0 || upper <= 0 || upper < lower) {
01265 cx_strfreev(bounds);
01266 cx_strfreev(ranges);
01267 cx_strfreev(lists);
01268
01269 if (fibers) {
01270 cx_free(fibers);
01271 }
01272
01273 return NULL;
01274 }
01275
01276 ++nfibers;
01277
01278 if (upper > lower) {
01279 nfibers += upper - lower;
01280 }
01281
01282 fibers = cx_realloc(fibers, nfibers * sizeof(cxint));
01283
01284 for (j = first; j < nfibers; j++) {
01285 fibers[j] = lower + j - first;
01286 }
01287
01288 first = nfibers;
01289
01290 }
01291
01292 cx_strfreev(bounds);
01293 bounds = NULL;
01294
01295 ++i;
01296
01297 }
01298
01299 cx_strfreev(ranges);
01300 cx_strfreev(lists);
01301
01302 qsort(fibers, nfibers, sizeof(cxint), _giraffe_compare_int);
01303
01304
01305
01306
01307
01308
01309 fl = cx_slist_new();
01310
01311 for (i = 0; i < nfibers; i++) {
01312 cx_slist_push_back(fl, fibers + i);
01313 }
01314
01315 cx_slist_unique(fl, _giraffe_compare_int);
01316
01317 nfibers = cx_slist_size(fl);
01318 _fibers = cx_malloc(nfibers * sizeof(cxint));
01319
01320 i = 0;
01321
01322 pos = cx_slist_begin(fl);
01323 while (pos != cx_slist_end(fl)) {
01324
01325 cxint *fn = cx_slist_get(fl, pos);
01326
01327 cx_assert(fn != NULL);
01328 _fibers[i] = *fn;
01329
01330 pos = cx_slist_next(fl, pos);
01331 ++i;
01332 }
01333 cx_slist_delete(fl);
01334 cx_free(fibers);
01335
01336 *nspec = nfibers;
01337 return _fibers;
01338
01339 }