GIRAFFE Pipeline Reference Manual

gicube.c

00001 /* $Id: gicube.c,v 1.5 2012/08/17 14:16:01 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: 2012/08/17 14:16:01 $
00024  * $Revision: 1.5 $
00025  * $Name: giraffe-2_10 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #  include <config.h>
00030 #endif
00031 
00032 #include <string.h>
00033 #include <math.h>
00034 
00035 #include <cxmemory.h>
00036 #include <cxmessages.h>
00037 #include <cxstrutils.h>
00038 
00039 #include <cpl_error.h>
00040 #include <cpl_array.h>
00041 #include <cpl_matrix.h>
00042 #include <cpl_image.h>
00043 #include <cpl_imagelist.h>
00044 #include <cpl_propertylist.h>
00045 
00046 #include "gialias.h"
00047 #include "gierror.h"
00048 #include "gicube.h"
00049 #include "giutils.h"
00050 
00051 
00060 enum GiCubeAxes {
00061     GICUBE_X = 0,
00062     GICUBE_Y = 1,
00063     GICUBE_Z = 2,
00064     GICUBE_AXES
00065 };
00066 
00067 typedef enum GiCubeAxes GiCubeAxes;
00068 
00069 
00070 struct GiCubeAxis {
00071     cxdouble start;
00072     cxdouble step;
00073 };
00074 
00075 typedef struct GiCubeAxis GiCubeAxis;
00076 
00077 
00078 struct GiCubeWCS {
00079     cxdouble origin[GICUBE_AXES];
00080     cxdouble point[GICUBE_AXES];
00081 
00082     cxchar* axis_type[GICUBE_AXES];
00083     cxchar* axis_unit[GICUBE_AXES];
00084 
00085     cpl_matrix* transform;
00086 };
00087 
00088 typedef struct GiCubeWCS GiCubeWCS;
00089 
00090 
00091 struct GiCube {
00092     cxsize width;
00093     cxsize height;
00094     cxsize depth;
00095     cxsize size;
00096 
00097     GiCubeAxis* axes[GICUBE_AXES];
00098 
00099     GiCubeWCS* wcs;
00100 
00101     cxdouble* pixels;
00102 
00103     cpl_imagelist* planes;
00104 };
00105 
00106 
00107 
00108 inline static void
00109 _giraffe_cube_clear_wcs(GiCube* self)
00110 {
00111 
00112     register cxsize axis = 0;
00113 
00114     for (axis = 0; axis < GICUBE_AXES; ++axis) {
00115 
00116         if (self->wcs->axis_type[axis] != NULL) {
00117             cx_free(self->wcs->axis_type[axis]);
00118             self->wcs->axis_type[axis] = NULL;
00119         }
00120 
00121         if (self->wcs->axis_unit[axis] != NULL) {
00122             cx_free(self->wcs->axis_unit[axis]);
00123             self->wcs->axis_unit[axis] = NULL;
00124         }
00125 
00126     }
00127 
00128     cpl_matrix_delete(self->wcs->transform);
00129     self->wcs->transform = NULL;
00130 
00131     cx_free(self->wcs);
00132     self->wcs = NULL;
00133 
00134     return;
00135 
00136 }
00137 
00138 
00139 inline static void
00140 _giraffe_cube_set_wcs(GiCube* self, const cpl_propertylist* axes,
00141                       const cpl_matrix* transform)
00142 {
00143 
00144     GiCubeWCS* wcs = NULL;
00145 
00146     cx_assert(self != NULL);
00147     cx_assert(axes != NULL);
00148     cx_assert(transform != NULL);
00149 
00150     wcs = cx_malloc(sizeof *self->wcs);
00151 
00152     wcs->transform = cpl_matrix_duplicate(transform);
00153 
00154     wcs->origin[GICUBE_X] = cpl_propertylist_get_double(axes, "XORIGIN");
00155     wcs->origin[GICUBE_Y] = cpl_propertylist_get_double(axes, "YORIGIN");
00156     wcs->origin[GICUBE_Z] = cpl_propertylist_get_double(axes, "ZORIGIN");
00157 
00158     wcs->point[GICUBE_X] = cpl_propertylist_get_double(axes, "XPOINT");
00159     wcs->point[GICUBE_Y] = cpl_propertylist_get_double(axes, "YPOINT");
00160     wcs->point[GICUBE_Z] = cpl_propertylist_get_double(axes, "ZPOINT");
00161 
00162     wcs->axis_type[GICUBE_X] =
00163             cx_strdup(cpl_propertylist_get_string(axes, "XTYPE"));
00164     wcs->axis_type[GICUBE_Y] =
00165             cx_strdup(cpl_propertylist_get_string(axes, "YTYPE"));
00166     wcs->axis_type[GICUBE_Z] =
00167             cx_strdup(cpl_propertylist_get_string(axes, "ZTYPE"));
00168 
00169     wcs->axis_unit[GICUBE_X] =
00170             cx_strdup(cpl_propertylist_get_string(axes, "XUNIT"));
00171     wcs->axis_unit[GICUBE_Y] =
00172             cx_strdup(cpl_propertylist_get_string(axes, "YUNIT"));
00173     wcs->axis_unit[GICUBE_Z] =
00174             cx_strdup(cpl_propertylist_get_string(axes, "ZUNIT"));
00175 
00176 
00177     if (self->wcs != NULL) {
00178         _giraffe_cube_clear_wcs(self);
00179     }
00180 
00181     self->wcs = wcs;
00182 
00183     return;
00184 
00185 }
00186 
00187 
00188 inline static cxdouble
00189 _giraffe_cube_get_wcs_origin(const GiCube* self, GiCubeAxes axis)
00190 {
00191     return self->wcs->origin[axis];
00192 }
00193 
00194 
00195 inline static cxdouble
00196 _giraffe_cube_get_wcs_point(const GiCube* self, GiCubeAxes axis)
00197 {
00198     return self->wcs->point[axis];
00199 }
00200 
00201 
00202 inline static const cxchar*
00203 _giraffe_cube_get_wcs_axistype(const GiCube* self, GiCubeAxes axis)
00204 {
00205     return self->wcs->axis_type[axis];
00206 }
00207 
00208 
00209 inline static const cxchar*
00210 _giraffe_cube_get_wcs_axisunit(const GiCube* self, GiCubeAxes axis)
00211 {
00212     return self->wcs->axis_unit[axis];
00213 }
00214 
00215 
00216 inline static const cpl_matrix*
00217 _giraffe_cube_get_wcs_transform(const GiCube* self)
00218 {
00219     return self->wcs->transform;
00220 }
00221 
00222 
00223 inline static void
00224 _giraffe_cube_set_size(GiCube* self, cxsize width, cxsize height,
00225                        cxsize depth)
00226 {
00227 
00228     self->width = width;
00229     self->height = height;
00230     self->depth = depth;
00231 
00232     self->size = self->width * self->height * self->depth;
00233 
00234     return;
00235 
00236 }
00237 
00238 
00239 inline static GiCube*
00240 _giraffe_cube_new(void)
00241 {
00242 
00243     GiCube* self = cx_malloc(sizeof *self);
00244 
00245 
00246     if (self != NULL) {
00247         _giraffe_cube_set_size(self, 0, 0, 0);
00248 
00249         self->axes[GICUBE_X] = NULL;
00250         self->axes[GICUBE_Y] = NULL;
00251         self->axes[GICUBE_Z] = NULL;
00252 
00253         self->wcs = NULL;
00254 
00255         self->pixels = NULL;
00256         self->planes = NULL;
00257     }
00258 
00259     return self;
00260 
00261 }
00262 
00263 
00264 inline static cxint
00265 _giraffe_cube_init_planes(GiCube* self)
00266 {
00267 
00268     register cxsize i = 0;
00269 
00270     register cxdouble* base = NULL;
00271 
00272 
00273     self->planes = cpl_imagelist_new();
00274     cx_assert(self->planes != NULL);
00275 
00276 
00277     base = self->pixels;
00278 
00279     for (i = 0; i < self->depth; i++) {
00280 
00281         cpl_image* plane = cpl_image_wrap_double(self->width, self->height,
00282                                                  base);
00283 
00284         cx_assert(plane != NULL);
00285         cpl_imagelist_set(self->planes, plane, i);
00286 
00287         base += self->width * self->height;
00288 
00289     }
00290 
00291     return 0;
00292 
00293 }
00294 
00295 
00296 inline static void
00297 _giraffe_cube_clear_planes(GiCube* self)
00298 {
00299 
00300     register cxsize i = 0;
00301 
00302 
00303     for (i = 0; i < self->depth; i++) {
00304 
00305         cpl_image* plane = cpl_imagelist_unset(self->planes, 0);
00306 
00307         cpl_image_unwrap(plane);
00308 
00309     }
00310 
00311     cx_assert(cpl_imagelist_get_size(self->planes) == 0);
00312 
00313     cpl_imagelist_delete(self->planes);
00314     self->planes =NULL;
00315 
00316     return;
00317 
00318 }
00319 
00320 
00321 inline static void
00322 _giraffe_cube_delete(GiCube* self)
00323 {
00324 
00325     register cxint i = 0;
00326 
00327     for (i = 0; i < GICUBE_AXES; i++) {
00328         if (self->axes[i] != NULL) {
00329             cx_free(self->axes[i]);
00330             self->axes[i] = NULL;
00331         }
00332     }
00333 
00334     if (self->wcs != NULL) {
00335         _giraffe_cube_clear_wcs(self);
00336         self->wcs = NULL;
00337     }
00338 
00339     if (self->planes != NULL) {
00340         _giraffe_cube_clear_planes(self);
00341         self->planes = NULL;
00342     }
00343 
00344     if (self->pixels != NULL) {
00345         cx_free(self->pixels);
00346         self->pixels = NULL;
00347     }
00348 
00349     cx_free(self);
00350 
00351     return;
00352 
00353 }
00354 
00355 
00356 inline static cxbool
00357 _giraffe_cube_has_axis(const GiCube* self, GiCubeAxes axis)
00358 {
00359     return (self->axes[axis] == NULL) ? FALSE : TRUE;
00360 }
00361 
00362 
00363 inline static cxint
00364 _giraffe_cube_get_axis(const GiCube* self, GiCubeAxes axis, cxdouble* start,
00365                        cxdouble* step)
00366 {
00367 
00368     if (self->axes[axis] == NULL) {
00369         return 1;
00370     }
00371     else {
00372 
00373         if (start != NULL) {
00374             *start = self->axes[axis]->start;
00375         }
00376 
00377         if (step != NULL) {
00378             *step = self->axes[axis]->step;
00379         }
00380 
00381     }
00382 
00383     return 0;
00384 
00385 }
00386 
00387 
00388 inline static cxint
00389 _giraffe_cube_set_axis(GiCube* self, GiCubeAxes axis, cxdouble start,
00390                        cxdouble step)
00391 {
00392 
00393     if (self->axes[axis] == NULL) {
00394         self->axes[axis] = cx_calloc(1, sizeof(GiCubeAxis));
00395     }
00396 
00397     cx_assert(self->axes[axis] != NULL);
00398 
00399     self->axes[axis]->start = start;
00400     self->axes[axis]->step = step;
00401 
00402     return 0;
00403 
00404 }
00405 
00406 
00419 GiCube*
00420 giraffe_cube_new(void)
00421 {
00422 
00423     return _giraffe_cube_new();
00424 
00425 }
00426 
00427 
00454 GiCube*
00455 giraffe_cube_create(cxsize width, cxsize height, cxsize depth, cxdouble* data)
00456 {
00457 
00458     GiCube* self = _giraffe_cube_new();
00459 
00460 
00461     _giraffe_cube_set_size(self, width, height, depth);
00462 
00463     if (self->size == 0) {
00464         _giraffe_cube_delete(self);
00465         return NULL;
00466     }
00467 
00468     if (data != NULL) {
00469         self->pixels = data;
00470     }
00471     else {
00472         self->pixels = cx_calloc(self->size, sizeof(cxdouble));
00473     }
00474 
00475     cx_assert(self->pixels != NULL);
00476 
00477 
00478     /*
00479      * Create the image list object for accessing the cube plane by plane.
00480      * It is also needed (for the time being) to save a cube to disk.
00481      */
00482 
00483     giraffe_error_push();
00484 
00485     _giraffe_cube_init_planes(self);
00486 
00487     if (cpl_error_get_code() != CPL_ERROR_NONE) {
00488         _giraffe_cube_delete(self);
00489         return NULL;
00490     }
00491 
00492     giraffe_error_pop();
00493 
00494     return self;
00495 
00496 }
00497 
00498 
00511 void
00512 giraffe_cube_delete(GiCube* self)
00513 {
00514 
00515     if (self != NULL) {
00516         _giraffe_cube_delete(self);
00517     }
00518 
00519     return;
00520 
00521 }
00522 
00523 
00537 cxsize
00538 giraffe_cube_get_width(const GiCube* self)
00539 {
00540 
00541     cx_assert(self != NULL);
00542     return self->width;
00543 
00544 }
00545 
00546 
00560 cxsize
00561 giraffe_cube_get_height(const GiCube* self)
00562 {
00563 
00564     cx_assert(self != NULL);
00565     return self->height;
00566 
00567 }
00568 
00569 
00583 cxsize
00584 giraffe_cube_get_depth(const GiCube* self)
00585 {
00586 
00587     cx_assert(self != NULL);
00588     return self->depth;
00589 
00590 }
00591 
00592 
00606 cxsize
00607 giraffe_cube_get_size(const GiCube* self)
00608 {
00609 
00610     cx_assert(self != NULL);
00611     return self->size;
00612 
00613 }
00614 
00615 
00634 cxint
00635 giraffe_cube_set_size(GiCube* self, cxsize width, cxsize height, cxsize depth)
00636 {
00637 
00638     const cxchar* const _id = "giraffe_cube_set_size";
00639 
00640 
00641     cx_assert(self != NULL);
00642 
00643     if ((width == 0) || (height == 0) || (depth == 0)) {
00644         cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
00645         return 1;
00646     }
00647 
00648     if ((self->width == width) && (self->height == height) &&
00649         (self->depth == depth)) {
00650         memset(self->pixels, 0, self->size * sizeof(cxdouble));
00651     }
00652     else {
00653 
00654         /*
00655          * Clear the list of planes and destroy the old pixel buffer
00656          */
00657 
00658         if (self->planes != NULL) {
00659             _giraffe_cube_clear_planes(self);
00660         }
00661 
00662         if (self->pixels != NULL) {
00663             cx_free(self->pixels);
00664         }
00665 
00666 
00667         /*
00668          * Set the new sizes
00669          */
00670 
00671         _giraffe_cube_set_size(self, width, height, depth);
00672 
00673 
00674         /*
00675          * Re-create the pixel buffer and the list of planes from the updated
00676          * size specifications.
00677          */
00678 
00679         self->pixels = cx_calloc(self->size, sizeof(cxdouble));
00680         cx_assert(self->pixels);
00681 
00682 
00683         giraffe_error_push();
00684 
00685         _giraffe_cube_init_planes(self);
00686 
00687         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00688             return 1;
00689         }
00690 
00691         giraffe_error_pop();
00692 
00693     }
00694 
00695     return 0;
00696 
00697 }
00698 
00699 
00714 cxdouble*
00715 giraffe_cube_get_data(const GiCube* self)
00716 {
00717 
00718     const cxchar* const _id = "giraffe_cube_get_data";
00719 
00720 
00721     if (self == NULL) {
00722         cpl_error_set(_id, CPL_ERROR_NULL_INPUT);
00723         return 0;
00724     }
00725 
00726     return self->pixels;
00727 
00728 }
00729 
00730 
00745 cxbool
00746 giraffe_cube_has_xaxis(const GiCube* self)
00747 {
00748     return _giraffe_cube_has_axis(self, GICUBE_X);
00749 }
00750 
00751 
00766 cxbool
00767 giraffe_cube_has_yaxis(const GiCube* self)
00768 {
00769     return _giraffe_cube_has_axis(self, GICUBE_Y);
00770 }
00771 
00772 
00787 cxbool
00788 giraffe_cube_has_zaxis(const GiCube* self)
00789 {
00790     return _giraffe_cube_has_axis(self, GICUBE_Z);
00791 }
00792 
00793 
00808 cxbool
00809 giraffe_cube_has_wcs(const GiCube* self)
00810 {
00811     return self->wcs != NULL;
00812 }
00813 
00814 
00835 cxint
00836 giraffe_cube_get_xaxis(const GiCube* self, cxdouble* start, cxdouble* step)
00837 {
00838 
00839     cx_assert(self != NULL);
00840 
00841     return _giraffe_cube_get_axis(self, GICUBE_X, start, step);
00842 
00843 }
00844 
00845 
00866 cxint
00867 giraffe_cube_get_yaxis(const GiCube* self, cxdouble* start, cxdouble* step)
00868 {
00869 
00870     cx_assert(self != NULL);
00871 
00872     return _giraffe_cube_get_axis(self, GICUBE_Y, start, step);
00873 
00874 }
00875 
00876 
00897 cxint
00898 giraffe_cube_get_zaxis(const GiCube* self, cxdouble* start, cxdouble* step)
00899 {
00900 
00901     cx_assert(self != NULL);
00902 
00903     return _giraffe_cube_get_axis(self, GICUBE_Z, start, step);
00904 
00905 }
00906 
00907 
00923 cxint
00924 giraffe_cube_set_xaxis(GiCube* self, cxdouble start, cxdouble step)
00925 {
00926 
00927     cx_assert(self != NULL);
00928 
00929     return _giraffe_cube_set_axis(self, GICUBE_X, start, step);
00930 
00931 }
00932 
00933 
00949 cxint
00950 giraffe_cube_set_yaxis(GiCube* self, cxdouble start, cxdouble step)
00951 {
00952 
00953     cx_assert(self != NULL);
00954 
00955     return _giraffe_cube_set_axis(self, GICUBE_Y, start, step);
00956 
00957 }
00958 
00959 
00975 cxint
00976 giraffe_cube_set_zaxis(GiCube* self, cxdouble start, cxdouble step)
00977 {
00978 
00979     cx_assert(self != NULL);
00980 
00981     return _giraffe_cube_set_axis(self, GICUBE_Z, start, step);
00982 
00983 }
00984 
00985 
01000 void
01001 giraffe_cube_clear_wcs(GiCube* self)
01002 {
01003 
01004     if (self->wcs != NULL) {
01005         _giraffe_cube_clear_wcs(self);
01006     }
01007 
01008     return;
01009 
01010 }
01011 
01012 
01039 cxint
01040 giraffe_cube_set_wcs(GiCube* self, const cpl_propertylist* axes,
01041                      const cpl_matrix* transformation)
01042 {
01043 
01044     cx_assert(self != NULL);
01045 
01046     if ((axes == NULL) || (transformation == NULL)) {
01047         return -1;
01048     }
01049 
01050     if ((cpl_matrix_get_nrow(transformation) != GICUBE_AXES) ||
01051             (cpl_matrix_get_ncol(transformation) != GICUBE_AXES)) {
01052         return 3;
01053     }
01054 
01055     if ((cpl_propertylist_has(axes, "XORIGIN") == FALSE) ||
01056             (cpl_propertylist_has(axes, "YORIGIN") == FALSE) ||
01057             (cpl_propertylist_has(axes, "ZORIGIN") == FALSE)) {
01058         return 2;
01059     }
01060 
01061     if ((cpl_propertylist_has(axes, "XPOINT") == FALSE) ||
01062             (cpl_propertylist_has(axes, "YPOINT") == FALSE) ||
01063             (cpl_propertylist_has(axes, "ZPOINT") == FALSE)) {
01064         return 2;
01065     }
01066 
01067     if ((cpl_propertylist_has(axes, "XTYPE") == FALSE) ||
01068             (cpl_propertylist_has(axes, "YTYPE") == FALSE) ||
01069             (cpl_propertylist_has(axes, "ZTYPE") == FALSE)) {
01070         return 2;
01071     }
01072 
01073     if ((cpl_propertylist_has(axes, "XUNIT") == FALSE) ||
01074             (cpl_propertylist_has(axes, "YUNIT") == FALSE) ||
01075             (cpl_propertylist_has(axes, "ZUNIT") == FALSE)) {
01076         return 2;
01077     }
01078 
01079     _giraffe_cube_set_wcs(self, axes, transformation);
01080 
01081     return 1;
01082 }
01083 
01084 
01098 cxint
01099 giraffe_cube_sqrt(GiCube* self)
01100 {
01101 
01102     cpl_error_code status = CPL_ERROR_NONE;
01103 
01104 
01105     if (self == NULL) {
01106         return -1;
01107     }
01108 
01109     cx_assert(self->planes != NULL);
01110 
01111     status = cpl_imagelist_power(self->planes, 0.5);
01112 
01113     if (status != CPL_ERROR_NONE) {
01114         return 1;
01115     }
01116 
01117     return 0;
01118 
01119 }
01120 
01121 
01149 cpl_image*
01150 giraffe_cube_integrate(const GiCube* self, cxdouble start, cxdouble end)
01151 {
01152 
01153     cxsize depth = 0;
01154     cxsize first = (cxsize)ceil(start);
01155     cxsize last  = (cxsize)floor(end);
01156 
01157     cpl_image* image = NULL;
01158 
01159 
01160     if (self == NULL) {
01161         return NULL;
01162     }
01163 
01164     depth = giraffe_cube_get_depth(self);
01165 
01166     if ((start >= end) || (start < 0.) || (end > depth)) {
01167         return NULL;
01168     }
01169 
01170 
01171     image = cpl_image_duplicate(cpl_imagelist_get(self->planes, first));
01172 
01173     if (image != NULL) {
01174 
01175         if (first == last) {
01176             cpl_image_multiply_scalar(image, (end - start));
01177         }
01178         else {
01179 
01180             cxsize i = 0;
01181 
01182             cxdouble fstart = first - start;
01183             cxdouble fend   = end - last;
01184 
01185 
01186             for (i = first + 1; i < last; ++i) {
01187                 cpl_image_add(image,
01188                               cpl_imagelist_get_const(self->planes, i));
01189             }
01190 
01191 
01192             /*
01193              * Correct for the pixel fractions at both ends of the
01194              * integration domain.
01195              */
01196 
01197             if ((fstart > 0.) && (first > 0)) {
01198                 cpl_image* tmp = cpl_imagelist_get(self->planes, first - 1);
01199 
01200                 tmp = cpl_image_multiply_scalar_create(tmp, fstart);
01201                 cpl_image_add(image, tmp);
01202 
01203                 cpl_image_delete(tmp);
01204                 tmp = NULL;
01205             }
01206 
01207             if ((fend > 0.) && (last < depth)) {
01208                 cpl_image* tmp = cpl_imagelist_get(self->planes, last);
01209 
01210                 tmp = cpl_image_multiply_scalar_create(tmp, fend);
01211                 cpl_image_add(image, tmp);
01212 
01213                 cpl_image_delete(tmp);
01214                 tmp = NULL;
01215             }
01216 
01217         }
01218 
01219     }
01220 
01221     return image;
01222 
01223 }
01224 
01225 
01243 cxint
01244 giraffe_cube_save(const GiCube* self, cpl_propertylist* properties,
01245                   const cxchar* filename, cxcptr data)
01246 {
01247 
01248     cxbool xaxis = FALSE;
01249     cxbool yaxis = FALSE;
01250     cxbool zaxis = FALSE;
01251 
01252     cxdouble xstart = 0.;
01253     cxdouble xstep  = 0.;
01254     cxdouble ystart = 0.;
01255     cxdouble ystep  = 0.;
01256     cxdouble zstart = 0.;
01257     cxdouble zstep  = 0.;
01258 
01259     cxuint iomode = CPL_IO_CREATE;
01260 
01261 
01262     if (properties == NULL || filename == NULL) {
01263         return -1;
01264     }
01265 
01266 
01267     /*
01268      * If present use the cube writer configuration
01269      */
01270 
01271     if (data != NULL) {
01272         iomode = *((cxuint*)data);
01273     }
01274 
01275 
01276     if (self == NULL) {
01277 
01278         /*
01279          * If no cube has been provided, but properties and a filename
01280          * were given an empty cube is written to the file. Currently
01281          * this is restricted to creating a new cube file, to avoid
01282          * turning the property list into a valid extension header.
01283          */
01284 
01285         if (iomode != CPL_IO_CREATE) {
01286             return -2;
01287         }
01288 
01289         giraffe_error_push();
01290 
01291         cpl_propertylist_erase_regexp(properties, "CRVAL[0-9]*", 0);
01292         cpl_propertylist_erase_regexp(properties, "CRPIX[0-9]*", 0);
01293         cpl_propertylist_erase_regexp(properties, "CDELT[0-9]*", 0);
01294         cpl_propertylist_erase_regexp(properties, "CTYPE[0-9]*", 0);
01295         cpl_propertylist_erase_regexp(properties, "CUNIT[0-9]*", 0);
01296 
01297         cpl_propertylist_erase(properties, GIALIAS_BUNIT);
01298 
01299         cpl_propertylist_erase(properties, "DATAMIN");
01300         cpl_propertylist_erase(properties, "DATAMAX");
01301 
01302         cpl_propertylist_erase(properties, GIALIAS_DATAMEAN);
01303         cpl_propertylist_erase(properties, GIALIAS_DATAMEDI);
01304         cpl_propertylist_erase(properties, GIALIAS_DATASIG);
01305 
01306         cpl_propertylist_save(properties, filename, iomode);
01307 
01308         if (cpl_error_get_code() != CPL_ERROR_NONE) {
01309             return 1;
01310         }
01311 
01312         giraffe_error_pop();
01313 
01314     }
01315     else {
01316 
01317         cxsize size = 0;
01318 
01319         const cpl_array* pixels = NULL;
01320 
01321 
01322         /*
01323          * Update the data cube's properties. The world coordinates are only
01324          * written if a world coordinate system has been previously defined.
01325          * If a full world coordinate system is not present, the world
01326          * coordinates as defined by the cube's axes are used provided that
01327          * the information is present for all three axes. If this information
01328          * is missing too, no world coordinates are written.
01329          */
01330 
01331         if (giraffe_cube_get_xaxis(self, &xstart, &xstep) == 0) {
01332             xaxis = TRUE;
01333         }
01334 
01335         if (giraffe_cube_get_yaxis(self, &ystart, &ystep) == 0) {
01336             yaxis = TRUE;
01337         }
01338 
01339         if (giraffe_cube_get_zaxis(self, &zstart, &zstep) == 0) {
01340             zaxis = TRUE;
01341         }
01342 
01343 
01344         if (giraffe_cube_has_wcs(self) == TRUE) {
01345 
01346             const cxchar* ctype[GICUBE_AXES];
01347             const cxchar* cunit[GICUBE_AXES];
01348 
01349             cxint status = 0;
01350 
01351             cxdouble crpix[GICUBE_AXES];
01352             cxdouble crval[GICUBE_AXES];
01353 
01354             const cpl_matrix* cd = _giraffe_cube_get_wcs_transform(self);
01355 
01356 
01357             crpix[GICUBE_X] = _giraffe_cube_get_wcs_origin(self, GICUBE_X);
01358             crpix[GICUBE_Y] = _giraffe_cube_get_wcs_origin(self, GICUBE_Y);
01359             crpix[GICUBE_Z] = _giraffe_cube_get_wcs_origin(self, GICUBE_Z);
01360 
01361             crval[GICUBE_X] = _giraffe_cube_get_wcs_point(self, GICUBE_X);
01362             crval[GICUBE_Y] = _giraffe_cube_get_wcs_point(self, GICUBE_Y);
01363             crval[GICUBE_Z] = _giraffe_cube_get_wcs_point(self, GICUBE_Z);
01364 
01365             ctype[GICUBE_X] = _giraffe_cube_get_wcs_axistype(self, GICUBE_X);
01366             ctype[GICUBE_Y] = _giraffe_cube_get_wcs_axistype(self, GICUBE_Y);
01367             ctype[GICUBE_Z] = _giraffe_cube_get_wcs_axistype(self, GICUBE_Z);
01368 
01369             cunit[GICUBE_X] = _giraffe_cube_get_wcs_axisunit(self, GICUBE_X);
01370             cunit[GICUBE_Y] = _giraffe_cube_get_wcs_axisunit(self, GICUBE_Y);
01371             cunit[GICUBE_Z] = _giraffe_cube_get_wcs_axisunit(self, GICUBE_Z);
01372 
01373             status = giraffe_propertylist_update_wcs(properties, GICUBE_AXES,
01374                                                      crpix, crval, ctype, cunit,
01375                                                      cd);
01376 
01377             if (status != 0) {
01378                 giraffe_propertylist_update_wcs(properties, 0, NULL, NULL, NULL,
01379                                                 NULL, NULL);
01380             }
01381 
01382         }
01383         else if ((xaxis == TRUE) && (yaxis == TRUE) && (zaxis == TRUE)) {
01384 
01385             const cxchar* ctype[] = {"PIXEL", "PIXEL", "AWAV"};
01386             const cxchar* cunit[] = {"bin", "bin", "nm"};
01387 
01388             cxint status = 0;
01389 
01390             cxdouble crpix[] = {1., 1., 1.};
01391             cxdouble crval[] = {xstart, ystart, zstart};
01392 
01393             cpl_matrix* cd = cpl_matrix_new(3, 3);
01394 
01395             cpl_matrix_set(cd, 0, 0, xstep);
01396             cpl_matrix_set(cd, 1, 1, ystep);
01397             cpl_matrix_set(cd, 2, 2, zstep);
01398 
01399             status = giraffe_propertylist_update_wcs(properties, GICUBE_AXES,
01400                                                      crpix, crval, ctype, cunit,
01401                                                      cd);
01402 
01403             if (status != 0) {
01404                 giraffe_propertylist_update_wcs(properties, 0, NULL, NULL, NULL,
01405                                                 NULL, NULL);
01406             }
01407 
01408             cpl_matrix_delete(cd);
01409             cd = NULL;
01410 
01411         }
01412         else {
01413 
01414             giraffe_propertylist_update_wcs(properties, 0, NULL, NULL, NULL,
01415                                             NULL, NULL);
01416 
01417         }
01418 
01419 
01420         /*
01421          * Update data properties
01422          */
01423 
01424         giraffe_error_push();
01425 
01426         size = giraffe_cube_get_size(self);
01427         pixels = cpl_array_wrap_double(giraffe_cube_get_data(self), size);
01428 
01429 
01430         cpl_propertylist_update_string(properties, GIALIAS_BUNIT,
01431                                        "adu");
01432 
01433         cpl_propertylist_update_double(properties, GIALIAS_DATAMIN,
01434                                        cpl_array_get_min(pixels));
01435         cpl_propertylist_set_comment(properties, GIALIAS_DATAMIN,
01436                                      "Minimal pixel value");
01437 
01438         cpl_propertylist_update_double(properties, GIALIAS_DATAMAX,
01439                                        cpl_array_get_max(pixels));
01440         cpl_propertylist_set_comment(properties, GIALIAS_DATAMAX,
01441                                      "Maximum pixel value");
01442 
01443         cpl_propertylist_update_double(properties, GIALIAS_DATAMEAN,
01444                                        cpl_array_get_mean(pixels));
01445         cpl_propertylist_set_comment(properties, GIALIAS_DATAMEAN,
01446                                      "Mean of pixel values");
01447 
01448         cpl_propertylist_update_double(properties, GIALIAS_DATASIG,
01449                                        cpl_array_get_stdev(pixels));
01450         cpl_propertylist_set_comment(properties, GIALIAS_DATASIG,
01451                                      "Standard deviation of pixel values");
01452 
01453         cpl_propertylist_update_double(properties, GIALIAS_DATAMEDI,
01454                                        cpl_array_get_median(pixels));
01455         cpl_propertylist_set_comment(properties, GIALIAS_DATAMEDI,
01456                                      "Median of pixel values");
01457 
01458         cpl_array_unwrap((cpl_array*)pixels);
01459         pixels = NULL;
01460 
01461         if (cpl_error_get_code() != CPL_ERROR_NONE) {
01462             return 1;
01463         }
01464 
01465         giraffe_error_pop();
01466 
01467 
01468         /*
01469          * Write the data cube to the output file
01470          */
01471 
01472         giraffe_error_push();
01473 
01474         cpl_imagelist_save(self->planes, filename, CPL_BPP_IEEE_FLOAT,
01475                            properties, iomode);
01476 
01477         if (cpl_error_get_code() != CPL_ERROR_NONE) {
01478             return 1;
01479         }
01480 
01481         giraffe_error_pop();
01482 
01483     }
01484 
01485     return 0;
01486 
01487 }

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