GIRAFFE Pipeline Reference Manual

gimasterflat.c

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

This file is part of the GIRAFFE Pipeline Reference Manual 2.11.1.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Fri May 24 12:29:02 2013 by doxygen 1.4.7 written by Dimitri van Heesch, © 1997-2004