GIRAFFE Pipeline Reference Manual

gislitgeometry.c

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

This file is part of the GIRAFFE Pipeline Reference Manual 2.9.0.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Jan 26 14:20:28 2012 by doxygen 1.6.3 written by Dimitri van Heesch, © 1997-2004