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