GIRAFFE Pipeline Reference Manual

gistandard.c

00001 /* $Id: gistandard.c,v 1.17 2011/02/08 15:27:58 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: 2011/02/08 15:27:58 $
00024  * $Revision: 1.17 $
00025  * $Name: giraffe-2_8_8 $
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     /*
01466      * Spectrum rebinning
01467      */
01468 
01469     cpl_msg_info(_id, "Spectrum rebinning");
01470 
01471     rebin_config = giraffe_rebin_config_create(config);
01472 
01473     rebinning = giraffe_rebinning_new();
01474 
01475     status = 0;
01476 
01477     status = giraffe_rebin_spectra(rebinning, extraction, fibers,
01478                                    localization, grating, slitgeometry,
01479                                    wcalcoeff, rebin_config);
01480 
01481     if (status) {
01482         cpl_msg_error(_id, "Rebinning of standard spectra failed! "
01483                       "Aborting...");
01484 
01485         giraffe_rebinning_destroy(rebinning);
01486 
01487         giraffe_extraction_destroy(extraction);
01488         giraffe_localization_destroy(localization);
01489 
01490         giraffe_table_delete(wcalcoeff);
01491 
01492         giraffe_table_delete(slitgeometry);
01493         giraffe_table_delete(grating);
01494         giraffe_table_delete(fibers);
01495 
01496         giraffe_rebin_config_destroy(rebin_config);
01497 
01498         return 1;
01499 
01500     }
01501 
01502     giraffe_extraction_destroy(extraction);
01503     extraction = NULL;
01504 
01505     giraffe_localization_destroy(localization);
01506     localization = NULL;
01507 
01508     giraffe_rebin_config_destroy(rebin_config);
01509     rebin_config = NULL;
01510 
01511 
01512     /*
01513      * Save and register the results of the spectrum rebinning.
01514      */
01515 
01516     /* Rebinned spectra */
01517 
01518     giraffe_image_add_info(rebinning->spectra, &info, set);
01519 
01520     rbin_frame = giraffe_frame_create_image(rebinning->spectra,
01521                                             GIFRAME_STANDARD_RBNSPECTRA,
01522                                             CPL_FRAME_LEVEL_FINAL,
01523                                             TRUE, TRUE);
01524 
01525     if (rbin_frame == NULL) {
01526         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01527 
01528         giraffe_rebinning_destroy(rebinning);
01529 
01530         giraffe_table_delete(wcalcoeff);
01531 
01532         giraffe_table_delete(slitgeometry);
01533         giraffe_table_delete(grating);
01534         giraffe_table_delete(fibers);
01535 
01536         return 1;
01537     }
01538 
01539     status = giraffe_fiberlist_attach(rbin_frame, fibers);
01540 
01541     if (status) {
01542         cpl_msg_error(_id, "Cannot attach fiber setup to local "
01543                       "file '%s'! Aborting ...",
01544                       cpl_frame_get_filename(rbin_frame));
01545 
01546         giraffe_rebinning_destroy(rebinning);
01547         giraffe_table_delete(wcalcoeff);
01548 
01549         giraffe_table_delete(slitgeometry);
01550         giraffe_table_delete(grating);
01551         giraffe_table_delete(fibers);
01552 
01553         cpl_frame_delete(rbin_frame);
01554 
01555         return 1;
01556     }
01557 
01558     cpl_frameset_insert(set, rbin_frame);
01559 
01560     /* Rebinned spectra errors */
01561 
01562     giraffe_image_add_info(rebinning->errors, &info, set);
01563 
01564     rbin_frame = giraffe_frame_create_image(rebinning->errors,
01565                                             GIFRAME_STANDARD_RBNERRORS,
01566                                             CPL_FRAME_LEVEL_FINAL,
01567                                             TRUE, TRUE);
01568 
01569     if (rbin_frame == NULL) {
01570         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01571 
01572         giraffe_rebinning_destroy(rebinning);
01573 
01574         giraffe_table_delete(wcalcoeff);
01575 
01576         giraffe_table_delete(slitgeometry);
01577         giraffe_table_delete(grating);
01578         giraffe_table_delete(fibers);
01579 
01580         return 1;
01581     }
01582 
01583     status = giraffe_fiberlist_attach(rbin_frame, fibers);
01584 
01585     if (status) {
01586         cpl_msg_error(_id, "Cannot attach fiber setup to local "
01587                       "file '%s'! Aborting ...",
01588                       cpl_frame_get_filename(rbin_frame));
01589 
01590         giraffe_rebinning_destroy(rebinning);
01591 
01592         giraffe_table_delete(wcalcoeff);
01593 
01594         giraffe_table_delete(slitgeometry);
01595         giraffe_table_delete(grating);
01596         giraffe_table_delete(fibers);
01597 
01598         cpl_frame_delete(rbin_frame);
01599 
01600         return 1;
01601     }
01602 
01603     cpl_frameset_insert(set, rbin_frame);
01604 
01605 
01606 
01607     /*
01608      * Optional image and data cube construction (only for IFU and Argus)
01609      */
01610 
01611     properties = giraffe_image_get_properties(rebinning->spectra);
01612     mode = giraffe_get_mode(properties);
01613 
01614 
01615     if (mode == GIMODE_IFU || mode == GIMODE_ARGUS) {
01616 
01617         cpl_frame* rimg_frame = NULL;
01618 
01619         GiFieldOfView* fov = NULL;
01620 
01621         GiFieldOfViewConfig* fov_config = NULL;
01622 
01623 
01624         fov_config = giraffe_fov_config_create(config);
01625 
01626         cpl_msg_info(_id, "Reconstructing image and data cube from rebinned "
01627                      "spectra ...");
01628 
01629         fov = giraffe_fov_new();
01630 
01631         status = giraffe_fov_build(fov, rebinning, fibers, wcalcoeff, grating,
01632                                    slitgeometry, fov_config);
01633 
01634         if (status) {
01635 
01636             if (status == -2) {
01637                 cpl_msg_warning(_id, "No reconstructed image was built. "
01638                                 "Fiber list has no fiber position "
01639                                 "information.");
01640             }
01641             else {
01642                 cpl_msg_error(_id, "Image reconstruction failed! Aborting...");
01643 
01644                 giraffe_fov_delete(fov);
01645                 giraffe_rebinning_destroy(rebinning);
01646 
01647                 giraffe_table_delete(wcalcoeff);
01648 
01649                 giraffe_table_delete(slitgeometry);
01650                 giraffe_table_delete(grating);
01651                 giraffe_table_delete(fibers);
01652 
01653                 giraffe_fov_config_destroy(fov_config);
01654 
01655                 return 1;
01656             }
01657 
01658         }
01659 
01660         giraffe_fov_config_destroy(fov_config);
01661 
01662 
01663         /*
01664          * Save and register the results of the image reconstruction.
01665          */
01666 
01667         /* Reconstructed image */
01668 
01669         giraffe_image_add_info(fov->fov.spectra, &info, set);
01670 
01671         rimg_frame = giraffe_frame_create_image(fov->fov.spectra,
01672                                                 GIFRAME_STANDARD_RCSPECTRA,
01673                                                 CPL_FRAME_LEVEL_FINAL,
01674                                                 TRUE, TRUE);
01675 
01676         if (rimg_frame == NULL) {
01677             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01678 
01679             giraffe_fov_delete(fov);
01680             giraffe_rebinning_destroy(rebinning);
01681 
01682             giraffe_table_delete(wcalcoeff);
01683 
01684             giraffe_table_delete(slitgeometry);
01685             giraffe_table_delete(grating);
01686             giraffe_table_delete(fibers);
01687 
01688             return 1;
01689         }
01690 
01691         cpl_frameset_insert(set, rimg_frame);
01692 
01693         /* Reconstructed image errors */
01694 
01695         giraffe_image_add_info(fov->fov.errors, &info, set);
01696 
01697         rimg_frame = giraffe_frame_create_image(fov->fov.errors,
01698                                                 GIFRAME_STANDARD_RCERRORS,
01699                                                 CPL_FRAME_LEVEL_FINAL,
01700                                                 TRUE, TRUE);
01701 
01702         if (rimg_frame == NULL) {
01703             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01704 
01705             giraffe_fov_delete(fov);
01706             giraffe_rebinning_destroy(rebinning);
01707 
01708             giraffe_table_delete(wcalcoeff);
01709 
01710             giraffe_table_delete(slitgeometry);
01711             giraffe_table_delete(grating);
01712             giraffe_table_delete(fibers);
01713 
01714             return 1;
01715         }
01716 
01717         cpl_frameset_insert(set, rimg_frame);
01718 
01719         /* Spectrum cube */
01720 
01721         if (fov->cubes.spectra != NULL) {
01722 
01723             cxint component = 0;
01724 
01725             GiFrameCreator creator = (GiFrameCreator) giraffe_fov_save_cubes;
01726 
01727 
01728             properties = giraffe_image_get_properties(rebinning->spectra);
01729             properties = cpl_propertylist_duplicate(properties);
01730 
01731             giraffe_add_frameset_info(properties, set, info.sequence);
01732 
01733             rimg_frame = giraffe_frame_create(GIFRAME_STANDARD_CUBE_SPECTRA,
01734                                               CPL_FRAME_LEVEL_FINAL,
01735                                               properties,
01736                                               fov,
01737                                               &component,
01738                                               creator);
01739 
01740             cpl_propertylist_delete(properties);
01741             properties = NULL;
01742 
01743             if (rimg_frame == NULL) {
01744                 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01745 
01746                 giraffe_fov_delete(fov);
01747                 fov = NULL;
01748 
01749                 giraffe_rebinning_destroy(rebinning);
01750                 rebinning = NULL;
01751 
01752                 giraffe_table_delete(wcalcoeff);
01753                 wcalcoeff = NULL;
01754 
01755                 giraffe_table_delete(slitgeometry);
01756                 slitgeometry = NULL;
01757 
01758                 giraffe_table_delete(grating);
01759                 grating = NULL;
01760 
01761                 giraffe_table_delete(fibers);
01762                 fibers = NULL;
01763 
01764                 return 1;
01765             }
01766 
01767             status = giraffe_fiberlist_attach(rimg_frame, fibers);
01768 
01769             if (status != 0) {
01770                 cpl_msg_error(_id, "Cannot attach fiber setup to local "
01771                               "file '%s'! Aborting ...",
01772                               cpl_frame_get_filename(rimg_frame));
01773 
01774                 cpl_frame_delete(rimg_frame);
01775 
01776                 giraffe_fov_delete(fov);
01777                 fov = NULL;
01778 
01779                 giraffe_rebinning_destroy(rebinning);
01780                 rebinning = NULL;
01781 
01782                 giraffe_table_delete(wcalcoeff);
01783                 wcalcoeff = NULL;
01784 
01785                 giraffe_table_delete(slitgeometry);
01786                 slitgeometry = NULL;
01787 
01788                 giraffe_table_delete(grating);
01789                 grating = NULL;
01790 
01791                 giraffe_table_delete(fibers);
01792                 fibers = NULL;
01793 
01794                 return 1;
01795             }
01796 
01797             cpl_frameset_insert(set, rimg_frame);
01798 
01799         }
01800 
01801         /* Error cube */
01802 
01803         if (fov->cubes.errors != NULL) {
01804 
01805             cxint component = 1;
01806 
01807             GiFrameCreator creator = (GiFrameCreator) giraffe_fov_save_cubes;
01808 
01809             properties = giraffe_image_get_properties(rebinning->errors);
01810             properties = cpl_propertylist_duplicate(properties);
01811 
01812             giraffe_add_frameset_info(properties, set, info.sequence);
01813 
01814             rimg_frame = giraffe_frame_create(GIFRAME_STANDARD_CUBE_ERRORS,
01815                                               CPL_FRAME_LEVEL_FINAL,
01816                                               properties,
01817                                               fov,
01818                                               &component,
01819                                               creator);
01820 
01821             cpl_propertylist_delete(properties);
01822             properties = NULL;
01823 
01824             if (rimg_frame == NULL) {
01825                 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01826 
01827                 giraffe_fov_delete(fov);
01828                 fov = NULL;
01829 
01830                 giraffe_rebinning_destroy(rebinning);
01831                 rebinning = NULL;
01832 
01833                 giraffe_table_delete(wcalcoeff);
01834                 wcalcoeff = NULL;
01835 
01836                 giraffe_table_delete(slitgeometry);
01837                 slitgeometry = NULL;
01838 
01839                 giraffe_table_delete(grating);
01840                 grating = NULL;
01841 
01842                 giraffe_table_delete(fibers);
01843                 fibers = NULL;
01844 
01845                 return 1;
01846             }
01847 
01848             status = giraffe_fiberlist_attach(rimg_frame, fibers);
01849 
01850             if (status != 0) {
01851                 cpl_msg_error(_id, "Cannot attach fiber setup to local "
01852                               "file '%s'! Aborting ...",
01853                               cpl_frame_get_filename(rimg_frame));
01854 
01855                 cpl_frame_delete(rimg_frame);
01856 
01857                 giraffe_fov_delete(fov);
01858                 fov = NULL;
01859 
01860                 giraffe_rebinning_destroy(rebinning);
01861                 rebinning = NULL;
01862 
01863                 giraffe_table_delete(wcalcoeff);
01864                 wcalcoeff = NULL;
01865 
01866                 giraffe_table_delete(slitgeometry);
01867                 slitgeometry = NULL;
01868 
01869                 giraffe_table_delete(grating);
01870                 grating = NULL;
01871 
01872                 giraffe_table_delete(fibers);
01873                 fibers = NULL;
01874 
01875                 return 1;
01876             }
01877 
01878             cpl_frameset_insert(set, rimg_frame);
01879         }
01880 
01881         giraffe_fov_delete(fov);
01882         fov = NULL;
01883 
01884     }
01885 
01886 
01887     /*
01888      * Response computation
01889      */
01890 
01891     cpl_msg_info(_id, "Computing instrument response function...");
01892 
01893     filename = cpl_frame_get_filename(flxstd_frame);
01894 
01895     flxstd = giraffe_table_new();
01896     status = giraffe_table_load(flxstd, filename, 1, NULL);
01897 
01898     if (status != 0) {
01899         cpl_msg_error(_id, "Cannot load flux standards catalog from "
01900                       "'%s'. Aborting ...", filename);
01901 
01902         giraffe_rebinning_destroy(rebinning);
01903         rebinning = NULL;
01904 
01905         giraffe_table_delete(wcalcoeff);
01906         wcalcoeff = NULL;
01907 
01908         giraffe_table_delete(slitgeometry);
01909         slitgeometry = NULL;
01910 
01911         giraffe_table_delete(grating);
01912         grating = NULL;
01913 
01914         giraffe_table_delete(fibers);
01915         fibers = NULL;
01916 
01917         return 1;
01918     }
01919 
01920 
01921    /*
01922     * Search the flux standard catalog for the observed flux standard
01923     * object.
01924     */
01925 
01926     refflx = giraffe_select_flux_standard(flxstd, rebinning->spectra, 1.);
01927 
01928     if (refflx == NULL) {
01929         cpl_msg_error(_id, "No matching flux standard found in the "
01930                 "catalog '%s'! Aborting ...", filename);
01931 
01932         giraffe_table_delete(flxstd);
01933         flxstd = NULL;
01934 
01935         giraffe_rebinning_destroy(rebinning);
01936         rebinning = NULL;
01937 
01938         giraffe_table_delete(wcalcoeff);
01939         wcalcoeff = NULL;
01940 
01941         giraffe_table_delete(slitgeometry);
01942         slitgeometry = NULL;
01943 
01944         giraffe_table_delete(grating);
01945         grating = NULL;
01946 
01947         giraffe_table_delete(fibers);
01948         fibers = NULL;
01949 
01950         return 1;
01951     }
01952 
01953     giraffe_table_delete(flxstd);
01954     flxstd = NULL;
01955 
01956 
01957     filename = cpl_frame_get_filename(atmext_frame);
01958 
01959     atmext = giraffe_table_new();
01960     status = giraffe_table_load(atmext, filename, 1, NULL);
01961 
01962     if (status != 0) {
01963         cpl_msg_error(_id, "Cannot load atmospheric extinction data from "
01964                       "'%s'. Aborting ...", filename);
01965 
01966         giraffe_table_delete(refflx);
01967         refflx = NULL;
01968 
01969         giraffe_rebinning_destroy(rebinning);
01970         rebinning = NULL;
01971 
01972         giraffe_table_delete(wcalcoeff);
01973         wcalcoeff = NULL;
01974 
01975         giraffe_table_delete(slitgeometry);
01976         slitgeometry = NULL;
01977 
01978         giraffe_table_delete(grating);
01979         grating = NULL;
01980 
01981         giraffe_table_delete(fibers);
01982         fibers = NULL;
01983 
01984         return 1;
01985     }
01986 
01987 
01988     fxcal_config = giraffe_fxcalibration_config_create(config);
01989 
01990     response = giraffe_response_new();
01991 
01992     status = giraffe_calibrate_flux(response, rebinning, fibers, NULL,
01993                                     refflx, atmext, fxcal_config);
01994 
01995     if (status != 0) {
01996 
01997         cpl_msg_error(_id, "Instrument resonse computation failed!");
01998 
01999         giraffe_response_delete(response);
02000         response = NULL;
02001 
02002         giraffe_fxcalibration_config_destroy(fxcal_config);
02003         fxcal_config = NULL;
02004 
02005         giraffe_table_delete(atmext);
02006         atmext = NULL;
02007 
02008         giraffe_table_delete(refflx);
02009         refflx = NULL;
02010 
02011         giraffe_rebinning_destroy(rebinning);
02012         rebinning = NULL;
02013 
02014         giraffe_table_delete(wcalcoeff);
02015         wcalcoeff = NULL;
02016 
02017         giraffe_table_delete(slitgeometry);
02018         slitgeometry = NULL;
02019 
02020         giraffe_table_delete(grating);
02021         grating = NULL;
02022 
02023         giraffe_table_delete(fibers);
02024         fibers = NULL;
02025 
02026         return 1;
02027 
02028     }
02029 
02030     giraffe_fxcalibration_config_destroy(fxcal_config);
02031     fxcal_config = NULL;
02032 
02033     giraffe_table_delete(refflx);
02034     refflx = NULL;
02035 
02036     giraffe_table_delete(atmext);
02037     atmext = NULL;
02038 
02039 
02040     /*
02041      * Save and register the instrument response product
02042      */
02043 
02044     giraffe_image_add_info(response->response, &info, set);
02045 
02046     rsp_frame = giraffe_frame_create_image(response->response,
02047                                            GIFRAME_INSTRUMENT_RESPONSE,
02048                                            CPL_FRAME_LEVEL_FINAL,
02049                                            TRUE, TRUE);
02050 
02051     if (rsp_frame == NULL) {
02052 
02053         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
02054 
02055         giraffe_response_delete(response);
02056         response = NULL;
02057 
02058         giraffe_rebinning_destroy(rebinning);
02059         rebinning = NULL;
02060 
02061         giraffe_table_delete(wcalcoeff);
02062         wcalcoeff = NULL;
02063 
02064         giraffe_table_delete(slitgeometry);
02065         slitgeometry = NULL;
02066 
02067         giraffe_table_delete(grating);
02068         grating = NULL;
02069 
02070         giraffe_table_delete(fibers);
02071         fibers = NULL;
02072 
02073         return 1;
02074 
02075     }
02076 
02077     cpl_frameset_insert(set, rsp_frame);
02078 
02079 
02080     /*
02081      * Save and register the efficiency curve product
02082      */
02083 
02084     giraffe_table_add_info(response->efficiency, &info, set);
02085 
02086     rsp_frame = giraffe_frame_create_table(response->efficiency,
02087                                            GIFRAME_EFFICIENCY_CURVE,
02088                                            CPL_FRAME_LEVEL_FINAL,
02089                                            TRUE, TRUE);
02090 
02091     if (rsp_frame == NULL) {
02092 
02093         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
02094 
02095         giraffe_response_delete(response);
02096         response = NULL;
02097 
02098         giraffe_rebinning_destroy(rebinning);
02099         rebinning = NULL;
02100 
02101         giraffe_table_delete(wcalcoeff);
02102         wcalcoeff = NULL;
02103 
02104         giraffe_table_delete(slitgeometry);
02105         slitgeometry = NULL;
02106 
02107         giraffe_table_delete(grating);
02108         grating = NULL;
02109 
02110         giraffe_table_delete(fibers);
02111         fibers = NULL;
02112 
02113         return 1;
02114 
02115     }
02116 
02117     cpl_frameset_insert(set, rsp_frame);
02118 
02119     giraffe_response_delete(response);
02120     response = NULL;
02121 
02122 
02123     /*
02124      * Cleanup
02125      */
02126 
02127     giraffe_table_delete(wcalcoeff);
02128 
02129     giraffe_table_delete(slitgeometry);
02130     giraffe_table_delete(grating);
02131     giraffe_table_delete(fibers);
02132 
02133     giraffe_rebinning_destroy(rebinning);
02134 
02135     return 0;
02136 
02137 }
02138 
02139 
02140 static cxint
02141 giqcstandard(cpl_frameset* set)
02142 {
02143 
02144     const cxchar* const fctid = "giqcstandard";
02145 
02146 
02147     const cxdouble saturation = 60000.;
02148     const cxdouble wlscale = 0.1;
02149 
02150     cxint i = 0;
02151     cxint status = 0;
02152     cxint nbin = 0;
02153     cxint npixel = 0;
02154     cxint nsaturated = 0;
02155 
02156     const cxdouble* pixels = NULL;
02157 
02158     cxdouble wlmin = 0.;
02159     cxdouble wlmax = 0.;
02160     cxdouble efficiency = 0.;
02161 
02162     cpl_propertylist* properties = NULL;
02163     cpl_propertylist* _properties = NULL;
02164     cpl_propertylist* qclog = NULL;
02165 
02166     cpl_frame* rframe = NULL;
02167     cpl_frame* pframe = NULL;
02168 
02169     cpl_image* _rimage = NULL;
02170 
02171     cpl_table* _ptable = NULL;
02172 
02173     GiImage* rimage = NULL;
02174 
02175     GiTable* ptable = NULL;
02176 
02177     GiPaf* qc = NULL;
02178 
02179 
02180     cpl_msg_info(fctid, "Computing QC1 parameters ...");
02181 
02182     qc = giraffe_qclog_open(0);
02183 
02184     if (qc == NULL) {
02185         cpl_msg_error(fctid, "Cannot create QC1 log!");
02186         return 1;
02187     }
02188 
02189     qclog = giraffe_paf_get_properties(qc);
02190     cx_assert(qclog != NULL);
02191 
02192 
02193     /*
02194      * Process efficiency table
02195      */
02196 
02197     pframe = giraffe_get_frame(set, GIFRAME_EFFICIENCY_CURVE,
02198                                CPL_FRAME_GROUP_PRODUCT);
02199 
02200     if (pframe == NULL) {
02201         cpl_msg_error(fctid, "Missing product frame (%s)",
02202                       GIFRAME_EFFICIENCY_CURVE);
02203 
02204         giraffe_paf_delete(qc);
02205         qc = NULL;
02206 
02207         return 1;
02208     }
02209 
02210     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
02211                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
02212 
02213     ptable = giraffe_table_new();
02214     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
02215                                 "EFFICIENCY_CURVE");
02216 
02217     if (status != 0) {
02218         cpl_msg_error(fctid, "Could not load efficiency table '%s'! "
02219                       "Aborting ...", cpl_frame_get_filename(pframe));
02220 
02221         giraffe_table_delete(ptable);
02222         ptable = NULL;
02223 
02224         giraffe_paf_delete(qc);
02225         qc = NULL;
02226 
02227         return 1;
02228     }
02229 
02230 
02231     /*
02232      * Load first raw image as reference
02233      */
02234 
02235     rframe = cpl_frameset_find(set, GIFRAME_STANDARD);
02236 
02237     if (rframe == NULL) {
02238         cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_STANDARD);
02239 
02240         giraffe_table_delete(ptable);
02241         ptable = NULL;
02242 
02243         giraffe_paf_delete(qc);
02244         qc = NULL;
02245 
02246         return 1;
02247     }
02248 
02249     rimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02250     status = giraffe_image_load(rimage, cpl_frame_get_filename(rframe), 0);
02251 
02252     if (status != 0) {
02253         cpl_msg_error(fctid, "Could not load standard star observation '%s'!",
02254                       cpl_frame_get_filename(rframe));
02255 
02256         giraffe_image_delete(rimage);
02257         rimage = NULL;
02258 
02259         giraffe_table_delete(ptable);
02260         ptable = NULL;
02261 
02262         giraffe_paf_delete(qc);
02263         qc = NULL;
02264 
02265         return 1;
02266 
02267     }
02268 
02269     _rimage = giraffe_image_get(rimage);
02270     cx_assert(_rimage != NULL);
02271 
02272     properties = giraffe_image_get_properties(rimage);
02273     cx_assert(properties != NULL);
02274 
02275     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
02276     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
02277 
02278     cpl_propertylist_update_string(qclog, "PRO.CATG",
02279                                    cpl_frame_get_tag(pframe));
02280     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02281                                  "Pipeline product category");
02282 
02283 
02284     /*
02285      * Count the number of saturated pixels in the raw frame
02286      */
02287 
02288     pixels = cpl_image_get_data(_rimage);
02289     npixel = cpl_image_get_size_x(_rimage) * cpl_image_get_size_y(_rimage);
02290 
02291     _rimage = NULL;
02292 
02293     for (i = 0; i < npixel; i++) {
02294         if (pixels[i] > saturation) {
02295             ++nsaturated;
02296         }
02297     }
02298 
02299     pixels = NULL;
02300 
02301     giraffe_image_delete(rimage);
02302     rimage = NULL;
02303 
02304 
02305     /*
02306      * Compute mean efficiency from a wavelength range around the
02307      * central wavelength.
02308      */
02309 
02310     _ptable = giraffe_table_get(ptable);
02311     cx_assert(_ptable != NULL);
02312 
02313     properties = giraffe_table_get_properties(ptable);
02314     cx_assert(properties != NULL);
02315 
02316     if (cpl_propertylist_has(properties, GIALIAS_GRATWLEN) == FALSE) {
02317 
02318         giraffe_table_delete(ptable);
02319         ptable = NULL;
02320 
02321         giraffe_paf_delete(qc);
02322         qc = NULL;
02323 
02324         cpl_msg_error(fctid, "Missing property '%s'", GIALIAS_GRATWLEN);
02325 
02326         return 1;
02327 
02328     }
02329     else {
02330 
02331         cxdouble wlband = 0.;
02332         cxdouble wl0 = cpl_propertylist_get_double(properties,
02333                                                    GIALIAS_GRATWLEN);
02334 
02335 
02336         wlmin = cpl_propertylist_get_double(properties, GIALIAS_BINWLMIN);
02337         wlmax = cpl_propertylist_get_double(properties, GIALIAS_BINWLMAX);
02338 
02339         cx_assert((wlmin < wl0) && (wl0 < wlmax));
02340 
02341         wlband = wlscale * fabs(wlmax - wlmin);
02342 
02343         wlmin = CX_MAX(wlmin, (wl0 - wlband));
02344         wlmax = CX_MIN(wlmax, (wl0 + wlband));
02345 
02346         cpl_msg_info(fctid, "Computing spectrograph efficiency from "
02347                      "wavelength range ]%.1f, %.1f[", wlmin, wlmax);
02348 
02349     }
02350 
02351     nbin = 0;
02352 
02353     for (i = 0; i < cpl_table_get_nrow(_ptable); ++i) {
02354 
02355         cxdouble wavelength = cpl_table_get_double(_ptable, "WLEN", i, NULL);
02356 
02357         if ((wavelength > wlmin) && (wavelength < wlmax)) {
02358 
02359             efficiency += cpl_table_get_double(_ptable, "EFFICIENCY",
02360                                                i, NULL);
02361             ++nbin;
02362 
02363         }
02364 
02365     }
02366 
02367     efficiency /= (cxdouble)nbin;
02368 
02369 
02370     cpl_propertylist_update_int(properties, GIALIAS_QCNSAT, nsaturated);
02371     cpl_propertylist_set_comment(properties, GIALIAS_QCNSAT, "Number of "
02372                                  "saturated pixels in the first raw frame");
02373 
02374     giraffe_propertylist_copy(qclog, "QC.OUT1.NSAT.RAW", properties,
02375                               GIALIAS_QCNSAT);
02376 
02377 
02378     cpl_propertylist_update_double(properties, GIALIAS_QCEFFICIENCY,
02379                                    efficiency);
02380     cpl_propertylist_set_comment(properties, GIALIAS_QCEFFICIENCY,
02381                                  "Efficiency of the spectrograph.");
02382 
02383     giraffe_propertylist_copy(qclog, "QC.EFFICIENCY.MEAN", properties,
02384                               GIALIAS_QCEFFICIENCY);
02385 
02386 
02387     if (cpl_propertylist_has(properties, GIALIAS_SKY_LEVEL) == TRUE) {
02388 
02389         cxdouble mean_sky = cpl_propertylist_get_double(properties,
02390                                                         GIALIAS_SKY_LEVEL);
02391 
02392         cpl_propertylist_update_double(properties, GIALIAS_QCSKYLEVEL,
02393                                        mean_sky);
02394         cpl_propertylist_set_comment(properties, GIALIAS_QCSKYLEVEL,
02395                                      "Mean sky level [ADU]");
02396 
02397         giraffe_propertylist_copy(qclog, "QC.SKY.MEAN", properties,
02398                                   GIALIAS_QCSKYLEVEL);
02399 
02400     }
02401 
02402 
02403     /*
02404      * Write QC1 log and save updated product.
02405      */
02406 
02407     _properties = cpl_propertylist_duplicate(properties);
02408 
02409     cpl_propertylist_erase_regexp(_properties, "ESO QC.*", 0);
02410 
02411     cpl_image_save(NULL, cpl_frame_get_filename(pframe), CPL_BPP_8_UNSIGNED,
02412                    _properties, CPL_IO_CREATE);
02413 
02414     cpl_propertylist_delete(_properties);
02415     _properties = NULL;
02416 
02417     giraffe_table_attach(ptable, cpl_frame_get_filename(pframe), 1, NULL);
02418 
02419     giraffe_table_delete(ptable);
02420     ptable = NULL;
02421 
02422     giraffe_qclog_close(qc);
02423     qc = NULL;
02424 
02425     return 0;
02426 
02427 }
02428 
02429 
02430 /*
02431  * Build table of contents, i.e. the list of available plugins, for
02432  * this module. This function is exported.
02433  */
02434 
02435 int
02436 cpl_plugin_get_info(cpl_pluginlist* list)
02437 {
02438 
02439     cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
02440     cpl_plugin* plugin = &recipe->interface;
02441 
02442 
02443     cpl_plugin_init(plugin,
02444                     CPL_PLUGIN_API,
02445                     GIRAFFE_BINARY_VERSION,
02446                     CPL_PLUGIN_TYPE_RECIPE,
02447                     "gistandard",
02448                     "Process a spectro-photometric standard star "
02449                     "observation and compute the instrument response curve.",
02450                     "For detailed information please refer to the "
02451                     "GIRAFFE pipeline user manual.\nIt is available at "
02452                     "http://www.eso.org/pipelines.",
02453                     "Giraffe Pipeline",
02454                     PACKAGE_BUGREPORT,
02455                     giraffe_get_license(),
02456                     gistandard_create,
02457                     gistandard_exec,
02458                     gistandard_destroy);
02459 
02460     cpl_pluginlist_append(list, plugin);
02461 
02462     return 0;
02463 
02464 }

This file is part of the GIRAFFE Pipeline Reference Manual 2.8.8.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Fri Mar 4 10:50:28 2011 by doxygen 1.6.3 written by Dimitri van Heesch, © 1997-2004