GRAVI Pipeline Reference Manual  0.9.7
gravity_piezo.c
1 /* $Id: gravity_vis.c,v 1.29 2011/12/3 09:16:12 nazouaoui Exp $
2  *
3  * This file is part of the GRAVI Pipeline
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: nazouaoui $
23  * $Date: 2011/12/3 09:16:12 $
24  * $Revision: 1.29 $
25  * $Name: $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include <cpl.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <time.h>
40 
41 #include "gravi_data.h"
42 #include "gravi_pfits.h"
43 #include "gravi_dfs.h"
44 
45 #include "gravi_utils.h"
46 
47 #include "gravi_calib.h"
48 #include "gravi_p2vmred.h"
49 #include "gravi_eop.h"
50 #include "gravi_metrology.h"
51 
52 #include "gravi_signal.h"
53 #include "gravi_vis.h"
54 #include "gravi_tf.h"
55 
56 #include "gravi_preproc.h"
57 // #include "gravi_p2vm.h"
58 
59 /*-----------------------------------------------------------------------------
60  Private function prototypes
61  -----------------------------------------------------------------------------*/
62 
63 static int gravity_piezo_create(cpl_plugin *);
64 static int gravity_piezo_exec(cpl_plugin *);
65 static int gravity_piezo_destroy(cpl_plugin *);
66 static int gravity_piezo(cpl_frameset *, const cpl_parameterlist *);
67 
68 /*-----------------------------------------------------------------------------
69  Static variables
70  -----------------------------------------------------------------------------*/
71 
72 static char gravity_piezo_short[] = GRAVI_UNOFFERED"Calibrate the response of the piezo actuators.";
73 static char gravity_piezo_description[] = GRAVI_UNOFFERED"This recipe compute the response (open loop transfer function) of the piezo actuators used to fringe-track in GRAVITY.\n"
74  GRAVI_RECIPE_INPUT"\n"
75  GRAVI_FLAT_MAP" : flat calibration (PRO.CATG="GRAVI_FLAT_MAP")\n"
76  GRAVI_BAD_MAP" : badpixel calibration (PRO.CATG="GRAVI_BAD_MAP") \n"
77  GRAVI_WAVE_MAP" : wave calibration (PRO.CATG="GRAVI_WAVE_MAP")\n"
78  GRAVI_P2VM_MAP" : p2vm calibration (PRO.CATG="GRAVI_P2VM_MAP")\n"
79  GRAVI_DARK_MAP" : dark calibration (PRO.CATG="GRAVI_DARK_MAP")\n"
80  GRAVI_PIEZOTF_RAW" : dedicated observations \n"
81  GRAVI_RECIPE_OUTPUT"\n"
82  GRAVI_PIEZOTF_MAP" : Respose of the piezo\n"
83  "";
84 
85 /*-----------------------------------------------------------------------------
86  Function code
87  -----------------------------------------------------------------------------*/
88 
89 /*----------------------------------------------------------------------------*/
99 /*----------------------------------------------------------------------------*/
100 int cpl_plugin_get_info(cpl_pluginlist * list)
101 {
102  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
103  cpl_plugin * plugin = &recipe->interface;
104 
105  if (cpl_plugin_init(plugin,
106  CPL_PLUGIN_API,
107  GRAVI_BINARY_VERSION,
108  CPL_PLUGIN_TYPE_RECIPE,
109  "gravity_piezo",
110  gravity_piezo_short,
111  gravity_piezo_description,
112  "Nabih Azouaoui, Vincent Lapeyrere, JB. Le Bouquin",
113  PACKAGE_BUGREPORT,
114  gravi_get_license(),
115  gravity_piezo_create,
116  gravity_piezo_exec,
117  gravity_piezo_destroy)) {
118  cpl_msg_error(cpl_func, "Plugin initialization failed");
119  (void)cpl_error_set_where(cpl_func);
120  return 1;
121  }
122 
123  if (cpl_pluginlist_append(list, plugin)) {
124  cpl_msg_error(cpl_func, "Error adding plugin to list");
125  (void)cpl_error_set_where(cpl_func);
126  return 1;
127  }
128 
129  return 0;
130 }
131 
132 /*----------------------------------------------------------------------------*/
140 /*----------------------------------------------------------------------------*/
141 static int gravity_piezo_create(cpl_plugin * plugin)
142 {
143  cpl_recipe * recipe;
144  // cpl_parameter * p;
145 
146  /* Do not create the recipe if an error code is already set */
147  if (cpl_error_get_code() != CPL_ERROR_NONE) {
148  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
149  cpl_func, __LINE__, cpl_error_get_where());
150  return (int)cpl_error_get_code();
151  }
152 
153  if (plugin == NULL) {
154  cpl_msg_error(cpl_func, "Null plugin");
155  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
156  }
157 
158  /* Verify plugin type */
159  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
160  cpl_msg_error(cpl_func, "Plugin is not a recipe");
161  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
162  }
163 
164  /* Get the recipe */
165  recipe = (cpl_recipe *)plugin;
166 
167  /* Create the parameters list in the cpl_recipe object */
168  recipe->parameters = cpl_parameterlist_new();
169  if (recipe->parameters == NULL) {
170  cpl_msg_error(cpl_func, "Parameter list allocation failed");
171  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
172  }
173 
174  /* Fill the parameters list */
175  int isCalib = 1;
176 
177  /* Use static names (output_procatg.fits) */
178  gravi_parameter_add_static_name (recipe->parameters);
179 
180  /* Intermediate files */
181  gravi_parameter_add_biassub_file (recipe->parameters);
182  gravi_parameter_add_preproc_file (recipe->parameters);
183 
184  /* Snr */
185  gravi_parameter_add_compute_snr (recipe->parameters, isCalib);
186 
187  /* Rejection */
188  gravi_parameter_add_rejection (recipe->parameters, isCalib);
189 
190  /* Parameters for gravi_compute_vis */
191  gravi_parameter_add_compute_vis (recipe->parameters, isCalib);
192 
193  return 0;
194 }
195 
196 /*----------------------------------------------------------------------------*/
202 /*----------------------------------------------------------------------------*/
203 static int gravity_piezo_exec(cpl_plugin * plugin)
204 {
205 
206  cpl_recipe * recipe;
207  int recipe_status;
208  cpl_errorstate initial_errorstate = cpl_errorstate_get();
209 
210 
211  /* Return immediately if an error code is already set */
212  if (cpl_error_get_code() != CPL_ERROR_NONE) {
213  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
214  cpl_func, __LINE__, cpl_error_get_where());
215  return (int)cpl_error_get_code();
216  }
217 
218  if (plugin == NULL) {
219  cpl_msg_error(cpl_func, "Null plugin");
220  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
221  }
222 
223  /* Verify plugin type */
224  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
225  cpl_msg_error(cpl_func, "Plugin is not a recipe");
226  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
227  }
228 
229  /* Get the recipe */
230  recipe = (cpl_recipe *)plugin;
231 
232  /* Verify parameter and frame lists */
233  if (recipe->parameters == NULL) {
234  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
235  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
236  }
237  if (recipe->frames == NULL) {
238  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
239  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
240  }
241 
242  /* Invoke the recipe */
243  recipe_status = gravity_piezo(recipe->frames, recipe->parameters);
244 
245  /* Ensure DFS-compliance of the products */
246  if (cpl_dfs_update_product_header(recipe->frames)) {
247  if (!recipe_status){
248  recipe_status = (int)cpl_error_get_code();
249  }
250  }
251 
252  if (!cpl_errorstate_is_equal(initial_errorstate)) {
253  /* Dump the error history since recipe execution start.
254  At this point the recipe cannot recover from the error */
255  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
256  }
257 
258  return recipe_status;
259 }
260 
261 /*----------------------------------------------------------------------------*/
267 /*----------------------------------------------------------------------------*/
268 static int gravity_piezo_destroy(cpl_plugin * plugin)
269 {
270  cpl_recipe * recipe;
271 
272  if (plugin == NULL) {
273  cpl_msg_error(cpl_func, "Null plugin");
274  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
275  }
276 
277  /* Verify plugin type */
278  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
279  cpl_msg_error(cpl_func, "Plugin is not a recipe");
280  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
281  }
282 
283  /* Get the recipe */
284  recipe = (cpl_recipe *)plugin;
285 
286  cpl_parameterlist_delete(recipe->parameters);
287 
288  return 0;
289 }
290 
291 
292 /*----------------------------------------------------------------------------*/
300 /*----------------------------------------------------------------------------*/
301 static int gravity_piezo(cpl_frameset * frameset,
302  const cpl_parameterlist * parlist)
303 {
304  cpl_frameset * recipe_frameset=NULL, * wavecalib_frameset=NULL, * dark_frameset=NULL,
305  * darkcalib_frameset=NULL, * flatcalib_frameset=NULL, * p2vmcalib_frameset=NULL,
306  * badcalib_frameset=NULL, *used_frameset=NULL, * current_frameset=NULL;
307 
308  cpl_frame * frame=NULL;
309 
310  gravi_data * p2vm_map=NULL, * data=NULL, * wave_map=NULL, * dark_map=NULL,
311  * profile_map=NULL, * badpix_map=NULL, * preproc_data=NULL, * p2vmred_data=NULL, * oi_vis=NULL;
312 
313  int nb_vis, nb_frame;
314 
315  /* Message */
316  gravity_print_banner ();
317  cpl_msg_set_time_on();
318  cpl_msg_set_component_on();
319  gravi_msg_function_start(1);
320 
321  cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
322  cpl_error_get_code()) ;
323 
324  /* Dispatch the frameset */
325  p2vmcalib_frameset = gravi_frameset_extract_p2vm_map (frameset);
326  darkcalib_frameset = gravi_frameset_extract_dark_map (frameset);
327  wavecalib_frameset = gravi_frameset_extract_wave_map (frameset);
328  dark_frameset = gravi_frameset_extract_dark_data (frameset);
329  flatcalib_frameset = gravi_frameset_extract_flat_map (frameset);
330  badcalib_frameset = gravi_frameset_extract_bad_map (frameset);
331 
332  recipe_frameset = gravi_frameset_extract_piezotf_data (frameset);
333 
334  /* To use this recipe the frameset must contain the p2vm, wave and
335  * gain calibration file. */
336  if ( cpl_frameset_get_size (p2vmcalib_frameset) !=1 ||
337  cpl_frameset_get_size (wavecalib_frameset) !=1 ||
338  cpl_frameset_get_size (flatcalib_frameset) !=1 ||
339  cpl_frameset_get_size (badcalib_frameset) != 1 ||
340  cpl_frameset_get_size (recipe_frameset) < 1 ||
341  (cpl_frameset_is_empty (dark_frameset) &&
342  cpl_frameset_is_empty (darkcalib_frameset) )) {
343  cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
344  "Illegal number of P2VM, FLAT, WAVE, BAD, DARK, PIEZOTF file on the frameset");
345  goto cleanup;
346  }
347 
348  /* Insert calibration frame into the used frameset */
349  used_frameset = cpl_frameset_new();
350 
351  /*
352  * Identify the DARK in the input frameset
353  */
354 
355  if (!cpl_frameset_is_empty (dark_frameset)) {
356 
357  frame = cpl_frameset_get_position (dark_frameset, 0);
358  data = gravi_data_load_rawframe (frame, used_frameset);
359  gravi_data_detector_cleanup (data, parlist);
360 
361  /* Compute dark */
362  dark_map = gravi_compute_dark (data);
363  FREE (gravi_data_delete, data);
364 
365  CPLCHECK_CLEAN ("Could not compute the DARK map");
366 
367  /* Save the dark map */
368  gravi_data_save_new (dark_map, frameset, NULL, parlist,
369  NULL, frame, "gravity_piezo",
370  NULL, GRAVI_DARK_MAP);
371 
372  CPLCHECK_CLEAN ("Could not save the DARK map");
373  }
374  else if (!cpl_frameset_is_empty (darkcalib_frameset)) {
375 
376  frame = cpl_frameset_get_position (darkcalib_frameset, 0);
377  dark_map = gravi_data_load_frame (frame, used_frameset);
378 
379  CPLCHECK_CLEAN ("Could not load the DARK map");
380  }
381  else
382  cpl_msg_info (cpl_func, "There is no DARK in the frame set");
383 
384  /* Identify the BAD in the input frameset */
385  frame = cpl_frameset_get_position (badcalib_frameset, 0);
386  badpix_map = gravi_data_load_frame (frame, used_frameset);
387 
388  /* Identify the FLAT in the input frameset */
389  frame = cpl_frameset_get_position (flatcalib_frameset, 0);
390  profile_map = gravi_data_load_frame (frame, used_frameset);
391 
392  /* Identify the WAVE in the input frameset */
393  frame = cpl_frameset_get_position (wavecalib_frameset, 0);
394  wave_map = gravi_data_load_frame (frame, used_frameset);
395 
396  /* Identify the P2VM in the input frameset */
397  frame = cpl_frameset_get_position (p2vmcalib_frameset, 0);
398  p2vm_map = gravi_data_load_frame (frame, used_frameset);
399 
400  /*
401  * Loop on input RAW frames to be reduced
402  */
403 
404  nb_vis = 0;
405  oi_vis = gravi_data_new(0);
406 
407  nb_frame = cpl_frameset_get_size (recipe_frameset);
408 
409  for (int thread = 0; thread < nb_frame; thread++){
410  current_frameset = cpl_frameset_duplicate (used_frameset);
411 
412  cpl_msg_info (cpl_func, " ***** OBJECT %d over %d ***** ", thread+1, nb_frame);
413 
414  /*
415  * Reduce the OBJECT
416  */
417 
418  frame = cpl_frameset_get_position (recipe_frameset, thread);
419  data = gravi_data_load_rawframe (frame, current_frameset);
420  gravi_data_detector_cleanup (data, parlist);
421 
422  /* Option save the preproc file */
423  if (gravi_param_get_bool (parlist,"gravity.dfs.bias-subtracted-file")) {
424 
425  gravi_data_save_new (data, frameset, NULL, parlist,
426  current_frameset, frame, "gravity_piezo",
427  NULL, "BIAS_SUBTRACTED");
428 
429  CPLCHECK_CLEAN ("Cannot save the BIAS_SUBTRACTED product");
430  }
431 
432 
433  /* Check the shutters */
434  if ( !gravi_data_check_shutter_open (data) ) {
435  cpl_msg_warning (cpl_func, "Shutter problem in the OBJECT");
436  }
437 
438  /* Extract spectrum */
439  preproc_data = gravi_extract_spectrum (data, profile_map, dark_map,
440  badpix_map, NULL, parlist);
441  CPLCHECK_CLEAN ("Cannot extract spectrum");
442 
443  /* Rescale to common wavelength */
444  gravi_align_spectrum (preproc_data, wave_map, p2vm_map);
445  CPLCHECK_CLEAN ("Cannot re-interpolate spectrum");
446 
447  /* Move extensions from raw_data */
448  gravi_data_move_ext (preproc_data, data, GRAVI_ARRAY_GEOMETRY_EXT);
449  gravi_data_move_ext (preproc_data, data, GRAVI_OPTICAL_TRAIN_EXT);
450  gravi_data_move_ext (preproc_data, data, GRAVI_OPDC_EXT);
451  gravi_data_move_ext (preproc_data, data, GRAVI_FDDL_EXT);
452  gravi_data_move_ext (preproc_data, data, GRAVI_METROLOGY_EXT);
453  FREE (gravi_data_delete, data);
454  CPLCHECK_CLEAN ("Cannot move ext");
455 
456  /* Option save the preproc file */
457  if (gravi_param_get_bool (parlist,"gravity.dfs.preproc-file")) {
458 
459  gravi_data_save_new (preproc_data, frameset, NULL, parlist,
460  current_frameset, frame, "gravity_piezo",
461  NULL, GRAVI_PREPROC);
462 
463  CPLCHECK_CLEAN ("Cannot save the PREPROC product");
464  }
465 
466  /* Compute the flux and visibilities for each telescope and
467  * per acquisition with the P2VM applied to preproc_data */
468  p2vmred_data = gravi_compute_p2vmred (preproc_data, p2vm_map, "single", parlist);
469  CPLCHECK_CLEAN ("Cannot apply p2vm to the preproc data");
470 
471  /* Move extensions and delete preproc */
472  gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_METROLOGY_EXT);
473  gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_FDDL_EXT);
474  gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_OPDC_EXT);
475  FREE (gravi_data_delete, preproc_data);
476  CPLCHECK_CLEAN ("Cannot delete preproc");
477 
478  /* Reduce the OPDC table */
479  gravi_compute_opdc_state (p2vmred_data);
480  CPLCHECK_CLEAN ("Cannot reduce OPDC");
481 
482  /* Reduce the metrology */
483  gravi_metrology_reduce (p2vmred_data);
484  CPLCHECK_CLEAN ("Cannot reduce metrology");
485 
486  /* Compute the SNR_SMT and GDELAY_SMT columns */
487  gravi_compute_snr (p2vmred_data, parlist);
488  CPLCHECK_MSG ("Cannot compute SNR");
489 
490  /* Compute the additional signals for averaging */
491  gravi_compute_signals (p2vmred_data, NULL, parlist);
492  CPLCHECK_MSG ("Cannot compute signals");
493 
494  /* Compute rejection flags for averaging */
495  gravi_compute_rejection (p2vmred_data, parlist);
496  CPLCHECK_MSG ("Cannot rejection flags signals");
497 
498  /* Add here your computation of QC */
499 
500  /* Save the PIEZOTF which is in fact a P2VMREDUCED */
501  gravi_data_save_new (p2vmred_data, frameset, NULL, parlist,
502  current_frameset, frame, "gravity_piezo", NULL, "PIEZOTF");
503 
504  CPLCHECK_CLEAN ("Cannot save the PIEZOTF product");
505 
506  nb_vis++;
507  cpl_msg_info (cpl_func,"Free the p2vmreduced");
508  FREE (cpl_frameset_delete, current_frameset);
509  FREE (gravi_data_delete, p2vmred_data);
510  }
511  /* End loop on the input files to reduce */
512 
513  /* Terminate the function */
514  goto cleanup;
515 
516 cleanup:
517  /* Deallocation of all variables */
518  cpl_msg_info(cpl_func,"Memory cleanup");
519 
520  FREE (gravi_data_delete,dark_map);
521  FREE (gravi_data_delete,data);
522  FREE (gravi_data_delete,preproc_data);
523  FREE (gravi_data_delete,profile_map);
524  FREE (gravi_data_delete,wave_map);
525  FREE (gravi_data_delete,badpix_map);
526  FREE (gravi_data_delete,p2vm_map);
527  FREE (gravi_data_delete,p2vmred_data);
528  FREE (gravi_data_delete,oi_vis);
529  FREE (cpl_frameset_delete,darkcalib_frameset);
530  FREE (cpl_frameset_delete,wavecalib_frameset);
531  FREE (cpl_frameset_delete,flatcalib_frameset);
532  FREE (cpl_frameset_delete,badcalib_frameset);
533  FREE (cpl_frameset_delete,p2vmcalib_frameset);
534  FREE (cpl_frameset_delete,dark_frameset);
535  FREE (cpl_frameset_delete,recipe_frameset);
536  FREE (cpl_frameset_delete,current_frameset);
537  FREE (cpl_frameset_delete,used_frameset);
538 
539  gravi_msg_function_exit(1);
540  return (int)cpl_error_get_code();
541 }