GIRAFFE Pipeline Reference Manual

gislitgeometry.c

00001 /* $Id: gislitgeometry.c,v 1.15 2006/07/12 15:25:58 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: 2006/07/12 15:25:58 $
00024  * $Revision: 1.15 $
00025  * $Name: giraffe-2_5_2 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #  include <config.h>
00030 #endif
00031 
00032 #include <cpl_msg.h>
00033 
00034 #include "gierror.h"
00035 #include "gimessages.h"
00036 #include "giframe.h"
00037 #include "gifiberutils.h"
00038 #include "gimatrix.h"
00039 #include "gislitgeometry.h"
00040 
00041 
00050 /*
00051  * @brief
00052  *   Create a cpl_matrix at a specified position of the GiSlitGeometry
00053  *
00054  * @param self  GiSlitGeometry in which to create the cpl_matrix
00055  * @param pos   Position at which to create the matrix
00056  * @param nrow  Number of rows of the matrix
00057  * @param ncol  Number of columns of the matrix
00058  *
00059  * Creates a cpl_matrix at position @em pos inside the GiSlitGeometry
00060  * @em self of @em nrow rows and @em ncol columns. If a cpl_matrix is
00061  * already present at position @em pos, it is properly deallocated first.
00062  */
00063 
00064 inline static void
00065 _giraffe_slitgeometry_insert(GiSlitGeometry *self, cxint pos, cxint nrow,
00066                              cxint ncol)
00067 {
00068 
00069     if (self == NULL) {
00070         return;
00071     }
00072 
00073     if (self->subslits == NULL) {
00074         return;
00075     }
00076 
00077     if ((pos < 0) || (pos > self->nsubslits)) {
00078         return;
00079     }
00080 
00081     if (self->subslits[pos] != NULL) {
00082         cpl_matrix_delete(self->subslits[pos]);
00083     }
00084 
00085     self->subslits[pos] = cpl_matrix_new(nrow, ncol);
00086 
00087     return;
00088 
00089 }
00090 
00091 
00102 GiSlitGeometry *
00103 giraffe_slitgeometry_new(void)
00104 {
00105 
00106     GiSlitGeometry *self = cx_malloc(sizeof *self);
00107 
00108     self->xf = NULL;
00109     self->yf = NULL;
00110 
00111     self->nsubslits = 0;
00112     self->subslits  = NULL;
00113 
00114     return self;
00115 
00116 }
00117 
00118 
00131 GiSlitGeometry *
00132 giraffe_slitgeometry_duplicate(GiSlitGeometry *other)
00133 {
00134 
00135     GiSlitGeometry *clone = NULL;
00136 
00137 
00138     if (other) {
00139 
00140         cxint i;
00141 
00142 
00143         clone = (GiSlitGeometry *)cx_malloc(sizeof *clone);
00144 
00145         if ((other->subslits == NULL) || (other->nsubslits == 0)) {
00146 
00147             clone->nsubslits = other->nsubslits;
00148             clone->subslits = other->subslits;
00149 
00150             return clone;
00151 
00152         }
00153 
00154         clone->nsubslits = other->nsubslits;
00155         clone->subslits  = cx_calloc(clone->nsubslits, sizeof(cpl_matrix *));
00156 
00157         for (i = 0; i < other->nsubslits; i++) {
00158             giraffe_slitgeometry_set(clone, i,
00159                                      giraffe_slitgeometry_get(other,i));
00160         }
00161 
00162     }
00163 
00164     return clone;
00165 
00166 }
00167 
00168 
00193 GiSlitGeometry *
00194 giraffe_slitgeometry_create(GiTable *slitgeometry, cxbool subslits)
00195 {
00196 
00197     const cxchar *fctid = "giraffe_slitgeometry_create";
00198 
00199 
00200     const cxchar *c_xf = "XF";
00201     const cxchar *c_yf = "YF";
00202     const cxchar *c_fps = "FPS";
00203     const cxchar *c_ssn = "SSN";
00204     const cxchar *c_rindex = NULL;
00205 
00206     cxint status;
00207     cxint nfibers = 0;
00208     cxint max_nsubslits = 0;
00209     cxint i             = 0;
00210     cxint j             = 0;
00211     cxint count         = 0;
00212     cxint column_index  = 0;
00213 
00214     cpl_matrix *nsubslits = NULL;
00215 
00216     cpl_table *_slitgeometry = NULL;
00217 
00218     GiSlitGeometry *self = NULL;
00219 
00220 
00221     if (slitgeometry == NULL) {
00222         return NULL;
00223     }
00224 
00225     self = giraffe_slitgeometry_new();
00226 
00227     if (self == NULL) {
00228         return NULL;
00229     }
00230 
00231     _slitgeometry = giraffe_table_get(slitgeometry);
00232     nfibers = cpl_table_get_nrow(_slitgeometry);
00233 
00234     self->xf = cpl_matrix_new(nfibers, 1);
00235     self->yf = cpl_matrix_new(nfibers, 1);
00236     self->fps = cpl_matrix_new(nfibers, 1);
00237     self->rindex = cpl_matrix_new(nfibers, 1);
00238 
00239     nsubslits = cpl_matrix_new(nfibers, 1);
00240 
00241 
00242     c_rindex = giraffe_fiberlist_query_index(_slitgeometry);
00243 
00244     /*
00245      *  Copy relevant data to matrices
00246      */
00247 
00248     max_nsubslits = 0;
00249 
00250     for (i = 0; i < nfibers; i++) {
00251 
00252         cxint _nsubslits = cpl_table_get_int(_slitgeometry, c_ssn, i, NULL);
00253         cxint _fps = cpl_table_get_int(_slitgeometry, c_fps, i, NULL) - 1;
00254         cxint _index = cpl_table_get_int(_slitgeometry, c_rindex,
00255                                          i, NULL) - 1;
00256 
00257         cxdouble _xf = cpl_table_get(_slitgeometry, c_xf, i, NULL);;
00258         cxdouble _yf = cpl_table_get(_slitgeometry, c_yf, i, NULL);
00259 
00260 
00261         if (_nsubslits > max_nsubslits) {
00262             max_nsubslits = _nsubslits;
00263         }
00264 
00265         status = cpl_matrix_set(self->xf, i, 0, _xf);
00266         status = cpl_matrix_set(self->yf, i, 0, _yf);
00267         status = cpl_matrix_set(self->fps, i, 0, (cxdouble)_fps);
00268         status = cpl_matrix_set(self->rindex, i, 0, (cxdouble)_index);
00269 
00270         status = cpl_matrix_set(nsubslits, i, 0, (cxdouble)_nsubslits);
00271 
00272     }
00273 
00274 
00275     /*
00276      *  Create Slit Geometry
00277      */
00278 
00279     if (subslits) {
00280 
00281         /* create multiple subslits */
00282 
00283         giraffe_slitgeometry_resize(self, max_nsubslits);
00284 
00285         for (i = 1; i <= max_nsubslits; i++) {
00286 
00287             cxint curr_ssn;
00288 
00289             cpl_matrix *ref_matrix = NULL;
00290 
00291             count = 0;
00292             for (j = 0; j < nfibers; j++) {
00293                 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
00294 
00295                 if (i == curr_ssn) {
00296                     ++count;
00297                 }
00298             }
00299 
00300             _giraffe_slitgeometry_insert(self, i - 1, count, 1);
00301 
00302             ref_matrix = giraffe_slitgeometry_get(self, i - 1);
00303 
00304             column_index = 0;
00305             for (j = 0; j < nfibers; j++) {
00306 
00307                 curr_ssn = (cxint) cpl_matrix_get(nsubslits, j, 0);
00308 
00309                 if (i == curr_ssn) {
00310 
00311                     status = cpl_matrix_set(ref_matrix, column_index, 0,
00312                                             (cxdouble)j);
00313                     ++column_index;
00314                 }
00315             }
00316         }
00317 
00318         cpl_msg_debug(fctid, "Using multiple slits for Slit Geometry");
00319 
00320     }
00321     else {
00322 
00323         /* create one subslit containing all fibers */
00324 
00325         cpl_matrix *ref_matrix = NULL;
00326 
00327         giraffe_slitgeometry_resize(self, 1);
00328         _giraffe_slitgeometry_insert(self, 0, nfibers, 1);
00329 
00330         ref_matrix = giraffe_slitgeometry_get(self, 0);
00331 
00332         for (j = 0; j < nfibers; j++) {
00333 
00334             status = cpl_matrix_set(ref_matrix, j, 0, (cxdouble)j);
00335 
00336         }
00337 
00338         cpl_msg_debug(fctid, "Using single slit for Slit Geometry");
00339 
00340     }
00341 
00342     return self;
00343 
00344 }
00345 
00346 
00358 void
00359 giraffe_slitgeometry_delete(GiSlitGeometry *self)
00360 {
00361 
00362     if (self == NULL) {
00363         return;
00364     }
00365 
00366     if (self->subslits != NULL) {
00367 
00368         cxint i;
00369 
00370         for (i = 0; i < self->nsubslits; i++) {
00371             cpl_matrix_delete(self->subslits[i]);
00372         }
00373 
00374         cx_free(self->subslits);
00375 
00376     }
00377 
00378     return;
00379 
00380 }
00381 
00382 
00396 cxint
00397 giraffe_slitgeometry_size(GiSlitGeometry *self)
00398 {
00399 
00400     if (self == NULL) {
00401         return -1;
00402     }
00403 
00404     if (self->subslits != NULL) {
00405         return self->nsubslits;
00406     }
00407 
00408     return 0;
00409 
00410 }
00411 
00412 
00425 void
00426 giraffe_slitgeometry_resize(GiSlitGeometry *self, cxint size)
00427 {
00428 
00429     if (self == NULL) {
00430         return;
00431     }
00432 
00433     if (size == self->nsubslits) {
00434         return;
00435     }
00436 
00437     if (self->subslits != NULL) {
00438 
00439         cxint i;
00440 
00441         for (i = 0; i < self->nsubslits; i++) {
00442             cpl_matrix_delete(self->subslits[i]);
00443         }
00444 
00445     }
00446 
00447     cx_free(self->subslits);
00448 
00449     self->nsubslits = size;
00450     self->subslits = cx_calloc(self->nsubslits, sizeof(cpl_matrix *));
00451 
00452     return;
00453 
00454 }
00455 
00456 
00472 void
00473 giraffe_slitgeometry_set(GiSlitGeometry *self, cxint pos,
00474                          cpl_matrix *nm)
00475 {
00476 
00477     if (self == NULL) {
00478         return;
00479     }
00480 
00481     if (self->subslits == NULL) {
00482         return;
00483     }
00484 
00485     if ((pos < 0) || (pos > self->nsubslits)) {
00486         return;
00487     }
00488 
00489     if (self->subslits[pos] != NULL) {
00490         cpl_matrix_delete(self->subslits[pos]);
00491     }
00492 
00493     if (nm) {
00494         self->subslits[pos] = cpl_matrix_duplicate(nm);
00495     }
00496     else {
00497         self->subslits[pos] = NULL;
00498     }
00499 
00500     return;
00501 
00502 }
00503 
00504 
00518 cpl_matrix *
00519 giraffe_slitgeometry_get(GiSlitGeometry *self, cxint pos)
00520 {
00521 
00522     if (self == NULL) {
00523         return NULL;
00524     }
00525 
00526     if (self->subslits == NULL) {
00527         return NULL;
00528     }
00529 
00530     if ((pos < 0) || (pos > self->nsubslits)) {
00531         return NULL;
00532     }
00533 
00534     return self->subslits[pos];
00535 
00536 }
00537 
00538 
00549 void
00550 giraffe_slitgeometry_print(GiSlitGeometry *self)
00551 {
00552 
00553     const cxchar *fctid = "giraffe_slitgeometry_print";
00554 
00555     cxint i;
00556 
00557     gi_message("Current slit geometry setup");
00558 
00559     if (self == NULL) {
00560         gi_message("Empty slit geometry!");
00561         return;
00562     }
00563 
00564     if (self->subslits == NULL) {
00565         gi_message(fctid, "Invalid slit geometry, no slit matrices "
00566                    "present!");
00567         return;
00568     }
00569 
00570 
00571     for (i = 0; i < self->nsubslits; i++) {
00572 
00573         cxint nrow = 0;
00574 
00575         cpl_matrix *ref  = NULL;
00576 
00577         ref  = giraffe_slitgeometry_get(self, i);
00578         nrow = cpl_matrix_get_nrow(ref);
00579 
00580         giraffe_matrix_dump(ref, nrow);
00581     }
00582 
00583     return;
00584 
00585 }
00586 
00587 
00608 GiTable *
00609 giraffe_slitgeometry_load(const GiTable *fibers, const cxchar *filename,
00610                           cxint pos, const cxchar *tag)
00611 {
00612 
00613     const cxchar *fctid = "giraffe_slitgeometry_load";
00614 
00615 
00616     const cxchar *fps_name = "FPS";
00617     const cxchar *ridx = NULL;
00618 
00619     cxint i;
00620     cxint nfibers = 0;
00621 
00622     cpl_propertylist *properties = NULL;
00623 
00624     cpl_table *_fibers = NULL;
00625     cpl_table *_slit_geometry = NULL;
00626 
00627     GiTable *slit_geometry = NULL;
00628 
00629     GiInstrumentMode mode;
00630 
00631 
00632 
00633     if (fibers == NULL) {
00634         cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00635         return NULL;
00636     }
00637 
00638     _fibers = giraffe_table_get(fibers);
00639 
00640     if (_fibers == NULL) {
00641         cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00642         return NULL;
00643     }
00644 
00645     /*
00646      * Get the instrument setup corresponding to the slit geometry in
00647      * the file.
00648      */
00649 
00650     properties = cpl_propertylist_load(filename, 0);
00651 
00652     if (properties == NULL) {
00653         cpl_msg_error(fctid, "Cannot load properies of data set 0 "
00654                       "from `%s'!", filename);
00655         cpl_propertylist_delete(properties);
00656         return NULL;
00657     }
00658     else {
00659 
00660         mode = giraffe_get_mode(properties);
00661 
00662         if (mode == GIMODE_NONE) {
00663             cpl_msg_error(fctid, "Invalid instrument mode!");
00664 
00665             cpl_propertylist_delete(properties);
00666             return NULL;
00667         }
00668 
00669     }
00670 
00671     cpl_propertylist_delete(properties);
00672 
00673 
00674     /*
00675      * Load the slit geometry information
00676      */
00677 
00678     slit_geometry = giraffe_table_new();
00679 
00680     giraffe_error_push();
00681 
00682     if (giraffe_table_load(slit_geometry, filename, pos, tag)) {
00683         if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
00684             cpl_msg_error(fctid, "Data set %d in `%s' is not a slit "
00685                           "geometry table!", pos, filename);
00686             giraffe_table_delete(slit_geometry);
00687             return NULL;
00688         }
00689         else {
00690             cpl_msg_error(fctid, "Cannot load data set %d (slit geometry) "
00691                           "from `%s!", pos, filename);
00692             giraffe_table_delete(slit_geometry);
00693             return NULL;
00694         }
00695     }
00696 
00697     giraffe_error_pop();
00698 
00699     _slit_geometry = giraffe_table_get(slit_geometry);
00700 
00701     if (!cpl_table_has_column(_slit_geometry, fps_name)) {
00702         if (cpl_table_has_column(_slit_geometry, "NSPEC")) {
00703             cpl_msg_warning(fctid, "Slit geometry loaded from `%s' uses "
00704                             "deprecated OGL column names.", filename);
00705 
00706             // FIXME: This should not be done here. The data should
00707             //        be correct!
00708             //        The following code assumes that all possible fibers
00709             //        are listed in the order they appear on an image.
00710             //        Only fibers which do not appear on the CCD on the
00711             //        right side (high FPS numbers for Medusa and IFU, low
00712             //        FPS numbers for Argus) may be missing. For all other
00713             //        cases the code below would just generate garbage.
00714 
00715             cpl_table_duplicate_column(_slit_geometry, fps_name,
00716                                        _slit_geometry, "NSPEC");
00717 
00718             cpl_table_name_column(_slit_geometry, "NSPEC", "INDEX");
00719 
00720             if (mode == GIMODE_ARGUS) {
00721 
00722                 cxint nrow = cpl_table_get_nrow(_slit_geometry);
00723 
00724                 for (i = 0; i < nrow; i++) {
00725 
00726                     cxint idx = cpl_table_get_int(_slit_geometry, "INDEX",
00727                                                   nrow - i - 1, NULL);
00728 
00729                     cpl_table_set_int(_slit_geometry, fps_name, i, idx);
00730 
00731                 }
00732 
00733             }
00734 
00735         }
00736         else {
00737             cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00738             giraffe_table_delete(slit_geometry);
00739             return NULL;
00740         }
00741     }
00742 
00743 
00744     /*
00745      * Extract the slit geometry information corresponding to the
00746      * given fiber setup
00747      */
00748 
00749     nfibers = cpl_table_get_nrow(_fibers);
00750 
00751     cpl_table_unselect_all(_slit_geometry);
00752 
00753     for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
00754 
00755         cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
00756         cxint j;
00757 
00758         for (j = 0; j < nfibers; j++) {
00759 
00760             cxint _fps = cpl_table_get_int(_fibers, "FPS", j, NULL);
00761 
00762             if (_fps == fps) {
00763                 cpl_table_select_row(_slit_geometry, i);
00764                 break;
00765             }
00766 
00767         }
00768 
00769     }
00770 
00771     _slit_geometry = cpl_table_extract_selected(_slit_geometry);
00772 
00773 
00774     ridx = giraffe_fiberlist_query_index(_fibers);
00775     cpl_table_new_column(_slit_geometry, "RINDEX", CPL_TYPE_INT);
00776 
00777     for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
00778 
00779         cxint fps = cpl_table_get_int(_slit_geometry, fps_name, i, NULL);
00780         cxint j;
00781 
00782         for (j = 0; j < nfibers; j++) {
00783 
00784             cxint _fps = cpl_table_get_int(_fibers, "FPS", j, NULL);
00785 
00786             if (_fps == fps) {
00787 
00788                 cxint _ridx = cpl_table_get_int(_fibers, ridx, j , NULL);
00789 
00790                 cpl_table_set_int(_slit_geometry, "RINDEX", i, _ridx);
00791                 break;
00792 
00793             }
00794 
00795         }
00796 
00797     }
00798 
00799 
00800     /*
00801      * If the loaded table had the OGL label for the fiber position within
00802      * the slit (FPS) change it.
00803      */
00804 
00805     if (strcmp(fps_name, "FPS") != 0) {
00806         cpl_table_name_column(_slit_geometry, fps_name, "FPS");
00807     }
00808 
00809 
00810     /*
00811      * Reset the index column
00812      */
00813 
00814     for (i = 0; i < cpl_table_get_nrow(_slit_geometry); i++) {
00815         cpl_table_set_int(_slit_geometry, "INDEX", i, i + 1);
00816     }
00817 
00818     giraffe_table_set(slit_geometry, _slit_geometry);
00819 
00820     cpl_table_delete(_slit_geometry);
00821     _slit_geometry = NULL;
00822 
00823     return slit_geometry;
00824 
00825 }
00826 
00827 
00828 cpl_frame *
00829 giraffe_slitgeometry_save(const GiTable *slitgeometry)
00830 {
00831 
00832     cpl_frame *frame = NULL;
00833 
00834 
00835     if (slitgeometry) {
00836 
00837         GiTable *slit = giraffe_table_duplicate(slitgeometry);
00838 
00839 
00840         if (slit == NULL) {
00841             return NULL;
00842         }
00843 
00844         if (cpl_table_has_column(giraffe_table_get(slit), "RINDEX")) {
00845             cpl_table_erase_column(giraffe_table_get(slit), "RINDEX");
00846         }
00847 
00848         frame = giraffe_frame_create_table(slit, GIFRAME_SLITSETUP,
00849                                            CPL_FRAME_LEVEL_FINAL,
00850                                            TRUE, TRUE);
00851 
00852         giraffe_table_delete(slit);
00853 
00854     }
00855 
00856     return frame;
00857 
00858 }

This file is part of the GIRAFFE Pipeline Reference Manual 2.5.2.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Fri Jun 13 14:36:24 2008 by doxygen 1.4.6 written by Dimitri van Heesch, © 1997-2004