fors_stack.c

00001 /* $Id: fors_stack.c,v 1.17 2010/09/14 07:49:30 cizzo Exp $
00002  *
00003  * This file is part of the FORS Library
00004  * Copyright (C) 2002-2010 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: 2010/09/14 07:49:30 $
00024  * $Revision: 1.17 $
00025  * $Name: fors-4_8_6 $
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         sm->method = KSIGMA;
00188     }
00189     else {
00190         assure( false, return NULL, "Unknown stack method '%s'", sm->method_name);
00191     }
00192 
00193     switch (sm->method) {
00194     case AVERAGE: break;
00195     case MEDIAN: break;
00196     case MINMAX:
00197 
00198         cpl_msg_indent_more();
00199         cpl_msg_indent_more();
00200         name = cpl_sprintf("%s.%s", context, "minrejection");
00201         sm->pars.minmax.min_reject = dfs_get_parameter_int_const(parameters, 
00202                                                                  name);
00203         cpl_free((void *)name); name = NULL;
00204         cpl_msg_indent_less();
00205         cpl_msg_indent_less();
00206         assure( !cpl_error_get_code(), return NULL, NULL );
00207         
00208         cpl_msg_indent_more();
00209         cpl_msg_indent_more();
00210         name = cpl_sprintf("%s.%s", context, "maxrejection");
00211         sm->pars.minmax.max_reject = dfs_get_parameter_int_const(parameters, 
00212                                                                  name);
00213         cpl_free((void *)name); name = NULL;
00214         cpl_msg_indent_less();
00215         cpl_msg_indent_less();
00216         assure( !cpl_error_get_code(), return NULL, NULL );
00217 
00218         break;
00219     case KSIGMA:
00220         cpl_msg_indent_more();
00221         cpl_msg_indent_more();
00222         name = cpl_sprintf("%s.%s", context, "klow");
00223         sm->pars.ksigma.klow = dfs_get_parameter_double_const(parameters, 
00224                                                               name);
00225         cpl_free((void *)name); name = NULL;
00226         cpl_msg_indent_less();
00227         cpl_msg_indent_less();
00228         assure( !cpl_error_get_code(), return NULL, NULL );
00229         
00230         cpl_msg_indent_more();
00231         cpl_msg_indent_more();
00232         name = cpl_sprintf("%s.%s", context, "khigh");
00233         sm->pars.ksigma.khigh = dfs_get_parameter_double_const(parameters, 
00234                                                                name);
00235         cpl_free((void *)name); name = NULL;
00236         cpl_msg_indent_less();
00237         cpl_msg_indent_less();
00238         assure( !cpl_error_get_code(), return NULL, NULL );
00239 
00240         cpl_msg_indent_more();
00241         cpl_msg_indent_more();
00242         name = cpl_sprintf("%s.%s", context, "kiter");
00243         sm->pars.ksigma.kiter = dfs_get_parameter_int_const(parameters, 
00244                                                             name);
00245         cpl_free((void *)name); name = NULL;
00246         cpl_msg_indent_less();
00247         cpl_msg_indent_less();
00248         assure( !cpl_error_get_code(), return NULL, NULL );
00249         
00250         break;
00251     default:
00252         passure( false, return NULL );
00253         break;
00254     } /* switch sm->method */
00255 
00256     cleanup;
00257     return sm;
00258 }
00259 
00264 void
00265 fors_stack_method_delete(stack_method **sm)
00266 {
00267     if (sm && *sm) {
00268         cpl_free(*sm); *sm = NULL;
00269     }
00270     return;
00271 }
00272 
00273 #undef cleanup
00274 #define cleanup
00275 
00280 static const char *fors_stack_method_get_string(const stack_method *sm)
00281 {
00282     assure( sm != NULL, return "Null", NULL );
00283 
00284     return sm->method_name;
00285 }
00286 
00287 #undef cleanup
00288 #define cleanup \
00289 do { \
00290 } while (0)
00291 
00297 fors_image *
00298 fors_stack_const(const fors_image_list *images, const stack_method *sm)
00299 {
00300     fors_image *master = NULL;
00301 
00302     assure( images != NULL, return master, NULL );
00303     assure( fors_image_list_size(images) > 0, return master, 
00304            "No images to collapse");
00305     
00306     cpl_msg_info(cpl_func, "Stacking images (method = %s)",
00307                  fors_stack_method_get_string(sm)); 
00308 
00309     switch (sm->method) {
00310     case AVERAGE: 
00311         master = fors_image_collapse_create(images);
00312         break;
00313     case MEDIAN: 
00314         master = fors_image_collapse_median_create(images);
00315         break;
00316     case MINMAX:
00317         master = fors_image_collapse_minmax_create(images, 
00318                                   sm->pars.minmax.min_reject,
00319                                   sm->pars.minmax.max_reject);
00320         break;
00321     case KSIGMA: 
00322 /*
00323         assure( false, return NULL, "Unsupported stack method %s",
00324                 fors_stack_method_get_string(sm));
00325 */
00326         master = fors_image_collapse_ksigma_create(images, 
00327                                   sm->pars.ksigma.klow,
00328                                   sm->pars.ksigma.khigh,
00329                                   sm->pars.ksigma.kiter);
00330         break;
00331     default:
00332         assure( false, return NULL, "Unknown stack method '%s' (%d)",
00333                 fors_stack_method_get_string(sm), sm->method);
00334         break;
00335     }    
00336 
00337     return master;
00338 }
00339 
00343 fors_image *
00344 fors_stack(fors_image_list *images, const stack_method *sm)
00345 {
00346     return fors_stack_const((const fors_image_list *)images, sm);
00347 }
00348 
00349 

Generated on Fri Mar 4 09:46:01 2011 for FORS Pipeline Reference Manual by  doxygen 1.4.7