GIRAFFE Pipeline Reference Manual

gifiberutils.c

00001 /* $Id: gifiberutils.c,v 1.50 2012/08/17 14:17:38 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: 2012/08/17 14:17:38 $
00024  * $Revision: 1.50 $
00025  * $Name: giraffe-2_10 $
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     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      * Select rows in the fiber table which have a corresponding entry
00483      * in the OzPoz table. Both tables are associated using the
00484      * `button number'. For matching entries the OzPoz data is copied
00485      * to the fiber table. Also the simultaneous calibration fibers
00486      * are copied.
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          * If fiber equals -1 it is a simultaneous calibration, which
00502          * has no entry in the OzPoz table. Otherwise we try to find it
00503          * in the OzPoz table and copy the data for this fiber.
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      * Finalize the fiber list by applying the user specified fiber
00619      * selection list. Fibers which do not have an entry in the
00620      * OzPoz table or which are beyond the limits are ignored.
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      * Update index column
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      * Sort the final table according to the INDEX column
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      * Create new column containing the fiber index of the calibration
01030      * spectrum in the reference table which is used to process the current
01031      * spectrum.
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      * Write the reference fiber index of all fibers with a corresponding
01057      * entry in the reference fiber list to the input fiber list and select
01058      * it. Extract all selected fibers.
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      * From this point on, _fibers is not just a reference anymore, but
01093      * points to a newly allocated table object, which must be managed
01094      * properly.
01095      */
01096 
01097     _fibers = cpl_table_extract_selected(_fibers);
01098 
01099 
01100     /*
01101      * Rewrite index column
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          * Create sorted list of subslit numbers
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          * Remove duplicate subslit numbers from the list
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      * Remove duplicates from the fiber list
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 }

This file is part of the GIRAFFE Pipeline Reference Manual 2.10.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Mar 7 14:11:02 2013 by doxygen 1.4.7 written by Dimitri van Heesch, © 1997-2004