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 cxbool missing = TRUE;
00495
00496 cxint fiber = cpl_table_get_int(fibers, "RP", i, NULL);
00497
00498
00499
00500
00501
00502
00503
00504
00505 if (fiber == -1 && calsim == TRUE) {
00506 cpl_table_set_string(fibers, "OBJECT", i, "CALSIM");
00507 cpl_table_unselect_row(fibers, i);
00508 missing = FALSE;
00509 }
00510 else if (fiber == 0 && mode == GIMODE_ARGUS) {
00511 cpl_table_unselect_row(fibers, i);
00512 missing = FALSE;
00513 }
00514 else {
00515
00516 register cxint j;
00517
00518
00519 for (j = 0; j < nbuttons; j++) {
00520
00521 cxint button = cpl_table_get_int(_ozpoz, "BUTTON", j, NULL);
00522
00523
00524 if (fiber == button) {
00525 const cxchar *object;
00526
00527 cxdouble r, theta, orient;
00528
00529 cxdouble ra = 0.;
00530 cxdouble dec = 0.;
00531 cxdouble mag = 0.;
00532 cxdouble b_v = 0.;
00533
00534
00535 object = cpl_table_get_string(_ozpoz, "OBJECT", j);
00536
00537 r = cpl_table_get_double(_ozpoz, "R", j, NULL);
00538 theta = cpl_table_get_double(_ozpoz, "THETA", j, NULL);
00539 orient = cpl_table_get_double(_ozpoz, "ORIENT", j, NULL);
00540
00541 if (cpl_table_has_column(_ozpoz, "RA")) {
00542 ra = cpl_table_get_double(_ozpoz, "RA", j, NULL);
00543 }
00544
00545 if (cpl_table_has_column(_ozpoz, "DEC")) {
00546 dec = cpl_table_get_double(_ozpoz, "DEC", j, NULL);
00547 }
00548
00549 if (cpl_table_has_column(_ozpoz, "MAGNITUDE")) {
00550 mag = cpl_table_get_float(_ozpoz, "MAGNITUDE", j,
00551 NULL);
00552 }
00553
00554 if (cpl_table_has_column(_ozpoz, "B_V")) {
00555 b_v = cpl_table_get_double(_ozpoz, "B_V", j, NULL);
00556 b_v = CX_CLAMP(b_v, -5., 5.);
00557 }
00558
00559 cpl_table_set_string(fibers, "OBJECT", i, object);
00560
00561 cpl_table_set_double(fibers, "R", i, r);
00562 cpl_table_set_double(fibers, "THETA", i, theta);
00563 cpl_table_set_double(fibers, "ORIENT", i, orient);
00564
00565 if (cpl_table_has_column(fibers, "RA")) {
00566 cpl_table_set_double(fibers, "RA", i, ra);
00567 }
00568
00569 if (cpl_table_has_column(fibers, "DEC")) {
00570 cpl_table_set_double(fibers, "DEC", i, dec);
00571 }
00572
00573 if (cpl_table_has_column(fibers, "MAGNITUDE")) {
00574 cpl_table_set_double(fibers, "MAGNITUDE", i, mag);
00575 }
00576
00577 if (cpl_table_has_column(fibers, "B_V")) {
00578 cpl_table_set_double(fibers, "B_V", i, b_v);
00579 }
00580
00581 cpl_table_unselect_row(fibers, i);
00582 missing = FALSE;
00583 break;
00584 }
00585 }
00586 }
00587
00588 if (missing == TRUE) {
00589
00590 cxint _fps = cpl_table_get_int(fibers, "FPS", i, NULL);
00591 cpl_msg_debug(fctid, "Fiber at FPS = %d is not used", _fps);
00592
00593 }
00594
00595 }
00596
00597
00598 giraffe_error_push();
00599
00600 cpl_table_erase_selected(fibers);
00601
00602 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00603 cpl_table_delete(fibers);
00604 return NULL;
00605 }
00606
00607 giraffe_error_pop();
00608
00609 giraffe_table_delete(ozpoz);
00610 ozpoz = NULL;
00611
00612
00613
00614
00615
00616
00617
00618
00619 if (spectra && nspec > 0) {
00620
00621 register cxint rows = cpl_table_get_nrow(fibers);
00622
00623
00624 cx_assert(cpl_table_get_column_type(fibers, "FPD") == CPL_TYPE_INT);
00625
00626 cpl_table_select_all(fibers);
00627
00628 for (i = 0; i < rows; i++) {
00629
00630 register cxint j;
00631 register cxint selected = 0;
00632 register cxint idx = cpl_table_get_int(fibers, "FPD", i, NULL);
00633
00634
00635 for (j = 0; j < nspec; j++) {
00636 if (idx == spectra[j]) {
00637 selected = 1;
00638 break;
00639 }
00640 }
00641
00642 if (selected) {
00643 cpl_table_unselect_row(fibers, i);
00644 }
00645 else {
00646 cpl_table_select_row(fibers, i);
00647 }
00648
00649 }
00650
00651 giraffe_error_push();
00652
00653 cpl_table_erase_selected(fibers);
00654
00655 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00656 cpl_table_delete(fibers);
00657 return NULL;
00658 }
00659
00660 giraffe_error_pop();
00661
00662 }
00663
00664
00665
00666
00667
00668
00669 for (i = 0; i < cpl_table_get_nrow(fibers); i++) {
00670 cpl_table_set_int(fibers, "INDEX", i, i + 1);
00671 }
00672
00673
00674
00675
00676
00677
00678 cx_assert(sorting_order == NULL);
00679
00680 sorting_order = cpl_propertylist_new();
00681 cpl_propertylist_append_bool(sorting_order, "INDEX", 0);
00682
00683 cpl_table_sort(fibers, sorting_order);
00684
00685 cpl_propertylist_delete(sorting_order);
00686 sorting_order = NULL;
00687
00688
00689 return fibers;
00690
00691 }
00692
00693
00717 GiTable *
00718 giraffe_fiberlist_load(const cxchar *filename, cxint dataset,
00719 const cxchar *tag)
00720 {
00721
00722 const cxchar *fctid = "giraffe_fiberlist_load";
00723
00724
00725 GiTable *fibers = giraffe_table_new();
00726
00727
00728 cx_assert(fibers != NULL);
00729
00730 giraffe_error_push();
00731
00732 if (giraffe_table_load(fibers, filename, dataset, tag)) {
00733 if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
00734 cpl_msg_error(fctid, "Data set %d in `%s' is not a fiber table!",
00735 dataset, filename);
00736 giraffe_table_delete(fibers);
00737 return NULL;
00738 }
00739 else {
00740 cpl_msg_error(fctid, "Cannot load data set %d (fiber table) "
00741 "from `%s'!", dataset, filename);
00742 giraffe_table_delete(fibers);
00743 return NULL;
00744 }
00745 }
00746
00747 giraffe_error_pop();
00748
00749 return fibers;
00750
00751 }
00752
00753
00770 cxint
00771 giraffe_fiberlist_save(GiTable *fibers, const cxchar *filename)
00772 {
00773
00774 const cxchar *fctid = "giraffe_fiberlist_save";
00775
00776 cxbool created = FALSE;
00777
00778 cxint code;
00779
00780 cpl_propertylist *properties = NULL;
00781 cpl_table *table = NULL;
00782
00783
00784 if (fibers == NULL || filename == NULL) {
00785 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00786 return 1;
00787 }
00788
00789 table = giraffe_table_get(fibers);
00790
00791 if (table == NULL) {
00792 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00793 return 1;
00794 }
00795
00796 properties = giraffe_table_get_properties(fibers);
00797
00798 if (properties == NULL) {
00799 properties = cpl_propertylist_new();
00800
00801 cpl_propertylist_append_string(properties, GIALIAS_EXTNAME,
00802 GIFRAME_FIBER_SETUP);
00803 created = TRUE;
00804
00805 giraffe_table_set_properties(fibers, properties);
00806 }
00807 else {
00808 if (cpl_propertylist_has(properties, GIALIAS_EXTNAME)) {
00809 cpl_propertylist_set_string(properties, GIALIAS_EXTNAME,
00810 GIFRAME_FIBER_SETUP);
00811 }
00812 else {
00813 cpl_propertylist_append_string(properties, GIALIAS_EXTNAME,
00814 GIFRAME_FIBER_SETUP);
00815 }
00816 }
00817 cpl_propertylist_set_comment(properties, GIALIAS_EXTNAME,
00818 "FITS Extension name");
00819
00820 code = cpl_table_save(table, NULL, properties, filename, CPL_IO_EXTEND);
00821
00822 if (created == TRUE) {
00823 cpl_propertylist_delete(properties);
00824 }
00825
00826 return code == CPL_ERROR_NONE ? 0 : 1;
00827
00828 }
00829
00830
00847 cxint
00848 giraffe_fiberlist_attach(cpl_frame *frame, GiTable *fibers)
00849 {
00850
00851 const cxchar *fctid = "giraffe_fiberlist_attach";
00852
00853
00854 cxbool created = FALSE;
00855
00856 cxint status = 0;
00857
00858 cpl_propertylist *properties = NULL;
00859
00860 GiTable *_fibers = NULL;
00861
00862
00863 if (frame == NULL || fibers == NULL) {
00864 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00865 return 1;
00866 }
00867
00868 _fibers = giraffe_table_duplicate(fibers);
00869
00870 properties = giraffe_table_get_properties(_fibers);
00871
00872 if (properties == NULL) {
00873 properties = cpl_propertylist_new();
00874 giraffe_table_set_properties(_fibers, properties);
00875 created = TRUE;
00876 }
00877
00878 if (cpl_table_has_column(giraffe_table_get(_fibers), "RINDEX")) {
00879 cpl_table_erase_column(giraffe_table_get(_fibers), "RINDEX");
00880 }
00881
00882 status = giraffe_frame_attach_table(frame, _fibers, GIFRAME_FIBER_SETUP,
00883 TRUE);
00884
00885 if (created == TRUE) {
00886 cpl_propertylist_delete(properties);
00887 }
00888
00889 properties = NULL;
00890
00891 giraffe_table_delete(_fibers);
00892 _fibers = NULL;
00893
00894 return status;
00895
00896 }
00897
00898
00916 cxint giraffe_fiberlist_compare(const GiTable *fibers,
00917 const GiTable *reference)
00918 {
00919
00920 register cxint i;
00921 cxint equal = 1;
00922
00923 cpl_table *_fibers = giraffe_table_get(fibers);
00924 cpl_table *_reference = giraffe_table_get(reference);
00925
00926
00927 if (_fibers == NULL || _reference == NULL) {
00928 return -1;
00929 }
00930
00931 if (!cpl_table_has_column(_fibers, "FPS") ||
00932 !cpl_table_has_column(_reference, "FPS")) {
00933 return -2;
00934 }
00935
00936
00937 for (i = 0; i < cpl_table_get_nrow(_reference); i++) {
00938
00939 cxbool found = FALSE;
00940
00941 cxint j;
00942 cxint fps = cpl_table_get_int(_reference, "FPS", i, NULL);
00943
00944 for (j = 0; j < cpl_table_get_nrow(_fibers); j++) {
00945 cxint _fps = cpl_table_get_int(_fibers, "FPS", j, NULL);
00946
00947 if (fps == _fps) {
00948 found = TRUE;
00949 break;
00950 }
00951 }
00952
00953 if (found == FALSE) {
00954 equal = 0;
00955 break;
00956 }
00957
00958 }
00959
00960 return equal;
00961
00962 }
00963
00964
00985 cxint
00986 giraffe_fiberlist_associate(GiTable *fibers, const GiTable *reference)
00987 {
00988
00989 const cxchar *fctid = "giraffe_fiberlist_associate";
00990
00991 register cxint i;
00992
00993 cxint nf = 0;
00994 cxint nr = 0;
00995
00996 cpl_table *_fibers = NULL;
00997 cpl_table *_reference = NULL;
00998
00999
01000 if (fibers == NULL) {
01001 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
01002 return 1;
01003 }
01004
01005 if (reference == NULL) {
01006 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
01007 return 1;
01008 }
01009
01010 _fibers = giraffe_table_get(fibers);
01011 _reference = giraffe_table_get(reference);
01012
01013 if (!cpl_table_has_column(_fibers, "FPS")) {
01014 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
01015 return 1;
01016 }
01017
01018 if (!cpl_table_has_column(_reference, "FPS")) {
01019 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
01020 return 1;
01021 }
01022
01023
01024
01025
01026
01027
01028
01029
01030 if (!cpl_table_has_column(_fibers, "RINDEX")) {
01031
01032 cxint size = cpl_table_get_nrow(_fibers);
01033
01034 cxint status = cpl_table_duplicate_column(_fibers, "RINDEX",
01035 _fibers, "INDEX");
01036
01037 if (status != CPL_ERROR_NONE) {
01038 return 2;
01039 }
01040
01041 status = cpl_table_fill_column_window_int(_fibers, "RINDEX", 0,
01042 size, -1);
01043
01044 if (status != CPL_ERROR_NONE) {
01045 return 2;
01046 }
01047
01048 }
01049
01050
01051
01052
01053
01054
01055
01056
01057 nf = cpl_table_get_nrow(_fibers);
01058 nr = cpl_table_get_nrow(_reference);
01059
01060 cpl_table_unselect_all(_fibers);
01061
01062 for (i = 0; i < nf; i++) {
01063
01064 register cxint j;
01065
01066 cxint fps = cpl_table_get_int(_fibers, "FPS", i, NULL);
01067
01068
01069 for (j = 0; j < nr; j++) {
01070
01071 cxint _fps = cpl_table_get_int(_reference, "FPS", j, NULL);
01072
01073
01074 if (fps == _fps) {
01075
01076 cxint ridx = cpl_table_get_int(_reference, "INDEX", j, NULL);
01077
01078 cpl_table_set_int(_fibers, "RINDEX", i, ridx);
01079 cpl_table_select_row(_fibers, i);
01080
01081 break;
01082 }
01083 }
01084 }
01085
01086
01087
01088
01089
01090
01091
01092
01093 _fibers = cpl_table_extract_selected(_fibers);
01094
01095
01096
01097
01098
01099
01100 for (i = 0; i < cpl_table_get_nrow(_fibers); i++) {
01101 cpl_table_set_int(_fibers, "INDEX", i, i + 1);
01102 }
01103
01104
01105 giraffe_table_set(fibers, _fibers);
01106
01107 cpl_table_delete(_fibers);
01108
01109 return 0;
01110
01111 }
01112
01113
01127 cxint
01128 giraffe_fiberlist_clear_index(GiTable* fibers)
01129 {
01130
01131 cpl_table* _fibers = NULL;
01132
01133 if (fibers == NULL) {
01134 return -1;
01135 }
01136
01137 _fibers = giraffe_table_get(fibers);
01138
01139 if (_fibers == NULL) {
01140 return 1;
01141 }
01142
01143 giraffe_error_push();
01144
01145 if (cpl_table_has_column(_fibers, "RINDEX") == TRUE) {
01146 cpl_table_erase_column(_fibers, "RINDEX");
01147 }
01148
01149 if (cpl_error_get_code() != CPL_ERROR_NONE) {
01150 return 2;
01151 }
01152
01153 giraffe_error_pop();
01154
01155 return 0;
01156
01157 }
01173 const cxchar *
01174 giraffe_fiberlist_query_index(const cpl_table *fibers)
01175 {
01176
01177 const cxchar *names[] = {"RINDEX", "INDEX", NULL};
01178 const cxchar **idx = names;
01179
01180
01181 while (*idx != NULL) {
01182
01183 if (cpl_table_has_column((cpl_table *)fibers, *idx) != 0) {
01184 break;
01185 }
01186
01187 ++idx;
01188 }
01189
01190 return *idx;
01191
01192 }
01193
01194
01210 cpl_array*
01211 giraffe_fiberlist_get_subslits(const cpl_table* fibers)
01212 {
01213
01214 cxint nfibers = 0;
01215
01216 cpl_array* subslits = NULL;
01217
01218
01219 cx_assert(fibers != NULL);
01220
01221 nfibers = cpl_table_get_nrow(fibers);
01222
01223
01224 if (nfibers > 0) {
01225
01226 cxint i = 0;
01227 cxint nss = 0;
01228 cxint* ssn = NULL;
01229
01230
01231 subslits = cpl_array_new(nfibers, CPL_TYPE_INT);
01232 cpl_array_fill_window(subslits, 0, nfibers, 0);
01233
01234 ssn = cpl_array_get_data_int(subslits);
01235
01236
01237
01238
01239
01240
01241 for (i = 0; i < nfibers; ++i) {
01242 ssn[i] = cpl_table_get_int(fibers, "SSN", i, NULL);
01243 }
01244
01245 qsort(ssn, nfibers, sizeof(cxint), _giraffe_compare_int);
01246
01247
01248
01249
01250
01251
01252 for (i = 1; i < nfibers; ++i) {
01253 if (ssn[i] != ssn[nss]) {
01254 ssn[++nss] = ssn[i];
01255 }
01256 }
01257
01258 ++nss;
01259 cpl_array_set_size(subslits, nss);
01260
01261 }
01262
01263 return subslits;
01264
01265 }
01266
01267
01297 cxint *
01298 giraffe_parse_spectrum_selection(const cxchar *selection, cxint *nspec)
01299 {
01300
01301 cxchar **lists = NULL;
01302 cxchar **ranges = NULL;
01303
01304 cxint i;
01305 cxint first = 0;
01306 cxint nfibers = 0;
01307 cxint *fibers = NULL;
01308 cxint *_fibers = NULL;
01309
01310 cx_slist *fl = NULL;
01311
01312 cx_slist_iterator pos;
01313
01314
01315 *nspec = 0;
01316
01317 lists = cx_strsplit(selection, ";", 2);
01318
01319 if (lists == NULL) {
01320 return NULL;
01321 }
01322
01323 if (lists[1] != NULL) {
01324 gi_warning("Usage of fiber exclusion lists is not supported! "
01325 "The given exclusion list is ignored!");
01326 }
01327
01328 ranges = cx_strsplit(lists[0], ",", -1);
01329
01330 if (ranges == NULL) {
01331 cx_strfreev(lists);
01332 return NULL;
01333 }
01334
01335 i = 0;
01336 while (ranges[i] != NULL) {
01337
01338 cxchar **bounds = cx_strsplit(ranges[i], "-", 2);
01339
01340 cxint j;
01341
01342
01343 if (bounds == NULL) {
01344 cx_strfreev(ranges);
01345 cx_strfreev(lists);
01346
01347 if (fibers) {
01348 cx_free(fibers);
01349 }
01350
01351 return NULL;
01352 }
01353 else {
01354
01355 cxchar *last;
01356
01357 cxlong lower = -1;
01358 cxlong upper = -1;
01359
01360
01361 lower = strtol(bounds[0], &last, 10);
01362
01363 if (*last != '\0') {
01364 cx_strfreev(bounds);
01365 cx_strfreev(ranges);
01366 cx_strfreev(lists);
01367
01368 if (fibers) {
01369 cx_free(fibers);
01370 }
01371
01372 return NULL;
01373 }
01374
01375 if (bounds[1] != NULL) {
01376
01377 upper = strtol(bounds[1], &last, 10);
01378
01379 if (*last != '\0') {
01380 cx_strfreev(bounds);
01381 cx_strfreev(ranges);
01382 cx_strfreev(lists);
01383
01384 if (fibers) {
01385 cx_free(fibers);
01386 }
01387
01388 return NULL;
01389 }
01390 }
01391
01392 upper = upper > 0 ? upper : lower;
01393
01394 if (lower <= 0 || upper <= 0 || upper < lower) {
01395 cx_strfreev(bounds);
01396 cx_strfreev(ranges);
01397 cx_strfreev(lists);
01398
01399 if (fibers) {
01400 cx_free(fibers);
01401 }
01402
01403 return NULL;
01404 }
01405
01406 ++nfibers;
01407
01408 if (upper > lower) {
01409 nfibers += upper - lower;
01410 }
01411
01412 fibers = cx_realloc(fibers, nfibers * sizeof(cxint));
01413
01414 for (j = first; j < nfibers; j++) {
01415 fibers[j] = lower + j - first;
01416 }
01417
01418 first = nfibers;
01419
01420 }
01421
01422 cx_strfreev(bounds);
01423 bounds = NULL;
01424
01425 ++i;
01426
01427 }
01428
01429 cx_strfreev(ranges);
01430 cx_strfreev(lists);
01431
01432 qsort(fibers, nfibers, sizeof(cxint), _giraffe_compare_int);
01433
01434
01435
01436
01437
01438
01439 fl = cx_slist_new();
01440
01441 for (i = 0; i < nfibers; i++) {
01442 cx_slist_push_back(fl, fibers + i);
01443 }
01444
01445 cx_slist_unique(fl, _giraffe_compare_int);
01446
01447 nfibers = cx_slist_size(fl);
01448 _fibers = cx_malloc(nfibers * sizeof(cxint));
01449
01450 i = 0;
01451
01452 pos = cx_slist_begin(fl);
01453 while (pos != cx_slist_end(fl)) {
01454
01455 cxint *fn = cx_slist_get(fl, pos);
01456
01457 cx_assert(fn != NULL);
01458 _fibers[i] = *fn;
01459
01460 pos = cx_slist_next(fl, pos);
01461 ++i;
01462 }
01463 cx_slist_delete(fl);
01464 cx_free(fibers);
01465
01466 *nspec = nfibers;
01467 return _fibers;
01468
01469 }