GRAVI Pipeline Reference Manual  0.9.10
gravity_dark.c
1 /* $Id: gravity_dark.c,v 1.29 2011/03/10 09:16:12 nazouaoui 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 /*
22  * $Author: nazouaoui $
23  * $Date: 2011/03/10 09:16:12 $
24  * $Revision: 1.29 $
25  * $Name: $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include <cpl.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <time.h>
40 
41 #include "gravi_utils.h"
42 #include "gravi_pfits.h"
43 #include "gravi_dfs.h"
44 #include "gravi_calib.h"
45 
46 #include "gravi_data.h"
47 
48 /*-----------------------------------------------------------------------------
49  Private function prototypes
50  -----------------------------------------------------------------------------*/
51 
52 static int gravity_dark_create(cpl_plugin *);
53 static int gravity_dark_exec(cpl_plugin *);
54 static int gravity_dark_destroy(cpl_plugin *);
55 static int gravity_dark(cpl_frameset *, const cpl_parameterlist *);
56 
57 /*-----------------------------------------------------------------------------
58  Static variables
59  -----------------------------------------------------------------------------*/
60 
61 static char gravity_dark_short[] = "Calibrate the detector noise and background level.";
62 static char gravity_dark_description[] =
63  "This recipe computes the DARK calibration for the SC and the FT detector. The SC detector is first debias using the biaspixels, before computing the dark mean and rms. For both detector, the mean dark level of each pixel and the stdev of each pixel are saved in the output product.\n"
64  GRAVI_RECIPE_INPUT"\n"
65  GRAVI_DARK_RAW" : raw dark, all shutters closed (DPR.TYPE=DARK)\n"
66  GRAVI_RECIPE_OUTPUT"\n"
67  GRAVI_DARK_MAP" : dark calibration\n"
68  "";
69 
70 /*-----------------------------------------------------------------------------
71  Function code
72  -----------------------------------------------------------------------------*/
73 
74 /*----------------------------------------------------------------------------*/
84 /*----------------------------------------------------------------------------*/
85 int cpl_plugin_get_info(cpl_pluginlist * list)
86 {
87  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
88  cpl_plugin * plugin = &recipe->interface;
89 
90  if (cpl_plugin_init(plugin,
91  CPL_PLUGIN_API,
92  GRAVI_BINARY_VERSION,
93  CPL_PLUGIN_TYPE_RECIPE,
94  "gravity_dark",
95  gravity_dark_short,
96  gravity_dark_description,
97  "Nabih Azouaoui, Vincent Lapeyrere, JB. Le Bouquin",
98  PACKAGE_BUGREPORT,
99  gravi_get_license(),
100  gravity_dark_create,
101  gravity_dark_exec,
102  gravity_dark_destroy)) {
103  cpl_msg_error(cpl_func, "Plugin initialization failed");
104  (void)cpl_error_set_where(cpl_func);
105  return 1;
106  }
107 
108  if (cpl_pluginlist_append(list, plugin)) {
109  cpl_msg_error(cpl_func, "Error adding plugin to list");
110  (void)cpl_error_set_where(cpl_func);
111  return 1;
112  }
113 
114  return 0;
115 }
116 
117 /*----------------------------------------------------------------------------*/
125 /*----------------------------------------------------------------------------*/
126 static int gravity_dark_create(cpl_plugin * plugin)
127 {
128  cpl_recipe * recipe;
129  // cpl_parameter * p;
130 
131  /* Do not create the recipe if an error code is already set */
132  if (cpl_error_get_code() != CPL_ERROR_NONE) {
133  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
134  cpl_func, __LINE__, cpl_error_get_where());
135  return (int)cpl_error_get_code();
136  }
137 
138  if (plugin == NULL) {
139  cpl_msg_error(cpl_func, "Null plugin");
140  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
141  }
142 
143  /* Verify plugin type */
144  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
145  cpl_msg_error(cpl_func, "Plugin is not a recipe");
146  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
147  }
148 
149  /* Get the recipe */
150  recipe = (cpl_recipe *)plugin;
151 
152  /* Create the parameters list in the cpl_recipe object */
153  recipe->parameters = cpl_parameterlist_new();
154  if (recipe->parameters == NULL) {
155  cpl_msg_error(cpl_func, "Parameter list allocation failed");
156  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
157  }
158 
159  /* Use static names (output_procatg.fits) */
160  gravi_parameter_add_static_name (recipe->parameters);
161 
162  /* Bias-method */
163  gravi_parameter_add_biasmethod (recipe->parameters);
164 
165  return 0;
166 }
167 
168 /*----------------------------------------------------------------------------*/
174 /*----------------------------------------------------------------------------*/
175 static int gravity_dark_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_dark(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_dark_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 
261 /*----------------------------------------------------------------------------*/
268 /*----------------------------------------------------------------------------*/
269 static int gravity_dark (cpl_frameset * frameset,
270  const cpl_parameterlist * parlist)
271 {
272  cpl_frameset * dark_frameset = NULL, * used_frameset = NULL;
273  cpl_frame * frame = NULL;
274  gravi_data * raw_dark = NULL, * reduced_dark = NULL;
275  int comp, nb_frame;
276 
277 
278  /* Message */
279  gravity_print_banner ();
280  cpl_msg_set_time_on();
281  cpl_msg_set_component_on();
282  gravi_msg_function_start(1);
283 
284  /* Identify the RAW and CALIB frames in the input frameset */
285  cpl_ensure_code (gravi_dfs_set_groups (frameset) == CPL_ERROR_NONE, cpl_error_get_code());
286 
287  /* Dispatch the framesets */
288  dark_frameset = gravi_frameset_extract_dark_data (frameset);
289 
290  /* Check the frameset */
291  if (cpl_frameset_is_empty (dark_frameset)) {
292  cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
293  "No DARK_RAW file on the frameset") ;
294  goto cleanup;
295  }
296 
297  /* Load all DARK in the frameset into a single data */
298  nb_frame = cpl_frameset_get_size (dark_frameset);
299  used_frameset = cpl_frameset_new ();
300 
301  for (comp = 0; comp < nb_frame; comp++){
302  gravi_data * data_tmp;
303  cpl_frame * frame_tmp;
304 
305  /* Load this frame */
306  frame_tmp = cpl_frameset_get_position (dark_frameset, comp);
307  data_tmp = gravi_data_load_rawframe (frame_tmp, used_frameset);
308  gravi_data_detector_cleanup (data_tmp, parlist);
309 
310  /* Cleanup unused data */
311  gravi_data_erase (data_tmp, GRAVI_METROLOGY_EXT);
312  gravi_data_erase (data_tmp, GRAVI_OPDC_EXT);
313  gravi_data_erase (data_tmp, GRAVI_FDDL_EXT);
314 
315  /* FIXME: shall remove the FT except for the first one */
316 
317  if (comp == 0) {
318  /* Use the first frame for merging */
319  frame = frame_tmp;
320  raw_dark = data_tmp; data_tmp = NULL;
321  }
322  else {
323  /* Merge to first frame */
324  int force = 0;
325  gravi_data_append (raw_dark, data_tmp, force);
326  FREE (gravi_data_delete, data_tmp);
327  }
328 
329  CPLCHECK_CLEAN ("Cannot load all DARK into a single data");
330  }
331 
332 
333 
334  /* Compute the reduced DARK */
335  reduced_dark = gravi_compute_dark (raw_dark);
336  FREE (gravi_data_delete, raw_dark);
337 
338  CPLCHECK_CLEAN ("Could not compute the DARK map");
339 
340  /* Create product frame */
341  gravi_data_save_new (reduced_dark, frameset, NULL, parlist,
342  used_frameset, frame, "gravity_dark",
343  NULL, GRAVI_DARK_MAP);
344 
345  CPLCHECK_CLEAN ("Could not save the DARK map");
346 
347  /* Terminate the function */
348  goto cleanup;
349 
350 cleanup:
351  /* Deallocation of all variables */
352  cpl_msg_info (cpl_func,"Memory cleanup");
353 
354  FREE (gravi_data_delete, reduced_dark);
355  FREE (gravi_data_delete, raw_dark);
356  FREE (cpl_frameset_delete, dark_frameset);
357  FREE (cpl_frameset_delete, used_frameset);
358 
359  gravi_msg_function_exit(1);
360  return (int)cpl_error_get_code();
361 }
362 
363