GIRAFFE Pipeline Reference Manual

giwavecalibration.c

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

This file is part of the GIRAFFE Pipeline Reference Manual 2.5.1.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Tue Mar 18 10:47:44 2008 by doxygen 1.4.6 written by Dimitri van Heesch, © 1997-2004