GRAVI Pipeline Reference Manual  0.7.12
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", 1);
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  /* --STATE threshold for fringe DET in FT */
275  p = cpl_parameter_new_value("gravi.state_threshold_ft",
276  CPL_TYPE_DOUBLE, "STATE threshold for fringe detection in FT (>=0)", "gravi.vis_reduce", -1.0);
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  /* --Minimum locking ratio to accept SC frame */
283  p = cpl_parameter_new_value("gravi.fringedet_threshold_sc",
284  CPL_TYPE_DOUBLE, "Fringe-detection ratio threshold to accept SC frame (0..1)", "gravi.vis_reduce", 0.8);
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  /* --vFactor threshold to accept SC frame */
291  p = cpl_parameter_new_value("gravi.vfactor_threshold_sc",
292  CPL_TYPE_DOUBLE, "vFactor threshold to accept SC frame (0..1)", "gravi.vis_reduce", 0.0);
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  /* --Debias the V2 of SC */
299  p = cpl_parameter_new_value("gravi.debias_sc",
300  CPL_TYPE_BOOL, "Subtrast the V2 bias from SC", "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  /* --Debias the V2 of FT */
307  p = cpl_parameter_new_value("gravi.debias_ft",
308  CPL_TYPE_BOOL, "Subtrast the V2 bias from FT", "gravi", TRUE);
309  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
310  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
311  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CFG);
312  cpl_parameterlist_append(recipe->parameters, p);
313 
314  /* --Use the metrology -- should be TRUE because the WAVE is modulated */
315  p = cpl_parameter_new_value("gravi.use_met",
316  CPL_TYPE_BOOL, "Use the metrology to rephase the SC data", "gravi", TRUE);
317  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CLI);
318  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
319  cpl_parameter_disable(p, CPL_PARAMETER_MODE_CFG);
320  cpl_parameterlist_append(recipe->parameters, p);
321 
322  return 0;
323 }
324 
325 /*----------------------------------------------------------------------------*/
331 /*----------------------------------------------------------------------------*/
332 static int gravi_all_p2vm_exec(cpl_plugin * plugin)
333 {
334 
335  cpl_recipe * recipe;
336  int recipe_status;
337  cpl_errorstate initial_errorstate = cpl_errorstate_get();
338 
339  /* Return immediately if an error code is already set */
340  if (cpl_error_get_code() != CPL_ERROR_NONE) {
341  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
342  cpl_func, __LINE__, cpl_error_get_where());
343  return (int)cpl_error_get_code();
344  }
345 
346  if (plugin == NULL) {
347  cpl_msg_error(cpl_func, "Null plugin");
348  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
349  }
350 
351  /* Verify plugin type */
352  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
353  cpl_msg_error(cpl_func, "Plugin is not a recipe");
354  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
355  }
356 
357  /* Get the recipe */
358  recipe = (cpl_recipe *)plugin;
359 
360  /* Verify parameter and frame lists */
361  if (recipe->parameters == NULL) {
362  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
363  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
364  }
365  if (recipe->frames == NULL) {
366  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
367  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
368  }
369 
370  /* Invoke the recipe */
371  recipe_status = gravi_all_p2vm(recipe->frames, recipe->parameters);
372 
373  /* Ensure DFS-compliance of the products */
374  if (cpl_dfs_update_product_header(recipe->frames)) {
375  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
376  }
377 
378  if (!cpl_errorstate_is_equal(initial_errorstate)) {
379  /* Dump the error history since recipe execution start.
380  At this point the recipe cannot recover from the error */
381  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
382  }
383 
384  return recipe_status;
385 }
386 
387 /*----------------------------------------------------------------------------*/
393 /*----------------------------------------------------------------------------*/
394 static int gravi_all_p2vm_destroy(cpl_plugin * plugin)
395 {
396  cpl_recipe * recipe;
397 
398  if (plugin == NULL) {
399  cpl_msg_error(cpl_func, "Null plugin");
400  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
401  }
402 
403  /* Verify plugin type */
404  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
405  cpl_msg_error(cpl_func, "Plugin is not a recipe");
406  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
407  }
408 
409  /* Get the recipe */
410  recipe = (cpl_recipe *)plugin;
411 
412  cpl_parameterlist_delete(recipe->parameters);
413 
414  return 0;
415 }
416 
417 /*
418  * Browse the parameter list to get the nsmooth_SC parameter provided by user.
419  * If value is default (-1), then the default is returned depending on the
420  * spectral resolution.
421  */
422 int gravi_get_nsmooth_for_p2vm(gravi_data * data, const cpl_parameterlist * parlist)
423 {
424  int nsmooth;
425 
426  /* Get the nsmooth from parameter list */
427  nsmooth = cpl_parameter_get_int( cpl_parameterlist_find_const(parlist, "gravi.preproc_param.nsmooth_SC") );
428 
429  /* If valid, return it (0 is valid, means no smoothing) */
430  if (nsmooth >= 0 ) return nsmooth;
431 
432  /* Default from spectral resolution */
433  const char * resolution = gravi_pfits_get_spec_res (gravi_data_get_propertylist(data, GRAVI_PRIMARY_HDR_NAME_EXT));
434 
435  if ( !(strcmp(resolution, "HIGH")) ) {
436  cpl_msg_info(cpl_func,"Default smoothing is 15 (HIGH)");
437  nsmooth = 15;
438  }
439  else if ( !(strcmp(resolution, "MEDIUM")) ) {
440  cpl_msg_info(cpl_func,"Default smoothing is 3 (MEDIUM)");
441  nsmooth = 3;
442  }
443  else if ( !(strcmp(resolution, "LOW")) ) {
444  cpl_msg_info(cpl_func,"Default is no smoothing of data (LOW)");
445  nsmooth = 0;
446  } else {
447  cpl_msg_warning(cpl_func,"Unknown spectral resolution thus no smoothing of data");
448  nsmooth = 0;
449  }
450 
451  return nsmooth;
452 }
453 
454 /*----------------------------------------------------------------------------*/
462 /*----------------------------------------------------------------------------*/
463 static int gravi_all_p2vm(cpl_frameset * frameset,
464  const cpl_parameterlist * parlist)
465 {
466  cpl_frameset * p2vm_frameset=NULL, * wavecalib_frameset=NULL, * darkcalib_frameset=NULL,
467  * gaincalib_frameset=NULL, * dark_frameset=NULL, * wave_frameset=NULL,
468  * badpix_frameset=NULL, * gain_frameset=NULL;
469  cpl_propertylist * applist=NULL, * primary_hdr=NULL, * primary_hdr_dark=NULL, * p2vm_plist=NULL,
470  * primary_hdr_wave=NULL, * bad_primary_hdr=NULL, * profile_primary_hdr=NULL, * plist=NULL;
471  cpl_frame * frame=NULL;
472  const cpl_parameter * p=NULL;
473  char * out_dark=NULL, * out_wave=NULL, * preproc_name=NULL, * out_gain=NULL;
474  const char * filename=NULL, * origin=NULL, * acq_start=NULL;
475  gravi_data * p2vm_data=NULL, * data=NULL, * dark_map=NULL, * wave_map=NULL,
476  * profile_map=NULL, * badpix_map=NULL;
477  gravi_data ** calib_datas=NULL, * wave_data=NULL;
478  gravi_data * preproc_data=NULL;
479  gravi_data ** raw_data=NULL;
480  gravi_data * p2vm_reduced = NULL;
481  gravi_data * oi_visflat = NULL;
482 
483  int nb_frame, i, nb_frame_gain, j;
484  int rest;
485  double gain_ft, gain_sc, mjd_obs, acq_mjd;
486  int * shutter=NULL;
487  cpl_table * p2vm_met = NULL, * metrology_table=NULL, * opl_table = NULL, * detector_table=NULL,
488  *p2vm_table=NULL;
489  cpl_propertylist * met_plist=NULL;
490  cpl_frameset * preproc_frame=NULL;
491  int ** valid_trans = cpl_malloc (2 * sizeof (int*));
492  int ** valid_CP = cpl_malloc (2 * sizeof (int*)), type_data;
493  int n_tel = 4, n_wave, n_region;
494  cpl_propertylist * oiwave_plist=NULL;
495  int met_check = 1, def_p2vm = 1;
496  cpl_propertylist * p2vm_primary_hdr=NULL;
497  clock_t start, end;
498  int tel_1[6] = {0,0,0,1,1,2};
499  int tel_2[6] = {1,2,3,2,3,3};
500  int nsmooth;
501  char * out_p2vm = NULL, * out_visflat = NULL ;
502 
503  for (i = 0 ; i < 2; i++){
504  valid_trans[i] = cpl_calloc (4, sizeof (int));
505  valid_CP[i] = cpl_calloc (6, sizeof (int));
506  }
507 
508  /* Message */
509  cpl_msg_set_time_on();
510  cpl_msg_set_component_on();
511  cpl_msg_info(cpl_func,"Start function -- cleanup");
512 
513  /* Get the input frameset */
514  cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE, cpl_error_get_code()) ;
515 
516  /* Extract a set of frame p2vm and set of frame dark wave */
517  p2vm_frameset = gravi_frameset_extract_p2vm_data(frameset);
518  wavecalib_frameset = gravi_frameset_extract_wave_file(frameset);
519  darkcalib_frameset = gravi_frameset_extract_dark_file(frameset);
520  gaincalib_frameset = gravi_frameset_extract_flat_file(frameset);
521  wave_frameset = gravi_frameset_extract_wave(frameset);
522  dark_frameset = gravi_frameset_extract_dark(frameset);
523  gain_frameset = gravi_frameset_extract_flat(frameset);
524  badpix_frameset = gravi_frameset_extract_badpix(frameset);
525 
526  /* To use this recipe the frameset must contain at least
527  * one P2VM frame. */
528  if ( cpl_frameset_is_empty(p2vm_frameset) ) {
529  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT, "No P2VM frame on the frameset") ;
530  goto cleanup;
531  }
532 
533  /* To use this recipe the frameset must contain at least
534  * one FLAT frame. */
535  if (cpl_frameset_is_empty(gaincalib_frameset) && cpl_frameset_is_empty(gain_frameset) ) {
536  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT, "No FLAT file in the frameset") ;
537  goto cleanup;
538  }
539 
540  /* To use this recipe the frameset must contain at least
541  * one DARK frame. */
542  if (cpl_frameset_is_empty(darkcalib_frameset) && cpl_frameset_is_empty(dark_frameset) ) {
543  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT, "No DARK file in the frameset") ;
544  goto cleanup;
545  }
546 
547  /* To use this recipe the frameset must contain at least
548  * one WAVE frame. */
549  if (cpl_frameset_is_empty(wave_frameset) && cpl_frameset_is_empty(wavecalib_frameset) ) {
550  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT, "No WAVE file in the frameset") ;
551  goto cleanup;
552  }
553 
554  /*
555  * (1) Identify and extract the dark file
556  */
557  cpl_msg_info( cpl_func, " ***** Get dark map ***** " );
558 
559  if (!cpl_frameset_is_empty(dark_frameset)) {
560  /* The DARK in the frame_set is a raw dark */
561 
562  /* Verbose */
563  frame = cpl_frameset_get_position(dark_frameset, 0);
564  filename = cpl_frame_get_filename(frame);
565  cpl_msg_info (cpl_func, "This file %s is a raw DARK file", FILESHORT(filename));
566 
567  /* Load data */
568  data = gravi_data_load(filename);
569 
570  /* The DARK file must contains all the shutter close */
571  primary_hdr = gravi_data_get_propertylist(data, GRAVI_PRIMARY_HDR_NAME_EXT);
572  shutter = gravi_shutters_check(primary_hdr);
573  if (!((shutter[0] == 0) && (shutter[1] == 0) &&
574  (shutter[2] == 0) && (shutter[3] == 0))){
575  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT, "Shutter problem");
576  goto cleanup;
577  }
578 
579  /* Compute the DARK */
580  dark_map = gravi_compute_dark(data);
581 
582  CPLCHECK_INT("Cannot compute the DARK map");
583 
584  /* Add additional parameters */
585  cpl_frameset_insert(darkcalib_frameset, cpl_frame_duplicate(frame));
586  primary_hdr_dark = gravi_data_get_propertylist(dark_map, GRAVI_PRIMARY_HDR_NAME_EXT);
587  applist = gravi_propertylist_get_qc (primary_hdr_dark);
588  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, DARK);
589 
590  /* Build the output name */
591  // out_dark = cpl_sprintf("master_dark.%s", FILESHORT(filename));
592  out_dark = gravi_data_product_name (filename, "dark");
593 
594  /* Save the dark map */
595  gravi_data_save(dark_map, frameset, out_dark, parlist,
596  darkcalib_frameset, frame, "gravi_all_p2vm", applist);
597 
598  CPLCHECK_CLEAN("Could not save the DARK map");
599 
600  FREE( cpl_propertylist_delete, applist);
601  FREE( gravi_data_delete, data);
602  FREE( cpl_free, shutter);
603  FREE( cpl_free, out_dark);
604  }
605  else if (!cpl_frameset_is_empty(darkcalib_frameset)) {
606  /* The DARK in the frame_set is a calibrated dark */
607 
608  /* Verbose */
609  frame = cpl_frameset_get_position(darkcalib_frameset, 0);
610  cpl_frameset_insert (dark_frameset, cpl_frame_duplicate (frame));
611  filename = cpl_frame_get_filename(frame);
612  cpl_msg_info (cpl_func, "This file %s is a DARK file already computed", FILESHORT(filename));
613 
614  /* Load this DARK */
615  dark_map = gravi_data_load(filename);
616  }
617 
618  /* End check of DARK in the frameset */
619 
620  /*
621  * (2) Identify and extract the BADPIX file
622  */
623  cpl_msg_info( cpl_func, " ***** Get bad pixel map ***** " );
624 
625  if (!cpl_frameset_is_empty(badpix_frameset)){
626 
627  /* Verbose */
628  frame = cpl_frameset_get_position(badpix_frameset, 0);
629  filename = cpl_frame_get_filename(frame);
630  cpl_msg_info (cpl_func, "This file %s is a BAD pixel map", FILESHORT(filename));
631 
632  /* Load this BADPIX */
633  badpix_map = gravi_data_load(filename);
634 
635  }
636  else {
637  cpl_msg_info( cpl_func, "Compute the BAD pixel map from DARK" );
638 
639  /* If no BADPIX, compute it from the DARK */
640  badpix_map = gravi_compute_badpix(dark_map, parlist);
641 
642  CPLCHECK_INT("Cannot compute the BAD pixel from DARK");
643 
644  /* Additional parameters */
645  bad_primary_hdr = gravi_data_get_propertylist (badpix_map, GRAVI_PRIMARY_HDR_NAME_EXT);
646  applist = gravi_propertylist_get_qc (bad_primary_hdr);
647  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, BAD);
648 
649  /* Output file name */
650  frame = cpl_frameset_get_position (dark_frameset, 0);
651  filename = cpl_frame_get_filename (frame);
652  //out_dark = cpl_sprintf("badpix.%s", FILESHORT(filename));
653  out_dark = gravi_data_product_name (filename, "badpix");
654 
655  /* Save the BADPIX */
656  gravi_data_save (badpix_map, frameset, out_dark, parlist,
657  dark_frameset, frame, "gravi_all_p2vm", applist);
658 
659  CPLCHECK_CLEAN("Could not save the BAD pixel map");
660 
661  FREE( cpl_propertylist_delete, applist );
662  FREE( cpl_free, out_dark );
663 
664  }
665  /* End check of BADPIX in the frameset */
666 
667  FREE( cpl_frameset_delete, darkcalib_frameset);
668  FREE( cpl_frameset_delete, dark_frameset);
669  FREE( cpl_frameset_delete, badpix_frameset);
670 
671 
672  /*
673  * (3) Check that the gain map in the input frameset
674  */
675  cpl_msg_info( cpl_func, " ***** Get gain map ***** " );
676 
677  if ( (!cpl_frameset_is_empty(gain_frameset)) &&
678  (cpl_frameset_is_empty(gaincalib_frameset) ) ) {
679  cpl_msg_info( cpl_func, "Compute the profile map from FLAT files" );
680 
681  /* Identify the flat files */
682  nb_frame_gain = cpl_frameset_get_size (gain_frameset);
683  raw_data = cpl_malloc(nb_frame_gain * sizeof(gravi_data *));
684 
685  /* Build the list of FLAT files and output file name */
686  for (i = 0; i < nb_frame_gain; i++) {
687  frame = cpl_frameset_get_position(gain_frameset, i);
688  filename = cpl_frame_get_filename(frame);
689  raw_data[i] = gravi_data_load(filename);
690  primary_hdr = gravi_data_get_propertylist(raw_data[i],
691  GRAVI_PRIMARY_HDR_NAME_EXT);
692  shutter = gravi_shutters_check(primary_hdr);
693  FREE( cpl_free, shutter );
694  if (i == 0){
695  // out_gain = cpl_sprintf("master_profile.%s", FILESHORT(filename));
696  out_gain = gravi_data_product_name (filename, "flat");
697  }
698 
699  }
700 
701  /* Compute the profile from the list of FLAT */
702  profile_map = gravi_compute_profile(raw_data, dark_map, badpix_map,
703  nb_frame_gain, parlist);
704 
705  CPLCHECK_INT("Cannot compute the FLAT profile");
706 
707  /* Compute the gain and extract the gain map */
708  gain_sc = gravi_compute_gain(raw_data, nb_frame_gain, dark_map, badpix_map, GRAVI_IMAGING_DATA_SC_EXT);
709  cpl_msg_info (cpl_func, "QC_MEANGAIN_SC = %.4f [ADU/e-] Mean gain of SC detector", gain_sc);
710 
711  gain_ft = gravi_compute_gain(raw_data, nb_frame_gain, dark_map, badpix_map, GRAVI_IMAGING_DATA_FT_EXT);
712  cpl_msg_info (cpl_func, "QC_MEANGAIN_FT = %.4f [ADU/e-] Mean gain of FT detector", gain_ft);
713 
714  /* Save the profile map */
715  profile_primary_hdr = gravi_data_get_propertylist(profile_map, GRAVI_PRIMARY_HDR_NAME_EXT);
716  applist = gravi_propertylist_get_qc (profile_primary_hdr);
717  cpl_propertylist_append_double (applist, QC_MEANGAIN_FT, gain_ft);
718  cpl_propertylist_set_comment( applist, QC_MEANGAIN_FT, "[ADU/e-] Mean gain of FT detector" );
719  cpl_propertylist_append_double (applist, QC_MEANGAIN_SC, gain_sc);
720  cpl_propertylist_set_comment( applist, QC_MEANGAIN_SC, "[ADU/e-] Mean gain of SC detector" );
721  cpl_propertylist_append_string (applist, CPL_DFS_PRO_CATG, FLAT);
722 
723  frame = cpl_frameset_get_position(gain_frameset, 0);
724 
725  gravi_data_save(profile_map, frameset, out_gain, parlist,
726  gain_frameset, frame, "gravi_all_p2vm", applist);
727 
728  CPLCHECK_CLEAN("Could not save the FLAT profile_map");
729 
730  /* Free the list of files */
731  FREELOOP( gravi_data_delete, raw_data, nb_frame_gain );
732  FREE( cpl_propertylist_delete, applist );
733  FREE( cpl_free, out_gain );
734 
735  } else if (!cpl_frameset_is_empty(gaincalib_frameset)) {
736 
737  frame = cpl_frameset_get_position (gaincalib_frameset, 0);
738 
739  /* Verbose */
740  filename = cpl_frame_get_filename(frame);
741  cpl_msg_info (cpl_func, "This file %s is a FLAT file already computed", FILESHORT(filename));
742 
743  /* Load the profile map */
744  profile_map = gravi_data_load(filename);
745  }
746 
747  FREE( cpl_frameset_delete, gaincalib_frameset );
748  FREE( cpl_frameset_delete, gain_frameset );
749 
750  /* End check of GAIN in the frameset */
751 
752 
753 
754  /*
755  * (4) Check and get the WAVE frame
756  */
757  cpl_msg_info( cpl_func, " ***** Get wave map ***** " );
758 
759  if ((!cpl_frameset_is_empty(wave_frameset)) &&
760  (cpl_frameset_is_empty(wavecalib_frameset))) {
761  /* The WAVE in the frame_set is a raw wave */
762 
763  /* Verbose */
764  frame = cpl_frameset_get_position(wave_frameset, 0);
765  filename = cpl_frame_get_filename(frame);
766  cpl_msg_info (cpl_func, "This file %s is a raw WAVE file", FILESHORT(filename));
767 
768  /* Load this wave */
769  data = gravi_data_load(filename);
770  primary_hdr = gravi_data_get_propertylist(data, GRAVI_PRIMARY_HDR_NAME_EXT);
771  shutter = gravi_shutters_check(primary_hdr);
772 
773  /* Check the shutters */
774  if ( !((shutter[0] == 1) && (shutter[1] == 1) &&
775  (shutter[2] == 1) && (shutter[3] == 1)) ) {
776  cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT, "Shutter problem");
777  goto cleanup;
778  }
779 
780 
781  /* Compute the p2vm of the metrology if requested */
782  // p = cpl_parameterlist_find_const(parlist, "gravi.gravi_all_p2vm.opd_met");
783  // if ((cpl_parameter_get_bool (p)) && (met_check)){
784  if (met_check){
785 
786  /* Verbose */
787  cpl_msg_info( cpl_func, "Compute the p2vm of the metrology in the WAVE file");
788 
789  metrology_table = gravi_data_get_table(data, GRAVI_METROLOGY_EXT);
790  met_plist = cpl_propertylist_duplicate (gravi_data_get_propertylist(data, GRAVI_METROLOGY_EXT));
791 
792  start = clock();
793  opl_table = cpl_table_new (cpl_table_get_nrow(metrology_table));
794  p2vm_met = gravi_metrology_calibration (metrology_table, opl_table, 0);
795 
796  cpl_msg_info(cpl_func, "Execution time gravi_metrology_calibration : %f s",
797  (clock() - start) / (double)CLOCKS_PER_SEC);
798 
799  CPLCHECK_CLEAN("Error while computing p2vm of the metrology");
800  met_check = 0;
801  }
802  /* End computation of the p2vm of the metrology */
803 
804  /* Compute the WAVE table */
805  wave_map = gravi_compute_wave(data, profile_map, dark_map, badpix_map, opl_table, parlist);
806 
807  CPLCHECK_INT("Cannot compute the wave_map");
808 
809  /* Additional parameters */
810  primary_hdr_wave = gravi_data_get_propertylist(wave_map, GRAVI_PRIMARY_HDR_NAME_EXT);
811  applist = gravi_propertylist_get_qc (primary_hdr_wave);
812  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, WAVE);
813 
814  /* Output filename for WAVE */
815  out_wave = gravi_data_product_name (filename, "wave");
816 
817  /* Save the WAVE map */
818  gravi_data_save(wave_map, frameset, out_wave, parlist,
819  wave_frameset, frame, "gravi_all_p2vm", applist);
820 
821  CPLCHECK_CLEAN("Could not save the WAVE map");
822 
823  /* Free */
824  FREE( cpl_propertylist_delete, applist );
825  FREE( cpl_table_delete, opl_table );
826  FREE( gravi_data_delete, data );
827  FREE( cpl_free, shutter );
828  FREE( cpl_free, out_wave );
829 
830  } else if (!cpl_frameset_is_empty(wavecalib_frameset) ){
831  /* The WAVE in the frame_set is a calibrated dark */
832 
833  /* Verbose */
834  frame = cpl_frameset_get_position(wavecalib_frameset, 0);
835  filename = cpl_frame_get_filename(frame);
836  cpl_msg_info (cpl_func, "This file %s is a WAVE file already computed", FILESHORT(filename));
837 
838  /* Load this WAVE */
839  wave_map = gravi_data_load(filename);
840  }
841  /* End check of WAVE in the frameset */
842 
843  /* Copy the P2VM metrology from the master wave file if not computed by the recipe */
844  if ((gravi_data_has_extension (wave_map, GRAVI_P2VM_MET_EXT)) && (met_check)) {
845 
846  met_plist = cpl_propertylist_duplicate ( gravi_data_get_propertylist (wave_map, GRAVI_P2VM_MET_EXT));
847  p2vm_met = cpl_table_duplicate ( gravi_data_get_table (wave_map, GRAVI_P2VM_MET_EXT));
848  met_check = 0;
849 
850  }
851 
852  FREE( cpl_frameset_delete, wavecalib_frameset );
853  FREE( cpl_frameset_delete, wave_frameset );
854 
855  calib_datas = cpl_malloc(4 * sizeof(gravi_data *));
856  calib_datas[0] = dark_map;
857  calib_datas[1] = wave_map;
858  calib_datas[2] = profile_map;
859  calib_datas[3] = badpix_map;
860 
861  /* Get the parameter about preprocfile requested or not */
862  p = cpl_parameterlist_find_const(parlist, "gravi.preproc_param.preproc_file");
863 
864 
865  /*
866  * (6) Loop on files of the p2vm frameset
867  */
868 
869  /* Get the number of the p2vm frame contained in the frameset */
870  nb_frame = cpl_frameset_get_size(p2vm_frameset);
871 
872  for (i = 0; i < nb_frame; i++) {
873 
874  /* Build the filename */
875  frame = cpl_frameset_get_position(p2vm_frameset, i);
876  filename = cpl_frame_get_filename(frame);
877 
878  /* Verbose */
879  cpl_msg_info (cpl_func, " ***** file %d over %d ***** ", i+1, nb_frame );
880  cpl_msg_info (cpl_func, "Calibration of this file %s", FILESHORT(filename));
881 
882  /* Load data */
883  data = gravi_data_load(filename);
884  primary_hdr = gravi_data_get_propertylist(data, GRAVI_PRIMARY_HDR_NAME_EXT);
885 
886  /* Verbose the shutters */
887  shutter = gravi_shutters_check(primary_hdr);
888  cpl_msg_info( cpl_func, "Shutters: %d-%d-%d-%d",
889  shutter[0], shutter[1], shutter[2], shutter[3] );
890 
891  /*
892  * Create the product filename as the first P2VM file (1-1-0-0).
893  * This is to ensure the run_gravi_reduce.py script check
894  * for the correct product
895  */
896  if ( out_p2vm==NULL && shutter[0]==1 && shutter[1]==1 && shutter[2]==0 && shutter[3]==0 )
897  {
898  out_p2vm = gravi_data_product_name (filename, "p2vm");
899  cpl_msg_info (cpl_func,"Use this filename for the P2VM product: %s",out_p2vm);
900  }
901  if ( out_visflat==NULL && shutter[0]==1 && shutter[1]==1 && shutter[2]==1 && shutter[3]==1 )
902  {
903  out_visflat = gravi_data_product_name (filename, "visflat");
904  cpl_msg_info (cpl_func,"Use this filename for the VIS_FLAT product: %s",out_visflat);
905  }
906 
907 
908  /*
909  * OPTIMIZE: the file 1-1-1-1 is not necessary if the p2vm_met is already done
910  * and thus should not be preproc
911  */
912 
913  /*
914  * If all shutter open and met_check is requested
915  * Then compute the p2vm of the metrology
916  */
917  if ((shutter[0] == 1) && (shutter[1] == 1) &&
918  (shutter[2] == 1) && (shutter[3] == 1) ) {
919 
920  /* If the metrology p2vm still has to be computed */
921  if (met_check && p2vm_met == NULL) {
922 
923  /* Verbose */
924  cpl_msg_info (cpl_func, "Compute the p2vm of the metrology");
925 
926  metrology_table = gravi_data_get_table(data, GRAVI_METROLOGY_EXT);
927  met_plist = cpl_propertylist_duplicate (gravi_data_get_propertylist(data,
928  GRAVI_METROLOGY_EXT));
929 
930  /* Compute the p2vm of the metrology */
931  opl_table = cpl_table_new ( cpl_table_get_nrow(metrology_table) );
932  p2vm_met = gravi_metrology_calibration (metrology_table, opl_table, 0);
933 
934  CPLCHECK_CLEAN("Error while computing p2vm of the metrology");
935 
936  met_check = 0;
937  } else {
938  cpl_msg_info (cpl_func, "Nothing to be done with the file.");
939  }
940 
941  /* Here we go to next file */
942  FREE( cpl_free, shutter );
943  // FREE( gravi_data_delete, data );
944  wave_data = data; data = NULL;
945  continue;
946  }
947  /* End if all shutters open and met_check requested */
948 
949  FREE( cpl_free, shutter );
950 
951  /*
952  * Preproc this file
953  */
954 
955  preproc_data = gravi_preproc(data, calib_datas, 4, NULL, parlist);
956  FREE( gravi_data_delete, data );
957 
958  /* Catch error */
959  CPLCHECK_CLEAN("Cannot preproc data");
960 
961  /*
962  * Eventually smooth the SC data
963  */
964 
965  /* If negative, use the default smoothing from spectral resolution */
966  nsmooth = gravi_get_nsmooth_for_p2vm (preproc_data, parlist);
967 
968  /* Smooth the data */
969  gravi_smooth_preproc (preproc_data, nsmooth);
970 
971  /*
972  * Construction of the p2vm data. Thus only once
973  * (def_p2vm - 0 if already done)
974  */
975  if (def_p2vm){
976 
977  /* Verbose*/
978  cpl_msg_info (cpl_func, "Construction of the p2vm map");
979 
980  p2vm_data = gravi_data_new(0);
981  p2vm_primary_hdr = cpl_propertylist_new ();
982 
983  /* Add the NSMOOTH parameter */
984  cpl_propertylist_append_int (p2vm_primary_hdr, "ESO QC P2VM NSMOOTH SC", nsmooth);
985  cpl_propertylist_set_comment(p2vm_primary_hdr, "ESO QC P2VM NSMOOTH SC", "number of smoothed spectral channels in P2VM computation");
986 
987 
988  /*
989  * Duplicate some common tables
990  */
991  for (j = 0; j < gravi_data_get_size (preproc_data); j++){
992  plist = gravi_data_get_propertylist_x (preproc_data, j);
993  const char * plist_name = gravi_pfits_get_extname (plist);
994  if (plist_name == NULL)
995  continue;
996 
997  type_data = gravi_pfits_get_extension_type (plist);
998 
999  if (!(strcmp (plist_name, INS_DESCRIPTION) &&
1000  strcmp (plist_name, INS_TRAIN) &&
1001  strcmp (plist_name, GRAVI_IMAGING_DETECTOR_FT_EXT) &&
1002  strcmp (plist_name, GRAVI_IMAGING_DETECTOR_SC_EXT) &&
1003  strcmp (plist_name, GRAVI_OI_WAVELENGTH_FT_EXT) &&
1004  strcmp (plist_name, GRAVI_OI_WAVELENGTH_SC_EXT))) {
1005  if (type_data == 2)
1006  gravi_data_add (p2vm_data, plist,
1007  cpl_table_duplicate (gravi_data_get_table_x(preproc_data, j)));
1008  else if (type_data == 3)
1009  gravi_data_add_cube (p2vm_data, plist,
1010  cpl_imagelist_duplicate(gravi_data_get_cube_x(preproc_data, j)));
1011  }
1012  }
1013 
1014  /*
1015  * Build the p2vm_table of SC
1016  */
1017 
1018  /* Check the number of region of FT to read the header */
1019  primary_hdr = gravi_data_get_propertylist(preproc_data,
1020  GRAVI_PRIMARY_HDR_NAME_EXT);
1021 
1022  detector_table = gravi_data_get_table (preproc_data, GRAVI_IMAGING_DETECTOR_SC_EXT);
1023  n_region = cpl_table_get_nrow(detector_table);
1024 
1025  oiwave_plist = gravi_data_get_oi_propertylist
1026  (preproc_data, GRAVI_OI_WAVELENGTH_SC_EXT, (n_region>24?SPECTRO_SC_P1:SPECTRO_SC) );
1027 
1028  /* Init the p2vm_table */
1029  cpl_propertylist * wave = gravi_data_get_propertylist(wave_map, GRAVI_WAVE_DATA_SC_EXT);
1030 
1031  n_wave = gravi_pfits_get_nwave(oiwave_plist);
1032 
1033  p2vm_table = gravi_p2vm_new(n_region, n_wave, n_tel);
1034  plist = cpl_propertylist_new();
1035  origin = gravi_pfits_get_origin (primary_hdr);
1036  cpl_propertylist_append_string(plist, "ORIGIN", origin);
1037  cpl_propertylist_append_int(plist, "NREGION", n_region);
1038  cpl_propertylist_append_int(plist, "NWAVE", n_wave);
1039  cpl_propertylist_append_string(plist, "EXTNAME", GRAVI_P2VM_DATA_SC_EXT);
1040  char * sc, *ft;
1041  int pair;
1042 
1043  sc = "OPD SC COEFF SIGN";
1044  cpl_propertylist_append_float (plist, sc, cpl_propertylist_get_float (wave, sc));
1045 
1046  /* Add the p2vm_table of SC to the final p2vm_data set
1047  * Point to NULL since the table pertain to the p2vm_data */
1048  gravi_data_add (p2vm_data, plist, p2vm_table);
1049  p2vm_table = NULL;
1050 
1051  /*
1052  * Build the p2vm_table of FT
1053  */
1054 
1055  /* Check the number of region of FT to read the header */
1056  detector_table = gravi_data_get_table (preproc_data, GRAVI_IMAGING_DETECTOR_FT_EXT);
1057  n_region = cpl_table_get_nrow(detector_table);
1058 
1059  oiwave_plist = gravi_data_get_oi_propertylist
1060  (preproc_data, GRAVI_OI_WAVELENGTH_FT_EXT, (n_region>24?SPECTRO_FT_P1:SPECTRO_FT) );
1061 
1062  wave = gravi_data_get_propertylist (wave_map, GRAVI_WAVE_DATA_FT_EXT);
1063 
1064  /* Init the p2vm_table */
1065  n_wave = gravi_pfits_get_nwave(oiwave_plist);
1066 
1067  p2vm_table = gravi_p2vm_new(n_region, n_wave, n_tel);
1068 
1069  cpl_propertylist_set_int(plist, "NREGION", n_region);
1070  cpl_propertylist_set_int(plist, "NWAVE", n_wave);
1071  cpl_propertylist_set_string(plist, "EXTNAME", GRAVI_P2VM_DATA_FT_EXT);
1072 
1073  ft = "OPD FT COEFF SIGN";
1074  cpl_propertylist_append_float (plist, ft, cpl_propertylist_get_float (wave, ft));
1075 
1076  /* Add the p2vm_table of FT to the final p2vm_data set
1077  * Point to NULL since the table pertain to the p2vm_data */
1078  gravi_data_add (p2vm_data, plist, p2vm_table);
1079  p2vm_table = NULL;
1080 
1081  /*
1082  * Add the primary header to the p2vm_datat set
1083  */
1084  gravi_data_set_propertylist (p2vm_data, GRAVI_PRIMARY_HDR_NAME_EXT, p2vm_primary_hdr);
1085  FREE (cpl_propertylist_delete,p2vm_primary_hdr);
1086 
1087  FREE (cpl_propertylist_delete,plist);
1088  def_p2vm = 0;
1089 
1090  }
1091  /* End construction of the p2vm */
1092 
1093  /*
1094  * Compute the part of the p2vm associated to this file
1095  */
1096  gravi_compute_p2vm (p2vm_data, preproc_data, 0, valid_trans, valid_CP);
1097 
1098  CPLCHECK_CLEAN("Cannot compute the P2VM");
1099 
1100  /* Option save the proproc file */
1101  if (cpl_parameter_get_bool(p)){
1102  cpl_msg_info ( cpl_func, "Save the preproc file as requested" );
1103 
1104  preproc_frame = cpl_frameset_new ();
1105  cpl_frameset_insert (preproc_frame, cpl_frame_duplicate (frame));
1106  preproc_name = gravi_data_product_name (filename, "preproc");
1107 
1108  applist = gravi_propertylist_get_qc (gravi_data_get_propertylist (preproc_data, GRAVI_PRIMARY_HDR_NAME_EXT));
1109  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, PREPROC);
1110  gravi_data_save(preproc_data, frameset, preproc_name, parlist, preproc_frame, frame, "gravi_all_p2vm", applist);
1111 
1112  FREE( cpl_propertylist_delete, applist);
1113  FREE( cpl_frameset_delete, preproc_frame);
1114  FREE( cpl_free, preproc_name);
1115  }
1116 
1117  /* Delete the preproc data */
1118  start = clock();
1119  FREE (gravi_data_delete,preproc_data);
1120  cpl_msg_info(cpl_func, "Execution time to delete preproc_data : %f s",
1121  (clock() - start) / (double)CLOCKS_PER_SEC);
1122 
1123  /* End loop on files to build the p2vm */
1124  }
1125 
1126  /*
1127  * Save the intermediate product
1128  */
1129  if ( cpl_parameter_get_bool(p) || 1 ) {
1130  cpl_msg_info (cpl_func, "Save the p2vm_data_norma file" );
1131  primary_hdr = gravi_data_get_propertylist (p2vm_data, GRAVI_PRIMARY_HDR_NAME_EXT);
1132  cpl_propertylist_append_string(primary_hdr, CPL_DFS_PRO_CATG, DEBUG);
1133  gravi_data_save_data (p2vm_data, "p2vm_data_norma.fits", CPL_IO_CREATE);
1134  }
1135 
1136  /*
1137  * (7) P2VM normalization
1138  */
1139 
1140  if ( gravi_param_get_bool(parlist, "gravi.normalize_p2vm") )
1141  {
1142  gravi_p2vm_normalisation (p2vm_data, valid_trans, valid_CP );
1143  CPLCHECK_CLEAN("Cannot normalise the p2vm_map");
1144  }
1145  else
1146  {
1147  cpl_msg_warning (cpl_func,"P2VM normalization skipped by user (normalize-p2vm=FALSE)");
1148  }
1149 
1150 
1151  /* Add the p2vm metrology field to the gravi_data
1152  * Point to NULL since the table pertain to the p2vm_data */
1153  if (met_check == 0) {
1154 
1155  cpl_msg_info (cpl_func, "Add the p2vm metrology field" );
1156 
1157  cpl_propertylist_set_string (met_plist, "EXTNAME", GRAVI_P2VM_MET_EXT);
1158  gravi_data_add (p2vm_data, met_plist, p2vm_met);
1159  p2vm_met=NULL;
1160 
1161  FREE (cpl_propertylist_delete,met_plist);
1162  }
1163 
1164 
1165  /*
1166  * (8) Compute the VIS_FLAT of the WAVE, to get an OIFITS file
1167  * with the instrumental imprint to remove them if needed.
1168  */
1169 
1170  cpl_msg_info (cpl_func, " ***** Analyse the WAVE file to correct the internal closure phases ***** ");
1171 
1172  cpl_msg_info (cpl_func, "Preproc the WAVE");
1173  preproc_data = gravi_preproc(wave_data, calib_datas, 4, p2vm_data, parlist);
1174  CPLCHECK_CLEAN("Cannot preproc the WAVE");
1175 
1176  /* Perform the phase calibration */
1177  int phase_flag = gravi_param_get_int (parlist, "gravi.phase_calibration");
1178  if (phase_flag > 0 ) {
1179 
1180  cpl_msg_info (cpl_func, "Extract the P2VMREDUCED of WAVE to calibrate the phases");
1181  p2vm_reduced = gravi_p2vm_reduce (preproc_data, p2vm_data, "gravi_single", parlist);
1182  CPLCHECK_CLEAN("Cannot apply p2vm");
1183 
1184  cpl_msg_info (cpl_func, "Recalibrate the phase of the P2VM");
1185  gravi_p2vm_phase_correction (p2vm_data, p2vm_reduced, phase_flag-1);
1186 
1187  FREE (gravi_data_delete, p2vm_reduced);
1188  CPLCHECK_CLEAN("Cannot recalibrate the P2VM phases");
1189 
1190  } else {
1191  cpl_msg_info (cpl_func, "P2VM phases are kept to zero (option phase-calibration=0)");
1192  }
1193 
1194  cpl_msg_info (cpl_func, " ***** Reduce the WAVE file to create the VIS_FLAT ***** ");
1195 
1196  cpl_msg_info (cpl_func, "Extract the P2VMREDUCED of WAVE as VIS_FLAT (again)...");
1197  p2vm_reduced = gravi_p2vm_reduce (preproc_data, p2vm_data, "gravi_single", parlist);
1198 
1199  cpl_msg_info (cpl_func, "Average the VIS_FLAT");
1200  oi_visflat = gravi_data_new(0);
1201  gravi_vis_reduce (oi_visflat, p2vm_reduced, 0, parlist, "gravi_single");
1202 
1203  cpl_msg_info (cpl_func, "Normalize the flux of the VIS_FLAT");
1204  gravi_normalize_flux (oi_visflat);
1205 
1206  CPLCHECK_CLEAN("Cannot average");
1207 
1208  cpl_msg_info (cpl_func, "Save the VIS_FLAT");
1209  applist = gravi_propertylist_get_qc (gravi_data_get_propertylist (oi_visflat, GRAVI_PRIMARY_HDR_NAME_EXT));
1210  cpl_propertylist_append_string (applist, CPL_DFS_PRO_CATG, VIS_FLAT);
1211  gravi_data_save (oi_visflat, frameset, out_visflat, parlist,
1212  p2vm_frameset, NULL, "gravi_all_p2vm", applist);
1213 
1214  CPLCHECK_CLEAN("Cannot save the VIS_FAT");
1215 
1216  /* Delete the computation of the VIS_FLAT */
1217  FREE (cpl_propertylist_delete, applist);
1218  FREE (gravi_data_delete, p2vm_reduced);
1219  FREE (gravi_data_delete, oi_visflat);
1220 
1221  CPLCHECK_CLEAN("Cannot delete");
1222 
1223 
1224  /*
1225  * (9) Create product frame, add DataFlow keywords, save the file, log the
1226  * saved file in the input frameset. Note that the output filename
1227  * is already created (from first P2VM file)
1228  */
1229 
1230  p2vm_plist = gravi_data_get_propertylist(p2vm_data, GRAVI_PRIMARY_HDR_NAME_EXT);
1231  applist = gravi_propertylist_get_qc (p2vm_plist);
1232 
1233  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, P2VM);
1234 
1235  gravi_data_save( p2vm_data, frameset, out_p2vm, parlist,
1236  p2vm_frameset, NULL, "gravi_all_p2vm", applist);
1237 
1238  CPLCHECK_CLEAN("Could not save the P2VM on the output file");
1239 
1240  /* Deallocation of all variables */
1241  cleanup:
1242  cpl_msg_info(cpl_func,"Cleanup memory");
1243  FREE (cpl_frameset_delete, dark_frameset);
1244  FREE (cpl_frameset_delete, darkcalib_frameset);
1245  FREE (cpl_frameset_delete, badpix_frameset);
1246  FREE (gravi_data_delete, p2vm_reduced);
1247  FREE (gravi_data_delete, oi_visflat);
1248  FREE (gravi_data_delete, wave_data);
1249  FREE (gravi_data_delete, dark_map);
1250  FREELOOP( gravi_data_delete, raw_data, nb_frame_gain);
1251  FREE (gravi_data_delete, badpix_map);
1252  FREE (cpl_propertylist_delete, met_plist);
1253  FREE (cpl_frameset_delete, wavecalib_frameset);
1254  FREE (cpl_frameset_delete, gaincalib_frameset);
1255  FREE (cpl_frameset_delete, gain_frameset);
1256  FREE (cpl_frameset_delete, wave_frameset);
1257  FREE (gravi_data_delete, data);
1258  FREE (gravi_data_delete, preproc_data);
1259  FREE (cpl_free, calib_datas);
1260  FREE (gravi_data_delete, dark_map);
1261  FREE (gravi_data_delete, wave_map);
1262  FREE (gravi_data_delete, profile_map);
1263  FREE (gravi_data_delete, badpix_map);
1264  FREELOOP (cpl_free, valid_CP, 2);
1265  FREELOOP (cpl_free, valid_trans, 2);
1266  FREE (cpl_free, out_visflat);
1267  FREE (cpl_free, out_p2vm);
1268  FREE (gravi_data_delete, p2vm_data);
1269  FREE (cpl_frameset_delete, p2vm_frameset);
1270  FREE (cpl_propertylist_delete, applist);
1271  FREE (cpl_table_delete, opl_table);
1272  FREE (cpl_table_delete, p2vm_met);
1273  FREE (cpl_free, shutter);
1274 
1275  CPLCHECK_INT("Could not cleanup memory");
1276 
1277  cpl_msg_info( cpl_func, "Exit function" );
1278  return (int)cpl_error_get_code();
1279 }
1280 
1281