FORS Pipeline Reference Manual 4.9.20
|
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_9_20 $ 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