GIRAFFE Pipeline Reference Manual

gifiberutils.c

00001 /* $Id: gifiberutils.c,v 1.45.2.1 2008/02/21 10:52:40 rpalsa Exp $
00002  *
00003  * This file is part of the GIRAFFE Pipeline
00004  * Copyright (C) 2002-2006 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 /*
00022  * $Author: rpalsa $
00023  * $Date: 2008/02/21 10:52:40 $
00024  * $Revision: 1.45.2.1 $
00025  * $Name: giraffe-2_5_1 $
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      * Check whether the input file is a calibration and retrieve the
00130      * name of the slit in use.
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      * Load OzPoz table from current frame
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      * Load fiber table from current frame.
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      * Select all entries with the appropriate slit name from the table
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      * Move the relevant columns from the fiber table to the
00304      * final fibers list.
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      * For Argus the slit is mirrored compared to IFU and Medusa
00407      * and we have to reverse the order of the slits table.
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      * Postprocess initial fiber table
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      * Select rows in the fiber table which have a corresponding entry
00482      * in the OzPoz table. Both tables are associated using the
00483      * `button number'. For matching entries the OzPoz data is copied
00484      * to the fiber table. Also the simultaneous calibration fibers
00485      * are copied.
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          * If fiber equals -1 it is a simultaneous calibration, which
00499          * has no entry in the OzPoz table. Otherwise we try to find it
00500          * in the OzPoz table and copy the data for this fiber.
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      * Finalize the fiber list by applying the user specified fiber
00602      * selection list. Fibers which do not have an entry in the
00603      * OzPoz table or which are beyond the limits are ignored.
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      * Update index column
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      * Sort the final table according to the INDEX column
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      * Create new column containing the fiber index of the calibration
01013      * spectrum in the reference table which is used to process the current
01014      * spectrum.
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      * Write the reference fiber index of all fibers with a corresponding
01040      * entry in the reference fiber list to the input fiber list and select
01041      * it. Extract all selected fibers.
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      * From this point on, _fibers is not just a reference anymore, but
01076      * points to a newly allocated table object, which must be managed
01077      * properly.
01078      */
01079 
01080     _fibers = cpl_table_extract_selected(_fibers);
01081 
01082 
01083     /*
01084      * Rewrite index column
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      * Remove duplicates from the fiber list
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 }

This file is part of the GIRAFFE Pipeline Reference Manual 2.5.1.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Tue Mar 18 10:47:42 2008 by doxygen 1.4.6 written by Dimitri van Heesch, © 1997-2004