FORS Pipeline Reference Manual  4.12.5
fors_stack.c
1 /* $Id: fors_stack.c,v 1.17 2010-09-14 07:49:30 cizzo Exp $
2  *
3  * This file is part of the FORS Library
4  * Copyright (C) 2002-2010 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  * $Author: cizzo $
23  * $Date: 2010-09-14 07:49:30 $
24  * $Revision: 1.17 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 #include <fors_stack.h>
33 
34 #include <fors_dfs.h>
35 #include <fors_utils.h>
36 
37 #include <cpl.h>
38 
39 #include <string.h>
40 #include <stdbool.h>
41 
55 void fors_stack_define_parameters(cpl_parameterlist *parameters,
56  const char *context,
57  const char *default_method)
58 {
59  cpl_parameter *p;
60  const char *full_name = NULL;
61  const char *name;
62 
63  name = "stack_method";
64  full_name = cpl_sprintf("%s.%s", context, name);
65  p = cpl_parameter_new_enum(full_name,
66  CPL_TYPE_STRING,
67  "Frames combination method",
68  context,
69  default_method, 4,
70  "average", "median", "minmax", "ksigma");
71  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
72  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
73  cpl_parameterlist_append(parameters, p);
74  cpl_free((void *)full_name);
75 
76 
77  /* minmax */
78  name = "minrejection";
79  full_name = cpl_sprintf("%s.%s", context, name);
80  p = cpl_parameter_new_value(full_name,
81  CPL_TYPE_INT,
82  "Number of lowest values to be rejected",
83  context,
84  1);
85  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
86  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
87  cpl_parameterlist_append(parameters, p);
88  cpl_free((void *)full_name);
89 
90  name = "maxrejection";
91  full_name = cpl_sprintf("%s.%s", context, name);
92  p = cpl_parameter_new_value(full_name,
93  CPL_TYPE_INT,
94  "Number of highest values to be rejected",
95  context,
96  1);
97  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
98  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
99  cpl_parameterlist_append(parameters, p);
100  cpl_free((void *)full_name);
101 
102  /* ksigma */
103  name = "klow";
104  full_name = cpl_sprintf("%s.%s", context, name);
105  p = cpl_parameter_new_value(full_name,
106  CPL_TYPE_DOUBLE,
107  "Low threshold in ksigma method",
108  context,
109  3.0);
110  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
111  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
112  cpl_parameterlist_append(parameters, p);
113  cpl_free((void *)full_name);
114 
115  name = "khigh";
116  full_name = cpl_sprintf("%s.%s", context, name);
117  p = cpl_parameter_new_value(full_name,
118  CPL_TYPE_DOUBLE,
119  "High threshold in ksigma method",
120  context,
121  3.0);
122  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
123  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
124  cpl_parameterlist_append(parameters, p);
125  cpl_free((void *)full_name);
126 
127  name = "kiter";
128  full_name = cpl_sprintf("%s.%s", context, name);
129  p = cpl_parameter_new_value(full_name,
130  CPL_TYPE_INT,
131  "Max number of iterations in ksigma method",
132  context,
133  999);
134  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
135  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
136  cpl_parameterlist_append(parameters, p);
137  cpl_free((void *)full_name);
138 
139  return;
140 }
141 
142 #undef cleanup
143 #define cleanup \
144 do { \
145  cpl_free((void *)name); \
146 } while (0)
147 
156 stack_method *
157 fors_stack_method_new(const cpl_parameterlist *parameters, const char *context)
158 {
159  stack_method *sm = cpl_malloc(sizeof(stack_method));
160  const char *name = NULL;
161 
162  cpl_msg_info(cpl_func, "Stack method parameters:");
163 
164  cpl_msg_indent_more();
165  name = cpl_sprintf("%s.%s", context, "stack_method");
166  sm->method_name = dfs_get_parameter_string_const(parameters,
167  name);
168  cpl_free((void *)name); name = NULL;
169  cpl_msg_indent_less();
170 
171  assure( !cpl_error_get_code(), return NULL, NULL );
172  assure( sm->method_name != NULL, return NULL, NULL );
173 
174  if (strcmp(sm->method_name, "average") == 0) {
175  sm->method = AVERAGE;
176  }
177  else if (strcmp(sm->method_name, "mean") == 0) {
178  sm->method = MEAN;
179  }
180  else if (strcmp(sm->method_name, "wmean") == 0) {
181  sm->method = WMEAN;
182  }
183  else if (strcmp(sm->method_name, "median") == 0) {
184  sm->method = MEDIAN;
185  }
186  else if (strcmp(sm->method_name, "minmax") == 0) {
187 /*
188  assure( false, return NULL, "Unsupported stack method %s", sm->method_name);
189 */
190  sm->method = MINMAX;
191  }
192  else if (strcmp(sm->method_name, "ksigma") == 0) {
193  sm->method = KSIGMA;
194  }
195  else {
196  assure( false, return NULL, "Unknown stack method '%s'", sm->method_name);
197  }
198 
199  switch (sm->method) {
200  case AVERAGE: break;
201  case MEAN: break;
202  case WMEAN: break;
203  case MEDIAN: break;
204  case MINMAX:
205 
206  cpl_msg_indent_more();
207  cpl_msg_indent_more();
208  name = cpl_sprintf("%s.%s", context, "minrejection");
209  sm->pars.minmax.min_reject = dfs_get_parameter_int_const(parameters,
210  name);
211  cpl_free((void *)name); name = NULL;
212  cpl_msg_indent_less();
213  cpl_msg_indent_less();
214  assure( !cpl_error_get_code(), return NULL, NULL );
215 
216  cpl_msg_indent_more();
217  cpl_msg_indent_more();
218  name = cpl_sprintf("%s.%s", context, "maxrejection");
219  sm->pars.minmax.max_reject = dfs_get_parameter_int_const(parameters,
220  name);
221  cpl_free((void *)name); name = NULL;
222  cpl_msg_indent_less();
223  cpl_msg_indent_less();
224  assure( !cpl_error_get_code(), return NULL, NULL );
225 
226  break;
227  case KSIGMA:
228  cpl_msg_indent_more();
229  cpl_msg_indent_more();
230  name = cpl_sprintf("%s.%s", context, "klow");
231  sm->pars.ksigma.klow = dfs_get_parameter_double_const(parameters,
232  name);
233  cpl_free((void *)name); name = NULL;
234  cpl_msg_indent_less();
235  cpl_msg_indent_less();
236  assure( !cpl_error_get_code(), return NULL, NULL );
237 
238  cpl_msg_indent_more();
239  cpl_msg_indent_more();
240  name = cpl_sprintf("%s.%s", context, "khigh");
241  sm->pars.ksigma.khigh = dfs_get_parameter_double_const(parameters,
242  name);
243  cpl_free((void *)name); name = NULL;
244  cpl_msg_indent_less();
245  cpl_msg_indent_less();
246  assure( !cpl_error_get_code(), return NULL, NULL );
247 
248  cpl_msg_indent_more();
249  cpl_msg_indent_more();
250  name = cpl_sprintf("%s.%s", context, "kiter");
251  sm->pars.ksigma.kiter = dfs_get_parameter_int_const(parameters,
252  name);
253  cpl_free((void *)name); name = NULL;
254  cpl_msg_indent_less();
255  cpl_msg_indent_less();
256  assure( !cpl_error_get_code(), return NULL, NULL );
257 
258  break;
259  default:
260  passure( false, return NULL );
261  break;
262  } /* switch sm->method */
263 
264  cleanup;
265  return sm;
266 }
267 
272 void
273 fors_stack_method_delete(stack_method **sm)
274 {
275  if (sm && *sm) {
276  cpl_free(*sm); *sm = NULL;
277  }
278  return;
279 }
280 
281 #undef cleanup
282 #define cleanup
283 
288 const char *fors_stack_method_get_string(const stack_method *sm)
289 {
290  assure( sm != NULL, return "Null", NULL );
291 
292  return sm->method_name;
293 }
294 
295 #undef cleanup
296 #define cleanup \
297 do { \
298 } while (0)
299 
305 fors_image *
306 fors_stack_const(const fors_image_list *images, const stack_method *sm)
307 {
308  fors_image *master = NULL;
309 
310  assure( images != NULL, return master, NULL );
311  assure( fors_image_list_size(images) > 0, return master,
312  "No images to collapse");
313 
314  cpl_msg_info(cpl_func, "Stacking images (method = %s)",
316 
317  switch (sm->method) {
318  case AVERAGE:
319  master = fors_image_collapse_create(images);
320  break;
321  case MEDIAN:
322  master = fors_image_collapse_median_create(images);
323  break;
324  case MINMAX:
325  master = fors_image_collapse_minmax_create(images,
326  sm->pars.minmax.min_reject,
327  sm->pars.minmax.max_reject);
328  break;
329  case KSIGMA:
330 /*
331  assure( false, return NULL, "Unsupported stack method %s",
332  fors_stack_method_get_string(sm));
333 */
334  master = fors_image_collapse_ksigma_create(images,
335  sm->pars.ksigma.klow,
336  sm->pars.ksigma.khigh,
337  sm->pars.ksigma.kiter);
338  break;
339  default:
340  assure( false, return NULL, "Unknown stack method '%s' (%d)",
341  fors_stack_method_get_string(sm), sm->method);
342  break;
343  }
344 
345  return master;
346 }
347 
351 fors_image *
352 fors_stack(fors_image_list *images, const stack_method *sm)
353 {
354  return fors_stack_const((const fors_image_list *)images, sm);
355 }
356 
357 
fors_image * fors_image_collapse_create(const fors_image_list *images)
Average collapse.
Definition: fors_image.c:1473
const char * fors_stack_method_get_string(const stack_method *sm)
Stack method as string.
Definition: fors_stack.c:288
fors_image * fors_image_collapse_ksigma_create(const fors_image_list *images, int low, int high, int iter)
Ksigma collapse.
Definition: fors_image.c:1595
#define assure(EXPR)
Definition: list.c:101
int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:791
void fors_stack_define_parameters(cpl_parameterlist *parameters, const char *context, const char *default_method)
Define recipe parameters.
Definition: fors_stack.c:55
fors_image * fors_image_collapse_median_create(const fors_image_list *images)
Median collapse.
Definition: fors_image.c:1647
void fors_stack_method_delete(stack_method **sm)
Destructor.
Definition: fors_stack.c:273
stack_method * fors_stack_method_new(const cpl_parameterlist *parameters, const char *context)
Get stack method from parameter list.
Definition: fors_stack.c:157
const char * dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:811
fors_image * fors_stack(fors_image_list *images, const stack_method *sm)
Same as fors_stack_const()
Definition: fors_stack.c:352
fors_image * fors_stack_const(const fors_image_list *images, const stack_method *sm)
Stack images.
Definition: fors_stack.c:306
fors_image * fors_image_collapse_minmax_create(const fors_image_list *images, int low, int high)
Minmax collapse.
Definition: fors_image.c:1539
double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:801