GIRAFFE Pipeline Reference Manual

giwavecalibration.c

00001 /* $Id: giwavecalibration.c,v 1.41.2.2 2008/06/09 15:11:51 rpalsa Exp $
00002  *
00003  * This file is part of the GIRAFFE Pipeline
00004  * Copyright (C) 2002-2006 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 /*
00022  * $Author: rpalsa $
00023  * $Date: 2008/06/09 15:11:51 $
00024  * $Revision: 1.41.2.2 $
00025  * $Name: giraffe-2_5_2 $
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 slit geometry 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 (strcmp(bias_config->areas, "None")) {
00493         cpl_msg_warning(fctid, "User defined bias areas are not yet "
00494                                "supported. Using image pre- and overscan "
00495                                "areas!");
00496 
00497         biasareas = NULL;
00498     }
00499 
00500     if (bias_config->method == GIBIAS_METHOD_MASTER ||
00501         bias_config->method == GIBIAS_METHOD_ZMASTER) {
00502 
00503         if (!mbias_frame) {
00504             cpl_msg_error(fctid, "Missing master bias frame! Selected bias "
00505                                  "removal method requires a master bias "
00506                                  "frame!");
00507 
00508             giraffe_image_delete(bpixel);
00509             giraffe_image_delete(arcspectrum);
00510             giraffe_bias_config_destroy(bias_config);
00511 
00512             return 1;
00513         }
00514         else {
00515 
00516             status = 0;
00517             filename = cpl_frame_get_filename(mbias_frame);
00518 
00519             mbias = giraffe_image_new(CPL_TYPE_DOUBLE);
00520             status = giraffe_image_load(mbias, filename, 0);
00521 
00522             if (status) {
00523                 cpl_msg_error(fctid, "Cannot load master bias from '%s'. "
00524                                      "Aborting ...", filename);
00525 
00526                 giraffe_image_delete(bpixel);
00527                 giraffe_image_delete(arcspectrum);
00528                 giraffe_image_delete(mbias);
00529                 giraffe_bias_config_destroy(bias_config);
00530 
00531                 return 1;
00532             }
00533         }
00534     }
00535 
00536 
00537     /*
00538      * Compute and remove the bias from the stacked flat field frame.
00539      */
00540 
00541     bsarcspectrum = giraffe_image_new(CPL_TYPE_DOUBLE);
00542 
00543     status = giraffe_bias_remove(bsarcspectrum, arcspectrum, mbias, bpixel,
00544                                  biasareas, bias_config);
00545 
00546     giraffe_image_delete(arcspectrum);
00547     arcspectrum = NULL;
00548 
00549     if (mbias) {
00550         giraffe_image_delete(mbias);
00551         mbias = NULL;
00552     }
00553 
00554     if (biasareas) {
00555         cpl_matrix_delete(biasareas);
00556         biasareas = NULL;
00557     }
00558 
00559     giraffe_bias_config_destroy(bias_config);
00560     bias_config = NULL;
00561 
00562     if (status) {
00563         cpl_msg_error(fctid, "Bias removal failed. Aborting ...");
00564 
00565         giraffe_image_delete(bpixel);
00566         giraffe_image_delete(bsarcspectrum);
00567         return 1;
00568     }
00569 
00570 
00571     /*
00572      * Determine fiber setup
00573      */
00574 
00575     cpl_msg_info(fctid, "Recipe Step : Fiber Setup");
00576 
00577     cpl_msg_info(fctid, "Building fiber setup for frame '%s'.",
00578                  cpl_frame_get_filename(arcspec_frame));
00579 
00580     fibers = giraffe_fibers_setup(arcspec_frame, mlocy_frame);
00581 
00582     if (!fibers) {
00583         cpl_msg_error(fctid, "Cannot create fiber setup for frame '%s'! "
00584                       "Aborting ...", cpl_frame_get_filename(arcspec_frame));
00585 
00586         giraffe_image_delete(bpixel);
00587         giraffe_image_delete(bsarcspectrum);
00588 
00589         return 1;
00590     }
00591 
00592     cpl_msg_info(fctid, "Fiber reference setup taken from localization "
00593                  "frame '%s'.", cpl_frame_get_filename(mlocy_frame));
00594 
00595 
00596     /*
00597      * Load spectrum localization.
00598      */
00599 
00600     localization = giraffe_localization_new();
00601 
00602     filename = cpl_frame_get_filename(mlocy_frame);
00603     status = 0;
00604 
00605     localization->locy  = giraffe_image_new(CPL_TYPE_DOUBLE);
00606     status = giraffe_image_load(localization->locy, filename, 0);
00607 
00608     if (status) {
00609         cpl_msg_error(fctid, "Cannot load localization (centroid "
00610                       "position) frame from '%s'. Aborting ...",
00611                       filename);
00612 
00613         giraffe_localization_destroy(localization);
00614         giraffe_image_delete(bpixel);
00615         giraffe_image_delete(bsarcspectrum);
00616         giraffe_table_delete(fibers);
00617 
00618         return 1;
00619 
00620     }
00621 
00622 
00623     filename = cpl_frame_get_filename(mlocw_frame);
00624     status = 0;
00625 
00626     localization->locw  = giraffe_image_new(CPL_TYPE_DOUBLE);
00627     status = giraffe_image_load(localization->locw, filename, 0);
00628 
00629     if (status) {
00630         cpl_msg_error(fctid, "Cannot load localization (spectrum width) "
00631                       "frame from '%s'. Aborting ...", filename);
00632 
00633         giraffe_localization_destroy(localization);
00634         giraffe_image_delete(bpixel);
00635         giraffe_image_delete(bsarcspectrum);
00636         giraffe_table_delete(fibers);
00637 
00638         return 1;
00639 
00640     }
00641 
00642 
00643     /*
00644      * Perform spectrum extraction on the master flat field.
00645      */
00646 
00647     cpl_msg_info(fctid, "Recipe Step : Spectrum Extraction");
00648 
00649     if (slight_frame) {
00650 
00651         filename = cpl_frame_get_filename(slight_frame);
00652         status = 0;
00653 
00654         slight = giraffe_image_new(CPL_TYPE_DOUBLE);
00655         status = giraffe_image_load(slight, filename, 0);
00656 
00657         if (status) {
00658             cpl_msg_error(fctid, "Cannot load scattered light model from "
00659                           "'%s'. Aborting ...", filename);
00660 
00661             giraffe_image_delete(bpixel);
00662             giraffe_image_delete(bsarcspectrum);
00663             giraffe_table_delete(fibers);
00664             giraffe_localization_destroy(localization);
00665             giraffe_image_delete(slight);
00666 
00667             return 1;
00668 
00669         }
00670 
00671     }
00672 
00673     extract_config = giraffe_extract_config_create(config);
00674 
00675     if ((extract_config->emethod == GIEXTRACT_OPTIMAL) ||
00676         (extract_config->emethod == GIEXTRACT_HORNE)) {
00677 
00678         if (psfdata_frame == NULL) {
00679 
00680             const cxchar* emethod = "Optimal";
00681 
00682             if (extract_config->emethod == GIEXTRACT_HORNE) {
00683                 emethod = "Horne";
00684             }
00685 
00686             cpl_msg_error(fctid, "%s spectrum extraction requires PSF "
00687                           "profile data. Aborting ...", emethod);
00688 
00689             giraffe_extract_config_destroy(extract_config);
00690             extract_config = NULL;
00691 
00692             if (slight != NULL) {
00693                 giraffe_image_delete(slight);
00694                 slight = NULL;
00695             }
00696 
00697             giraffe_localization_destroy(localization);
00698             localization = NULL;
00699 
00700             if (bpixel) {
00701                 giraffe_image_delete(bpixel);
00702                 bpixel = NULL;
00703             }
00704 
00705             giraffe_table_delete(fibers);
00706             fibers = NULL;
00707 
00708             giraffe_image_delete(bsarcspectrum);
00709             bsarcspectrum = NULL;
00710 
00711             return 1;
00712 
00713         }
00714         else {
00715 
00716             filename = cpl_frame_get_filename(psfdata_frame);
00717             status = 0;
00718 
00719             localization->psf  = giraffe_psfdata_new();
00720             status = giraffe_psfdata_load(localization->psf, filename);
00721 
00722             if (status) {
00723                 cpl_msg_error(fctid, "Cannot load PSF profile data frame from "
00724                               "'%s'. Aborting ...", filename);
00725 
00726                 giraffe_extract_config_destroy(extract_config);
00727                 extract_config = NULL;
00728 
00729                 if (slight != NULL) {
00730                     giraffe_image_delete(slight);
00731                     slight = NULL;
00732                 }
00733 
00734                 giraffe_localization_destroy(localization);
00735                 localization = NULL;
00736 
00737                 if (bpixel) {
00738                     giraffe_image_delete(bpixel);
00739                     bpixel = NULL;
00740                 }
00741 
00742                 giraffe_table_delete(fibers);
00743                 fibers = NULL;
00744 
00745                 giraffe_image_delete(bsarcspectrum);
00746                 bsarcspectrum = NULL;
00747 
00748                 return 1;
00749 
00750             }
00751 
00752         }
00753 
00754     }
00755 
00756 
00757     extraction = giraffe_extraction_new();
00758 
00759     status = giraffe_extract_spectra(extraction, bsarcspectrum, fibers,
00760                                      localization, bpixel, slight,
00761                                      extract_config);
00762 
00763     if (status) {
00764         cpl_msg_error(fctid, "Spectrum extraction failed! Aborting ...");
00765 
00766          giraffe_image_delete(bpixel);
00767          giraffe_image_delete(bsarcspectrum);
00768          giraffe_table_delete(fibers);
00769          giraffe_localization_destroy(localization);
00770          giraffe_image_delete(slight);
00771          giraffe_extract_config_destroy(extract_config);
00772          giraffe_extraction_destroy(extraction);
00773 
00774         return 1;
00775     }
00776 
00777     giraffe_image_delete(slight);
00778     slight = NULL;
00779 
00780     giraffe_image_delete(bpixel);
00781     bpixel = NULL;
00782 
00783     giraffe_image_delete(bsarcspectrum);
00784     bsarcspectrum = NULL;
00785 
00786     giraffe_extract_config_destroy(extract_config);
00787     extract_config = NULL;
00788 
00789     /*
00790      * Save the spectrum extraction results and register them as
00791      * products.
00792      */
00793 
00794     cpl_msg_info(fctid, "Writing extracted spectra ...");
00795 
00796     /* Extracted spectra */
00797 
00798     giraffe_image_add_info(extraction->spectra, &info, set);
00799 
00800     sext_frame = giraffe_frame_create_image(extraction->spectra,
00801                                             GIFRAME_ARC_LAMP_EXTSPECTRA,
00802                                             CPL_FRAME_LEVEL_INTERMEDIATE,
00803                                             TRUE, TRUE);
00804 
00805     if (sext_frame == NULL) {
00806         cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
00807 
00808         giraffe_table_delete(fibers);
00809 
00810         giraffe_localization_destroy(localization);
00811         giraffe_extraction_destroy(extraction);
00812 
00813         return 1;
00814     }
00815 
00816     status = giraffe_fiberlist_attach(sext_frame, fibers);
00817 
00818     if (status) {
00819         cpl_msg_error(fctid, "Cannot attach fiber setup to local file '%s'! "
00820                       "Aborting ...", cpl_frame_get_filename(sext_frame));
00821 
00822         cpl_frame_delete(sext_frame);
00823 
00824         giraffe_table_delete(fibers);
00825 
00826         giraffe_localization_destroy(localization);
00827         giraffe_extraction_destroy(extraction);
00828 
00829         return 1;
00830     }
00831 
00832     cpl_frameset_insert(set, sext_frame);
00833 
00834     /* Extracted spectra errors */
00835 
00836     giraffe_image_add_info(extraction->error, &info, set);
00837 
00838     sext_frame = giraffe_frame_create_image(extraction->error,
00839                                             GIFRAME_ARC_LAMP_EXTERRORS,
00840                                             CPL_FRAME_LEVEL_INTERMEDIATE,
00841                                             TRUE, TRUE);
00842 
00843     if (sext_frame == NULL) {
00844         cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
00845 
00846         giraffe_table_delete(fibers);
00847 
00848         giraffe_localization_destroy(localization);
00849         giraffe_extraction_destroy(extraction);
00850 
00851         return 1;
00852     }
00853 
00854     status = giraffe_fiberlist_attach(sext_frame, fibers);
00855 
00856     if (status) {
00857         cpl_msg_error(fctid, "Cannot attach fiber setup to local file '%s'! "
00858                       "Aborting ...", cpl_frame_get_filename(sext_frame));
00859 
00860         cpl_frame_delete(sext_frame);
00861 
00862         giraffe_table_delete(fibers);
00863 
00864         giraffe_localization_destroy(localization);
00865         giraffe_extraction_destroy(extraction);
00866 
00867         return 1;
00868     }
00869 
00870     cpl_frameset_insert(set, sext_frame);
00871 
00872     /* Extracted spectra pixels */
00873 
00874     if (extraction->npixels != NULL) {
00875 
00876         giraffe_image_add_info(extraction->npixels, &info, set);
00877 
00878         sext_frame = giraffe_frame_create_image(extraction->npixels,
00879                                                 GIFRAME_ARC_LAMP_EXTPIXELS,
00880                                                 CPL_FRAME_LEVEL_INTERMEDIATE,
00881                                                 TRUE, TRUE);
00882 
00883         if (sext_frame == NULL) {
00884             cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
00885 
00886             giraffe_table_delete(fibers);
00887 
00888             giraffe_localization_destroy(localization);
00889             giraffe_extraction_destroy(extraction);
00890 
00891             return 1;
00892         }
00893 
00894         status = giraffe_fiberlist_attach(sext_frame, fibers);
00895 
00896         if (status) {
00897             cpl_msg_error(fctid, "Cannot attach fiber setup to local file '%s'! "
00898                         "Aborting ...", cpl_frame_get_filename(sext_frame));
00899 
00900             cpl_frame_delete(sext_frame);
00901 
00902             giraffe_table_delete(fibers);
00903 
00904             giraffe_localization_destroy(localization);
00905             giraffe_extraction_destroy(extraction);
00906 
00907             return 1;
00908         }
00909 
00910         cpl_frameset_insert(set, sext_frame);
00911 
00912     }
00913 
00914     /* Extracted spectra centroids */
00915 
00916     giraffe_image_add_info(extraction->centroid, &info, set);
00917 
00918     sext_frame = giraffe_frame_create_image(extraction->centroid,
00919                                             GIFRAME_ARC_LAMP_EXTTRACE,
00920                                             CPL_FRAME_LEVEL_INTERMEDIATE,
00921                                             TRUE, TRUE);
00922 
00923     if (sext_frame == NULL) {
00924         cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
00925 
00926         giraffe_table_delete(fibers);
00927 
00928         giraffe_localization_destroy(localization);
00929         giraffe_extraction_destroy(extraction);
00930 
00931         return 1;
00932     }
00933 
00934     status = giraffe_fiberlist_attach(sext_frame, fibers);
00935 
00936     if (status) {
00937         cpl_msg_error(fctid, "Cannot attach fiber setup to local file '%s'! "
00938                       "Aborting ...", cpl_frame_get_filename(sext_frame));
00939 
00940         cpl_frame_delete(sext_frame);
00941 
00942         giraffe_table_delete(fibers);
00943 
00944         giraffe_localization_destroy(localization);
00945         giraffe_extraction_destroy(extraction);
00946 
00947         return 1;
00948     }
00949 
00950     cpl_frameset_insert(set, sext_frame);
00951 
00952     /* Extraction model spectra */
00953 
00954     if (extraction->model != NULL) {
00955 
00956         giraffe_image_add_info(extraction->model, &info, set);
00957 
00958         sext_frame = giraffe_frame_create_image(extraction->model,
00959                                                 GIFRAME_ARC_LAMP_EXTMODEL,
00960                                                 CPL_FRAME_LEVEL_FINAL,
00961                                                 TRUE, TRUE);
00962 
00963         if (sext_frame == NULL) {
00964             cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
00965 
00966             giraffe_table_delete(fibers);
00967 
00968             giraffe_localization_destroy(localization);
00969             giraffe_extraction_destroy(extraction);
00970 
00971             return 1;
00972         }
00973 
00974         status = giraffe_fiberlist_attach(sext_frame, fibers);
00975 
00976         if (status != 0) {
00977             cpl_msg_error(fctid, "Cannot attach fiber setup to local file '%s'! "
00978                           "Aborting ...", cpl_frame_get_filename(sext_frame));
00979 
00980             cpl_frame_delete(sext_frame);
00981 
00982             giraffe_table_delete(fibers);
00983 
00984             giraffe_localization_destroy(localization);
00985             giraffe_extraction_destroy(extraction);
00986 
00987             return 1;
00988         }
00989 
00990         cpl_frameset_insert(set, sext_frame);
00991 
00992     }
00993 
00994     /*
00995      * Perform Wavelength Calibration
00996      */
00997 
00998     cpl_msg_info(fctid, "Recipe Step : Wavelength Calibration");
00999 
01000     filename = cpl_frame_get_filename(grating_frame);
01001     status = 0;
01002 
01003     grating = giraffe_table_new();
01004     status = giraffe_table_load(grating, filename, 1, NULL);
01005 
01006     if (status) {
01007         cpl_msg_error(fctid, "Cannot load grating table from '%s'. "
01008                       "Aborting ...", filename);
01009 
01010         giraffe_table_delete(fibers);
01011         giraffe_localization_destroy(localization);
01012         giraffe_extraction_destroy(extraction);
01013 
01014         return 1;
01015     }
01016 
01017 
01018     filename = cpl_frame_get_filename(slitgeo_frame);
01019 
01020     slitgeo = giraffe_slitgeometry_load(fibers, filename, 1, NULL);
01021 
01022     if (slitgeo == NULL) {
01023         cpl_msg_error(fctid, "Cannot load slit geometry table from '%s'. "
01024                       "Aborting ...", filename);
01025 
01026         giraffe_table_delete(fibers);
01027         giraffe_localization_destroy(localization);
01028         giraffe_extraction_destroy(extraction);
01029         giraffe_table_delete(grating);
01030 
01031         return 1;
01032     }
01033     else {
01034 
01035         /*
01036          * Check whether the contains the positions for all fibers
01037          * provided by the fiber setup. If this is not the case
01038          * this is an error.
01039          */
01040 
01041         if (giraffe_fiberlist_compare(slitgeo, fibers) != 1) {
01042             cpl_msg_error(fctid, "Slit geometry data from '%s' is not "
01043                     "applicable for current fiber setup! "
01044                             "Aborting ...", filename);
01045 
01046             giraffe_table_delete(slitgeo);
01047             giraffe_table_delete(fibers);
01048             giraffe_localization_destroy(localization);
01049             giraffe_extraction_destroy(extraction);
01050             giraffe_table_delete(grating);
01051 
01052             return 1;
01053         }
01054 
01055     }
01056 
01057 
01058     filename = cpl_frame_get_filename(lines_frame);
01059     status = 0;
01060 
01061     wavelengths = giraffe_table_new();
01062     status = giraffe_table_load(wavelengths, filename, 1, NULL);
01063 
01064     if (status) {
01065         cpl_msg_error(fctid, "Cannot load arc-line data from '%s'. "
01066                       "Aborting ...", filename);
01067 
01068         giraffe_table_delete(fibers);
01069         giraffe_localization_destroy(localization);
01070         giraffe_extraction_destroy(extraction);
01071         giraffe_table_delete(grating);
01072         giraffe_table_delete(slitgeo);
01073 
01074         return 1;
01075 
01076     }
01077 
01078     if (wcal_frame != NULL) {
01079 
01080         wcal_initial = giraffe_table_new();
01081 
01082         filename = cpl_frame_get_filename(wcal_frame);
01083         status = giraffe_table_load(wcal_initial, filename, 1, NULL);
01084 
01085         if (status) {
01086             cpl_msg_error(fctid, "Cannot load initial wavelength solution "
01087                           "from '%s'. Aborting ...", filename);
01088 
01089             giraffe_table_delete(wcal_initial);
01090 
01091             giraffe_table_delete(fibers);
01092             giraffe_localization_destroy(localization);
01093             giraffe_extraction_destroy(extraction);
01094             giraffe_table_delete(grating);
01095             giraffe_table_delete(slitgeo);
01096 
01097             return 1;
01098 
01099         }
01100 
01101     }
01102 
01103     wcal_config = giraffe_wlcalibration_config_create(config);
01104     cx_assert(wcal_config != NULL);
01105 
01106     wlsolution = giraffe_wcaldata_new();
01107 
01108     status = giraffe_calibrate_wavelength(wlsolution, extraction,
01109                                           localization, fibers, slitgeo,
01110                                           grating, wavelengths, wcal_initial,
01111                                           wcal_config);
01112 
01113     if (status) {
01114         cpl_msg_error(fctid, "Error during wavelength calibration, "
01115                              "aborting...");
01116 
01117         giraffe_table_delete(fibers);
01118         giraffe_localization_destroy(localization);
01119         giraffe_extraction_destroy(extraction);
01120         giraffe_table_delete(grating);
01121         giraffe_table_delete(slitgeo);
01122         giraffe_table_delete(wavelengths);
01123         giraffe_table_delete(wcal_initial);
01124 
01125         giraffe_wcaldata_delete(wlsolution);
01126         giraffe_wlcalibration_config_destroy(wcal_config);
01127 
01128         return 1;
01129 
01130     }
01131 
01132     giraffe_wlcalibration_config_destroy(wcal_config);
01133     wcal_config = NULL;
01134 
01135     giraffe_table_delete(wcal_initial);
01136     wcal_initial = NULL;
01137 
01138     giraffe_table_delete(wavelengths);
01139     wavelengths = NULL;
01140 
01141 
01142     /*
01143      * Save and register the wavelength calibration results.
01144      */
01145 
01146     /* Coefficients of the x-residuals fit */
01147 
01148     giraffe_table_add_info(wlsolution->coeffs, &info, set);
01149 
01150     wcal_frame = giraffe_frame_create_table(wlsolution->coeffs,
01151                                             GIFRAME_WAVELENGTH_SOLUTION,
01152                                             CPL_FRAME_LEVEL_FINAL,
01153                                             TRUE, TRUE);
01154 
01155     if (wcal_frame == NULL) {
01156 
01157         cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
01158 
01159         giraffe_table_delete(fibers);
01160         giraffe_localization_destroy(localization);
01161         giraffe_extraction_destroy(extraction);
01162         giraffe_table_delete(grating);
01163         giraffe_table_delete(slitgeo);
01164 
01165         giraffe_wcaldata_delete(wlsolution);
01166 
01167         return 1;
01168 
01169     }
01170 
01171     cpl_frameset_insert(set, wcal_frame);
01172 
01173     /* Lines data */
01174 
01175     properties = giraffe_table_get_properties(wlsolution->coeffs);
01176     creator = (GiFrameCreator)giraffe_linedata_writer;
01177 
01178     ldata_frame = giraffe_frame_create(GIFRAME_LINE_DATA,
01179                                        CPL_FRAME_LEVEL_FINAL,
01180                                        properties, wlsolution->linedata,
01181                                        NULL,
01182                                        creator);
01183 
01184     if (ldata_frame == NULL) {
01185 
01186         cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
01187 
01188         giraffe_table_delete(fibers);
01189         giraffe_localization_destroy(localization);
01190         giraffe_extraction_destroy(extraction);
01191         giraffe_table_delete(grating);
01192         giraffe_table_delete(slitgeo);
01193 
01194         giraffe_wcaldata_delete(wlsolution);
01195 
01196         properties = NULL;
01197 
01198         return 1;
01199 
01200     }
01201 
01202     properties = NULL;
01203 
01204     giraffe_linedata_delete(wlsolution->linedata);
01205     wlsolution->linedata = NULL;
01206 
01207     cpl_frameset_insert(set, ldata_frame);
01208 
01209 
01210     /*
01211      * Optional slit geometry calibration. Note that this step requires a
01212      * rebinned arc-lamp frame as input!
01213      */
01214 
01215     if (slitgeometry == TRUE) {
01216 
01217         cpl_frame* slit_frame = NULL;
01218 
01219         GiSGCalConfig* scal_config = NULL;
01220 
01221         GiTable* mask = NULL;
01222         GiTable* slit = NULL;
01223 
01224 
01225         cpl_msg_info(fctid, "Calibrating slit geometry ...");
01226 
01227         scal_config = giraffe_sgcalibration_config_create(config);
01228 
01229 
01230         filename = cpl_frame_get_filename(scal_frame);
01231 
01232         mask = giraffe_table_new();
01233         status = giraffe_table_load(mask, filename, 1, NULL);
01234 
01235         if (status != 0) {
01236             cpl_msg_error(fctid, "Cannot load slit geometry mask from '%s'. "
01237                           "Aborting ...", filename);
01238 
01239             giraffe_sgcalibration_config_destroy(scal_config);
01240 
01241             giraffe_table_delete(mask);
01242 
01243             giraffe_wcaldata_delete(wlsolution);
01244 
01245             giraffe_localization_destroy(localization);
01246             giraffe_extraction_destroy(extraction);
01247 
01248             giraffe_table_delete(fibers);
01249             giraffe_table_delete(grating);
01250             giraffe_table_delete(slitgeo);
01251 
01252             return 1;
01253 
01254         }
01255 
01256         slit = giraffe_table_new();
01257 
01258         status = giraffe_calibrate_slit(slit, extraction, localization, fibers,
01259                                         wlsolution->coeffs, slitgeo, grating,
01260                                         mask, scal_config);
01261 
01262         if (status != 0) {
01263             cpl_msg_error(fctid, "Slit geometry calibration failed! "
01264                           "Aborting ...");
01265 
01266             giraffe_sgcalibration_config_destroy(scal_config);
01267 
01268             giraffe_table_delete(slit);
01269             giraffe_table_delete(mask);
01270 
01271             giraffe_wcaldata_delete(wlsolution);
01272 
01273             giraffe_localization_destroy(localization);
01274             giraffe_extraction_destroy(extraction);
01275 
01276             giraffe_table_delete(fibers);
01277             giraffe_table_delete(grating);
01278             giraffe_table_delete(slitgeo);
01279 
01280             return 1;
01281 
01282         }
01283 
01284 
01285         /*
01286          * Save and register the slit geometry calibration results.
01287          */
01288 
01289 
01290         giraffe_table_add_info(slit, &info, set);
01291 
01292         slit_frame = giraffe_slitgeometry_save(slit);
01293 
01294         if (!slit_frame) {
01295 
01296             cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
01297 
01298             giraffe_sgcalibration_config_destroy(scal_config);
01299 
01300             giraffe_table_delete(slit);
01301             giraffe_table_delete(mask);
01302 
01303             giraffe_wcaldata_delete(wlsolution);
01304 
01305             giraffe_localization_destroy(localization);
01306             giraffe_extraction_destroy(extraction);
01307 
01308             giraffe_table_delete(fibers);
01309             giraffe_table_delete(grating);
01310             giraffe_table_delete(slitgeo);
01311 
01312             return 1;
01313         }
01314 
01315         cpl_frameset_insert(set, slit_frame);
01316 
01317         giraffe_table_delete(mask);
01318         giraffe_sgcalibration_config_destroy(scal_config);
01319 
01320 
01321         /*
01322          * Replace the slit geometry table with the new one.
01323          */
01324 
01325         giraffe_table_delete(slitgeo);
01326         slitgeo = slit;
01327 
01328     }
01329 
01330 
01331     /*
01332      * Optional rebinning of the previously extracted arc-lamp spectra.
01333      */
01334 
01335     if (rebin == TRUE) {
01336 
01337         cpl_frame* rbin_frame = NULL;
01338 
01339         GiRebinConfig* rebin_config;
01340 
01341 
01342         cpl_msg_info(fctid, "Recipe Step : Spectrum Rebinning");
01343 
01344         rebin_config = giraffe_rebin_config_create(config);
01345 
01346         rebinning = giraffe_rebinning_new();
01347 
01348         status = giraffe_rebin_spectra(rebinning, extraction, fibers,
01349                                        localization, grating, slitgeo,
01350                                        wlsolution->coeffs, rebin_config);
01351 
01352         if (status) {
01353             cpl_msg_error(fctid, "Rebinning of arc-lamp spectra failed! "
01354                           "Aborting...");
01355 
01356             giraffe_wcaldata_delete(wlsolution);
01357 
01358             giraffe_rebinning_destroy(rebinning);
01359             giraffe_localization_destroy(localization);
01360             giraffe_extraction_destroy(extraction);
01361 
01362             giraffe_table_delete(grating);
01363             giraffe_table_delete(slitgeo);
01364             giraffe_table_delete(fibers);
01365 
01366             giraffe_rebin_config_destroy(rebin_config);
01367 
01368             return 1;
01369 
01370         }
01371 
01372         giraffe_rebin_config_destroy(rebin_config);
01373 
01374         /*
01375          * Save and register the results of the spectrum rebinning.
01376          */
01377 
01378         /* Rebinned spectra */
01379 
01380         giraffe_image_add_info(rebinning->spectra, &info, set);
01381 
01382         rbin_frame = giraffe_frame_create_image(rebinning->spectra,
01383                                                 GIFRAME_ARC_LAMP_RBNSPECTRA,
01384                                                 CPL_FRAME_LEVEL_FINAL,
01385                                                 TRUE, TRUE);
01386 
01387         if (rbin_frame == NULL) {
01388 
01389             cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
01390 
01391             giraffe_wcaldata_delete(wlsolution);
01392 
01393             giraffe_rebinning_destroy(rebinning);
01394             giraffe_localization_destroy(localization);
01395             giraffe_extraction_destroy(extraction);
01396 
01397             giraffe_table_delete(grating);
01398             giraffe_table_delete(slitgeo);
01399             giraffe_table_delete(fibers);
01400 
01401             return 1;
01402 
01403         }
01404 
01405         status = giraffe_fiberlist_attach(rbin_frame, fibers);
01406 
01407         if (status) {
01408             cpl_msg_error(fctid, "Cannot attach fiber setup to local "
01409                           "file '%s'! Aborting ...",
01410                           cpl_frame_get_filename(rbin_frame));
01411 
01412             giraffe_wcaldata_delete(wlsolution);
01413 
01414             giraffe_rebinning_destroy(rebinning);
01415             giraffe_localization_destroy(localization);
01416             giraffe_extraction_destroy(extraction);
01417 
01418             giraffe_table_delete(grating);
01419             giraffe_table_delete(slitgeo);
01420             giraffe_table_delete(fibers);
01421 
01422             cpl_frame_delete(rbin_frame);
01423 
01424             return 1;
01425 
01426         }
01427 
01428         cpl_frameset_insert(set, rbin_frame);
01429 
01430         /* Rebinned spectra errors */
01431 
01432         giraffe_image_add_info(rebinning->errors, &info, set);
01433 
01434         rbin_frame = giraffe_frame_create_image(rebinning->errors,
01435                                                 GIFRAME_ARC_LAMP_RBNERRORS,
01436                                                 CPL_FRAME_LEVEL_FINAL,
01437                                                 TRUE, TRUE);
01438 
01439         if (rbin_frame == NULL) {
01440 
01441             cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
01442 
01443             giraffe_wcaldata_delete(wlsolution);
01444 
01445             giraffe_rebinning_destroy(rebinning);
01446             giraffe_localization_destroy(localization);
01447             giraffe_extraction_destroy(extraction);
01448 
01449             giraffe_table_delete(grating);
01450             giraffe_table_delete(slitgeo);
01451             giraffe_table_delete(fibers);
01452 
01453             return 1;
01454 
01455         }
01456 
01457         status = giraffe_fiberlist_attach(rbin_frame, fibers);
01458 
01459         if (status) {
01460 
01461             cpl_msg_error(fctid, "Cannot attach fiber setup to local "
01462                           "file '%s'! Aborting ...",
01463                           cpl_frame_get_filename(rbin_frame));
01464 
01465             giraffe_wcaldata_delete(wlsolution);
01466 
01467             giraffe_rebinning_destroy(rebinning);
01468             giraffe_localization_destroy(localization);
01469             giraffe_extraction_destroy(extraction);
01470 
01471             giraffe_table_delete(grating);
01472             giraffe_table_delete(slitgeo);
01473             giraffe_table_delete(fibers);
01474 
01475             cpl_frame_delete(rbin_frame);
01476 
01477             return 1;
01478 
01479         }
01480 
01481         cpl_frameset_insert(set, rbin_frame);
01482 
01483     }
01484 
01485 
01486     /*
01487      * Postprocessing
01488      */
01489 
01490     giraffe_table_delete(fibers);
01491     fibers = NULL;
01492 
01493     giraffe_localization_destroy(localization);
01494     localization = NULL;
01495 
01496     giraffe_extraction_destroy(extraction);
01497     extraction = NULL;
01498 
01499     if (rebinning != NULL) {
01500         giraffe_rebinning_destroy(rebinning);
01501         rebinning = NULL;
01502     }
01503 
01504     giraffe_table_delete(grating);
01505     grating = NULL;
01506 
01507     giraffe_table_delete(slitgeo);
01508     slitgeo = NULL;
01509 
01510     giraffe_wcaldata_delete(wlsolution);
01511     wlsolution = NULL;
01512 
01513     return 0;
01514 
01515 }
01516 
01517 
01518 static cxint
01519 giqcwavecalibration(cpl_frameset* set)
01520 {
01521 
01522     const cxchar* const fctid = "giqcwavecalibration";
01523 
01524 
01525     cxint i = 0;
01526     cxint j = 0;
01527     cxint nx = 0;
01528     cxint ny = 0;
01529     cxint npixel = 0;
01530     cxint nsaturated = 0;
01531     cxint status = 0;
01532 
01533     const cxdouble saturation = 60000.;
01534     const cxdouble* pixels = NULL;
01535 
01536     cxdouble efficiency[2] = {0., 0.};
01537     cxdouble wlcenter = 0.;
01538     cxdouble mean = 0.;
01539     cxdouble rms = 0.;
01540     cxdouble pixel2nm = 1.;
01541     cxdouble fwhm_domain[2] = {0., 100.};
01542     cxdouble* _tdata = NULL;
01543 
01544     cpl_propertylist* properties = NULL;
01545     cpl_propertylist* qclog = NULL;
01546 
01547     cpl_frame* rframe = NULL;
01548     cpl_frame* pframe = NULL;
01549 
01550     const cpl_image* _rimage = NULL;
01551     const cpl_image* _pimage = NULL;
01552 
01553     cpl_image* _test = NULL;
01554     cpl_image* _test0 = NULL;
01555     cpl_image* _test1 = NULL;
01556 
01557     cpl_table* _ptable = NULL;
01558 
01559     GiImage* rimage = NULL;
01560     GiImage* pimage = NULL;
01561 
01562     GiTable* ptable = NULL;
01563 
01564     GiLineData* plines = NULL;
01565 
01566     GiPaf* qc = NULL;
01567 
01568     GiWindow w;
01569 
01570 
01571 
01572     cpl_msg_info(fctid, "Computing QC1 parameters ...");
01573 
01574 
01575     /*
01576      * Compute lamp efficiencies from the rebinned frame if
01577      * it is available. If not the efficiencies are set to 0.
01578      */
01579 
01580     pframe = giraffe_get_frame(set, GIFRAME_ARC_LAMP_EXTSPECTRA,
01581                                CPL_FRAME_GROUP_PRODUCT);
01582 
01583     if (pframe == NULL) {
01584 
01585         cpl_msg_warning(fctid, "Product '%s' not found.",
01586                         GIFRAME_ARC_LAMP_EXTSPECTRA);
01587 
01588         cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
01589                         GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
01590 
01591         efficiency[0] = 0.;
01592         efficiency[1] = 0.;
01593 
01594     }
01595 
01596 
01597     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
01598     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
01599 
01600     if (status != 0) {
01601         cpl_msg_error(fctid, "Could not load extracted spectra '%s'!",
01602                       cpl_frame_get_filename(pframe));
01603 
01604         giraffe_image_delete(pimage);
01605         pimage = NULL;
01606 
01607         giraffe_paf_delete(qc);
01608         qc = NULL;
01609 
01610         return 1;
01611     }
01612 
01613     _pimage = giraffe_image_get(pimage);
01614     cx_assert(_pimage != NULL);
01615 
01616 
01617     ptable = giraffe_table_new();
01618     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
01619                                 NULL);
01620 
01621     if (status != 0) {
01622         cpl_msg_error(fctid, "Could not load extracted spectra fiber setup!");
01623 
01624         giraffe_table_delete(ptable);
01625         ptable = NULL;
01626 
01627         giraffe_image_delete(pimage);
01628         pimage = NULL;
01629 
01630         giraffe_paf_delete(qc);
01631         qc = NULL;
01632 
01633         return 1;
01634     }
01635 
01636     _ptable = giraffe_table_get(ptable);
01637     cx_assert(_ptable != NULL);
01638 
01639     if (cpl_table_has_column(_ptable, "RP") == FALSE) {
01640 
01641         cpl_msg_warning(fctid, "Column 'RP' not found in fiber setup table!");
01642         cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
01643                         GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
01644 
01645         efficiency[0] = 0.;
01646         efficiency[1] = 0.;
01647 
01648     }
01649     else {
01650 
01651         properties = giraffe_image_get_properties(pimage);
01652         cx_assert(properties != NULL);
01653 
01654         if (cpl_propertylist_has(properties, GIALIAS_EXPTIME) == FALSE) {
01655 
01656             cpl_msg_warning(fctid, "Property '%s' not found in '%s'.",
01657                             GIALIAS_EXPTIME, cpl_frame_get_filename(rframe));
01658             cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
01659                             GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
01660 
01661             efficiency[0] = 0.;
01662             efficiency[1] = 0.;
01663 
01664         }
01665         else {
01666 
01667             cxint fiber = 0;
01668             cxint nb = cpl_image_get_size_y(_pimage);
01669             cxint nf[2] = {0, 0};
01670 
01671             cxdouble exptime = cpl_propertylist_get_double(properties,
01672                 GIALIAS_EXPTIME);
01673             cxdouble* _sum = NULL;
01674 
01675             cpl_image* sum = NULL;
01676 
01677 
01678             sum = cpl_image_collapse_create(_pimage, 0);
01679             _sum = cpl_image_get_data_double(sum);
01680 
01681             for (fiber = 0; fiber < cpl_table_get_nrow(_ptable); ++fiber) {
01682 
01683                 cxint rp = cpl_table_get_int(_ptable, "RP", fiber, NULL);
01684 
01685                 if (rp == -1) {
01686                     efficiency[1] += _sum[fiber];
01687                     ++nf[1];
01688                 }
01689                 else {
01690                     efficiency[0] += _sum[fiber];
01691                     ++nf[0];
01692                 }
01693 
01694             }
01695 
01696             _sum = NULL;
01697 
01698             cpl_image_delete(sum);
01699             sum = NULL;
01700 
01701             if (nf[0] == 0) {
01702                 cpl_msg_warning(fctid, "No OzPoz fibers found in the "
01703                         "current fiber setup.");
01704                 cpl_msg_warning(fctid, "Setting lamp efficiency (%s) to 0.",
01705                         GIALIAS_QCLAMP);
01706                 efficiency[0] = 0.;
01707             }
01708             else {
01709                 efficiency[0] /= nf[0] * nb * exptime;
01710             }
01711 
01712             if (nf[1] == 0) {
01713                 cpl_msg_warning(fctid, "No simultaneous calibration fibers "
01714                         "found in the current fiber setup.");
01715                 cpl_msg_warning(fctid, "Setting lamp efficiency (%s) to 0.",
01716                         GIALIAS_QCLAMP_SIMCAL);
01717                 efficiency[1] = 0.;
01718             }
01719             else {
01720                 efficiency[1] /= nf[1] * nb * exptime;
01721             }
01722 
01723         }
01724 
01725         properties = NULL;
01726 
01727     }
01728 
01729     _ptable = NULL;
01730     _pimage = NULL;
01731 
01732     giraffe_table_delete(ptable);
01733     ptable = NULL;
01734 
01735     giraffe_image_delete(pimage);
01736     pimage = NULL;
01737 
01738 
01739     /*
01740      * Load first raw image as reference
01741      */
01742 
01743     rframe = cpl_frameset_find(set, GIFRAME_ARC_SPECTRUM);
01744 
01745     if (rframe == NULL) {
01746         cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_ARC_SPECTRUM);
01747 
01748         giraffe_paf_delete(qc);
01749         qc = NULL;
01750 
01751         return 1;
01752     }
01753 
01754     cpl_msg_info(fctid, "Processing reference frame '%s' (%s)",
01755                  cpl_frame_get_filename(rframe), cpl_frame_get_tag(rframe));
01756 
01757     rimage = giraffe_image_new(CPL_TYPE_DOUBLE);
01758     status = giraffe_image_load(rimage, cpl_frame_get_filename(rframe), 0);
01759 
01760     if (status != 0) {
01761 
01762         cpl_msg_error(fctid, "Could not load arc-lamp spectra '%s'!",
01763                       cpl_frame_get_filename(rframe));
01764 
01765         giraffe_image_delete(rimage);
01766         rimage = NULL;
01767 
01768         giraffe_paf_delete(qc);
01769         qc = NULL;
01770 
01771         return 1;
01772 
01773     }
01774 
01775     _rimage = giraffe_image_get(rimage);
01776     cx_assert(_rimage != NULL);
01777 
01778 
01779     /*
01780      * Compute mean level of the first raw frame and count the number
01781      * of saturated pixels.
01782      */
01783 
01784     properties = giraffe_image_get_properties(rimage);
01785     cx_assert(properties != NULL);
01786 
01787     if (cpl_propertylist_has(properties, GIALIAS_OVSCX)) {
01788 
01789         cxint _ox = cpl_propertylist_get_int(properties, GIALIAS_OVSCX);
01790         cxint _nx = cpl_image_get_size_x(_rimage) - 2 * CX_MAX(0, _ox) - 1;
01791 
01792         w.x0 = CX_MAX(0, _ox) + 1;
01793         w.x1 = w.x0 + _nx;
01794 
01795     }
01796 
01797     if (cpl_propertylist_has(properties, GIALIAS_OVSCY)) {
01798 
01799         cxint _oy = cpl_propertylist_get_int(properties, GIALIAS_OVSCY);
01800         cxint _ny = cpl_image_get_size_y(_rimage) - 2 * CX_MAX(0, _oy) - 1;
01801 
01802         w.y0 = CX_MAX(0, _oy) + 1;
01803         w.y1 = w.y0 + _ny;
01804 
01805     }
01806 
01807     mean = cpl_image_get_mean_window(_rimage, w.x0, w.y0, w.x1, w.y1);
01808 
01809     pixels = cpl_image_get_data_const(_rimage);
01810     npixel = cpl_image_get_size_x(_rimage) * cpl_image_get_size_y(_rimage);
01811 
01812     for (i = 0; i < npixel; i++) {
01813         if (pixels[i] > saturation) {
01814             ++nsaturated;
01815         }
01816     }
01817 
01818 
01819     /*
01820      * Process dispersion solution
01821      */
01822 
01823     qc = giraffe_qclog_open(0);
01824 
01825     if (qc == NULL) {
01826         cpl_msg_error(fctid, "Cannot create QC1 log!");
01827 
01828         giraffe_image_delete(rimage);
01829         rimage = NULL;
01830 
01831         return 1;
01832     }
01833 
01834     qclog = giraffe_paf_get_properties(qc);
01835     cx_assert(qclog != NULL);
01836 
01837     pframe = giraffe_get_frame(set, GIFRAME_WAVELENGTH_SOLUTION,
01838                                CPL_FRAME_GROUP_PRODUCT);
01839 
01840     if (pframe == NULL) {
01841         cpl_msg_error(fctid, "Missing product frame (%s)",
01842                       GIFRAME_WAVELENGTH_SOLUTION);
01843 
01844         giraffe_paf_delete(qc);
01845         qc = NULL;
01846 
01847         giraffe_image_delete(rimage);
01848         rimage = NULL;
01849 
01850         return 1;
01851     }
01852 
01853     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
01854                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
01855 
01856     ptable = giraffe_table_new();
01857     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
01858                                 NULL);
01859 
01860     if (status != 0) {
01861         cpl_msg_error(fctid, "Could not load dispersion solution '%s'!",
01862                       cpl_frame_get_filename(pframe));
01863 
01864         giraffe_table_delete(ptable);
01865         ptable = NULL;
01866 
01867         giraffe_image_delete(rimage);
01868         rimage = NULL;
01869 
01870         giraffe_paf_delete(qc);
01871         qc = NULL;
01872 
01873         return 1;
01874     }
01875 
01876     properties = giraffe_image_get_properties(rimage);
01877     cx_assert(properties != NULL);
01878 
01879     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
01880     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
01881     giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
01882                               GIALIAS_SETUPNAME);
01883     giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
01884                               GIALIAS_SLITNAME);
01885     giraffe_propertylist_copy(qclog, "INS.GRAT.NAME", properties,
01886                               GIALIAS_GRATNAME);
01887     giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
01888                               GIALIAS_GRATWLEN);
01889 
01890     cpl_propertylist_update_string(qclog, "PRO.CATG",
01891                                    cpl_frame_get_tag(pframe));
01892     cpl_propertylist_set_comment(qclog, "PRO.CATG",
01893                                  "Pipeline product category");
01894 
01895     properties = giraffe_table_get_properties(ptable);
01896     cx_assert(properties != NULL);
01897 
01898     giraffe_propertylist_copy(qclog, "PRO.WSOL.RMS", properties,
01899                               GIALIAS_WSOL_RMS);
01900     giraffe_propertylist_copy(qclog, "PRO.WSOL.NLINES", properties,
01901                        GIALIAS_WSOL_NLINES);
01902     giraffe_propertylist_copy(qclog, "PRO.WSOL.NACCEPT", properties,
01903                        GIALIAS_WSOL_NACCEPT);
01904     giraffe_propertylist_copy(qclog, "PRO.WSOL.NREJECT", properties,
01905                        GIALIAS_WSOL_NREJECT);
01906     giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
01907                               GIALIAS_NFIBERS);
01908 
01909 
01910     giraffe_table_delete(ptable);
01911     ptable = NULL;
01912 
01913     giraffe_qclog_close(qc);
01914     qc = NULL;
01915 
01916 
01917     /*
01918      * Process rebinned arc-lamp spectrum
01919      */
01920 
01921     qc = giraffe_qclog_open(1);
01922 
01923     if (qc == NULL) {
01924         cpl_msg_error(fctid, "Cannot create QC1 log!");
01925         return 1;
01926     }
01927 
01928     qclog = giraffe_paf_get_properties(qc);
01929     cx_assert(qclog != NULL);
01930 
01931     pframe = giraffe_get_frame(set, GIFRAME_ARC_LAMP_RBNSPECTRA,
01932                                CPL_FRAME_GROUP_PRODUCT);
01933 
01934     if (pframe == NULL) {
01935         cpl_msg_error(fctid, "Missing product frame (%s)",
01936                       GIFRAME_ARC_LAMP_RBNSPECTRA);
01937 
01938         giraffe_image_delete(rimage);
01939         rimage = NULL;
01940 
01941         giraffe_paf_delete(qc);
01942         qc = NULL;
01943 
01944         return 1;
01945     }
01946 
01947     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
01948                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
01949 
01950     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
01951     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
01952 
01953     if (status != 0) {
01954         cpl_msg_error(fctid, "Could not load rebinned arc-lamp spectra '%s'!",
01955                       cpl_frame_get_filename(pframe));
01956 
01957         giraffe_image_delete(pimage);
01958         pimage = NULL;
01959 
01960         giraffe_image_delete(rimage);
01961         rimage = NULL;
01962 
01963         giraffe_paf_delete(qc);
01964         qc = NULL;
01965 
01966         return 1;
01967     }
01968 
01969     ptable = giraffe_table_new();
01970     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
01971                                 NULL);
01972 
01973     if (status != 0) {
01974         cpl_msg_error(fctid, "Could not load rebinned arc-lamp spectra '%s'!",
01975                       cpl_frame_get_filename(pframe));
01976 
01977         giraffe_table_delete(ptable);
01978         ptable = NULL;
01979 
01980         giraffe_image_delete(pimage);
01981         pimage = NULL;
01982 
01983         giraffe_image_delete(rimage);
01984         rimage = NULL;
01985 
01986         giraffe_paf_delete(qc);
01987         qc = NULL;
01988 
01989         return 1;
01990     }
01991 
01992     properties = giraffe_image_get_properties(rimage);
01993     cx_assert(properties != NULL);
01994 
01995     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
01996     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
01997     giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
01998                               GIALIAS_SETUPNAME);
01999     giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
02000                               GIALIAS_SLITNAME);
02001     giraffe_propertylist_copy(qclog, "INS.GRAT.NAME", properties,
02002                               GIALIAS_GRATNAME);
02003     giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
02004                               GIALIAS_GRATWLEN);
02005 
02006     cpl_propertylist_update_string(qclog, "PRO.CATG",
02007                                    cpl_frame_get_tag(pframe));
02008     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02009                                  "Pipeline product category");
02010 
02011     properties = giraffe_image_get_properties(pimage);
02012     cx_assert(properties != NULL);
02013 
02014     giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
02015                               GIALIAS_DATAMEAN);
02016     giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
02017                               GIALIAS_DATASIG);
02018     giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
02019                               GIALIAS_DATAMEDI);
02020     giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
02021                               GIALIAS_NFIBERS);
02022 
02023 
02024     cpl_propertylist_update_double(properties, GIALIAS_QCMEAN, mean);
02025     cpl_propertylist_set_comment(properties, GIALIAS_QCMEAN, "Mean level of "
02026                           "first raw frame");
02027 
02028     giraffe_propertylist_copy(qclog, "QC.OUT1.MEAN.RAW", properties,
02029                        GIALIAS_QCMEAN);
02030 
02031 
02032     cpl_propertylist_update_int(properties, GIALIAS_QCNSAT, nsaturated);
02033     cpl_propertylist_set_comment(properties, GIALIAS_QCNSAT, "Number of "
02034                           "saturated pixels in the first raw frame");
02035 
02036     giraffe_propertylist_copy(qclog, "QC.OUT1.NSAT.RAW", properties,
02037                        GIALIAS_QCNSAT);
02038 
02039 
02040     /*
02041      * Calibration lamp monitoring
02042      */
02043 
02044     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
02045     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
02046                                  "Calibration lamp efficiency");
02047 
02048     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
02049                               GIALIAS_QCLAMP);
02050 
02051     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
02052                                    efficiency[1]);
02053     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
02054                                  "SIMCAL lamp efficiency");
02055 
02056     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
02057                               GIALIAS_QCLAMP_SIMCAL);
02058 
02059 
02060     /* Compute rebinned emission line straightness. */
02061 
02062     _pimage = giraffe_image_get(pimage);
02063 
02064     _test = cpl_image_duplicate(_pimage);
02065     _tdata = cpl_image_get_data(_test);
02066 
02067     nx = cpl_image_get_size_x(_test);
02068     ny = cpl_image_get_size_y(_test);
02069 
02070     for (i = 0; i < nx * ny; i++) {
02071         _tdata[i] = _tdata[i] > 0. ? log(_tdata[i]) : 0.;
02072     }
02073 
02074     _tdata = NULL;
02075 
02076     _test0 = cpl_image_extract(_test, 4, 1, 4, ny);
02077 
02078     _test1 = cpl_image_collapse_create(_test, 1);
02079     cpl_image_divide_scalar(_test1, nx);
02080 
02081     cpl_image_delete(_test);
02082     _test = NULL;
02083 
02084 
02085     _test = cpl_image_subtract_create(_test0, _test1);
02086 
02087     cpl_image_delete(_test0);
02088     _test0 = NULL;
02089 
02090     cpl_image_delete(_test1);
02091     _test1 = NULL;
02092 
02093 
02094     _tdata = cpl_image_get_data(_test);
02095 
02096     rms = 0;
02097 
02098     for (i = 0; i < ny; i++) {
02099         _tdata[i] = exp(_tdata[i]);
02100         rms += pow(_tdata[i], 2.);
02101     }
02102 
02103     rms = sqrt(rms / (ny - 1));
02104 
02105     cpl_image_delete(_test);
02106     _test = NULL;
02107 
02108     cpl_propertylist_update_double(properties, GIALIAS_QCRBRMS, rms);
02109     cpl_propertylist_set_comment(properties, GIALIAS_QCRBRMS,
02110                                  "RMS of rebinned arc-lamp spectra");
02111 
02112     giraffe_propertylist_copy(qclog, "QC.WSOL.REBIN.RMS", properties,
02113                        GIALIAS_QCRBRMS);
02114 
02115 
02116     status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
02117 
02118     if (status != 0) {
02119         cpl_msg_error(fctid, "Could not save rebinned arc-lamp spectra "
02120                       "'%s'!", cpl_frame_get_filename(pframe));
02121 
02122         giraffe_table_delete(ptable);
02123         ptable = NULL;
02124 
02125         giraffe_image_delete(pimage);
02126         pimage = NULL;
02127 
02128         giraffe_image_delete(rimage);
02129         rimage = NULL;
02130 
02131         giraffe_paf_delete(qc);
02132         qc = NULL;
02133 
02134         return 1;
02135     }
02136 
02137     status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
02138                                   1, NULL);
02139 
02140     if (status != 0) {
02141         cpl_msg_error(fctid, "Could not save rebinned arc-lamp spectra "
02142                       "'%s'!", cpl_frame_get_filename(pframe));
02143 
02144         giraffe_table_delete(ptable);
02145         ptable = NULL;
02146 
02147         giraffe_image_delete(pimage);
02148         pimage = NULL;
02149 
02150         giraffe_image_delete(rimage);
02151         rimage = NULL;
02152 
02153         giraffe_paf_delete(qc);
02154         qc = NULL;
02155 
02156         return 1;
02157     }
02158 
02159     giraffe_image_delete(pimage);
02160     pimage = NULL;
02161 
02162     giraffe_table_delete(ptable);
02163     ptable = NULL;
02164 
02165     giraffe_qclog_close(qc);
02166     qc = NULL;
02167 
02168 
02169     /*
02170      * Process line data
02171      */
02172 
02173     qc = giraffe_qclog_open(2);
02174 
02175     if (qc == NULL) {
02176         cpl_msg_error(fctid, "Cannot create QC1 log!");
02177         return 1;
02178     }
02179 
02180     qclog = giraffe_paf_get_properties(qc);
02181     cx_assert(qclog != NULL);
02182 
02183     pframe = giraffe_get_frame(set, GIFRAME_LINE_DATA,
02184                                CPL_FRAME_GROUP_PRODUCT);
02185 
02186     if (pframe == NULL) {
02187         cpl_msg_error(fctid, "Missing product frame (%s)",
02188                       GIFRAME_LINE_DATA);
02189 
02190         giraffe_image_delete(rimage);
02191         rimage = NULL;
02192 
02193         giraffe_paf_delete(qc);
02194         qc = NULL;
02195 
02196         return 1;
02197     }
02198 
02199     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
02200                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
02201 
02202 
02203     /*
02204      * Load line data
02205      */
02206 
02207     plines = giraffe_linedata_new();
02208 
02209     status = giraffe_linedata_load(plines, cpl_frame_get_filename(pframe));
02210 
02211     if (status != 0) {
02212         cpl_msg_error(fctid, "Could not load line data '%s'!",
02213                       cpl_frame_get_filename(pframe));
02214 
02215         giraffe_linedata_delete(plines);
02216         plines = NULL;
02217 
02218         giraffe_image_delete(rimage);
02219         rimage = NULL;
02220 
02221         giraffe_paf_delete(qc);
02222         qc = NULL;
02223 
02224         return 1;
02225     }
02226 
02227     properties = giraffe_image_get_properties(rimage);
02228     cx_assert(properties != NULL);
02229 
02230     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
02231     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
02232     giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
02233                               GIALIAS_SETUPNAME);
02234     giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
02235                               GIALIAS_SLITNAME);
02236     giraffe_propertylist_copy(qclog, "INS.GRAT.NAME", properties,
02237                               GIALIAS_GRATNAME);
02238     giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
02239                               GIALIAS_GRATWLEN);
02240 
02241     cpl_propertylist_update_string(qclog, "PRO.CATG",
02242                                    cpl_frame_get_tag(pframe));
02243     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02244                                  "Pipeline product category");
02245 
02246 
02247     _pimage = giraffe_linedata_get_data(plines, "FWHM");
02248 
02249     if (_pimage == NULL) {
02250         cpl_msg_error(fctid, "FWHM line data not found!");
02251 
02252         giraffe_linedata_delete(plines);
02253         plines = NULL;
02254 
02255         giraffe_image_delete(rimage);
02256         rimage = NULL;
02257 
02258         giraffe_paf_delete(qc);
02259         qc = NULL;
02260 
02261         return 1;
02262     }
02263 
02264     nx = cpl_image_get_size_x(_pimage);
02265     ny = cpl_image_get_size_y(_pimage);
02266 
02267     pixels = cpl_image_get_data_const(_pimage);
02268 
02269     for (j = 0; j < 2; ++j) {
02270 
02271         register cxint ndata = nx * ny;
02272 
02273         npixel = 0;
02274         mean = 0.;
02275         rms  = 0.;
02276 
02277         for (i = 0; i < ndata; ++i) {
02278 
02279             if ((pixels[i] >= fwhm_domain[0]) &&
02280                 (pixels[i] < fwhm_domain[1])) {
02281                 mean += pixels[i];
02282                 ++npixel;
02283             }
02284 
02285         }
02286 
02287         if (npixel == 0) {
02288             cpl_msg_error(fctid, "All line FWHM data are invalid!");
02289 
02290             giraffe_linedata_delete(plines);
02291             plines = NULL;
02292 
02293             giraffe_image_delete(rimage);
02294             rimage = NULL;
02295 
02296             giraffe_paf_delete(qc);
02297             qc = NULL;
02298 
02299             return 1;
02300         }
02301 
02302         mean /= npixel;
02303 
02304         for (i = 0; i < ndata; ++i) {
02305 
02306             if ((pixels[i] >= fwhm_domain[0]) &&
02307                 (pixels[i] < fwhm_domain[1])) {
02308                 rms += pow(pixels[i] - mean, 2.);
02309             }
02310 
02311         }
02312 
02313         if (npixel > 1) {
02314             rms = sqrt(rms / (npixel - 1));
02315         }
02316 
02317         fwhm_domain[1] = 10. * rms;
02318 
02319     }
02320 
02321 
02322     properties = cpl_propertylist_load(cpl_frame_get_filename(pframe), 0);
02323     cx_assert(properties != NULL);
02324 
02325     if (cpl_propertylist_has(properties, GIALIAS_GRATWLEN) == FALSE) {
02326         cpl_msg_error(fctid, "Grating central wavelength property '%s' not "
02327                       "found!", GIALIAS_GRATWLEN);
02328 
02329         cpl_propertylist_delete(properties);
02330         properties = NULL;
02331 
02332         giraffe_linedata_delete(plines);
02333         plines = NULL;
02334 
02335         giraffe_image_delete(rimage);
02336         rimage = NULL;
02337 
02338         giraffe_paf_delete(qc);
02339         qc = NULL;
02340 
02341         return 1;
02342     }
02343 
02344     if (cpl_propertylist_has(properties, GIALIAS_WSOL_SCALE) == FALSE) {
02345         cpl_msg_error(fctid, "Line data property '%s' not found!",
02346                       GIALIAS_WSOL_SCALE);
02347 
02348         cpl_propertylist_delete(properties);
02349         properties = NULL;
02350 
02351         giraffe_linedata_delete(plines);
02352         plines = NULL;
02353 
02354         giraffe_image_delete(rimage);
02355         rimage = NULL;
02356 
02357         giraffe_paf_delete(qc);
02358         qc = NULL;
02359 
02360         return 1;
02361     }
02362 
02363     wlcenter = cpl_propertylist_get_double(properties, GIALIAS_GRATWLEN);
02364     pixel2nm = cpl_propertylist_get_double(properties, GIALIAS_WSOL_SCALE);
02365 
02366     mean *= pixel2nm;
02367     rms *= pixel2nm;
02368 
02369     cpl_propertylist_update_double(properties, GIALIAS_QCRESOLAVG, mean);
02370     cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLAVG,
02371                                  "Average line FWHM [nm]");
02372 
02373     cpl_propertylist_update_double(properties, GIALIAS_QCRESOLRMS, rms);
02374     cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLRMS,
02375                                  "RMS of line FWHM [nm]");
02376 
02377     cpl_propertylist_update_double(properties, GIALIAS_QCRESOLPWR,
02378                                    wlcenter / mean);
02379     cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLPWR,
02380                                  "Resolving power");
02381 
02382     giraffe_propertylist_copy(qclog, "QC.RESOL.MEAN", properties,
02383                               GIALIAS_QCRESOLAVG);
02384     giraffe_propertylist_copy(qclog, "QC.RESOL.RMS", properties,
02385                               GIALIAS_QCRESOLRMS);
02386     giraffe_propertylist_copy(qclog, "QC.RESOL.POWER", properties,
02387                               GIALIAS_QCRESOLPWR);
02388 
02389 
02390     status = giraffe_linedata_save(plines, properties,
02391                                    cpl_frame_get_filename(pframe));
02392 
02393     if (status != 0) {
02394         cpl_msg_error(fctid, "Could not save line data "
02395                       "'%s'!", cpl_frame_get_filename(pframe));
02396 
02397         cpl_propertylist_delete(properties);
02398         properties = NULL;
02399 
02400         giraffe_linedata_delete(plines);
02401         plines = NULL;
02402 
02403         giraffe_image_delete(rimage);
02404         rimage = NULL;
02405 
02406         giraffe_paf_delete(qc);
02407         qc = NULL;
02408 
02409         return 1;
02410     }
02411 
02412     cpl_propertylist_delete(properties);
02413     properties = NULL;
02414 
02415     giraffe_qclog_close(qc);
02416     qc = NULL;
02417 
02418 
02419     /*
02420      * Cleanup
02421      */
02422 
02423     giraffe_image_delete(rimage);
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     cpl_plugin_init(plugin,
02443                     CPL_PLUGIN_API,
02444                     GIRAFFE_BINARY_VERSION,
02445                     CPL_PLUGIN_TYPE_RECIPE,
02446                     "giwavecalibration",
02447                     "Compute dispersion solution from an arc-lamp spectrum.",
02448                     "For detailed information please refer to the "
02449                     "GIRAFFE pipeline user manual.\nIt is available at "
02450                     "http://www.eso.org/pipelines.",
02451                     "Giraffe Pipeline",
02452                     PACKAGE_BUGREPORT,
02453                     giraffe_get_license(),
02454                     giwavecalibration_create,
02455                     giwavecalibration_exec,
02456                     giwavecalibration_destroy);
02457 
02458     cpl_pluginlist_append(list, plugin);
02459 
02460     return 0;
02461 
02462 }

This file is part of the GIRAFFE Pipeline Reference Manual 2.5.2.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Fri Jun 13 14:36:24 2008 by doxygen 1.4.6 written by Dimitri van Heesch, © 1997-2004