GIRAFFE Pipeline Reference Manual

gimasterflat.c

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

This file is part of the GIRAFFE Pipeline Reference Manual 2.8.8.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Fri Mar 4 10:50:27 2011 by doxygen 1.6.3 written by Dimitri van Heesch, © 1997-2004