GRAVI Pipeline Reference Manual  1.2.3
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_FLOW"\n"
58  "* Load input files\n"
59  "* Compute badpixel from dark rms, dark median, and flat value\n"
60  "* Save the product)\n"
61  GRAVI_RECIPE_INPUT"\n"
62  GRAVI_DARK_RAW" : raw dark, all shutters closed (DPR.TYPE=DARK)\n"
63  GRAVI_FLAT_RAW" x4 : raw flats, one sutter open (DPR.TYPE=FLAT)\n"
64  GRAVI_RECIPE_OUTPUT"\n"
65  GRAVI_BAD_MAP" : badpixel calibration (PRO.CATG="GRAVI_BAD_MAP") \n"
66  ;
67 
68 /*-----------------------------------------------------------------------------
69  Function code
70  -----------------------------------------------------------------------------*/
71 
72 /*----------------------------------------------------------------------------*/
82 /*----------------------------------------------------------------------------*/
83 int cpl_plugin_get_info(cpl_pluginlist * list)
84 {
85  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
86  cpl_plugin * plugin = &recipe->interface;
87 
88  if (cpl_plugin_init(plugin,
89  CPL_PLUGIN_API,
90  GRAVI_BINARY_VERSION,
91  CPL_PLUGIN_TYPE_RECIPE,
92  "gravity_badpix",
93  gravity_badpix_short,
94  gravity_badpix_description,
95  "Nabih Azouaoui, Vincent Lapeyrere, JB. Le Bouquin",
96  PACKAGE_BUGREPORT,
98  gravity_badpix_create,
99  gravity_badpix_exec,
100  gravity_badpix_destroy)) {
101  cpl_msg_error(cpl_func, "Plugin initialization failed");
102  (void)cpl_error_set_where(cpl_func);
103  return 1;
104  }
105 
106  if (cpl_pluginlist_append(list, plugin)) {
107  cpl_msg_error(cpl_func, "Error adding plugin to list");
108  (void)cpl_error_set_where(cpl_func);
109  return 1;
110  }
111 
112  return 0;
113 }
114 
115 /*----------------------------------------------------------------------------*/
123 /*----------------------------------------------------------------------------*/
124 static int gravity_badpix_create(cpl_plugin * plugin)
125 {
126  cpl_recipe * recipe;
127  // cpl_parameter * p;
128 
129  /* Do not create the recipe if an error code is already set */
130  if (cpl_error_get_code() != CPL_ERROR_NONE) {
131  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
132  cpl_func, __LINE__, cpl_error_get_where());
133  return (int)cpl_error_get_code();
134  }
135 
136  if (plugin == NULL) {
137  cpl_msg_error(cpl_func, "Null plugin");
138  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
139  }
140 
141  /* Verify plugin type */
142  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
143  cpl_msg_error(cpl_func, "Plugin is not a recipe");
144  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
145  }
146 
147  /* Get the recipe */
148  recipe = (cpl_recipe *)plugin;
149 
150  /* Create the parameters list in the cpl_recipe object */
151  recipe->parameters = cpl_parameterlist_new();
152  if (recipe->parameters == NULL) {
153  cpl_msg_error(cpl_func, "Parameter list allocation failed");
154  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
155  }
156 
157  /* Fill the parameters list */
158 
159  /* Use static names (output_procatg.fits) */
160  gravi_parameter_add_static_name (recipe->parameters);
161 
162  /* Badpix */
163  gravi_parameter_add_badpix (recipe->parameters);
164 
165  return 0;
166 }
167 
168 /*----------------------------------------------------------------------------*/
174 /*----------------------------------------------------------------------------*/
175 static int gravity_badpix_exec(cpl_plugin * plugin)
176 {
177 
178  cpl_recipe * recipe;
179  int recipe_status;
180  cpl_errorstate initial_errorstate = cpl_errorstate_get();
181 
182  /* Return immediately if an error code is already set */
183  if (cpl_error_get_code() != CPL_ERROR_NONE) {
184  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
185  cpl_func, __LINE__, cpl_error_get_where());
186  return (int)cpl_error_get_code();
187  }
188 
189  if (plugin == NULL) {
190  cpl_msg_error(cpl_func, "Null plugin");
191  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
192  }
193 
194  /* Verify plugin type */
195  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
196  cpl_msg_error(cpl_func, "Plugin is not a recipe");
197  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
198  }
199 
200  /* Get the recipe */
201  recipe = (cpl_recipe *)plugin;
202 
203  /* Verify parameter and frame lists */
204  if (recipe->parameters == NULL) {
205  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
206  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
207  }
208  if (recipe->frames == NULL) {
209  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
210  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
211  }
212 
213  /* Invoke the recipe */
214  recipe_status = gravity_badpix(recipe->frames, recipe->parameters);
215 
216  /* Ensure DFS-compliance of the products */
217  if (cpl_dfs_update_product_header(recipe->frames)) {
218  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
219  }
220 
221  if (!cpl_errorstate_is_equal(initial_errorstate)) {
222  /* Dump the error history since recipe execution start.
223  At this point the recipe cannot recover from the error */
224  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
225  }
226 
227  return recipe_status;
228 }
229 
230 /*----------------------------------------------------------------------------*/
236 /*----------------------------------------------------------------------------*/
237 static int gravity_badpix_destroy(cpl_plugin * plugin)
238 {
239  cpl_recipe * recipe;
240 
241  if (plugin == NULL) {
242  cpl_msg_error(cpl_func, "Null plugin");
243  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
244  }
245 
246  /* Verify plugin type */
247  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
248  cpl_msg_error(cpl_func, "Plugin is not a recipe");
249  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
250  }
251 
252  /* Get the recipe */
253  recipe = (cpl_recipe *)plugin;
254 
255  cpl_parameterlist_delete(recipe->parameters);
256 
257  return 0;
258 }
259 
260 /*----------------------------------------------------------------------------*/
268 /*----------------------------------------------------------------------------*/
269 static int gravity_badpix(cpl_frameset * frameset,
270  const cpl_parameterlist * parlist)
271 {
272  cpl_frameset * dark_frameset=NULL, * flat_frameset=NULL, * used_frameset=NULL;
273 
274  cpl_frame * frame=NULL;
275 
276  gravi_data * data = NULL, * dark_map=NULL;
277  gravi_data ** raw_data=NULL, * badpix_map=NULL;
278 
279  int nb_frame_gain = 0;
280 
281  /* Message */
282  gravity_print_banner ();
283  cpl_msg_set_time_on();
284  cpl_msg_set_component_on();
285  gravi_msg_function_start(1);
286 
287  /* Get the input frameset */
288  cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE, cpl_error_get_code()) ;
289 
290  /* Init the used frameset */
291  used_frameset = cpl_frameset_new ();
292 
293  /* Extract DARK frameset */
294  dark_frameset = gravi_frameset_extract_dark_data (frameset);
295 
296  /* Extract FLAT frameset */
297  flat_frameset = gravi_frameset_extract_flat_data (frameset);
298 
299  /* To use this recipe the frameset must contain the p2vm, wave and
300  * gain calibration file. */
301  if ( cpl_frameset_is_empty (dark_frameset) ||
302  cpl_frameset_get_size (dark_frameset) != 1 ||
303  cpl_frameset_is_empty (flat_frameset) ||
304  cpl_frameset_get_size (flat_frameset) != 4 ) {
305  cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
306  "Need 1 DARK_RAW and 4 FLAT_RAW");
307  goto cleanup;
308  }
309 
310 
311  /*
312  * (1) Identify and extract the dark file
313  */
314 
315  cpl_msg_info (cpl_func, " ***** Compute DARK map ***** ");
316 
317  /* Load this DARK_RAW */
318  frame = cpl_frameset_get_position (dark_frameset, 0);
319  data = gravi_data_load_rawframe (frame, used_frameset);
320  /* Don't cleanup, since the bias-pixels maybe illuminated */
321  // gravi_data_detector_cleanup (data, parlist);
322 
323  /* Compute the dark */
324  dark_map = gravi_compute_dark (data);
325  FREE (gravi_data_delete, data);
326 
327  CPLCHECK_CLEAN ("Cannot compute the DARK map");
328 
329  /*
330  * (2) Load the FLAT files
331  */
332 
333  cpl_msg_info (cpl_func, " ***** Load FLATs ***** ");
334 
335  /* Identify the flat files */
336  nb_frame_gain = cpl_frameset_get_size (flat_frameset);
337  raw_data = cpl_calloc (nb_frame_gain, sizeof(gravi_data *));
338 
339  /* Build the list of FLAT files and output file name */
340  for (int i = 0; i < nb_frame_gain; i++) {
341  frame = cpl_frameset_get_position (flat_frameset, i);
342  raw_data[i] = gravi_data_load_rawframe (frame, used_frameset);
343  /* Don't cleanup, since the bias-pixels maybe illuminated */
344  // gravi_data_detector_cleanup (raw_data[i], parlist);
345  }
346 
347  /*
348  * (2) Compute the BADPIX from the DARK and FLATs
349  */
350 
351  cpl_msg_info (cpl_func, " ***** Compute BAD pixel map ***** ");
352  badpix_map = gravi_compute_badpix (dark_map, raw_data,
353  nb_frame_gain, parlist);
354 
355  CPLCHECK_CLEAN("Cannot compute the BAD pixel from DARK and FLATs");
356 
357  /* Free the list of files */
358  FREELOOP (gravi_data_delete, raw_data, nb_frame_gain);
359 
360  /* Save the BAD */
361  frame = cpl_frameset_get_position (dark_frameset, 0);
362  gravi_data_save_new (badpix_map, frameset, NULL, NULL, parlist,
363  NULL, frame, "gravity_badpix",
364  NULL, GRAVI_BAD_MAP);
365 
366  CPLCHECK_CLEAN ("Could not save the BAD pixel map");
367 
368  /* Deallocation of all variables */
369  cleanup:
370  cpl_msg_info (cpl_func,"Cleanup memory");
371 
372  FREE (cpl_frameset_delete, dark_frameset);
373  FREE (gravi_data_delete, dark_map);
374  FREELOOP (gravi_data_delete, raw_data, nb_frame_gain);
375  FREE (gravi_data_delete, badpix_map);
376  FREE (cpl_frameset_delete, flat_frameset);
377  FREE (cpl_frameset_delete, used_frameset);
378  FREE (gravi_data_delete, data);
379 
380  /* FIXME: check a *change* of cpl_state instead */
381  CPLCHECK_INT ("Could not cleanup memory");
382 
383  gravi_msg_function_exit(1);
384  return (int)cpl_error_get_code();
385 }
386 
387 
cpl_parameter * gravi_parameter_add_badpix(cpl_parameterlist *self)
Add badpix parameters to the input parameter list.
Definition: gravi_dfs.c:187
cpl_frameset * gravi_frameset_extract_dark_data(cpl_frameset *frameset)
Extract DARK_RAW frame from the input frameset.
Definition: gravi_dfs.c:913
gravi_data * gravi_data_load_rawframe(cpl_frame *frame, cpl_frameset *used_frameset)
Load a RAW FITS file and create a gravi_data.
Definition: gravi_data.c:690
cpl_error_code gravi_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: gravi_dfs.c:78
const char * gravi_get_license(void)
Get the pipeline copyright and license.
Definition: gravi_utils.c:104
cpl_error_code gravi_data_save_new(gravi_data *self, cpl_frameset *allframes, const char *filename, const char *suffix, const cpl_parameterlist *parlist, cpl_frameset *usedframes, cpl_frame *frame, const char *recipe, cpl_propertylist *applist, const char *proCatg)
Save a gravi data in a CPL-complian FITS file.
Definition: gravi_data.c:896
gravi_data * gravi_compute_badpix(gravi_data *dark_map, gravi_data **flats_data, int nflat, const cpl_parameterlist *params)
Identify the bad pixels in the DARK map and create the BAD map.
Definition: gravi_calib.c:1760
void gravi_data_delete(gravi_data *self)
Delete a gravi data.
Definition: gravi_data.c:137
gravi_data * gravi_compute_dark(gravi_data *raw_data)
Compute the DARK calibration map.
Definition: gravi_calib.c:122