GIRAFFE Pipeline Reference Manual

gistandard.c

00001 /* $Id: gistandard.c,v 1.18 2012/08/17 14:13:28 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: 2012/08/17 14:13:28 $
00024  * $Revision: 1.18 $
00025  * $Name: giraffe-2_10 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #  include <config.h>
00030 #endif
00031 
00032 #include <math.h>
00033 
00034 #include <cxslist.h>
00035 
00036 #include <cpl_recipe.h>
00037 #include <cpl_plugininfo.h>
00038 #include <cpl_parameterlist.h>
00039 #include <cpl_frameset.h>
00040 #include <cpl_msg.h>
00041 
00042 #include "gialias.h"
00043 #include "giframe.h"
00044 #include "gifibers.h"
00045 #include "gifiberutils.h"
00046 #include "gislitgeometry.h"
00047 #include "gipsfdata.h"
00048 #include "gibias.h"
00049 #include "gidark.h"
00050 #include "giextract.h"
00051 #include "giflat.h"
00052 #include "gitransmission.h"
00053 #include "girebinning.h"
00054 #include "gifov.h"
00055 #include "gifxcalibration.h"
00056 #include "gimessages.h"
00057 #include "gierror.h"
00058 #include "giqclog.h"
00059 #include "giutils.h"
00060 
00061 
00062 static cxint gistandard(cpl_parameterlist* config, cpl_frameset* set);
00063 static cxint giqcstandard(cpl_frameset* set);
00064 
00065 
00066 
00067 /*
00068  * Create the recipe instance, i.e. setup the parameter list for this
00069  * recipe and make it availble to the application using the interface.
00070  */
00071 
00072 static cxint
00073 gistandard_create(cpl_plugin* plugin)
00074 {
00075 
00076     cpl_recipe* recipe = (cpl_recipe*)plugin;
00077 
00078     cpl_parameter* p = NULL;
00079 
00080 
00081     giraffe_error_init();
00082 
00083 
00084     /*
00085      * We have to provide the option we accept to the application. We
00086      * need to setup our parameter list and hook it into the recipe
00087      * interface.
00088      */
00089 
00090     recipe->parameters = cpl_parameterlist_new();
00091     cx_assert(recipe->parameters != NULL);
00092 
00093 
00094     /*
00095      * Fill the parameter list.
00096      */
00097 
00098     /* Bias removal */
00099 
00100     giraffe_bias_config_add(recipe->parameters);
00101 
00102     /* Dark subtraction */
00103 
00104     /* TBD */
00105 
00106     /* Spectrum extraction */
00107 
00108     giraffe_extract_config_add(recipe->parameters);
00109 
00110     /* Flat fielding and relative fiber transmission correction */
00111 
00112     giraffe_flat_config_add(recipe->parameters);
00113 
00114     p = cpl_parameterlist_find(recipe->parameters, "giraffe.flat.apply");
00115     cx_assert(p != NULL);
00116 
00117     cpl_parameter_set_default_bool(p, FALSE);
00118 
00119     /* Spectrum rebinning */
00120 
00121     giraffe_rebin_config_add(recipe->parameters);
00122 
00123     p = cpl_parameterlist_find(recipe->parameters,
00124                                "giraffe.rebinning.range");
00125     cx_assert(p != NULL);
00126 
00127     cpl_parameter_set_default_string(p, "common");
00128 
00129     /* Image reconstruction (IFU and Argus only) */
00130 
00131     giraffe_fov_config_add(recipe->parameters);
00132 
00133     /* Flux calibration */
00134 
00135     giraffe_fxcalibration_config_add(recipe->parameters);
00136 
00137     return 0;
00138 
00139 }
00140 
00141 
00142 /*
00143  * Execute the plugin instance given by the interface.
00144  */
00145 
00146 static cxint
00147 gistandard_exec(cpl_plugin* plugin)
00148 {
00149 
00150     cxint status = 0;
00151 
00152     cpl_recipe* recipe = (cpl_recipe*)plugin;
00153 
00154 
00155     cx_assert(recipe->parameters != NULL);
00156     cx_assert(recipe->frames != NULL);
00157 
00158     status = gistandard(recipe->parameters, recipe->frames);
00159 
00160     if (status != 0) {
00161         return 1;
00162     }
00163 
00164     status = giqcstandard(recipe->frames);
00165 
00166     if (status != 0) {
00167         return 1;
00168     }
00169 
00170     return 0;
00171 
00172 }
00173 
00174 
00175 static cxint
00176 gistandard_destroy(cpl_plugin* plugin)
00177 {
00178 
00179     cpl_recipe* recipe = (cpl_recipe*)plugin;
00180 
00181 
00182     /*
00183      * We just destroy what was created during the plugin initialization
00184      * phase, i.e. the parameter list. The frame set is managed by the
00185      * application which called us, so we must not touch it,
00186      */
00187 
00188     cpl_parameterlist_delete(recipe->parameters);
00189 
00190     giraffe_error_clear();
00191 
00192     return 0;
00193 
00194 }
00195 
00196 
00197 /*
00198  * The actual recipe starts here.
00199  */
00200 
00201 static cxint
00202 gistandard(cpl_parameterlist* config, cpl_frameset* set)
00203 {
00204 
00205     const cxchar* const _id = "gistandard";
00206 
00207 
00208     const cxchar* filename = NULL;
00209 
00210     cxint status = 0;
00211 
00212     cxlong i;
00213     cxlong nstandard = 0;
00214 
00215     cxdouble exptime = 0.;
00216 
00217     cx_slist* slist = NULL;
00218 
00219     cpl_propertylist* properties = NULL;
00220 
00221     cpl_matrix* biasareas = NULL;
00222 
00223     cpl_frame* standard_frame = NULL;
00224     cpl_frame* mbias_frame = NULL;
00225     cpl_frame* mdark_frame = NULL;
00226     cpl_frame* bpixel_frame = NULL;
00227     cpl_frame* slight_frame = NULL;
00228     cpl_frame* locy_frame = NULL;
00229     cpl_frame* locw_frame = NULL;
00230     cpl_frame* flat_frame = NULL;
00231     cpl_frame* psfdata_frame = NULL;
00232     cpl_frame* grating_frame = NULL;
00233     cpl_frame* slit_frame = NULL;
00234     cpl_frame* wcal_frame = NULL;
00235     cpl_frame* rstandard_frame = NULL;
00236     cpl_frame* sext_frame = NULL;
00237     cpl_frame* rbin_frame = NULL;
00238     cpl_frame* atmext_frame = NULL;
00239     cpl_frame* flxstd_frame = NULL;
00240     cpl_frame* rsp_frame = NULL;
00241 
00242     GiImage* mbias = NULL;
00243     GiImage* mdark = NULL;
00244     GiImage* bpixel = NULL;
00245     GiImage* slight = NULL;
00246     GiImage* sstandard = NULL;
00247     GiImage* rstandard = NULL;
00248 
00249     GiTable* fibers = NULL;
00250     GiTable* slitgeometry = NULL;
00251     GiTable* grating = NULL;
00252     GiTable* wcalcoeff = NULL;
00253     GiTable* atmext = NULL;
00254     GiTable* flxstd = NULL;
00255     GiTable* refflx = NULL;
00256 
00257     GiLocalization* localization = NULL;
00258     GiExtraction* extraction = NULL;
00259     GiRebinning* rebinning = NULL;
00260     GiResponse* response = NULL;
00261 
00262     GiBiasConfig* bias_config = NULL;
00263     GiExtractConfig* extract_config = NULL;
00264     GiFlatConfig* flat_config = NULL;
00265     GiRebinConfig* rebin_config = NULL;
00266     GiFxCalibrationConfig* fxcal_config = NULL;
00267 
00268 
00269     GiInstrumentMode mode;
00270 
00271     GiRecipeInfo info = {(cxchar*)_id, 1, NULL};
00272 
00273     GiGroupInfo groups[] = {
00274         {GIFRAME_STANDARD, CPL_FRAME_GROUP_RAW},
00275         {GIFRAME_BADPIXEL_MAP, CPL_FRAME_GROUP_CALIB},
00276         {GIFRAME_BIAS_MASTER, CPL_FRAME_GROUP_CALIB},
00277         {GIFRAME_DARK_MASTER, CPL_FRAME_GROUP_CALIB},
00278         {GIFRAME_FIBER_FLAT_EXTSPECTRA, CPL_FRAME_GROUP_CALIB},
00279         {GIFRAME_FIBER_FLAT_EXTERRORS, CPL_FRAME_GROUP_CALIB},
00280         {GIFRAME_SCATTERED_LIGHT_MODEL, CPL_FRAME_GROUP_CALIB},
00281         {GIFRAME_LOCALIZATION_CENTROID, CPL_FRAME_GROUP_CALIB},
00282         {GIFRAME_LOCALIZATION_WIDTH, CPL_FRAME_GROUP_CALIB},
00283         {GIFRAME_PSF_CENTROID, CPL_FRAME_GROUP_CALIB},
00284         {GIFRAME_PSF_WIDTH, CPL_FRAME_GROUP_CALIB},
00285         {GIFRAME_PSF_DATA, CPL_FRAME_GROUP_CALIB},
00286         {GIFRAME_WAVELENGTH_SOLUTION, CPL_FRAME_GROUP_CALIB},
00287         {GIFRAME_SLITSETUP, CPL_FRAME_GROUP_CALIB},
00288         {GIFRAME_SLITMASTER, CPL_FRAME_GROUP_CALIB},
00289         {GIFRAME_GRATING, CPL_FRAME_GROUP_CALIB},
00290         {GIFRAME_EXTINCTION, CPL_FRAME_GROUP_CALIB},
00291         {GIFRAME_FLUX_STANDARDS, CPL_FRAME_GROUP_CALIB},
00292         {NULL, CPL_FRAME_GROUP_NONE}
00293     };
00294 
00295 
00296 
00297     if (!config) {
00298         cpl_msg_error(_id, "Invalid parameter list! Aborting ...");
00299         return 1;
00300     }
00301 
00302     if (!set) {
00303         cpl_msg_error(_id, "Invalid frame set! Aborting ...");
00304         return 1;
00305     }
00306 
00307     status = giraffe_frameset_set_groups(set, groups);
00308 
00309     if (status != 0) {
00310         cpl_msg_error(_id, "Setting frame group information failed!");
00311         return 1;
00312     }
00313 
00314 
00315     /*
00316      * Verify the frame set contents
00317      */
00318 
00319     nstandard = cpl_frameset_count_tags(set, GIFRAME_STANDARD);
00320 
00321     if (nstandard < 1) {
00322         cpl_msg_error(_id, "Too few (%ld) raw frames (%s) present in "
00323                       "frame set! Aborting ...", nstandard, GIFRAME_STANDARD);
00324         return 1;
00325     }
00326 
00327     locy_frame = cpl_frameset_find(set, GIFRAME_PSF_CENTROID);
00328 
00329     if (locy_frame == NULL) {
00330 
00331         locy_frame = cpl_frameset_find(set, GIFRAME_LOCALIZATION_CENTROID);
00332 
00333         if (locy_frame == NULL) {
00334             cpl_msg_info(_id, "No master localization (centroid position) "
00335                          "present in frame set. Aborting ...");
00336             return 1;
00337         }
00338 
00339     }
00340 
00341     locw_frame = cpl_frameset_find(set, GIFRAME_PSF_WIDTH);
00342 
00343     if (locw_frame == NULL) {
00344 
00345         locw_frame = cpl_frameset_find(set, GIFRAME_LOCALIZATION_WIDTH);
00346 
00347         if (locw_frame == NULL) {
00348             cpl_msg_info(_id, "No master localization (spectrum width) "
00349                          "present in frame set. Aborting ...");
00350             return 1;
00351         }
00352 
00353     }
00354 
00355     flat_frame = cpl_frameset_find(set, GIFRAME_FIBER_FLAT_EXTSPECTRA);
00356 
00357     if (flat_frame == NULL) {
00358 
00359         cpl_msg_error(_id, "No extracted flat field spectra frame present in frame set. "
00360                       "Aborting ...");
00361         return 1;
00362 
00363     }
00364 
00365     grating_frame = cpl_frameset_find(set, GIFRAME_GRATING);
00366 
00367     if (!grating_frame) {
00368         cpl_msg_error(_id, "No grating data present in frame set. "
00369                       "Aborting ...");
00370         return 1;
00371     }
00372 
00373     slit_frame = giraffe_get_slitgeometry(set);
00374 
00375     if (!slit_frame) {
00376         cpl_msg_error(_id, "No slit geometry present in frame set. "
00377                       "Aborting ...");
00378         return 1;
00379     }
00380 
00381     wcal_frame = cpl_frameset_find(set, GIFRAME_WAVELENGTH_SOLUTION);
00382 
00383     if (!wcal_frame) {
00384         cpl_msg_error(_id, "No dispersion solution present in frame set. "
00385                       "Aborting ...");
00386         return 1;
00387     }
00388 
00389     atmext_frame = cpl_frameset_find(set, GIFRAME_EXTINCTION);
00390 
00391     if (!atmext_frame) {
00392         cpl_msg_error(_id, "No atmospheric extinction table present in "
00393                       "frame set. Aborting ...");
00394         return 1;
00395     }
00396 
00397     flxstd_frame = cpl_frameset_find(set, GIFRAME_FLUX_STANDARDS);
00398 
00399     if (!flxstd_frame) {
00400         cpl_msg_error(_id, "No flux standards present in frame set. "
00401                       "Aborting ...");
00402         return 1;
00403     }
00404 
00405     bpixel_frame = cpl_frameset_find(set, GIFRAME_BADPIXEL_MAP);
00406 
00407     if (!bpixel_frame) {
00408         cpl_msg_info(_id, "No bad pixel map present in frame set.");
00409     }
00410 
00411     mbias_frame = cpl_frameset_find(set, GIFRAME_BIAS_MASTER);
00412 
00413     if (!mbias_frame) {
00414         cpl_msg_info(_id, "No master bias present in frame set.");
00415     }
00416 
00417     mdark_frame = cpl_frameset_find(set, GIFRAME_DARK_MASTER);
00418 
00419     if (!mdark_frame) {
00420         cpl_msg_info(_id, "No master dark present in frame set.");
00421     }
00422 
00423     slight_frame = cpl_frameset_find(set, GIFRAME_SCATTERED_LIGHT_MODEL);
00424 
00425     if (!slight_frame) {
00426         cpl_msg_info(_id, "No scattered light model present in frame set.");
00427     }
00428 
00429     psfdata_frame = cpl_frameset_find(set, GIFRAME_PSF_DATA);
00430 
00431     if (!psfdata_frame) {
00432         cpl_msg_info(_id, "No PSF profile parameters present in frame set.");
00433     }
00434 
00435 
00436     /*
00437      * Load raw images
00438      */
00439 
00440     slist = cx_slist_new();
00441 
00442     standard_frame = cpl_frameset_find(set, GIFRAME_STANDARD);
00443 
00444     for (i = 0; i < nstandard; i++) {
00445 
00446         filename = cpl_frame_get_filename(standard_frame);
00447 
00448         GiImage* raw = giraffe_image_new(CPL_TYPE_DOUBLE);
00449 
00450 
00451         status = giraffe_image_load(raw, filename, 0);
00452 
00453         if (status) {
00454             cpl_msg_error(_id, "Cannot load raw standard frame from '%s'. "
00455                           "Aborting ...", filename);
00456 
00457             cx_slist_destroy(slist, (cx_free_func) giraffe_image_delete);
00458 
00459             return 1;
00460         }
00461 
00462         cx_slist_push_back(slist, raw);
00463 
00464         standard_frame = cpl_frameset_find(set, NULL);
00465 
00466     }
00467 
00468     nstandard = (cxint)cx_slist_size(slist);
00469     sstandard = cx_slist_pop_front(slist);
00470 
00471     properties = giraffe_image_get_properties(sstandard);
00472     cx_assert(properties != NULL);
00473 
00474     if (nstandard > 1) {
00475 
00476         /*
00477          * Create a stacked image from the list of raw images.
00478          * Each raw image is disposed when it is no longer needed.
00479          */
00480 
00481         cpl_msg_info(_id, "Averaging standard star observations ...");
00482 
00483         exptime = cpl_propertylist_get_double(properties, GIALIAS_EXPTIME);
00484 
00485         for (i = 1; i < nstandard; i++) {
00486 
00487             cpl_propertylist* _properties;
00488 
00489             GiImage* standard = cx_slist_pop_front(slist);
00490 
00491 
00492             cpl_image_add(giraffe_image_get(sstandard),
00493                           giraffe_image_get(standard));
00494 
00495             _properties = giraffe_image_get_properties(standard);
00496             cx_assert(_properties != NULL);
00497 
00498             exptime += cpl_propertylist_get_double(_properties,
00499                                                    GIALIAS_EXPTIME);
00500 
00501             giraffe_image_delete(standard);
00502 
00503         }
00504 
00505         cpl_image_divide_scalar(giraffe_image_get(sstandard), nstandard);
00506     }
00507 
00508     cx_assert(cx_slist_empty(slist));
00509     cx_slist_delete(slist);
00510     slist = NULL;
00511 
00512 
00513     if (nstandard > 1) {
00514 
00515         /*
00516          * Update stacked standard star image properties
00517          */
00518 
00519         cpl_msg_info(_id, "Updating stacked standard star image "
00520                      "properties ...");
00521 
00522         cpl_propertylist_set_double(properties, GIALIAS_EXPTIME,
00523                                     exptime / nstandard);
00524 
00525         cpl_propertylist_append_double(properties, GIALIAS_EXPTTOT, exptime);
00526         cpl_propertylist_set_comment(properties, GIALIAS_EXPTTOT,
00527                                      "Total exposure time of all frames "
00528                                      "combined");
00529 
00530         cpl_propertylist_append_int(properties, GIALIAS_DATANCOM, nstandard);
00531         cpl_propertylist_set_comment(properties, GIALIAS_DATANCOM, "Number of "
00532                               "frames combined");
00533 
00534         cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
00535 
00536     }
00537 
00538 
00539     /*
00540      * Prepare for bias subtraction
00541      */
00542 
00543     bias_config = giraffe_bias_config_create(config);
00544 
00545     /*
00546      * Setup user defined areas to use for the bias computation
00547      */
00548 
00549     if (bias_config->method == GIBIAS_METHOD_MASTER ||
00550         bias_config->method == GIBIAS_METHOD_ZMASTER) {
00551 
00552         if (!mbias_frame) {
00553             cpl_msg_error(_id, "Missing master bias frame! Selected bias "
00554                           "removal method requires a master bias frame!");
00555 
00556             giraffe_bias_config_destroy(bias_config);
00557             giraffe_image_delete(sstandard);
00558 
00559             return 1;
00560         }
00561         else {
00562             filename = cpl_frame_get_filename(mbias_frame);
00563 
00564 
00565             mbias = giraffe_image_new(CPL_TYPE_DOUBLE);
00566             status = giraffe_image_load(mbias, filename, 0);
00567 
00568             if (status) {
00569                 cpl_msg_error(_id, "Cannot load master bias from '%s'. "
00570                               "Aborting ...", filename);
00571 
00572                 giraffe_bias_config_destroy(bias_config);
00573                 giraffe_image_delete(sstandard);
00574 
00575                 return 1;
00576             }
00577         }
00578     }
00579 
00580 
00581     /*
00582      * Load bad pixel map if it is present in the frame set.
00583      */
00584 
00585     if (bpixel_frame) {
00586 
00587         filename = cpl_frame_get_filename(bpixel_frame);
00588 
00589 
00590         bpixel = giraffe_image_new(CPL_TYPE_INT);
00591         status = giraffe_image_load(bpixel, filename, 0);
00592 
00593         if (status) {
00594             cpl_msg_error(_id, "Cannot load bad pixel map from '%s'. "
00595                           "Aborting ...", filename);
00596 
00597             giraffe_image_delete(bpixel);
00598             bpixel = NULL;
00599 
00600             if (mbias != NULL) {
00601                 giraffe_image_delete(mbias);
00602                 mbias = NULL;
00603             }
00604 
00605             giraffe_bias_config_destroy(bias_config);
00606             bias_config = NULL;
00607 
00608             giraffe_image_delete(sstandard);
00609             sstandard = NULL;
00610 
00611             return 1;
00612         }
00613 
00614     }
00615 
00616 
00617     /*
00618      * Compute and remove the bias from the stacked flat field frame.
00619      */
00620 
00621     rstandard = giraffe_image_new(CPL_TYPE_DOUBLE);
00622 
00623     status = giraffe_bias_remove(rstandard, sstandard, mbias, bpixel,
00624                                  biasareas, bias_config);
00625 
00626     giraffe_image_delete(sstandard);
00627 
00628     if (mbias) {
00629         giraffe_image_delete(mbias);
00630         mbias = NULL;
00631     }
00632 
00633     giraffe_bias_config_destroy(bias_config);
00634 
00635     if (status) {
00636         cpl_msg_error(_id, "Bias removal failed. Aborting ...");
00637 
00638         giraffe_image_delete(rstandard);
00639         rstandard = NULL;
00640 
00641         if (bpixel != NULL) {
00642             giraffe_image_delete(bpixel);
00643             bpixel = NULL;
00644         }
00645 
00646         return 1;
00647     }
00648 
00649 
00650     /*
00651      * Load master dark if it is present in the frame set and correct
00652      * the master flat field for the dark current.
00653      */
00654 
00655     if (mdark_frame) {
00656 
00657         GiDarkConfig dark_config = {GIDARK_METHOD_ZMASTER, 0.};
00658 
00659 
00660         cpl_msg_info(_id, "Correcting for dark current ...");
00661 
00662         filename = cpl_frame_get_filename(mdark_frame);
00663 
00664         mdark = giraffe_image_new(CPL_TYPE_DOUBLE);
00665         status = giraffe_image_load(mdark, filename, 0);
00666 
00667         if (status != 0) {
00668             cpl_msg_error(_id, "Cannot load master dark from '%s'. "
00669                           "Aborting ...", filename);
00670 
00671             giraffe_image_delete(rstandard);
00672             rstandard = NULL;
00673 
00674             if (bpixel != NULL) {
00675                 giraffe_image_delete(bpixel);
00676                 bpixel = NULL;
00677             }
00678 
00679             return 1;
00680         }
00681 
00682         status = giraffe_subtract_dark(rstandard, mdark, bpixel, NULL,
00683                                        &dark_config);
00684 
00685         if (status != 0) {
00686             cpl_msg_error(_id, "Dark subtraction failed! Aborting ...");
00687 
00688             giraffe_image_delete(mdark);
00689             mdark = NULL;
00690 
00691             giraffe_image_delete(rstandard);
00692             rstandard = NULL;
00693 
00694             if (bpixel != NULL) {
00695                 giraffe_image_delete(bpixel);
00696                 bpixel = NULL;
00697             }
00698 
00699             return 1;
00700         }
00701 
00702         giraffe_image_delete(mdark);
00703         mdark = NULL;
00704 
00705     }
00706 
00707 
00708     /*
00709      * Update the reduced standard star observation properties, save the
00710      * reduced standard star frame and register it as product.
00711      */
00712 
00713     cpl_msg_info(_id, "Writing pre-processed standard star image ...");
00714 
00715     giraffe_image_add_info(rstandard, &info, set);
00716 
00717     rstandard_frame = giraffe_frame_create_image(rstandard,
00718                                              GIFRAME_STANDARD_REDUCED,
00719                                              CPL_FRAME_LEVEL_INTERMEDIATE,
00720                                              TRUE, TRUE);
00721 
00722     if (rstandard_frame == NULL) {
00723         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
00724 
00725         giraffe_image_delete(rstandard);
00726 
00727         return 1;
00728     }
00729 
00730     cpl_frameset_insert(set, rstandard_frame);
00731 
00732 
00733     /*
00734      * Determine fiber setup
00735      */
00736 
00737     standard_frame = cpl_frameset_find(set, GIFRAME_STANDARD);
00738 
00739     cpl_msg_info(_id, "Building fiber setup for frame '%s'.",
00740                  cpl_frame_get_filename(standard_frame));
00741 
00742     fibers = giraffe_fibers_setup(standard_frame, locy_frame);
00743 
00744     if (!fibers) {
00745         cpl_msg_error(_id, "Cannot create fiber setup for frame '%s'! "
00746                       "Aborting ...", cpl_frame_get_filename(standard_frame));
00747 
00748         if (bpixel) {
00749             giraffe_image_delete(bpixel);
00750             bpixel = NULL;
00751         }
00752 
00753         giraffe_image_delete(rstandard);
00754 
00755         return 1;
00756     }
00757 
00758     cpl_msg_info(_id, "Fiber reference setup taken from localization "
00759                  "frame '%s'.", cpl_frame_get_filename(locy_frame));
00760 
00761 
00762     /*
00763      * Load fiber localization
00764      */
00765 
00766     localization = giraffe_localization_new();
00767 
00768     filename = cpl_frame_get_filename(locy_frame);
00769     status = 0;
00770 
00771     localization->locy  = giraffe_image_new(CPL_TYPE_DOUBLE);
00772     status = giraffe_image_load(localization->locy, filename, 0);
00773 
00774     if (status) {
00775         cpl_msg_error(_id, "Cannot load localization (centroid "
00776                       "position) frame from '%s'. Aborting ...",
00777                       filename);
00778 
00779         giraffe_localization_destroy(localization);
00780 
00781         if (bpixel) {
00782             giraffe_image_delete(bpixel);
00783             bpixel = NULL;
00784         }
00785 
00786         giraffe_table_delete(fibers);
00787         giraffe_image_delete(rstandard);
00788 
00789         return 1;
00790     }
00791 
00792 
00793     filename = cpl_frame_get_filename(locw_frame);
00794     status = 0;
00795 
00796     localization->locw  = giraffe_image_new(CPL_TYPE_DOUBLE);
00797     status = giraffe_image_load(localization->locw, filename, 0);
00798 
00799     if (status) {
00800         cpl_msg_error(_id, "Cannot load localization (spectrum width) "
00801                       "frame from '%s'. Aborting ...", filename);
00802 
00803         giraffe_localization_destroy(localization);
00804 
00805         if (bpixel) {
00806             giraffe_image_delete(bpixel);
00807             bpixel = NULL;
00808         }
00809 
00810         giraffe_table_delete(fibers);
00811         giraffe_image_delete(rstandard);
00812 
00813         return 1;
00814     }
00815 
00816 
00817     /*
00818      * Spectrum extraction
00819      */
00820 
00821     if (slight_frame) {
00822 
00823         filename = cpl_frame_get_filename(slight_frame);
00824 
00825 
00826         slight = giraffe_image_new(CPL_TYPE_DOUBLE);
00827         status = giraffe_image_load(slight, filename, 0);
00828 
00829         if (status) {
00830             cpl_msg_error(_id, "Cannot load scattered light model from '%s'. "
00831                           "Aborting ...", filename);
00832 
00833             giraffe_image_delete(slight);
00834 
00835             giraffe_localization_destroy(localization);
00836 
00837             if (bpixel) {
00838                 giraffe_image_delete(bpixel);
00839                 bpixel = NULL;
00840             }
00841 
00842             giraffe_table_delete(fibers);
00843             giraffe_image_delete(rstandard);
00844 
00845             return 1;
00846 
00847         }
00848 
00849     }
00850 
00851 
00852     extract_config = giraffe_extract_config_create(config);
00853 
00854     if ((extract_config->emethod == GIEXTRACT_OPTIMAL) ||
00855         (extract_config->emethod == GIEXTRACT_HORNE)) {
00856 
00857         if (psfdata_frame == NULL) {
00858 
00859             const cxchar* emethod = "Optimal";
00860 
00861             if (extract_config->emethod == GIEXTRACT_HORNE) {
00862                 emethod = "Horne";
00863             }
00864 
00865             cpl_msg_error(_id, "%s spectrum extraction requires PSF "
00866                           "profile data. Aborting ...", emethod);
00867 
00868             giraffe_extract_config_destroy(extract_config);
00869             extract_config = NULL;
00870 
00871             if (slight != NULL) {
00872                 giraffe_image_delete(slight);
00873                 slight = NULL;
00874             }
00875 
00876             giraffe_localization_destroy(localization);
00877             localization = NULL;
00878 
00879             if (bpixel) {
00880                 giraffe_image_delete(bpixel);
00881                 bpixel = NULL;
00882             }
00883 
00884             giraffe_table_delete(fibers);
00885             fibers = NULL;
00886 
00887             giraffe_image_delete(rstandard);
00888             rstandard = NULL;
00889 
00890             return 1;
00891 
00892         }
00893         else {
00894 
00895             filename = cpl_frame_get_filename(psfdata_frame);
00896             status = 0;
00897 
00898             localization->psf  = giraffe_psfdata_new();
00899             status = giraffe_psfdata_load(localization->psf, filename);
00900 
00901             if (status) {
00902                 cpl_msg_error(_id, "Cannot load PSF profile data frame from "
00903                               "'%s'. Aborting ...", filename);
00904 
00905                 giraffe_extract_config_destroy(extract_config);
00906                 extract_config = NULL;
00907 
00908                 if (slight != NULL) {
00909                     giraffe_image_delete(slight);
00910                     slight = NULL;
00911                 }
00912 
00913                 giraffe_localization_destroy(localization);
00914                 localization = NULL;
00915 
00916                 if (bpixel) {
00917                     giraffe_image_delete(bpixel);
00918                     bpixel = NULL;
00919                 }
00920 
00921                 giraffe_table_delete(fibers);
00922                 fibers = NULL;
00923 
00924                 giraffe_image_delete(rstandard);
00925                 rstandard = NULL;
00926 
00927                 return 1;
00928 
00929             }
00930 
00931         }
00932 
00933     }
00934 
00935 
00936     extraction = giraffe_extraction_new();
00937 
00938     status = giraffe_extract_spectra(extraction, rstandard, fibers,
00939                                      localization, bpixel, slight,
00940                                      extract_config);
00941 
00942     if (status) {
00943         cpl_msg_error(_id, "Spectrum extraction failed! Aborting ...");
00944 
00945         giraffe_extraction_destroy(extraction);
00946         giraffe_extract_config_destroy(extract_config);
00947 
00948         giraffe_image_delete(slight);
00949 
00950         giraffe_localization_destroy(localization);
00951 
00952         if (bpixel) {
00953             giraffe_image_delete(bpixel);
00954             bpixel = NULL;
00955         }
00956 
00957         giraffe_table_delete(fibers);
00958         giraffe_image_delete(rstandard);
00959 
00960         return 1;
00961     }
00962 
00963     giraffe_image_delete(slight);
00964     slight = NULL;
00965 
00966     if (bpixel) {
00967         giraffe_image_delete(bpixel);
00968         bpixel = NULL;
00969     }
00970 
00971     giraffe_image_delete(rstandard);
00972     rstandard = NULL;
00973 
00974     giraffe_extract_config_destroy(extract_config);
00975 
00976 
00977     /*
00978      * Get the relative fiber transmission data from the extracted flat
00979      * field and add it to the fiber table.
00980      */
00981 
00982     filename = cpl_frame_get_filename(flat_frame);
00983 
00984     cpl_msg_info(_id, "Loading relative fiber transmission data from '%s'.",
00985                  filename);
00986 
00987     status = giraffe_transmission_attach(fibers, filename);
00988 
00989     if (status != 0) {
00990 
00991         giraffe_extraction_destroy(extraction);
00992         giraffe_localization_destroy(localization);
00993 
00994         giraffe_table_delete(grating);
00995         giraffe_table_delete(fibers);
00996 
00997         cpl_msg_error(_id, "Cannot load relative fiber transmission data "
00998                       "from '%s'. Aborting ...", filename);
00999 
01000         return 1;
01001 
01002     }
01003 
01004 
01005     /*
01006      * Apply flat field and/or the relative fiber transmission correction.
01007      */
01008 
01009     flat_config = giraffe_flat_config_create(config);
01010 
01011     if (flat_config->apply == TRUE) {
01012 
01013         const cpl_frame* flat_errors_frame = NULL;
01014 
01015         GiImage* flat = NULL;
01016         GiImage* errors = NULL;
01017 
01018 
01019         filename = cpl_frame_get_filename(flat_frame);
01020 
01021         flat = giraffe_image_new(CPL_TYPE_DOUBLE);
01022         status = giraffe_image_load(flat, filename, 0);
01023 
01024         if (status) {
01025             cpl_msg_error(_id, "Cannot load flat field spectra from '%s'. "
01026                           "Aborting ...", filename);
01027 
01028             giraffe_image_delete(flat);
01029 
01030             giraffe_flat_config_destroy(flat_config);
01031 
01032             giraffe_extraction_destroy(extraction);
01033             giraffe_localization_destroy(localization);
01034 
01035             giraffe_table_delete(grating);
01036             giraffe_table_delete(fibers);
01037 
01038             return 1;
01039         }
01040 
01041 
01042         flat_errors_frame =
01043             cpl_frameset_find(set, GIFRAME_FIBER_FLAT_EXTERRORS);
01044 
01045         if (flat_errors_frame == NULL) {
01046             cpl_msg_warning(_id, "Missing flat field spectra errors "
01047                             "frame!");
01048         }
01049         else {
01050 
01051             filename = cpl_frame_get_filename(flat_errors_frame);
01052 
01053             errors = giraffe_image_new(CPL_TYPE_DOUBLE);
01054             status = giraffe_image_load(errors, filename, 0);
01055 
01056             if (status) {
01057                 cpl_msg_error(_id, "Cannot load flat field spectra "
01058                               "errors from '%s'. Aborting ...",
01059                               filename);
01060 
01061                 giraffe_image_delete(errors);
01062                 giraffe_image_delete(flat);
01063 
01064                 giraffe_flat_config_destroy(flat_config);
01065 
01066                 giraffe_extraction_destroy(extraction);
01067                 giraffe_localization_destroy(localization);
01068 
01069                 giraffe_table_delete(grating);
01070                 giraffe_table_delete(fibers);
01071 
01072                 return 1;
01073             }
01074 
01075         }
01076 
01077         cpl_msg_info(_id, "Applying flat field correction ...");
01078 
01079         status = giraffe_flat_apply(extraction, fibers, flat, errors,
01080                                     flat_config);
01081 
01082         if (status) {
01083             cpl_msg_error(_id, "Flat field correction failed! "
01084                           "Aborting ...");
01085 
01086             giraffe_image_delete(errors);
01087             giraffe_image_delete(flat);
01088 
01089             giraffe_flat_config_destroy(flat_config);
01090 
01091             giraffe_extraction_destroy(extraction);
01092             giraffe_localization_destroy(localization);
01093 
01094             giraffe_table_delete(grating);
01095             giraffe_table_delete(fibers);
01096 
01097             return 1;
01098         }
01099 
01100         giraffe_image_delete(errors);
01101         errors = NULL;
01102 
01103         giraffe_image_delete(flat);
01104         flat = NULL;
01105 
01106     }
01107 
01108     if (flat_config->transmission == TRUE) {
01109 
01110         cpl_msg_info(_id, "Applying relative fiber transmission "
01111                      "correction");
01112 
01113         status = giraffe_transmission_apply(extraction, fibers);
01114 
01115         if (status) {
01116 
01117             cpl_msg_error(_id, "Relative transmission correction failed! "
01118                           "Aborting ...");
01119 
01120             giraffe_flat_config_destroy(flat_config);
01121             flat_config = NULL;
01122 
01123             giraffe_extraction_destroy(extraction);
01124             giraffe_localization_destroy(localization);
01125 
01126             giraffe_table_delete(grating);
01127             giraffe_table_delete(fibers);
01128 
01129             return 1;
01130 
01131         }
01132 
01133     }
01134 
01135     giraffe_flat_config_destroy(flat_config);
01136     flat_config = NULL;
01137 
01138 
01139     /*
01140      * Save the spectrum extraction results and register them as
01141      * products.
01142      */
01143 
01144     cpl_msg_info(_id, "Writing extracted spectra ...");
01145 
01146     /* Extracted spectra */
01147 
01148     giraffe_image_add_info(extraction->spectra, &info, set);
01149 
01150     sext_frame = giraffe_frame_create_image(extraction->spectra,
01151                                             GIFRAME_STANDARD_EXTSPECTRA,
01152                                             CPL_FRAME_LEVEL_FINAL,
01153                                             TRUE, TRUE);
01154 
01155     if (sext_frame == NULL) {
01156         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01157 
01158         giraffe_extraction_destroy(extraction);
01159         giraffe_localization_destroy(localization);
01160 
01161         giraffe_table_delete(grating);
01162         giraffe_table_delete(fibers);
01163 
01164         return 1;
01165     }
01166 
01167     status = giraffe_fiberlist_attach(sext_frame, fibers);
01168 
01169     if (status) {
01170         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01171                       "Aborting ...", cpl_frame_get_filename(sext_frame));
01172 
01173         cpl_frame_delete(sext_frame);
01174 
01175         giraffe_extraction_destroy(extraction);
01176         giraffe_localization_destroy(localization);
01177 
01178         giraffe_table_delete(grating);
01179         giraffe_table_delete(fibers);
01180 
01181         return 1;
01182     }
01183 
01184     cpl_frameset_insert(set, sext_frame);
01185 
01186     /* Extracted spectra errors */
01187 
01188     giraffe_image_add_info(extraction->error, &info, set);
01189 
01190     sext_frame = giraffe_frame_create_image(extraction->error,
01191                                             GIFRAME_STANDARD_EXTERRORS,
01192                                             CPL_FRAME_LEVEL_FINAL,
01193                                             TRUE, TRUE);
01194 
01195     if (sext_frame == NULL) {
01196         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01197 
01198         giraffe_extraction_destroy(extraction);
01199         giraffe_localization_destroy(localization);
01200 
01201         giraffe_table_delete(grating);
01202         giraffe_table_delete(fibers);
01203 
01204         return 1;
01205     }
01206 
01207     status = giraffe_fiberlist_attach(sext_frame, fibers);
01208 
01209     if (status) {
01210         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01211                       "Aborting ...", cpl_frame_get_filename(sext_frame));
01212 
01213         cpl_frame_delete(sext_frame);
01214 
01215         giraffe_extraction_destroy(extraction);
01216         giraffe_localization_destroy(localization);
01217 
01218         giraffe_table_delete(grating);
01219         giraffe_table_delete(fibers);
01220 
01221         return 1;
01222     }
01223 
01224     cpl_frameset_insert(set, sext_frame);
01225 
01226     /* Extracted spectra pixels */
01227 
01228     if (extraction->npixels != NULL) {
01229 
01230         giraffe_image_add_info(extraction->npixels, &info, set);
01231 
01232         sext_frame = giraffe_frame_create_image(extraction->npixels,
01233                                                 GIFRAME_STANDARD_EXTPIXELS,
01234                                                 CPL_FRAME_LEVEL_FINAL,
01235                                                 TRUE, TRUE);
01236 
01237         if (sext_frame == NULL) {
01238             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01239 
01240             giraffe_extraction_destroy(extraction);
01241             giraffe_localization_destroy(localization);
01242 
01243             giraffe_table_delete(grating);
01244             giraffe_table_delete(fibers);
01245 
01246             return 1;
01247         }
01248 
01249         status = giraffe_fiberlist_attach(sext_frame, fibers);
01250 
01251         if (status) {
01252             cpl_msg_error(_id, "Cannot attach fiber setup to local file "
01253                           "'%s'! Aborting ...",
01254                           cpl_frame_get_filename(sext_frame));
01255 
01256             cpl_frame_delete(sext_frame);
01257 
01258             giraffe_extraction_destroy(extraction);
01259             giraffe_localization_destroy(localization);
01260 
01261             giraffe_table_delete(grating);
01262             giraffe_table_delete(fibers);
01263 
01264             return 1;
01265         }
01266 
01267         cpl_frameset_insert(set, sext_frame);
01268 
01269     }
01270 
01271     /* Extracted spectra centroids */
01272 
01273     giraffe_image_add_info(extraction->centroid, &info, set);
01274 
01275     sext_frame = giraffe_frame_create_image(extraction->centroid,
01276                                             GIFRAME_STANDARD_EXTTRACE,
01277                                             CPL_FRAME_LEVEL_FINAL,
01278                                             TRUE, TRUE);
01279 
01280     if (sext_frame == NULL) {
01281         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01282 
01283         giraffe_extraction_destroy(extraction);
01284         giraffe_localization_destroy(localization);
01285 
01286         giraffe_table_delete(grating);
01287         giraffe_table_delete(fibers);
01288 
01289         return 1;
01290     }
01291 
01292     status = giraffe_fiberlist_attach(sext_frame, fibers);
01293 
01294     if (status) {
01295         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01296                       "Aborting ...", cpl_frame_get_filename(sext_frame));
01297 
01298         cpl_frame_delete(sext_frame);
01299 
01300         giraffe_extraction_destroy(extraction);
01301         giraffe_localization_destroy(localization);
01302 
01303         giraffe_table_delete(grating);
01304         giraffe_table_delete(fibers);
01305 
01306         return 1;
01307     }
01308 
01309     cpl_frameset_insert(set, sext_frame);
01310 
01311     /* Extraction model spectra */
01312 
01313     if (extraction->model != NULL) {
01314 
01315         giraffe_image_add_info(extraction->model, &info, set);
01316 
01317         sext_frame = giraffe_frame_create_image(extraction->model,
01318                                                 GIFRAME_STANDARD_EXTMODEL,
01319                                                 CPL_FRAME_LEVEL_FINAL,
01320                                                 TRUE, TRUE);
01321 
01322         if (sext_frame == NULL) {
01323             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01324 
01325             giraffe_extraction_destroy(extraction);
01326             giraffe_localization_destroy(localization);
01327 
01328             giraffe_table_delete(grating);
01329             giraffe_table_delete(fibers);
01330 
01331             return 1;
01332         }
01333 
01334         status = giraffe_fiberlist_attach(sext_frame, fibers);
01335 
01336         if (status != 0) {
01337             cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01338                           "Aborting ...", cpl_frame_get_filename(sext_frame));
01339 
01340             cpl_frame_delete(sext_frame);
01341 
01342             giraffe_extraction_destroy(extraction);
01343             giraffe_localization_destroy(localization);
01344 
01345             giraffe_table_delete(grating);
01346             giraffe_table_delete(fibers);
01347 
01348             return 1;
01349         }
01350 
01351         cpl_frameset_insert(set, sext_frame);
01352 
01353     }
01354 
01355 
01356     /*
01357      * Load dispersion solution
01358      */
01359 
01360 
01361     filename = (cxchar *)cpl_frame_get_filename(wcal_frame);
01362 
01363     wcalcoeff = giraffe_table_new();
01364     status = giraffe_table_load(wcalcoeff, filename, 1, NULL);
01365 
01366     if (status) {
01367         cpl_msg_error(_id, "Cannot load dispersion solution from "
01368                       "'%s'. Aborting ...", filename);
01369 
01370         giraffe_extraction_destroy(extraction);
01371         giraffe_localization_destroy(localization);
01372 
01373         giraffe_table_delete(wcalcoeff);
01374 
01375         giraffe_table_delete(grating);
01376         giraffe_table_delete(fibers);
01377 
01378         return 1;
01379     }
01380 
01381 
01382     /*
01383      * Load grating data
01384      */
01385 
01386     filename = (cxchar *)cpl_frame_get_filename(grating_frame);
01387 
01388     status = 0;
01389 
01390     grating = giraffe_table_new();
01391     status = giraffe_table_load(grating, filename, 1, NULL);
01392 
01393     if (status) {
01394         cpl_msg_error(_id, "Cannot load grating data from '%s'. "
01395                       "Aborting ...", filename);
01396 
01397         giraffe_extraction_destroy(extraction);
01398         giraffe_localization_destroy(localization);
01399 
01400         giraffe_table_delete(wcalcoeff);
01401 
01402         giraffe_table_delete(grating);
01403         giraffe_table_delete(fibers);
01404 
01405         return 1;
01406     }
01407 
01408 
01409     /*
01410      * Load slit geometry data
01411      */
01412 
01413 
01414     filename = (cxchar *)cpl_frame_get_filename(slit_frame);
01415 
01416     slitgeometry = giraffe_slitgeometry_load(fibers, filename, 1, NULL);
01417 
01418     if (slitgeometry == NULL) {
01419         cpl_msg_error(_id, "Cannot load slit geometry data from '%s'. "
01420                       "Aborting ...", filename);
01421 
01422         giraffe_table_delete(wcalcoeff);
01423 
01424         giraffe_extraction_destroy(extraction);
01425         giraffe_localization_destroy(localization);
01426 
01427         giraffe_table_delete(wcalcoeff);
01428 
01429         giraffe_table_delete(grating);
01430         giraffe_table_delete(fibers);
01431 
01432         return 1;
01433     }
01434     else {
01435 
01436         /*
01437          * Check whether the contains the positions for all fibers
01438          * provided by the fiber setup. If this is not the case
01439          * this is an error.
01440          */
01441 
01442         if (giraffe_fiberlist_compare(slitgeometry, fibers) != 1) {
01443             cpl_msg_error(_id, "Slit geometry data from '%s' is not "
01444                     "applicable for current fiber setup! "
01445                             "Aborting ...", filename);
01446 
01447             giraffe_table_delete(slitgeometry);
01448             giraffe_table_delete(wcalcoeff);
01449 
01450             giraffe_extraction_destroy(extraction);
01451             giraffe_localization_destroy(localization);
01452 
01453             giraffe_table_delete(wcalcoeff);
01454 
01455             giraffe_table_delete(grating);
01456             giraffe_table_delete(fibers);
01457 
01458             return 1;
01459         }
01460 
01461     }
01462 
01463 
01464     /*
01465      * Spectrum rebinning
01466      */
01467 
01468     cpl_msg_info(_id, "Spectrum rebinning");
01469 
01470     rebin_config = giraffe_rebin_config_create(config);
01471 
01472     rebinning = giraffe_rebinning_new();
01473 
01474     status = 0;
01475 
01476     status = giraffe_rebin_spectra(rebinning, extraction, fibers,
01477                                    localization, grating, slitgeometry,
01478                                    wcalcoeff, rebin_config);
01479 
01480     if (status) {
01481         cpl_msg_error(_id, "Rebinning of standard spectra failed! "
01482                       "Aborting...");
01483 
01484         giraffe_rebinning_destroy(rebinning);
01485 
01486         giraffe_extraction_destroy(extraction);
01487         giraffe_localization_destroy(localization);
01488 
01489         giraffe_table_delete(wcalcoeff);
01490 
01491         giraffe_table_delete(slitgeometry);
01492         giraffe_table_delete(grating);
01493         giraffe_table_delete(fibers);
01494 
01495         giraffe_rebin_config_destroy(rebin_config);
01496 
01497         return 1;
01498 
01499     }
01500 
01501     giraffe_extraction_destroy(extraction);
01502     extraction = NULL;
01503 
01504     giraffe_localization_destroy(localization);
01505     localization = NULL;
01506 
01507     giraffe_rebin_config_destroy(rebin_config);
01508     rebin_config = NULL;
01509 
01510 
01511     /*
01512      * Save and register the results of the spectrum rebinning.
01513      */
01514 
01515     /* Rebinned spectra */
01516 
01517     giraffe_image_add_info(rebinning->spectra, &info, set);
01518 
01519     rbin_frame = giraffe_frame_create_image(rebinning->spectra,
01520                                             GIFRAME_STANDARD_RBNSPECTRA,
01521                                             CPL_FRAME_LEVEL_FINAL,
01522                                             TRUE, TRUE);
01523 
01524     if (rbin_frame == NULL) {
01525         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01526 
01527         giraffe_rebinning_destroy(rebinning);
01528 
01529         giraffe_table_delete(wcalcoeff);
01530 
01531         giraffe_table_delete(slitgeometry);
01532         giraffe_table_delete(grating);
01533         giraffe_table_delete(fibers);
01534 
01535         return 1;
01536     }
01537 
01538     status = giraffe_fiberlist_attach(rbin_frame, fibers);
01539 
01540     if (status) {
01541         cpl_msg_error(_id, "Cannot attach fiber setup to local "
01542                       "file '%s'! Aborting ...",
01543                       cpl_frame_get_filename(rbin_frame));
01544 
01545         giraffe_rebinning_destroy(rebinning);
01546         giraffe_table_delete(wcalcoeff);
01547 
01548         giraffe_table_delete(slitgeometry);
01549         giraffe_table_delete(grating);
01550         giraffe_table_delete(fibers);
01551 
01552         cpl_frame_delete(rbin_frame);
01553 
01554         return 1;
01555     }
01556 
01557     cpl_frameset_insert(set, rbin_frame);
01558 
01559     /* Rebinned spectra errors */
01560 
01561     giraffe_image_add_info(rebinning->errors, &info, set);
01562 
01563     rbin_frame = giraffe_frame_create_image(rebinning->errors,
01564                                             GIFRAME_STANDARD_RBNERRORS,
01565                                             CPL_FRAME_LEVEL_FINAL,
01566                                             TRUE, TRUE);
01567 
01568     if (rbin_frame == NULL) {
01569         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01570 
01571         giraffe_rebinning_destroy(rebinning);
01572 
01573         giraffe_table_delete(wcalcoeff);
01574 
01575         giraffe_table_delete(slitgeometry);
01576         giraffe_table_delete(grating);
01577         giraffe_table_delete(fibers);
01578 
01579         return 1;
01580     }
01581 
01582     status = giraffe_fiberlist_attach(rbin_frame, fibers);
01583 
01584     if (status) {
01585         cpl_msg_error(_id, "Cannot attach fiber setup to local "
01586                       "file '%s'! Aborting ...",
01587                       cpl_frame_get_filename(rbin_frame));
01588 
01589         giraffe_rebinning_destroy(rebinning);
01590 
01591         giraffe_table_delete(wcalcoeff);
01592 
01593         giraffe_table_delete(slitgeometry);
01594         giraffe_table_delete(grating);
01595         giraffe_table_delete(fibers);
01596 
01597         cpl_frame_delete(rbin_frame);
01598 
01599         return 1;
01600     }
01601 
01602     cpl_frameset_insert(set, rbin_frame);
01603 
01604 
01605     /*
01606      * Optional image and data cube construction (only for IFU and Argus)
01607      */
01608 
01609     properties = giraffe_image_get_properties(rebinning->spectra);
01610     mode = giraffe_get_mode(properties);
01611 
01612 
01613     if (mode == GIMODE_IFU || mode == GIMODE_ARGUS) {
01614 
01615         cpl_frame* rimg_frame = NULL;
01616 
01617         GiFieldOfView* fov = NULL;
01618 
01619         GiFieldOfViewConfig* fov_config = NULL;
01620 
01621         GiFieldOfViewCubeFormat cube_format = GIFOV_FORMAT_ESO3D;
01622 
01623 
01624         fov_config = giraffe_fov_config_create(config);
01625 
01626         cube_format = fov_config->format;
01627 
01628 
01629         cpl_msg_info(_id, "Reconstructing image and data cube from rebinned "
01630                      "spectra ...");
01631 
01632         fov = giraffe_fov_new();
01633 
01634         status = giraffe_fov_build(fov, rebinning, fibers, wcalcoeff, grating,
01635                                    slitgeometry, fov_config);
01636 
01637         if (status) {
01638 
01639             if (status == -2) {
01640                 cpl_msg_warning(_id, "No reconstructed image was built. "
01641                                 "Fiber list has no fiber position "
01642                                 "information.");
01643             }
01644             else {
01645                 cpl_msg_error(_id, "Image reconstruction failed! Aborting...");
01646 
01647                 giraffe_fov_delete(fov);
01648                 giraffe_rebinning_destroy(rebinning);
01649 
01650                 giraffe_table_delete(wcalcoeff);
01651 
01652                 giraffe_table_delete(slitgeometry);
01653                 giraffe_table_delete(grating);
01654                 giraffe_table_delete(fibers);
01655 
01656                 giraffe_fov_config_destroy(fov_config);
01657 
01658                 return 1;
01659             }
01660 
01661         }
01662 
01663         giraffe_fov_config_destroy(fov_config);
01664 
01665 
01666         /*
01667          * Save and register the results of the image reconstruction.
01668          */
01669 
01670         /* Reconstructed image */
01671 
01672         giraffe_image_add_info(fov->fov.spectra, &info, set);
01673 
01674         rimg_frame = giraffe_frame_create_image(fov->fov.spectra,
01675                                                 GIFRAME_STANDARD_RCSPECTRA,
01676                                                 CPL_FRAME_LEVEL_FINAL,
01677                                                 TRUE, TRUE);
01678 
01679         if (rimg_frame == NULL) {
01680             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01681 
01682             giraffe_fov_delete(fov);
01683             giraffe_rebinning_destroy(rebinning);
01684 
01685             giraffe_table_delete(wcalcoeff);
01686 
01687             giraffe_table_delete(slitgeometry);
01688             giraffe_table_delete(grating);
01689             giraffe_table_delete(fibers);
01690 
01691             return 1;
01692         }
01693 
01694         cpl_frameset_insert(set, rimg_frame);
01695 
01696 
01697         /* Reconstructed image errors */
01698 
01699         giraffe_image_add_info(fov->fov.errors, &info, set);
01700 
01701         rimg_frame = giraffe_frame_create_image(fov->fov.errors,
01702                                                 GIFRAME_STANDARD_RCERRORS,
01703                                                 CPL_FRAME_LEVEL_FINAL,
01704                                                 TRUE, TRUE);
01705 
01706         if (rimg_frame == NULL) {
01707             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01708 
01709             giraffe_fov_delete(fov);
01710             giraffe_rebinning_destroy(rebinning);
01711 
01712             giraffe_table_delete(wcalcoeff);
01713 
01714             giraffe_table_delete(slitgeometry);
01715             giraffe_table_delete(grating);
01716             giraffe_table_delete(fibers);
01717 
01718             return 1;
01719         }
01720 
01721         cpl_frameset_insert(set, rimg_frame);
01722 
01723 
01724         /* Save data cubes according to format selection */
01725 
01726         if (cube_format == GIFOV_FORMAT_SINGLE) {
01727 
01728             /* Spectrum cube */
01729 
01730             if (fov->cubes.spectra != NULL) {
01731 
01732                 cxint component = 0;
01733 
01734                 GiFrameCreator creator = (GiFrameCreator) giraffe_fov_save_cubes;
01735 
01736 
01737                 properties = giraffe_image_get_properties(rebinning->spectra);
01738                 properties = cpl_propertylist_duplicate(properties);
01739 
01740                 giraffe_add_frameset_info(properties, set, info.sequence);
01741 
01742                 rimg_frame = giraffe_frame_create(GIFRAME_STANDARD_CUBE_SPECTRA,
01743                                                   CPL_FRAME_LEVEL_FINAL,
01744                                                   properties,
01745                                                   fov,
01746                                                   &component,
01747                                                   creator);
01748 
01749                 cpl_propertylist_delete(properties);
01750                 properties = NULL;
01751 
01752                 if (rimg_frame == NULL) {
01753                     cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01754 
01755                     giraffe_fov_delete(fov);
01756                     fov = NULL;
01757 
01758                     giraffe_rebinning_destroy(rebinning);
01759                     rebinning = NULL;
01760 
01761                     giraffe_table_delete(wcalcoeff);
01762                     wcalcoeff = NULL;
01763 
01764                     giraffe_table_delete(slitgeometry);
01765                     slitgeometry = NULL;
01766 
01767                     giraffe_table_delete(grating);
01768                     grating = NULL;
01769 
01770                     giraffe_table_delete(fibers);
01771                     fibers = NULL;
01772 
01773                     return 1;
01774                 }
01775 
01776                 status = giraffe_fiberlist_attach(rimg_frame, fibers);
01777 
01778                 if (status != 0) {
01779                     cpl_msg_error(_id, "Cannot attach fiber setup to local "
01780                                   "file '%s'! Aborting ...",
01781                                   cpl_frame_get_filename(rimg_frame));
01782 
01783                     cpl_frame_delete(rimg_frame);
01784 
01785                     giraffe_fov_delete(fov);
01786                     fov = NULL;
01787 
01788                     giraffe_rebinning_destroy(rebinning);
01789                     rebinning = NULL;
01790 
01791                     giraffe_table_delete(wcalcoeff);
01792                     wcalcoeff = NULL;
01793 
01794                     giraffe_table_delete(slitgeometry);
01795                     slitgeometry = NULL;
01796 
01797                     giraffe_table_delete(grating);
01798                     grating = NULL;
01799 
01800                     giraffe_table_delete(fibers);
01801                     fibers = NULL;
01802 
01803                     return 1;
01804                 }
01805 
01806                 cpl_frameset_insert(set, rimg_frame);
01807 
01808             }
01809 
01810             /* Error cube */
01811 
01812             if (fov->cubes.errors != NULL) {
01813 
01814                 cxint component = 1;
01815 
01816                 GiFrameCreator creator = (GiFrameCreator) giraffe_fov_save_cubes;
01817 
01818 
01819                 properties = giraffe_image_get_properties(rebinning->errors);
01820                 properties = cpl_propertylist_duplicate(properties);
01821 
01822                 giraffe_add_frameset_info(properties, set, info.sequence);
01823 
01824                 rimg_frame = giraffe_frame_create(GIFRAME_STANDARD_CUBE_ERRORS,
01825                                                   CPL_FRAME_LEVEL_FINAL,
01826                                                   properties,
01827                                                   fov,
01828                                                   &component,
01829                                                   creator);
01830 
01831                 cpl_propertylist_delete(properties);
01832                 properties = NULL;
01833 
01834                 if (rimg_frame == NULL) {
01835                     cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01836 
01837                     giraffe_fov_delete(fov);
01838                     fov = NULL;
01839 
01840                     giraffe_rebinning_destroy(rebinning);
01841                     rebinning = NULL;
01842 
01843                     giraffe_table_delete(wcalcoeff);
01844                     wcalcoeff = NULL;
01845 
01846                     giraffe_table_delete(slitgeometry);
01847                     slitgeometry = NULL;
01848 
01849                     giraffe_table_delete(grating);
01850                     grating = NULL;
01851 
01852                     giraffe_table_delete(fibers);
01853                     fibers = NULL;
01854 
01855                     return 1;
01856                 }
01857 
01858                 status = giraffe_fiberlist_attach(rimg_frame, fibers);
01859 
01860                 if (status != 0) {
01861                     cpl_msg_error(_id, "Cannot attach fiber setup to local "
01862                                   "file '%s'! Aborting ...",
01863                                   cpl_frame_get_filename(rimg_frame));
01864 
01865                     cpl_frame_delete(rimg_frame);
01866 
01867                     giraffe_fov_delete(fov);
01868                     fov = NULL;
01869 
01870                     giraffe_rebinning_destroy(rebinning);
01871                     rebinning = NULL;
01872 
01873                     giraffe_table_delete(wcalcoeff);
01874                     wcalcoeff = NULL;
01875 
01876                     giraffe_table_delete(slitgeometry);
01877                     slitgeometry = NULL;
01878 
01879                     giraffe_table_delete(grating);
01880                     grating = NULL;
01881 
01882                     giraffe_table_delete(fibers);
01883                     fibers = NULL;
01884 
01885                     return 1;
01886                 }
01887 
01888                 cpl_frameset_insert(set, rimg_frame);
01889             }
01890 
01891         }
01892         else {
01893 
01894             /* Data Cube (ESO 3D format) */
01895 
01896             GiFrameCreator creator = (GiFrameCreator) giraffe_fov_save_cubes_eso3d;
01897 
01898             properties = giraffe_image_get_properties(rebinning->spectra);
01899             properties = cpl_propertylist_duplicate(properties);
01900 
01901             giraffe_add_frameset_info(properties, set, info.sequence);
01902 
01903             rimg_frame = giraffe_frame_create(GIFRAME_STANDARD_CUBE,
01904                                               CPL_FRAME_LEVEL_FINAL,
01905                                               properties,
01906                                               fov,
01907                                               NULL,
01908                                               creator);
01909 
01910             cpl_propertylist_delete(properties);
01911             properties = NULL;
01912 
01913             if (rimg_frame == NULL) {
01914                 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01915 
01916                 giraffe_fov_delete(fov);
01917                 fov = NULL;
01918 
01919                 giraffe_rebinning_destroy(rebinning);
01920                 rebinning = NULL;
01921 
01922                 giraffe_table_delete(wcalcoeff);
01923                 wcalcoeff = NULL;
01924 
01925                 giraffe_table_delete(slitgeometry);
01926                 slitgeometry = NULL;
01927 
01928                 giraffe_table_delete(grating);
01929                 grating = NULL;
01930 
01931                 giraffe_table_delete(fibers);
01932                 fibers = NULL;
01933 
01934                 return 1;
01935             }
01936 
01937             status = giraffe_fiberlist_attach(rimg_frame, fibers);
01938 
01939             if (status != 0) {
01940                 cpl_msg_error(_id, "Cannot attach fiber setup to local "
01941                               "file '%s'! Aborting ...",
01942                               cpl_frame_get_filename(rimg_frame));
01943 
01944                 cpl_frame_delete(rimg_frame);
01945 
01946                 giraffe_fov_delete(fov);
01947                 fov = NULL;
01948 
01949                 giraffe_rebinning_destroy(rebinning);
01950                 rebinning = NULL;
01951 
01952                 giraffe_table_delete(wcalcoeff);
01953                 wcalcoeff = NULL;
01954 
01955                 giraffe_table_delete(slitgeometry);
01956                 slitgeometry = NULL;
01957 
01958                 giraffe_table_delete(grating);
01959                 grating = NULL;
01960 
01961                 giraffe_table_delete(fibers);
01962                 fibers = NULL;
01963 
01964                 return 1;
01965             }
01966 
01967             cpl_frameset_insert(set, rimg_frame);
01968 
01969         }
01970 
01971         giraffe_fov_delete(fov);
01972         fov = NULL;
01973 
01974     }
01975 
01976 
01977     /*
01978      * Response computation
01979      */
01980 
01981     cpl_msg_info(_id, "Computing instrument response function...");
01982 
01983     filename = cpl_frame_get_filename(flxstd_frame);
01984 
01985     flxstd = giraffe_table_new();
01986     status = giraffe_table_load(flxstd, filename, 1, NULL);
01987 
01988     if (status != 0) {
01989         cpl_msg_error(_id, "Cannot load flux standards catalog from "
01990                       "'%s'. Aborting ...", filename);
01991 
01992         giraffe_rebinning_destroy(rebinning);
01993         rebinning = NULL;
01994 
01995         giraffe_table_delete(wcalcoeff);
01996         wcalcoeff = NULL;
01997 
01998         giraffe_table_delete(slitgeometry);
01999         slitgeometry = NULL;
02000 
02001         giraffe_table_delete(grating);
02002         grating = NULL;
02003 
02004         giraffe_table_delete(fibers);
02005         fibers = NULL;
02006 
02007         return 1;
02008     }
02009 
02010 
02011    /*
02012     * Search the flux standard catalog for the observed flux standard
02013     * object.
02014     */
02015 
02016     refflx = giraffe_select_flux_standard(flxstd, rebinning->spectra, 1.);
02017 
02018     if (refflx == NULL) {
02019         cpl_msg_error(_id, "No matching flux standard found in the "
02020                 "catalog '%s'! Aborting ...", filename);
02021 
02022         giraffe_table_delete(flxstd);
02023         flxstd = NULL;
02024 
02025         giraffe_rebinning_destroy(rebinning);
02026         rebinning = NULL;
02027 
02028         giraffe_table_delete(wcalcoeff);
02029         wcalcoeff = NULL;
02030 
02031         giraffe_table_delete(slitgeometry);
02032         slitgeometry = NULL;
02033 
02034         giraffe_table_delete(grating);
02035         grating = NULL;
02036 
02037         giraffe_table_delete(fibers);
02038         fibers = NULL;
02039 
02040         return 1;
02041     }
02042 
02043     giraffe_table_delete(flxstd);
02044     flxstd = NULL;
02045 
02046 
02047     filename = cpl_frame_get_filename(atmext_frame);
02048 
02049     atmext = giraffe_table_new();
02050     status = giraffe_table_load(atmext, filename, 1, NULL);
02051 
02052     if (status != 0) {
02053         cpl_msg_error(_id, "Cannot load atmospheric extinction data from "
02054                       "'%s'. Aborting ...", filename);
02055 
02056         giraffe_table_delete(refflx);
02057         refflx = NULL;
02058 
02059         giraffe_rebinning_destroy(rebinning);
02060         rebinning = NULL;
02061 
02062         giraffe_table_delete(wcalcoeff);
02063         wcalcoeff = NULL;
02064 
02065         giraffe_table_delete(slitgeometry);
02066         slitgeometry = NULL;
02067 
02068         giraffe_table_delete(grating);
02069         grating = NULL;
02070 
02071         giraffe_table_delete(fibers);
02072         fibers = NULL;
02073 
02074         return 1;
02075     }
02076 
02077 
02078     fxcal_config = giraffe_fxcalibration_config_create(config);
02079 
02080     response = giraffe_response_new();
02081 
02082     status = giraffe_calibrate_flux(response, rebinning, fibers, NULL,
02083                                     refflx, atmext, fxcal_config);
02084 
02085     if (status != 0) {
02086 
02087         cpl_msg_error(_id, "Instrument resonse computation failed!");
02088 
02089         giraffe_response_delete(response);
02090         response = NULL;
02091 
02092         giraffe_fxcalibration_config_destroy(fxcal_config);
02093         fxcal_config = NULL;
02094 
02095         giraffe_table_delete(atmext);
02096         atmext = NULL;
02097 
02098         giraffe_table_delete(refflx);
02099         refflx = NULL;
02100 
02101         giraffe_rebinning_destroy(rebinning);
02102         rebinning = NULL;
02103 
02104         giraffe_table_delete(wcalcoeff);
02105         wcalcoeff = NULL;
02106 
02107         giraffe_table_delete(slitgeometry);
02108         slitgeometry = NULL;
02109 
02110         giraffe_table_delete(grating);
02111         grating = NULL;
02112 
02113         giraffe_table_delete(fibers);
02114         fibers = NULL;
02115 
02116         return 1;
02117 
02118     }
02119 
02120     giraffe_fxcalibration_config_destroy(fxcal_config);
02121     fxcal_config = NULL;
02122 
02123     giraffe_table_delete(refflx);
02124     refflx = NULL;
02125 
02126     giraffe_table_delete(atmext);
02127     atmext = NULL;
02128 
02129 
02130     /*
02131      * Save and register the instrument response product
02132      */
02133 
02134     giraffe_image_add_info(response->response, &info, set);
02135 
02136     rsp_frame = giraffe_frame_create_image(response->response,
02137                                            GIFRAME_INSTRUMENT_RESPONSE,
02138                                            CPL_FRAME_LEVEL_FINAL,
02139                                            TRUE, TRUE);
02140 
02141     if (rsp_frame == NULL) {
02142 
02143         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
02144 
02145         giraffe_response_delete(response);
02146         response = NULL;
02147 
02148         giraffe_rebinning_destroy(rebinning);
02149         rebinning = NULL;
02150 
02151         giraffe_table_delete(wcalcoeff);
02152         wcalcoeff = NULL;
02153 
02154         giraffe_table_delete(slitgeometry);
02155         slitgeometry = NULL;
02156 
02157         giraffe_table_delete(grating);
02158         grating = NULL;
02159 
02160         giraffe_table_delete(fibers);
02161         fibers = NULL;
02162 
02163         return 1;
02164 
02165     }
02166 
02167     cpl_frameset_insert(set, rsp_frame);
02168 
02169 
02170     /*
02171      * Save and register the efficiency curve product
02172      */
02173 
02174     giraffe_table_add_info(response->efficiency, &info, set);
02175 
02176     rsp_frame = giraffe_frame_create_table(response->efficiency,
02177                                            GIFRAME_EFFICIENCY_CURVE,
02178                                            CPL_FRAME_LEVEL_FINAL,
02179                                            TRUE, TRUE);
02180 
02181     if (rsp_frame == NULL) {
02182 
02183         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
02184 
02185         giraffe_response_delete(response);
02186         response = NULL;
02187 
02188         giraffe_rebinning_destroy(rebinning);
02189         rebinning = NULL;
02190 
02191         giraffe_table_delete(wcalcoeff);
02192         wcalcoeff = NULL;
02193 
02194         giraffe_table_delete(slitgeometry);
02195         slitgeometry = NULL;
02196 
02197         giraffe_table_delete(grating);
02198         grating = NULL;
02199 
02200         giraffe_table_delete(fibers);
02201         fibers = NULL;
02202 
02203         return 1;
02204 
02205     }
02206 
02207     cpl_frameset_insert(set, rsp_frame);
02208 
02209     giraffe_response_delete(response);
02210     response = NULL;
02211 
02212 
02213     /*
02214      * Cleanup
02215      */
02216 
02217     giraffe_table_delete(wcalcoeff);
02218 
02219     giraffe_table_delete(slitgeometry);
02220     giraffe_table_delete(grating);
02221     giraffe_table_delete(fibers);
02222 
02223     giraffe_rebinning_destroy(rebinning);
02224 
02225     return 0;
02226 
02227 }
02228 
02229 
02230 static cxint
02231 giqcstandard(cpl_frameset* set)
02232 {
02233 
02234     const cxchar* const fctid = "giqcstandard";
02235 
02236 
02237     const cxdouble saturation = 60000.;
02238     const cxdouble wlscale = 0.1;
02239 
02240     cxint i = 0;
02241     cxint status = 0;
02242     cxint nbin = 0;
02243     cxint npixel = 0;
02244     cxint nsaturated = 0;
02245 
02246     const cxdouble* pixels = NULL;
02247 
02248     cxdouble wlmin = 0.;
02249     cxdouble wlmax = 0.;
02250     cxdouble efficiency = 0.;
02251 
02252     cpl_propertylist* properties = NULL;
02253     cpl_propertylist* _properties = NULL;
02254     cpl_propertylist* qclog = NULL;
02255 
02256     cpl_frame* rframe = NULL;
02257     cpl_frame* pframe = NULL;
02258 
02259     cpl_image* _rimage = NULL;
02260 
02261     cpl_table* _ptable = NULL;
02262 
02263     GiImage* rimage = NULL;
02264 
02265     GiTable* ptable = NULL;
02266 
02267     GiPaf* qc = NULL;
02268 
02269 
02270     cpl_msg_info(fctid, "Computing QC1 parameters ...");
02271 
02272     qc = giraffe_qclog_open(0);
02273 
02274     if (qc == NULL) {
02275         cpl_msg_error(fctid, "Cannot create QC1 log!");
02276         return 1;
02277     }
02278 
02279     qclog = giraffe_paf_get_properties(qc);
02280     cx_assert(qclog != NULL);
02281 
02282 
02283     /*
02284      * Process efficiency table
02285      */
02286 
02287     pframe = giraffe_get_frame(set, GIFRAME_EFFICIENCY_CURVE,
02288                                CPL_FRAME_GROUP_PRODUCT);
02289 
02290     if (pframe == NULL) {
02291         cpl_msg_error(fctid, "Missing product frame (%s)",
02292                       GIFRAME_EFFICIENCY_CURVE);
02293 
02294         giraffe_paf_delete(qc);
02295         qc = NULL;
02296 
02297         return 1;
02298     }
02299 
02300     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
02301                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
02302 
02303     ptable = giraffe_table_new();
02304     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
02305                                 "EFFICIENCY_CURVE");
02306 
02307     if (status != 0) {
02308         cpl_msg_error(fctid, "Could not load efficiency table '%s'! "
02309                       "Aborting ...", cpl_frame_get_filename(pframe));
02310 
02311         giraffe_table_delete(ptable);
02312         ptable = NULL;
02313 
02314         giraffe_paf_delete(qc);
02315         qc = NULL;
02316 
02317         return 1;
02318     }
02319 
02320 
02321     /*
02322      * Load first raw image as reference
02323      */
02324 
02325     rframe = cpl_frameset_find(set, GIFRAME_STANDARD);
02326 
02327     if (rframe == NULL) {
02328         cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_STANDARD);
02329 
02330         giraffe_table_delete(ptable);
02331         ptable = NULL;
02332 
02333         giraffe_paf_delete(qc);
02334         qc = NULL;
02335 
02336         return 1;
02337     }
02338 
02339     rimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02340     status = giraffe_image_load(rimage, cpl_frame_get_filename(rframe), 0);
02341 
02342     if (status != 0) {
02343         cpl_msg_error(fctid, "Could not load standard star observation '%s'!",
02344                       cpl_frame_get_filename(rframe));
02345 
02346         giraffe_image_delete(rimage);
02347         rimage = NULL;
02348 
02349         giraffe_table_delete(ptable);
02350         ptable = NULL;
02351 
02352         giraffe_paf_delete(qc);
02353         qc = NULL;
02354 
02355         return 1;
02356 
02357     }
02358 
02359     _rimage = giraffe_image_get(rimage);
02360     cx_assert(_rimage != NULL);
02361 
02362     properties = giraffe_image_get_properties(rimage);
02363     cx_assert(properties != NULL);
02364 
02365     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
02366     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
02367 
02368     cpl_propertylist_update_string(qclog, "PRO.CATG",
02369                                    cpl_frame_get_tag(pframe));
02370     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02371                                  "Pipeline product category");
02372 
02373 
02374     /*
02375      * Count the number of saturated pixels in the raw frame
02376      */
02377 
02378     pixels = cpl_image_get_data(_rimage);
02379     npixel = cpl_image_get_size_x(_rimage) * cpl_image_get_size_y(_rimage);
02380 
02381     _rimage = NULL;
02382 
02383     for (i = 0; i < npixel; i++) {
02384         if (pixels[i] > saturation) {
02385             ++nsaturated;
02386         }
02387     }
02388 
02389     pixels = NULL;
02390 
02391     giraffe_image_delete(rimage);
02392     rimage = NULL;
02393 
02394 
02395     /*
02396      * Compute mean efficiency from a wavelength range around the
02397      * central wavelength.
02398      */
02399 
02400     _ptable = giraffe_table_get(ptable);
02401     cx_assert(_ptable != NULL);
02402 
02403     properties = giraffe_table_get_properties(ptable);
02404     cx_assert(properties != NULL);
02405 
02406     if (cpl_propertylist_has(properties, GIALIAS_GRATWLEN) == FALSE) {
02407 
02408         giraffe_table_delete(ptable);
02409         ptable = NULL;
02410 
02411         giraffe_paf_delete(qc);
02412         qc = NULL;
02413 
02414         cpl_msg_error(fctid, "Missing property '%s'", GIALIAS_GRATWLEN);
02415 
02416         return 1;
02417 
02418     }
02419     else {
02420 
02421         cxdouble wlband = 0.;
02422         cxdouble wl0 = cpl_propertylist_get_double(properties,
02423                                                    GIALIAS_GRATWLEN);
02424 
02425 
02426         wlmin = cpl_propertylist_get_double(properties, GIALIAS_BINWLMIN);
02427         wlmax = cpl_propertylist_get_double(properties, GIALIAS_BINWLMAX);
02428 
02429         cx_assert((wlmin < wl0) && (wl0 < wlmax));
02430 
02431         wlband = wlscale * fabs(wlmax - wlmin);
02432 
02433         wlmin = CX_MAX(wlmin, (wl0 - wlband));
02434         wlmax = CX_MIN(wlmax, (wl0 + wlband));
02435 
02436         cpl_msg_info(fctid, "Computing spectrograph efficiency from "
02437                      "wavelength range ]%.1f, %.1f[", wlmin, wlmax);
02438 
02439     }
02440 
02441     nbin = 0;
02442 
02443     for (i = 0; i < cpl_table_get_nrow(_ptable); ++i) {
02444 
02445         cxdouble wavelength = cpl_table_get_double(_ptable, "WLEN", i, NULL);
02446 
02447         if ((wavelength > wlmin) && (wavelength < wlmax)) {
02448 
02449             efficiency += cpl_table_get_double(_ptable, "EFFICIENCY",
02450                                                i, NULL);
02451             ++nbin;
02452 
02453         }
02454 
02455     }
02456 
02457     efficiency /= (cxdouble)nbin;
02458 
02459 
02460     cpl_propertylist_update_int(properties, GIALIAS_QCNSAT, nsaturated);
02461     cpl_propertylist_set_comment(properties, GIALIAS_QCNSAT, "Number of "
02462                                  "saturated pixels in the first raw frame");
02463 
02464     giraffe_propertylist_copy(qclog, "QC.OUT1.NSAT.RAW", properties,
02465                               GIALIAS_QCNSAT);
02466 
02467 
02468     cpl_propertylist_update_double(properties, GIALIAS_QCEFFICIENCY,
02469                                    efficiency);
02470     cpl_propertylist_set_comment(properties, GIALIAS_QCEFFICIENCY,
02471                                  "Efficiency of the spectrograph.");
02472 
02473     giraffe_propertylist_copy(qclog, "QC.EFFICIENCY.MEAN", properties,
02474                               GIALIAS_QCEFFICIENCY);
02475 
02476 
02477     if (cpl_propertylist_has(properties, GIALIAS_SKY_LEVEL) == TRUE) {
02478 
02479         cxdouble mean_sky = cpl_propertylist_get_double(properties,
02480                                                         GIALIAS_SKY_LEVEL);
02481 
02482         cpl_propertylist_update_double(properties, GIALIAS_QCSKYLEVEL,
02483                                        mean_sky);
02484         cpl_propertylist_set_comment(properties, GIALIAS_QCSKYLEVEL,
02485                                      "Mean sky level [ADU]");
02486 
02487         giraffe_propertylist_copy(qclog, "QC.SKY.MEAN", properties,
02488                                   GIALIAS_QCSKYLEVEL);
02489 
02490     }
02491 
02492 
02493     /*
02494      * Write QC1 log and save updated product.
02495      */
02496 
02497     _properties = cpl_propertylist_duplicate(properties);
02498 
02499     cpl_propertylist_erase_regexp(_properties, "ESO QC.*", 0);
02500 
02501     cpl_image_save(NULL, cpl_frame_get_filename(pframe), CPL_BPP_8_UNSIGNED,
02502                    _properties, CPL_IO_CREATE);
02503 
02504     cpl_propertylist_delete(_properties);
02505     _properties = NULL;
02506 
02507     giraffe_table_attach(ptable, cpl_frame_get_filename(pframe), 1, NULL);
02508 
02509     giraffe_table_delete(ptable);
02510     ptable = NULL;
02511 
02512     giraffe_qclog_close(qc);
02513     qc = NULL;
02514 
02515     return 0;
02516 
02517 }
02518 
02519 
02520 /*
02521  * Build table of contents, i.e. the list of available plugins, for
02522  * this module. This function is exported.
02523  */
02524 
02525 int
02526 cpl_plugin_get_info(cpl_pluginlist* list)
02527 {
02528 
02529     cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
02530     cpl_plugin* plugin = &recipe->interface;
02531 
02532 
02533     cpl_plugin_init(plugin,
02534                     CPL_PLUGIN_API,
02535                     GIRAFFE_BINARY_VERSION,
02536                     CPL_PLUGIN_TYPE_RECIPE,
02537                     "gistandard",
02538                     "Process a spectro-photometric standard star "
02539                     "observation and compute the instrument response curve.",
02540                     "For detailed information please refer to the "
02541                     "GIRAFFE pipeline user manual.\nIt is available at "
02542                     "http://www.eso.org/pipelines.",
02543                     "Giraffe Pipeline",
02544                     PACKAGE_BUGREPORT,
02545                     giraffe_get_license(),
02546                     gistandard_create,
02547                     gistandard_exec,
02548                     gistandard_destroy);
02549 
02550     cpl_pluginlist_append(list, plugin);
02551 
02552     return 0;
02553 
02554 }

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:03 2013 by doxygen 1.4.7 written by Dimitri van Heesch, © 1997-2004