GRAVI Pipeline Reference Manual  1.2.3
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, the FT and the ACQ detectors. The SC detector is first debiased using the biaspixels, before computing the dark mean and rms. For detectors, the mean dark level of each pixel and the stdev of each pixel are saved in the output product.\n"
64  GRAVI_RECIPE_FLOW"\n"
65  "* Loop on input dark files and concatenate them\n"
66  "* Compute the median and rms of these concatenated files\n"
67  "* Save the product (FT, SC, ACQ camera into same product)\n"
68  GRAVI_RECIPE_INPUT"\n"
69  GRAVI_DARK_RAW" : raw dark, all shutters closed (DPR.TYPE=DARK)\n"
70  GRAVI_RECIPE_OUTPUT"\n"
71  GRAVI_DARK_MAP" : dark calibration\n"
72  "";
73 
74 /*-----------------------------------------------------------------------------
75  Function code
76  -----------------------------------------------------------------------------*/
77 
78 /*----------------------------------------------------------------------------*/
88 /*----------------------------------------------------------------------------*/
89 int cpl_plugin_get_info(cpl_pluginlist * list)
90 {
91  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
92  cpl_plugin * plugin = &recipe->interface;
93 
94  if (cpl_plugin_init(plugin,
95  CPL_PLUGIN_API,
96  GRAVI_BINARY_VERSION,
97  CPL_PLUGIN_TYPE_RECIPE,
98  "gravity_dark",
99  gravity_dark_short,
100  gravity_dark_description,
101  "Nabih Azouaoui, Vincent Lapeyrere, JB. Le Bouquin",
102  PACKAGE_BUGREPORT,
104  gravity_dark_create,
105  gravity_dark_exec,
106  gravity_dark_destroy)) {
107  cpl_msg_error(cpl_func, "Plugin initialization failed");
108  (void)cpl_error_set_where(cpl_func);
109  return 1;
110  }
111 
112  if (cpl_pluginlist_append(list, plugin)) {
113  cpl_msg_error(cpl_func, "Error adding plugin to list");
114  (void)cpl_error_set_where(cpl_func);
115  return 1;
116  }
117 
118  return 0;
119 }
120 
121 /*----------------------------------------------------------------------------*/
129 /*----------------------------------------------------------------------------*/
130 static int gravity_dark_create(cpl_plugin * plugin)
131 {
132  cpl_recipe * recipe;
133  // cpl_parameter * p;
134 
135  /* Do not create the recipe if an error code is already set */
136  if (cpl_error_get_code() != CPL_ERROR_NONE) {
137  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
138  cpl_func, __LINE__, cpl_error_get_where());
139  return (int)cpl_error_get_code();
140  }
141 
142  if (plugin == NULL) {
143  cpl_msg_error(cpl_func, "Null plugin");
144  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
145  }
146 
147  /* Verify plugin type */
148  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
149  cpl_msg_error(cpl_func, "Plugin is not a recipe");
150  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
151  }
152 
153  /* Get the recipe */
154  recipe = (cpl_recipe *)plugin;
155 
156  /* Create the parameters list in the cpl_recipe object */
157  recipe->parameters = cpl_parameterlist_new();
158  if (recipe->parameters == NULL) {
159  cpl_msg_error(cpl_func, "Parameter list allocation failed");
160  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
161  }
162 
163  /* Use static names (output_procatg.fits) */
164  gravi_parameter_add_static_name (recipe->parameters);
165 
166  /* Bias-method */
167  gravi_parameter_add_biasmethod (recipe->parameters);
168 
169  return 0;
170 }
171 
172 /*----------------------------------------------------------------------------*/
178 /*----------------------------------------------------------------------------*/
179 static int gravity_dark_exec(cpl_plugin * plugin)
180 {
181 
182  cpl_recipe * recipe;
183  int recipe_status;
184  cpl_errorstate initial_errorstate = cpl_errorstate_get();
185 
186  /* Return immediately if an error code is already set */
187  if (cpl_error_get_code() != CPL_ERROR_NONE) {
188  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
189  cpl_func, __LINE__, cpl_error_get_where());
190  return (int)cpl_error_get_code();
191  }
192 
193  if (plugin == NULL) {
194  cpl_msg_error(cpl_func, "Null plugin");
195  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
196  }
197 
198  /* Verify plugin type */
199  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
200  cpl_msg_error(cpl_func, "Plugin is not a recipe");
201  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
202  }
203 
204  /* Get the recipe */
205  recipe = (cpl_recipe *)plugin;
206 
207  /* Verify parameter and frame lists */
208  if (recipe->parameters == NULL) {
209  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
210  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
211  }
212  if (recipe->frames == NULL) {
213  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
214  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
215  }
216 
217  /* Invoke the recipe */
218  recipe_status = gravity_dark(recipe->frames, recipe->parameters);
219 
220  /* Ensure DFS-compliance of the products */
221  if (cpl_dfs_update_product_header(recipe->frames)) {
222  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
223  }
224 
225  if (!cpl_errorstate_is_equal(initial_errorstate)) {
226  /* Dump the error history since recipe execution start.
227  At this point the recipe cannot recover from the error */
228  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
229  }
230 
231  return recipe_status;
232 }
233 
234 /*----------------------------------------------------------------------------*/
240 /*----------------------------------------------------------------------------*/
241 static int gravity_dark_destroy(cpl_plugin * plugin)
242 {
243  cpl_recipe * recipe;
244 
245  if (plugin == NULL) {
246  cpl_msg_error(cpl_func, "Null plugin");
247  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
248  }
249 
250  /* Verify plugin type */
251  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
252  cpl_msg_error(cpl_func, "Plugin is not a recipe");
253  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
254  }
255 
256  /* Get the recipe */
257  recipe = (cpl_recipe *)plugin;
258 
259  cpl_parameterlist_delete(recipe->parameters);
260 
261  return 0;
262 }
263 
264 
265 /*----------------------------------------------------------------------------*/
272 /*----------------------------------------------------------------------------*/
273 static int gravity_dark (cpl_frameset * frameset,
274  const cpl_parameterlist * parlist)
275 {
276  cpl_frameset * dark_frameset = NULL, * used_frameset = NULL;
277  cpl_frame * frame = NULL;
278  gravi_data * raw_dark = NULL, * reduced_dark = NULL;
279  int comp, nb_frame;
280 
281 
282  /* Message */
283  gravity_print_banner ();
284  cpl_msg_set_time_on();
285  cpl_msg_set_component_on();
286  gravi_msg_function_start(1);
287 
288  /* Identify the RAW and CALIB frames in the input frameset */
289  cpl_ensure_code (gravi_dfs_set_groups (frameset) == CPL_ERROR_NONE, cpl_error_get_code());
290 
291  /* Dispatch the framesets */
292  dark_frameset = gravi_frameset_extract_dark_data (frameset);
293 
294  /* Check the frameset */
295  if (cpl_frameset_is_empty (dark_frameset)) {
296  cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
297  "No DARK_RAW file on the frameset") ;
298  goto cleanup;
299  }
300 
301  /* Load all DARK in the frameset into a single data */
302  nb_frame = cpl_frameset_get_size (dark_frameset);
303  used_frameset = cpl_frameset_new ();
304 
305  for (comp = 0; comp < nb_frame; comp++){
306  gravi_data * data_tmp;
307  cpl_frame * frame_tmp;
308 
309  /* Load this frame */
310  frame_tmp = cpl_frameset_get_position (dark_frameset, comp);
311  data_tmp = gravi_data_load_rawframe (frame_tmp, used_frameset);
312  gravi_data_detector_cleanup (data_tmp, parlist);
313 
314  /* Cleanup unused data */
315  //gravi_data_erase (data_tmp, GRAVI_METROLOGY_EXT);
316  gravi_data_erase (data_tmp, GRAVI_OPDC_EXT);
317  gravi_data_erase (data_tmp, GRAVI_FDDL_EXT);
318 
319  /* FIXME: shall remove the FT except for the first one */
320 
321  if (comp == 0) {
322  /* Use the first frame for merging */
323  frame = frame_tmp;
324  raw_dark = data_tmp; data_tmp = NULL;
325  }
326  else {
327  /* Merge to first frame */
328  /* FIX ME: does not use multiple DARK for metrology Volts */
329  int force = 0;
330  gravi_data_append (raw_dark, data_tmp, force);
331  FREE (gravi_data_delete, data_tmp);
332  }
333 
334  CPLCHECK_CLEAN ("Cannot load all DARK into a single data");
335  }
336 
337 
338  /* Compute the reduced DARK */
339  reduced_dark = gravi_compute_dark (raw_dark);
340  FREE (gravi_data_delete, raw_dark);
341 
342  CPLCHECK_CLEAN ("Could not compute the DARK map");
343 
344  /* Create product frame */
345  gravi_data_save_new (reduced_dark, frameset, NULL, NULL, parlist,
346  used_frameset, frame, "gravity_dark",
347  NULL, GRAVI_DARK_MAP);
348 
349  CPLCHECK_CLEAN ("Could not save the DARK map");
350 
351  /* Terminate the function */
352  goto cleanup;
353 
354 cleanup:
355  /* Deallocation of all variables */
356  cpl_msg_info (cpl_func,"Memory cleanup");
357 
358  FREE (gravi_data_delete, reduced_dark);
359  FREE (gravi_data_delete, raw_dark);
360  FREE (cpl_frameset_delete, dark_frameset);
361  FREE (cpl_frameset_delete, used_frameset);
362 
363  gravi_msg_function_exit(1);
364  return (int)cpl_error_get_code();
365 }
366 
367 
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_detector_cleanup(gravi_data *data, const cpl_parameterlist *parlist)
Perform self-bias correction to the SC raw data.
Definition: gravi_data.c:1086
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
void gravi_data_delete(gravi_data *self)
Delete a gravi data.
Definition: gravi_data.c:137
cpl_error_code gravi_data_erase(gravi_data *self, const char *extname)
Erase an extension by its EXTNAME.
Definition: gravi_data.c:1832
cpl_error_code gravi_data_append(gravi_data *first, const gravi_data *second, int force)
Append a gravi_data into another existing one.
Definition: gravi_data.c:290
gravi_data * gravi_compute_dark(gravi_data *raw_data)
Compute the DARK calibration map.
Definition: gravi_calib.c:122