GIRAFFE Pipeline Reference Manual

gimasterflat.c

00001 /* $Id: gimasterflat.c,v 1.46.2.1 2008/02/21 11:03:29 rpalsa Exp $
00002  *
00003  * This file is part of the GIRAFFE Pipeline
00004  * Copyright (C) 2002-2006 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 /*
00022  * $Author: rpalsa $
00023  * $Date: 2008/02/21 11:03:29 $
00024  * $Revision: 1.46.2.1 $
00025  * $Name: giraffe-2_5_1 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #  include <config.h>
00030 #endif
00031 
00032 #include <math.h>
00033 
00034 #include <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         fibers = giraffe_fibers_setup(flat_frame, mlocy_frame);
00771 
00772         if (!fibers) {
00773             cpl_msg_error(_id, "Cannot create fiber setup for frame '%s'! "
00774                           "Aborting ...", cpl_frame_get_filename(flat_frame));
00775 
00776             giraffe_image_delete(mflat);
00777 
00778             if (bpixel) {
00779                 giraffe_image_delete(bpixel);
00780             }
00781 
00782             giraffe_fibers_config_destroy(fibers_config);
00783 
00784             return 1;
00785         }
00786 
00787         cpl_msg_info(_id, "Fiber reference setup taken from localization "
00788                      "frame '%s'.", cpl_frame_get_filename(mlocy_frame));
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      * Compute localization mask from the PSF profile of the fibers
01020      */
01021 
01022     psf_config = giraffe_psf_config_create(config);
01023 
01024     if (psf_config == NULL) {
01025         cpl_msg_error(_id, "Invalid fiber profile fit configuration!");
01026 
01027         giraffe_localization_destroy(sloc);
01028         sloc = NULL;
01029 
01030         giraffe_table_delete(fibers);
01031         fibers = NULL;
01032 
01033         giraffe_image_delete(mflat);
01034         mflat = NULL;
01035 
01036         if (bpixel != NULL) {
01037             giraffe_image_delete(bpixel);
01038             bpixel = NULL;
01039         }
01040 
01041         return 1;
01042 
01043     }
01044 
01045     ploc = giraffe_localization_new();
01046 
01047     status = giraffe_compute_fiber_profiles(ploc, mflat, fibers, sloc,
01048                                             bpixel, psf_config);
01049 
01050     if (status != 0) {
01051         cpl_msg_error(_id, "Fiber profile computation failed! Aborting ...");
01052 
01053         giraffe_localization_destroy(ploc);
01054         ploc = NULL;
01055 
01056         giraffe_psf_config_destroy(psf_config);
01057         psf_config = NULL;
01058 
01059         giraffe_localization_destroy(sloc);
01060         sloc = NULL;
01061 
01062         giraffe_table_delete(fibers);
01063         fibers = NULL;
01064 
01065         giraffe_image_delete(mflat);
01066         mflat = NULL;
01067 
01068         if (bpixel != NULL) {
01069             giraffe_image_delete(bpixel);
01070             bpixel = NULL;
01071         }
01072 
01073         return 1;
01074 
01075     }
01076 
01077     giraffe_psf_config_destroy(psf_config);
01078     psf_config = NULL;
01079 
01080     giraffe_localization_destroy(sloc);
01081     sloc = NULL;
01082 
01083 
01084     /*
01085      * Save the computed fiber traces and register its components as
01086      * products.
01087      */
01088 
01089     cpl_msg_info(_id, "Writing fiber traces ...");
01090 
01091 
01092     /* Fiber profile centroids */
01093 
01094     giraffe_image_add_info(ploc->locy, &info, set);
01095 
01096     ploc_frame = giraffe_frame_create_image(ploc->locy,
01097                                             GIFRAME_PSF_CENTROID,
01098                                             CPL_FRAME_LEVEL_FINAL,
01099                                             TRUE, TRUE);
01100 
01101     if (ploc_frame == NULL) {
01102         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01103 
01104         giraffe_localization_destroy(ploc);
01105         ploc = NULL;
01106 
01107         giraffe_table_delete(fibers);
01108         fibers = NULL;
01109 
01110         giraffe_image_delete(mflat);
01111         mflat = NULL;
01112 
01113         if (bpixel != NULL) {
01114             giraffe_image_delete(bpixel);
01115             bpixel = NULL;
01116         }
01117 
01118         return 1;
01119     }
01120 
01121     status = giraffe_fiberlist_attach(ploc_frame, fibers);
01122 
01123     if (status != 0) {
01124         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01125                       "Aborting ...", cpl_frame_get_filename(ploc_frame));
01126 
01127         cpl_frame_delete(ploc_frame);
01128 
01129         giraffe_localization_destroy(ploc);
01130         ploc = NULL;
01131 
01132         giraffe_table_delete(fibers);
01133         fibers = NULL;
01134 
01135         giraffe_image_delete(mflat);
01136         mflat = NULL;
01137 
01138         if (bpixel != NULL) {
01139             giraffe_image_delete(bpixel);
01140             bpixel = NULL;
01141         }
01142 
01143         return 1;
01144     }
01145 
01146     cpl_frameset_insert(set, ploc_frame);
01147 
01148 
01149     /* Fiber profile widths */
01150 
01151     giraffe_image_add_info(ploc->locw, &info, set);
01152 
01153     ploc_frame = giraffe_frame_create_image(ploc->locw,
01154                                             GIFRAME_PSF_WIDTH,
01155                                             CPL_FRAME_LEVEL_FINAL,
01156                                             TRUE, TRUE);
01157 
01158     if (ploc_frame == NULL) {
01159         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01160 
01161         giraffe_localization_destroy(ploc);
01162         ploc = NULL;
01163 
01164         giraffe_table_delete(fibers);
01165         fibers = NULL;
01166 
01167         giraffe_image_delete(mflat);
01168         mflat = NULL;
01169 
01170         if (bpixel != NULL) {
01171             giraffe_image_delete(bpixel);
01172             bpixel = NULL;
01173         }
01174 
01175         return 1;
01176     }
01177 
01178     status = giraffe_fiberlist_attach(ploc_frame, fibers);
01179 
01180     if (status != 0) {
01181         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01182                       "Aborting ...", cpl_frame_get_filename(ploc_frame));
01183 
01184         cpl_frame_delete(ploc_frame);
01185 
01186         giraffe_localization_destroy(ploc);
01187         ploc = NULL;
01188 
01189         giraffe_table_delete(fibers);
01190         fibers = NULL;
01191 
01192         giraffe_image_delete(mflat);
01193         mflat = NULL;
01194 
01195         if (bpixel != NULL) {
01196             giraffe_image_delete(bpixel);
01197             bpixel = NULL;
01198         }
01199 
01200         return 1;
01201     }
01202 
01203     cpl_frameset_insert(set, ploc_frame);
01204 
01205 
01206     /* Fiber profile centroid and widths fit coefficients */
01207 
01208     giraffe_table_add_info(ploc->locc, &info, set);
01209 
01210     ploc_frame = giraffe_frame_create_table(ploc->locc,
01211                                             GIFRAME_PSF_FIT,
01212                                             CPL_FRAME_LEVEL_FINAL,
01213                                             TRUE, TRUE);
01214 
01215     if (ploc_frame == NULL) {
01216         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01217 
01218         giraffe_localization_destroy(ploc);
01219         ploc = NULL;
01220 
01221         giraffe_table_delete(fibers);
01222         fibers = NULL;
01223 
01224         giraffe_image_delete(mflat);
01225         mflat = NULL;
01226 
01227         if (bpixel != NULL) {
01228             giraffe_image_delete(bpixel);
01229             bpixel = NULL;
01230         }
01231 
01232         return 1;
01233     }
01234 
01235     status = giraffe_fiberlist_attach(ploc_frame, fibers);
01236 
01237     if (status != 0) {
01238         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01239                       "Aborting ...", cpl_frame_get_filename(ploc_frame));
01240 
01241         cpl_frame_delete(ploc_frame);
01242 
01243         giraffe_localization_destroy(ploc);
01244         ploc = NULL;
01245 
01246         giraffe_table_delete(fibers);
01247         fibers = NULL;
01248 
01249         giraffe_image_delete(mflat);
01250         mflat = NULL;
01251 
01252         if (bpixel != NULL) {
01253             giraffe_image_delete(bpixel);
01254             bpixel = NULL;
01255         }
01256 
01257         return 1;
01258     }
01259 
01260     cpl_frameset_insert(set, ploc_frame);
01261 
01262 
01263     if (ploc->psf) {
01264 
01265         GiFrameCreator creator = (GiFrameCreator) giraffe_psfdata_save;
01266 
01267         properties = giraffe_image_get_properties(ploc->locy);
01268 
01269         ploc_frame = giraffe_frame_create(GIFRAME_PSF_DATA,
01270                                           CPL_FRAME_LEVEL_FINAL,
01271                                           properties, ploc->psf,
01272                                           NULL,
01273                                           creator);
01274 
01275         if (ploc_frame == NULL) {
01276             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01277 
01278             giraffe_localization_destroy(ploc);
01279             ploc = NULL;
01280 
01281             giraffe_table_delete(fibers);
01282             fibers = NULL;
01283 
01284             giraffe_image_delete(mflat);
01285             mflat = NULL;
01286 
01287             if (bpixel != NULL) {
01288                 giraffe_image_delete(bpixel);
01289                 bpixel = NULL;
01290             }
01291 
01292             return 1;
01293         }
01294 
01295         status = giraffe_fiberlist_attach(ploc_frame, fibers);
01296 
01297         if (status != 0) {
01298             cpl_msg_error(_id, "Cannot attach fiber setup to local "
01299                           "file '%s'! Aborting ...",
01300                           cpl_frame_get_filename(ploc_frame));
01301 
01302             cpl_frame_delete(ploc_frame);
01303 
01304             giraffe_localization_destroy(ploc);
01305             ploc = NULL;
01306 
01307             giraffe_table_delete(fibers);
01308             fibers = NULL;
01309 
01310             giraffe_image_delete(mflat);
01311             mflat = NULL;
01312 
01313             if (bpixel != NULL) {
01314                 giraffe_image_delete(bpixel);
01315                 bpixel = NULL;
01316             }
01317 
01318             return 1;
01319         }
01320 
01321         cpl_frameset_insert(set, ploc_frame);
01322 
01323     }
01324 
01325 
01326     /*
01327      * Optional scattered light model computation
01328      */
01329 
01330     // FIXME: Check whether scattered light modeling code should stay here!
01331 
01332     if (slmodel == TRUE) {
01333 
01334         cpl_frame* slmodel_frame = NULL;
01335 
01336         GiSLightConfig* slight_config = NULL;
01337 
01338 
01339         cpl_msg_info(_id, "Computing scattered light model ...");
01340 
01341         slight_config = giraffe_slight_config_create(config);
01342 
01343         if (slight_config == NULL) {
01344             cpl_msg_error(_id, "Invalid scattered light model "
01345                           "configuration!");
01346 
01347             giraffe_table_delete(fibers);
01348             giraffe_image_delete(mflat);
01349 
01350             if (bpixel) {
01351                 giraffe_image_delete(bpixel);
01352             }
01353 
01354             giraffe_localization_destroy(ploc);
01355             ploc = NULL;
01356 
01357             return 1;
01358 
01359         }
01360 
01361         slight = giraffe_image_new(CPL_TYPE_DOUBLE);
01362 
01363         status = giraffe_adjust_scattered_light(slight, mflat, ploc,
01364                                                 bpixel, NULL, slight_config);
01365 
01366         if (status != 0) {
01367             cpl_msg_error(_id, "Scattered light model computation failed! "
01368                           "Aborting ...");
01369 
01370             giraffe_image_delete(slight);
01371 
01372             giraffe_slight_config_destroy(slight_config);
01373 
01374             giraffe_table_delete(fibers);
01375             giraffe_image_delete(mflat);
01376 
01377             if (bpixel != NULL) {
01378                 giraffe_image_delete(bpixel);
01379                 bpixel = NULL;
01380             }
01381 
01382             giraffe_localization_destroy(ploc);
01383             ploc = NULL;
01384 
01385             return 1;
01386         }
01387 
01388 
01389         giraffe_slight_config_destroy(slight_config);
01390         slight_config = NULL;
01391 
01392 
01393         /*
01394          * Save scattered light model
01395          */
01396 
01397         cpl_msg_info(_id, "Writing scattered light model ...");
01398 
01399         giraffe_image_add_info(slight, &info, set);
01400 
01401         slmodel_frame =
01402             giraffe_frame_create_image(slight,
01403                                        GIFRAME_SCATTERED_LIGHT_MODEL,
01404                                        CPL_FRAME_LEVEL_FINAL,
01405                                        TRUE, TRUE);
01406 
01407         if (slmodel_frame == NULL) {
01408             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01409 
01410             giraffe_image_delete(slight);
01411 
01412             giraffe_table_delete(fibers);
01413             giraffe_image_delete(mflat);
01414 
01415             if (bpixel != NULL) {
01416                 giraffe_image_delete(bpixel);
01417                 bpixel = NULL;
01418             }
01419 
01420             giraffe_localization_destroy(ploc);
01421             ploc = NULL;
01422 
01423             return 1;
01424         }
01425 
01426         cpl_frameset_insert(set, slmodel_frame);
01427 
01428         giraffe_image_delete(slight);
01429         slight = NULL;
01430 
01431     }
01432 
01433 
01434     /*
01435      * Perform spectrum extraction on the master flat field.
01436      */
01437 
01438     cpl_msg_info(_id, "Extracting spectra ...");
01439 
01440     if (slight_frame != NULL) {
01441 
01442         const cxchar* filename = cpl_frame_get_filename(slight_frame);
01443 
01444 
01445         slight = giraffe_image_new(CPL_TYPE_DOUBLE);
01446         status = giraffe_image_load(slight, filename, 0);
01447 
01448         if (status != 0) {
01449             cpl_msg_error(_id, "Cannot load scattered light model from '%s'. "
01450                           "Aborting ...", filename);
01451 
01452             giraffe_image_delete(slight);
01453 
01454             giraffe_table_delete(fibers);
01455             giraffe_image_delete(mflat);
01456 
01457             if (bpixel != NULL) {
01458                 giraffe_image_delete(bpixel);
01459                 bpixel = NULL;
01460             }
01461 
01462             giraffe_localization_destroy(ploc);
01463             ploc = NULL;
01464 
01465             return 1;
01466 
01467         }
01468 
01469     }
01470 
01471     extract_config = giraffe_extract_config_create(config);
01472 
01473     extraction = giraffe_extraction_new();
01474 
01475     status = giraffe_extract_spectra(extraction, mflat, fibers,
01476                                      ploc, bpixel, slight,
01477                                      extract_config);
01478 
01479     if (status != 0) {
01480         cpl_msg_error(_id, "Spectrum extraction failed! Aborting ...");
01481 
01482         giraffe_extraction_destroy(extraction);
01483 
01484         giraffe_image_delete(slight);
01485 
01486         giraffe_localization_destroy(ploc);
01487         ploc = NULL;
01488 
01489         giraffe_table_delete(fibers);
01490         giraffe_image_delete(mflat);
01491 
01492         if (bpixel != NULL) {
01493             giraffe_image_delete(bpixel);
01494             bpixel = NULL;
01495         }
01496 
01497         giraffe_extract_config_destroy(extract_config);
01498 
01499         return 1;
01500     }
01501 
01502     giraffe_image_delete(slight);
01503     giraffe_image_delete(mflat);
01504 
01505     if (bpixel != NULL) {
01506         giraffe_image_delete(bpixel);
01507         bpixel = NULL;
01508     }
01509 
01510     giraffe_extract_config_destroy(extract_config);
01511 
01512 
01513     /*
01514      * Normalize extracted spectra and errors
01515      */
01516 
01517     mean = cpl_image_get_mean(giraffe_image_get(extraction->spectra));
01518 
01519     cpl_image_divide_scalar(giraffe_image_get(extraction->spectra), mean);
01520 
01521     properties = giraffe_image_get_properties(extraction->spectra);
01522     cpl_propertylist_update_double(properties, GIALIAS_FLAT_SCALE, mean);
01523     cpl_propertylist_set_comment(properties, GIALIAS_FLAT_SCALE,
01524                                  "Flat field scale factor");
01525 
01526 
01527     cpl_image_divide_scalar(giraffe_image_get(extraction->error), mean);
01528 
01529     properties = giraffe_image_get_properties(extraction->error);
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     /*
01536      * Compute relative fiber transmission correction.
01537      */
01538 
01539     if (transmission == TRUE) {
01540 
01541         const cxchar* filename = NULL;
01542 
01543 
01544         transmission_config = giraffe_transmission_config_create(config);
01545 
01546         cpl_msg_info(_id, "Computing relative fiber transmission ...");
01547 
01548         filename  = cpl_frame_get_filename(grating_frame);
01549 
01550         grating = giraffe_table_new();
01551         status = giraffe_table_load(grating, filename, 1, NULL);
01552 
01553         if (status != 0) {
01554             cpl_msg_error(_id, "Cannot load grating data from '%s'. "
01555                           "Aborting ...", filename);
01556 
01557             giraffe_table_delete(grating);
01558 
01559             giraffe_transmission_config_destroy(transmission_config);
01560 
01561             giraffe_extraction_destroy(extraction);
01562 
01563             giraffe_localization_destroy(ploc);
01564             ploc = NULL;
01565 
01566             giraffe_table_delete(fibers);
01567 
01568             return 1;
01569         }
01570 
01571 
01572         filename = cpl_frame_get_filename(slit_frame);
01573 
01574         slitgeometry = giraffe_slitgeometry_load(fibers, filename, 1, NULL);
01575 
01576         if (slitgeometry == NULL) {
01577             cpl_msg_error(_id, "Cannot load slit geometry data from '%s'. "
01578                           "Aborting ...", filename);
01579 
01580             giraffe_table_delete(grating);
01581 
01582             giraffe_transmission_config_destroy(transmission_config);
01583 
01584             giraffe_extraction_destroy(extraction);
01585 
01586             giraffe_localization_destroy(ploc);
01587             ploc = NULL;
01588 
01589             giraffe_table_delete(fibers);
01590 
01591             return 1;
01592         }
01593         else {
01594 
01595             /*
01596              * Check whether the contains the positions for all fibers
01597              * provided by the fiber setup. If this is not the case
01598              * this is an error.
01599              */
01600 
01601             if (giraffe_fiberlist_compare(slitgeometry, fibers) != 1) {
01602                 cpl_msg_error(_id, "Slit geometry data from '%s' is not "
01603                               "applicable for current fiber setup! "
01604                               "Aborting ...", filename);
01605 
01606                 giraffe_table_delete(slitgeometry);
01607                 giraffe_table_delete(grating);
01608 
01609                 giraffe_transmission_config_destroy(transmission_config);
01610 
01611                 giraffe_extraction_destroy(extraction);
01612 
01613                 giraffe_localization_destroy(ploc);
01614                 ploc = NULL;
01615 
01616                 giraffe_table_delete(fibers);
01617 
01618                 return 1;
01619             }
01620 
01621         }
01622 
01623 
01624         if (wcal_frame != NULL) {
01625 
01626             filename = cpl_frame_get_filename(wcal_frame);
01627 
01628             cpl_msg_info(_id, "Loading wavelength solution from '%s'",
01629                          filename);
01630 
01631             wlsolution = giraffe_table_new();
01632             status = giraffe_table_load(wlsolution, filename, 1, NULL);
01633 
01634             if (status != 0) {
01635                 cpl_msg_error(_id, "Cannot load wavelength solution from "
01636                               "'%s'. Aborting ...", filename);
01637 
01638                 giraffe_table_delete(wlsolution);
01639                 giraffe_table_delete(slitgeometry);
01640                 giraffe_table_delete(grating);
01641 
01642                 giraffe_transmission_config_destroy(transmission_config);
01643 
01644                 giraffe_extraction_destroy(extraction);
01645 
01646                 giraffe_localization_destroy(ploc);
01647                 ploc = NULL;
01648 
01649                 giraffe_table_delete(fibers);
01650 
01651                 return 1;
01652             }
01653 
01654         }
01655 
01656 
01657         status = giraffe_transmission_compute(extraction, fibers,
01658                                               ploc, wlsolution,
01659                                               grating, slitgeometry);
01660 
01661         if (status != 0) {
01662             cpl_msg_error(_id, "Relative transmission computation failed! "
01663                           "Aborting ...");
01664 
01665             if (wlsolution != NULL) {
01666                 giraffe_table_delete(wlsolution);
01667                 wlsolution = NULL;
01668             }
01669 
01670             giraffe_table_delete(slitgeometry);
01671             giraffe_table_delete(grating);
01672 
01673             giraffe_transmission_config_destroy(transmission_config);
01674 
01675             giraffe_extraction_destroy(extraction);
01676 
01677             giraffe_localization_destroy(ploc);
01678             ploc = NULL;
01679 
01680             giraffe_table_delete(fibers);
01681 
01682             return 1;
01683         }
01684 
01685         if (wlsolution != NULL) {
01686             giraffe_table_delete(wlsolution);
01687             wlsolution = NULL;
01688         }
01689 
01690         giraffe_table_delete(slitgeometry);
01691         giraffe_table_delete(grating);
01692 
01693         giraffe_transmission_config_destroy(transmission_config);
01694 
01695     }
01696 
01697     giraffe_localization_destroy(ploc);
01698     ploc = NULL;
01699 
01700 
01701     /*
01702      * Save the spectrum extraction results and register them as
01703      * products.
01704      */
01705 
01706     cpl_msg_info(_id, "Writing extracted spectra ...");
01707 
01708     /* Extracted spectra */
01709 
01710     giraffe_image_add_info(extraction->spectra, &info, set);
01711 
01712     sext_frame = giraffe_frame_create_image(extraction->spectra,
01713                                             GIFRAME_FIBER_FLAT_EXTSPECTRA,
01714                                             CPL_FRAME_LEVEL_FINAL,
01715                                             TRUE, TRUE);
01716 
01717     if (sext_frame == NULL) {
01718         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01719 
01720         giraffe_extraction_destroy(extraction);
01721         giraffe_table_delete(fibers);
01722 
01723         return 1;
01724     }
01725 
01726     status = giraffe_fiberlist_attach(sext_frame, fibers);
01727 
01728     if (status != 0) {
01729         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01730                       "Aborting ...", cpl_frame_get_filename(sext_frame));
01731 
01732         cpl_frame_delete(sext_frame);
01733 
01734         giraffe_extraction_destroy(extraction);
01735         giraffe_table_delete(fibers);
01736 
01737         return 1;
01738     }
01739 
01740     cpl_frameset_insert(set, sext_frame);
01741 
01742     /* Extracted spectra errors */
01743 
01744     giraffe_image_add_info(extraction->error, &info, set);
01745 
01746     sext_frame = giraffe_frame_create_image(extraction->error,
01747                                             GIFRAME_FIBER_FLAT_EXTERRORS,
01748                                             CPL_FRAME_LEVEL_FINAL,
01749                                             TRUE, TRUE);
01750 
01751     if (sext_frame == NULL) {
01752         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01753 
01754         giraffe_extraction_destroy(extraction);
01755         giraffe_table_delete(fibers);
01756 
01757         return 1;
01758     }
01759 
01760     status = giraffe_fiberlist_attach(sext_frame, fibers);
01761 
01762     if (status != 0) {
01763         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01764                       "Aborting ...", cpl_frame_get_filename(sext_frame));
01765 
01766         cpl_frame_delete(sext_frame);
01767 
01768         giraffe_extraction_destroy(extraction);
01769         giraffe_table_delete(fibers);
01770 
01771         return 1;
01772     }
01773 
01774     cpl_frameset_insert(set, sext_frame);
01775 
01776     /* Extracted spectra pixels */
01777 
01778     if (extraction->npixels != NULL) {
01779 
01780         giraffe_image_add_info(extraction->npixels, &info, set);
01781 
01782         sext_frame = giraffe_frame_create_image(extraction->npixels,
01783                                                 GIFRAME_FIBER_FLAT_EXTPIXELS,
01784                                                 CPL_FRAME_LEVEL_FINAL,
01785                                                 TRUE, TRUE);
01786 
01787         if (sext_frame == NULL) {
01788             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01789 
01790             giraffe_extraction_destroy(extraction);
01791             giraffe_table_delete(fibers);
01792 
01793             return 1;
01794         }
01795 
01796         status = giraffe_fiberlist_attach(sext_frame, fibers);
01797 
01798         if (status != 0) {
01799             cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01800                         "Aborting ...", cpl_frame_get_filename(sext_frame));
01801 
01802             cpl_frame_delete(sext_frame);
01803 
01804             giraffe_extraction_destroy(extraction);
01805             giraffe_table_delete(fibers);
01806 
01807             return 1;
01808         }
01809 
01810         cpl_frameset_insert(set, sext_frame);
01811 
01812     }
01813 
01814     /* Extracted spectra centroids */
01815 
01816     giraffe_image_add_info(extraction->centroid, &info, set);
01817 
01818     sext_frame = giraffe_frame_create_image(extraction->centroid,
01819                                             GIFRAME_FIBER_FLAT_EXTTRACE,
01820                                             CPL_FRAME_LEVEL_FINAL,
01821                                             TRUE, TRUE);
01822 
01823     if (sext_frame == NULL) {
01824         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01825 
01826         giraffe_extraction_destroy(extraction);
01827         giraffe_table_delete(fibers);
01828 
01829         return 1;
01830     }
01831 
01832     status = giraffe_fiberlist_attach(sext_frame, fibers);
01833 
01834     if (status != 0) {
01835         cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01836                       "Aborting ...", cpl_frame_get_filename(sext_frame));
01837 
01838         cpl_frame_delete(sext_frame);
01839 
01840         giraffe_extraction_destroy(extraction);
01841         giraffe_table_delete(fibers);
01842 
01843         return 1;
01844     }
01845 
01846     cpl_frameset_insert(set, sext_frame);
01847 
01848     /* Extraction model spectra */
01849 
01850     if (extraction->model != NULL) {
01851 
01852         giraffe_image_add_info(extraction->model, &info, set);
01853 
01854         sext_frame = giraffe_frame_create_image(extraction->model,
01855                                                 GIFRAME_FIBER_FLAT_EXTMODEL,
01856                                                 CPL_FRAME_LEVEL_FINAL,
01857                                                 TRUE, TRUE);
01858 
01859         if (sext_frame == NULL) {
01860             cpl_msg_error(_id, "Cannot create local file! Aborting ...");
01861 
01862             giraffe_extraction_destroy(extraction);
01863             giraffe_table_delete(fibers);
01864 
01865             return 1;
01866         }
01867 
01868         status = giraffe_fiberlist_attach(sext_frame, fibers);
01869 
01870         if (status != 0) {
01871             cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
01872                         "Aborting ...", cpl_frame_get_filename(sext_frame));
01873 
01874             cpl_frame_delete(sext_frame);
01875 
01876             giraffe_extraction_destroy(extraction);
01877             giraffe_table_delete(fibers);
01878 
01879             return 1;
01880         }
01881 
01882         cpl_frameset_insert(set, sext_frame);
01883 
01884     }
01885 
01886 
01887     /*
01888      * Cleanup
01889      */
01890 
01891     giraffe_extraction_destroy(extraction);
01892     giraffe_table_delete(fibers);
01893 
01894     return 0;
01895 
01896 }
01897 
01898 
01899 static cxint
01900 giqcmasterflat(cpl_frameset* set)
01901 {
01902 
01903     const cxchar* const fctid = "giqcmasterflat";
01904 
01905 
01906     cxint i = 0;
01907     cxint nx = 0;
01908     cxint ny = 0;
01909     cxint npixel = 0;
01910     cxint nsaturated = 0;
01911     cxint status = 0;
01912 
01913     const cxdouble saturation = 60000.;
01914     const cxdouble* pixels = NULL;
01915     cxdouble efficiency[2] = {0., 0.};
01916     cxdouble scale = 1.;
01917     cxdouble mean = 0.;
01918     cxdouble rms = 0.;
01919     cxdouble diff = 0.;
01920     cxdouble* _pdata = NULL;
01921     cxdouble* _tdata = NULL;
01922 
01923     cpl_propertylist* properties = NULL;
01924     cpl_propertylist* qclog = NULL;
01925 
01926     cpl_frame* rframe = NULL;
01927     cpl_frame* pframe = NULL;
01928 
01929     cpl_image* _rimage = NULL;
01930     cpl_image* _pimage = NULL;
01931     cpl_image* _test = NULL;
01932 
01933     cpl_table* _ptable = NULL;
01934 
01935     GiImage* rimage = NULL;
01936     GiImage* pimage = NULL;
01937 
01938     GiTable* ptable = NULL;
01939 
01940     GiPaf* qc = NULL;
01941 
01942     GiWindow w = {0, 0, 0, 0};
01943 
01944 
01945 
01946     cpl_msg_info(fctid, "Computing QC1 parameters ...");
01947 
01948     qc = giraffe_qclog_open(0);
01949 
01950     if (qc == NULL) {
01951         cpl_msg_error(fctid, "Cannot create QC1 log!");
01952         return 1;
01953     }
01954 
01955     qclog = giraffe_paf_get_properties(qc);
01956     cx_assert(qclog != NULL);
01957 
01958 
01959     /*
01960      * Compute lamp efficiencies from the rebinned frame if
01961      * it is available. If not the efficiencies are set to 0.
01962      */
01963 
01964     pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_EXTSPECTRA,
01965                                CPL_FRAME_GROUP_PRODUCT);
01966 
01967     if (pframe == NULL) {
01968 
01969         cpl_msg_warning(fctid, "Product '%s' not found.",
01970                         GIFRAME_FIBER_FLAT_EXTSPECTRA);
01971 
01972         cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
01973                         GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
01974 
01975         efficiency[0] = 0.;
01976         efficiency[1] = 0.;
01977 
01978     }
01979 
01980 
01981     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
01982     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
01983 
01984     if (status != 0) {
01985         cpl_msg_error(fctid, "Could not load extracted spectra '%s'!",
01986                       cpl_frame_get_filename(pframe));
01987 
01988         giraffe_image_delete(pimage);
01989         pimage = NULL;
01990 
01991         giraffe_paf_delete(qc);
01992         qc = NULL;
01993 
01994         return 1;
01995     }
01996 
01997     _pimage = giraffe_image_get(pimage);
01998     cx_assert(_pimage != NULL);
01999 
02000 
02001     ptable = giraffe_table_new();
02002     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
02003                                 NULL);
02004 
02005     if (status != 0) {
02006         cpl_msg_error(fctid, "Could not load extracted spectra fiber setup!");
02007 
02008         giraffe_table_delete(ptable);
02009         ptable = NULL;
02010 
02011         giraffe_image_delete(pimage);
02012         pimage = NULL;
02013 
02014         giraffe_paf_delete(qc);
02015         qc = NULL;
02016 
02017         return 1;
02018     }
02019 
02020     _ptable = giraffe_table_get(ptable);
02021     cx_assert(_ptable != NULL);
02022 
02023     if (cpl_table_has_column(_ptable, "RP") == FALSE) {
02024 
02025         cpl_msg_warning(fctid, "Column 'RP' not found in fiber setup table!");
02026         cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
02027                         GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
02028 
02029         efficiency[0] = 0.;
02030         efficiency[1] = 0.;
02031 
02032     }
02033     else {
02034 
02035         properties = giraffe_image_get_properties(pimage);
02036         cx_assert(properties != NULL);
02037 
02038         if (cpl_propertylist_has(properties, GIALIAS_EXPTIME) == FALSE) {
02039 
02040             cpl_msg_warning(fctid, "Property '%s' not found in '%s'.",
02041                             GIALIAS_EXPTIME, cpl_frame_get_filename(rframe));
02042             cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
02043                             GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
02044 
02045             efficiency[0] = 0.;
02046             efficiency[1] = 0.;
02047 
02048         }
02049         else {
02050 
02051             cxbool scaled = cpl_propertylist_has(properties,
02052                                                  GIALIAS_FLAT_SCALE);
02053 
02054             cxint fiber = 0;
02055             cxint nb = cpl_image_get_size_y(_pimage);
02056             cxint nf[2] = {0, 0};
02057 
02058             cxdouble exptime = cpl_propertylist_get_double(properties,
02059                 GIALIAS_EXPTIME);
02060             cxdouble* _sum = NULL;
02061 
02062             cpl_image* sum = NULL;
02063 
02064 
02065             if (scaled == TRUE) {
02066 
02067                 scale = cpl_propertylist_get_double(properties,
02068                     GIALIAS_FLAT_SCALE);
02069                 cpl_image_multiply_scalar(_pimage, scale);
02070 
02071 
02072             }
02073 
02074             sum = cpl_image_collapse_create(_pimage, 0);
02075             _sum = cpl_image_get_data_double(sum);
02076 
02077             for (fiber = 0; fiber < cpl_table_get_nrow(_ptable); ++fiber) {
02078 
02079                 cxint rp = cpl_table_get_int(_ptable, "RP", fiber, NULL);
02080 
02081                 if (rp == -1) {
02082                     efficiency[1] += _sum[fiber];
02083                     ++nf[1];
02084                 }
02085                 else {
02086                     efficiency[0] += _sum[fiber];
02087                     ++nf[0];
02088                 }
02089 
02090             }
02091 
02092             _sum = NULL;
02093 
02094             cpl_image_delete(sum);
02095             sum = NULL;
02096 
02097             efficiency[0] /= nf[0] * nb * exptime;
02098             efficiency[1] /= nf[1] * nb * exptime;
02099 
02100         }
02101 
02102         properties = NULL;
02103 
02104     }
02105 
02106     _ptable = NULL;
02107     _pimage = NULL;
02108 
02109     giraffe_table_delete(ptable);
02110     ptable = NULL;
02111 
02112     giraffe_image_delete(pimage);
02113     pimage = NULL;
02114 
02115 
02116     /*
02117      * Process master flat field
02118      */
02119 
02120 
02121     pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_MASTER,
02122                                CPL_FRAME_GROUP_PRODUCT);
02123 
02124     if (pframe == NULL) {
02125         cpl_msg_error(fctid, "Missing product frame (%s)",
02126                       GIFRAME_FIBER_FLAT_MASTER);
02127 
02128         giraffe_paf_delete(qc);
02129         qc = NULL;
02130 
02131         return 1;
02132     }
02133 
02134     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
02135                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
02136 
02137     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02138     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
02139 
02140     if (status != 0) {
02141         cpl_msg_error(fctid, "Could not load master flat field '%s'!",
02142                       cpl_frame_get_filename(pframe));
02143 
02144         giraffe_image_delete(pimage);
02145         pimage = NULL;
02146 
02147         giraffe_paf_delete(qc);
02148         qc = NULL;
02149 
02150         return 1;
02151     }
02152 
02153 
02154     /*
02155      * Load first raw image as reference
02156      */
02157 
02158     rframe = cpl_frameset_find(set, GIFRAME_FIBER_FLAT);
02159 
02160     if (rframe == NULL) {
02161         cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_FIBER_FLAT);
02162 
02163         giraffe_image_delete(pimage);
02164         pimage = NULL;
02165 
02166         giraffe_paf_delete(qc);
02167         qc = NULL;
02168 
02169         return 1;
02170     }
02171 
02172     rimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02173     status = giraffe_image_load(rimage, cpl_frame_get_filename(rframe), 0);
02174 
02175     if (status != 0) {
02176 
02177         cpl_msg_error(fctid, "Could not load flat field '%s'!",
02178                       cpl_frame_get_filename(rframe));
02179 
02180         giraffe_image_delete(rimage);
02181         rimage = NULL;
02182 
02183         giraffe_image_delete(pimage);
02184         pimage = NULL;
02185 
02186         giraffe_paf_delete(qc);
02187         qc = NULL;
02188 
02189         return 1;
02190 
02191     }
02192 
02193     _rimage = giraffe_image_get(rimage);
02194     cx_assert(_rimage != NULL);
02195 
02196     properties = giraffe_image_get_properties(rimage);
02197     cx_assert(properties != NULL);
02198 
02199     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
02200     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
02201     giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
02202                               GIALIAS_SETUPNAME);
02203     giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
02204                               GIALIAS_SLITNAME);
02205     giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
02206                               GIALIAS_GRATWLEN);
02207     giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
02208 
02209     cpl_propertylist_update_string(qclog, "PRO.CATG",
02210                                    cpl_frame_get_tag(pframe));
02211     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02212                                  "Pipeline product category");
02213 
02214     properties = giraffe_image_get_properties(pimage);
02215     cx_assert(properties != NULL);
02216 
02217     giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
02218                               GIALIAS_DATAMEAN);
02219     giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
02220                               GIALIAS_DATASIG);
02221     giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
02222                               GIALIAS_DATAMEDI);
02223     giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
02224                               GIALIAS_DATANCOM);
02225 
02226 
02227     /*
02228      * Compute mean level of the first raw frame and count the number
02229      * of saturated pixels.
02230      */
02231 
02232     properties = giraffe_image_get_properties(rimage);
02233     cx_assert(properties != NULL);
02234 
02235     if (cpl_propertylist_has(properties, GIALIAS_OVSCX) == TRUE) {
02236 
02237         cxint _ox = cpl_propertylist_get_int(properties, GIALIAS_OVSCX);
02238         cxint _nx = cpl_image_get_size_x(_rimage) - 2 * CX_MAX(0, _ox) - 1;
02239 
02240         w.x0 = CX_MAX(0, _ox) + 1;
02241         w.x1 = w.x0 + _nx;
02242 
02243     }
02244 
02245     if (cpl_propertylist_has(properties, GIALIAS_OVSCY) == TRUE) {
02246 
02247         cxint _oy = cpl_propertylist_get_int(properties, GIALIAS_OVSCY);
02248         cxint _ny = cpl_image_get_size_y(_rimage) - 2 * CX_MAX(0, _oy) - 1;
02249 
02250         w.y0 = CX_MAX(0, _oy) + 1;
02251         w.y1 = w.y0 + _ny;
02252 
02253     }
02254 
02255     mean = cpl_image_get_mean_window(_rimage, w.x0, w.y0, w.x1, w.y1);
02256 
02257     pixels = cpl_image_get_data(_rimage);
02258     npixel = cpl_image_get_size_x(_rimage) * cpl_image_get_size_y(_rimage);
02259 
02260     for (i = 0; i < npixel; i++) {
02261         if (pixels[i] > saturation) {
02262             ++nsaturated;
02263         }
02264     }
02265 
02266 
02267     properties = giraffe_image_get_properties(pimage);
02268     cx_assert(properties != NULL);
02269 
02270     cpl_propertylist_update_double(properties, GIALIAS_QCMEAN, mean);
02271     cpl_propertylist_set_comment(properties, GIALIAS_QCMEAN, "Mean level of "
02272                                  "first raw frame");
02273 
02274     giraffe_propertylist_copy(qclog, "QC.OUT1.MEAN.RAW", properties,
02275                               GIALIAS_QCMEAN);
02276 
02277 
02278     cpl_propertylist_update_int(properties, GIALIAS_QCNSAT, nsaturated);
02279     cpl_propertylist_set_comment(properties, GIALIAS_QCNSAT, "Number of "
02280                                  "saturated pixels in the first raw frame");
02281 
02282     giraffe_propertylist_copy(qclog, "QC.OUT1.NSAT.RAW", properties,
02283                               GIALIAS_QCNSAT);
02284 
02285 
02286     /*
02287      * Calibration lamp monitoring
02288      */
02289 
02290     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
02291     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
02292                                  "Calibration lamp efficiency");
02293 
02294     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
02295                               GIALIAS_QCLAMP);
02296 
02297     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
02298                                    efficiency[1]);
02299     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
02300                                  "SIMCAL lamp efficiency");
02301 
02302     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
02303                               GIALIAS_QCLAMP_SIMCAL);
02304 
02305 
02306     /*
02307      * Write QC1 log and save updated master flat field.
02308      */
02309 
02310     giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
02311 
02312     giraffe_image_delete(pimage);
02313     pimage = NULL;
02314 
02315     giraffe_qclog_close(qc);
02316     qc = NULL;
02317 
02318 
02319     /*
02320      * Process fiber localization centroid
02321      */
02322 
02323     qc = giraffe_qclog_open(1);
02324 
02325     if (qc == NULL) {
02326         cpl_msg_error(fctid, "Cannot create QC1 log!");
02327 
02328         giraffe_image_delete(rimage);
02329         rimage = NULL;
02330 
02331         return 1;
02332     }
02333 
02334     qclog = giraffe_paf_get_properties(qc);
02335     cx_assert(qclog != NULL);
02336 
02337     pframe = giraffe_get_frame(set, GIFRAME_LOCALIZATION_CENTROID,
02338                                CPL_FRAME_GROUP_PRODUCT);
02339 
02340     if (pframe == NULL) {
02341         cpl_msg_error(fctid, "Missing product frame (%s)",
02342                       GIFRAME_LOCALIZATION_CENTROID);
02343 
02344         giraffe_paf_delete(qc);
02345         qc = NULL;
02346 
02347         giraffe_image_delete(rimage);
02348         rimage = NULL;
02349 
02350         return 1;
02351     }
02352 
02353     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
02354                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
02355 
02356 
02357     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02358     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
02359 
02360     if (status != 0) {
02361         cpl_msg_error(fctid, "Could not load localization centroids '%s'!",
02362                       cpl_frame_get_filename(pframe));
02363 
02364         giraffe_image_delete(pimage);
02365         pimage = NULL;
02366 
02367         giraffe_image_delete(rimage);
02368         rimage = NULL;
02369 
02370         giraffe_paf_delete(qc);
02371         qc = NULL;
02372 
02373         return 1;
02374     }
02375 
02376     ptable = giraffe_table_new();
02377     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
02378                                 NULL);
02379 
02380     if (status != 0) {
02381         cpl_msg_error(fctid, "Could not load localization centroids '%s'!",
02382                       cpl_frame_get_filename(pframe));
02383 
02384         giraffe_table_delete(ptable);
02385         ptable = NULL;
02386 
02387         giraffe_image_delete(pimage);
02388         pimage = NULL;
02389 
02390         giraffe_image_delete(rimage);
02391         rimage = NULL;
02392 
02393         giraffe_paf_delete(qc);
02394         qc = NULL;
02395 
02396         return 1;
02397     }
02398 
02399     properties = giraffe_image_get_properties(rimage);
02400     cx_assert(properties != NULL);
02401 
02402     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
02403     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
02404     giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
02405                               GIALIAS_SETUPNAME);
02406     giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
02407                               GIALIAS_SLITNAME);
02408     giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
02409                               GIALIAS_GRATWLEN);
02410     giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
02411 
02412     cpl_propertylist_update_string(qclog, "PRO.CATG",
02413                                    cpl_frame_get_tag(pframe));
02414     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02415                                  "Pipeline product category");
02416 
02417     properties = giraffe_image_get_properties(pimage);
02418     cx_assert(properties != NULL);
02419 
02420     giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
02421                               GIALIAS_DATAMEAN);
02422     giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
02423                               GIALIAS_DATASIG);
02424     giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
02425                               GIALIAS_DATAMEDI);
02426     giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
02427                               GIALIAS_DATANCOM);
02428     giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
02429                               GIALIAS_NFIBERS);
02430 
02431 
02432     /*
02433      * Calibration lamp monitoring
02434      */
02435 
02436     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
02437     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
02438                                  "Calibration lamp efficiency");
02439 
02440     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
02441                               GIALIAS_QCLAMP);
02442 
02443     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
02444                                    efficiency[1]);
02445     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
02446                                  "SIMCAL lamp efficiency");
02447 
02448     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
02449                               GIALIAS_QCLAMP_SIMCAL);
02450 
02451 
02452     /* Fiber signal curvature RMS */
02453 
02454     _pimage = giraffe_image_get(pimage);
02455 
02456     _test = cpl_image_collapse_create(_pimage, 0);
02457     cpl_image_divide_scalar(_test, cpl_image_get_size_y(_pimage));
02458 
02459     _pdata = cpl_image_get_data(_pimage);
02460     _tdata = cpl_image_get_data(_test);
02461 
02462     rms = 0.;
02463 
02464     nx = cpl_image_get_size_x(_pimage);
02465     ny = cpl_image_get_size_y(_pimage);
02466 
02467     for (i = 0; i < nx; i++) {
02468 
02469         cxint j;
02470 
02471         cxdouble _rms = 0.;
02472 
02473 
02474         for (j = 0; j < ny; j++) {
02475             _rms += pow(_pdata[j * nx + i] - _tdata[i], 2.);
02476         }
02477 
02478         rms += sqrt(_rms / (ny - 1));
02479 
02480     }
02481 
02482     rms /= nx;
02483 
02484     cpl_image_delete(_test);
02485     _test = NULL;
02486 
02487     cpl_propertylist_update_double(properties, GIALIAS_QCLCRMS, rms);
02488     cpl_propertylist_set_comment(properties, GIALIAS_QCLCRMS,
02489                                  "Mean fibre signal curvature");
02490 
02491     giraffe_propertylist_copy(qclog, "QC.FIBRE.CENTROID.RMS", properties,
02492                               GIALIAS_QCLCRMS);
02493 
02494 
02495     /* Difference of fiber signal curvature */
02496 
02497     diff = 0.;
02498 
02499     for (i = 0; i < nx; i++) {
02500 
02501         cxdouble min = cpl_image_get_min_window(_pimage,
02502                                                 i + 1, 1, i + 1, ny);
02503         cxdouble max = cpl_image_get_max_window(_pimage,
02504                                                 i + 1, 1, i + 1, ny);
02505 
02506         diff += max - min;
02507 
02508     }
02509 
02510     diff /= nx;
02511 
02512     cpl_propertylist_update_double(properties, GIALIAS_QCLCDIFF, diff);
02513     cpl_propertylist_set_comment(properties, GIALIAS_QCLCDIFF,
02514                                  "Mean difference of fibre signal "
02515                                  "curvature");
02516 
02517     giraffe_propertylist_copy(qclog, "QC.FIBRE.CENTROID.DIFF", properties,
02518                               GIALIAS_QCLCDIFF);
02519 
02520 
02521     status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
02522 
02523     if (status != 0) {
02524         cpl_msg_error(fctid, "Could not save localization centroids '%s'!",
02525                       cpl_frame_get_filename(pframe));
02526 
02527         giraffe_table_delete(ptable);
02528         ptable = NULL;
02529 
02530         giraffe_image_delete(pimage);
02531         pimage = NULL;
02532 
02533         giraffe_image_delete(rimage);
02534         rimage = NULL;
02535 
02536         giraffe_paf_delete(qc);
02537         qc = NULL;
02538 
02539         return 1;
02540     }
02541 
02542     status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
02543                                   1, NULL);
02544 
02545     if (status != 0) {
02546         cpl_msg_error(fctid, "Could not save localization centroids '%s'!",
02547                       cpl_frame_get_filename(pframe));
02548 
02549         giraffe_table_delete(ptable);
02550         ptable = NULL;
02551 
02552         giraffe_image_delete(pimage);
02553         pimage = NULL;
02554 
02555         giraffe_image_delete(rimage);
02556         rimage = NULL;
02557 
02558         giraffe_paf_delete(qc);
02559         qc = NULL;
02560 
02561         return 1;
02562     }
02563 
02564     giraffe_image_delete(pimage);
02565     pimage = NULL;
02566 
02567     giraffe_table_delete(ptable);
02568     ptable = NULL;
02569 
02570     giraffe_qclog_close(qc);
02571     qc = NULL;
02572 
02573 
02574     /*
02575      * Process fiber localization width
02576      */
02577 
02578     qc = giraffe_qclog_open(2);
02579 
02580     if (qc == NULL) {
02581         cpl_msg_error(fctid, "Cannot create QC1 log!");
02582 
02583         giraffe_image_delete(rimage);
02584         rimage = NULL;
02585 
02586         return 1;
02587     }
02588 
02589     qclog = giraffe_paf_get_properties(qc);
02590     cx_assert(qclog != NULL);
02591 
02592     pframe = giraffe_get_frame(set, GIFRAME_LOCALIZATION_WIDTH,
02593                                CPL_FRAME_GROUP_PRODUCT);
02594 
02595     if (pframe == NULL) {
02596         cpl_msg_error(fctid, "Missing product frame (%s)",
02597                       GIFRAME_LOCALIZATION_WIDTH);
02598 
02599         giraffe_paf_delete(qc);
02600         qc = NULL;
02601 
02602         giraffe_image_delete(rimage);
02603         rimage = NULL;
02604 
02605         return 1;
02606     }
02607 
02608     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
02609                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
02610 
02611 
02612     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02613     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
02614 
02615     if (status != 0) {
02616         cpl_msg_error(fctid, "Could not load localization widths '%s'!",
02617                       cpl_frame_get_filename(pframe));
02618 
02619         giraffe_image_delete(pimage);
02620         pimage = NULL;
02621 
02622         giraffe_image_delete(rimage);
02623         rimage = NULL;
02624 
02625         giraffe_paf_delete(qc);
02626         qc = NULL;
02627 
02628         return 1;
02629     }
02630 
02631     ptable = giraffe_table_new();
02632     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
02633                                 NULL);
02634 
02635     if (status != 0) {
02636         cpl_msg_error(fctid, "Could not load localization widths '%s'!",
02637                       cpl_frame_get_filename(pframe));
02638 
02639         giraffe_table_delete(ptable);
02640         ptable = NULL;
02641 
02642         giraffe_image_delete(pimage);
02643         pimage = NULL;
02644 
02645         giraffe_image_delete(rimage);
02646         rimage = NULL;
02647 
02648         giraffe_paf_delete(qc);
02649         qc = NULL;
02650 
02651         return 1;
02652     }
02653 
02654     properties = giraffe_image_get_properties(rimage);
02655     cx_assert(properties != NULL);
02656 
02657     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
02658     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
02659     giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
02660                               GIALIAS_SETUPNAME);
02661     giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
02662                               GIALIAS_SLITNAME);
02663     giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
02664                               GIALIAS_GRATWLEN);
02665     giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
02666 
02667     cpl_propertylist_update_string(qclog, "PRO.CATG",
02668                                    cpl_frame_get_tag(pframe));
02669     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02670                                  "Pipeline product category");
02671 
02672     properties = giraffe_image_get_properties(pimage);
02673     cx_assert(properties != NULL);
02674 
02675     giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
02676                               GIALIAS_DATAMEAN);
02677     giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
02678                               GIALIAS_DATASIG);
02679     giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
02680                               GIALIAS_DATAMEDI);
02681     giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
02682                               GIALIAS_DATANCOM);
02683     giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
02684                               GIALIAS_NFIBERS);
02685 
02686 
02687     /*
02688      * Calibration lamp monitoring
02689      */
02690 
02691     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
02692     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
02693                                  "Calibration lamp efficiency");
02694 
02695     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
02696                               GIALIAS_QCLAMP);
02697 
02698     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
02699                                    efficiency[1]);
02700     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
02701                                  "SIMCAL lamp efficiency");
02702 
02703     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
02704                               GIALIAS_QCLAMP_SIMCAL);
02705 
02706 
02707     /* Compute fiber width statistics, i.e. the mean width and its RMS */
02708 
02709     _pimage = giraffe_image_get(pimage);
02710 
02711     _test = cpl_image_collapse_create(_pimage, 0);
02712     cpl_image_divide_scalar(_test, cpl_image_get_size_y(_pimage));
02713 
02714     _pdata = cpl_image_get_data(_pimage);
02715     _tdata = cpl_image_get_data(_test);
02716 
02717     mean = 0.;
02718     rms = 0.;
02719 
02720     nx = cpl_image_get_size_x(_pimage);
02721     ny = cpl_image_get_size_y(_pimage);
02722 
02723     for (i = 0; i < nx; i++) {
02724 
02725         cxint j;
02726 
02727         cxdouble _rms = 0.;
02728 
02729 
02730         for (j = 0; j < ny; j++) {
02731             _rms += pow(_pdata[j * nx + i] - _tdata[i], 2.);
02732         }
02733 
02734         mean += _tdata[i];
02735         rms += sqrt(_rms / (ny - 1));
02736 
02737     }
02738 
02739     mean /= nx;
02740     rms /= nx;
02741 
02742     cpl_image_delete(_test);
02743     _test = NULL;
02744 
02745 
02746     cpl_propertylist_update_double(properties, GIALIAS_QCLWAVG, mean);
02747     cpl_propertylist_set_comment(properties, GIALIAS_QCLWAVG,
02748                                  "Mean fibre half width");
02749 
02750     giraffe_propertylist_copy(qclog, "QC.FIBRE.WIDTH.MEAN", properties,
02751                               GIALIAS_QCLWAVG);
02752 
02753     cpl_propertylist_update_double(properties, GIALIAS_QCLWRMS, rms);
02754     cpl_propertylist_set_comment(properties, GIALIAS_QCLWRMS,
02755                                  "RMS of fibre half width");
02756 
02757     giraffe_propertylist_copy(qclog, "QC.FIBRE.WIDTH.RMS", properties,
02758                               GIALIAS_QCLWRMS);
02759 
02760 
02761     status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
02762 
02763     if (status != 0) {
02764         cpl_msg_error(fctid, "Could not save localization widths '%s'!",
02765                       cpl_frame_get_filename(pframe));
02766 
02767         giraffe_table_delete(ptable);
02768         ptable = NULL;
02769 
02770         giraffe_image_delete(pimage);
02771         pimage = NULL;
02772 
02773         giraffe_image_delete(rimage);
02774         rimage = NULL;
02775 
02776         giraffe_paf_delete(qc);
02777         qc = NULL;
02778 
02779         return 1;
02780     }
02781 
02782     status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
02783                                   1, NULL);
02784 
02785     if (status != 0) {
02786         cpl_msg_error(fctid, "Could not save localization widths '%s'!",
02787                       cpl_frame_get_filename(pframe));
02788 
02789         giraffe_table_delete(ptable);
02790         ptable = NULL;
02791 
02792         giraffe_image_delete(pimage);
02793         pimage = NULL;
02794 
02795         giraffe_image_delete(rimage);
02796         rimage = NULL;
02797 
02798         giraffe_paf_delete(qc);
02799         qc = NULL;
02800 
02801         return 1;
02802     }
02803 
02804     giraffe_image_delete(pimage);
02805     pimage = NULL;
02806 
02807     giraffe_table_delete(ptable);
02808     ptable = NULL;
02809 
02810     giraffe_qclog_close(qc);
02811     qc = NULL;
02812 
02813 
02814     /*
02815      * Process extracted flat field spectra
02816      */
02817 
02818     qc = giraffe_qclog_open(3);
02819 
02820     if (qc == NULL) {
02821         cpl_msg_error(fctid, "Cannot create QC1 log!");
02822 
02823         giraffe_image_delete(rimage);
02824         rimage = NULL;
02825 
02826         return 1;
02827     }
02828 
02829     qclog = giraffe_paf_get_properties(qc);
02830     cx_assert(qclog != NULL);
02831 
02832     pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_EXTSPECTRA,
02833                                CPL_FRAME_GROUP_PRODUCT);
02834 
02835     if (pframe == NULL) {
02836         cpl_msg_error(fctid, "Missing product frame (%s)",
02837                       GIFRAME_FIBER_FLAT_EXTSPECTRA);
02838 
02839         giraffe_paf_delete(qc);
02840         qc = NULL;
02841 
02842         giraffe_image_delete(rimage);
02843         rimage = NULL;
02844 
02845         return 1;
02846     }
02847 
02848     cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
02849                  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
02850 
02851 
02852     pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
02853     status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
02854 
02855     if (status != 0) {
02856         cpl_msg_error(fctid, "Could not load extracted flat field spectra "
02857                       "'%s'!", cpl_frame_get_filename(pframe));
02858 
02859         giraffe_image_delete(pimage);
02860         pimage = NULL;
02861 
02862         giraffe_image_delete(rimage);
02863         rimage = NULL;
02864 
02865         giraffe_paf_delete(qc);
02866         qc = NULL;
02867 
02868         return 1;
02869     }
02870 
02871     ptable = giraffe_table_new();
02872     status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
02873                                 NULL);
02874 
02875     if (status != 0) {
02876         cpl_msg_error(fctid, "Could not load extracted flat field spectra "
02877                       "'%s'!", cpl_frame_get_filename(pframe));
02878 
02879         giraffe_table_delete(ptable);
02880         ptable = NULL;
02881 
02882         giraffe_image_delete(pimage);
02883         pimage = NULL;
02884 
02885         giraffe_image_delete(rimage);
02886         rimage = NULL;
02887 
02888         giraffe_paf_delete(qc);
02889         qc = NULL;
02890 
02891         return 1;
02892     }
02893 
02894     properties = giraffe_image_get_properties(rimage);
02895     cx_assert(properties != NULL);
02896 
02897     giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
02898     giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
02899     giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
02900                               GIALIAS_SETUPNAME);
02901     giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
02902                               GIALIAS_SLITNAME);
02903     giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
02904                               GIALIAS_GRATWLEN);
02905     giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
02906 
02907     cpl_propertylist_update_string(qclog, "PRO.CATG",
02908                                    cpl_frame_get_tag(pframe));
02909     cpl_propertylist_set_comment(qclog, "PRO.CATG",
02910                                  "Pipeline product category");
02911 
02912     properties = giraffe_image_get_properties(pimage);
02913     cx_assert(properties != NULL);
02914 
02915     giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
02916                               GIALIAS_DATAMEAN);
02917     giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
02918                               GIALIAS_DATASIG);
02919     giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
02920                               GIALIAS_DATAMEDI);
02921     giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
02922                               GIALIAS_DATANCOM);
02923     giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
02924                               GIALIAS_NFIBERS);
02925 
02926 
02927     /*
02928      * Calibration lamp monitoring
02929      */
02930 
02931     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
02932     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
02933                                  "Calibration lamp efficiency");
02934 
02935     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
02936                               GIALIAS_QCLAMP);
02937 
02938     cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
02939                                    efficiency[1]);
02940     cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
02941                                  "SIMCAL lamp efficiency");
02942 
02943     giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
02944                               GIALIAS_QCLAMP_SIMCAL);
02945 
02946 
02947     _ptable = giraffe_table_get(ptable);
02948 
02949     if (cpl_table_has_column(_ptable, "TRANSMISSION") == FALSE) {
02950         cpl_msg_warning(fctid, "Relative fiber transmission not available! "
02951                         "QC parameter computation skipped.");
02952     }
02953     else {
02954 
02955         const cxdouble low = 0.5;
02956         const cxdouble high = 2.0;
02957 
02958         cxdouble t = 0.;
02959         cxdouble dt = 0.;
02960 
02961         cpl_table* ttable = NULL;
02962 
02963 
02964         rms = 0.;
02965 
02966         cpl_table_unselect_all(_ptable);
02967 
02968         cpl_table_or_selected_int(_ptable, "RP", CPL_GREATER_THAN, 0);
02969         cpl_table_and_selected_double(_ptable, "TRANSMISSION",
02970                                       CPL_GREATER_THAN, low);
02971         cpl_table_and_selected_double(_ptable, "TRANSMISSION",
02972                                       CPL_LESS_THAN, high);
02973 
02974         ttable = cpl_table_extract_selected(_ptable);
02975 
02976         if (ttable == NULL || cpl_table_get_nrow(ttable) <= 0) {
02977             cpl_msg_warning(fctid, "No fiber found within transmission "
02978                             "range ]%.2f, %.2f[", low, high);
02979 
02980         }
02981         else {
02982 
02983             t = cpl_table_get_column_median(ttable, "TRANSMISSION");
02984 
02985             for (i = 0; i < cpl_table_get_nrow(ttable); i++) {
02986 
02987                 cxdouble _t = cpl_table_get_double(ttable, "TRANSMISSION", i,
02988                                                   NULL);
02989                 rms += pow(_t - t, 2.);
02990 
02991             }
02992 
02993             rms = sqrt(rms / (cpl_table_get_nrow(ttable) - 1));
02994 
02995         }
02996 
02997         if (!cpl_table_has_column(_ptable, "DTRANSMISSION")) {
02998             cpl_msg_warning(fctid, "Relative fiber transmission error not "
02999                             "available! QC parameter computation skipped.");
03000         }
03001         else {
03002 
03003             cx_assert(cpl_table_has_column(ttable, "DTRANSMISSION") != 0);
03004             dt = cpl_table_get_column_median(ttable, "DTRANSMISSION");
03005 
03006         }
03007 
03008         cpl_table_delete(ttable);
03009         ttable = NULL;
03010 
03011 
03012         cpl_propertylist_update_double(properties, GIALIAS_QCTRMED, t);
03013         cpl_propertylist_set_comment(properties, GIALIAS_QCTRMED, "Median of "
03014                               "relative fibre transmission");
03015 
03016         giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.MEDIAN", properties,
03017                            GIALIAS_QCTRMED);
03018 
03019 
03020         cpl_propertylist_update_double(properties, GIALIAS_QCTRRMS, rms);
03021         cpl_propertylist_set_comment(properties, GIALIAS_QCTRRMS, "RMS of "
03022                               "relative fibre transmission");
03023 
03024         giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.RMS", properties,
03025                            GIALIAS_QCTRRMS);
03026 
03027 
03028         cpl_propertylist_update_double(properties, GIALIAS_QCTRERR, dt);
03029         cpl_propertylist_set_comment(properties, GIALIAS_QCTRERR, "Median of "
03030                               "relative fibre transmission error");
03031 
03032         giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.ERROR", properties,
03033                            GIALIAS_QCTRERR);
03034 
03035     }
03036 
03037     status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
03038 
03039     if (status != 0) {
03040         cpl_msg_error(fctid, "Could not save extracted flat field spectra "
03041                       "'%s'!", cpl_frame_get_filename(pframe));
03042 
03043         giraffe_table_delete(ptable);
03044         ptable = NULL;
03045 
03046         giraffe_image_delete(pimage);
03047         pimage = NULL;
03048 
03049         giraffe_image_delete(rimage);
03050         rimage = NULL;
03051 
03052         giraffe_paf_delete(qc);
03053         qc = NULL;
03054 
03055         return 1;
03056     }
03057 
03058     status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
03059                                   1, NULL);
03060 
03061     if (status != 0) {
03062         cpl_msg_error(fctid, "Could not save extracted flat field spectra "
03063                       "'%s'!", cpl_frame_get_filename(pframe));
03064 
03065         giraffe_table_delete(ptable);
03066         ptable = NULL;
03067 
03068         giraffe_image_delete(pimage);
03069         pimage = NULL;
03070 
03071         giraffe_image_delete(rimage);
03072         rimage = NULL;
03073 
03074         giraffe_paf_delete(qc);
03075         qc = NULL;
03076 
03077         return 1;
03078     }
03079 
03080     giraffe_image_delete(pimage);
03081     pimage = NULL;
03082 
03083     giraffe_table_delete(ptable);
03084     ptable = NULL;
03085 
03086     giraffe_qclog_close(qc);
03087     qc = NULL;
03088 
03089 
03090     /*
03091      * Cleanup
03092      */
03093 
03094     giraffe_image_delete(rimage);
03095 
03096     return 0;
03097 
03098 }
03099 
03100 
03101 /*
03102  * Build table of contents, i.e. the list of available plugins, for
03103  * this module. This function is exported.
03104  */
03105 
03106 int
03107 cpl_plugin_get_info(cpl_pluginlist* list)
03108 {
03109 
03110     cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
03111     cpl_plugin* plugin = &recipe->interface;
03112 
03113 
03114     cpl_plugin_init(plugin,
03115                     CPL_PLUGIN_API,
03116                     GIRAFFE_BINARY_VERSION,
03117                     CPL_PLUGIN_TYPE_RECIPE,
03118                     "gimasterflat",
03119                     "Create the fiber master flat field and the "
03120                     "localization mask.",
03121                     "For detailed information please refer to the "
03122                     "GIRAFFE pipeline user manual.\nIt is available at "
03123                     "http://www.eso.org/pipelines.",
03124                     "Giraffe Pipeline",
03125                     PACKAGE_BUGREPORT,
03126                     giraffe_get_license(),
03127                     gimasterflat_create,
03128                     gimasterflat_exec,
03129                     gimasterflat_destroy);
03130 
03131     cpl_pluginlist_append(list, plugin);
03132 
03133     return 0;
03134 
03135 }

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