GIRAFFE Pipeline Reference Manual

gicube.c

00001 /* $Id: gicube.c,v 1.2 2007/08/23 08:39:06 rpalsa Exp $
00002  *
00003  * This file is part of the GIRAFFE Pipeline
00004  * Copyright (C) 2002-2007 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: 2007/08/23 08:39:06 $
00024  * $Revision: 1.2 $
00025  * $Name: giraffe-2_5_1 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #  include <config.h>
00030 #endif
00031 
00032 #include <string.h>
00033 
00034 #include <cxmemory.h>
00035 #include <cxmessages.h>
00036 
00037 #include <cpl_error.h>
00038 #include <cpl_image.h>
00039 #include <cpl_imagelist.h>
00040 
00041 #include "gialias.h"
00042 #include "gierror.h"
00043 #include "gicube.h"
00044 #include "giutils.h"
00045 
00046 
00055 enum GiCubeAxes {
00056     GICUBE_X = 0,
00057     GICUBE_Y = 1,
00058     GICUBE_Z = 2,
00059     GICUBE_AXES
00060 };
00061 
00062 typedef enum GiCubeAxes GiCubeAxes;
00063 
00064 
00065 struct GiCubeAxis {
00066     cxdouble start;
00067     cxdouble step;
00068 };
00069 
00070 typedef struct GiCubeAxis GiCubeAxis;
00071 
00072 
00073 struct GiCube {
00074     cxsize width;
00075     cxsize height;
00076     cxsize depth;
00077     cxsize size;
00078 
00079     GiCubeAxis* axes[GICUBE_AXES];
00080 
00081     cxdouble* pixels;
00082 
00083     cpl_imagelist* planes;
00084 };
00085 
00086 
00087 inline static void
00088 _giraffe_cube_set_size(GiCube* self, cxsize width, cxsize height,
00089                        cxsize depth)
00090 {
00091 
00092     self->width = width;
00093     self->height = height;
00094     self->depth = depth;
00095 
00096     self->size = self->width * self->height * self->depth;
00097 
00098     return;
00099 
00100 }
00101 
00102 
00103 inline static GiCube*
00104 _giraffe_cube_new(void)
00105 {
00106 
00107     GiCube* self = cx_malloc(sizeof *self);
00108 
00109 
00110     if (self != NULL) {
00111         _giraffe_cube_set_size(self, 0, 0, 0);
00112 
00113         self->axes[GICUBE_X] = NULL;
00114         self->axes[GICUBE_Y] = NULL;
00115         self->axes[GICUBE_Z] = NULL;
00116 
00117         self->pixels = NULL;
00118         self->planes = NULL;
00119     }
00120 
00121     return self;
00122 
00123 }
00124 
00125 
00126 inline static cxint
00127 _giraffe_cube_init_planes(GiCube* self)
00128 {
00129 
00130     register cxsize i = 0;
00131 
00132     register cxdouble* base = NULL;
00133 
00134 
00135     self->planes = cpl_imagelist_new();
00136     cx_assert(self->planes != NULL);
00137 
00138 
00139     base = self->pixels;
00140 
00141     for (i = 0; i < self->depth; i++) {
00142 
00143         cpl_image* plane = cpl_image_wrap_double(self->width, self->height,
00144                                                  base);
00145 
00146         cx_assert(plane != NULL);
00147         cpl_imagelist_set(self->planes, plane, i);
00148 
00149         base += self->width * self->height;
00150 
00151     }
00152 
00153     return 0;
00154 
00155 }
00156 
00157 
00158 inline static void
00159 _giraffe_cube_clear_planes(GiCube* self)
00160 {
00161 
00162     register cxsize i = 0;
00163 
00164 
00165     for (i = 0; i < self->depth; i++) {
00166 
00167         cpl_image* plane = cpl_imagelist_unset(self->planes, 0);
00168 
00169         cpl_image_unwrap(plane);
00170 
00171     }
00172 
00173     cx_assert(cpl_imagelist_get_size(self->planes) == 0);
00174 
00175     cpl_imagelist_delete(self->planes);
00176     self->planes =NULL;
00177 
00178     return;
00179 
00180 }
00181 
00182 
00183 inline static void
00184 _giraffe_cube_delete(GiCube* self)
00185 {
00186 
00187     register cxint i = 0;
00188 
00189     for (i = 0; i < GICUBE_AXES; i++) {
00190         if (self->axes[i] != NULL) {
00191             cx_free(self->axes[i]);
00192             self->axes[i] = NULL;
00193         }
00194     }
00195 
00196     if (self->planes != NULL) {
00197         _giraffe_cube_clear_planes(self);
00198         self->planes = NULL;
00199     }
00200 
00201     if (self->pixels != NULL) {
00202         cx_free(self->pixels);
00203         self->pixels = NULL;
00204     }
00205 
00206     cx_free(self);
00207 
00208     return;
00209 
00210 }
00211 
00212 
00213 inline static cxint
00214 _giraffe_cube_get_axis(const GiCube* self, GiCubeAxes axis, cxdouble* start,
00215                        cxdouble* step)
00216 {
00217 
00218     if (self->axes[axis] == NULL) {
00219         return 1;
00220     }
00221     else {
00222 
00223         if (start != NULL) {
00224             *start = self->axes[axis]->start;
00225         }
00226 
00227         if (step != NULL) {
00228             *step = self->axes[axis]->step;
00229         }
00230 
00231     }
00232 
00233     return 0;
00234 
00235 }
00236 
00237 
00238 inline static cxint
00239 _giraffe_cube_set_axis(GiCube* self, GiCubeAxes axis, cxdouble start,
00240                        cxdouble step)
00241 {
00242 
00243     if (self->axes[axis] == NULL) {
00244         self->axes[axis] = cx_calloc(1, sizeof(GiCubeAxis));
00245     }
00246 
00247     cx_assert(self->axes[axis] != NULL);
00248 
00249     self->axes[axis]->start = start;
00250     self->axes[axis]->step = step;
00251 
00252     return 0;
00253 
00254 }
00255 
00256 
00269 GiCube*
00270 giraffe_cube_new(void)
00271 {
00272 
00273     return _giraffe_cube_new();
00274 
00275 }
00276 
00277 
00304 GiCube*
00305 giraffe_cube_create(cxsize width, cxsize height, cxsize depth, cxdouble* data)
00306 {
00307 
00308     GiCube* self = _giraffe_cube_new();
00309 
00310 
00311     _giraffe_cube_set_size(self, width, height, depth);
00312 
00313     if (self->size == 0) {
00314         _giraffe_cube_delete(self);
00315         return NULL;
00316     }
00317 
00318     if (data != NULL) {
00319         self->pixels = data;
00320     }
00321     else {
00322         self->pixels = cx_calloc(self->size, sizeof(cxdouble));
00323     }
00324 
00325     cx_assert(self->pixels != NULL);
00326 
00327 
00328     /*
00329      * Create the image list object for accessing the cube plane by plane.
00330      * It is also needed (for the time being) to save a cube to disk.
00331      */
00332 
00333     giraffe_error_push();
00334 
00335     _giraffe_cube_init_planes(self);
00336 
00337     if (cpl_error_get_code() != CPL_ERROR_NONE) {
00338         _giraffe_cube_delete(self);
00339         return NULL;
00340     }
00341 
00342     giraffe_error_pop();
00343 
00344     return self;
00345 
00346 }
00347 
00348 
00361 void
00362 giraffe_cube_delete(GiCube* self)
00363 {
00364 
00365     if (self != NULL) {
00366         _giraffe_cube_delete(self);
00367     }
00368 
00369     return;
00370 
00371 }
00372 
00373 
00387 cxsize
00388 giraffe_cube_get_width(const GiCube* self)
00389 {
00390 
00391     cx_assert(self != NULL);
00392     return self->width;
00393 
00394 }
00395 
00396 
00410 cxsize
00411 giraffe_cube_get_height(const GiCube* self)
00412 {
00413 
00414     cx_assert(self != NULL);
00415     return self->height;
00416 
00417 }
00418 
00419 
00433 cxsize
00434 giraffe_cube_get_depth(const GiCube* self)
00435 {
00436 
00437     cx_assert(self != NULL);
00438     return self->depth;
00439 
00440 }
00441 
00442 
00456 cxsize
00457 giraffe_cube_get_size(const GiCube* self)
00458 {
00459 
00460     cx_assert(self != NULL);
00461     return self->size;
00462 
00463 }
00464 
00465 
00484 cxint
00485 giraffe_cube_set_size(GiCube* self, cxsize width, cxsize height, cxsize depth)
00486 {
00487 
00488     const cxchar* const _id = "giraffe_cube_set_size";
00489 
00490 
00491     cx_assert(self != NULL);
00492 
00493     if ((width == 0) || (height == 0) || (depth == 0)) {
00494         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
00495         return 1;
00496     }
00497 
00498     if ((self->width == width) && (self->height == height) &&
00499         (self->depth == depth)) {
00500         memset(self->pixels, 0, self->size * sizeof(cxdouble));
00501     }
00502     else {
00503 
00504         /*
00505          * Clear the list of planes and destroy the old pixel buffer
00506          */
00507 
00508         if (self->planes != NULL) {
00509             _giraffe_cube_clear_planes(self);
00510         }
00511 
00512         if (self->pixels != NULL) {
00513             cx_free(self->pixels);
00514         }
00515 
00516 
00517         /*
00518          * Set the new sizes
00519          */
00520 
00521         _giraffe_cube_set_size(self, width, height, depth);
00522 
00523 
00524         /*
00525          * Re-create the pixel buffer and the list of planes from the updated
00526          * size specifications.
00527          */
00528 
00529         self->pixels = cx_calloc(self->size, sizeof(cxdouble));
00530         cx_assert(self->pixels);
00531 
00532 
00533         giraffe_error_push();
00534 
00535         _giraffe_cube_init_planes(self);
00536 
00537         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00538             return 1;
00539         }
00540 
00541         giraffe_error_pop();
00542 
00543     }
00544 
00545     return 0;
00546 
00547 }
00548 
00549 
00564 cxdouble*
00565 giraffe_cube_get_data(const GiCube* self)
00566 {
00567 
00568     const cxchar* const _id = "giraffe_cube_get_data";
00569 
00570 
00571     if (self == NULL) {
00572         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00573         return 0;
00574     }
00575 
00576     return self->pixels;
00577 
00578 }
00579 
00580 
00601 cxint
00602 giraffe_cube_get_xaxis(const GiCube* self, cxdouble* start, cxdouble* step)
00603 {
00604 
00605     cx_assert(self != NULL);
00606 
00607     return _giraffe_cube_get_axis(self, GICUBE_X, start, step);
00608 
00609 }
00610 
00611 
00632 cxint
00633 giraffe_cube_get_yaxis(const GiCube* self, cxdouble* start, cxdouble* step)
00634 {
00635 
00636     cx_assert(self != NULL);
00637 
00638     return _giraffe_cube_get_axis(self, GICUBE_Y, start, step);
00639 
00640 }
00641 
00642 
00663 cxint
00664 giraffe_cube_get_zaxis(const GiCube* self, cxdouble* start, cxdouble* step)
00665 {
00666 
00667     cx_assert(self != NULL);
00668 
00669     return _giraffe_cube_get_axis(self, GICUBE_Z, start, step);
00670 
00671 }
00672 
00673 
00689 cxint
00690 giraffe_cube_set_xaxis(GiCube* self, cxdouble start, cxdouble step)
00691 {
00692 
00693     cx_assert(self != NULL);
00694 
00695     return _giraffe_cube_set_axis(self, GICUBE_X, start, step);
00696 
00697 }
00698 
00699 
00715 cxint
00716 giraffe_cube_set_yaxis(GiCube* self, cxdouble start, cxdouble step)
00717 {
00718 
00719     cx_assert(self != NULL);
00720 
00721     return _giraffe_cube_set_axis(self, GICUBE_Y, start, step);
00722 
00723 }
00724 
00725 
00741 cxint
00742 giraffe_cube_set_zaxis(GiCube* self, cxdouble start, cxdouble step)
00743 {
00744 
00745     cx_assert(self != NULL);
00746 
00747     return _giraffe_cube_set_axis(self, GICUBE_Z, start, step);
00748 
00749 }
00750 
00751 
00769 cxint
00770 giraffe_cube_save(const GiCube* self, cpl_propertylist* properties,
00771                   const cxchar* filename, cxcptr data)
00772 {
00773 
00774     cxbool xaxis = FALSE;
00775     cxbool yaxis = FALSE;
00776     cxbool zaxis = FALSE;
00777 
00778     cxdouble xstart = 0.;
00779     cxdouble xstep = 0.;
00780     cxdouble ystart = 0.;
00781     cxdouble ystep = 0.;
00782     cxdouble zstart = 0.;
00783     cxdouble zstep = 0.;
00784 
00785 
00786     /* Unused */
00787     data = NULL;
00788 
00789     if (self == NULL || properties == NULL || filename == NULL) {
00790         return -1;
00791     }
00792 
00793 
00794     /*
00795      * Update the data cube's properties. The world coordinates are only
00796      * written if the information is present for all three axes.
00797      */
00798 
00799     if (giraffe_cube_get_xaxis(self, &xstart, &xstep) == 0) {
00800         xaxis = TRUE;
00801     }
00802 
00803     if (giraffe_cube_get_yaxis(self, &ystart, &ystep) == 0) {
00804         yaxis = TRUE;
00805     }
00806 
00807     if (giraffe_cube_get_zaxis(self, &zstart, &zstep) == 0) {
00808         zaxis = TRUE;
00809     }
00810 
00811 
00812     if ((xaxis == TRUE) && (yaxis == TRUE) && (zaxis == TRUE)) {
00813 
00814         const cxchar* ctype[] = {"PIXEL", "PIXEL", "WAVE"};
00815         const cxchar* cunit[] = {"pixel", "pixel", "nm"};
00816 
00817         cxint status = 0;
00818 
00819         cxdouble crpix[] = {1., 1., 1.};
00820         cxdouble crval[] = {xstart, ystart, zstart};
00821 
00822         cpl_matrix* cd = cpl_matrix_new(3, 3);
00823 
00824         cpl_matrix_set(cd, 0, 0, xstep);
00825         cpl_matrix_set(cd, 1, 1, ystep);
00826         cpl_matrix_set(cd, 2, 2, zstep);
00827 
00828         status = giraffe_propertylist_update_wcs(properties, 3, crpix, crval,
00829                                                  ctype, cunit, cd);
00830 
00831         if (status != 0) {
00832             giraffe_propertylist_update_wcs(properties, 0, NULL, NULL, NULL,
00833                                             NULL, NULL);
00834         }
00835 
00836         cpl_matrix_delete(cd);
00837         cd = NULL;
00838 
00839     }
00840     else {
00841 
00842         giraffe_propertylist_update_wcs(properties, 0, NULL, NULL, NULL,
00843                                         NULL, NULL);
00844 
00845     }
00846 
00847     giraffe_error_push();
00848 
00849     cpl_imagelist_save(self->planes, filename, CPL_BPP_IEEE_FLOAT,
00850                        properties, CPL_IO_DEFAULT);
00851 
00852     if (cpl_error_get_code() != CPL_ERROR_NONE) {
00853         return 1;
00854     }
00855 
00856     giraffe_error_pop();
00857 
00858     return 0;
00859 
00860 }

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:41 2008 by doxygen 1.4.6 written by Dimitri van Heesch, © 1997-2004