FORS Pipeline Reference Manual  4.12.5
fors_flatfield.c
1 /* $Id: fors_flatfield.c,v 1.6 2013-04-24 14:14:13 cgarcia Exp $
2  *
3  * This file is part of the FORS Data Reduction Pipeline
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: cgarcia $
23  * $Date: 2013-04-24 14:14:13 $
24  * $Revision: 1.6 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 #include <math.h>
33 #include <cpl.h>
34 #include <moses.h>
35 #include <fors_dfs.h>
36 
37 static int fors_flatfield_create(cpl_plugin *);
38 static int fors_flatfield_exec(cpl_plugin *);
39 static int fors_flatfield_destroy(cpl_plugin *);
40 static int fors_flatfield(cpl_parameterlist *, cpl_frameset *);
41 
42 static char fors_flatfield_description[] =
43 "This recipe is used to divide the input frame by the normalised flat\n"
44 "field frame produced by recipe fors_normalise_flat. The input frame must\n"
45 "be already bias subtracted (e.g., by recipe fors_remove_bias).\n"
46 "In the table below the MXU acronym can be alternatively read as MOS and\n"
47 "LSS.\n\n"
48 "Input files:\n\n"
49 " DO category: Type: Explanation: Required:\n"
50 " SCIENCE_UNBIAS_MXU\n"
51 " or STANDARD_UNBIAS_MXU Raw Bias subtracted frame Y\n"
52 " MASTER_NORM_FLAT_MXU Calib Normalised flat frame Y\n\n"
53 "Output files:\n\n"
54 " DO category: Data type: Explanation:\n"
55 " SCIENCE_UNFLAT_MXU\n"
56 " or STANDARD_UNFLAT_MXU FITS image Flat field corrected frame\n\n";
57 
58 #define fors_flatfield_exit(message) \
59 { \
60 if (message) cpl_msg_error(recipe, message); \
61 cpl_image_delete(raw_image); \
62 cpl_image_delete(norm_flat); \
63 cpl_propertylist_delete(header); \
64 cpl_msg_indent_less(); \
65 return -1; \
66 }
67 
68 #define fors_flatfield_exit_memcheck(message) \
69 { \
70 if (message) cpl_msg_info(recipe, message); \
71 printf("free raw_image (%p)\n", raw_image); \
72 cpl_image_delete(raw_image); \
73 printf("free norm_flat (%p)\n", norm_flat); \
74 cpl_image_delete(norm_flat); \
75 printf("free header (%p)\n", header); \
76 cpl_propertylist_delete(header); \
77 cpl_msg_indent_less(); \
78 return 0; \
79 }
80 
81 
93 int cpl_plugin_get_info(cpl_pluginlist *list)
94 {
95  cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
96  cpl_plugin *plugin = &recipe->interface;
97 
98  cpl_plugin_init(plugin,
99  CPL_PLUGIN_API,
100  FORS_BINARY_VERSION,
101  CPL_PLUGIN_TYPE_RECIPE,
102  "fors_flatfield",
103  "Flat field correction of input frame",
104  fors_flatfield_description,
105  "Carlo Izzo",
106  PACKAGE_BUGREPORT,
107  "This file is currently part of the FORS Instrument Pipeline\n"
108  "Copyright (C) 2002-2010 European Southern Observatory\n\n"
109  "This program is free software; you can redistribute it and/or modify\n"
110  "it under the terms of the GNU General Public License as published by\n"
111  "the Free Software Foundation; either version 2 of the License, or\n"
112  "(at your option) any later version.\n\n"
113  "This program is distributed in the hope that it will be useful,\n"
114  "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
115  "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
116  "GNU General Public License for more details.\n\n"
117  "You should have received a copy of the GNU General Public License\n"
118  "along with this program; if not, write to the Free Software Foundation,\n"
119  "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
120  fors_flatfield_create,
121  fors_flatfield_exec,
122  fors_flatfield_destroy);
123 
124  cpl_pluginlist_append(list, plugin);
125 
126  return 0;
127 }
128 
129 
140 static int fors_flatfield_create(cpl_plugin *plugin)
141 {
142  cpl_recipe *recipe;
143 /* Uncomment in case parameters are defined
144  cpl_parameter *p;
145 */
146 
147  /*
148  * Check that the plugin is part of a valid recipe
149  */
150 
151  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
152  recipe = (cpl_recipe *)plugin;
153  else
154  return -1;
155 
156  /*
157  * Create the (empty) parameters list in the cpl_recipe object
158  */
159 
160  recipe->parameters = cpl_parameterlist_new();
161 
162  return 0;
163 }
164 
165 
174 static int fors_flatfield_exec(cpl_plugin *plugin)
175 {
176  cpl_recipe *recipe;
177 
178  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
179  recipe = (cpl_recipe *)plugin;
180  else
181  return -1;
182 
183  return fors_flatfield(recipe->parameters, recipe->frames);
184 }
185 
186 
195 static int fors_flatfield_destroy(cpl_plugin *plugin)
196 {
197  cpl_recipe *recipe;
198 
199  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
200  recipe = (cpl_recipe *)plugin;
201  else
202  return -1;
203 
204  cpl_parameterlist_delete(recipe->parameters);
205 
206  return 0;
207 }
208 
209 
219 static int fors_flatfield(cpl_parameterlist *parlist, cpl_frameset *frameset)
220 {
221 
222  const char *recipe = "fors_flatfield";
223 
224 
225  /*
226  * CPL objects
227  */
228 
229  cpl_image *raw_image = NULL;
230  cpl_image *norm_flat = NULL;
231  cpl_propertylist *header = NULL;
232 
233  /*
234  * Auxiliary variables
235  */
236 
237  char version[80];
238  const char *norm_flat_tag;
239  const char *raw_image_tag;
240  const char *pro_image_tag;
241  char *instrume = NULL;
242  int science_mxu;
243  int science_mos;
244  int science_lss;
245  int standard_mxu;
246  int standard_mos;
247  int standard_lss;
248  int nflat, nframe;
249 
250 
251  cpl_msg_set_indentation(2);
252 
253 
254  cpl_msg_info(recipe, "Check input set-of-frames:");
255  cpl_msg_indent_more();
256 
257  nframe = science_mxu = cpl_frameset_count_tags(frameset,
258  "SCIENCE_UNBIAS_MXU");
259  nframe += science_mos = cpl_frameset_count_tags(frameset,
260  "SCIENCE_UNBIAS_MOS");
261  nframe += science_lss = cpl_frameset_count_tags(frameset,
262  "SCIENCE_UNBIAS_LSS");
263  nframe += standard_mxu = cpl_frameset_count_tags(frameset,
264  "STANDARD_UNBIAS_MXU");
265  nframe += standard_mos = cpl_frameset_count_tags(frameset,
266  "STANDARD_UNBIAS_MOS");
267  nframe += standard_lss = cpl_frameset_count_tags(frameset,
268  "STANDARD_UNBIAS_LSS");
269 
270  if (nframe == 0) {
271  fors_flatfield_exit("Missing required input scientific frame");
272  }
273  if (nframe > 1) {
274  cpl_msg_error(recipe, "Too many input scientific frames (%d > 1)",
275  nframe);
276  fors_flatfield_exit(NULL);
277  }
278 
279  if (science_mxu) {
280  norm_flat_tag = "MASTER_NORM_FLAT_MXU";
281  pro_image_tag = "SCIENCE_UNFLAT_MXU";
282  raw_image_tag = "SCIENCE_UNBIAS_MXU";
283  }
284  else if (science_mos) {
285  norm_flat_tag = "MASTER_NORM_FLAT_MOS";
286  pro_image_tag = "SCIENCE_UNFLAT_MOS";
287  raw_image_tag = "SCIENCE_UNBIAS_MOS";
288  }
289  else if (science_lss) {
290  norm_flat_tag = "MASTER_NORM_FLAT_LSS";
291  pro_image_tag = "SCIENCE_UNFLAT_LSS";
292  raw_image_tag = "SCIENCE_UNBIAS_LSS";
293  }
294  else if (standard_mxu) {
295  norm_flat_tag = "MASTER_NORM_FLAT_MXU";
296  pro_image_tag = "STANDARD_UNFLAT_MXU";
297  raw_image_tag = "STANDARD_UNBIAS_MXU";
298  }
299  else if (standard_mos) {
300  norm_flat_tag = "MASTER_NORM_FLAT_MOS";
301  pro_image_tag = "STANDARD_UNFLAT_MOS";
302  raw_image_tag = "STANDARD_UNBIAS_MOS";
303  }
304  else if (standard_lss) {
305  norm_flat_tag = "MASTER_NORM_FLAT_LSS";
306  pro_image_tag = "STANDARD_UNFLAT_LSS";
307  raw_image_tag = "STANDARD_UNBIAS_LSS";
308  }
309 
310  nflat = cpl_frameset_count_tags(frameset, norm_flat_tag);
311  if (nflat == 0) {
312  cpl_msg_error(recipe, "Missing required input: %s", norm_flat_tag);
313  fors_flatfield_exit(NULL);
314  }
315  if (nflat > 1) {
316  cpl_msg_error(recipe, "Too many in input (%d > 1): %s",
317  nflat, norm_flat_tag);
318  fors_flatfield_exit(NULL);
319  }
320 
321  if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
322  fors_flatfield_exit("Input frames are not from the same grism");
323 
324  if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
325  fors_flatfield_exit("Input frames are not from the same filter");
326 
327  if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
328  fors_flatfield_exit("Input frames are not from the same chip");
329 
330  header = dfs_load_header(frameset, raw_image_tag, 0);
331 
332  if (header == NULL) {
333  cpl_msg_error(recipe, "Cannot load header of %s frame", raw_image_tag);
334  fors_flatfield_exit(NULL);
335  }
336 
337  instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
338  if (instrume == NULL) {
339  cpl_msg_error(recipe, "Missing keyword INSTRUME in %s header",
340  raw_image_tag);
341  fors_flatfield_exit(NULL);
342  }
343 
344  if (instrume[4] == '1')
345  snprintf(version, 80, "%s/%s", "fors1", VERSION);
346  if (instrume[4] == '2')
347  snprintf(version, 80, "%s/%s", "fors2", VERSION);
348 
349  cpl_msg_indent_less();
350  cpl_msg_info(recipe, "Load input frames:");
351  cpl_msg_indent_more();
352 
353  norm_flat = dfs_load_image(frameset, norm_flat_tag, CPL_TYPE_FLOAT, 0, 1);
354  if (norm_flat == NULL)
355  fors_flatfield_exit("Cannot load normalised flat field");
356 
357  raw_image = dfs_load_image(frameset, raw_image_tag, CPL_TYPE_FLOAT, 0, 0);
358  if (raw_image == NULL) {
359  cpl_msg_error(recipe, "Cannot load %s frame", raw_image_tag);
360  fors_flatfield_exit(NULL);
361  }
362 
363  cpl_msg_indent_less();
364  cpl_msg_info(recipe, "Divide input %s by flat field...", raw_image_tag);
365  cpl_msg_indent_more();
366 
367  if (cpl_image_divide(raw_image, norm_flat) != CPL_ERROR_NONE) {
368  cpl_msg_error(recipe, "Failure of flat field correction: %s",
369  cpl_error_get_message());
370  fors_flatfield_exit(NULL);
371  }
372  cpl_image_delete(norm_flat); norm_flat = NULL;
373 
374  cpl_msg_indent_less();
375 
376  if (dfs_save_image(frameset, raw_image, pro_image_tag,
377  header, parlist, recipe, version))
378  fors_flatfield_exit(NULL);
379 
380  cpl_propertylist_delete(header); header = NULL;
381  cpl_image_delete(raw_image); raw_image = NULL;
382 
383  return 0;
384 }
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
Definition: fors_bias.c:62
cpl_image * dfs_load_image(cpl_frameset *frameset, const char *category, cpl_type type, int ext, int calib)
Loading image data of given category.
Definition: fors_dfs.c:845
cpl_propertylist * dfs_load_header(cpl_frameset *frameset, const char *category, int ext)
Loading header associated to data of given category.
Definition: fors_dfs.c:951
int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
Saving table data of given category.
Definition: fors_dfs.c:1685
int dfs_save_image(cpl_frameset *frameset, const cpl_image *image, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const char *version)
Saving image data of given category.
Definition: fors_dfs.c:1447
Definition: list.c:74