GRAVI Pipeline Reference Manual  0.9.6
gravity_badpix.c
1 /* $Id: gravity_badpix.c,v 1.29 2009/02/10 09:16:12 llundin Exp $
2  *
3  * This file is part of the GRAVI Pipeline
4  * Copyright (C) 2002,2003 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 
25 /*-----------------------------------------------------------------------------
26  Includes
27  -----------------------------------------------------------------------------*/
28 
29 #include <cpl.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <time.h>
33 
34 #include "gravi_data.h"
35 #include "gravi_pfits.h"
36 #include "gravi_dfs.h"
37 
38 #include "gravi_utils.h"
39 
40 #include "gravi_calib.h"
41 
42 
43 /*-----------------------------------------------------------------------------
44  Private function prototypes
45  -----------------------------------------------------------------------------*/
46 
47 static int gravity_badpix_create(cpl_plugin *);
48 static int gravity_badpix_exec(cpl_plugin *);
49 static int gravity_badpix_destroy(cpl_plugin *);
50 static int gravity_badpix(cpl_frameset *, const cpl_parameterlist *);
51 
52 /*-----------------------------------------------------------------------------
53  Static variables
54  -----------------------------------------------------------------------------*/
55 static char gravity_badpix_short[] = "Calibrate the badpixels from the detectors.";
56 static char gravity_badpix_description[] = "The recipe creates a BAD calibration map from raw DARKs and raw FLATs observations. Since it is not associated with the calibration of the instrumental transmission, more specific darks or flats can be used. Such as very long darks, fore better statistic; and/or defocused flats to illuminate more pixels. The create BAD map can then be used as an input for further calibration (P2VM) and observations.\n"
57  GRAVI_RECIPE_INPUT"\n"
58  GRAVI_DARK_RAW" : raw dark, all shutters closed (DPR.TYPE=DARK)\n"
59  GRAVI_FLAT_RAW" x4 : raw flats, one sutter open (DPR.TYPE=FLAT)\n"
60  GRAVI_RECIPE_OUTPUT"\n"
61  GRAVI_BAD_MAP" : badpixel calibration (PRO.CATG="GRAVI_BAD_MAP") \n"
62  ;
63 
64 /*-----------------------------------------------------------------------------
65  Function code
66  -----------------------------------------------------------------------------*/
67 
68 /*----------------------------------------------------------------------------*/
78 /*----------------------------------------------------------------------------*/
79 int cpl_plugin_get_info(cpl_pluginlist * list)
80 {
81  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
82  cpl_plugin * plugin = &recipe->interface;
83 
84  if (cpl_plugin_init(plugin,
85  CPL_PLUGIN_API,
86  GRAVI_BINARY_VERSION,
87  CPL_PLUGIN_TYPE_RECIPE,
88  "gravity_badpix",
89  gravity_badpix_short,
90  gravity_badpix_description,
91  "Nabih Azouaoui, Vincent Lapeyrere, JB. Le Bouquin",
92  PACKAGE_BUGREPORT,
93  gravi_get_license(),
94  gravity_badpix_create,
95  gravity_badpix_exec,
96  gravity_badpix_destroy)) {
97  cpl_msg_error(cpl_func, "Plugin initialization failed");
98  (void)cpl_error_set_where(cpl_func);
99  return 1;
100  }
101 
102  if (cpl_pluginlist_append(list, plugin)) {
103  cpl_msg_error(cpl_func, "Error adding plugin to list");
104  (void)cpl_error_set_where(cpl_func);
105  return 1;
106  }
107 
108  return 0;
109 }
110 
111 /*----------------------------------------------------------------------------*/
119 /*----------------------------------------------------------------------------*/
120 static int gravity_badpix_create(cpl_plugin * plugin)
121 {
122  cpl_recipe * recipe;
123  // cpl_parameter * p;
124 
125  /* Do not create the recipe if an error code is already set */
126  if (cpl_error_get_code() != CPL_ERROR_NONE) {
127  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
128  cpl_func, __LINE__, cpl_error_get_where());
129  return (int)cpl_error_get_code();
130  }
131 
132  if (plugin == NULL) {
133  cpl_msg_error(cpl_func, "Null plugin");
134  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
135  }
136 
137  /* Verify plugin type */
138  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
139  cpl_msg_error(cpl_func, "Plugin is not a recipe");
140  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
141  }
142 
143  /* Get the recipe */
144  recipe = (cpl_recipe *)plugin;
145 
146  /* Create the parameters list in the cpl_recipe object */
147  recipe->parameters = cpl_parameterlist_new();
148  if (recipe->parameters == NULL) {
149  cpl_msg_error(cpl_func, "Parameter list allocation failed");
150  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
151  }
152 
153  /* Fill the parameters list */
154 
155  /* Use static names (output_procatg.fits) */
156  gravi_parameter_add_static_name (recipe->parameters);
157 
158  /* Badpix */
159  gravi_parameter_add_badpix (recipe->parameters);
160 
161  return 0;
162 }
163 
164 /*----------------------------------------------------------------------------*/
170 /*----------------------------------------------------------------------------*/
171 static int gravity_badpix_exec(cpl_plugin * plugin)
172 {
173 
174  cpl_recipe * recipe;
175  int recipe_status;
176  cpl_errorstate initial_errorstate = cpl_errorstate_get();
177 
178  /* Return immediately if an error code is already set */
179  if (cpl_error_get_code() != CPL_ERROR_NONE) {
180  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
181  cpl_func, __LINE__, cpl_error_get_where());
182  return (int)cpl_error_get_code();
183  }
184 
185  if (plugin == NULL) {
186  cpl_msg_error(cpl_func, "Null plugin");
187  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
188  }
189 
190  /* Verify plugin type */
191  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
192  cpl_msg_error(cpl_func, "Plugin is not a recipe");
193  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
194  }
195 
196  /* Get the recipe */
197  recipe = (cpl_recipe *)plugin;
198 
199  /* Verify parameter and frame lists */
200  if (recipe->parameters == NULL) {
201  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
202  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
203  }
204  if (recipe->frames == NULL) {
205  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
206  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
207  }
208 
209  /* Invoke the recipe */
210  recipe_status = gravity_badpix(recipe->frames, recipe->parameters);
211 
212  /* Ensure DFS-compliance of the products */
213  if (cpl_dfs_update_product_header(recipe->frames)) {
214  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
215  }
216 
217  if (!cpl_errorstate_is_equal(initial_errorstate)) {
218  /* Dump the error history since recipe execution start.
219  At this point the recipe cannot recover from the error */
220  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
221  }
222 
223  return recipe_status;
224 }
225 
226 /*----------------------------------------------------------------------------*/
232 /*----------------------------------------------------------------------------*/
233 static int gravity_badpix_destroy(cpl_plugin * plugin)
234 {
235  cpl_recipe * recipe;
236 
237  if (plugin == NULL) {
238  cpl_msg_error(cpl_func, "Null plugin");
239  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
240  }
241 
242  /* Verify plugin type */
243  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
244  cpl_msg_error(cpl_func, "Plugin is not a recipe");
245  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
246  }
247 
248  /* Get the recipe */
249  recipe = (cpl_recipe *)plugin;
250 
251  cpl_parameterlist_delete(recipe->parameters);
252 
253  return 0;
254 }
255 
256 /*----------------------------------------------------------------------------*/
264 /*----------------------------------------------------------------------------*/
265 static int gravity_badpix(cpl_frameset * frameset,
266  const cpl_parameterlist * parlist)
267 {
268  cpl_frameset * dark_frameset=NULL, * flat_frameset=NULL, * used_frameset=NULL;
269 
270  cpl_frame * frame=NULL;
271 
272  gravi_data * data = NULL, * dark_map=NULL;
273  gravi_data ** raw_data=NULL, * badpix_map=NULL;
274 
275  int nb_frame_gain = 0;
276 
277  /* Message */
278  gravity_print_banner ();
279  cpl_msg_set_time_on();
280  cpl_msg_set_component_on();
281  gravi_msg_function_start(1);
282 
283  /* Get the input frameset */
284  cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE, cpl_error_get_code()) ;
285 
286  /* Init the used frameset */
287  used_frameset = cpl_frameset_new ();
288 
289  /* Extract DARK frameset */
290  dark_frameset = gravi_frameset_extract_dark_data (frameset);
291 
292  /* Extract FLAT frameset */
293  flat_frameset = gravi_frameset_extract_flat_data (frameset);
294 
295  /* To use this recipe the frameset must contain the p2vm, wave and
296  * gain calibration file. */
297  if ( cpl_frameset_is_empty (dark_frameset) ||
298  cpl_frameset_get_size (dark_frameset) != 1 ||
299  cpl_frameset_is_empty (flat_frameset) ||
300  cpl_frameset_get_size (flat_frameset) != 4 ) {
301  cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
302  "Need 1 DARK_RAW and 4 FLAT_RAW");
303  goto cleanup;
304  }
305 
306 
307  /*
308  * (1) Identify and extract the dark file
309  */
310 
311  cpl_msg_info (cpl_func, " ***** Compute DARK map ***** ");
312 
313  /* Load this DARK_RAW */
314  frame = cpl_frameset_get_position (dark_frameset, 0);
315  data = gravi_data_load_rawframe (frame, used_frameset);
316  /* Don't cleanup, since the bias-pixels maybe illuminated */
317  // gravi_data_detector_cleanup (data, parlist);
318 
319  /* Compute the dark */
320  dark_map = gravi_compute_dark (data);
321  FREE (gravi_data_delete, data);
322 
323  CPLCHECK_CLEAN ("Cannot compute the DARK map");
324 
325  /*
326  * (2) Load the FLAT files
327  */
328 
329  cpl_msg_info (cpl_func, " ***** Load FLATs ***** ");
330 
331  /* Identify the flat files */
332  nb_frame_gain = cpl_frameset_get_size (flat_frameset);
333  raw_data = cpl_calloc (nb_frame_gain, sizeof(gravi_data *));
334 
335  /* Build the list of FLAT files and output file name */
336  for (int i = 0; i < nb_frame_gain; i++) {
337  frame = cpl_frameset_get_position (flat_frameset, i);
338  raw_data[i] = gravi_data_load_rawframe (frame, used_frameset);
339  /* Don't cleanup, since the bias-pixels maybe illuminated */
340  // gravi_data_detector_cleanup (raw_data[i], parlist);
341  }
342 
343  /*
344  * (2) Compute the BADPIX from the DARK and FLATs
345  */
346 
347  cpl_msg_info (cpl_func, " ***** Compute BAD pixel map ***** ");
348  badpix_map = gravi_compute_badpix (dark_map, raw_data,
349  nb_frame_gain, parlist);
350 
351  CPLCHECK_CLEAN("Cannot compute the BAD pixel from DARK and FLATs");
352 
353  /* Free the list of files */
354  FREELOOP (gravi_data_delete, raw_data, nb_frame_gain);
355 
356  /* Save the BAD */
357  frame = cpl_frameset_get_position (dark_frameset, 0);
358  gravi_data_save_new (badpix_map, frameset, NULL, parlist,
359  NULL, frame, "gravity_badpix",
360  NULL, GRAVI_BAD_MAP);
361 
362  CPLCHECK_CLEAN ("Could not save the BAD pixel map");
363 
364  /* Deallocation of all variables */
365  cleanup:
366  cpl_msg_info (cpl_func,"Cleanup memory");
367 
368  FREE (cpl_frameset_delete, dark_frameset);
369  FREE (gravi_data_delete, dark_map);
370  FREELOOP (gravi_data_delete, raw_data, nb_frame_gain);
371  FREE (gravi_data_delete, badpix_map);
372  FREE (cpl_frameset_delete, flat_frameset);
373  FREE (cpl_frameset_delete, used_frameset);
374  FREE (gravi_data_delete, data);
375 
376  /* FIXME: check a *change* of cpl_state instead */
377  CPLCHECK_INT ("Could not cleanup memory");
378 
379  gravi_msg_function_exit(1);
380  return (int)cpl_error_get_code();
381 }
382 
383