GIRAFFE Pipeline Reference Manual

gireconstruct.c

00001 /* $Id: gireconstruct.c,v 1.31.2.1 2008/02/21 10:52:40 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: 2008/02/21 10:52:40 $
00024  * $Revision: 1.31.2.1 $
00025  * $Name: giraffe-2_5_1 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #  include <config.h>
00030 #endif
00031 
00032 #include <math.h>
00033 
00034 #include <cxslist.h>
00035 #include <cxstrutils.h>
00036 
00037 #include <cpl_propertylist.h>
00038 
00039 #include "gialias.h"
00040 #include "gimessages.h"
00041 #include "gigrating.h"
00042 #include "gireconstruct.h"
00043 #include "gisutils.h"
00044 #include "giutils.h"
00045 
00046 
00055 inline static cxint
00056 _giraffe_compare_int(cxcptr first, cxcptr second)
00057 {
00058 
00059     cxint *_first = (cxint *)first;
00060     cxint *_second = (cxint *)second;
00061 
00062     return *_first - *_second;
00063 
00064 }
00065 
00066 
00067 inline static GiImage*
00068 _giraffe_reconstruct_image(GiImage* flux, cpl_table* fibers)
00069 {
00070 
00071     cxint nx;
00072     cxint ny;
00073     cxint nf;
00074 
00075     GiImage* image = NULL;
00076 
00077 
00078     cx_assert(flux != NULL);
00079     cx_assert(fibers != NULL);
00080 
00081     nf = cpl_table_get_nrow(fibers);
00082 
00083     if (nf <= 0) {
00084         return NULL;
00085     }
00086 
00087     nx = (cxint) cpl_table_get_column_max(fibers, "X");
00088     ny = (cxint) cpl_table_get_column_max(fibers, "Y");
00089 
00090     if ((nx < 1) || (ny < 1)) {
00091         return NULL;
00092     }
00093 
00094     image = giraffe_image_create(CPL_TYPE_DOUBLE, nx, ny);
00095 
00096     if (image != NULL) {
00097 
00098         cxint j;
00099 
00100         cxdouble* _flux = cpl_image_get_data(giraffe_image_get(flux));
00101         cxdouble* _pixels = cpl_image_get_data(giraffe_image_get(image));
00102 
00103         cpl_propertylist* properties = giraffe_image_get_properties(flux);
00104 
00105 
00106         for (j = 0; j < nf; j++) {
00107 
00108             cxint idx = cpl_table_get_int(fibers, "INDEX", j, NULL);
00109             cxint x = cpl_table_get_int(fibers, "X", j, NULL);
00110             cxint y = cpl_table_get_int(fibers, "Y", j, NULL);
00111 
00112 
00113             /*
00114              * Fill image pixels skipping special fibers (CalSim or Sky)
00115              * which have x = 0 and y = 0.
00116              */
00117 
00118             if (x > 0 && y > 0) {
00119                 _pixels[(y - 1) * nx + (x - 1)] = _flux[idx - 1];
00120             }
00121 
00122         }
00123 
00124         if (properties != NULL) {
00125             giraffe_image_set_properties(image, properties);
00126         }
00127 
00128     }
00129 
00130     return image;
00131 
00132 }
00133 
00134 
00135 inline static GiCube*
00136 _giraffe_reconstruct_create_cube(GiImage* spectra, cpl_table* fibers,
00137                                  GiRange* limits)
00138 {
00139 
00140     cxint first = 0;
00141     cxint last = 0;
00142     cxint nx = 0;
00143     cxint ny = 0;
00144     cxint nz = 0;
00145 
00146     cxdouble wmin = 0.;
00147     cxdouble wmax = 0.;
00148     cxdouble wstep = 0.;
00149     cxdouble fstart = 1.;
00150     cxdouble fend = 1.;
00151 
00152     cpl_propertylist* properties = giraffe_image_get_properties(spectra);
00153 
00154     cpl_image* _spectra = giraffe_image_get(spectra);
00155 
00156     GiCube* cube = NULL;
00157 
00158 
00159     if ((properties == NULL) || (_spectra == NULL)) {
00160         return NULL;
00161     }
00162 
00163 
00164     /*
00165      * Get the spectral range of the input spectra.
00166      */
00167 
00168     if (cpl_propertylist_has(properties, GIALIAS_BINWLMIN) == FALSE) {
00169         return NULL;
00170     }
00171     else {
00172         wmin = cpl_propertylist_get_double(properties, GIALIAS_BINWLMIN);
00173     }
00174 
00175     if (cpl_propertylist_has(properties, GIALIAS_BINWLMAX) == FALSE) {
00176         return NULL;
00177     }
00178     else {
00179         wmax = cpl_propertylist_get_double(properties, GIALIAS_BINWLMAX);
00180     }
00181 
00182     if (cpl_propertylist_has(properties, GIALIAS_BINSTEP) == FALSE) {
00183         return NULL;
00184     }
00185     else {
00186         wstep = cpl_propertylist_get_double(properties, GIALIAS_BINSTEP);
00187     }
00188 
00189 
00190     /*
00191      * Determine the pixel limits corresponding to the spectral range.
00192      */
00193 
00194     first = 0;
00195     last = cpl_image_get_size_y(_spectra) - 1;
00196 
00197     if (giraffe_range_get_min(limits) > wmin) {
00198 
00199         cxdouble pixel = (giraffe_range_get_min(limits) - wmin) / wstep;
00200 
00201 
00202         first += ceil(pixel);
00203         fstart = pixel - first;
00204 
00205     }
00206 
00207     if (giraffe_range_get_max(limits) < wmax) {
00208 
00209         cxdouble pixel = last - (wmax - giraffe_range_get_max(limits)) / wstep;
00210 
00211 
00212         last = floor(pixel);
00213         fend = pixel - last;
00214 
00215     }
00216 
00217 
00218     /*
00219      * Determine the layout of the cube from the list of fibers.
00220      */
00221 
00222     nx = (cxint) cpl_table_get_column_max(fibers, "X");
00223     ny = (cxint) cpl_table_get_column_max(fibers, "Y");
00224     nz = last - first + 1;
00225 
00226 
00227     /*
00228      * Create the data cube and fill it with the flux values.
00229      */
00230 
00231     cube = giraffe_cube_create(nx, ny, nz, NULL);
00232 
00233     giraffe_cube_set_xaxis(cube, 1., 1.);
00234     giraffe_cube_set_yaxis(cube, 1., 1.);
00235     giraffe_cube_set_zaxis(cube, wmin, wstep);
00236 
00237     if (cube != NULL) {
00238 
00239         register cxint i = 0;
00240         register cxint nf = cpl_table_get_nrow(fibers);
00241 
00242         cxdouble* spixels = cpl_image_get_data_double(_spectra);
00243         cxdouble* cpixels = giraffe_cube_get_data(cube);
00244 
00245 
00246         cx_assert(spixels != NULL);
00247         cx_assert(cpixels != NULL);
00248         cx_assert(nf == cpl_image_get_size_x(_spectra));
00249 
00250         for (i = 0; i < nf; i++) {
00251 
00252             register cxint j = 0;
00253 
00254             cxint idx = cpl_table_get_int(fibers, "INDEX", i, NULL) - 1;
00255             cxint x = cpl_table_get_int(fibers, "X", i, NULL) - 1;
00256             cxint y = cpl_table_get_int(fibers, "Y", i, NULL) - 1;
00257 
00258 
00259             /*
00260              * Fill image pixels skipping special fibers (CalSim or Sky)
00261              * which have x = 0 and y = 0.
00262              */
00263 
00264             for (j = 0; j < nz; j++) {
00265 
00266                 if ((x >= 0) && (y >= 0)) {
00267                     cpixels[(ny * j + y) * nx + x] =
00268                         spixels[(first + j) * nf + idx];
00269                 }
00270 
00271             }
00272 
00273         }
00274 
00275     }
00276 
00277     return cube;
00278 
00279 }
00280 
00281 
00282 inline static cxint
00283 _giraffe_reconstruct_build_images(cx_slist* images, cx_slist* fluxes,
00284                                   cpl_table* fibers)
00285 {
00286 
00287     cx_slist_iterator first = cx_slist_begin(fluxes);
00288 
00289     while (first != cx_slist_end(fluxes)) {
00290 
00291         GiImage* flux = cx_slist_get(fluxes, first);
00292         GiImage* image = NULL;
00293 
00294 
00295         image = _giraffe_reconstruct_image(flux, fibers);
00296 
00297         if (image == NULL) {
00298             return -1;
00299         }
00300 
00301         cx_slist_push_back(images, image);
00302         first = cx_slist_next(fluxes, first);
00303 
00304     }
00305 
00306     cx_assert(cx_slist_size(images) == cx_slist_size(fluxes));
00307 
00308     return 0;
00309 
00310 }
00311 
00312 
00313 inline static cxint
00314 _giraffe_reconstruct_get_subslits(cxint** ssn, cpl_table* fibers)
00315 {
00316 
00317     cxint i;
00318     cxint nfibers = 0;
00319     cxint nss = 0;
00320 
00321 
00322     cx_assert(ssn != NULL);
00323 
00324     if (fibers == NULL) {
00325         return 0;
00326     }
00327 
00328     nfibers = cpl_table_get_nrow(fibers);
00329 
00330     if (nfibers > 0) {
00331 
00332         *ssn = cx_malloc(nfibers * sizeof(cxint));
00333         (*ssn)[nss] = cpl_table_get_int(fibers, "SSN", 0, NULL);
00334         ++nss;
00335 
00336         for (i = 1; i < nfibers; i++) {
00337 
00338             cxint _ssn = cpl_table_get_int(fibers, "SSN", i, NULL);
00339 
00340             if (_ssn != (*ssn)[nss - 1]) {
00341                 (*ssn)[nss] = _ssn;
00342                 ++nss;
00343             }
00344 
00345         }
00346 
00347         *ssn = cx_realloc(*ssn, nss * sizeof(cxint));
00348         qsort(*ssn, nss, sizeof(cxint), _giraffe_compare_int);
00349 
00350     }
00351 
00352     return nss;
00353 
00354 }
00355 
00356 
00357 inline static cxint
00358 _giraffe_reconstruct_build_subslits(cx_slist* subslits, const cx_slist* fluxes,
00359                                     const cpl_table* fibers, cxint nslits,
00360                                     const cxint* slits)
00361 {
00362 
00363     cxint i;
00364 
00365     cx_slist* subfibers = NULL;
00366 
00367     cx_slist_iterator first;
00368 
00369 
00370     if (!cx_slist_empty(subslits)) {
00371         return 1;
00372     }
00373 
00374     subfibers = cx_slist_new();
00375 
00376     for (i = 0; i < nslits; i++) {
00377 
00378         cpl_table* _fibers = NULL;
00379 
00380         cpl_table_unselect_all((cpl_table*) fibers);
00381         cpl_table_or_selected_int((cpl_table*) fibers, "SSN", CPL_EQUAL_TO,
00382                                   slits[i]);
00383 
00384         _fibers = cpl_table_extract_selected((cpl_table*) fibers);
00385 
00386         if (_fibers == NULL || cpl_table_get_nrow(_fibers) <= 0) {
00387             cx_slist_destroy(subfibers, (cx_free_func)cpl_table_delete);
00388             return 2;
00389         }
00390 
00391         cx_slist_push_back(subfibers, _fibers);
00392 
00393     }
00394 
00395     first = cx_slist_begin(fluxes);
00396 
00397     while (first != cx_slist_end(fluxes)) {
00398 
00399         cx_slist* subimages = cx_slist_new();
00400         cx_slist_iterator fpos = cx_slist_begin(subfibers);
00401 
00402 
00403         while (fpos != cx_slist_end(subfibers)) {
00404 
00405             cpl_table* _fibers = cx_slist_get(subfibers, fpos);
00406 
00407             GiImage* subimage = NULL;
00408             GiImage* flux = cx_slist_get(fluxes, first);
00409 
00410             subimage = _giraffe_reconstruct_image(flux, _fibers);
00411 
00412             cx_slist_push_back(subimages, subimage);
00413             fpos = cx_slist_next(subfibers, fpos);
00414 
00415         }
00416 
00417         cx_assert(cx_slist_size(subimages) == (cxsize) nslits);
00418 
00419         cx_slist_push_back(subslits, subimages);
00420         first = cx_slist_next(fluxes, first);
00421 
00422     }
00423 
00424     cx_slist_destroy(subfibers, (cx_free_func) cpl_table_delete);
00425     cx_assert(cx_slist_size(subslits) == cx_slist_size(fluxes));
00426 
00427     return 0;
00428 
00429 }
00430 
00431 
00432 inline static cxint
00433 _giraffe_reconstruct_arrange_subslits(cx_slist* images,
00434                                       const cx_slist* subimages,
00435                                       cxint nrow, cxint ncolumn,
00436                                       cxint offset)
00437 {
00438 
00439     cx_slist_iterator spos;
00440 
00441 
00442     cx_assert(images != NULL);
00443 
00444     if (subimages == NULL || cx_slist_empty(subimages)) {
00445         return 1;
00446     }
00447 
00448     if (ncolumn <= 0) {
00449         return 1;
00450     }
00451 
00452     spos = cx_slist_begin(subimages);
00453 
00454     while (spos != cx_slist_end(subimages)) {
00455 
00456         cx_slist* subslits = cx_slist_get(subimages, spos);
00457 
00458         cx_slist_iterator ipos = NULL;
00459 
00460         cxint x = 0;
00461         cxint y = 0;
00462         cxint nx = 0;
00463         cxint ny = 0;
00464         cxint sx = 0;
00465         cxint sy = 0;
00466         cxint column = 0;
00467         cxint xshift = offset;
00468         cxint yshift = offset;
00469         cxint nslit = cx_slist_size(subslits);
00470 
00471         cpl_propertylist* properties = NULL;
00472 
00473         GiImage* image  = NULL;
00474 
00475 
00476         /*
00477          * Compute the size of the combined output image from the largest
00478          * image in the list. The properties of the mosaic image are taken
00479          * from the first (non-empty) image in the list.
00480          */
00481 
00482         ipos = cx_slist_begin(subslits);
00483 
00484         while (ipos != cx_slist_end(subslits)) {
00485 
00486             const GiImage* simage = cx_slist_get(subslits, ipos);
00487 
00488             if (simage != NULL) {
00489 
00490                 cxint _nx = cpl_image_get_size_x(giraffe_image_get(simage));
00491                 cxint _ny = cpl_image_get_size_y(giraffe_image_get(simage));
00492 
00493                 sx = CX_MAX(nx, _nx);
00494                 sy = CX_MAX(ny, _ny);
00495 
00496                 if (properties == NULL) {
00497                     properties = giraffe_image_get_properties(simage);
00498                 }
00499 
00500             }
00501 
00502             ipos = cx_slist_next(subslits, ipos);
00503 
00504         }
00505 
00506         if (properties == NULL) {
00507             return 1;
00508         }
00509 
00510 
00511         /*
00512          * Adjust the number of rows to what is actually needed.
00513          */
00514 
00515         nrow = CX_MAX(nslit / ncolumn, nrow);
00516 
00517         if (nslit % ncolumn != 0) {
00518             ++nrow;
00519         }
00520 
00521 
00522         /*
00523          * Compute the size of the final "mosaic" image
00524          */
00525 
00526         nx = sx * ncolumn;
00527         ny = sy * nrow;
00528 
00529 
00530         if (offset < 0) {
00531             xshift = nx / -offset + 1;
00532             yshift = ny / -offset + 1;
00533         }
00534 
00535         nx += ncolumn * xshift - (xshift % 2);
00536         ny += nrow * yshift - (yshift % 2);
00537 
00538 
00539         /*
00540          * Arrange subimages into a single image.
00541          */
00542 
00543         image = giraffe_image_create(CPL_TYPE_DOUBLE, nx, ny);
00544         giraffe_image_set_properties(image, properties);
00545 
00546         y = yshift / 2;
00547         x = xshift / 2;
00548 
00549         ipos = cx_slist_begin(subslits);
00550 
00551         while (ipos != cx_slist_end(subslits)) {
00552 
00553             const GiImage* simage = cx_slist_get(subslits, ipos);
00554 
00555             if (simage != NULL) {
00556 
00557                 cxint status = giraffe_image_paste(image, simage,
00558                                                    x, y, TRUE);
00559 
00560                 if (status != 0) {
00561                     giraffe_image_delete(image);
00562                     return 1;
00563                 }
00564 
00565             }
00566 
00567             ++column;
00568 
00569             if (column < ncolumn) {
00570                 x += sx + xshift;
00571             }
00572             else {
00573 
00574                 column = 0;
00575 
00576                 x = xshift / 2;
00577                 y += sy + yshift;
00578 
00579             }
00580 
00581             ipos = cx_slist_next(subslits, ipos);
00582 
00583         }
00584 
00585         cx_slist_push_back(images, image);
00586         spos = cx_slist_next(subimages, spos);
00587 
00588     }
00589 
00590     return 0;
00591 
00592 }
00593 
00594 
00616 cxint
00617 giraffe_reconstruction_build(GiReconstruction* result, GiRebinning* rebinning,
00618                              GiTable* fibers, GiTable* wsolution,
00619                              GiTable* grating, GiTable* slitgeometry,
00620                              GiReconstructConfig* config)
00621 {
00622 
00623     const cxchar* const fctid = "giraffe_reconstruction_build";
00624 
00625     cxint status = 0;
00626 
00627     cx_slist* fluxes = NULL;
00628     cx_slist* images = NULL;
00629 
00630     cpl_propertylist* properties = NULL;
00631 
00632     cpl_table* _fibers = NULL;
00633 
00634     GiInstrumentMode mode;
00635 
00636     GiRange* limits = NULL;
00637 
00638     GiImage* tmp = NULL;
00639 
00640     GiCube* scube = NULL;
00641     GiCube* ecube = NULL;
00642 
00643 
00644     if (result == NULL) {
00645         cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00646         return -1;
00647     }
00648 
00649     if ((result->spectra != NULL) || (result->errors != NULL) ||
00650         (result->cube_spectra != NULL) || (result->cube_errors != NULL)) {
00651         gi_warning("Results structure at %p is not empty! Contents "
00652                    "might be lost.", fctid, result);
00653     }
00654 
00655     if (rebinning == NULL) {
00656         cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00657         return -1;
00658     }
00659 
00660     if (rebinning->spectra == NULL || rebinning->errors == NULL) {
00661         cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
00662         return -1;
00663     }
00664 
00665     if (fibers == NULL) {
00666         cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00667         return -1;
00668     }
00669 
00670     _fibers = giraffe_table_get(fibers);
00671 
00672     if (_fibers == NULL) {
00673         cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00674         return -1;
00675     }
00676 
00677     if (!cpl_table_has_column(_fibers, "X") ||
00678         !cpl_table_has_column(_fibers, "Y")) {
00679         cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00680         return -2;
00681     }
00682 
00683     if (config == NULL) {
00684         cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00685         return -1;
00686     }
00687 
00688 
00689     /*
00690      * Detemine the instrument mode. Spectra taken in IFU mode must
00691      * be processed on a per subslit basis, while ARGUS data can
00692      * be processed ignoring the subslit information (simple
00693      * reconstruction based on X and Y positions of fibers only)
00694      */
00695 
00696     properties = giraffe_image_get_properties(rebinning->spectra);
00697 
00698     if (properties == NULL) {
00699         cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00700         return -1;
00701     }
00702 
00703     mode = giraffe_get_mode(properties);
00704 
00705 
00706     /*
00707      * The image will be reconstructed from the input spectra common
00708      * wavelength range, taking into account a possibly user defined
00709      * wavelength range.
00710      */
00711 
00712     limits = giraffe_rebin_get_wavelength_range(rebinning->spectra, wsolution,
00713                                                 grating, slitgeometry, TRUE);
00714 
00715     if (limits == NULL) {
00716         cpl_msg_error(fctid, "Computation of spectra common wavelength "
00717                       "range failed!");
00718         return 1;
00719     }
00720 
00721     if (config->minimum > 0.) {
00722         if (config->minimum < giraffe_range_get_min(limits)) {
00723             cpl_msg_warning(fctid, "Ignoring invalid wavelength range "
00724                             "minimum %.3f nm", config->minimum);
00725         }
00726         else {
00727             giraffe_range_set_min(limits, config->minimum);
00728         }
00729     }
00730 
00731     if (config->maximum > 0.) {
00732         if (config->maximum > giraffe_range_get_max(limits)) {
00733             cpl_msg_warning(fctid, "Ignoring invalid wavelength range "
00734                             "maximum %.3f nm", config->maximum);
00735         }
00736         else {
00737             giraffe_range_set_max(limits, config->maximum);
00738         }
00739     }
00740 
00741     cpl_msg_info(fctid, "Building image for wavelength range [%.3f nm, "
00742                  "%.3f nm].", giraffe_range_get_min(limits),
00743                  giraffe_range_get_max(limits));
00744 
00745 
00746     /*
00747      * Convert limits if the spectrum wavelength scale is logarithmic
00748      */
00749 
00750     if (cpl_propertylist_has(properties, GIALIAS_BINSCALE)) {
00751 
00752         const cxchar* s = cpl_propertylist_get_string(properties,
00753                                                       GIALIAS_BINSCALE);
00754 
00755         if (cx_strncasecmp(s, "log", 3) == 0) {
00756             giraffe_range_set_min(limits, log(giraffe_range_get_min(limits)));
00757             giraffe_range_set_max(limits, log(giraffe_range_get_max(limits)));
00758         }
00759     }
00760     else {
00761         cpl_msg_warning(fctid, "Could not determine spectrum wavelength "
00762                         "scaling method. Missing property `%s'. Assuming "
00763                         "scaling method `linear'!", GIALIAS_BINSCALE);
00764     }
00765 
00766 
00767     /*
00768      * Create two lists, one containing the input images from which an image
00769      * shall be created. Each image in the list is used to create a
00770      * reconstructed image, which is stored in the output list.
00771      */
00772 
00773     fluxes = cx_slist_new();
00774 
00775     tmp = giraffe_integrate_flux(rebinning->spectra, limits);
00776 
00777     if (tmp == NULL) {
00778         giraffe_range_delete(limits);
00779         return 1;
00780     }
00781 
00782     cx_slist_push_back(fluxes, tmp);
00783 
00784     if (rebinning->errors != NULL) {
00785 
00786         GiImage* errors = giraffe_image_duplicate(rebinning->errors);
00787 
00788         cpl_image_power(giraffe_image_get(errors), 2.);
00789 
00790         tmp = giraffe_integrate_flux(errors, limits);
00791         giraffe_image_delete(errors);
00792 
00793         if (tmp == NULL) {
00794             cx_slist_destroy(fluxes, (cx_free_func)giraffe_image_delete);
00795             giraffe_range_delete(limits);
00796             return 1;
00797         }
00798 
00799         cx_slist_push_back(fluxes, tmp);
00800     }
00801 
00802     images = cx_slist_new();
00803 
00804 
00805     switch (mode) {
00806         case GIMODE_IFU:
00807         {
00808 
00809             cxint nssn = 0;
00810             cxint* ssn = NULL;
00811 
00812             cx_slist* subslits = NULL;
00813 
00814 
00815             /*
00816              * Determine the number and the list of used subslits.
00817              */
00818 
00819             nssn = _giraffe_reconstruct_get_subslits(&ssn, _fibers);
00820 
00821             subslits = cx_slist_new();
00822 
00823             status = _giraffe_reconstruct_build_subslits(subslits, fluxes,
00824                                                          _fibers, nssn, ssn);
00825 
00826             if (status) {
00827                 cx_free(ssn);
00828                 ssn = NULL;
00829 
00830                 cx_slist_destroy(subslits, (cx_free_func)giraffe_image_delete);
00831                 subslits = NULL;
00832 
00833                 cx_slist_destroy(images, (cx_free_func)giraffe_image_delete);
00834                 images = NULL;
00835 
00836                 cx_slist_destroy(fluxes, (cx_free_func)giraffe_image_delete);
00837                 fluxes = NULL;
00838 
00839                 return 1;
00840             }
00841 
00842             cx_free(ssn);
00843             ssn = NULL;
00844 
00845             status = _giraffe_reconstruct_arrange_subslits(images, subslits,
00846                                                            5, 3, -4);
00847 
00848             if (status) {
00849                 cx_slist_destroy(subslits, (cx_free_func)giraffe_image_delete);
00850                 subslits = NULL;
00851 
00852                 cx_slist_destroy(images,  (cx_free_func)giraffe_image_delete);
00853                 images = NULL;
00854 
00855                 cx_slist_destroy(fluxes, (cx_free_func)giraffe_image_delete);
00856                 fluxes = NULL;
00857 
00858                 return 1;
00859             }
00860 
00861             break;
00862         }
00863 
00864         case GIMODE_ARGUS:
00865         {
00866             status = _giraffe_reconstruct_build_images(images, fluxes,
00867                                                        _fibers);
00868 
00869             if (status) {
00870                 cx_slist_destroy(images, (cx_free_func)giraffe_image_delete);
00871                 images = NULL;
00872 
00873                 cx_slist_destroy(fluxes, (cx_free_func)giraffe_image_delete);
00874                 fluxes = NULL;
00875 
00876                 return 1;
00877             }
00878 
00879             if (config->cube == TRUE) {
00880 
00881                 scube = _giraffe_reconstruct_create_cube(rebinning->spectra,
00882                                                          _fibers, limits);
00883 
00884                 if (scube == NULL) {
00885 
00886                     cx_slist_destroy(images,
00887                                      (cx_free_func)giraffe_image_delete);
00888                     images = NULL;
00889 
00890                     cx_slist_destroy(fluxes,
00891                                      (cx_free_func)giraffe_image_delete);
00892                     fluxes = NULL;
00893 
00894                     return 1;
00895 
00896                 }
00897 
00898                 ecube = _giraffe_reconstruct_create_cube(rebinning->errors,
00899                                                          _fibers, limits);
00900 
00901                 if (ecube == NULL) {
00902 
00903                     giraffe_cube_delete(scube);
00904                     scube = NULL;
00905 
00906                     cx_slist_destroy(images,
00907                                      (cx_free_func)giraffe_image_delete);
00908                     images = NULL;
00909 
00910                     cx_slist_destroy(fluxes,
00911                                      (cx_free_func)giraffe_image_delete);
00912                     fluxes = NULL;
00913 
00914                     return 1;
00915 
00916                 }
00917 
00918             }
00919 
00920             break;
00921         }
00922 
00923         default:
00924             result->spectra = NULL;
00925             result->errors = NULL;
00926             result->cube_spectra = NULL;
00927             result->cube_errors = NULL;
00928 
00929             return 1;
00930             break;
00931     }
00932 
00933 
00934     /*
00935      * TBD: Treat special fibers (SimCal and Sky) here
00936      */
00937 
00938 
00939     cx_slist_destroy(fluxes, (cx_free_func)giraffe_image_delete);
00940 
00941     giraffe_range_delete(limits);
00942 
00943 
00944     /*
00945      * Hook the results into the result container.
00946      */
00947 
00948     result->spectra = cx_slist_pop_front(images);
00949 
00950     if (!cx_slist_empty(images)) {
00951 
00952         // FIXME: Use only pixels defined in the fiber table instead of
00953         //        relying on the pixel intensity to protect the square
00954         //        root computation.
00955 
00956         GiImage* errors = cx_slist_pop_front(images);
00957 
00958         cpl_image* _errors = giraffe_image_get(errors);
00959 
00960         cxint i;
00961         cxint nx = cpl_image_get_size_x(_errors);
00962         cxint ny = cpl_image_get_size_y(_errors);
00963 
00964         cxdouble* pixels = cpl_image_get_data(_errors);
00965 
00966 
00967         for (i = 0; i < nx * ny - 1; i++) {
00968             if (pixels[i] > 0.) {
00969                 pixels[i] = sqrt(pixels[i]);
00970             }
00971         }
00972 
00973         result->errors = errors;
00974 
00975     }
00976 
00977     if (scube != NULL) {
00978         result->cube_spectra = scube;
00979     }
00980 
00981     if (ecube != NULL) {
00982         result->cube_errors = ecube;
00983     }
00984 
00985     cx_assert(cx_slist_empty(images));
00986     cx_slist_destroy(images, (cx_free_func)giraffe_image_delete);
00987 
00988     return 0;
00989 
00990 }
00991 
00992 
01003 GiReconstruction*
01004 giraffe_reconstruction_new(void)
01005 {
01006 
01007     GiReconstruction* self = cx_malloc(sizeof *self);
01008 
01009     self->spectra = NULL;
01010     self->errors = NULL;
01011     self->cube_spectra = NULL;
01012     self->cube_errors = NULL;
01013 
01014     return self;
01015 
01016 }
01017 
01018 
01035 void
01036 giraffe_reconstruction_delete(GiReconstruction* reconstruction)
01037 {
01038 
01039     if (reconstruction != NULL) {
01040         cx_free(reconstruction);
01041         reconstruction = NULL;
01042     }
01043 
01044     return;
01045 
01046 }
01047 
01048 
01062 void
01063 giraffe_reconstruction_destroy(GiReconstruction* reconstruction)
01064 {
01065 
01066     if (reconstruction != NULL) {
01067 
01068         if (reconstruction->spectra != NULL) {
01069             giraffe_image_delete(reconstruction->spectra);
01070             reconstruction->spectra = NULL;
01071         }
01072 
01073         if (reconstruction->errors != NULL) {
01074             giraffe_image_delete(reconstruction->errors);
01075             reconstruction->errors = NULL;
01076         }
01077 
01078         if (reconstruction->cube_spectra != NULL) {
01079             giraffe_cube_delete(reconstruction->cube_spectra);
01080             reconstruction->cube_spectra = NULL;
01081         }
01082 
01083         if (reconstruction->cube_errors != NULL) {
01084             giraffe_cube_delete(reconstruction->cube_errors);
01085             reconstruction->cube_errors = NULL;
01086         }
01087 
01088         cx_free(reconstruction);
01089         reconstruction = NULL;
01090 
01091     }
01092 
01093     return;
01094 
01095 }
01096 
01097 
01108 GiReconstructConfig*
01109 giraffe_reconstruct_config_create(cpl_parameterlist* list)
01110 {
01111 
01112     cpl_parameter* p;
01113 
01114     GiReconstructConfig* config = NULL;
01115 
01116 
01117     if (list == NULL) {
01118         return NULL;
01119     }
01120 
01121     config = cx_calloc(1, sizeof *config);
01122 
01123 
01124     p = cpl_parameterlist_find(list, "giraffe.reconstruction.range.minimum");
01125     config->minimum = cpl_parameter_get_double(p);
01126 
01127     p = cpl_parameterlist_find(list, "giraffe.reconstruction.range.maximum");
01128     config->maximum = cpl_parameter_get_double(p);
01129 
01130     p = cpl_parameterlist_find(list, "giraffe.reconstruction.cube");
01131     config->cube = cpl_parameter_get_bool(p);
01132 
01133     return config;
01134 
01135 }
01136 
01137 
01150 void
01151 giraffe_reconstruct_config_destroy(GiReconstructConfig* config)
01152 {
01153 
01154     if (config != NULL) {
01155         cx_free(config);
01156     }
01157 
01158     return;
01159 
01160 }
01161 
01162 
01174 void
01175 giraffe_reconstruct_config_add(cpl_parameterlist* list)
01176 {
01177 
01178     cpl_parameter* p;
01179 
01180 
01181     if (list == NULL) {
01182         return;
01183     }
01184 
01185     p = cpl_parameter_new_value("giraffe.reconstruction.range.minimum",
01186                                 CPL_TYPE_DOUBLE,
01187                                 "Minimum wavelength for image reconstruction",
01188                                 "giraffe.reconstruction.range",
01189                                 0.);
01190     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "recon-min");
01191     cpl_parameterlist_append(list, p);
01192 
01193 
01194     p = cpl_parameter_new_value("giraffe.reconstruction.range.maximum",
01195                                 CPL_TYPE_DOUBLE,
01196                                 "Maximum wavelength for image reconstruction",
01197                                 "giraffe.reconstruction.range",
01198                                 0.);
01199     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "recon-max");
01200     cpl_parameterlist_append(list, p);
01201 
01202 
01203     p = cpl_parameter_new_value("giraffe.reconstruction.cube",
01204                                 CPL_TYPE_BOOL,
01205                                 "Turns data cube creation on and off "
01206                                 "(Argus only!)",
01207                                 "giraffe.reconstruction.cube",
01208                                 TRUE);
01209     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "recon-cube");
01210     cpl_parameterlist_append(list, p);
01211 
01212     return;
01213 
01214 }

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