GRAVI Pipeline Reference Manual  0.9.7
gravity_disp.c
1 /* $Id: gravity_disp.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_preproc.h"
49 #include "gravi_p2vmred.h"
50 #include "gravi_signal.h"
51 #include "gravi_vis.h"
52 #include "gravi_metrology.h"
53 #include "gravi_disp.h"
54 
55 
56 
57 
58 
59 /*-----------------------------------------------------------------------------
60  Private function prototypes
61  -----------------------------------------------------------------------------*/
62 
63 static int gravity_disp_create(cpl_plugin *);
64 static int gravity_disp_exec(cpl_plugin *);
65 static int gravity_disp_destroy(cpl_plugin *);
66 static int gravity_disp(cpl_frameset *, const cpl_parameterlist *);
67 
68 /*-----------------------------------------------------------------------------
69  Static variables
70  -----------------------------------------------------------------------------*/
71 
72 static char gravity_disp_short[] = "Calibrate the linearity and the dispersion of the differential delay lines.";
73 static char gravity_disp_description[] =
74  "This recipe is associated to the template GRAVI_all_disp. It measure the phases obtained on the internal source at the position of the Argon lines and various stretch of the FDDL. It deduces the linearity model and the dispersion model of the differential delay lines. These models are stored as polynomials versus wavelength.\n"
75  GRAVI_RECIPE_INPUT"\n"
76  GRAVI_FLAT_MAP" : flat calibration (PRO.CATG="GRAVI_FLAT_MAP")\n"
77  GRAVI_BAD_MAP" : badpixel calibration (PRO.CATG="GRAVI_BAD_MAP") \n"
78  GRAVI_WAVE_MAP" : wave calibration (PRO.CATG="GRAVI_WAVE_MAP")\n"
79  GRAVI_P2VM_MAP" : p2vm calibration (PRO.CATG="GRAVI_P2VM_MAP")\n"
80  GRAVI_DARK_MAP" : dark calibration\n"
81  GRAVI_DISP_RAW" >10 : raw dispersion\n"
82  GRAVI_RECIPE_OUTPUT"\n"
83  GRAVI_DISP_MODEL" : dispersion model of FDDL\n"
84  "";
85 
86 /*-----------------------------------------------------------------------------
87  Function code
88  -----------------------------------------------------------------------------*/
89 
90 /*----------------------------------------------------------------------------*/
100 /*----------------------------------------------------------------------------*/
101 int cpl_plugin_get_info(cpl_pluginlist * list)
102 {
103  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
104  cpl_plugin * plugin = &recipe->interface;
105 
106  if (cpl_plugin_init(plugin,
107  CPL_PLUGIN_API,
108  GRAVI_BINARY_VERSION,
109  CPL_PLUGIN_TYPE_RECIPE,
110  "gravity_disp",
111  gravity_disp_short,
112  gravity_disp_description,
113  "Nabih Azouaoui, Vincent Lapeyrere, JB. Le Bouquin",
114  PACKAGE_BUGREPORT,
115  gravi_get_license(),
116  gravity_disp_create,
117  gravity_disp_exec,
118  gravity_disp_destroy)) {
119  cpl_msg_error(cpl_func, "Plugin initialization failed");
120  (void)cpl_error_set_where(cpl_func);
121  return 1;
122  }
123 
124  if (cpl_pluginlist_append(list, plugin)) {
125  cpl_msg_error(cpl_func, "Error adding plugin to list");
126  (void)cpl_error_set_where(cpl_func);
127  return 1;
128  }
129 
130  return 0;
131 }
132 
133 /*----------------------------------------------------------------------------*/
141 /*----------------------------------------------------------------------------*/
142 static int gravity_disp_create(cpl_plugin * plugin)
143 {
144  cpl_recipe * recipe;
145  // cpl_parameter * p;
146 
147  /* Do not create the recipe if an error code is already set */
148  if (cpl_error_get_code() != CPL_ERROR_NONE) {
149  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
150  cpl_func, __LINE__, cpl_error_get_where());
151  return (int)cpl_error_get_code();
152  }
153 
154  if (plugin == NULL) {
155  cpl_msg_error(cpl_func, "Null plugin");
156  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
157  }
158 
159  /* Verify plugin type */
160  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
161  cpl_msg_error(cpl_func, "Plugin is not a recipe");
162  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
163  }
164 
165  /* Get the recipe */
166  recipe = (cpl_recipe *)plugin;
167 
168  /* Create the parameters list in the cpl_recipe object */
169  recipe->parameters = cpl_parameterlist_new();
170  if (recipe->parameters == NULL) {
171  cpl_msg_error(cpl_func, "Parameter list allocation failed");
172  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
173  }
174 
175  /* Fill the parameters list */
176  int isCalib = 1;
177 
178  /* Use static names (output_procatg.fits) */
179  gravi_parameter_add_static_name (recipe->parameters);
180 
181  /* Intermediate files */
182  gravi_parameter_add_preproc_file (recipe->parameters);
183  gravi_parameter_add_p2vmred_file (recipe->parameters);
184  gravi_parameter_add_vis_file (recipe->parameters);
185 
186  /* Snr */
187  gravi_parameter_add_compute_snr (recipe->parameters, isCalib);
188 
189  /* Rejection */
190  gravi_parameter_add_rejection (recipe->parameters, isCalib);
191 
192  /* Parameters for gravi_compute_vis */
193  gravi_parameter_add_compute_vis (recipe->parameters, isCalib);
194 
195  return 0;
196 }
197 
198 /*----------------------------------------------------------------------------*/
204 /*----------------------------------------------------------------------------*/
205 static int gravity_disp_exec(cpl_plugin * plugin)
206 {
207 
208  cpl_recipe * recipe;
209  int recipe_status;
210  cpl_errorstate initial_errorstate = cpl_errorstate_get();
211 
212  /* Return immediately if an error code is already set */
213  if (cpl_error_get_code() != CPL_ERROR_NONE) {
214  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
215  cpl_func, __LINE__, cpl_error_get_where());
216  return (int)cpl_error_get_code();
217  }
218 
219  if (plugin == NULL) {
220  cpl_msg_error(cpl_func, "Null plugin");
221  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
222  }
223 
224  /* Verify plugin type */
225  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
226  cpl_msg_error(cpl_func, "Plugin is not a recipe");
227  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
228  }
229 
230  /* Get the recipe */
231  recipe = (cpl_recipe *)plugin;
232 
233  /* Verify parameter and frame lists */
234  if (recipe->parameters == NULL) {
235  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
236  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
237  }
238  if (recipe->frames == NULL) {
239  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
240  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
241  }
242 
243  /* Invoke the recipe */
244  recipe_status = gravity_disp(recipe->frames, recipe->parameters);
245 
246  /* Ensure DFS-compliance of the products */
247 
248  if (cpl_dfs_update_product_header(recipe->frames)) {
249  if (!recipe_status){
250  recipe_status = (int)cpl_error_get_code();
251  }
252  }
253 
254  if (!cpl_errorstate_is_equal(initial_errorstate)) {
255  /* Dump the error history since recipe execution start.
256  At this point the recipe cannot recover from the error */
257  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
258  }
259 
260  return recipe_status;
261 }
262 
263 /*----------------------------------------------------------------------------*/
269 /*----------------------------------------------------------------------------*/
270 static int gravity_disp_destroy(cpl_plugin * plugin)
271 {
272  cpl_recipe * recipe;
273 
274  if (plugin == NULL) {
275  cpl_msg_error(cpl_func, "Null plugin");
276  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
277  }
278 
279  /* Verify plugin type */
280  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
281  cpl_msg_error(cpl_func, "Plugin is not a recipe");
282  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
283  }
284 
285  /* Get the recipe */
286  recipe = (cpl_recipe *)plugin;
287 
288  cpl_parameterlist_delete(recipe->parameters);
289 
290  return 0;
291 }
292 
293 
294 /*----------------------------------------------------------------------------*/
302 /*----------------------------------------------------------------------------*/
303 static int gravity_disp(cpl_frameset * frameset,
304  const cpl_parameterlist * parlist)
305 {
306  cpl_frameset * disp_frameset=NULL, * darkcalib_frameset=NULL,
307  * dark_frameset=NULL, * wavecalib_frameset=NULL,
308  * badcalib_frameset=NULL, * flatcalib_frameset=NULL, * dispvis_frameset=NULL,
309  * p2vmcalib_frameset=NULL, * wavelampcalib_frameset=NULL, *used_frameset=NULL,
310  * current_frameset=NULL;
311 
312  cpl_frame * frame=NULL;
313 
314  gravi_data * disp_map = NULL, * data = NULL, * dark_map = NULL, * wave_map = NULL,
315  * profile_map = NULL, * badpix_map = NULL, * p2vmred_data = NULL, * preproc_data = NULL,
316  * p2vm_map = NULL, * vis_data = NULL, * tmpvis_data=NULL, * argon_data=NULL;
317 
318  int nb_frame;
319 
320  /* Message */
321  gravity_print_banner ();
322  cpl_msg_set_time_on();
323  cpl_msg_set_component_on();
324  gravi_msg_function_start(1);
325 
326 
327  /* Identify the RAW and CALIB frames in the input frameset */
328  cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
329  cpl_error_get_code()) ;
330 
331  /* Check if a DISP_VIS is already existing */
332  dispvis_frameset = gravi_frameset_extract_dispvis_data (frameset);
333 
334  /* Insert calibration frame into the used frameset */
335  used_frameset = cpl_frameset_new();
336 
337  /* No DISP_VIS, reduce all data */
338  if (cpl_frameset_is_empty (dispvis_frameset)){
339 
340  /* Identify the ARGON, P2VM, DISP, DARK, WAVE, FLAT, BADPIX frames */
341  wavelampcalib_frameset = gravi_frameset_extract_wavelamp_map (frameset);
342  p2vmcalib_frameset = gravi_frameset_extract_p2vm_map (frameset);
343  wavecalib_frameset = gravi_frameset_extract_wave_map (frameset);
344  flatcalib_frameset = gravi_frameset_extract_flat_map (frameset);
345  badcalib_frameset = gravi_frameset_extract_bad_map (frameset);
346 
347  darkcalib_frameset = gravi_frameset_extract_dark_map (frameset);
348  dark_frameset = gravi_frameset_extract_dark_data (frameset);
349 
350  disp_frameset = gravi_frameset_extract_disp_data (frameset);
351 
352  /* Check inputs */
353  if ( cpl_frameset_is_empty(p2vmcalib_frameset) ||
354  cpl_frameset_is_empty(wavecalib_frameset) ||
355  cpl_frameset_is_empty(flatcalib_frameset) ||
356  cpl_frameset_is_empty(badcalib_frameset) ||
357  ( cpl_frameset_is_empty(dark_frameset) &&
358  cpl_frameset_is_empty(darkcalib_frameset) ) ||
359  cpl_frameset_is_empty(disp_frameset) ||
360  cpl_frameset_is_empty(wavelampcalib_frameset) ) {
361 
362  cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
363  "Missing P2VM, DARK, BAD, WAVE, WAVELAMP, FLAT or DISP frames") ;
364  goto cleanup;
365  }
366 
367  /*
368  * Identify the DARK in the input frameset
369  */
370 
371  if (!cpl_frameset_is_empty (dark_frameset)) {
372 
373  frame = cpl_frameset_get_position (dark_frameset, 0);
374  data = gravi_data_load_rawframe (frame, used_frameset);
375  gravi_data_detector_cleanup (data, parlist);
376 
377  /* Compute dark */
378  dark_map = gravi_compute_dark (data);
379  FREE (gravi_data_delete, data);
380 
381  CPLCHECK_CLEAN ("Could not compute the DARK map");
382 
383  /* Save the dark map */
384  gravi_data_save_new (dark_map, frameset, NULL, parlist,
385  NULL, frame, "gravi_single",
386  NULL, GRAVI_DARK_MAP);
387 
388  CPLCHECK_CLEAN ("Could not save the DARK map");
389  }
390  else if (!cpl_frameset_is_empty (darkcalib_frameset)) {
391 
392  frame = cpl_frameset_get_position (darkcalib_frameset, 0);
393  dark_map = gravi_data_load_frame (frame, used_frameset);
394 
395  CPLCHECK_CLEAN ("Could not load the DARK map");
396  }
397  else
398  cpl_msg_error (cpl_func, "There is no DARK in the frame set");
399 
400  /* Identify the BAD in the input frameset */
401  frame = cpl_frameset_get_position (badcalib_frameset, 0);
402  badpix_map = gravi_data_load_frame (frame, used_frameset);
403 
404  /* Identify the FLAT in the input frameset */
405  frame = cpl_frameset_get_position (flatcalib_frameset, 0);
406  profile_map = gravi_data_load_frame (frame, used_frameset);
407 
408  /* Identify the WAVE in the input frameset */
409  frame = cpl_frameset_get_position (wavecalib_frameset, 0);
410  wave_map = gravi_data_load_frame (frame, used_frameset);
411 
412  /* Identify the P2VM in the input frameset */
413  frame = cpl_frameset_get_position (p2vmcalib_frameset, 0);
414  p2vm_map = gravi_data_load_frame (frame, used_frameset);
415 
416  CPLCHECK_CLEAN ("Error while loading the calibration map");
417 
418 
419  /*
420  * Loop on input DISP files
421  */
422 
423  nb_frame = cpl_frameset_get_size (disp_frameset);
424  for (int ivis = 0; ivis < nb_frame; ivis++) {
425  current_frameset = cpl_frameset_duplicate (used_frameset);
426 
427  cpl_msg_info (cpl_func, "*** Processing file %d over %d *** ", ivis+1, nb_frame);
428 
429  frame = cpl_frameset_get_position (disp_frameset, ivis);
430  data = gravi_data_load_rawframe (frame, current_frameset);
431  gravi_data_detector_cleanup (data, parlist);
432 
433  /* Extract spectrum */
434  preproc_data = gravi_extract_spectrum (data, profile_map, dark_map,
435  badpix_map, NULL, parlist);
436  CPLCHECK_CLEAN ("Cannot extract spectrum");
437 
438  /* Rescale to common wavelength */
439  gravi_align_spectrum (preproc_data, wave_map, p2vm_map);
440  CPLCHECK_CLEAN ("Cannot re-interpolate spectrum");
441 
442  /* Move extensions from raw_data */
443  gravi_data_move_ext (preproc_data, data, GRAVI_ARRAY_GEOMETRY_EXT);
444  gravi_data_move_ext (preproc_data, data, GRAVI_OPTICAL_TRAIN_EXT);
445  gravi_data_move_ext (preproc_data, data, GRAVI_OPDC_EXT);
446  gravi_data_move_ext (preproc_data, data, GRAVI_FDDL_EXT);
447  gravi_data_move_ext (preproc_data, data, GRAVI_METROLOGY_EXT);
448  CPLCHECK_CLEAN ("Cannot move ext");
449 
450  FREE (gravi_data_delete,data);
451 
452  /* Option save the proproc file */
453  if (gravi_param_get_bool (parlist,"gravity.dfs.preproc-file")) {
454 
455  gravi_data_save_new (preproc_data, frameset, NULL, parlist,
456  current_frameset, frame, "gravity_disp",
457  NULL, GRAVI_PREPROC);
458 
459  CPLCHECK_CLEAN ("Could not save the preproc data");
460  }
461 
462  /* Compute the flux and visibilities for each telescope and
463  * per acquisition with the P2VM applied to preproc_data */
464  p2vmred_data = gravi_compute_p2vmred (preproc_data, p2vm_map, "gravi_single", parlist);
465  CPLCHECK_CLEAN ("Cannot apply p2vm to the preproc data");
466 
467  /* Move extensions and delete preproc */
468  gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_METROLOGY_EXT);
469  gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_FDDL_EXT);
470  gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_OPDC_EXT);
471  FREE (gravi_data_delete, preproc_data);
472  CPLCHECK_CLEAN ("Cannot delete preproc");
473 
474  /* Reduce the OPDC table */
475  gravi_compute_opdc_state (p2vmred_data);
476  CPLCHECK_CLEAN ("Cannot reduce OPDC");
477 
478  /* Reduce the metrology */
479  gravi_metrology_reduce (p2vmred_data);
480  CPLCHECK_CLEAN ("Cannot reduce metrology");
481 
482  /* Compute the SNR_SMT and GDELAY_SMT columns */
483  gravi_compute_snr (p2vmred_data, parlist);
484  CPLCHECK_MSG ("Cannot compute SNR");
485 
486  /* Compute the additional signals for averaging */
487  gravi_compute_signals (p2vmred_data, disp_map, parlist);
488  CPLCHECK_MSG ("Cannot compute signals");
489 
490  /* Compute rejection flags for averaging */
491  gravi_compute_rejection (p2vmred_data, parlist);
492  CPLCHECK_MSG ("Cannot rejection flags signals");
493 
494  /* Visibility and flux are averaged and the followings
495  * are saved in Visibility data in tables VIS, VIS2 and T3 */
496  tmpvis_data = gravi_compute_vis (p2vmred_data, parlist);
497  CPLCHECK_CLEAN ("Cannot average the visibilities");
498 
499  /* Save the VIS */
500  if (gravi_param_get_bool (parlist,"gravity.dfs.vis-file")) {
501 
502  gravi_data_save_new (tmpvis_data, frameset, NULL, parlist,
503  current_frameset, frame, "gravity_disp",
504  NULL, GRAVI_VIS_SINGLE_CALIB);
505 
506  CPLCHECK_CLEAN ("Cannot save the VIS product");
507  }
508 
509  /* Save the P2VMREDUCED */
510  if (gravi_param_get_bool (parlist,"gravity.dfs.p2vmred-file")) {
511 
512  gravi_data_save_new (p2vmred_data, frameset, NULL, parlist,
513  current_frameset, frame, "gravity_disp",
514  NULL, GRAVI_P2VMRED_SINGLE_CALIB);
515 
516  CPLCHECK_CLEAN ("Cannot save the P2VMREDUCED product");
517  }
518 
519 
520  /* Merge with already existing */
521  if (ivis == 0) {
522  vis_data = tmpvis_data; tmpvis_data = NULL;
523  }
524  else {
525  cpl_msg_info (cpl_func,"Merge with previous OI_VIS");
526  gravi_data_append (vis_data, tmpvis_data, 1);
527  FREE (gravi_data_delete, tmpvis_data);
528  }
529  CPLCHECK_CLEAN ("Cannot merge the visibilities");
530 
531  cpl_msg_info (cpl_func,"Free the p2vmreduced");
532  FREE (cpl_frameset_delete, current_frameset);
533  FREE (gravi_data_delete, p2vmred_data);
534  }
535  /* End loop on the input files to reduce */
536 
537  /* Recompute the TIME column from the MJD column
538  * in all OIFITS tables to follow standard */
539  gravi_vis_mjd_to_time (vis_data);
540 
541  /* Identify the WAVELAMP in the input frameset */
542  frame = cpl_frameset_get_position (wavelampcalib_frameset, 0);
543  argon_data = gravi_data_load_frame (frame, used_frameset);
544 
545  /* Duplicate POS_ARGON into the VIS file */
546  gravi_data_copy_ext (vis_data, argon_data, "POS_ARGON");
547 
548  /* Save the output data file based on the first frame of the frameset */
549  cpl_frameset_join (used_frameset, disp_frameset);
550  frame = cpl_frameset_get_position (disp_frameset, 0);
551 
552  gravi_data_save_new (vis_data, frameset, NULL, parlist,
553  used_frameset, frame, "gravity_disp",
554  NULL, GRAVI_DISP_VIS);
555 
556  CPLCHECK_CLEAN("Could not save the VIS_SINGLE product");
557 
558  FREE (gravi_data_delete, profile_map);
559  FREE (gravi_data_delete, dark_map);
560  FREE (gravi_data_delete, wave_map);
561  FREE (gravi_data_delete, badpix_map);
562  FREE (gravi_data_delete, p2vm_map);
563  FREE (cpl_frameset_delete, darkcalib_frameset);
564  FREE (cpl_frameset_delete, wavecalib_frameset);
565  FREE (cpl_frameset_delete, dark_frameset);
566  FREE (cpl_frameset_delete, flatcalib_frameset);
567  FREE (cpl_frameset_delete, badcalib_frameset);
568  FREE (cpl_frameset_delete, p2vmcalib_frameset);
569  FREE (cpl_frameset_delete, wavelampcalib_frameset);
570  }
571  else {
572 
573  /* Load the DIS_VIS already computed */
574  frame = cpl_frameset_get_position (dispvis_frameset, 0);
575  vis_data = gravi_data_load_frame (frame, used_frameset);
576 
577  CPLCHECK_CLEAN ("Cannot load the DISP_VIS file");
578 
579  disp_frameset = cpl_frameset_duplicate (dispvis_frameset);
580  }
581 
582  /*
583  * Compute the dispersion table of a set of disp frames
584  */
585 
586  gravi_disp_cleanup (vis_data);
587 
588  disp_map = gravi_compute_disp (vis_data);
589 
590  CPLCHECK_CLEAN ("Error while computing the disp_map");
591 
592  /* Create product frame */
593  frame = cpl_frameset_get_position (disp_frameset, 0);
594 
595  /* Save the DISP_MODEL */
596  gravi_data_save_new (disp_map, frameset, NULL, parlist,
597  used_frameset, frame, "gravity_disp",
598  NULL, GRAVI_DISP_MODEL);
599 
600  CPLCHECK_CLEAN("Could not save the DISP_MODEL product");
601 
602  /* Deallocation of all variables */
603  goto cleanup;
604 
605 cleanup :
606  cpl_msg_info(cpl_func,"Memory cleanup");
607  FREE (gravi_data_delete, data);
608  FREE (gravi_data_delete, tmpvis_data);
609  FREE (gravi_data_delete, vis_data);
610  FREE (gravi_data_delete, disp_map);
611  FREE (gravi_data_delete, dark_map);
612  FREE (gravi_data_delete, wave_map);
613  FREE (gravi_data_delete, profile_map);
614  FREE (gravi_data_delete, badpix_map);
615  FREE (gravi_data_delete, p2vmred_data);
616  FREE (gravi_data_delete, p2vm_map);
617  FREE (gravi_data_delete, preproc_data);
618  FREE (cpl_frameset_delete, disp_frameset);
619  FREE (cpl_frameset_delete, dispvis_frameset);
620  FREE (cpl_frameset_delete, darkcalib_frameset);
621  FREE (cpl_frameset_delete, dark_frameset);
622  FREE (cpl_frameset_delete, wavecalib_frameset);
623  FREE (cpl_frameset_delete, badcalib_frameset);
624  FREE (cpl_frameset_delete, flatcalib_frameset);
625  FREE (cpl_frameset_delete, p2vmcalib_frameset);
626  FREE (cpl_frameset_delete, wavelampcalib_frameset);
627  FREE (cpl_frameset_delete, used_frameset);
628  FREE (cpl_frameset_delete, current_frameset);
629 
630  gravi_msg_function_exit(1);
631  return (int)cpl_error_get_code();
632 }
633 
634