fors_stack.c

00001 /* $Id: fors_stack.c,v 1.15 2008/02/28 15:04:54 cizzo Exp $
00002  *
00003  * This file is part of the FORS Library
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: cizzo $
00023  * $Date: 2008/02/28 15:04:54 $
00024  * $Revision: 1.15 $
00025  * $Name:  $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #include <fors_stack.h>
00033 
00034 #include <fors_dfs.h>
00035 #include <fors_utils.h>
00036 
00037 #include <cpl.h>
00038 
00039 #include <string.h>
00040 #include <stdbool.h>
00041 
00055 void fors_stack_define_parameters(cpl_parameterlist *parameters, 
00056                                   const char *context,
00057                                   const char *default_method)
00058 {
00059     cpl_parameter *p;
00060     const char *full_name = NULL;
00061     const char *name;
00062 
00063     name = "stack_method";
00064     full_name = cpl_sprintf("%s.%s", context, name);
00065     p = cpl_parameter_new_enum(full_name,
00066                                CPL_TYPE_STRING,
00067                                "Frames combination method",
00068                                context,
00069                                default_method, 4,
00070                                "average", "median", "minmax", "ksigma");
00071     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00072     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00073     cpl_parameterlist_append(parameters, p);
00074     cpl_free((void *)full_name);
00075 
00076 
00077     /* minmax */
00078     name = "minrejection";
00079     full_name = cpl_sprintf("%s.%s", context, name);
00080     p = cpl_parameter_new_value(full_name,
00081                                 CPL_TYPE_INT,
00082                                 "Number of lowest values to be rejected",
00083                                 context,
00084                                 1);
00085     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00086     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00087     cpl_parameterlist_append(parameters, p);
00088     cpl_free((void *)full_name);
00089 
00090     name = "maxrejection";
00091     full_name = cpl_sprintf("%s.%s", context, name);
00092     p = cpl_parameter_new_value(full_name,
00093                                 CPL_TYPE_INT,
00094                                 "Number of highest values to be rejected",
00095                                 context,
00096                                 1);
00097     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00098     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00099     cpl_parameterlist_append(parameters, p);
00100     cpl_free((void *)full_name);
00101 
00102     /* ksigma */
00103     name = "klow";
00104     full_name = cpl_sprintf("%s.%s", context, name);
00105     p = cpl_parameter_new_value(full_name,
00106                                 CPL_TYPE_DOUBLE,
00107                                 "Low threshold in ksigma method",
00108                                 context,
00109                                 3.0);
00110     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00111     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00112     cpl_parameterlist_append(parameters, p);
00113     cpl_free((void *)full_name);
00114 
00115     name = "khigh";
00116     full_name = cpl_sprintf("%s.%s", context, name);
00117     p = cpl_parameter_new_value(full_name,
00118                                 CPL_TYPE_DOUBLE,
00119                                 "High threshold in ksigma method",
00120                                 context,
00121                                 3.0);
00122     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00123     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00124     cpl_parameterlist_append(parameters, p);
00125     cpl_free((void *)full_name);
00126 
00127     name = "kiter";
00128     full_name = cpl_sprintf("%s.%s", context, name);
00129     p = cpl_parameter_new_value(full_name,
00130                                 CPL_TYPE_INT,
00131                                 "Max number of iterations in ksigma method",
00132                                 context,
00133                                 999);
00134     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00135     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00136     cpl_parameterlist_append(parameters, p);
00137     cpl_free((void *)full_name);
00138 
00139     return;
00140 }
00141 
00142 #undef cleanup
00143 #define cleanup \
00144 do { \
00145     cpl_free((void *)name); \
00146 } while (0)
00147 
00156 stack_method *
00157 fors_stack_method_new(const cpl_parameterlist *parameters, const char *context)
00158 {
00159     stack_method *sm = cpl_malloc(sizeof(stack_method));
00160     const char *name = NULL;
00161 
00162     cpl_msg_info(cpl_func, "Stack method parameters:");
00163 
00164     cpl_msg_indent_more();
00165     name = cpl_sprintf("%s.%s", context, "stack_method");
00166     sm->method_name = dfs_get_parameter_string_const(parameters, 
00167                                             name);
00168     cpl_free((void *)name); name = NULL;
00169     cpl_msg_indent_less();
00170 
00171     assure( !cpl_error_get_code(), return NULL, NULL );
00172     assure( sm->method_name != NULL, return NULL, NULL );
00173 
00174     if (strcmp(sm->method_name, "average") == 0) {
00175         sm->method = AVERAGE;
00176     }
00177     else if (strcmp(sm->method_name, "median") == 0) {
00178         sm->method = MEDIAN;
00179     }
00180     else if (strcmp(sm->method_name, "minmax") == 0) {
00181 /*
00182         assure( false, return NULL, "Unsupported stack method %s", sm->method_name);
00183 */
00184         sm->method = MINMAX;
00185     }
00186     else if (strcmp(sm->method_name, "ksigma") == 0) {
00187         assure( false, return NULL, "Unsupported stack method %s", sm->method_name);
00188         sm->method = KSIGMA;
00189     }
00190     else {
00191         assure( false, return NULL, "Unknown stack method '%s'", sm->method_name);
00192     }
00193 
00194     switch (sm->method) {
00195     case AVERAGE: break;
00196     case MEDIAN: break;
00197     case MINMAX:
00198 
00199         cpl_msg_indent_more();
00200         cpl_msg_indent_more();
00201         name = cpl_sprintf("%s.%s", context, "minrejection");
00202         sm->pars.minmax.min_reject = dfs_get_parameter_int_const(parameters, 
00203                                                                  name);
00204         cpl_free((void *)name); name = NULL;
00205         cpl_msg_indent_less();
00206         cpl_msg_indent_less();
00207         assure( !cpl_error_get_code(), return NULL, NULL );
00208         
00209         cpl_msg_indent_more();
00210         cpl_msg_indent_more();
00211         name = cpl_sprintf("%s.%s", context, "maxrejection");
00212         sm->pars.minmax.max_reject = dfs_get_parameter_int_const(parameters, 
00213                                                                  name);
00214         cpl_free((void *)name); name = NULL;
00215         cpl_msg_indent_less();
00216         cpl_msg_indent_less();
00217         assure( !cpl_error_get_code(), return NULL, NULL );
00218 
00219         break;
00220     case KSIGMA:
00221         cpl_msg_indent_more();
00222         cpl_msg_indent_more();
00223         name = cpl_sprintf("%s.%s", context, "klow");
00224         sm->pars.ksigma.klow = dfs_get_parameter_double_const(parameters, 
00225                                                               name);
00226         cpl_free((void *)name); name = NULL;
00227         cpl_msg_indent_less();
00228         cpl_msg_indent_less();
00229         assure( !cpl_error_get_code(), return NULL, NULL );
00230         
00231         cpl_msg_indent_more();
00232         cpl_msg_indent_more();
00233         name = cpl_sprintf("%s.%s", context, "khigh");
00234         sm->pars.ksigma.khigh = dfs_get_parameter_double_const(parameters, 
00235                                                                name);
00236         cpl_free((void *)name); name = NULL;
00237         cpl_msg_indent_less();
00238         cpl_msg_indent_less();
00239         assure( !cpl_error_get_code(), return NULL, NULL );
00240 
00241         cpl_msg_indent_more();
00242         cpl_msg_indent_more();
00243         name = cpl_sprintf("%s.%s", context, "kiter");
00244         sm->pars.ksigma.kiter = dfs_get_parameter_int_const(parameters, 
00245                                                             name);
00246         cpl_free((void *)name); name = NULL;
00247         cpl_msg_indent_less();
00248         cpl_msg_indent_less();
00249         assure( !cpl_error_get_code(), return NULL, NULL );
00250         
00251         break;
00252     default:
00253         passure( false, return NULL );
00254         break;
00255     } /* switch sm->method */
00256 
00257     cleanup;
00258     return sm;
00259 }
00260 
00265 void
00266 fors_stack_method_delete(stack_method **sm)
00267 {
00268     if (sm && *sm) {
00269         cpl_free(*sm); *sm = NULL;
00270     }
00271     return;
00272 }
00273 
00274 #undef cleanup
00275 #define cleanup
00276 
00281 static const char *fors_stack_method_get_string(const stack_method *sm)
00282 {
00283     assure( sm != NULL, return "Null", NULL );
00284 
00285     return sm->method_name;
00286 }
00287 
00288 #undef cleanup
00289 #define cleanup \
00290 do { \
00291 } while (0)
00292 
00298 fors_image *
00299 fors_stack_const(const fors_image_list *images, const stack_method *sm)
00300 {
00301     fors_image *master = NULL;
00302 
00303     assure( images != NULL, return master, NULL );
00304     assure( fors_image_list_size(images) > 0, return master, 
00305            "No images to collapse");
00306     
00307     cpl_msg_info(cpl_func, "Stacking images (method = %s)",
00308                  fors_stack_method_get_string(sm)); 
00309 
00310     switch (sm->method) {
00311     case AVERAGE: 
00312         master = fors_image_collapse_create(images);
00313         break;
00314     case MEDIAN: 
00315         master = fors_image_collapse_median_create(images);
00316         break;
00317     case MINMAX:
00318         /* When implementing this method, also revist the computation
00319            of RONEXP */
00320 /*
00321         assure( false, return NULL, "Unsupported stack method %s",
00322                 fors_stack_method_get_string(sm));
00323 */
00324         master = fors_image_collapse_minmax_create(images, 
00325                                   sm->pars.minmax.min_reject,
00326                                   sm->pars.minmax.max_reject);
00327         break;
00328     case KSIGMA: 
00329         assure( false, return NULL, "Unsupported stack method %s",
00330                 fors_stack_method_get_string(sm));
00331         break;
00332     default:
00333         assure( false, return NULL, "Unknown stack method '%s' (%d)",
00334                 fors_stack_method_get_string(sm), sm->method);
00335         break;
00336     }    
00337 
00338     return master;
00339 }
00340 
00344 fors_image *
00345 fors_stack(fors_image_list *images, const stack_method *sm)
00346 {
00347     return fors_stack_const((const fors_image_list *)images, sm);
00348 }
00349 
00350 

Generated on Wed Sep 10 07:31:52 2008 for FORS Pipeline Reference Manual by  doxygen 1.4.6