GIRAFFE Pipeline Reference Manual

gimasterflat.c

00001 /* $Id: gimasterflat.c,v 1.46.2.2 2008/06/09 15:07:01 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:07:01 $
00024  * $Revision: 1.46.2.2 $
00025  * $Name: giraffe-2_5_3 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #  include <config.h>
00030 #endif
00031 
00032 #include <math.h>
00033 
00034 #include <cxslist.h>
00035 #include <cxmessages.h>
00036 #include <cxmemory.h>
00037 
00038 #include <cpl_recipe.h>
00039 #include <cpl_plugininfo.h>
00040 #include <cpl_parameterlist.h>
00041 #include <cpl_frameset.h>
00042 #include <cpl_msg.h>
00043 
00044 #include "gialias.h"
00045 #include "gierror.h"
00046 #include "giframe.h"
00047 #include "giimage.h"
00048 #include "giwindow.h"
00049 #include "gifibers.h"
00050 #include "gifiberutils.h"
00051 #include "gislitgeometry.h"
00052 #include "gibias.h"
00053 #include "gidark.h"
00054 #include "gilocalize.h"
00055 #include "gipsf.h"
00056 #include "giextract.h"
00057 #include "gitransmission.h"
00058 #include "gislight.h"
00059 #include "giqclog.h"
00060 #include "giutils.h"
00061 
00062 
00063 static cxint gimasterflat(cpl_parameterlist* config, cpl_frameset* set);
00064 static cxint giqcmasterflat(cpl_frameset* set);
00065 
00066 
00067 /*
00068  * Create the recipe instance, i.e. setup the parameter list for this
00069  * recipe and make it availble to the application using the interface.
00070  */
00071 
00072 static cxint
00073 gimasterflat_create(cpl_plugin* plugin)
00074 {
00075 
00076     cpl_recipe* recipe = (cpl_recipe*)plugin;
00077 
00078     cpl_parameter* p;
00079 
00080 
00081     giraffe_error_init();
00082 
00083 
00084     /*
00085      * We have to provide the option we accept to the application. We
00086      * need to setup our parameter list and hook it into the recipe
00087      * interface.
00088      */
00089 
00090     recipe->parameters = cpl_parameterlist_new();
00091     cx_assert(recipe->parameters != NULL);
00092 
00093 
00094     /*
00095      * Fill the parameter list.
00096      */
00097 
00098     /* Fiber selection */
00099 
00100     giraffe_fibers_config_add(recipe->parameters);
00101 
00102     /* Bias removal */
00103 
00104     giraffe_bias_config_add(recipe->parameters);
00105 
00106     /* Dark subtraction */
00107 
00108     /* TBD */
00109 
00110     /* Spectrum localization */
00111 
00112     giraffe_localize_config_add(recipe->parameters);
00113 
00114     /* PSF fitting (accurate localization) */
00115 
00116     giraffe_psf_config_add(recipe->parameters);
00117 
00118     /* Spectrum extraction */
00119 
00120     giraffe_extract_config_add(recipe->parameters);
00121 
00122     /* Relative fiber transmission correction */
00123 
00124     p = cpl_parameter_new_value("giraffe.masterflat.transmission",
00125                                 CPL_TYPE_BOOL,
00126                                 "Controls the relative fiber transmission "
00127                                 "computation.",
00128                                 "giraffe.masterflat",
00129                                 TRUE);
00130 
00131     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "transmission");
00132     cpl_parameterlist_append(recipe->parameters, p);
00133 
00134     giraffe_transmission_config_add(recipe->parameters);
00135 
00136 
00137     p = cpl_parameter_new_value("giraffe.masterflat.slight",
00138                                 CPL_TYPE_BOOL,
00139                                 "Controls the scattered light model "
00140                                 "computation.",
00141                                 "giraffe.masterflat",
00142                                 FALSE);
00143     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight");
00144     cpl_parameterlist_append(recipe->parameters, p);
00145 
00146     giraffe_slight_config_add(recipe->parameters);
00147 
00148     return 0;
00149 
00150 }
00151 
00152 
00153 /*
00154  * Execute the plugin instance given by the interface.
00155  */
00156 
00157 static cxint
00158 gimasterflat_exec(cpl_plugin* plugin)
00159 {
00160 
00161     cpl_recipe* recipe = (cpl_recipe*)plugin;
00162 
00163     cxint status = 0;
00164 
00165 
00166     if (recipe->parameters == NULL || recipe->frames == NULL) {
00167         return 1;
00168     }
00169 
00170     status = gimasterflat(recipe->parameters, recipe->frames);
00171 
00172     if (status != 0) {
00173         return 1;
00174     }
00175 
00176     status = giqcmasterflat(recipe->frames);
00177 
00178     if (status != 0) {
00179         return 1;
00180     }
00181 
00182     return 0;
00183 
00184 }
00185 
00186 
00187 static cxint
00188 gimasterflat_destroy(cpl_plugin* plugin)
00189 {
00190 
00191     cpl_recipe* recipe = (cpl_recipe*)plugin;
00192 
00193 
00194     /*
00195      * We just destroy what was created during the plugin initialization
00196      * phase, i.e. the parameter list. The frame set is managed by the
00197      * application which called us, so we must not touch it,
00198      */
00199 
00200     cpl_parameterlist_delete(recipe->parameters);
00201 
00202     giraffe_error_clear();
00203 
00204     return 0;
00205 
00206 }
00207 
00208 
00209 /*
00210  * The actual recipe starts here.
00211  */
00212 
00213 static cxint
00214 gimasterflat(cpl_parameterlist* config, cpl_frameset* set)
00215 {
00216 
00217     const cxchar* const _id = "gimasterflat";
00218 
00219 
00220     cxbool transmission = FALSE;
00221     cxbool slmodel = FALSE;
00222 
00223     cxint status = 0;
00224     cxint nflats;
00225 
00226     cxlong i;
00227 
00228     cxdouble exptime = 0.;
00229     cxdouble mean = 0.;
00230 
00231     cx_slist* flats = NULL;
00232 
00233     cpl_parameter* p = NULL;
00234 
00235     cpl_propertylist* properties = NULL;
00236 
00237     cpl_matrix* biasareas = NULL;
00238 
00239     cpl_frame* flat_frame = NULL;
00240     cpl_frame* mbias_frame = NULL;
00241     cpl_frame* mdark_frame = NULL;
00242     cpl_frame* bpixel_frame = NULL;
00243     cpl_frame* slight_frame = NULL;
00244     cpl_frame* mlocy_frame = NULL;
00245     cpl_frame* mlocw_frame = NULL;
00246     cpl_frame* mlpsf_frame = NULL;
00247     cpl_frame* mflat_frame = NULL;
00248     cpl_frame* sloc_frame = NULL;
00249     cpl_frame* ploc_frame = NULL;
00250     cpl_frame* sext_frame = NULL;
00251     cpl_frame* slit_frame = NULL;
00252     cpl_frame* grating_frame = NULL;
00253     cpl_frame* wcal_frame = NULL;
00254 
00255     GiImage* bpixel = NULL;
00256     GiImage* mbias = NULL;
00257     GiImage* mdark = NULL;
00258     GiImage* slight = NULL;
00259     GiImage* sflat = NULL;
00260     GiImage* mflat = NULL;
00261 
00262     GiTable* fibers = NULL;
00263     GiTable* grating = NULL;
00264     GiTable* slitgeometry = NULL;
00265     GiTable* wlsolution = NULL;
00266 
00267     GiLocalization* sloc = NULL;
00268     GiLocalization* ploc = NULL;
00269     GiLocalization* mloc = NULL;
00270 
00271     GiExtraction* extraction = NULL;
00272 
00273     GiBiasConfig* bias_config = NULL;
00274 
00275     GiFibersConfig* fibers_config = NULL;
00276 
00277     GiLocalizeConfig* localize_config = NULL;
00278 
00279     GiPsfConfig* psf_config = NULL;
00280 
00281     GiExtractConfig* extract_config = NULL;
00282 
00283     GiTransmissionConfig* transmission_config = NULL;
00284 
00285     GiRecipeInfo info = {(cxchar*)_id, 1, NULL};
00286 
00287     GiGroupInfo groups[] = {
00288         {GIFRAME_FIBER_FLAT, CPL_FRAME_GROUP_RAW},
00289         {GIFRAME_BADPIXEL_MAP, CPL_FRAME_GROUP_CALIB},
00290         {GIFRAME_BIAS_MASTER, CPL_FRAME_GROUP_CALIB},
00291         {GIFRAME_DARK_MASTER, CPL_FRAME_GROUP_CALIB},
00292         {GIFRAME_SCATTERED_LIGHT_MODEL, CPL_FRAME_GROUP_CALIB},
00293         {GIFRAME_LOCALIZATION_CENTROID, CPL_FRAME_GROUP_CALIB},
00294         {GIFRAME_LOCALIZATION_WIDTH, CPL_FRAME_GROUP_CALIB},
00295         {GIFRAME_PSF_DATA, CPL_FRAME_GROUP_CALIB},
00296         {GIFRAME_WAVELENGTH_SOLUTION, CPL_FRAME_GROUP_CALIB},
00297         {GIFRAME_SLITSETUP, CPL_FRAME_GROUP_CALIB},
00298         {GIFRAME_SLITMASTER, CPL_FRAME_GROUP_CALIB},
00299         {GIFRAME_GRATING, CPL_FRAME_GROUP_CALIB},
00300         {NULL, CPL_FRAME_GROUP_NONE}
00301     };
00302 
00303 
00304 
00305     if (!config) {
00306         cpl_msg_error(_id, "Invalid parameter list! Aborting ...");
00307         return 1;
00308     }
00309 
00310     if (!set) {
00311         cpl_msg_error(_id, "Invalid frame set! Aborting ...");
00312         return 1;
00313     }
00314 
00315     status = giraffe_frameset_set_groups(set, groups);
00316 
00317     if (status != 0) {
00318         cpl_msg_error(_id, "Setting frame group information failed!");
00319         return 1;
00320     }
00321 
00322 
00323     p = cpl_parameterlist_find(config, "giraffe.masterflat.transmission");
00324 
00325     if (p != NULL) {
00326         transmission = cpl_parameter_get_bool(p);
00327     }
00328 
00329     p = cpl_parameterlist_find(config, "giraffe.masterflat.slight");
00330 
00331     if (p != NULL) {
00332         slmodel = cpl_parameter_get_bool(p);
00333     }
00334 
00335 
00336     /*
00337      * Verify the frame set contents
00338      */
00339 
00340     nflats = cpl_frameset_count_tags(set, GIFRAME_FIBER_FLAT);
00341 
00342     if (nflats < 1) {
00343         cpl_msg_error(_id, "Too few (%d) raw frames (%s) present in "
00344                       "frame set! Aborting ...", nflats, GIFRAME_FIBER_FLAT);
00345         return 1;
00346     }
00347 
00348 
00349     bpixel_frame = cpl_frameset_find(set, GIFRAME_BADPIXEL_MAP);
00350 
00351     if (!bpixel_frame) {
00352         cpl_msg_info(_id, "No bad pixel map present in frame set.");
00353     }
00354 
00355     mbias_frame = cpl_frameset_find(set, GIFRAME_BIAS_MASTER);
00356 
00357     if (!mbias_frame) {
00358         cpl_msg_info(_id, "No master bias present in frame set.");
00359     }
00360 
00361     mdark_frame = cpl_frameset_find(set, GIFRAME_DARK_MASTER);
00362 
00363     if (!mdark_frame) {
00364         cpl_msg_info(_id, "No master dark present in frame set.");
00365     }
00366 
00367     mlocy_frame = cpl_frameset_find(set, GIFRAME_LOCALIZATION_CENTROID);
00368 
00369     if (!mlocy_frame) {
00370         cpl_msg_info(_id, "No master localization (centroid position) "
00371                      "present in frame set.");
00372     }
00373 
00374     mlocw_frame = cpl_frameset_find(set, GIFRAME_LOCALIZATION_WIDTH);
00375 
00376     if (!mlocw_frame) {
00377         cpl_msg_info(_id, "No master localization (spectrum width) "
00378                      "present in frame set.");
00379     }
00380 
00381     mlpsf_frame = cpl_frameset_find(set, GIFRAME_PSF_DATA);
00382 
00383     if (!mlpsf_frame) {
00384         cpl_msg_info(_id, "No master localization (PSF parameters) "
00385                      "present in frame set.");
00386     }
00387 
00388     slight_frame = cpl_frameset_find(set, GIFRAME_SCATTERED_LIGHT_MODEL);
00389 
00390     if (!slight_frame) {
00391         cpl_msg_info(_id, "No scattered light model present in frame set.");
00392     }
00393 
00394     grating_frame = cpl_frameset_find(set, GIFRAME_GRATING);
00395 
00396     if (!grating_frame) {
00397         cpl_msg_info(_id, "No grating data present in frame set. "
00398                      "Aborting ...");
00399         return 1;
00400     }
00401 
00402     slit_frame = giraffe_get_slitgeometry(set);
00403 
00404     if (!slit_frame) {
00405         cpl_msg_info(_id, "No slitgeometry present in frame set. "
00406                      "Aborting ...");
00407         return 1;
00408     }
00409 
00410     wcal_frame = cpl_frameset_find(set, GIFRAME_WAVELENGTH_SOLUTION);
00411 
00412     if (!wcal_frame) {
00413         cpl_msg_info(_id, "No wavelength solution present in frame set.");
00414     }
00415 
00416 
00417     /*
00418      * Load raw images
00419      */
00420 
00421     flats = cx_slist_new();
00422 
00423     flat_frame = cpl_frameset_find(set, GIFRAME_FIBER_FLAT);
00424 
00425     for (i = 0; i < nflats; i++) {
00426 
00427         const cxchar* filename = cpl_frame_get_filename(flat_frame);
00428 
00429         GiImage* raw = giraffe_image_new(CPL_TYPE_DOUBLE);
00430 
00431 
00432         status = giraffe_image_load(raw, filename, 0);
00433 
00434         if (status) {
00435             cpl_msg_error(_id, "Cannot load raw flat from '%s'. "
00436                           "Aborting ...", filename);
00437 
00438             cx_slist_destroy(flats, (cx_free_func) giraffe_image_delete);
00439 
00440             return 1;
00441         }
00442 
00443         cx_slist_push_back(flats, raw);
00444 
00445         flat_frame = cpl_frameset_find(set, NULL);
00446 
00447     }
00448 
00449 
00450     /*
00451      * Create a stacked flat field from the list of raw images. Each raw
00452      * image is disposed when it is no longer needed.
00453      */
00454 
00455     // FIXME: For the moment we just do a simple averaging of all flats
00456     //        in the list, until the image combination is ported.
00457 
00458     cpl_msg_info(_id, "Averaging flat field frames ...");
00459 
00460     nflats = (cxint)cx_slist_size(flats);
00461     sflat = cx_slist_pop_front(flats);
00462 
00463     properties = giraffe_image_get_properties(sflat);
00464     cx_assert(properties != NULL);
00465 
00466     exptime = cpl_propertylist_get_double(properties, GIALIAS_EXPTIME);
00467 
00468     for (i = 1; i < nflats; i++) {
00469 
00470         cpl_propertylist* _properties;
00471 
00472         GiImage* flat = cx_slist_pop_front(flats);
00473 
00474 
00475         cpl_image_add(giraffe_image_get(sflat), giraffe_image_get(flat));
00476 
00477         _properties = giraffe_image_get_properties(flat);
00478         cx_assert(_properties != NULL);
00479 
00480         exptime += cpl_propertylist_get_double(_properties, GIALIAS_EXPTIME);
00481 
00482         giraffe_image_delete(flat);
00483 
00484     }
00485 
00486     cpl_image_divide_scalar(giraffe_image_get(sflat), nflats);
00487 
00488     cx_assert(cx_slist_empty(flats));
00489     cx_slist_delete(flats);
00490     flats = NULL;
00491 
00492 
00493     /*
00494      * Update stacked flat field properties
00495      */
00496 
00497     cpl_msg_info(_id, "Updating stacked flat field image properties ...");
00498 
00499     cpl_propertylist_update_double(properties, GIALIAS_EXPTIME, exptime / nflats);
00500 
00501     cpl_propertylist_update_double(properties, GIALIAS_EXPTTOT, exptime);
00502     cpl_propertylist_set_comment(properties, GIALIAS_EXPTTOT, "Total exposure "
00503                           "time of all frames combined");
00504 
00505     cpl_propertylist_update_int(properties, GIALIAS_DATANCOM, nflats);
00506     cpl_propertylist_set_comment(properties, GIALIAS_DATANCOM, "Number of "
00507                           "frames combined");
00508 
00509     cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
00510 
00511 
00512     /*
00513      * Prepare for bias subtraction
00514      */
00515 
00516     bias_config = giraffe_bias_config_create(config);
00517 
00518     /*
00519      * Setup user defined areas to use for the bias computation
00520      */
00521 
00522     if (strcmp(bias_config->areas, "None")) {
00523 
00524         cpl_msg_warning(_id, "User defined bias areas are not yet "
00525                         "supported. Using image pre- and overscan areas!");
00526 
00527         biasareas = NULL;
00528 
00529     }
00530 
00531 
00532     if (bias_config->method == GIBIAS_METHOD_MASTER ||
00533         bias_config->method == GIBIAS_METHOD_ZMASTER) {
00534 
00535         if (!mbias_frame) {
00536             cpl_msg_error(_id, "Missing master bias frame! Selected bias "
00537                           "removal method requires a master bias frame!");
00538 
00539             if (biasareas) {
00540                 cpl_matrix_delete(biasareas);
00541                 biasareas = NULL;
00542             }
00543 
00544             giraffe_bias_config_destroy(bias_config);
00545             giraffe_image_delete(sflat);
00546 
00547             return 1;
00548         }
00549         else {
00550             const cxchar* filename = cpl_frame_get_filename(mbias_frame);
00551 
00552 
00553             mbias = giraffe_image_new(CPL_TYPE_DOUBLE);
00554             status = giraffe_image_load(mbias, filename, 0);
00555 
00556             if (status) {
00557                 cpl_msg_error(_id, "Cannot load master bias from '%s'. "
00558                               "Aborting ...", filename);
00559 
00560                 if (biasareas) {
00561                     cpl_matrix_delete(biasareas);
00562                     biasareas = NULL;
00563                 }
00564 
00565                 giraffe_bias_config_destroy(bias_config);
00566                 giraffe_image_delete(sflat);
00567 
00568                 return 1;
00569             }
00570         }
00571     }
00572 
00573 
00574     /*
00575      * Load bad pixel map if it is present in the frame set.
00576      */
00577 
00578     if (bpixel_frame) {
00579 
00580         const cxchar* filename = cpl_frame_get_filename(bpixel_frame);
00581 
00582 
00583         bpixel = giraffe_image_new(CPL_TYPE_INT);
00584         status = giraffe_image_load(bpixel, filename, 0);
00585 
00586         if (status) {
00587             cpl_msg_error(_id, "Cannot load bad pixel map from '%s'. "
00588                           "Aborting ...", filename);
00589 
00590             if (biasareas) {
00591                 cpl_matrix_delete(biasareas);
00592                 biasareas = NULL;
00593             }
00594 
00595             if (mbias != NULL) {
00596                 giraffe_image_delete(mbias);
00597                 mbias = NULL;
00598             }
00599 
00600             giraffe_bias_config_destroy(bias_config);
00601             giraffe_image_delete(sflat);
00602 
00603             return 1;
00604         }
00605 
00606     }
00607 
00608 
00609     /*
00610      * Compute and remove the bias from the stacked flat field frame.
00611      */
00612 
00613     mflat = giraffe_image_new(CPL_TYPE_DOUBLE);
00614 
00615     status = giraffe_bias_remove(mflat, sflat, mbias, bpixel, biasareas,
00616                                  bias_config);
00617 
00618     giraffe_image_delete(sflat);
00619 
00620     if (mbias) {
00621         giraffe_image_delete(mbias);
00622         mbias = NULL;
00623     }
00624 
00625     if (biasareas) {
00626         cpl_matrix_delete(biasareas);
00627         biasareas = NULL;
00628     }
00629 
00630     giraffe_bias_config_destroy(bias_config);
00631 
00632     if (status) {
00633         cpl_msg_error(_id, "Bias removal failed. Aborting ...");
00634 
00635         giraffe_image_delete(mflat);
00636         mflat = NULL;
00637 
00638         if (bpixel != NULL) {
00639             giraffe_image_delete(bpixel);
00640             bpixel = NULL;
00641         }
00642 
00643         return 1;
00644     }
00645 
00646 
00647     /*
00648      * Load master dark if it is present in the frame set and correct
00649      * the master flat field for the dark current.
00650      */
00651 
00652     if (mdark_frame) {
00653 
00654         const cxchar* filename = cpl_frame_get_filename(mdark_frame);
00655 
00656         GiDarkConfig dark_config = {GIDARK_METHOD_ZMASTER, 0.};
00657 
00658 
00659         mdark = giraffe_image_new(CPL_TYPE_DOUBLE);
00660         status = giraffe_image_load(mdark, filename, 0);
00661 
00662         if (status != 0) {
00663             cpl_msg_error(_id, "Cannot load master dark from '%s'. "
00664                           "Aborting ...", filename);
00665 
00666             giraffe_image_delete(mflat);
00667             mflat = NULL;
00668 
00669             if (bpixel != NULL) {
00670                 giraffe_image_delete(bpixel);
00671                 bpixel = NULL;
00672             }
00673 
00674             return 1;
00675         }
00676 
00677         status = giraffe_subtract_dark(mflat, mdark, bpixel, NULL,
00678                                        &dark_config);
00679 
00680         if (status != 0) {
00681             cpl_msg_error(_id, "Dark subtraction failed! Aborting ...");
00682 
00683             giraffe_image_delete(mdark);
00684             mdark = NULL;
00685 
00686             giraffe_image_delete(mflat);
00687             mflat = NULL;
00688 
00689             if (bpixel != NULL) {
00690                 giraffe_image_delete(bpixel);
00691                 bpixel = NULL;
00692             }
00693 
00694             return 1;
00695         }
00696 
00697         giraffe_image_delete(mdark);
00698         mdark = NULL;
00699 
00700     }
00701 
00702 
00703     /*
00704      * Update master flat field properties, save the master flat field frame
00705      * and register it as product.
00706      */
00707 
00708     cpl_msg_info(_id, "Writing master flat field image ...");
00709 
00710     giraffe_image_add_info(mflat, &info, set);
00711 
00712     mflat_frame = giraffe_frame_create_image(mflat,
00713                                              GIFRAME_FIBER_FLAT_MASTER,
00714                                              CPL_FRAME_LEVEL_FINAL,
00715                                              TRUE, TRUE);
00716 
00717     if (mflat_frame == NULL) {
00718         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
00719 
00720         giraffe_image_delete(mflat);
00721 
00722         if (bpixel) {
00723             giraffe_image_delete(bpixel);
00724         }
00725 
00726         return 1;
00727     }
00728 
00729     cpl_frameset_insert(set, mflat_frame);
00730 
00731 
00732     /*
00733      * Determine fiber setup
00734      */
00735 
00736     cpl_msg_info(_id, "Recipe Step: Fiber setup");
00737 
00738     fibers_config = giraffe_fibers_config_create(config);
00739     flat_frame = cpl_frameset_find(set, GIFRAME_FIBER_FLAT);
00740 
00741     cpl_msg_info(_id, "Building fiber setup for frame '%s'.",
00742                  cpl_frame_get_filename(flat_frame));
00743 
00744     if (mlocy_frame == NULL) {
00745 
00746         fibers = giraffe_fibers_select(flat_frame, fibers_config);
00747 
00748         if (!fibers) {
00749             cpl_msg_error(_id, "Cannot determine fiber setup from flat "
00750                           "field frame '%s'! Aborting ...",
00751                           cpl_frame_get_filename(flat_frame));
00752 
00753             giraffe_image_delete(mflat);
00754 
00755             if (bpixel) {
00756                 giraffe_image_delete(bpixel);
00757             }
00758 
00759             giraffe_fibers_config_destroy(fibers_config);
00760 
00761             return 1;
00762         }
00763 
00764         cpl_msg_info(_id, "Fiber setup taken from flat field frame '%s'.",
00765                      cpl_frame_get_filename(flat_frame));
00766 
00767     }
00768     else {
00769 
00770         cpl_msg_info(_id, "Fiber reference setup taken from localization "
00771                      "frame '%s'.", cpl_frame_get_filename(mlocy_frame));
00772 
00773         fibers = giraffe_fibers_setup(flat_frame, mlocy_frame);
00774 
00775         if (!fibers) {
00776             cpl_msg_error(_id, "Cannot create fiber setup for frame '%s'! "
00777                           "Aborting ...", cpl_frame_get_filename(flat_frame));
00778 
00779             giraffe_image_delete(mflat);
00780 
00781             if (bpixel) {
00782                 giraffe_image_delete(bpixel);
00783             }
00784 
00785             giraffe_fibers_config_destroy(fibers_config);
00786 
00787             return 1;
00788         }
00789 
00790     }
00791 
00792     giraffe_fibers_config_destroy(fibers_config);
00793 
00794 
00795     /*
00796      * Perform spectrum localization on the created master flat field.
00797      */
00798 
00799     if (mlocy_frame != NULL) {
00800 
00801         const cxchar* filename = cpl_frame_get_filename(mlocy_frame);
00802 
00803 
00804         mloc = giraffe_localization_new();
00805         mloc->locy = giraffe_image_new(CPL_TYPE_DOUBLE);
00806         status = giraffe_image_load(mloc->locy, filename, 0);
00807 
00808         if (status) {
00809             cpl_msg_error(_id, "Cannot load master localization centroids "
00810                           "from '%s'. Aborting ...", filename);
00811 
00812             giraffe_localization_delete(mloc);
00813             mloc = NULL;
00814 
00815             giraffe_table_delete(fibers);
00816             giraffe_image_delete(mflat);
00817 
00818             if (bpixel) {
00819                 giraffe_image_delete(bpixel);
00820             }
00821 
00822             giraffe_localize_config_destroy(localize_config);
00823 
00824             return 1;
00825         }
00826 
00827     }
00828 
00829     localize_config = giraffe_localize_config_create(config);
00830 
00831     if (localize_config->full == FALSE) {
00832 
00833         // FIXME: For the time being just release the memory acquired.
00834         //        In future the master localization has to be loaded here
00835         //        and its completeness has to be checked.
00836 
00837         cpl_msg_error(_id, "Localization computation using only SIWC spectra "
00838                       "is not yet supported! Aborting ...");
00839 
00840         giraffe_table_delete(fibers);
00841         giraffe_image_delete(mflat);
00842 
00843         if (bpixel) {
00844             giraffe_image_delete(bpixel);
00845         }
00846 
00847         giraffe_localize_config_destroy(localize_config);
00848 
00849         return 1;
00850 
00851     }
00852 
00853     sloc = giraffe_localization_new();
00854 
00855     status = giraffe_localize_spectra(sloc, mflat, fibers, mloc,
00856                                       bpixel, localize_config);
00857 
00858     if (status) {
00859         cpl_msg_error(_id, "Spectrum localization failed! Aborting ...");
00860 
00861 
00862         giraffe_localization_destroy(sloc);
00863 
00864         if (mloc) {
00865             giraffe_localization_destroy(mloc);
00866         }
00867 
00868         giraffe_table_delete(fibers);
00869         giraffe_image_delete(mflat);
00870 
00871         if (bpixel) {
00872             giraffe_image_delete(bpixel);
00873         }
00874 
00875         giraffe_localize_config_destroy(localize_config);
00876 
00877         return 1;
00878     }
00879 
00880     giraffe_localize_config_destroy(localize_config);
00881 
00882     if (mloc != NULL) {
00883         giraffe_localization_destroy(mloc);
00884     }
00885 
00886 
00887     /*
00888      * Save the computed localization and register its components as
00889      * products.
00890      */
00891 
00892     cpl_msg_info(_id, "Writing fiber localization ...");
00893 
00894 
00895     /* Localization centroids */
00896 
00897     giraffe_image_add_info(sloc->locy, &info, set);
00898 
00899     sloc_frame = giraffe_frame_create_image(sloc->locy,
00900                                             GIFRAME_LOCALIZATION_CENTROID,
00901                                             CPL_FRAME_LEVEL_FINAL,
00902                                             TRUE, TRUE);
00903 
00904     if (sloc_frame == NULL) {
00905         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
00906 
00907         giraffe_localization_destroy(sloc);
00908 
00909         giraffe_table_delete(fibers);
00910         giraffe_image_delete(mflat);
00911 
00912         if (bpixel) {
00913             giraffe_image_delete(bpixel);
00914         }
00915 
00916         return 1;
00917     }
00918 
00919     status = giraffe_fiberlist_attach(sloc_frame, fibers);
00920 
00921     if (status) {
00922         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
00923                       "Aborting ...", cpl_frame_get_filename(sloc_frame));
00924 
00925         cpl_frame_delete(sloc_frame);
00926 
00927         giraffe_localization_destroy(sloc);
00928 
00929         giraffe_table_delete(fibers);
00930         giraffe_image_delete(mflat);
00931 
00932         if (bpixel) {
00933             giraffe_image_delete(bpixel);
00934         }
00935 
00936         return 1;
00937     }
00938 
00939     cpl_frameset_insert(set, sloc_frame);
00940 
00941 
00942     /* Localization half-width */
00943 
00944     giraffe_image_add_info(sloc->locw, &info, set);
00945 
00946     sloc_frame = giraffe_frame_create_image(sloc->locw,
00947                                             GIFRAME_LOCALIZATION_WIDTH,
00948                                             CPL_FRAME_LEVEL_FINAL,
00949                                             TRUE, TRUE);
00950 
00951     if (sloc_frame == NULL) {
00952         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
00953 
00954         giraffe_localization_destroy(sloc);
00955 
00956         giraffe_table_delete(fibers);
00957         giraffe_image_delete(mflat);
00958 
00959         if (bpixel) {
00960             giraffe_image_delete(bpixel);
00961         }
00962 
00963         return 1;
00964     }
00965 
00966     status = giraffe_fiberlist_attach(sloc_frame, fibers);
00967 
00968     if (status) {
00969         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
00970                       "Aborting ...", cpl_frame_get_filename(sloc_frame));
00971 
00972         cpl_frame_delete(sloc_frame);
00973 
00974         giraffe_localization_destroy(sloc);
00975 
00976         giraffe_table_delete(fibers);
00977         giraffe_image_delete(mflat);
00978 
00979         if (bpixel) {
00980             giraffe_image_delete(bpixel);
00981         }
00982 
00983         return 1;
00984     }
00985 
00986     cpl_frameset_insert(set, sloc_frame);
00987 
00988     /* Localization fit coefficients */
00989 
00990     if (sloc->locc) {
00991 
00992         giraffe_table_add_info(sloc->locc, &info, set);
00993 
00994         sloc_frame = giraffe_frame_create_table(sloc->locc,
00995                                                 GIFRAME_LOCALIZATION_FIT,
00996                                                 CPL_FRAME_LEVEL_FINAL,
00997                                                 TRUE, TRUE);
00998 
00999         if (sloc_frame == NULL) {
01000             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01001 
01002             giraffe_localization_destroy(sloc);
01003 
01004             giraffe_table_delete(fibers);
01005             giraffe_image_delete(mflat);
01006 
01007             if (bpixel) {
01008                 giraffe_image_delete(bpixel);
01009             }
01010 
01011             return 1;
01012         }
01013     }
01014 
01015     cpl_frameset_insert(set, sloc_frame);
01016     
01017     
01018     /*
01019      * Remove the reference index from the fiber setup, since the just
01020      * created localization is now used as position reference of the fibers. 
01021      */
01022 
01023     giraffe_fiberlist_clear_index(fibers);
01024 
01025     
01026     /*
01027      * Compute localization mask from the PSF profile of the fibers
01028      */
01029 
01030     psf_config = giraffe_psf_config_create(config);
01031 
01032     if (psf_config == NULL) {
01033         cpl_msg_error(_id, "Invalid fiber profile fit configuration!");
01034 
01035         giraffe_localization_destroy(sloc);
01036         sloc = NULL;
01037 
01038         giraffe_table_delete(fibers);
01039         fibers = NULL;
01040 
01041         giraffe_image_delete(mflat);
01042         mflat = NULL;
01043 
01044         if (bpixel != NULL) {
01045             giraffe_image_delete(bpixel);
01046             bpixel = NULL;
01047         }
01048 
01049         return 1;
01050 
01051     }
01052 
01053     ploc = giraffe_localization_new();
01054 
01055     status = giraffe_compute_fiber_profiles(ploc, mflat, fibers, sloc,
01056                                             bpixel, psf_config);
01057 
01058     if (status != 0) {
01059         cpl_msg_error(_id, "Fiber profile computation failed! Aborting ...");
01060 
01061         giraffe_localization_destroy(ploc);
01062         ploc = NULL;
01063 
01064         giraffe_psf_config_destroy(psf_config);
01065         psf_config = NULL;
01066 
01067         giraffe_localization_destroy(sloc);
01068         sloc = NULL;
01069 
01070         giraffe_table_delete(fibers);
01071         fibers = NULL;
01072 
01073         giraffe_image_delete(mflat);
01074         mflat = NULL;
01075 
01076         if (bpixel != NULL) {
01077             giraffe_image_delete(bpixel);
01078             bpixel = NULL;
01079         }
01080 
01081         return 1;
01082 
01083     }
01084 
01085     giraffe_psf_config_destroy(psf_config);
01086     psf_config = NULL;
01087 
01088     giraffe_localization_destroy(sloc);
01089     sloc = NULL;
01090 
01091 
01092     /*
01093      * Save the computed fiber traces and register its components as
01094      * products.
01095      */
01096 
01097     cpl_msg_info(_id, "Writing fiber traces ...");
01098 
01099 
01100     /* Fiber profile centroids */
01101 
01102     giraffe_image_add_info(ploc->locy, &info, set);
01103 
01104     ploc_frame = giraffe_frame_create_image(ploc->locy,
01105                                             GIFRAME_PSF_CENTROID,
01106                                             CPL_FRAME_LEVEL_FINAL,
01107                                             TRUE, TRUE);
01108 
01109     if (ploc_frame == NULL) {
01110         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01111 
01112         giraffe_localization_destroy(ploc);
01113         ploc = NULL;
01114 
01115         giraffe_table_delete(fibers);
01116         fibers = NULL;
01117 
01118         giraffe_image_delete(mflat);
01119         mflat = NULL;
01120 
01121         if (bpixel != NULL) {
01122             giraffe_image_delete(bpixel);
01123             bpixel = NULL;
01124         }
01125 
01126         return 1;
01127     }
01128 
01129     status = giraffe_fiberlist_attach(ploc_frame, fibers);
01130 
01131     if (status != 0) {
01132         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01133                       "Aborting ...", cpl_frame_get_filename(ploc_frame));
01134 
01135         cpl_frame_delete(ploc_frame);
01136 
01137         giraffe_localization_destroy(ploc);
01138         ploc = NULL;
01139 
01140         giraffe_table_delete(fibers);
01141         fibers = NULL;
01142 
01143         giraffe_image_delete(mflat);
01144         mflat = NULL;
01145 
01146         if (bpixel != NULL) {
01147             giraffe_image_delete(bpixel);
01148             bpixel = NULL;
01149         }
01150 
01151         return 1;
01152     }
01153 
01154     cpl_frameset_insert(set, ploc_frame);
01155 
01156 
01157     /* Fiber profile widths */
01158 
01159     giraffe_image_add_info(ploc->locw, &info, set);
01160 
01161     ploc_frame = giraffe_frame_create_image(ploc->locw,
01162                                             GIFRAME_PSF_WIDTH,
01163                                             CPL_FRAME_LEVEL_FINAL,
01164                                             TRUE, TRUE);
01165 
01166     if (ploc_frame == NULL) {
01167         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01168 
01169         giraffe_localization_destroy(ploc);
01170         ploc = NULL;
01171 
01172         giraffe_table_delete(fibers);
01173         fibers = NULL;
01174 
01175         giraffe_image_delete(mflat);
01176         mflat = NULL;
01177 
01178         if (bpixel != NULL) {
01179             giraffe_image_delete(bpixel);
01180             bpixel = NULL;
01181         }
01182 
01183         return 1;
01184     }
01185 
01186     status = giraffe_fiberlist_attach(ploc_frame, fibers);
01187 
01188     if (status != 0) {
01189         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01190                       "Aborting ...", cpl_frame_get_filename(ploc_frame));
01191 
01192         cpl_frame_delete(ploc_frame);
01193 
01194         giraffe_localization_destroy(ploc);
01195         ploc = NULL;
01196 
01197         giraffe_table_delete(fibers);
01198         fibers = NULL;
01199 
01200         giraffe_image_delete(mflat);
01201         mflat = NULL;
01202 
01203         if (bpixel != NULL) {
01204             giraffe_image_delete(bpixel);
01205             bpixel = NULL;
01206         }
01207 
01208         return 1;
01209     }
01210 
01211     cpl_frameset_insert(set, ploc_frame);
01212 
01213 
01214     /* Fiber profile centroid and widths fit coefficients */
01215 
01216     giraffe_table_add_info(ploc->locc, &info, set);
01217 
01218     ploc_frame = giraffe_frame_create_table(ploc->locc,
01219                                             GIFRAME_PSF_FIT,
01220                                             CPL_FRAME_LEVEL_FINAL,
01221                                             TRUE, TRUE);
01222 
01223     if (ploc_frame == NULL) {
01224         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01225 
01226         giraffe_localization_destroy(ploc);
01227         ploc = NULL;
01228 
01229         giraffe_table_delete(fibers);
01230         fibers = NULL;
01231 
01232         giraffe_image_delete(mflat);
01233         mflat = NULL;
01234 
01235         if (bpixel != NULL) {
01236             giraffe_image_delete(bpixel);
01237             bpixel = NULL;
01238         }
01239 
01240         return 1;
01241     }
01242 
01243     status = giraffe_fiberlist_attach(ploc_frame, fibers);
01244 
01245     if (status != 0) {
01246         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01247                       "Aborting ...", cpl_frame_get_filename(ploc_frame));
01248 
01249         cpl_frame_delete(ploc_frame);
01250 
01251         giraffe_localization_destroy(ploc);
01252         ploc = NULL;
01253 
01254         giraffe_table_delete(fibers);
01255         fibers = NULL;
01256 
01257         giraffe_image_delete(mflat);
01258         mflat = NULL;
01259 
01260         if (bpixel != NULL) {
01261             giraffe_image_delete(bpixel);
01262             bpixel = NULL;
01263         }
01264 
01265         return 1;
01266     }
01267 
01268     cpl_frameset_insert(set, ploc_frame);
01269 
01270 
01271     if (ploc->psf) {
01272 
01273         GiFrameCreator creator = (GiFrameCreator) giraffe_psfdata_save;
01274 
01275         properties = giraffe_image_get_properties(ploc->locy);
01276 
01277         ploc_frame = giraffe_frame_create(GIFRAME_PSF_DATA,
01278                                           CPL_FRAME_LEVEL_FINAL,
01279                                           properties, ploc->psf,
01280                                           NULL,
01281                                           creator);
01282 
01283         if (ploc_frame == NULL) {
01284             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01285 
01286             giraffe_localization_destroy(ploc);
01287             ploc = NULL;
01288 
01289             giraffe_table_delete(fibers);
01290             fibers = NULL;
01291 
01292             giraffe_image_delete(mflat);
01293             mflat = NULL;
01294 
01295             if (bpixel != NULL) {
01296                 giraffe_image_delete(bpixel);
01297                 bpixel = NULL;
01298             }
01299 
01300             return 1;
01301         }
01302 
01303         status = giraffe_fiberlist_attach(ploc_frame, fibers);
01304 
01305         if (status != 0) {
01306             cpl_msg_error(_id, "Cannot attach fiber setup to local "
01307                           "file '%s'! Aborting ...",
01308                           cpl_frame_get_filename(ploc_frame));
01309 
01310             cpl_frame_delete(ploc_frame);
01311 
01312             giraffe_localization_destroy(ploc);
01313             ploc = NULL;
01314 
01315             giraffe_table_delete(fibers);
01316             fibers = NULL;
01317 
01318             giraffe_image_delete(mflat);
01319             mflat = NULL;
01320 
01321             if (bpixel != NULL) {
01322                 giraffe_image_delete(bpixel);
01323                 bpixel = NULL;
01324             }
01325 
01326             return 1;
01327         }
01328 
01329         cpl_frameset_insert(set, ploc_frame);
01330 
01331     }
01332 
01333 
01334     /*
01335      * Optional scattered light model computation
01336      */
01337 
01338     // FIXME: Check whether scattered light modeling code should stay here!
01339 
01340     if (slmodel == TRUE) {
01341 
01342         cpl_frame* slmodel_frame = NULL;
01343 
01344         GiSLightConfig* slight_config = NULL;
01345 
01346 
01347         cpl_msg_info(_id, "Computing scattered light model ...");
01348 
01349         slight_config = giraffe_slight_config_create(config);
01350 
01351         if (slight_config == NULL) {
01352             cpl_msg_error(_id, "Invalid scattered light model "
01353                           "configuration!");
01354 
01355             giraffe_table_delete(fibers);
01356             giraffe_image_delete(mflat);
01357 
01358             if (bpixel) {
01359                 giraffe_image_delete(bpixel);
01360             }
01361 
01362             giraffe_localization_destroy(ploc);
01363             ploc = NULL;
01364 
01365             return 1;
01366 
01367         }
01368 
01369         slight = giraffe_image_new(CPL_TYPE_DOUBLE);
01370 
01371         status = giraffe_adjust_scattered_light(slight, mflat, ploc,
01372                                                 bpixel, NULL, slight_config);
01373 
01374         if (status != 0) {
01375             cpl_msg_error(_id, "Scattered light model computation failed! "
01376                           "Aborting ...");
01377 
01378             giraffe_image_delete(slight);
01379 
01380             giraffe_slight_config_destroy(slight_config);
01381 
01382             giraffe_table_delete(fibers);
01383             giraffe_image_delete(mflat);
01384 
01385             if (bpixel != NULL) {
01386                 giraffe_image_delete(bpixel);
01387                 bpixel = NULL;
01388             }
01389 
01390             giraffe_localization_destroy(ploc);
01391             ploc = NULL;
01392 
01393             return 1;
01394         }
01395 
01396 
01397         giraffe_slight_config_destroy(slight_config);
01398         slight_config = NULL;
01399 
01400 
01401         /*
01402          * Save scattered light model
01403          */
01404 
01405         cpl_msg_info(_id, "Writing scattered light model ...");
01406 
01407         giraffe_image_add_info(slight, &info, set);
01408 
01409         slmodel_frame =
01410             giraffe_frame_create_image(slight,
01411                                        GIFRAME_SCATTERED_LIGHT_MODEL,
01412                                        CPL_FRAME_LEVEL_FINAL,
01413                                        TRUE, TRUE);
01414 
01415         if (slmodel_frame == NULL) {
01416             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01417 
01418             giraffe_image_delete(slight);
01419 
01420             giraffe_table_delete(fibers);
01421             giraffe_image_delete(mflat);
01422 
01423             if (bpixel != NULL) {
01424                 giraffe_image_delete(bpixel);
01425                 bpixel = NULL;
01426             }
01427 
01428             giraffe_localization_destroy(ploc);
01429             ploc = NULL;
01430 
01431             return 1;
01432         }
01433 
01434         cpl_frameset_insert(set, slmodel_frame);
01435 
01436         giraffe_image_delete(slight);
01437         slight = NULL;
01438 
01439     }
01440 
01441 
01442     /*
01443      * Perform spectrum extraction on the master flat field.
01444      */
01445 
01446     cpl_msg_info(_id, "Extracting spectra ...");
01447 
01448     if (slight_frame != NULL) {
01449 
01450         const cxchar* filename = cpl_frame_get_filename(slight_frame);
01451 
01452 
01453         slight = giraffe_image_new(CPL_TYPE_DOUBLE);
01454         status = giraffe_image_load(slight, filename, 0);
01455 
01456         if (status != 0) {
01457             cpl_msg_error(_id, "Cannot load scattered light model from '%s'. "
01458                           "Aborting ...", filename);
01459 
01460             giraffe_image_delete(slight);
01461 
01462             giraffe_table_delete(fibers);
01463             giraffe_image_delete(mflat);
01464 
01465             if (bpixel != NULL) {
01466                 giraffe_image_delete(bpixel);
01467                 bpixel = NULL;
01468             }
01469 
01470             giraffe_localization_destroy(ploc);
01471             ploc = NULL;
01472 
01473             return 1;
01474 
01475         }
01476 
01477     }
01478 
01479     extract_config = giraffe_extract_config_create(config);
01480 
01481     extraction = giraffe_extraction_new();
01482 
01483     status = giraffe_extract_spectra(extraction, mflat, fibers,
01484                                      ploc, bpixel, slight,
01485                                      extract_config);
01486 
01487     if (status != 0) {
01488         cpl_msg_error(_id, "Spectrum extraction failed! Aborting ...");
01489 
01490         giraffe_extraction_destroy(extraction);
01491 
01492         giraffe_image_delete(slight);
01493 
01494         giraffe_localization_destroy(ploc);
01495         ploc = NULL;
01496 
01497         giraffe_table_delete(fibers);
01498         giraffe_image_delete(mflat);
01499 
01500         if (bpixel != NULL) {
01501             giraffe_image_delete(bpixel);
01502             bpixel = NULL;
01503         }
01504 
01505         giraffe_extract_config_destroy(extract_config);
01506 
01507         return 1;
01508     }
01509 
01510     giraffe_image_delete(slight);
01511     giraffe_image_delete(mflat);
01512 
01513     if (bpixel != NULL) {
01514         giraffe_image_delete(bpixel);
01515         bpixel = NULL;
01516     }
01517 
01518     giraffe_extract_config_destroy(extract_config);
01519 
01520 
01521     /*
01522      * Normalize extracted spectra and errors
01523      */
01524 
01525     mean = cpl_image_get_mean(giraffe_image_get(extraction->spectra));
01526 
01527     cpl_image_divide_scalar(giraffe_image_get(extraction->spectra), mean);
01528 
01529     properties = giraffe_image_get_properties(extraction->spectra);
01530     cpl_propertylist_update_double(properties, GIALIAS_FLAT_SCALE, mean);
01531     cpl_propertylist_set_comment(properties, GIALIAS_FLAT_SCALE,
01532                                  "Flat field scale factor");
01533 
01534 
01535     cpl_image_divide_scalar(giraffe_image_get(extraction->error), mean);
01536 
01537     properties = giraffe_image_get_properties(extraction->error);
01538     cpl_propertylist_update_double(properties, GIALIAS_FLAT_SCALE, mean);
01539     cpl_propertylist_set_comment(properties, GIALIAS_FLAT_SCALE,
01540                                  "Flat field scale factor");
01541 
01542 
01543     /*
01544      * Compute relative fiber transmission correction.
01545      */
01546 
01547     if (transmission == TRUE) {
01548 
01549         const cxchar* filename = NULL;
01550 
01551 
01552         transmission_config = giraffe_transmission_config_create(config);
01553 
01554         cpl_msg_info(_id, "Computing relative fiber transmission ...");
01555 
01556         filename  = cpl_frame_get_filename(grating_frame);
01557 
01558         grating = giraffe_table_new();
01559         status = giraffe_table_load(grating, filename, 1, NULL);
01560 
01561         if (status != 0) {
01562             cpl_msg_error(_id, "Cannot load grating data from '%s'. "
01563                           "Aborting ...", filename);
01564 
01565             giraffe_table_delete(grating);
01566 
01567             giraffe_transmission_config_destroy(transmission_config);
01568 
01569             giraffe_extraction_destroy(extraction);
01570 
01571             giraffe_localization_destroy(ploc);
01572             ploc = NULL;
01573 
01574             giraffe_table_delete(fibers);
01575 
01576             return 1;
01577         }
01578 
01579 
01580         filename = cpl_frame_get_filename(slit_frame);
01581 
01582         slitgeometry = giraffe_slitgeometry_load(fibers, filename, 1, NULL);
01583 
01584         if (slitgeometry == NULL) {
01585             cpl_msg_error(_id, "Cannot load slit geometry data from '%s'. "
01586                           "Aborting ...", filename);
01587 
01588             giraffe_table_delete(grating);
01589 
01590             giraffe_transmission_config_destroy(transmission_config);
01591 
01592             giraffe_extraction_destroy(extraction);
01593 
01594             giraffe_localization_destroy(ploc);
01595             ploc = NULL;
01596 
01597             giraffe_table_delete(fibers);
01598 
01599             return 1;
01600         }
01601         else {
01602 
01603             /*
01604              * Check whether the contains the positions for all fibers
01605              * provided by the fiber setup. If this is not the case
01606              * this is an error.
01607              */
01608 
01609             if (giraffe_fiberlist_compare(slitgeometry, fibers) != 1) {
01610                 cpl_msg_error(_id, "Slit geometry data from '%s' is not "
01611                               "applicable for current fiber setup! "
01612                               "Aborting ...", filename);
01613 
01614                 giraffe_table_delete(slitgeometry);
01615                 giraffe_table_delete(grating);
01616 
01617                 giraffe_transmission_config_destroy(transmission_config);
01618 
01619                 giraffe_extraction_destroy(extraction);
01620 
01621                 giraffe_localization_destroy(ploc);
01622                 ploc = NULL;
01623 
01624                 giraffe_table_delete(fibers);
01625 
01626                 return 1;
01627             }
01628 
01629         }
01630 
01631 
01632         if (wcal_frame != NULL) {
01633 
01634             filename = cpl_frame_get_filename(wcal_frame);
01635 
01636             cpl_msg_info(_id, "Loading wavelength solution from '%s'",
01637                          filename);
01638 
01639             wlsolution = giraffe_table_new();
01640             status = giraffe_table_load(wlsolution, filename, 1, NULL);
01641 
01642             if (status != 0) {
01643                 cpl_msg_error(_id, "Cannot load wavelength solution from "
01644                               "'%s'. Aborting ...", filename);
01645 
01646                 giraffe_table_delete(wlsolution);
01647                 giraffe_table_delete(slitgeometry);
01648                 giraffe_table_delete(grating);
01649 
01650                 giraffe_transmission_config_destroy(transmission_config);
01651 
01652                 giraffe_extraction_destroy(extraction);
01653 
01654                 giraffe_localization_destroy(ploc);
01655                 ploc = NULL;
01656 
01657                 giraffe_table_delete(fibers);
01658 
01659                 return 1;
01660             }
01661 
01662         }
01663 
01664 
01665         status = giraffe_transmission_compute(extraction, fibers,
01666                                               ploc, wlsolution,
01667                                               grating, slitgeometry);
01668 
01669         if (status != 0) {
01670             cpl_msg_error(_id, "Relative transmission computation failed! "
01671                           "Aborting ...");
01672 
01673             if (wlsolution != NULL) {
01674                 giraffe_table_delete(wlsolution);
01675                 wlsolution = NULL;
01676             }
01677 
01678             giraffe_table_delete(slitgeometry);
01679             giraffe_table_delete(grating);
01680 
01681             giraffe_transmission_config_destroy(transmission_config);
01682 
01683             giraffe_extraction_destroy(extraction);
01684 
01685             giraffe_localization_destroy(ploc);
01686             ploc = NULL;
01687 
01688             giraffe_table_delete(fibers);
01689 
01690             return 1;
01691         }
01692 
01693         if (wlsolution != NULL) {
01694             giraffe_table_delete(wlsolution);
01695             wlsolution = NULL;
01696         }
01697 
01698         giraffe_table_delete(slitgeometry);
01699         giraffe_table_delete(grating);
01700 
01701         giraffe_transmission_config_destroy(transmission_config);
01702 
01703     }
01704 
01705     giraffe_localization_destroy(ploc);
01706     ploc = NULL;
01707 
01708 
01709     /*
01710      * Save the spectrum extraction results and register them as
01711      * products.
01712      */
01713 
01714     cpl_msg_info(_id, "Writing extracted spectra ...");
01715 
01716     /* Extracted spectra */
01717 
01718     giraffe_image_add_info(extraction->spectra, &info, set);
01719 
01720     sext_frame = giraffe_frame_create_image(extraction->spectra,
01721                                             GIFRAME_FIBER_FLAT_EXTSPECTRA,
01722                                             CPL_FRAME_LEVEL_FINAL,
01723                                             TRUE, TRUE);
01724 
01725     if (sext_frame == NULL) {
01726         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01727 
01728         giraffe_extraction_destroy(extraction);
01729         giraffe_table_delete(fibers);
01730 
01731         return 1;
01732     }
01733 
01734     status = giraffe_fiberlist_attach(sext_frame, fibers);
01735 
01736     if (status != 0) {
01737         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01738                       "Aborting ...", cpl_frame_get_filename(sext_frame));
01739 
01740         cpl_frame_delete(sext_frame);
01741 
01742         giraffe_extraction_destroy(extraction);
01743         giraffe_table_delete(fibers);
01744 
01745         return 1;
01746     }
01747 
01748     cpl_frameset_insert(set, sext_frame);
01749 
01750     /* Extracted spectra errors */
01751 
01752     giraffe_image_add_info(extraction->error, &info, set);
01753 
01754     sext_frame = giraffe_frame_create_image(extraction->error,
01755                                             GIFRAME_FIBER_FLAT_EXTERRORS,
01756                                             CPL_FRAME_LEVEL_FINAL,
01757                                             TRUE, TRUE);
01758 
01759     if (sext_frame == NULL) {
01760         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01761 
01762         giraffe_extraction_destroy(extraction);
01763         giraffe_table_delete(fibers);
01764 
01765         return 1;
01766     }
01767 
01768     status = giraffe_fiberlist_attach(sext_frame, fibers);
01769 
01770     if (status != 0) {
01771         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01772                       "Aborting ...", cpl_frame_get_filename(sext_frame));
01773 
01774         cpl_frame_delete(sext_frame);
01775 
01776         giraffe_extraction_destroy(extraction);
01777         giraffe_table_delete(fibers);
01778 
01779         return 1;
01780     }
01781 
01782     cpl_frameset_insert(set, sext_frame);
01783 
01784     /* Extracted spectra pixels */
01785 
01786     if (extraction->npixels != NULL) {
01787 
01788         giraffe_image_add_info(extraction->npixels, &info, set);
01789 
01790         sext_frame = giraffe_frame_create_image(extraction->npixels,
01791                                                 GIFRAME_FIBER_FLAT_EXTPIXELS,
01792                                                 CPL_FRAME_LEVEL_FINAL,
01793                                                 TRUE, TRUE);
01794 
01795         if (sext_frame == NULL) {
01796             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01797 
01798             giraffe_extraction_destroy(extraction);
01799             giraffe_table_delete(fibers);
01800 
01801             return 1;
01802         }
01803 
01804         status = giraffe_fiberlist_attach(sext_frame, fibers);
01805 
01806         if (status != 0) {
01807             cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01808                         "Aborting ...", cpl_frame_get_filename(sext_frame));
01809 
01810             cpl_frame_delete(sext_frame);
01811 
01812             giraffe_extraction_destroy(extraction);
01813             giraffe_table_delete(fibers);
01814 
01815             return 1;
01816         }
01817 
01818         cpl_frameset_insert(set, sext_frame);
01819 
01820     }
01821 
01822     /* Extracted spectra centroids */
01823 
01824     giraffe_image_add_info(extraction->centroid, &info, set);
01825 
01826     sext_frame = giraffe_frame_create_image(extraction->centroid,
01827                                             GIFRAME_FIBER_FLAT_EXTTRACE,
01828                                             CPL_FRAME_LEVEL_FINAL,
01829                                             TRUE, TRUE);
01830 
01831     if (sext_frame == NULL) {
01832         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01833 
01834         giraffe_extraction_destroy(extraction);
01835         giraffe_table_delete(fibers);
01836 
01837         return 1;
01838     }
01839 
01840     status = giraffe_fiberlist_attach(sext_frame, fibers);
01841 
01842     if (status != 0) {
01843         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01844                       "Aborting ...", cpl_frame_get_filename(sext_frame));
01845 
01846         cpl_frame_delete(sext_frame);
01847 
01848         giraffe_extraction_destroy(extraction);
01849         giraffe_table_delete(fibers);
01850 
01851         return 1;
01852     }
01853 
01854     cpl_frameset_insert(set, sext_frame);
01855 
01856     /* Extraction model spectra */
01857 
01858     if (extraction->model != NULL) {
01859 
01860         giraffe_image_add_info(extraction->model, &info, set);
01861 
01862         sext_frame = giraffe_frame_create_image(extraction->model,
01863                                                 GIFRAME_FIBER_FLAT_EXTMODEL,
01864                                                 CPL_FRAME_LEVEL_FINAL,
01865                                                 TRUE, TRUE);
01866 
01867         if (sext_frame == NULL) {
01868             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01869 
01870             giraffe_extraction_destroy(extraction);
01871             giraffe_table_delete(fibers);
01872 
01873             return 1;
01874         }
01875 
01876         status = giraffe_fiberlist_attach(sext_frame, fibers);
01877 
01878         if (status != 0) {
01879             cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01880                         "Aborting ...", cpl_frame_get_filename(sext_frame));
01881 
01882             cpl_frame_delete(sext_frame);
01883 
01884             giraffe_extraction_destroy(extraction);
01885             giraffe_table_delete(fibers);
01886 
01887             return 1;
01888         }
01889 
01890         cpl_frameset_insert(set, sext_frame);
01891 
01892     }
01893 
01894 
01895     /*
01896      * Cleanup
01897      */
01898 
01899     giraffe_extraction_destroy(extraction);
01900     giraffe_table_delete(fibers);
01901 
01902     return 0;
01903 
01904 }
01905 
01906 
01907 static cxint
01908 giqcmasterflat(cpl_frameset* set)
01909 {
01910 
01911     const cxchar* const fctid = "giqcmasterflat";
01912 
01913 
01914     cxint i = 0;
01915     cxint nx = 0;
01916     cxint ny = 0;
01917     cxint npixel = 0;
01918     cxint nsaturated = 0;
01919     cxint status = 0;
01920 
01921     const cxdouble saturation = 60000.;
01922     const cxdouble* pixels = NULL;
01923     cxdouble efficiency[2] = {0., 0.};
01924     cxdouble scale = 1.;
01925     cxdouble mean = 0.;
01926     cxdouble rms = 0.;
01927     cxdouble diff = 0.;
01928     cxdouble* _pdata = NULL;
01929     cxdouble* _tdata = NULL;
01930 
01931     cpl_propertylist* properties = NULL;
01932     cpl_propertylist* qclog = NULL;
01933 
01934     cpl_frame* rframe = NULL;
01935     cpl_frame* pframe = NULL;
01936 
01937     cpl_image* _rimage = NULL;
01938     cpl_image* _pimage = NULL;
01939     cpl_image* _test = NULL;
01940 
01941     cpl_table* _ptable = NULL;
01942 
01943     GiImage* rimage = NULL;
01944     GiImage* pimage = NULL;
01945 
01946     GiTable* ptable = NULL;
01947 
01948     GiPaf* qc = NULL;
01949 
01950     GiWindow w = {0, 0, 0, 0};
01951 
01952 
01953 
01954     cpl_msg_info(fctid, "Computing QC1 parameters ...");
01955 
01956     qc = giraffe_qclog_open(0);
01957 
01958     if (qc == NULL) {
01959         cpl_msg_error(fctid, "Cannot create QC1 log!");
01960         return 1;
01961     }
01962 
01963     qclog = giraffe_paf_get_properties(qc);
01964     cx_assert(qclog != NULL);
01965 
01966 
01967     /*
01968      * Compute lamp efficiencies from the rebinned frame if
01969      * it is available. If not the efficiencies are set to 0.
01970      */
01971 
01972     pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_EXTSPECTRA,
01973                                CPL_FRAME_GROUP_PRODUCT);
01974 
01975     if (pframe == NULL) {
01976 
01977         cpl_msg_warning(fctid, "Product '%s' not found.",
01978                         GIFRAME_FIBER_FLAT_EXTSPECTRA);
01979 
01980         cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
01981                         GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
01982 
01983         efficiency[0] = 0.;
01984         efficiency[1] = 0.;
01985 
01986     }
01987 
01988 
01989     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
01990     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
01991 
01992     if (status != 0) {
01993         cpl_msg_error(fctid, "Could not load extracted spectra '%s'!",
01994                       cpl_frame_get_filename(pframe));
01995 
01996         giraffe_image_delete(pimage);
01997         pimage = NULL;
01998 
01999         giraffe_paf_delete(qc);
02000         qc = NULL;
02001 
02002         return 1;
02003     }
02004 
02005     _pimage = giraffe_image_get(pimage);
02006     cx_assert(_pimage != NULL);
02007 
02008 
02009     ptable = giraffe_table_new();
02010     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
02011                                 NULL);
02012 
02013     if (status != 0) {
02014         cpl_msg_error(fctid, "Could not load extracted spectra fiber setup!");
02015 
02016         giraffe_table_delete(ptable);
02017         ptable = NULL;
02018 
02019         giraffe_image_delete(pimage);
02020         pimage = NULL;
02021 
02022         giraffe_paf_delete(qc);
02023         qc = NULL;
02024 
02025         return 1;
02026     }
02027 
02028     _ptable = giraffe_table_get(ptable);
02029     cx_assert(_ptable != NULL);
02030 
02031     if (cpl_table_has_column(_ptable, "RP") == FALSE) {
02032 
02033         cpl_msg_warning(fctid, "Column 'RP' not found in fiber setup table!");
02034         cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
02035                         GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
02036 
02037         efficiency[0] = 0.;
02038         efficiency[1] = 0.;
02039 
02040     }
02041     else {
02042 
02043         properties = giraffe_image_get_properties(pimage);
02044         cx_assert(properties != NULL);
02045 
02046         if (cpl_propertylist_has(properties, GIALIAS_EXPTIME) == FALSE) {
02047 
02048             cpl_msg_warning(fctid, "Property '%s' not found in '%s'.",
02049                             GIALIAS_EXPTIME, cpl_frame_get_filename(rframe));
02050             cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
02051                             GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
02052 
02053             efficiency[0] = 0.;
02054             efficiency[1] = 0.;
02055 
02056         }
02057         else {
02058 
02059             cxbool scaled = cpl_propertylist_has(properties,
02060                                                  GIALIAS_FLAT_SCALE);
02061 
02062             cxint fiber = 0;
02063             cxint nb = cpl_image_get_size_y(_pimage);
02064             cxint nf[2] = {0, 0};
02065 
02066             cxdouble exptime = cpl_propertylist_get_double(properties,
02067                 GIALIAS_EXPTIME);
02068             cxdouble* _sum = NULL;
02069 
02070             cpl_image* sum = NULL;
02071 
02072 
02073             if (scaled == TRUE) {
02074 
02075                 scale = cpl_propertylist_get_double(properties,
02076                     GIALIAS_FLAT_SCALE);
02077                 cpl_image_multiply_scalar(_pimage, scale);
02078 
02079 
02080             }
02081 
02082             sum = cpl_image_collapse_create(_pimage, 0);
02083             _sum = cpl_image_get_data_double(sum);
02084 
02085             for (fiber = 0; fiber < cpl_table_get_nrow(_ptable); ++fiber) {
02086 
02087                 cxint rp = cpl_table_get_int(_ptable, "RP", fiber, NULL);
02088 
02089                 if (rp == -1) {
02090                     efficiency[1] += _sum[fiber];
02091                     ++nf[1];
02092                 }
02093                 else {
02094                     efficiency[0] += _sum[fiber];
02095                     ++nf[0];
02096                 }
02097 
02098             }
02099 
02100             _sum = NULL;
02101 
02102             cpl_image_delete(sum);
02103             sum = NULL;
02104 
02105             if (nf[0] == 0) {
02106                 cpl_msg_warning(fctid, "No OzPoz fibers found in the "
02107                         "current fiber setup.");
02108                 cpl_msg_warning(fctid, "Setting lamp efficiency (%s) to 0.",
02109                         GIALIAS_QCLAMP);
02110                 efficiency[0] = 0.;
02111             }
02112             else {
02113                 efficiency[0] /= nf[0] * nb * exptime;
02114             }
02115             
02116             if (nf[1] == 0) {
02117                 cpl_msg_warning(fctid, "No simultaneous calibration fibers "
02118                         "found in the current fiber setup.");
02119                 cpl_msg_warning(fctid, "Setting lamp efficiency (%s) to 0.",
02120                         GIALIAS_QCLAMP_SIMCAL);
02121                 efficiency[1] = 0.;
02122             }
02123             else {
02124                 efficiency[1] /= nf[1] * nb * exptime;
02125             }                
02126 
02127         }
02128 
02129         properties = NULL;
02130 
02131     }
02132 
02133     _ptable = NULL;
02134     _pimage = NULL;
02135 
02136     giraffe_table_delete(ptable);
02137     ptable = NULL;
02138 
02139     giraffe_image_delete(pimage);
02140     pimage = NULL;
02141 
02142 
02143     /*
02144      * Process master flat field
02145      */
02146 
02147 
02148     pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_MASTER,
02149                                CPL_FRAME_GROUP_PRODUCT);
02150 
02151     if (pframe == NULL) {
02152         cpl_msg_error(fctid, "Missing product frame (%s)",
02153                       GIFRAME_FIBER_FLAT_MASTER);
02154 
02155         giraffe_paf_delete(qc);
02156         qc = NULL;
02157 
02158         return 1;
02159     }
02160 
02161     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
02162                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
02163 
02164     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02165     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
02166 
02167     if (status != 0) {
02168         cpl_msg_error(fctid, "Could not load master flat field '%s'!",
02169                       cpl_frame_get_filename(pframe));
02170 
02171         giraffe_image_delete(pimage);
02172         pimage = NULL;
02173 
02174         giraffe_paf_delete(qc);
02175         qc = NULL;
02176 
02177         return 1;
02178     }
02179 
02180 
02181     /*
02182      * Load first raw image as reference
02183      */
02184 
02185     rframe = cpl_frameset_find(set, GIFRAME_FIBER_FLAT);
02186 
02187     if (rframe == NULL) {
02188         cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_FIBER_FLAT);
02189 
02190         giraffe_image_delete(pimage);
02191         pimage = NULL;
02192 
02193         giraffe_paf_delete(qc);
02194         qc = NULL;
02195 
02196         return 1;
02197     }
02198 
02199     rimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02200     status = giraffe_image_load(rimage, cpl_frame_get_filename(rframe), 0);
02201 
02202     if (status != 0) {
02203 
02204         cpl_msg_error(fctid, "Could not load flat field '%s'!",
02205                       cpl_frame_get_filename(rframe));
02206 
02207         giraffe_image_delete(rimage);
02208         rimage = NULL;
02209 
02210         giraffe_image_delete(pimage);
02211         pimage = NULL;
02212 
02213         giraffe_paf_delete(qc);
02214         qc = NULL;
02215 
02216         return 1;
02217 
02218     }
02219 
02220     _rimage = giraffe_image_get(rimage);
02221     cx_assert(_rimage != NULL);
02222 
02223     properties = giraffe_image_get_properties(rimage);
02224     cx_assert(properties != NULL);
02225 
02226     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
02227     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
02228     giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
02229                               GIALIAS_SETUPNAME);
02230     giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
02231                               GIALIAS_SLITNAME);
02232     giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
02233                               GIALIAS_GRATWLEN);
02234     giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
02235 
02236     cpl_propertylist_update_string(qclog, "PRO.CATG",
02237                                    cpl_frame_get_tag(pframe));
02238     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02239                                  "Pipeline product category");
02240 
02241     properties = giraffe_image_get_properties(pimage);
02242     cx_assert(properties != NULL);
02243 
02244     giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
02245                               GIALIAS_DATAMEAN);
02246     giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
02247                               GIALIAS_DATASIG);
02248     giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
02249                               GIALIAS_DATAMEDI);
02250     giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
02251                               GIALIAS_DATANCOM);
02252 
02253 
02254     /*
02255      * Compute mean level of the first raw frame and count the number
02256      * of saturated pixels.
02257      */
02258 
02259     properties = giraffe_image_get_properties(rimage);
02260     cx_assert(properties != NULL);
02261 
02262     if (cpl_propertylist_has(properties, GIALIAS_OVSCX) == TRUE) {
02263 
02264         cxint _ox = cpl_propertylist_get_int(properties, GIALIAS_OVSCX);
02265         cxint _nx = cpl_image_get_size_x(_rimage) - 2 * CX_MAX(0, _ox) - 1;
02266 
02267         w.x0 = CX_MAX(0, _ox) + 1;
02268         w.x1 = w.x0 + _nx;
02269 
02270     }
02271 
02272     if (cpl_propertylist_has(properties, GIALIAS_OVSCY) == TRUE) {
02273 
02274         cxint _oy = cpl_propertylist_get_int(properties, GIALIAS_OVSCY);
02275         cxint _ny = cpl_image_get_size_y(_rimage) - 2 * CX_MAX(0, _oy) - 1;
02276 
02277         w.y0 = CX_MAX(0, _oy) + 1;
02278         w.y1 = w.y0 + _ny;
02279 
02280     }
02281 
02282     mean = cpl_image_get_mean_window(_rimage, w.x0, w.y0, w.x1, w.y1);
02283 
02284     pixels = cpl_image_get_data(_rimage);
02285     npixel = cpl_image_get_size_x(_rimage) * cpl_image_get_size_y(_rimage);
02286 
02287     for (i = 0; i < npixel; i++) {
02288         if (pixels[i] > saturation) {
02289             ++nsaturated;
02290         }
02291     }
02292 
02293 
02294     properties = giraffe_image_get_properties(pimage);
02295     cx_assert(properties != NULL);
02296 
02297     cpl_propertylist_update_double(properties, GIALIAS_QCMEAN, mean);
02298     cpl_propertylist_set_comment(properties, GIALIAS_QCMEAN, "Mean level of "
02299                                  "first raw frame");
02300 
02301     giraffe_propertylist_copy(qclog, "QC.OUT1.MEAN.RAW", properties,
02302                               GIALIAS_QCMEAN);
02303 
02304 
02305     cpl_propertylist_update_int(properties, GIALIAS_QCNSAT, nsaturated);
02306     cpl_propertylist_set_comment(properties, GIALIAS_QCNSAT, "Number of "
02307                                  "saturated pixels in the first raw frame");
02308 
02309     giraffe_propertylist_copy(qclog, "QC.OUT1.NSAT.RAW", properties,
02310                               GIALIAS_QCNSAT);
02311 
02312 
02313     /*
02314      * Calibration lamp monitoring
02315      */
02316 
02317     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
02318     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
02319                                  "Calibration lamp efficiency");
02320 
02321     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
02322                               GIALIAS_QCLAMP);
02323 
02324     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
02325                                    efficiency[1]);
02326     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
02327                                  "SIMCAL lamp efficiency");
02328 
02329     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
02330                               GIALIAS_QCLAMP_SIMCAL);
02331 
02332 
02333     /*
02334      * Write QC1 log and save updated master flat field.
02335      */
02336 
02337     giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
02338 
02339     giraffe_image_delete(pimage);
02340     pimage = NULL;
02341 
02342     giraffe_qclog_close(qc);
02343     qc = NULL;
02344 
02345 
02346     /*
02347      * Process fiber localization centroid
02348      */
02349 
02350     qc = giraffe_qclog_open(1);
02351 
02352     if (qc == NULL) {
02353         cpl_msg_error(fctid, "Cannot create QC1 log!");
02354 
02355         giraffe_image_delete(rimage);
02356         rimage = NULL;
02357 
02358         return 1;
02359     }
02360 
02361     qclog = giraffe_paf_get_properties(qc);
02362     cx_assert(qclog != NULL);
02363 
02364     pframe = giraffe_get_frame(set, GIFRAME_LOCALIZATION_CENTROID,
02365                                CPL_FRAME_GROUP_PRODUCT);
02366 
02367     if (pframe == NULL) {
02368         cpl_msg_error(fctid, "Missing product frame (%s)",
02369                       GIFRAME_LOCALIZATION_CENTROID);
02370 
02371         giraffe_paf_delete(qc);
02372         qc = NULL;
02373 
02374         giraffe_image_delete(rimage);
02375         rimage = NULL;
02376 
02377         return 1;
02378     }
02379 
02380     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
02381                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
02382 
02383 
02384     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02385     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
02386 
02387     if (status != 0) {
02388         cpl_msg_error(fctid, "Could not load localization centroids '%s'!",
02389                       cpl_frame_get_filename(pframe));
02390 
02391         giraffe_image_delete(pimage);
02392         pimage = NULL;
02393 
02394         giraffe_image_delete(rimage);
02395         rimage = NULL;
02396 
02397         giraffe_paf_delete(qc);
02398         qc = NULL;
02399 
02400         return 1;
02401     }
02402 
02403     ptable = giraffe_table_new();
02404     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
02405                                 NULL);
02406 
02407     if (status != 0) {
02408         cpl_msg_error(fctid, "Could not load localization centroids '%s'!",
02409                       cpl_frame_get_filename(pframe));
02410 
02411         giraffe_table_delete(ptable);
02412         ptable = NULL;
02413 
02414         giraffe_image_delete(pimage);
02415         pimage = NULL;
02416 
02417         giraffe_image_delete(rimage);
02418         rimage = NULL;
02419 
02420         giraffe_paf_delete(qc);
02421         qc = NULL;
02422 
02423         return 1;
02424     }
02425 
02426     properties = giraffe_image_get_properties(rimage);
02427     cx_assert(properties != NULL);
02428 
02429     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
02430     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
02431     giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
02432                               GIALIAS_SETUPNAME);
02433     giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
02434                               GIALIAS_SLITNAME);
02435     giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
02436                               GIALIAS_GRATWLEN);
02437     giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
02438 
02439     cpl_propertylist_update_string(qclog, "PRO.CATG",
02440                                    cpl_frame_get_tag(pframe));
02441     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02442                                  "Pipeline product category");
02443 
02444     properties = giraffe_image_get_properties(pimage);
02445     cx_assert(properties != NULL);
02446 
02447     giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
02448                               GIALIAS_DATAMEAN);
02449     giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
02450                               GIALIAS_DATASIG);
02451     giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
02452                               GIALIAS_DATAMEDI);
02453     giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
02454                               GIALIAS_DATANCOM);
02455     giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
02456                               GIALIAS_NFIBERS);
02457 
02458 
02459     /*
02460      * Calibration lamp monitoring
02461      */
02462 
02463     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
02464     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
02465                                  "Calibration lamp efficiency");
02466 
02467     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
02468                               GIALIAS_QCLAMP);
02469 
02470     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
02471                                    efficiency[1]);
02472     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
02473                                  "SIMCAL lamp efficiency");
02474 
02475     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
02476                               GIALIAS_QCLAMP_SIMCAL);
02477 
02478 
02479     /* Fiber signal curvature RMS */
02480 
02481     _pimage = giraffe_image_get(pimage);
02482 
02483     _test = cpl_image_collapse_create(_pimage, 0);
02484     cpl_image_divide_scalar(_test, cpl_image_get_size_y(_pimage));
02485 
02486     _pdata = cpl_image_get_data(_pimage);
02487     _tdata = cpl_image_get_data(_test);
02488 
02489     rms = 0.;
02490 
02491     nx = cpl_image_get_size_x(_pimage);
02492     ny = cpl_image_get_size_y(_pimage);
02493 
02494     for (i = 0; i < nx; i++) {
02495 
02496         cxint j;
02497 
02498         cxdouble _rms = 0.;
02499 
02500 
02501         for (j = 0; j < ny; j++) {
02502             _rms += pow(_pdata[j * nx + i] - _tdata[i], 2.);
02503         }
02504 
02505         rms += sqrt(_rms / (ny - 1));
02506 
02507     }
02508 
02509     rms /= nx;
02510 
02511     cpl_image_delete(_test);
02512     _test = NULL;
02513 
02514     cpl_propertylist_update_double(properties, GIALIAS_QCLCRMS, rms);
02515     cpl_propertylist_set_comment(properties, GIALIAS_QCLCRMS,
02516                                  "Mean fibre signal curvature");
02517 
02518     giraffe_propertylist_copy(qclog, "QC.FIBRE.CENTROID.RMS", properties,
02519                               GIALIAS_QCLCRMS);
02520 
02521 
02522     /* Difference of fiber signal curvature */
02523 
02524     diff = 0.;
02525 
02526     for (i = 0; i < nx; i++) {
02527 
02528         cxdouble min = cpl_image_get_min_window(_pimage,
02529                                                 i + 1, 1, i + 1, ny);
02530         cxdouble max = cpl_image_get_max_window(_pimage,
02531                                                 i + 1, 1, i + 1, ny);
02532 
02533         diff += max - min;
02534 
02535     }
02536 
02537     diff /= nx;
02538 
02539     cpl_propertylist_update_double(properties, GIALIAS_QCLCDIFF, diff);
02540     cpl_propertylist_set_comment(properties, GIALIAS_QCLCDIFF,
02541                                  "Mean difference of fibre signal "
02542                                  "curvature");
02543 
02544     giraffe_propertylist_copy(qclog, "QC.FIBRE.CENTROID.DIFF", properties,
02545                               GIALIAS_QCLCDIFF);
02546 
02547 
02548     status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
02549 
02550     if (status != 0) {
02551         cpl_msg_error(fctid, "Could not save localization centroids '%s'!",
02552                       cpl_frame_get_filename(pframe));
02553 
02554         giraffe_table_delete(ptable);
02555         ptable = NULL;
02556 
02557         giraffe_image_delete(pimage);
02558         pimage = NULL;
02559 
02560         giraffe_image_delete(rimage);
02561         rimage = NULL;
02562 
02563         giraffe_paf_delete(qc);
02564         qc = NULL;
02565 
02566         return 1;
02567     }
02568 
02569     status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
02570                                   1, NULL);
02571 
02572     if (status != 0) {
02573         cpl_msg_error(fctid, "Could not save localization centroids '%s'!",
02574                       cpl_frame_get_filename(pframe));
02575 
02576         giraffe_table_delete(ptable);
02577         ptable = NULL;
02578 
02579         giraffe_image_delete(pimage);
02580         pimage = NULL;
02581 
02582         giraffe_image_delete(rimage);
02583         rimage = NULL;
02584 
02585         giraffe_paf_delete(qc);
02586         qc = NULL;
02587 
02588         return 1;
02589     }
02590 
02591     giraffe_image_delete(pimage);
02592     pimage = NULL;
02593 
02594     giraffe_table_delete(ptable);
02595     ptable = NULL;
02596 
02597     giraffe_qclog_close(qc);
02598     qc = NULL;
02599 
02600 
02601     /*
02602      * Process fiber localization width
02603      */
02604 
02605     qc = giraffe_qclog_open(2);
02606 
02607     if (qc == NULL) {
02608         cpl_msg_error(fctid, "Cannot create QC1 log!");
02609 
02610         giraffe_image_delete(rimage);
02611         rimage = NULL;
02612 
02613         return 1;
02614     }
02615 
02616     qclog = giraffe_paf_get_properties(qc);
02617     cx_assert(qclog != NULL);
02618 
02619     pframe = giraffe_get_frame(set, GIFRAME_LOCALIZATION_WIDTH,
02620                                CPL_FRAME_GROUP_PRODUCT);
02621 
02622     if (pframe == NULL) {
02623         cpl_msg_error(fctid, "Missing product frame (%s)",
02624                       GIFRAME_LOCALIZATION_WIDTH);
02625 
02626         giraffe_paf_delete(qc);
02627         qc = NULL;
02628 
02629         giraffe_image_delete(rimage);
02630         rimage = NULL;
02631 
02632         return 1;
02633     }
02634 
02635     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
02636                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
02637 
02638 
02639     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02640     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
02641 
02642     if (status != 0) {
02643         cpl_msg_error(fctid, "Could not load localization widths '%s'!",
02644                       cpl_frame_get_filename(pframe));
02645 
02646         giraffe_image_delete(pimage);
02647         pimage = NULL;
02648 
02649         giraffe_image_delete(rimage);
02650         rimage = NULL;
02651 
02652         giraffe_paf_delete(qc);
02653         qc = NULL;
02654 
02655         return 1;
02656     }
02657 
02658     ptable = giraffe_table_new();
02659     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
02660                                 NULL);
02661 
02662     if (status != 0) {
02663         cpl_msg_error(fctid, "Could not load localization widths '%s'!",
02664                       cpl_frame_get_filename(pframe));
02665 
02666         giraffe_table_delete(ptable);
02667         ptable = NULL;
02668 
02669         giraffe_image_delete(pimage);
02670         pimage = NULL;
02671 
02672         giraffe_image_delete(rimage);
02673         rimage = NULL;
02674 
02675         giraffe_paf_delete(qc);
02676         qc = NULL;
02677 
02678         return 1;
02679     }
02680 
02681     properties = giraffe_image_get_properties(rimage);
02682     cx_assert(properties != NULL);
02683 
02684     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
02685     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
02686     giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
02687                               GIALIAS_SETUPNAME);
02688     giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
02689                               GIALIAS_SLITNAME);
02690     giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
02691                               GIALIAS_GRATWLEN);
02692     giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
02693 
02694     cpl_propertylist_update_string(qclog, "PRO.CATG",
02695                                    cpl_frame_get_tag(pframe));
02696     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02697                                  "Pipeline product category");
02698 
02699     properties = giraffe_image_get_properties(pimage);
02700     cx_assert(properties != NULL);
02701 
02702     giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
02703                               GIALIAS_DATAMEAN);
02704     giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
02705                               GIALIAS_DATASIG);
02706     giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
02707                               GIALIAS_DATAMEDI);
02708     giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
02709                               GIALIAS_DATANCOM);
02710     giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
02711                               GIALIAS_NFIBERS);
02712 
02713 
02714     /*
02715      * Calibration lamp monitoring
02716      */
02717 
02718     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
02719     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
02720                                  "Calibration lamp efficiency");
02721 
02722     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
02723                               GIALIAS_QCLAMP);
02724 
02725     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
02726                                    efficiency[1]);
02727     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
02728                                  "SIMCAL lamp efficiency");
02729 
02730     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
02731                               GIALIAS_QCLAMP_SIMCAL);
02732 
02733 
02734     /* Compute fiber width statistics, i.e. the mean width and its RMS */
02735 
02736     _pimage = giraffe_image_get(pimage);
02737 
02738     _test = cpl_image_collapse_create(_pimage, 0);
02739     cpl_image_divide_scalar(_test, cpl_image_get_size_y(_pimage));
02740 
02741     _pdata = cpl_image_get_data(_pimage);
02742     _tdata = cpl_image_get_data(_test);
02743 
02744     mean = 0.;
02745     rms = 0.;
02746 
02747     nx = cpl_image_get_size_x(_pimage);
02748     ny = cpl_image_get_size_y(_pimage);
02749 
02750     for (i = 0; i < nx; i++) {
02751 
02752         cxint j;
02753 
02754         cxdouble _rms = 0.;
02755 
02756 
02757         for (j = 0; j < ny; j++) {
02758             _rms += pow(_pdata[j * nx + i] - _tdata[i], 2.);
02759         }
02760 
02761         mean += _tdata[i];
02762         rms += sqrt(_rms / (ny - 1));
02763 
02764     }
02765 
02766     mean /= nx;
02767     rms /= nx;
02768 
02769     cpl_image_delete(_test);
02770     _test = NULL;
02771 
02772 
02773     cpl_propertylist_update_double(properties, GIALIAS_QCLWAVG, mean);
02774     cpl_propertylist_set_comment(properties, GIALIAS_QCLWAVG,
02775                                  "Mean fibre half width");
02776 
02777     giraffe_propertylist_copy(qclog, "QC.FIBRE.WIDTH.MEAN", properties,
02778                               GIALIAS_QCLWAVG);
02779 
02780     cpl_propertylist_update_double(properties, GIALIAS_QCLWRMS, rms);
02781     cpl_propertylist_set_comment(properties, GIALIAS_QCLWRMS,
02782                                  "RMS of fibre half width");
02783 
02784     giraffe_propertylist_copy(qclog, "QC.FIBRE.WIDTH.RMS", properties,
02785                               GIALIAS_QCLWRMS);
02786 
02787 
02788     status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
02789 
02790     if (status != 0) {
02791         cpl_msg_error(fctid, "Could not save localization widths '%s'!",
02792                       cpl_frame_get_filename(pframe));
02793 
02794         giraffe_table_delete(ptable);
02795         ptable = NULL;
02796 
02797         giraffe_image_delete(pimage);
02798         pimage = NULL;
02799 
02800         giraffe_image_delete(rimage);
02801         rimage = NULL;
02802 
02803         giraffe_paf_delete(qc);
02804         qc = NULL;
02805 
02806         return 1;
02807     }
02808 
02809     status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
02810                                   1, NULL);
02811 
02812     if (status != 0) {
02813         cpl_msg_error(fctid, "Could not save localization widths '%s'!",
02814                       cpl_frame_get_filename(pframe));
02815 
02816         giraffe_table_delete(ptable);
02817         ptable = NULL;
02818 
02819         giraffe_image_delete(pimage);
02820         pimage = NULL;
02821 
02822         giraffe_image_delete(rimage);
02823         rimage = NULL;
02824 
02825         giraffe_paf_delete(qc);
02826         qc = NULL;
02827 
02828         return 1;
02829     }
02830 
02831     giraffe_image_delete(pimage);
02832     pimage = NULL;
02833 
02834     giraffe_table_delete(ptable);
02835     ptable = NULL;
02836 
02837     giraffe_qclog_close(qc);
02838     qc = NULL;
02839 
02840 
02841     /*
02842      * Process extracted flat field spectra
02843      */
02844 
02845     qc = giraffe_qclog_open(3);
02846 
02847     if (qc == NULL) {
02848         cpl_msg_error(fctid, "Cannot create QC1 log!");
02849 
02850         giraffe_image_delete(rimage);
02851         rimage = NULL;
02852 
02853         return 1;
02854     }
02855 
02856     qclog = giraffe_paf_get_properties(qc);
02857     cx_assert(qclog != NULL);
02858 
02859     pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_EXTSPECTRA,
02860                                CPL_FRAME_GROUP_PRODUCT);
02861 
02862     if (pframe == NULL) {
02863         cpl_msg_error(fctid, "Missing product frame (%s)",
02864                       GIFRAME_FIBER_FLAT_EXTSPECTRA);
02865 
02866         giraffe_paf_delete(qc);
02867         qc = NULL;
02868 
02869         giraffe_image_delete(rimage);
02870         rimage = NULL;
02871 
02872         return 1;
02873     }
02874 
02875     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
02876                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
02877 
02878 
02879     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02880     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
02881 
02882     if (status != 0) {
02883         cpl_msg_error(fctid, "Could not load extracted flat field spectra "
02884                       "'%s'!", cpl_frame_get_filename(pframe));
02885 
02886         giraffe_image_delete(pimage);
02887         pimage = NULL;
02888 
02889         giraffe_image_delete(rimage);
02890         rimage = NULL;
02891 
02892         giraffe_paf_delete(qc);
02893         qc = NULL;
02894 
02895         return 1;
02896     }
02897 
02898     ptable = giraffe_table_new();
02899     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
02900                                 NULL);
02901 
02902     if (status != 0) {
02903         cpl_msg_error(fctid, "Could not load extracted flat field spectra "
02904                       "'%s'!", cpl_frame_get_filename(pframe));
02905 
02906         giraffe_table_delete(ptable);
02907         ptable = NULL;
02908 
02909         giraffe_image_delete(pimage);
02910         pimage = NULL;
02911 
02912         giraffe_image_delete(rimage);
02913         rimage = NULL;
02914 
02915         giraffe_paf_delete(qc);
02916         qc = NULL;
02917 
02918         return 1;
02919     }
02920 
02921     properties = giraffe_image_get_properties(rimage);
02922     cx_assert(properties != NULL);
02923 
02924     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
02925     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
02926     giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
02927                               GIALIAS_SETUPNAME);
02928     giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
02929                               GIALIAS_SLITNAME);
02930     giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
02931                               GIALIAS_GRATWLEN);
02932     giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
02933 
02934     cpl_propertylist_update_string(qclog, "PRO.CATG",
02935                                    cpl_frame_get_tag(pframe));
02936     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02937                                  "Pipeline product category");
02938 
02939     properties = giraffe_image_get_properties(pimage);
02940     cx_assert(properties != NULL);
02941 
02942     giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
02943                               GIALIAS_DATAMEAN);
02944     giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
02945                               GIALIAS_DATASIG);
02946     giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
02947                               GIALIAS_DATAMEDI);
02948     giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
02949                               GIALIAS_DATANCOM);
02950     giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
02951                               GIALIAS_NFIBERS);
02952 
02953 
02954     /*
02955      * Calibration lamp monitoring
02956      */
02957 
02958     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
02959     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
02960                                  "Calibration lamp efficiency");
02961 
02962     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
02963                               GIALIAS_QCLAMP);
02964 
02965     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
02966                                    efficiency[1]);
02967     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
02968                                  "SIMCAL lamp efficiency");
02969 
02970     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
02971                               GIALIAS_QCLAMP_SIMCAL);
02972 
02973 
02974     _ptable = giraffe_table_get(ptable);
02975 
02976     if (cpl_table_has_column(_ptable, "TRANSMISSION") == FALSE) {
02977         cpl_msg_warning(fctid, "Relative fiber transmission not available! "
02978                         "QC parameter computation skipped.");
02979     }
02980     else {
02981 
02982         const cxdouble low = 0.5;
02983         const cxdouble high = 2.0;
02984 
02985         cxint nf = 0;
02986         
02987         cxdouble t = 0.;
02988         cxdouble dt = 0.;
02989 
02990         cpl_table* ttable = NULL;
02991 
02992 
02993         rms = 0.;
02994 
02995         cpl_table_unselect_all(_ptable);
02996 
02997         cpl_table_or_selected_int(_ptable, "RP", CPL_GREATER_THAN, 0);
02998         cpl_table_and_selected_double(_ptable, "TRANSMISSION",
02999                                       CPL_GREATER_THAN, low);
03000         cpl_table_and_selected_double(_ptable, "TRANSMISSION",
03001                                       CPL_LESS_THAN, high);
03002 
03003         ttable = cpl_table_extract_selected(_ptable);
03004 
03005         nf = cpl_table_get_nrow(ttable);
03006         if (ttable == NULL || nf <= 0) {
03007             cpl_msg_warning(fctid, "No fiber found within transmission "
03008                             "range ]%.2f, %.2f[", low, high);
03009 
03010         }
03011         else {
03012 
03013             t = cpl_table_get_column_median(ttable, "TRANSMISSION");
03014 
03015             if (nf > 1) {
03016 
03017                 for (i = 0; i < cpl_table_get_nrow(ttable); i++) {
03018 
03019                     cxdouble _t = cpl_table_get_double(ttable,
03020                             "TRANSMISSION", i, NULL);
03021                     rms += pow(_t - t, 2.);
03022 
03023                 }
03024 
03025                 rms = sqrt(rms / (cpl_table_get_nrow(ttable) - 1));
03026                 
03027             }
03028             else {
03029                 rms = 0.;
03030             }
03031                 
03032 
03033         }
03034 
03035         if (!cpl_table_has_column(_ptable, "DTRANSMISSION")) {
03036             cpl_msg_warning(fctid, "Relative fiber transmission error not "
03037                             "available! QC parameter computation skipped.");
03038         }
03039         else {
03040 
03041             cx_assert(cpl_table_has_column(ttable, "DTRANSMISSION") != 0);
03042             dt = cpl_table_get_column_median(ttable, "DTRANSMISSION");
03043 
03044         }
03045 
03046         cpl_table_delete(ttable);
03047         ttable = NULL;
03048 
03049 
03050         cpl_propertylist_update_double(properties, GIALIAS_QCTRMED, t);
03051         cpl_propertylist_set_comment(properties, GIALIAS_QCTRMED, "Median of "
03052                               "relative fibre transmission");
03053 
03054         giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.MEDIAN", properties,
03055                            GIALIAS_QCTRMED);
03056 
03057 
03058         cpl_propertylist_update_double(properties, GIALIAS_QCTRRMS, rms);
03059         cpl_propertylist_set_comment(properties, GIALIAS_QCTRRMS, "RMS of "
03060                               "relative fibre transmission");
03061 
03062         giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.RMS", properties,
03063                            GIALIAS_QCTRRMS);
03064 
03065 
03066         cpl_propertylist_update_double(properties, GIALIAS_QCTRERR, dt);
03067         cpl_propertylist_set_comment(properties, GIALIAS_QCTRERR, "Median of "
03068                               "relative fibre transmission error");
03069 
03070         giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.ERROR", properties,
03071                            GIALIAS_QCTRERR);
03072 
03073         
03074         //FIXME: Check whether this number is useful!
03075 #if 0
03076         cpl_propertylist_update_int(properties, GIALIAS_QCTRNF, nf);
03077         cpl_propertylist_set_comment(properties, GIALIAS_QCTRNF, "Number "
03078                 "of fibres used for median transmission computation.");
03079 
03080         giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.NFIBRES",
03081                 properties, GIALIAS_QCTRNF);
03082 #endif
03083         cpl_msg_debug(fctid, "%d fibers used for median transmission "
03084                 "computation.", nf);
03085         
03086     }
03087 
03088     status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
03089 
03090     if (status != 0) {
03091         cpl_msg_error(fctid, "Could not save extracted flat field spectra "
03092                       "'%s'!", cpl_frame_get_filename(pframe));
03093 
03094         giraffe_table_delete(ptable);
03095         ptable = NULL;
03096 
03097         giraffe_image_delete(pimage);
03098         pimage = NULL;
03099 
03100         giraffe_image_delete(rimage);
03101         rimage = NULL;
03102 
03103         giraffe_paf_delete(qc);
03104         qc = NULL;
03105 
03106         return 1;
03107     }
03108 
03109     status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
03110                                   1, NULL);
03111 
03112     if (status != 0) {
03113         cpl_msg_error(fctid, "Could not save extracted flat field spectra "
03114                       "'%s'!", cpl_frame_get_filename(pframe));
03115 
03116         giraffe_table_delete(ptable);
03117         ptable = NULL;
03118 
03119         giraffe_image_delete(pimage);
03120         pimage = NULL;
03121 
03122         giraffe_image_delete(rimage);
03123         rimage = NULL;
03124 
03125         giraffe_paf_delete(qc);
03126         qc = NULL;
03127 
03128         return 1;
03129     }
03130 
03131     giraffe_image_delete(pimage);
03132     pimage = NULL;
03133 
03134     giraffe_table_delete(ptable);
03135     ptable = NULL;
03136 
03137     giraffe_qclog_close(qc);
03138     qc = NULL;
03139 
03140 
03141     /*
03142      * Cleanup
03143      */
03144 
03145     giraffe_image_delete(rimage);
03146 
03147     return 0;
03148 
03149 }
03150 
03151 
03152 /*
03153  * Build table of contents, i.e. the list of available plugins, for
03154  * this module. This function is exported.
03155  */
03156 
03157 int
03158 cpl_plugin_get_info(cpl_pluginlist* list)
03159 {
03160 
03161     cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
03162     cpl_plugin* plugin = &recipe->interface;
03163 
03164 
03165     cpl_plugin_init(plugin,
03166                     CPL_PLUGIN_API,
03167                     GIRAFFE_BINARY_VERSION,
03168                     CPL_PLUGIN_TYPE_RECIPE,
03169                     "gimasterflat",
03170                     "Create the fiber master flat field and the "
03171                     "localization mask.",
03172                     "For detailed information please refer to the "
03173                     "GIRAFFE pipeline user manual.\nIt is available at "
03174                     "http://www.eso.org/pipelines.",
03175                     "Giraffe Pipeline",
03176                     PACKAGE_BUGREPORT,
03177                     giraffe_get_license(),
03178                     gimasterflat_create,
03179                     gimasterflat_exec,
03180                     gimasterflat_destroy);
03181 
03182     cpl_pluginlist_append(list, plugin);
03183 
03184     return 0;
03185 
03186 }

This file is part of the GIRAFFE Pipeline Reference Manual 2.5.3.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Fri Jul 18 09:49:46 2008 by doxygen 1.4.6 written by Dimitri van Heesch, © 1997-2004