GRAVI Pipeline Reference Manual  0.7.11
gravi_all_p2vm.c
1 /* $Id: gravi_all_p2vm.c,v 1.29 2009/02/10 09:16:12 llundin 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: llundin $
23  * $Date: 2009/02/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 #include "gravi_vis.h"
48 
49 
50 
51 /*-----------------------------------------------------------------------------
52  Private function prototypes
53  -----------------------------------------------------------------------------*/
54 
55 static int gravi_all_p2vm_create(cpl_plugin *);
56 static int gravi_all_p2vm_exec(cpl_plugin *);
57 static int gravi_all_p2vm_destroy(cpl_plugin *);
58 static int gravi_all_p2vm(cpl_frameset *, const cpl_parameterlist *);
59 
60 /*-----------------------------------------------------------------------------
61  Static variables
62  -----------------------------------------------------------------------------*/
63 
64 static char gravi_all_p2vm_description[] =
65 "This recipe can reduces itself the master caqlibration files. But one can \n"
66 "optionally provide master calibration file as input to force to use a specific\n"
67 "one.\n"
68 "The output FITS file contain 3 p2vm tables with the values of the \n"
69 "transmission, phase and coherence for all the beam combiners (P2VM_SC, \n"
70 "P2VM_FT and P2VM_MET).\n"
71 "\n"
72 "Description DO category\n"
73 "Required input :\n"
74 " Raw dark file "GRAVI_DARK "\n"
75 " Raw flat file (4 files) "GRAVI_DARK "\n"
76 " Raw wave file "GRAVI_WAVE "\n"
77 " Raw p2vm files (6 files) "GRAVI_P2VM "\n"
78 "Or optionally\n"
79 " Master dark " DARK "\n"
80 " Master flat " FLAT "\n"
81 " Bad pixel map " BAD "\n"
82 " Master wave " WAVE "\n"
83 ""
84 "Output :"
85 " P2vm map " P2VM "\n"
86 " Master dark (opt.) " DARK "\n"
87 " Bad pixel map (opt.) " BAD "\n"
88 " Master flat (opt.) " FLAT "\n"
89 " Master wave (opt.) " WAVE "\n"
90 "\n";
91 
92 /*-----------------------------------------------------------------------------
93  Function code
94  -----------------------------------------------------------------------------*/
95 
96 /*----------------------------------------------------------------------------*/
106 /*----------------------------------------------------------------------------*/
107 int cpl_plugin_get_info(cpl_pluginlist * list)
108 {
109  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
110  cpl_plugin * plugin = &recipe->interface;
111 
112  if (cpl_plugin_init(plugin,
113  CPL_PLUGIN_API,
114  GRAVI_BINARY_VERSION,
115  CPL_PLUGIN_TYPE_RECIPE,
116  "gravi_all_p2vm",
117  "This recipe is used to compute p2vm matrix",
118  gravi_all_p2vm_description,
119  "Firstname Lastname",
120  PACKAGE_BUGREPORT,
121  gravi_get_license(),
122  gravi_all_p2vm_create,
123  gravi_all_p2vm_exec,
124  gravi_all_p2vm_destroy)) {
125  cpl_msg_error(cpl_func, "Plugin initialization failed");
126  (void)cpl_error_set_where(cpl_func);
127  return 1;
128  }
129 
130  if (cpl_pluginlist_append(list, plugin)) {
131  cpl_msg_error(cpl_func, "Error adding plugin to list");
132  (void)cpl_error_set_where(cpl_func);
133  return 1;
134  }
135 
136  return 0;
137 }
138 
139 /*----------------------------------------------------------------------------*/
147 /*----------------------------------------------------------------------------*/
148 static int gravi_all_p2vm_create(cpl_plugin * plugin)
149 {
150  cpl_recipe * recipe;
151  cpl_parameter * p;
152 
153  /* Do not create the recipe if an error code is already set */
154  if (cpl_error_get_code() != CPL_ERROR_NONE) {
155  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
156  cpl_func, __LINE__, cpl_error_get_where());
157  return (int)cpl_error_get_code();
158  }
159 
160  if (plugin == NULL) {
161  cpl_msg_error(cpl_func, "Null plugin");
162  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
163  }
164 
165  /* Verify plugin type */
166  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
167  cpl_msg_error(cpl_func, "Plugin is not a recipe");
168  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
169  }
170 
171  /* Get the recipe */
172  recipe = (cpl_recipe *)plugin;
173 
174  /* Create the parameters list in the cpl_recipe object */
175  recipe->parameters = cpl_parameterlist_new();
176  if (recipe->parameters == NULL) {
177  cpl_msg_error(cpl_func, "Parameter list allocation failed");
178  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
179  }
180 
181  /* Fill the parameters list */
182 
183  /* -- Normalise the output p2vm */
184  p = cpl_parameter_new_value("gravi.normalize_p2vm",
185  CPL_TYPE_BOOL, "Normalise the output P2VM (false is for debuging)", "gravi.gravi_all_p2vm", TRUE);
186  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "normalize-p2vm");
187  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
188  cpl_parameterlist_append(recipe->parameters, p);
189 
190  /* --Save the preproc files */
191  p = cpl_parameter_new_value("gravi.preproc_param.preproc_file",
192  CPL_TYPE_BOOL, "Save the preproc file", "gravi.gravi_all_p2vm", FALSE);
193  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "preproc-file");
194  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
195  cpl_parameterlist_append(recipe->parameters, p);
196 
197  /* --the minimum wavelength */
198  p = cpl_parameter_new_value("gravi.preproc_param.min_wave",
199  CPL_TYPE_DOUBLE, "the minimum wavelength", "gravi.gravi_all_p2vm", GRAVI_DEFAULT_LBD_MIN);
200  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambda-min");
201  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
202  cpl_parameterlist_append(recipe->parameters, p);
203 
204  /* --the maximum wavelength */
205  p = cpl_parameter_new_value("gravi.preproc_param.max_wave",
206  CPL_TYPE_DOUBLE, "the maximum wavelength", "gravi.gravi_all_p2vm", GRAVI_DEFAULT_LBD_MAX);
207  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "lambda-max");
208  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
209  cpl_parameterlist_append(recipe->parameters, p);
210 
211  /* --the number of the spectral element to compute for FT data */
212  p = cpl_parameter_new_value("gravi.preproc_param.nspectrum_FT",
213  CPL_TYPE_INT, "number of spectral channels in the FT data", "gravi.gravi_all_p2vm", GRAVI_DEFAULT_NB_LBD);
214  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nlambda-ft");
215  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
216  cpl_parameterlist_append(recipe->parameters, p);
217 
218  /* --the number of the spectral element to compute for SC data */
219  p = cpl_parameter_new_value("gravi.preproc_param.nspectrum_SC",
220  CPL_TYPE_INT, "number of spectral channels in the SC data", "gravi.gravi_all_p2vm", 0);
221  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nlambda-sc");
222  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
223  cpl_parameterlist_append(recipe->parameters, p);
224 
225  /* --the number of the spectral element to smooth for SC data */
226  p = cpl_parameter_new_value("gravi.preproc_param.nsmooth_SC",
227  CPL_TYPE_INT, "number of spectral channels to be smoothed in the SC data", "gravi.gravi_all_p2vm", -1);
228  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "nsmooth-sc");
229  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
230  cpl_parameterlist_append(recipe->parameters, p);
231 
232  /* --the width of the profile element */
233  p = cpl_parameter_new_value("gravi.gravi_all_flat."
234  "profile_width", CPL_TYPE_INT, "profile width option",
235  "gravi.gravi_all_flat", 6);
236  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "profile-width");
237  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
238  cpl_parameterlist_append(recipe->parameters, p);
239 
240  p = cpl_parameter_new_value("gravi."
241  "flat_param.Bad_dark_threshold", CPL_TYPE_INT, "the rms factor for "
242  "dark bad pixel threshold", "gravi.gravi_all_flat", 10);
243  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "bad-dark-threshold");
244  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
245  cpl_parameterlist_append(recipe->parameters, p);
246 
247  /* --Use the metrology -- should be TRUE because the WAVE is modulated */
248  p = cpl_parameter_new_value("gravi.phase_calibration",
249  CPL_TYPE_INT, "0: force phase to zero; 1: keep closures; 2: keep full phases", "gravi", 0);
250  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "phase-calibration");
251  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
252  cpl_parameterlist_append(recipe->parameters, p);
253 
254  /* Parameter to compute the VIS_FLAT
255  * They should be hidden to user in all modes
256  * FIXME: hidding these parameters does not work */
257 
258  /* -- Visibility correction */
259  p = cpl_parameter_new_value("gravi.vis_reduce.vis_correction",
260  CPL_TYPE_BOOL, "Correction of visibilities looses", "gravi.vis_reduce", FALSE);
261  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
262  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
263  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CFG);
264  cpl_parameterlist_append(recipe->parameters, p);
265 
266  /* --SNR threshold for fringe DET in FT */
267  p = cpl_parameter_new_value("gravi.snr_threshold_ft",
268  CPL_TYPE_DOUBLE, "SNR threshold for fringe detection in FT (>0)", "gravi", 5.0);
269  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
270  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
271  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CFG);
272  cpl_parameterlist_append(recipe->parameters, p);
273 
274  /* --Minimum locking ratio to accept SC frame */
275  p = cpl_parameter_new_value("gravi.fringedet_threshold_sc",
276  CPL_TYPE_DOUBLE, "Fringe-detection ratio threshold to accept SC frame (0..1)", "gravi.vis_reduce", 0.8);
277  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
278  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
279  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CFG);
280  cpl_parameterlist_append(recipe->parameters, p);
281 
282  /* --Debias the V2 of SC */
283  p = cpl_parameter_new_value("gravi.debias_sc",
284  CPL_TYPE_BOOL, "Subtrast the V2 bias from SC", "gravi", TRUE);
285  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
286  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
287  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CFG);
288  cpl_parameterlist_append(recipe->parameters, p);
289 
290  /* --Debias the V2 of FT */
291  p = cpl_parameter_new_value("gravi.debias_ft",
292  CPL_TYPE_BOOL, "Subtrast the V2 bias from FT", "gravi", TRUE);
293  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
294  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
295  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CFG);
296  cpl_parameterlist_append(recipe->parameters, p);
297 
298  /* --Use the metrology -- should be TRUE because the WAVE is modulated */
299  p = cpl_parameter_new_value("gravi.use_met",
300  CPL_TYPE_BOOL, "Use the metrology to rephase the SC data", "gravi", TRUE);
301  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
302  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
303  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CFG);
304  cpl_parameterlist_append(recipe->parameters, p);
305 
306  return 0;
307 }
308 
309 /*----------------------------------------------------------------------------*/
315 /*----------------------------------------------------------------------------*/
316 static int gravi_all_p2vm_exec(cpl_plugin * plugin)
317 {
318 
319  cpl_recipe * recipe;
320  int recipe_status;
321  cpl_errorstate initial_errorstate = cpl_errorstate_get();
322 
323  /* Return immediately if an error code is already set */
324  if (cpl_error_get_code() != CPL_ERROR_NONE) {
325  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
326  cpl_func, __LINE__, cpl_error_get_where());
327  return (int)cpl_error_get_code();
328  }
329 
330  if (plugin == NULL) {
331  cpl_msg_error(cpl_func, "Null plugin");
332  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
333  }
334 
335  /* Verify plugin type */
336  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
337  cpl_msg_error(cpl_func, "Plugin is not a recipe");
338  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
339  }
340 
341  /* Get the recipe */
342  recipe = (cpl_recipe *)plugin;
343 
344  /* Verify parameter and frame lists */
345  if (recipe->parameters == NULL) {
346  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
347  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
348  }
349  if (recipe->frames == NULL) {
350  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
351  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
352  }
353 
354  /* Invoke the recipe */
355  recipe_status = gravi_all_p2vm(recipe->frames, recipe->parameters);
356 
357  /* Ensure DFS-compliance of the products */
358  if (cpl_dfs_update_product_header(recipe->frames)) {
359  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
360  }
361 
362  if (!cpl_errorstate_is_equal(initial_errorstate)) {
363  /* Dump the error history since recipe execution start.
364  At this point the recipe cannot recover from the error */
365  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
366  }
367 
368  return recipe_status;
369 }
370 
371 /*----------------------------------------------------------------------------*/
377 /*----------------------------------------------------------------------------*/
378 static int gravi_all_p2vm_destroy(cpl_plugin * plugin)
379 {
380  cpl_recipe * recipe;
381 
382  if (plugin == NULL) {
383  cpl_msg_error(cpl_func, "Null plugin");
384  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
385  }
386 
387  /* Verify plugin type */
388  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
389  cpl_msg_error(cpl_func, "Plugin is not a recipe");
390  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
391  }
392 
393  /* Get the recipe */
394  recipe = (cpl_recipe *)plugin;
395 
396  cpl_parameterlist_delete(recipe->parameters);
397 
398  return 0;
399 }
400 
401 /*
402  * Browse the parameter list to get the nsmooth_SC parameter provided by user.
403  * If value is default (-1), then the default is returned depending on the
404  * spectral resolution.
405  */
406 int gravi_get_nsmooth_for_p2vm(gravi_data * data, const cpl_parameterlist * parlist)
407 {
408  int nsmooth;
409 
410  /* Get the nsmooth from parameter list */
411  nsmooth = cpl_parameter_get_int( cpl_parameterlist_find_const(parlist, "gravi.preproc_param.nsmooth_SC") );
412 
413  /* If valid, return it (0 is valid, means no smoothing) */
414  if (nsmooth >= 0 ) return nsmooth;
415 
416  /* Default from spectral resolution */
417  const char * resolution = gravi_pfits_get_spec_res (gravi_data_get_propertylist(data, GRAVI_PRIMARY_HDR_NAME_EXT));
418 
419  if ( !(strcmp(resolution, "HIGH")) ) {
420  cpl_msg_info(cpl_func,"Default smoothing is 15 (HIGH)");
421  nsmooth = 15;
422  }
423  else if ( !(strcmp(resolution, "MEDIUM")) ) {
424  cpl_msg_info(cpl_func,"Default smoothing is 3 (MEDIUM)");
425  nsmooth = 3;
426  }
427  else if ( !(strcmp(resolution, "LOW")) ) {
428  cpl_msg_info(cpl_func,"Default is no smoothing of data (LOW)");
429  nsmooth = 0;
430  } else {
431  cpl_msg_warning(cpl_func,"Unknown spectral resolution thus no smoothing of data");
432  nsmooth = 0;
433  }
434 
435  return nsmooth;
436 }
437 
438 /*----------------------------------------------------------------------------*/
446 /*----------------------------------------------------------------------------*/
447 static int gravi_all_p2vm(cpl_frameset * frameset,
448  const cpl_parameterlist * parlist)
449 {
450  cpl_frameset * p2vm_frameset=NULL, * wavecalib_frameset=NULL, * darkcalib_frameset=NULL,
451  * gaincalib_frameset=NULL, * dark_frameset=NULL, * wave_frameset=NULL,
452  * badpix_frameset=NULL, * gain_frameset=NULL;
453  cpl_propertylist * applist=NULL, * primary_hdr=NULL, * primary_hdr_dark=NULL, * p2vm_plist=NULL,
454  * primary_hdr_wave=NULL, * bad_primary_hdr=NULL, * profile_primary_hdr=NULL, * plist=NULL;
455  cpl_frame * frame=NULL;
456  const cpl_parameter * p=NULL;
457  char * out_dark=NULL, * out_wave=NULL, * preproc_name=NULL, * out_gain=NULL;
458  const char * filename=NULL, * origin=NULL, * acq_start=NULL;
459  gravi_data * p2vm_data=NULL, * data=NULL, * dark_map=NULL, * wave_map=NULL,
460  * profile_map=NULL, * badpix_map=NULL;
461  gravi_data ** calib_datas=NULL, * wave_data=NULL;
462  gravi_data * preproc_data=NULL;
463  gravi_data ** raw_data=NULL;
464  gravi_data * p2vm_reduced = NULL;
465  gravi_data * oi_visflat = NULL;
466 
467  int nb_frame, i, nb_frame_gain, j;
468  int rest;
469  double gain_ft, gain_sc, mjd_obs, acq_mjd;
470  int * shutter=NULL;
471  cpl_table * p2vm_met = NULL, * metrology_table=NULL, * opl_table = NULL, * detector_table=NULL,
472  *p2vm_table=NULL;
473  cpl_propertylist * met_plist=NULL;
474  cpl_frameset * preproc_frame=NULL;
475  int ** valid_trans = cpl_malloc (2 * sizeof (int*));
476  int ** valid_CP = cpl_malloc (2 * sizeof (int*)), type_data;
477  int n_tel = 4, n_wave, n_region;
478  cpl_propertylist * oiwave_plist=NULL;
479  int met_check = 1, def_p2vm = 1;
480  cpl_propertylist * p2vm_primary_hdr=NULL;
481  clock_t start, end;
482  int tel_1[6] = {0,0,0,1,1,2};
483  int tel_2[6] = {1,2,3,2,3,3};
484  int nsmooth;
485  char * out_p2vm = NULL, * out_visflat = NULL ;
486 
487  for (i = 0 ; i < 2; i++){
488  valid_trans[i] = cpl_calloc (4, sizeof (int));
489  valid_CP[i] = cpl_calloc (6, sizeof (int));
490  }
491 
492  /* Message */
493  cpl_msg_set_time_on();
494  cpl_msg_set_component_on();
495  cpl_msg_info(cpl_func,"Start function -- cleanup");
496 
497  /* Get the input frameset */
498  cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE, cpl_error_get_code()) ;
499 
500  /* Extract a set of frame p2vm and set of frame dark wave */
501  p2vm_frameset = gravi_frameset_extract_p2vm_data(frameset);
502  wavecalib_frameset = gravi_frameset_extract_wave_file(frameset);
503  darkcalib_frameset = gravi_frameset_extract_dark_file(frameset);
504  gaincalib_frameset = gravi_frameset_extract_flat_file(frameset);
505  wave_frameset = gravi_frameset_extract_wave(frameset);
506  dark_frameset = gravi_frameset_extract_dark(frameset);
507  gain_frameset = gravi_frameset_extract_flat(frameset);
508  badpix_frameset = gravi_frameset_extract_badpix(frameset);
509 
510  /* To use this recipe the frameset must contain at least
511  * one P2VM frame. */
512  if ( cpl_frameset_is_empty(p2vm_frameset) ) {
513  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT, "No P2VM frame on the frameset") ;
514  goto cleanup;
515  }
516 
517  /* To use this recipe the frameset must contain at least
518  * one FLAT frame. */
519  if (cpl_frameset_is_empty(gaincalib_frameset) && cpl_frameset_is_empty(gain_frameset) ) {
520  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT, "No FLAT file in the frameset") ;
521  goto cleanup;
522  }
523 
524  /* To use this recipe the frameset must contain at least
525  * one DARK frame. */
526  if (cpl_frameset_is_empty(darkcalib_frameset) && cpl_frameset_is_empty(dark_frameset) ) {
527  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT, "No DARK file in the frameset") ;
528  goto cleanup;
529  }
530 
531  /* To use this recipe the frameset must contain at least
532  * one WAVE frame. */
533  if (cpl_frameset_is_empty(wave_frameset) && cpl_frameset_is_empty(wavecalib_frameset) ) {
534  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT, "No WAVE file in the frameset") ;
535  goto cleanup;
536  }
537 
538  /*
539  * (1) Identify and extract the dark file
540  */
541  cpl_msg_info( cpl_func, " ***** Get dark map ***** " );
542 
543  if (!cpl_frameset_is_empty(dark_frameset)) {
544  /* The DARK in the frame_set is a raw dark */
545 
546  /* Verbose */
547  frame = cpl_frameset_get_position(dark_frameset, 0);
548  filename = cpl_frame_get_filename(frame);
549  cpl_msg_info (cpl_func, "This file %s is a raw DARK file", FILESHORT(filename));
550 
551  /* Load data */
552  data = gravi_data_load(filename);
553 
554  /* The DARK file must contains all the shutter close */
555  primary_hdr = gravi_data_get_propertylist(data, GRAVI_PRIMARY_HDR_NAME_EXT);
556  shutter = gravi_shutters_check(primary_hdr);
557  if (!((shutter[0] == 0) && (shutter[1] == 0) &&
558  (shutter[2] == 0) && (shutter[3] == 0))){
559  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT, "Shutter problem");
560  goto cleanup;
561  }
562 
563  /* Compute the DARK */
564  dark_map = gravi_compute_dark(data);
565 
566  CPLCHECK_INT("Cannot compute the DARK map");
567 
568  /* Add additional parameters */
569  cpl_frameset_insert(darkcalib_frameset, cpl_frame_duplicate(frame));
570  primary_hdr_dark = gravi_data_get_propertylist(dark_map, GRAVI_PRIMARY_HDR_NAME_EXT);
571  applist = gravi_propertylist_get_qc (primary_hdr_dark);
572  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, DARK);
573 
574  /* Build the output name */
575  // out_dark = cpl_sprintf("master_dark.%s", FILESHORT(filename));
576  out_dark = gravi_data_product_name (filename, "dark");
577 
578  /* Save the dark map */
579  gravi_data_save(dark_map, frameset, out_dark, parlist,
580  darkcalib_frameset, frame, "gravi_all_p2vm", applist);
581 
582  CPLCHECK_CLEAN("Could not save the DARK map");
583 
584  FREE( cpl_propertylist_delete, applist);
585  FREE( gravi_data_delete, data);
586  FREE( cpl_free, shutter);
587  FREE( cpl_free, out_dark);
588  }
589  else if (!cpl_frameset_is_empty(darkcalib_frameset)) {
590  /* The DARK in the frame_set is a calibrated dark */
591 
592  /* Verbose */
593  frame = cpl_frameset_get_position(darkcalib_frameset, 0);
594  cpl_frameset_insert (dark_frameset, cpl_frame_duplicate (frame));
595  filename = cpl_frame_get_filename(frame);
596  cpl_msg_info (cpl_func, "This file %s is a DARK file already computed", FILESHORT(filename));
597 
598  /* Load this DARK */
599  dark_map = gravi_data_load(filename);
600  }
601 
602  /* End check of DARK in the frameset */
603 
604  /*
605  * (2) Identify and extract the BADPIX file
606  */
607  cpl_msg_info( cpl_func, " ***** Get bad pixel map ***** " );
608 
609  if (!cpl_frameset_is_empty(badpix_frameset)){
610 
611  /* Verbose */
612  frame = cpl_frameset_get_position(badpix_frameset, 0);
613  filename = cpl_frame_get_filename(frame);
614  cpl_msg_info (cpl_func, "This file %s is a BAD pixel map", FILESHORT(filename));
615 
616  /* Load this BADPIX */
617  badpix_map = gravi_data_load(filename);
618 
619  }
620  else {
621  cpl_msg_info( cpl_func, "Compute the BAD pixel map from DARK" );
622 
623  /* If no BADPIX, compute it from the DARK */
624  badpix_map = gravi_compute_badpix(dark_map, parlist);
625 
626  CPLCHECK_INT("Cannot compute the BAD pixel from DARK");
627 
628  /* Additional parameters */
629  bad_primary_hdr = gravi_data_get_propertylist (badpix_map, GRAVI_PRIMARY_HDR_NAME_EXT);
630  applist = gravi_propertylist_get_qc (bad_primary_hdr);
631  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, BAD);
632 
633  /* Output file name */
634  frame = cpl_frameset_get_position (dark_frameset, 0);
635  filename = cpl_frame_get_filename (frame);
636  //out_dark = cpl_sprintf("badpix.%s", FILESHORT(filename));
637  out_dark = gravi_data_product_name (filename, "badpix");
638 
639  /* Save the BADPIX */
640  gravi_data_save (badpix_map, frameset, out_dark, parlist,
641  dark_frameset, frame, "gravi_all_p2vm", applist);
642 
643  CPLCHECK_CLEAN("Could not save the BAD pixel map");
644 
645  FREE( cpl_propertylist_delete, applist );
646  FREE( cpl_free, out_dark );
647 
648  }
649  /* End check of BADPIX in the frameset */
650 
651  FREE( cpl_frameset_delete, darkcalib_frameset);
652  FREE( cpl_frameset_delete, dark_frameset);
653  FREE( cpl_frameset_delete, badpix_frameset);
654 
655 
656  /*
657  * (3) Check that the gain map in the input frameset
658  */
659  cpl_msg_info( cpl_func, " ***** Get gain map ***** " );
660 
661  if ( (!cpl_frameset_is_empty(gain_frameset)) &&
662  (cpl_frameset_is_empty(gaincalib_frameset) ) ) {
663  cpl_msg_info( cpl_func, "Compute the profile map from FLAT files" );
664 
665  /* Identify the flat files */
666  nb_frame_gain = cpl_frameset_get_size (gain_frameset);
667  raw_data = cpl_malloc(nb_frame_gain * sizeof(gravi_data *));
668 
669  /* Build the list of FLAT files and output file name */
670  for (i = 0; i < nb_frame_gain; i++) {
671  frame = cpl_frameset_get_position(gain_frameset, i);
672  filename = cpl_frame_get_filename(frame);
673  raw_data[i] = gravi_data_load(filename);
674  primary_hdr = gravi_data_get_propertylist(raw_data[i],
675  GRAVI_PRIMARY_HDR_NAME_EXT);
676  shutter = gravi_shutters_check(primary_hdr);
677  FREE( cpl_free, shutter );
678  if (i == 0){
679  // out_gain = cpl_sprintf("master_profile.%s", FILESHORT(filename));
680  out_gain = gravi_data_product_name (filename, "flat");
681  }
682 
683  }
684 
685  /* Compute the profile from the list of FLAT */
686  profile_map = gravi_compute_profile(raw_data, dark_map, badpix_map,
687  nb_frame_gain, parlist);
688 
689  CPLCHECK_INT("Cannot compute the FLAT profile");
690 
691  /* Compute the gain and extract the gain map */
692  gain_sc = gravi_compute_gain(raw_data, nb_frame_gain, dark_map, badpix_map, GRAVI_IMAGING_DATA_SC_EXT);
693  cpl_msg_info (cpl_func, "QC_MEANGAIN_SC = %.4f [ADU/e-] Mean gain of SC detector", gain_sc);
694 
695  gain_ft = gravi_compute_gain(raw_data, nb_frame_gain, dark_map, badpix_map, GRAVI_IMAGING_DATA_FT_EXT);
696  cpl_msg_info (cpl_func, "QC_MEANGAIN_FT = %.4f [ADU/e-] Mean gain of FT detector", gain_ft);
697 
698  /* Save the profile map */
699  profile_primary_hdr = gravi_data_get_propertylist(profile_map, GRAVI_PRIMARY_HDR_NAME_EXT);
700  applist = gravi_propertylist_get_qc (profile_primary_hdr);
701  cpl_propertylist_append_double (applist, QC_MEANGAIN_FT, gain_ft);
702  cpl_propertylist_set_comment( applist, QC_MEANGAIN_FT, "[ADU/e-] Mean gain of FT detector" );
703  cpl_propertylist_append_double (applist, QC_MEANGAIN_SC, gain_sc);
704  cpl_propertylist_set_comment( applist, QC_MEANGAIN_SC, "[ADU/e-] Mean gain of SC detector" );
705  cpl_propertylist_append_string (applist, CPL_DFS_PRO_CATG, FLAT);
706 
707  frame = cpl_frameset_get_position(gain_frameset, 0);
708 
709  gravi_data_save(profile_map, frameset, out_gain, parlist,
710  gain_frameset, frame, "gravi_all_p2vm", applist);
711 
712  CPLCHECK_CLEAN("Could not save the FLAT profile_map");
713 
714  /* Free the list of files */
715  FREELOOP( gravi_data_delete, raw_data, nb_frame_gain );
716  FREE( cpl_propertylist_delete, applist );
717  FREE( cpl_free, out_gain );
718 
719  } else if (!cpl_frameset_is_empty(gaincalib_frameset)) {
720 
721  frame = cpl_frameset_get_position (gaincalib_frameset, 0);
722 
723  /* Verbose */
724  filename = cpl_frame_get_filename(frame);
725  cpl_msg_info (cpl_func, "This file %s is a FLAT file already computed", FILESHORT(filename));
726 
727  /* Load the profile map */
728  profile_map = gravi_data_load(filename);
729  }
730 
731  FREE( cpl_frameset_delete, gaincalib_frameset );
732  FREE( cpl_frameset_delete, gain_frameset );
733 
734  /* End check of GAIN in the frameset */
735 
736 
737 
738  /*
739  * (4) Check and get the WAVE frame
740  */
741  cpl_msg_info( cpl_func, " ***** Get wave map ***** " );
742 
743  if ((!cpl_frameset_is_empty(wave_frameset)) &&
744  (cpl_frameset_is_empty(wavecalib_frameset))) {
745  /* The WAVE in the frame_set is a raw wave */
746 
747  /* Verbose */
748  frame = cpl_frameset_get_position(wave_frameset, 0);
749  filename = cpl_frame_get_filename(frame);
750  cpl_msg_info (cpl_func, "This file %s is a raw WAVE file", FILESHORT(filename));
751 
752  /* Load this wave */
753  data = gravi_data_load(filename);
754  primary_hdr = gravi_data_get_propertylist(data, GRAVI_PRIMARY_HDR_NAME_EXT);
755  shutter = gravi_shutters_check(primary_hdr);
756 
757  /* Check the shutters */
758  if ( !((shutter[0] == 1) && (shutter[1] == 1) &&
759  (shutter[2] == 1) && (shutter[3] == 1)) ) {
760  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT, "Shutter problem");
761  goto cleanup;
762  }
763 
764 
765  /* Compute the p2vm of the metrology if requested */
766  // p = cpl_parameterlist_find_const(parlist, "gravi.gravi_all_p2vm.opd_met");
767  // if ((cpl_parameter_get_bool (p)) && (met_check)){
768  if (met_check){
769 
770  /* Verbose */
771  cpl_msg_info( cpl_func, "Compute the p2vm of the metrology in the WAVE file");
772 
773  metrology_table = gravi_data_get_table(data, GRAVI_METROLOGY_EXT);
774  met_plist = cpl_propertylist_duplicate (gravi_data_get_propertylist(data, GRAVI_METROLOGY_EXT));
775 
776  start = clock();
777  opl_table = cpl_table_new (cpl_table_get_nrow(metrology_table));
778  p2vm_met = gravi_metrology_calibration (metrology_table, opl_table, 0);
779 
780  cpl_msg_info(cpl_func, "Execution time gravi_metrology_calibration : %f s",
781  (clock() - start) / (double)CLOCKS_PER_SEC);
782 
783  CPLCHECK_CLEAN("Error while computing p2vm of the metrology");
784  met_check = 0;
785  }
786  /* End computation of the p2vm of the metrology */
787 
788  /* Compute the WAVE table */
789  wave_map = gravi_compute_wave(data, profile_map, dark_map, badpix_map, opl_table, parlist);
790 
791  CPLCHECK_INT("Cannot compute the wave_map");
792 
793  /* Additional parameters */
794  primary_hdr_wave = gravi_data_get_propertylist(wave_map, GRAVI_PRIMARY_HDR_NAME_EXT);
795  applist = gravi_propertylist_get_qc (primary_hdr_wave);
796  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, WAVE);
797 
798  /* Output filename for WAVE */
799  out_wave = gravi_data_product_name (filename, "wave");
800 
801  /* Save the WAVE map */
802  gravi_data_save(wave_map, frameset, out_wave, parlist,
803  wave_frameset, frame, "gravi_all_p2vm", applist);
804 
805  CPLCHECK_CLEAN("Could not save the WAVE map");
806 
807  /* Free */
808  FREE( cpl_propertylist_delete, applist );
809  FREE( cpl_table_delete, opl_table );
810  FREE( gravi_data_delete, data );
811  FREE( cpl_free, shutter );
812  FREE( cpl_free, out_wave );
813 
814  } else if (!cpl_frameset_is_empty(wavecalib_frameset) ){
815  /* The WAVE in the frame_set is a calibrated dark */
816 
817  /* Verbose */
818  frame = cpl_frameset_get_position(wavecalib_frameset, 0);
819  filename = cpl_frame_get_filename(frame);
820  cpl_msg_info (cpl_func, "This file %s is a WAVE file already computed", FILESHORT(filename));
821 
822  /* Load this WAVE */
823  wave_map = gravi_data_load(filename);
824  }
825  /* End check of WAVE in the frameset */
826 
827  /* Copy the P2VM metrology from the master wave file if not computed by the recipe */
828  if ((gravi_data_has_extension (wave_map, GRAVI_P2VM_MET_EXT)) && (met_check)) {
829 
830  met_plist = cpl_propertylist_duplicate ( gravi_data_get_propertylist (wave_map, GRAVI_P2VM_MET_EXT));
831  p2vm_met = cpl_table_duplicate ( gravi_data_get_table (wave_map, GRAVI_P2VM_MET_EXT));
832  met_check = 0;
833 
834  }
835 
836  FREE( cpl_frameset_delete, wavecalib_frameset );
837  FREE( cpl_frameset_delete, wave_frameset );
838 
839  calib_datas = cpl_malloc(4 * sizeof(gravi_data *));
840  calib_datas[0] = dark_map;
841  calib_datas[1] = wave_map;
842  calib_datas[2] = profile_map;
843  calib_datas[3] = badpix_map;
844 
845  /* Get the parameter about preprocfile requested or not */
846  p = cpl_parameterlist_find_const(parlist, "gravi.preproc_param.preproc_file");
847 
848 
849  /*
850  * (6) Loop on files of the p2vm frameset
851  */
852 
853  /* Get the number of the p2vm frame contained in the frameset */
854  nb_frame = cpl_frameset_get_size(p2vm_frameset);
855 
856  for (i = 0; i < nb_frame; i++) {
857 
858  /* Build the filename */
859  frame = cpl_frameset_get_position(p2vm_frameset, i);
860  filename = cpl_frame_get_filename(frame);
861 
862  /* Verbose */
863  cpl_msg_info (cpl_func, " ***** file %d over %d ***** ", i+1, nb_frame );
864  cpl_msg_info (cpl_func, "Calibration of this file %s", FILESHORT(filename));
865 
866  /* Load data */
867  data = gravi_data_load(filename);
868  primary_hdr = gravi_data_get_propertylist(data, GRAVI_PRIMARY_HDR_NAME_EXT);
869 
870  /* Verbose the shutters */
871  shutter = gravi_shutters_check(primary_hdr);
872  cpl_msg_info( cpl_func, "Shutters: %d-%d-%d-%d",
873  shutter[0], shutter[1], shutter[2], shutter[3] );
874 
875  /*
876  * Create the product filename as the first P2VM file (1-1-0-0).
877  * This is to ensure the run_gravi_reduce.py script check
878  * for the correct product
879  */
880  if ( out_p2vm==NULL && shutter[0]==1 && shutter[1]==1 && shutter[2]==0 & shutter[3]==0 )
881  {
882  out_p2vm = gravi_data_product_name (filename, "p2vm");
883  cpl_msg_info (cpl_func,"Use this filename for the P2VM product: %s",out_p2vm);
884  }
885  if ( out_visflat==NULL && shutter[0]==1 && shutter[1]==1 && shutter[2]==1 & shutter[3]==1 )
886  {
887  out_visflat = gravi_data_product_name (filename, "visflat");
888  cpl_msg_info (cpl_func,"Use this filename for the VIS_FLAT product: %s",out_visflat);
889  }
890 
891 
892  /*
893  * OPTIMIZE: the file 1-1-1-1 is not necessary if the p2vm_met is already done
894  * and thus should not be preproc
895  */
896 
897  /*
898  * If all shutter open and met_check is requested
899  * Then compute the p2vm of the metrology
900  */
901  if ((shutter[0] == 1) && (shutter[1] == 1) &&
902  (shutter[2] == 1) && (shutter[3] == 1) ) {
903 
904  /* If the metrology p2vm still has to be computed */
905  if (met_check && p2vm_met == NULL) {
906 
907  /* Verbose */
908  cpl_msg_info (cpl_func, "Compute the p2vm of the metrology");
909 
910  metrology_table = gravi_data_get_table(data, GRAVI_METROLOGY_EXT);
911  met_plist = cpl_propertylist_duplicate (gravi_data_get_propertylist(data,
912  GRAVI_METROLOGY_EXT));
913 
914  /* Compute the p2vm of the metrology */
915  opl_table = cpl_table_new ( cpl_table_get_nrow(metrology_table) );
916  p2vm_met = gravi_metrology_calibration (metrology_table, opl_table, 0);
917 
918  CPLCHECK_CLEAN("Error while computing p2vm of the metrology");
919 
920  met_check = 0;
921  } else {
922  cpl_msg_info (cpl_func, "Nothing to be done with the file.");
923  }
924 
925  /* Here we go to next file */
926  FREE( cpl_free, shutter );
927  // FREE( gravi_data_delete, data );
928  wave_data = data; data = NULL;
929  continue;
930  }
931  /* End if all shutters open and met_check requested */
932 
933  FREE( cpl_free, shutter );
934 
935  /*
936  * Preproc this file
937  */
938 
939  preproc_data = gravi_preproc(data, calib_datas, 4, NULL, parlist);
940  FREE( gravi_data_delete, data );
941 
942  /* Catch error */
943  CPLCHECK_CLEAN("Cannot preproc data");
944 
945  /*
946  * Eventually smooth the SC data
947  */
948 
949  /* If negative, use the default smoothing from spectral resolution */
950  nsmooth = gravi_get_nsmooth_for_p2vm (preproc_data, parlist);
951 
952  /* Smooth the data */
953  gravi_smooth_preproc (preproc_data, nsmooth);
954 
955  /*
956  * Construction of the p2vm data. Thus only once
957  * (def_p2vm - 0 if already done)
958  */
959  if (def_p2vm){
960 
961  /* Verbose*/
962  cpl_msg_info (cpl_func, "Construction of the p2vm map");
963 
964  p2vm_data = gravi_data_new(0);
965  p2vm_primary_hdr = cpl_propertylist_new ();
966 
967  /* Add the NSMOOTH parameter */
968  cpl_propertylist_append_int (p2vm_primary_hdr, "ESO QC P2VM NSMOOTH SC", nsmooth);
969  cpl_propertylist_set_comment(p2vm_primary_hdr, "ESO QC P2VM NSMOOTH SC", "number of smoothed spectral channels in P2VM computation");
970 
971 
972  /*
973  * Duplicate some common tables
974  */
975  for (j = 0; j < gravi_data_get_size (preproc_data); j++){
976  plist = gravi_data_get_propertylist_x (preproc_data, j);
977  const char * plist_name = gravi_pfits_get_extname (plist);
978  if (plist_name == NULL)
979  continue;
980 
981  type_data = gravi_pfits_get_extension_type (plist);
982 
983  if (!(strcmp (plist_name, INS_DESCRIPTION) &&
984  strcmp (plist_name, INS_TRAIN) &&
985  strcmp (plist_name, GRAVI_IMAGING_DETECTOR_FT_EXT) &&
986  strcmp (plist_name, GRAVI_IMAGING_DETECTOR_SC_EXT) &&
987  strcmp (plist_name, GRAVI_OI_WAVELENGTH_FT_EXT) &&
988  strcmp (plist_name, GRAVI_OI_WAVELENGTH_SC_EXT))) {
989  if (type_data == 2)
990  gravi_data_add (p2vm_data, plist,
991  cpl_table_duplicate (gravi_data_get_table_x(preproc_data, j)));
992  else if (type_data == 3)
993  gravi_data_add_cube (p2vm_data, plist,
994  cpl_imagelist_duplicate(gravi_data_get_cube_x(preproc_data, j)));
995  }
996  }
997 
998  /*
999  * Build the p2vm_table of SC
1000  */
1001 
1002  /* Check the number of region of FT to read the header */
1003  primary_hdr = gravi_data_get_propertylist(preproc_data,
1004  GRAVI_PRIMARY_HDR_NAME_EXT);
1005 
1006  detector_table = gravi_data_get_table (preproc_data, GRAVI_IMAGING_DETECTOR_SC_EXT);
1007  n_region = cpl_table_get_nrow(detector_table);
1008 
1009  oiwave_plist = gravi_data_get_oi_propertylist
1010  (preproc_data, GRAVI_OI_WAVELENGTH_SC_EXT, (n_region>24?SPECTRO_SC_P1:SPECTRO_SC) );
1011 
1012  /* Init the p2vm_table */
1013  cpl_propertylist * wave = gravi_data_get_propertylist(wave_map, GRAVI_WAVE_DATA_SC_EXT);
1014 
1015  n_wave = gravi_pfits_get_nwave(oiwave_plist);
1016 
1017  p2vm_table = gravi_p2vm_new(n_region, n_wave, n_tel);
1018  plist = cpl_propertylist_new();
1019  origin = gravi_pfits_get_origin (primary_hdr);
1020  cpl_propertylist_append_string(plist, "ORIGIN", origin);
1021  cpl_propertylist_append_int(plist, "NREGION", n_region);
1022  cpl_propertylist_append_int(plist, "NWAVE", n_wave);
1023  cpl_propertylist_append_string(plist, "EXTNAME", GRAVI_P2VM_DATA_SC_EXT);
1024  char * sc, *ft;
1025  int pair;
1026  for (pair = 0; pair < 6; pair ++){
1027 
1028  sc = cpl_sprintf("OPD SC COEFF SIGN (%d %d)",
1029  tel_1[pair]+1, tel_2[pair]+1);
1030 
1031  cpl_propertylist_append_float (plist, sc, cpl_propertylist_get_float (wave, sc));
1032  FREE (cpl_free,sc);
1033  }
1034 
1035  /* Add the p2vm_table of SC to the final p2vm_data set
1036  * Point to NULL since the table pertain to the p2vm_data */
1037  gravi_data_add (p2vm_data, plist, p2vm_table);
1038  p2vm_table = NULL;
1039 
1040  /*
1041  * Build the p2vm_table of FT
1042  */
1043 
1044  /* Check the number of region of FT to read the header */
1045  detector_table = gravi_data_get_table (preproc_data, GRAVI_IMAGING_DETECTOR_FT_EXT);
1046  n_region = cpl_table_get_nrow(detector_table);
1047 
1048  oiwave_plist = gravi_data_get_oi_propertylist
1049  (preproc_data, GRAVI_OI_WAVELENGTH_FT_EXT, (n_region>24?SPECTRO_FT_P1:SPECTRO_FT) );
1050 
1051  wave = gravi_data_get_propertylist (wave_map, GRAVI_WAVE_DATA_FT_EXT);
1052 
1053  /* Init the p2vm_table */
1054  n_wave = gravi_pfits_get_nwave(oiwave_plist);
1055 
1056  p2vm_table = gravi_p2vm_new(n_region, n_wave, n_tel);
1057 
1058  cpl_propertylist_set_int(plist, "NREGION", n_region);
1059  cpl_propertylist_set_int(plist, "NWAVE", n_wave);
1060  cpl_propertylist_set_string(plist, "EXTNAME", GRAVI_P2VM_DATA_FT_EXT);
1061 
1062  for (pair = 0; pair < 6; pair ++){
1063 
1064  ft = cpl_sprintf("OPD FT COEFF SIGN (%d %d)",
1065  tel_1[pair]+1, tel_2[pair]+1);
1066 
1067  cpl_propertylist_append_float (plist, ft,
1068  cpl_propertylist_get_float (wave, ft));
1069  FREE( cpl_free, ft);
1070  }
1071 
1072 
1073  /* Add the p2vm_table of FT to the final p2vm_data set
1074  * Point to NULL since the table pertain to the p2vm_data */
1075  gravi_data_add (p2vm_data, plist, p2vm_table);
1076  p2vm_table = NULL;
1077 
1078  /*
1079  * Add the primary header to the p2vm_datat set
1080  */
1081  gravi_data_set_propertylist (p2vm_data, GRAVI_PRIMARY_HDR_NAME_EXT, p2vm_primary_hdr);
1082  FREE (cpl_propertylist_delete,p2vm_primary_hdr);
1083 
1084  FREE (cpl_propertylist_delete,plist);
1085  def_p2vm = 0;
1086 
1087  }
1088  /* End construction of the p2vm */
1089 
1090  /*
1091  * Compute the part of the p2vm associated to this file
1092  */
1093  gravi_compute_p2vm (p2vm_data, preproc_data, 0, valid_trans, valid_CP);
1094 
1095  CPLCHECK_CLEAN("Cannot compute the P2VM");
1096 
1097  /* Option save the proproc file */
1098  if (cpl_parameter_get_bool(p)){
1099  cpl_msg_info ( cpl_func, "Save the preproc file as requested" );
1100 
1101  preproc_frame = cpl_frameset_new ();
1102  cpl_frameset_insert (preproc_frame, cpl_frame_duplicate (frame));
1103  preproc_name = gravi_data_product_name (filename, "preproc");
1104 
1105  applist = gravi_propertylist_get_qc (gravi_data_get_propertylist (preproc_data, GRAVI_PRIMARY_HDR_NAME_EXT));
1106  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, PREPROC);
1107  gravi_data_save(preproc_data, frameset, preproc_name, parlist, preproc_frame, frame, "gravi_all_p2vm", applist);
1108 
1109  FREE( cpl_propertylist_delete, applist);
1110  FREE( cpl_frameset_delete, preproc_frame);
1111  FREE( cpl_free, preproc_name);
1112  }
1113 
1114  /* Delete the preproc data */
1115  start = clock();
1116  FREE (gravi_data_delete,preproc_data);
1117  cpl_msg_info(cpl_func, "Execution time to delete preproc_data : %f s",
1118  (clock() - start) / (double)CLOCKS_PER_SEC);
1119 
1120  /* End loop on files to build the p2vm */
1121  }
1122 
1123  /*
1124  * Save the intermediate product
1125  */
1126  if ( cpl_parameter_get_bool(p) || 1 ) {
1127  cpl_msg_info (cpl_func, "Save the p2vm_data_norma file" );
1128  primary_hdr = gravi_data_get_propertylist (p2vm_data, GRAVI_PRIMARY_HDR_NAME_EXT);
1129  cpl_propertylist_append_string(primary_hdr, CPL_DFS_PRO_CATG, DEBUG);
1130  gravi_data_save_data (p2vm_data, "p2vm_data_norma.fits", CPL_IO_CREATE);
1131  }
1132 
1133  /*
1134  * (7) P2VM normalization
1135  */
1136 
1137  if ( gravi_param_get_bool(parlist, "gravi.normalize_p2vm") )
1138  {
1139  gravi_p2vm_normalisation (p2vm_data, valid_trans, valid_CP );
1140  CPLCHECK_CLEAN("Cannot normalise the p2vm_map");
1141  }
1142  else
1143  {
1144  cpl_msg_warning (cpl_func,"P2VM normalization skipped by user (normalize-p2vm=FALSE)");
1145  }
1146 
1147 
1148  /* Add the p2vm metrology field to the gravi_data
1149  * Point to NULL since the table pertain to the p2vm_data */
1150  if (met_check == 0) {
1151 
1152  cpl_msg_info (cpl_func, "Add the p2vm metrology field" );
1153 
1154  cpl_propertylist_set_string (met_plist, "EXTNAME", GRAVI_P2VM_MET_EXT);
1155  gravi_data_add (p2vm_data, met_plist, p2vm_met);
1156  p2vm_met=NULL;
1157 
1158  FREE (cpl_propertylist_delete,met_plist);
1159  }
1160 
1161 
1162  /*
1163  * (8) Compute the VIS_FLAT of the WAVE, to get an OIFITS file
1164  * with the instrumental imprint to remove them if needed.
1165  */
1166 
1167  cpl_msg_info (cpl_func, " ***** Analyse the WAVE file to correct the internal closure phases ***** ");
1168 
1169  cpl_msg_info (cpl_func, "Preproc the WAVE");
1170  preproc_data = gravi_preproc(wave_data, calib_datas, 4, p2vm_data, parlist);
1171  CPLCHECK_CLEAN("Cannot preproc the WAVE");
1172 
1173  /* Perform the phase calibration */
1174  int phase_flag = gravi_param_get_int (parlist, "gravi.phase_calibration");
1175  if (phase_flag > 0 ) {
1176 
1177  cpl_msg_info (cpl_func, "Extract the P2VMREDUCED of WAVE to calibrate the phases");
1178  p2vm_reduced = gravi_p2vm_reduce (preproc_data, p2vm_data, "gravi_single", parlist);
1179  CPLCHECK_CLEAN("Cannot apply p2vm");
1180 
1181  cpl_msg_info (cpl_func, "Recalibrate the phase of the P2VM");
1182  gravi_p2vm_phase_correction (p2vm_data, p2vm_reduced, phase_flag-1);
1183 
1184  FREE (gravi_data_delete, p2vm_reduced);
1185  CPLCHECK_CLEAN("Cannot recalibrate the P2VM phases");
1186 
1187  } else {
1188  cpl_msg_info (cpl_func, "P2VM phases are kept to zero (option phase-calibration=0)");
1189  }
1190 
1191  cpl_msg_info (cpl_func, " ***** Reduce the WAVE file to create the VIS_FLAT ***** ");
1192 
1193  cpl_msg_info (cpl_func, "Extract the P2VMREDUCED of WAVE as VIS_FLAT (again)...");
1194  p2vm_reduced = gravi_p2vm_reduce (preproc_data, p2vm_data, "gravi_single", parlist);
1195 
1196  cpl_msg_info (cpl_func, "Average the VIS_FLAT");
1197  oi_visflat = gravi_data_new(0);
1198  gravi_vis_reduce (oi_visflat, p2vm_reduced, 0, parlist, "gravi_single");
1199 
1200  cpl_msg_info (cpl_func, "Normalize the flux of the VIS_FLAT");
1201  gravi_normalize_flux (oi_visflat);
1202 
1203  CPLCHECK_CLEAN("Cannot average");
1204 
1205  cpl_msg_info (cpl_func, "Save the VIS_FLAT");
1206  applist = gravi_propertylist_get_qc (gravi_data_get_propertylist (oi_visflat, GRAVI_PRIMARY_HDR_NAME_EXT));
1207  cpl_propertylist_append_string (applist, CPL_DFS_PRO_CATG, VIS_FLAT);
1208  gravi_data_save (oi_visflat, frameset, out_visflat, parlist,
1209  p2vm_frameset, NULL, "gravi_all_p2vm", applist);
1210 
1211  CPLCHECK_CLEAN("Cannot save the VIS_FAT");
1212 
1213  /* Delete the computation of the VIS_FLAT */
1214  FREE (cpl_propertylist_delete, applist);
1215  FREE (gravi_data_delete, p2vm_reduced);
1216  FREE (gravi_data_delete, oi_visflat);
1217 
1218  CPLCHECK_CLEAN("Cannot delete");
1219 
1220 
1221  /*
1222  * (9) Create product frame, add DataFlow keywords, save the file, log the
1223  * saved file in the input frameset. Note that the output filename
1224  * is already created (from first P2VM file)
1225  */
1226 
1227  p2vm_plist = gravi_data_get_propertylist(p2vm_data, GRAVI_PRIMARY_HDR_NAME_EXT);
1228  applist = gravi_propertylist_get_qc (p2vm_plist);
1229 
1230  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, P2VM);
1231 
1232  gravi_data_save( p2vm_data, frameset, out_p2vm, parlist,
1233  p2vm_frameset, NULL, "gravi_all_p2vm", applist);
1234 
1235  CPLCHECK_CLEAN("Could not save the P2VM on the output file");
1236 
1237  /* Deallocation of all variables */
1238  cleanup:
1239  cpl_msg_info(cpl_func,"Cleanup memory");
1240  FREE (cpl_frameset_delete, dark_frameset);
1241  FREE (cpl_frameset_delete, darkcalib_frameset);
1242  FREE (cpl_frameset_delete, badpix_frameset);
1243  FREE (gravi_data_delete, p2vm_reduced);
1244  FREE (gravi_data_delete, oi_visflat);
1245  FREE (gravi_data_delete, wave_data);
1246  FREE (gravi_data_delete, dark_map);
1247  FREELOOP( gravi_data_delete, raw_data, nb_frame_gain);
1248  FREE (gravi_data_delete, badpix_map);
1249  FREE (cpl_propertylist_delete, met_plist);
1250  FREE (cpl_frameset_delete, wavecalib_frameset);
1251  FREE (cpl_frameset_delete, gaincalib_frameset);
1252  FREE (cpl_frameset_delete, gain_frameset);
1253  FREE (cpl_frameset_delete, wave_frameset);
1254  FREE (gravi_data_delete, data);
1255  FREE (gravi_data_delete, preproc_data);
1256  FREE (cpl_free, calib_datas);
1257  FREE (gravi_data_delete, dark_map);
1258  FREE (gravi_data_delete, wave_map);
1259  FREE (gravi_data_delete, profile_map);
1260  FREE (gravi_data_delete, badpix_map);
1261  FREELOOP (cpl_free, valid_CP, 2);
1262  FREELOOP (cpl_free, valid_trans, 2);
1263  FREE (cpl_free, out_visflat);
1264  FREE (cpl_free, out_p2vm);
1265  FREE (gravi_data_delete, p2vm_data);
1266  FREE (cpl_frameset_delete, p2vm_frameset);
1267  FREE (cpl_propertylist_delete, applist);
1268  FREE (cpl_table_delete, opl_table);
1269  FREE (cpl_table_delete, p2vm_met);
1270  FREE (cpl_free, shutter);
1271 
1272  CPLCHECK_INT("Could not cleanup memory");
1273 
1274  cpl_msg_info( cpl_func, "Exit function" );
1275  return (int)cpl_error_get_code();
1276 }
1277 
1278