GIRAFFE Pipeline Reference Manual

giwavecalibration.c

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

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