GIRAFFE Pipeline Reference Manual

giframestack.c

00001 /* $Id: giframestack.c,v 1.5 2012/01/12 16:18:37 rpalsa Exp $
00002  *
00003  * This file is part of the GIRAFFE Pipeline
00004  * Copyright (C) 2002-2006 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: rpalsa $
00023  * $Date: 2012/01/12 16:18:37 $
00024  * $Revision: 1.5 $
00025  * $Name: giraffe-2_9 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #  include <config.h>
00030 #endif
00031 
00032 #include <math.h>
00033 
00034 #include <cxmessages.h>
00035 #include <cxmemory.h>
00036 #include <cxlist.h>
00037 
00038 #include <cpl_type.h>
00039 #include <cpl_recipe.h>
00040 #include <cpl_plugininfo.h>
00041 #include <cpl_parameterlist.h>
00042 #include <cpl_frameset.h>
00043 #include <cpl_propertylist.h>
00044 #include <cpl_msg.h>
00045 
00046 #include "gialias.h"
00047 #include "giframe.h"
00048 #include "giimage.h"
00049 #include "gifibers.h"
00050 #include "gibias.h"
00051 #include "gimath.h"
00052 #include "gistacking.h"
00053 #include "giqclog.h"
00054 #include "gierror.h"
00055 #include "giutils.h"
00056 
00057 
00058 #define GIMASTERBIAS_BIAS_EXTENSION_IMG 0
00059 #define GIMASTERBIAS_BIAS_EXTENSION_PL 0
00060 #define GIMASTERBIAS_BAD_PIXEL_EXTENSION 0
00061 
00062 
00063 static cxint giframestack(cpl_parameterlist*, cpl_frameset*);
00064 
00065 
00066 /*
00067  * Create the recipe instance, i.e. setup the parameter list for this
00068  * recipe and make it availble to the application using the interface.
00069  */
00070 
00071 static cxint
00072 giframestack_create(cpl_plugin* plugin)
00073 {
00074 
00075     cpl_recipe* recipe = (cpl_recipe*)plugin;
00076 
00077     giraffe_error_init();
00078 
00079 
00080     /*
00081      * We have to provide the option we accept to the application. We
00082      * need to setup our parameter list and hook it into the recipe
00083      * interface.
00084      */
00085 
00086     recipe->parameters = cpl_parameterlist_new();
00087     cx_assert(recipe->parameters != NULL);
00088 
00089     /*
00090      * Fill the parameter list.
00091      */
00092 
00093     giraffe_stacking_config_add(recipe->parameters);
00094 
00095     return 0;
00096 
00097 }
00098 
00099 
00100 /*
00101  * Execute the plugin instance given by the interface.
00102  */
00103 
00104 static cxint
00105 giframestack_exec(cpl_plugin* plugin)
00106 {
00107 
00108     cpl_recipe* recipe = (cpl_recipe*)plugin;
00109 
00110     cxint status = 0;
00111 
00112 
00113     if (recipe->parameters == NULL || recipe->frames == NULL) {
00114         return 1;
00115     }
00116 
00117     status = giframestack(recipe->parameters, recipe->frames);
00118 
00119     if (status != 0) {
00120         return 1;
00121     }
00122 
00123     return 0;
00124 
00125 }
00126 
00127 
00128 static cxint
00129 giframestack_destroy(cpl_plugin* plugin)
00130 {
00131 
00132     cpl_recipe* recipe = (cpl_recipe*)plugin;
00133 
00134 
00135     /*
00136      * We just destroy what was created during the plugin initialization
00137      * phase, i.e. the parameter list. The frame set is managed by the
00138      * application which called us, so we must not touch it,
00139      */
00140 
00141     cpl_parameterlist_delete(recipe->parameters);
00142 
00143     giraffe_error_clear();
00144 
00145     return 0;
00146 
00147 }
00148 
00149 /*
00150  * The actual recipe starts here.
00151  */
00152 
00153 static cxint
00154 giframestack(cpl_parameterlist* config, cpl_frameset* set)
00155 {
00156 
00157     const cxchar* const _id = "giframestack";
00158 
00159 
00160     cxint i = 0;
00161     cxint status = 0;
00162 
00163     cxdouble exptime = 0.;
00164 
00165     cx_string* tag = NULL;
00166 
00167     cx_list* frames = NULL;
00168     cx_list* images = NULL;
00169 
00170     cx_list_iterator position;
00171 
00172     cpl_size count = 0;
00173 
00174     cpl_propertylist* properties = NULL;
00175 
00176     cpl_frame* frame = NULL;
00177 
00178     GiImage* image = NULL;
00179     GiImage* result = NULL;
00180     GiImage** stack = NULL;
00181 
00182     GiStackingConfig* setup = NULL;
00183 
00184     GiRecipeInfo info = {(cxchar*)_id, 1, NULL};
00185 
00186 
00187 
00188     setup = giraffe_stacking_config_create(config);
00189 
00190     if (setup == NULL) {
00191         cpl_msg_error(_id, "Invalid parameter list! Aborting ...");
00192         return 1;
00193     }
00194 
00195 
00196     /*
00197      * Create the list of frames to combine.
00198      */
00199 
00200     /*
00201      * Search for the first image in the input frameset. This is
00202      * used as reference in the selection of the other frames.
00203      */
00204 
00205     cpl_msg_info(_id, "Searching for frames to combine ...");
00206 
00207     frame = cpl_frameset_get_first(set);
00208 
00209     if (frame == NULL) {
00210         cpl_msg_error(_id, "Empty input frameset encountered!");
00211 
00212         giraffe_stacking_config_destroy(setup);
00213         setup = NULL;
00214 
00215         return 1;
00216     }
00217 
00218 
00219     image = giraffe_image_new(CPL_TYPE_DOUBLE);
00220 
00221     status = giraffe_image_load(image, cpl_frame_get_filename(frame), 0);
00222 
00223     while (status != 0 && count < cpl_frameset_get_size(set)) {
00224 
00225         frame = cpl_frameset_get_next(set);
00226 
00227         status = giraffe_image_load(image, cpl_frame_get_filename(frame), 0);
00228         ++count;
00229 
00230     }
00231 
00232     if (count == cpl_frameset_get_size(set)) {
00233         cpl_msg_error(_id, "The input frameset does not contain any "
00234                       "images.");
00235 
00236         giraffe_image_delete(image);
00237         image = NULL;
00238 
00239         giraffe_stacking_config_destroy(setup);
00240         setup = NULL;
00241 
00242         return 1;
00243     }
00244 
00245     tag = cx_string_create(cpl_frame_get_tag(frame));
00246 
00247 
00248     /*
00249      * Select frames for combination. Only frames with the same tag
00250      * and the same size as the first raw frame are combined. All
00251      * other frames are ignored.
00252      */
00253 
00254     cpl_msg_info(_id, "Selecting '%s' frames for combination.",
00255                  cx_string_get(tag));
00256 
00257     frames = cx_list_new();
00258     cx_list_push_back(frames, frame);
00259 
00260     images = cx_list_new();
00261     cx_list_push_back(images, image);
00262 
00263 
00264     frame = cpl_frameset_find(set, cx_string_get(tag));
00265 
00266     if (frame == cx_list_front(frames)) {
00267         frame = cpl_frameset_find(set, NULL);
00268     }
00269 
00270     while (frame != NULL) {
00271 
00272         if (frame != cx_list_front(frames)) {
00273 
00274             GiImage* _image = giraffe_image_new(CPL_TYPE_DOUBLE);
00275 
00276 
00277             status = giraffe_image_load(_image,
00278                                         cpl_frame_get_filename(frame), 0);
00279 
00280             if (status == 0) {
00281 
00282                 cxint nx = cpl_image_get_size_x(giraffe_image_get(_image));
00283                 cxint ny = cpl_image_get_size_y(giraffe_image_get(_image));
00284 
00285                 if (nx == cpl_image_get_size_x(giraffe_image_get(image)) &&
00286                     ny == cpl_image_get_size_y(giraffe_image_get(image))) {
00287 
00288                     cx_list_push_back(frames, frame);
00289                     cx_list_push_back(images, _image);
00290 
00291                 }
00292                 else {
00293 
00294                     cpl_msg_warning(_id, "Ignoring frame '%s' because of "
00295                                     "different size!",
00296                                     cpl_frame_get_filename(frame));
00297 
00298                     giraffe_image_delete(_image);
00299                     _image = NULL;
00300 
00301                 }
00302 
00303             }
00304             else {
00305                 giraffe_image_delete(_image);
00306                 _image = NULL;
00307             }
00308 
00309         }
00310 
00311         frame = cpl_frameset_find(set, NULL);
00312 
00313     }
00314 
00315 
00316     /*
00317      * Check whether there are sufficient raw frames present in the
00318      * set for the selected combination method.
00319      */
00320 
00321     count = cx_list_size(images);
00322 
00323     if (count < setup->min_nr_frames) {
00324 
00325         cpl_msg_error(_id, "Not enough frames (%" CPL_SIZE_FORMAT
00326                       "). Stacking method '%d' requires at least %d frames! "
00327                       "Aborting...", count, setup->stackmethod,
00328                       setup->min_nr_frames);
00329 
00330         cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00331         images = NULL;
00332 
00333         cx_list_delete(frames);
00334         frames = NULL;
00335 
00336         cx_string_delete(tag);
00337         tag = NULL;
00338 
00339         giraffe_stacking_config_destroy(setup);
00340         setup = NULL;
00341 
00342         return 1;
00343 
00344     }
00345 
00346 
00347     /*
00348      * Combine the selected frames
00349      */
00350 
00351     cpl_msg_info(_id, "Combining %" CPL_SIZE_FORMAT " frames (%s) ...", count,
00352                  cx_string_get(tag));
00353 
00354     stack = cx_calloc(count + 1, sizeof(GiImage*));
00355 
00356     i = 0;
00357     position = cx_list_begin(images);
00358 
00359     while (position != cx_list_end(images)) {
00360         stack[i] = cx_list_get(images, position);
00361         position = cx_list_next(images, position);
00362         ++i;
00363     }
00364 
00365     result = giraffe_stacking_stack_images(stack, setup);
00366 
00367     if (result == NULL) {
00368 
00369         cpl_msg_error(_id,"Frame combination failed! Aborting ...");
00370 
00371         cx_free(stack);
00372         stack = NULL;
00373 
00374         cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00375         images = NULL;
00376 
00377         cx_list_delete(frames);
00378         frames = NULL;
00379 
00380         cx_string_delete(tag);
00381         tag = NULL;
00382 
00383         giraffe_stacking_config_destroy(setup);
00384         setup = NULL;
00385 
00386         return 1;
00387 
00388     }
00389 
00390     cx_free(stack);
00391     stack = NULL;
00392 
00393     giraffe_stacking_config_destroy(setup);
00394     setup = NULL;
00395 
00396 
00397     /*
00398      * Update the properties of the combined result frame.
00399      */
00400 
00401     cpl_msg_info(_id, "Updating combined frame properties ...");
00402 
00403     properties = giraffe_image_get_properties(cx_list_front(images));
00404     cx_assert(properties != NULL);
00405 
00406     giraffe_image_set_properties(result, properties);
00407     properties = giraffe_image_get_properties(result);
00408 
00409     if (properties == NULL) {
00410 
00411         cpl_msg_error(_id, "Updating combined frame properties failed!");
00412 
00413         giraffe_image_delete(result);
00414         result = NULL;
00415 
00416         cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00417         images = NULL;
00418 
00419         cx_list_delete(frames);
00420         frames = NULL;
00421 
00422         cx_string_delete(tag);
00423         tag = NULL;
00424 
00425         return 1;
00426 
00427     }
00428 
00429     giraffe_error_push();
00430 
00431     cpl_propertylist_update_double(properties, GIALIAS_BZERO, 0.);
00432     cpl_propertylist_update_double(properties, GIALIAS_CRPIX1, 1.);
00433 
00434     exptime = 0.;
00435     position = cx_list_begin(images);
00436 
00437     while (position != cx_list_end(images)) {
00438 
00439         cpl_propertylist* p =
00440             giraffe_image_get_properties(cx_list_get(images, position));
00441 
00442         exptime += cpl_propertylist_get_double(p, GIALIAS_EXPTIME);
00443         position = cx_list_next(images, position);
00444 
00445     }
00446 
00447     cpl_propertylist_update_double(properties, GIALIAS_EXPTTOT, exptime);
00448 
00449     cpl_propertylist_update_int(properties, GIALIAS_DATANCOM, count);
00450 
00451     cpl_propertylist_erase(properties, GIALIAS_EXPTIME);
00452     cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
00453 
00454 
00455     if (cpl_error_get_code() != CPL_ERROR_NONE) {
00456 
00457         cpl_msg_error(_id, "Updating combined frame properties failed!");
00458 
00459         giraffe_image_delete(result);
00460         result = NULL;
00461 
00462         cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00463         images = NULL;
00464 
00465         cx_list_delete(frames);
00466         frames = NULL;
00467 
00468         cx_string_delete(tag);
00469         tag = NULL;
00470 
00471         return 1;
00472 
00473     }
00474 
00475     giraffe_error_pop();
00476 
00477 
00478     /*
00479      * Save the combined result frame and register it as a product.
00480      */
00481 
00482     cpl_msg_info(_id, "Writing combined frame ...");
00483 
00484     giraffe_image_add_info(result, &info, set);
00485 
00486     cx_string_append(tag, "_COMBINED");
00487 
00488     frame = giraffe_frame_create_image(result, cx_string_get(tag),
00489                                        CPL_FRAME_LEVEL_FINAL, TRUE, TRUE);
00490 
00491     if (frame == NULL) {
00492 
00493         cpl_msg_error(_id, "Cannot create local file! Aborting ...");
00494 
00495         giraffe_image_delete(result);
00496         result = NULL;
00497 
00498         cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00499         images = NULL;
00500 
00501         cx_list_delete(frames);
00502         frames = NULL;
00503 
00504         cx_string_delete(tag);
00505         tag = NULL;
00506 
00507         return 1;
00508 
00509     }
00510 
00511     cpl_frameset_insert(set, frame);
00512 
00513 
00514     /*
00515      * Cleanup
00516      */
00517 
00518     giraffe_image_delete(result);
00519     result = NULL;
00520 
00521     cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00522     images = NULL;
00523 
00524     cx_list_delete(frames);
00525     frames = NULL;
00526 
00527     cx_string_delete(tag);
00528     tag = NULL;
00529 
00530     return 0;
00531 
00532 }
00533 
00534 
00535 /*
00536  * Build table of contents, i.e. the list of available plugins, for
00537  * this module. This function is exported.
00538  */
00539 
00540 int
00541 cpl_plugin_get_info(cpl_pluginlist* list)
00542 {
00543 
00544     cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
00545     cpl_plugin* plugin = &recipe->interface;
00546 
00547 
00548     cpl_plugin_init(plugin,
00549                     CPL_PLUGIN_API,
00550                     GIRAFFE_BINARY_VERSION,
00551                     CPL_PLUGIN_TYPE_RECIPE,
00552                     "giframestack",
00553                     "Creates a stacked image from a set of raw images.",
00554                     "TBD",
00555                     "Giraffe Pipeline",
00556                     PACKAGE_BUGREPORT,
00557                     giraffe_get_license(),
00558                     giframestack_create,
00559                     giframestack_exec,
00560                     giframestack_destroy);
00561 
00562     cpl_pluginlist_append(list, plugin);
00563 
00564     return 0;
00565 
00566 }

This file is part of the GIRAFFE Pipeline Reference Manual 2.9.0.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Jan 26 14:20:27 2012 by doxygen 1.6.3 written by Dimitri van Heesch, © 1997-2004