GIRAFFE Pipeline Reference Manual

giframestack.c

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

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