GRAVI Pipeline Reference Manual  0.9.10
gravity_wavelamp.c
1 /* $Id: gravity_wavelamp.c,v 1.29 2015/01/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: 2015/01/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_data.h"
42 #include "gravi_pfits.h"
43 #include "gravi_dfs.h"
44 
45 #include "gravi_utils.h"
46 
47 #include "gravi_calib.h"
48 #include "gravi_wave.h"
49 #include "gravi_preproc.h"
50 #include "gravi_disp.h"
51 
52 /*-----------------------------------------------------------------------------
53  Private function prototypes
54  -----------------------------------------------------------------------------*/
55 
56 static int gravity_wavelamp_create(cpl_plugin *);
57 static int gravity_wavelamp_exec(cpl_plugin *);
58 static int gravity_wavelamp_destroy(cpl_plugin *);
59 static int gravity_wavelamp(cpl_frameset *, const cpl_parameterlist *);
60 
61 /*-----------------------------------------------------------------------------
62  Static variables
63  -----------------------------------------------------------------------------*/
64 
65 static char gravity_wavelamp_short[] = "Measure the position of the Argon lines in the spectra.";
66 static char gravity_wavelamp_description[] =
67 "This recipe is associated to the template gravity_wavelamp.\n"
68 "It reduce the raw argon file (WAVELAMP) and process it.\n"
69  GRAVI_RECIPE_INPUT"\n"
70  GRAVI_FLAT_MAP" : flat calibration (PRO.CATG="GRAVI_FLAT_MAP")\n"
71  GRAVI_BAD_MAP" : badpixel calibration (PRO.CATG="GRAVI_BAD_MAP") \n"
72  GRAVI_WAVE_MAP" : wave calibration (PRO.CATG="GRAVI_WAVE_MAP")\n"
73  GRAVI_P2VM_MAP" : p2vm calibration (PRO.CATG="GRAVI_P2VM_MAP")\n"
74  GRAVI_WAVELAMP_RAW" : long exposure of Argon lamp\n"
75  GRAVI_DARK_RAW" : dark of Argon exposure\n"
76  GRAVI_RECIPE_OUTPUT"\n"
77  GRAVI_WAVELAMP_MAP" : spectrum of Argon, with position of lines\n"
78  "";
79 
80 /*-----------------------------------------------------------------------------
81  Function code
82  -----------------------------------------------------------------------------*/
83 
84 /*----------------------------------------------------------------------------*/
94 /*----------------------------------------------------------------------------*/
95 int cpl_plugin_get_info(cpl_pluginlist * list)
96 {
97  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
98  cpl_plugin * plugin = &recipe->interface;
99 
100  if (cpl_plugin_init(plugin,
101  CPL_PLUGIN_API,
102  GRAVI_BINARY_VERSION,
103  CPL_PLUGIN_TYPE_RECIPE,
104  "gravity_wavelamp",
105  gravity_wavelamp_short,
106  gravity_wavelamp_description,
107  "Nabih Azouaoui, Vincent Lapeyrere, JB. Le Bouquin",
108  PACKAGE_BUGREPORT,
109  gravi_get_license(),
110  gravity_wavelamp_create,
111  gravity_wavelamp_exec,
112  gravity_wavelamp_destroy)) {
113  cpl_msg_error(cpl_func, "Plugin initialization failed");
114  (void)cpl_error_set_where(cpl_func);
115  return 1;
116  }
117 
118  if (cpl_pluginlist_append(list, plugin)) {
119  cpl_msg_error(cpl_func, "Error adding plugin to list");
120  (void)cpl_error_set_where(cpl_func);
121  return 1;
122  }
123 
124  return 0;
125 }
126 
127 /*----------------------------------------------------------------------------*/
135 /*----------------------------------------------------------------------------*/
136 static int gravity_wavelamp_create(cpl_plugin * plugin)
137 {
138  cpl_recipe * recipe;
139 
140  /* Do not create the recipe if an error code is already set */
141  if (cpl_error_get_code() != CPL_ERROR_NONE) {
142  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
143  cpl_func, __LINE__, cpl_error_get_where());
144  return (int)cpl_error_get_code();
145  }
146 
147  if (plugin == NULL) {
148  cpl_msg_error(cpl_func, "Null plugin");
149  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
150  }
151 
152  /* Verify plugin type */
153  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
154  cpl_msg_error(cpl_func, "Plugin is not a recipe");
155  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
156  }
157 
158  /* Get the recipe */
159  recipe = (cpl_recipe *)plugin;
160 
161  /* Create the parameters list in the cpl_recipe object */
162  recipe->parameters = cpl_parameterlist_new();
163  if (recipe->parameters == NULL) {
164  cpl_msg_error(cpl_func, "Parameter list allocation failed");
165  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
166  }
167 
168  /* Fill the parameters list */
169  gravi_parameter_add_static_name (recipe->parameters);
170 
171  return 0;
172 }
173 
174 /*----------------------------------------------------------------------------*/
180 /*----------------------------------------------------------------------------*/
181 static int gravity_wavelamp_exec(cpl_plugin * plugin)
182 {
183 
184  cpl_recipe * recipe;
185  int recipe_status;
186  cpl_errorstate initial_errorstate = cpl_errorstate_get();
187 
188  /* Return immediately if an error code is already set */
189  if (cpl_error_get_code() != CPL_ERROR_NONE) {
190  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
191  cpl_func, __LINE__, cpl_error_get_where());
192  return (int)cpl_error_get_code();
193  }
194 
195  if (plugin == NULL) {
196  cpl_msg_error(cpl_func, "Null plugin");
197  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
198  }
199 
200  /* Verify plugin type */
201  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
202  cpl_msg_error(cpl_func, "Plugin is not a recipe");
203  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
204  }
205 
206  /* Get the recipe */
207  recipe = (cpl_recipe *)plugin;
208 
209  /* Verify parameter and frame lists */
210  if (recipe->parameters == NULL) {
211  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
212  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
213  }
214  if (recipe->frames == NULL) {
215  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
216  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
217  }
218 
219  /* Invoke the recipe */
220  recipe_status = gravity_wavelamp(recipe->frames, recipe->parameters);
221 
222  /* Ensure DFS-compliance of the products */
223 
224  if (cpl_dfs_update_product_header(recipe->frames)) {
225  if (!recipe_status){
226  recipe_status = (int)cpl_error_get_code();
227  }
228  }
229 
230  if (!cpl_errorstate_is_equal(initial_errorstate)) {
231  /* Dump the error history since recipe execution start.
232  At this point the recipe cannot recover from the error */
233  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
234  }
235 
236  return recipe_status;
237 }
238 
239 /*----------------------------------------------------------------------------*/
245 /*----------------------------------------------------------------------------*/
246 static int gravity_wavelamp_destroy(cpl_plugin * plugin)
247 {
248  cpl_recipe * recipe;
249 
250  if (plugin == NULL) {
251  cpl_msg_error(cpl_func, "Null plugin");
252  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
253  }
254 
255  /* Verify plugin type */
256  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
257  cpl_msg_error(cpl_func, "Plugin is not a recipe");
258  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
259  }
260 
261  /* Get the recipe */
262  recipe = (cpl_recipe *)plugin;
263 
264  cpl_parameterlist_delete(recipe->parameters);
265 
266  return 0;
267 }
268 
269 
270 /*----------------------------------------------------------------------------*/
278 /*----------------------------------------------------------------------------*/
279 static int gravity_wavelamp(cpl_frameset * frameset,
280  const cpl_parameterlist * parlist)
281 {
282  cpl_frameset * wavecalib_frameset = NULL,
283  * badcalib_frameset = NULL, * flatcalib_frameset = NULL,
284  * p2vmcalib_frameset = NULL, * dark_frameset = NULL,
285  * wavelamp_frameset = NULL, * used_frameset = NULL,
286  * darkcalib_frameset = NULL;
287 
288  cpl_frame * frame;
289 
290  gravi_data * data = NULL, * dark_map = NULL, * wave_map = NULL,
291  * profile_map = NULL, * badpix_map = NULL, * preproc_data = NULL, * p2vm_map = NULL;
292 
293  /* Message */
294  gravity_print_banner ();
295  cpl_msg_set_time_on();
296  cpl_msg_set_component_on();
297  gravi_msg_function_start(1);
298 
299  cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
300  cpl_error_get_code()) ;
301 
302  /* Identify the input framesets */
303  wavelamp_frameset = gravi_frameset_extract_wavelamp_data (frameset);
304  dark_frameset = gravi_frameset_extract_dark_data (frameset);
305  darkcalib_frameset = gravi_frameset_extract_dark_map (frameset);
306  p2vmcalib_frameset = gravi_frameset_extract_p2vm_map (frameset);
307  wavecalib_frameset = gravi_frameset_extract_wave_map (frameset);
308  flatcalib_frameset = gravi_frameset_extract_flat_map (frameset);
309  badcalib_frameset = gravi_frameset_extract_bad_map (frameset);
310 
311  /* Check input framesets */
312  if ( (cpl_frameset_is_empty (dark_frameset) &&
313  cpl_frameset_is_empty (darkcalib_frameset)) ||
314  cpl_frameset_is_empty (wavelamp_frameset) ||
315  cpl_frameset_is_empty (p2vmcalib_frameset) ||
316  cpl_frameset_is_empty (wavecalib_frameset) ||
317  cpl_frameset_is_empty (flatcalib_frameset) ||
318  cpl_frameset_is_empty (badcalib_frameset) ) {
319 
320  cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
321  "Mising DARK, WAVELAMP, P2VM, WAVE, FLAT or BAD") ;
322  goto cleanup;
323  }
324 
325  /* Insert calibration frame into the used frameset */
326  used_frameset = cpl_frameset_new();
327 
328  /*
329  * Identify the DARK in the input frameset
330  */
331 
332  if (!cpl_frameset_is_empty (dark_frameset)) {
333 
334  frame = cpl_frameset_get_position (dark_frameset, 0);
335  data = gravi_data_load_rawframe (frame, used_frameset);
336  gravi_data_detector_cleanup (data, parlist);
337 
338  /* Compute dark */
339  dark_map = gravi_compute_dark (data);
340  FREE (gravi_data_delete, data);
341 
342  CPLCHECK_CLEAN ("Could not compute the DARK map");
343 
344  /* Save the dark map */
345  gravi_data_save_new (dark_map, frameset, NULL, parlist,
346  NULL, frame, "gravity_wavelamp",
347  NULL, GRAVI_DARK_MAP);
348 
349  CPLCHECK_CLEAN ("Could not save the DARK map");
350  }
351  else if (!cpl_frameset_is_empty (darkcalib_frameset)) {
352 
353  frame = cpl_frameset_get_position (darkcalib_frameset, 0);
354  dark_map = gravi_data_load_frame (frame, used_frameset);
355 
356  CPLCHECK_CLEAN ("Could not load the DARK map");
357  }
358  else
359  cpl_msg_info (cpl_func, "There is no DARK in the frame set");
360 
361 
362  /* Identify the BAD in the input frameset */
363  frame = cpl_frameset_get_position (badcalib_frameset, 0);
364  badpix_map = gravi_data_load_frame (frame, used_frameset);
365 
366  /* Identify the FLAT in the input frameset */
367  frame = cpl_frameset_get_position (flatcalib_frameset, 0);
368  profile_map = gravi_data_load_frame (frame, used_frameset);
369 
370  /* Identify the WAVE in the input frameset */
371  frame = cpl_frameset_get_position (wavecalib_frameset, 0);
372  wave_map = gravi_data_load_frame (frame, used_frameset);
373 
374  /* Identify the P2VM in the input frameset */
375  frame = cpl_frameset_get_position (p2vmcalib_frameset, 0);
376  p2vm_map = gravi_data_load_frame (frame, used_frameset);
377 
378  CPLCHECK_CLEAN ("Error while loading the calibration map");
379 
380 
381  /*
382  * Load input WAVELAMP_RAW
383  */
384  frame = cpl_frameset_get_position (wavelamp_frameset, 0);
385  data = gravi_data_load_rawframe (frame, used_frameset);
386  gravi_data_detector_cleanup (data, parlist);
387 
388  /* Create output data (FIXME: probably not necessary) */
389  gravi_data * argon_data = gravi_data_new (0);
390  cpl_propertylist * argon_header = gravi_data_get_header (argon_data);
391  cpl_propertylist_append (argon_header, gravi_data_get_header (data));
392 
393  /* Copy the IMAGING_DATA and IMAGING_DETECTOR extensions */
394  gravi_data_copy_ext (argon_data, data, GRAVI_IMAGING_DETECTOR_SC_EXT);
395  gravi_data_copy_ext (argon_data, data, GRAVI_IMAGING_DATA_SC_EXT);
396 
397  FREE (gravi_data_delete, data);
398 
399  /* Collapse ARGON */
400  cpl_imagelist * imglist = gravi_data_get_cube (argon_data, GRAVI_IMAGING_DATA_SC_EXT);
401  cpl_image * img_median = cpl_imagelist_collapse_median_create (imglist);
402 
403  /* Replace data in-place */
404  cpl_imagelist_empty (imglist);
405  cpl_imagelist_set (imglist, img_median, 0);
406 
407  /* Extract spectrum */
408  preproc_data = gravi_extract_spectrum (argon_data, profile_map, dark_map,
409  badpix_map, NULL, parlist);
410  FREE (gravi_data_delete, argon_data);
411  CPLCHECK_CLEAN ("Cannot extract spectrum");
412 
413  /* Compute the ARGON WAVE */
414  //cpl_table * spectrum_table, * argonwave_table;
415  //spectrum_table = gravi_data_get_spectrum_data (preproc_data, GRAVI_SC);
416  //argonwave_table = gravi_compute_argon_wave (spectrum_table);
417  //gravi_data_add_table (preproc_data, NULL, "WAVE_ARGON_RAW", argonwave_table);
418 
419  /* Rescale to common wavelength */
420  gravi_align_spectrum (preproc_data, wave_map, p2vm_map);
421  CPLCHECK_CLEAN ("Cannot re-interpolate spectrum");
422 
423  /* Compute the ARGON WAVE */
424  //spectrum_table = gravi_data_get_spectrum_data (preproc_data, GRAVI_SC);
425  //argonwave_table = gravi_compute_argon_wave (spectrum_table);
426  //gravi_data_add_table (preproc_data, NULL, "WAVE_ARGON_RESAMP", argonwave_table);
427 
428  /* Compute position */
429  gravi_compute_argon_pos (preproc_data);
430 
431  CPLCHECK_CLEAN ("Cannot compute the positions");
432 
433  /* Save the output data file */
434  gravi_data_save_new (preproc_data, frameset, NULL, parlist,
435  used_frameset, frame, "gravity_wavelamp",
436  NULL, GRAVI_WAVELAMP_MAP);
437 
438  CPLCHECK_CLEAN("Could not save the WAVELAMP");
439 
440  /* Deallocation of all variables */
441  goto cleanup;
442 
443 cleanup :
444  cpl_msg_info(cpl_func,"Memory cleanup");
445  FREE (cpl_frameset_delete, wavelamp_frameset);
446  FREE (cpl_frameset_delete, wavecalib_frameset);
447  FREE (cpl_frameset_delete, badcalib_frameset);
448  FREE (cpl_frameset_delete, flatcalib_frameset);
449  FREE (cpl_frameset_delete, p2vmcalib_frameset);
450  FREE (cpl_frameset_delete, used_frameset);
451  FREE (cpl_frameset_delete, dark_frameset);
452  FREE (cpl_frameset_delete, darkcalib_frameset);
453  FREE (gravi_data_delete, dark_map);
454  FREE (gravi_data_delete, wave_map);
455  FREE (gravi_data_delete, profile_map);
456  FREE (gravi_data_delete, badpix_map);
457  FREE (gravi_data_delete, p2vm_map);
458  FREE (gravi_data_delete, preproc_data);
459 
460  gravi_msg_function_exit(1);
461  return (int)cpl_error_get_code();
462 }
463 
464