GRAVI Pipeline Reference Manual 1.9.3
Loading...
Searching...
No Matches
gravity_vis.c
Go to the documentation of this file.
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 * History
28 * 12/11/2018 add static_param_frameset
29 * 26/11/2018 add static_param_frameset to call of gravi_reduce_acqcam
30 */
31
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36/*-----------------------------------------------------------------------------
37 Includes
38 -----------------------------------------------------------------------------*/
39
40#include <cpl.h>
41#include <stdio.h>
42#include <string.h>
43#include <time.h>
44#if defined(__linux__) && defined(__GLIBC__)
45#include <malloc.h> //Needed for malloc_trim()
46#endif
47
48#include "gravi_data.h"
49#include "gravi_pfits.h"
50#include "gravi_dfs.h"
51
52#include "gravi_utils.h"
53
54#include "gravi_calib.h"
55#include "gravi_wave.h"
56#include "gravi_p2vmred.h"
57#include "gravi_acqcam.h"
58#include "gravi_eop.h"
59#include "gravi_metrology.h"
60#include "gravi_demodulate.h"
61
62#include "gravi_signal.h"
63#include "gravi_vis.h"
64#include "gravi_tf.h"
65
66#include "gravi_preproc.h"
67
68/*-----------------------------------------------------------------------------
69 Private function prototypes
70 -----------------------------------------------------------------------------*/
71
72static int gravity_vis_create(cpl_plugin *);
73static int gravity_vis_exec(cpl_plugin *);
74static int gravity_vis_destroy(cpl_plugin *);
75static int gravity_vis(cpl_frameset *, cpl_parameterlist *);
76
77/*-----------------------------------------------------------------------------
78 Static variables
79 -----------------------------------------------------------------------------*/
80static char gravity_vis_short[] = "Compute the visibilities from raw observation of OBJECT.";
82 "This recipe is associated to the observations template. Its reduces the raw data acquired on calibrator or science targets and computes the uncalibrated visibilities, saved in an OIFITS file. If several OBJECT are provided, the recipe will reduce all of them and merge the resulting data into a single OIFITS. If several SKY_RAW are provided, the recipe reduces the first OBJECT with the first SKY file. Then each new OBJECT with the next SKY. When the number of SKYs is reached, the recipe loops back to first SKY file (so if the number of SKYs is larger than the number of OBJECTs, the last SKY won't be used). The recipe will reduce the data even if no SKY or no DARK is provided. However this will lead to wrong estimate of the visibility and squared visibility of the object. If the file DIAMETER_CAT is not provided, the recipe will use the diameter provided in the header to compute the transfer function QC parameters."
83 "\n"
84 "The tag in the DO category can be SINGLE/DUAL and CAL/SCI. They should reflect the instrument mode (SINGLE or DUAL) and the DPR.CATG of the observation (SCIENCE or CALIB). The tag in the PRO.CATG category will be SINGLE/DUAL and CAL/SCI depending on the input tag.\n"
86 "* Load the input file (loop on input OBJECT files)\n"
87 "* Extract the spectra (use BAD, DARK, SKY, FLAT files)\n"
88 "* Interpolate the spectra into a common wavelength table (use WAVE file)\n"
89 "* Compute the real-time visibilities (use P2VM file)\n"
90 "* Compute additional real-time signals (SNR, GDELAY...)\n"
91 "* Compute selection flags (= flag frames with SNR lower than threshold, vFactor lower than threshold...)\n"
92 "* Average the real-time visibilities, considering the selection flag\n"
93 "* Write the product\n"
95 GRAVI_FLAT_MAP" : flat calibration (PRO.CATG="GRAVI_FLAT_MAP")\n"
96 GRAVI_BAD_MAP" : badpixel calibration (PRO.CATG="GRAVI_BAD_MAP") \n"
97 GRAVI_WAVE_MAP" : wave calibration (PRO.CATG="GRAVI_WAVE_MAP")\n"
98 GRAVI_P2VM_MAP" : p2vm calibration (PRO.CATG="GRAVI_P2VM_MAP")\n"
99 GRAVI_DARK_MAP" : dark calibration (PRO.CATG="GRAVI_DARK_MAP")\n"
100 GRAVI_SINGLE_SCIENCE_RAW" : raw object (DPR.TYPE=OBJECT,SINGLE)\n"
101 GRAVI_SINGLE_SKY_RAW" : raw sky (DPR.TYPE=SKY,SINGLE)\n"
102 GRAVI_DISP_MODEL" (opt) : fiber dispersion model (PRO.CATG="GRAVI_DISP_MODEL")\n"
103 GRAVI_DIODE_POSITION" (opt) : met receiver position (PRO.CATG="GRAVI_DIODE_POSITION")\n"
104 GRAVI_DIAMETER_CAT" (opt) : catalog of diameter (PRO.CATG="GRAVI_DIAMETER_CAT")\n"
106 GRAVI_VIS_SINGLE_SCIENCE" : OIFITS file with uncalibrated visibilities\n"
107 GRAVI_SINGLE_SKY_MAP" (opt) : sky map\n"
108 GRAVI_P2VMRED_SINGLE_SCIENCE" (opt) : intermediate product (see detailled description of data)\n"
109 GRAVI_SPECTRUM" (opt) : intermediate product (see detailled description of data)\n"
110 GRAVI_PREPROC" (opt) : intermediate product (see detailled description of data)\n"
111 "";
112
113/*-----------------------------------------------------------------------------
114 Function code
115 -----------------------------------------------------------------------------*/
116
117/*----------------------------------------------------------------------------*/
127/*----------------------------------------------------------------------------*/
128int cpl_plugin_get_info(cpl_pluginlist * list)
129{
130 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
131 cpl_plugin * plugin = &recipe->interface;
132
133 if (cpl_plugin_init(plugin,
134 CPL_PLUGIN_API,
135 GRAVI_BINARY_VERSION,
136 CPL_PLUGIN_TYPE_RECIPE,
137 "gravity_vis",
140 "Nabih Azouaoui, Vincent Lapeyrere, JB. Le Bouquin",
141 PACKAGE_BUGREPORT,
146 cpl_msg_error(cpl_func, "Plugin initialization failed");
147 (void)cpl_error_set_where(cpl_func);
148 return 1;
149 }
150
151 if (cpl_pluginlist_append(list, plugin)) {
152 cpl_msg_error(cpl_func, "Error adding plugin to list");
153 (void)cpl_error_set_where(cpl_func);
154 return 1;
155 }
156
157 return 0;
158}
159
160/*----------------------------------------------------------------------------*/
168/*----------------------------------------------------------------------------*/
169static int gravity_vis_create(cpl_plugin * plugin)
170{
171 cpl_recipe * recipe;
172 cpl_parameter * p;
173
174 /* Do not create the recipe if an error code is already set */
175 if (cpl_error_get_code() != CPL_ERROR_NONE) {
176 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
177 cpl_func, __LINE__, cpl_error_get_where());
178 return (int)cpl_error_get_code();
179 }
180
181 if (plugin == NULL) {
182 cpl_msg_error(cpl_func, "Null plugin");
183 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
184 }
185
186 /* Verify plugin type */
187 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
188 cpl_msg_error(cpl_func, "Plugin is not a recipe");
189 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
190 }
191
192 /* Get the recipe */
193 recipe = (cpl_recipe *)plugin;
194
195 /* Create the parameters list in the cpl_recipe object */
196 recipe->parameters = cpl_parameterlist_new();
197 if (recipe->parameters == NULL) {
198 cpl_msg_error(cpl_func, "Parameter list allocation failed");
199 cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
200 }
201
202 /* Fill the parameters list */
203 int isCalib = 0;
204
205 /* Use static names (output_procatg.fits) */
206 gravi_parameter_add_static_name (recipe->parameters);
207
208 /* Intermediate files */
209 gravi_parameter_add_biassub_file (recipe->parameters);
210 gravi_parameter_add_spectrum_file (recipe->parameters);
211 gravi_parameter_add_preproc_file (recipe->parameters);
212 gravi_parameter_add_p2vmred_file (recipe->parameters);
213 gravi_parameter_add_astro_file (recipe->parameters);
214
215 /* PCA visphi flattening */
216 gravi_parameter_add_pca (recipe->parameters);
217
218 /* Averaging */
219 gravi_parameter_add_average_vis (recipe->parameters);
220
221 /* Bias-method */
222 gravi_parameter_add_biasmethod (recipe->parameters);
223
224 /* Extraction */
225 //gravi_parameter_add_extract (recipe->parameters); // need to get the param from the p2vm
226 gravi_parameter_add_metrology (recipe->parameters);
227 // gravi_parameter_add_preproc (recipe->parameters); // now automatically handled in the preproc
228
229 /* Snr, signal, rejectio flags, vis */
230 gravi_parameter_add_compute_snr (recipe->parameters);
231 gravi_parameter_add_compute_signal (recipe->parameters);
232 gravi_parameter_add_rejection (recipe->parameters, isCalib);
233 gravi_parameter_add_compute_vis (recipe->parameters, isCalib);
234
235 /* Correct from internal transmission */
236 p = cpl_parameter_new_value ("gravity.vis.flat-flux", CPL_TYPE_BOOL,
237 "Normalize the flux (stored in OI_FLUX binary extension) with "
238 "instrument transmission recorded in the \n"
239 "input P2VM calibration map. Consequently, the flux quantity is either "
240 "the intensity level recorded \n"
241 "in the detector, thus including the instrument transmission (FALSE); "
242 "or the intensity level at the instrument entrance (TRUE).",
243 "gravity.vis", FALSE);
244 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI, "flat-flux");
245 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
246 cpl_parameterlist_append (recipe->parameters, p);
247
248 /* Average sky */
249 p = cpl_parameter_new_value ("gravity.preproc.average-sky", CPL_TYPE_BOOL,
250 "Average the SKYs into a master SKY. If FALSE, the recipe loops\n "
251 "over the SKY to reduce each OBJECT with a different SKY",
252 "gravity.preproc", FALSE);
253 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI, "average-sky");
254 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
255 cpl_parameterlist_append (recipe->parameters, p);
256
257 /* Reduce ACQ_CAM */
258 p = cpl_parameter_new_value ("gravity.test.reduce-acq-cam", CPL_TYPE_BOOL,
259 "If TRUE, reduced ACQ_CAM images",
260 "gravity.test", FALSE);
261 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI, "reduce-acq-cam");
262 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
263 cpl_parameterlist_append (recipe->parameters, p);
264
265 /* Wave color correction */
266 p = cpl_parameter_new_value ("gravity.vis.color-wave-correction", CPL_TYPE_BOOL,
267 "If TRUE, creates a new OI_WAVELENGTH_EFF with corrected wavelength",
268 "gravity.vis", FALSE);
269 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI, "color-wave-correction");
270 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
271 cpl_parameterlist_append (recipe->parameters, p);
272
273 /* OIFITS format */
274 p = cpl_parameter_new_value ("gravity.vis.oifits2", CPL_TYPE_BOOL,
275 "If TRUE, the output products will be fully OIFITS2 compliant. "
276 "Note that TRUE will be the default and eventually the "
277 "parameter will be removed in the future",
278 "gravity.vis", FALSE);
279 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI, "oifits2");
280 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
281 cpl_parameterlist_append (recipe->parameters, p);
282
283 return 0;
284}
285
286/*----------------------------------------------------------------------------*/
292/*----------------------------------------------------------------------------*/
293static int gravity_vis_exec(cpl_plugin * plugin)
294{
295
296 cpl_recipe * recipe;
297 int recipe_status;
298 cpl_errorstate initial_errorstate = cpl_errorstate_get();
299
300
301 /* Return immediately if an error code is already set */
302 if (cpl_error_get_code() != CPL_ERROR_NONE) {
303 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
304 cpl_func, __LINE__, cpl_error_get_where());
305 return (int)cpl_error_get_code();
306 }
307
308 if (plugin == NULL) {
309 cpl_msg_error(cpl_func, "Null plugin");
310 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
311 }
312
313 /* Verify plugin type */
314 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
315 cpl_msg_error(cpl_func, "Plugin is not a recipe");
316 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
317 }
318
319 /* Get the recipe */
320 recipe = (cpl_recipe *)plugin;
321
322 /* Verify parameter and frame lists */
323 if (recipe->parameters == NULL) {
324 cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
325 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
326 }
327 if (recipe->frames == NULL) {
328 cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
329 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
330 }
331
332 /* Invoke the recipe */
333 recipe_status = gravity_vis(recipe->frames, recipe->parameters);
334
335 /* Ensure DFS-compliance of the products */
336 if (cpl_dfs_update_product_header(recipe->frames)) {
337 if (!recipe_status){
338 recipe_status = (int)cpl_error_get_code();
339 }
340 }
341
342 if (!cpl_errorstate_is_equal(initial_errorstate)) {
343 /* Dump the error history since recipe execution start.
344 At this point the recipe cannot recover from the error */
345 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
346 }
347
348 return recipe_status;
349}
350
351/*----------------------------------------------------------------------------*/
357/*----------------------------------------------------------------------------*/
358static int gravity_vis_destroy(cpl_plugin * plugin)
359{
360 cpl_recipe * recipe;
361
362 if (plugin == NULL) {
363 cpl_msg_error(cpl_func, "Null plugin");
364 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
365 }
366
367 /* Verify plugin type */
368 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
369 cpl_msg_error(cpl_func, "Plugin is not a recipe");
370 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
371 }
372
373 /* Get the recipe */
374 recipe = (cpl_recipe *)plugin;
375
376 cpl_parameterlist_delete(recipe->parameters);
377
378 return 0;
379}
380
381
382/*----------------------------------------------------------------------------*/
390/*----------------------------------------------------------------------------*/
391static int gravity_vis(cpl_frameset * frameset,
392 cpl_parameterlist * parlist)
393{
394 cpl_frameset * recipe_frameset=NULL, * wavecalib_frameset=NULL, * dark_frameset=NULL,
395 * darkcalib_frameset=NULL, * sky_frameset=NULL, * flatcalib_frameset=NULL, * p2vmcalib_frameset=NULL,
396 * badcalib_frameset=NULL, *used_frameset=NULL, * current_frameset=NULL, * dispcalib_frameset=NULL,
397 * metpos_frameset=NULL, * diamcat_frameset = NULL, *eop_frameset = NULL, *patch_frameset = NULL,
398 * static_param_frameset=NULL, * pcacalib_frameset = NULL;
399
400 cpl_frame * frame=NULL;
401
402 const char * frame_tag=NULL;
403 char * proCatg = NULL, * mode=NULL, * redCatg = NULL, * skyCatg = NULL;
404
405 gravi_data * p2vm_map=NULL, * data=NULL, * wave_map=NULL, * dark_map=NULL,
406 * profile_map=NULL, * badpix_map=NULL, * preproc_data=NULL, * p2vmred_data=NULL, * tmpvis_data=NULL,
407 * vis_data=NULL, * disp_map=NULL, * diodepos_data=NULL, * diamcat_data=NULL, *eop_map=NULL,
408 * static_param_data=NULL, * pca_calib_data=NULL;
409 gravi_data ** sky_maps = NULL;
410 cpl_propertylist ** p2vm_qcs = NULL;
411
412 int nb_frame, nb_sky;
413
414 /* Message */
417
418 cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
419 cpl_error_get_code()) ;
420
421 /* Dispatch the frameset */
422 p2vmcalib_frameset = gravi_frameset_extract_p2vm_map (frameset);
423 darkcalib_frameset = gravi_frameset_extract_dark_map (frameset);
424 wavecalib_frameset = gravi_frameset_extract_wave_map (frameset);
425 dark_frameset = gravi_frameset_extract_dark_data (frameset);
426 flatcalib_frameset = gravi_frameset_extract_flat_map (frameset);
427 badcalib_frameset = gravi_frameset_extract_bad_map (frameset);
428 dispcalib_frameset = gravi_frameset_extract_disp_map (frameset);
429 pcacalib_frameset = gravi_frameset_extract_pca_calib (frameset);
430 metpos_frameset = gravi_frameset_extract_met_pos (frameset);
431 diamcat_frameset = gravi_frameset_extract_diamcat_map (frameset);
432 eop_frameset = gravi_frameset_extract_eop_map (frameset);
433 patch_frameset = gravi_frameset_extract_patch (frameset);
434 static_param_frameset = gravi_frameset_extract_static_param (frameset);
435
436 recipe_frameset = gravi_frameset_extract_fringe_data (frameset);
437 sky_frameset = gravi_frameset_extract_sky_data (frameset);
438
439 /* To use this recipe the frameset must contain the p2vm, wave and
440 * gain calibration file. */
441 if ( cpl_frameset_get_size (p2vmcalib_frameset) !=1 ||
442 cpl_frameset_get_size (wavecalib_frameset) !=1 ||
443 cpl_frameset_get_size (flatcalib_frameset) !=1 ||
444 cpl_frameset_get_size (badcalib_frameset) != 1 ||
445 cpl_frameset_get_size (recipe_frameset) < 1 ||
446 (cpl_frameset_is_empty (dark_frameset) &&
447 cpl_frameset_is_empty (darkcalib_frameset) &&
448 cpl_frameset_is_empty (sky_frameset)) ) {
449 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
450 "Illegal number of P2VM, FLAT, WAVE, BAD, DARK or SKY, OBJECT file on the frameset");
451 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
452 "See online help: esorex --man gravity_vis");
453 goto cleanup;
454 }
455
456 /* Force some options if phase flattening is to be performed */
457 if (gravi_param_get_bool (parlist, "gravity.vis.flatten-visphi")) {
458 cpl_parameter *phase_ref = cpl_parameterlist_find (parlist, "gravity.vis.phase-ref-sc");
459 cpl_parameter *output_phase = cpl_parameterlist_find (parlist, "gravity.vis.output-phase-sc");
460
461 if (strcmp (cpl_parameter_get_string(phase_ref), "SELF_REF") != 0) {
462 cpl_msg_warning (cpl_func, "VISPHI flattening requires phase-ref-sc=SELF_REF, forcing");
463 cpl_parameter_set_string (phase_ref, "SELF_REF");
464 }
465
466 if (strcmp (cpl_parameter_get_string(output_phase), "SELF_VISPHI") != 0) {
467 cpl_msg_warning (cpl_func, "VISPHI flattening requires output-phase-sc=SELF_VISPHI, forcing");
468 cpl_parameter_set_string (output_phase, "SELF_VISPHI");
469 }
470 }
471
472 /* Insert calibration frame into the used frameset */
473 used_frameset = cpl_frameset_new();
474
475 /*
476 * Identify the DARK in the input frameset
477 */
478
479 if (!cpl_frameset_is_empty (dark_frameset)) {
480
481 frame = cpl_frameset_get_position (dark_frameset, 0);
482 data = gravi_data_load_rawframe (frame, used_frameset);
483 gravi_data_patch (data, patch_frameset);
484 gravi_data_detector_cleanup (data, parlist);
485
486 /* Compute dark */
487 dark_map = gravi_compute_dark (data);
488 FREE (gravi_data_delete, data);
489
490 CPLCHECK_CLEAN ("Could not compute the DARK map");
491
492 /* Save the dark map */
493 gravi_data_save_new (dark_map, frameset, NULL, NULL, parlist,
494 NULL, frame, "gravity_vis",
495 NULL, GRAVI_DARK_MAP);
496
497 CPLCHECK_CLEAN ("Could not save the DARK map");
498 }
499 else if (!cpl_frameset_is_empty (darkcalib_frameset)) {
500
501 frame = cpl_frameset_get_position (darkcalib_frameset, 0);
502 dark_map = gravi_data_load_frame (frame, used_frameset);
503
504 CPLCHECK_CLEAN ("Could not load the DARK map");
505 }
506 else
507 cpl_msg_info (cpl_func, "There is no DARK in the frame set");
508
509 /* Identify the BAD in the input frameset */
510 frame = cpl_frameset_get_position (badcalib_frameset, 0);
511 badpix_map = gravi_data_load_frame (frame, used_frameset);
512
513 /* Identify the FLAT in the input frameset */
514 frame = cpl_frameset_get_position (flatcalib_frameset, 0);
515 profile_map = gravi_data_load_frame (frame, used_frameset);
516
517 /* Identify the WAVE in the input frameset */
518 frame = cpl_frameset_get_position (wavecalib_frameset, 0);
519 wave_map = gravi_data_load_frame (frame, used_frameset);
520
521 /* Identify the P2VM in the input frameset */
522 frame = cpl_frameset_get_position (p2vmcalib_frameset, 0);
523 p2vm_map = gravi_data_load_frame (frame, used_frameset);
524 cpl_parameter * param_extrapixel = gravi_pfits_get_extrapixel_param(gravi_data_get_header(p2vm_map));
525 cpl_parameterlist_append(parlist, param_extrapixel);
526
527 /* Load the DISP_MODEL in the input frameset */
528 if (!cpl_frameset_is_empty (dispcalib_frameset)) {
529 frame = cpl_frameset_get_position (dispcalib_frameset, 0);
530 disp_map = gravi_data_load_frame (frame, used_frameset);
531 }
532 else
533 cpl_msg_info (cpl_func, "There is no DISP_MODEL in the frameset");
534
535 /* Load the DIODE_POSITION in the input frameset */
536 if (!cpl_frameset_is_empty (metpos_frameset)) {
537 frame = cpl_frameset_get_position (metpos_frameset, 0);
538 diodepos_data = gravi_data_load_frame (frame, used_frameset);
539 }
540 else
541 cpl_msg_info (cpl_func, "There is no DIODE_POSITION in the frameset");
542
543 /* Load the EOP_PARAM */
544 if ( !cpl_frameset_is_empty (eop_frameset) ) {
545 frame = cpl_frameset_get_position (eop_frameset, 0);
546 eop_map = gravi_data_load_frame (frame, used_frameset);
547 }
548 else
549 cpl_msg_info (cpl_func, "There is no EOP_PARAM in the frameset");
550
551 /* START EKW 12/11/2018 read constant parameter from calibration file */
552 /* Load the STATIC_PARAM Parameter */
553 if (!cpl_frameset_is_empty (static_param_frameset)) {
554 frame = cpl_frameset_get_position (static_param_frameset, 0);
555 static_param_data = gravi_data_load_frame (frame, used_frameset);
556 }
557 else
558 cpl_msg_info (cpl_func, "There is no STATIC_PARAM in the frameset");
559
560 /* Load the DIAMETER_CAT */
561 if ( !cpl_frameset_is_empty (diamcat_frameset) ) {
562 frame = cpl_frameset_get_position (diamcat_frameset, 0);
563 diamcat_data = gravi_data_load_frame (frame, used_frameset);
564 }
565 else
566 cpl_msg_info (cpl_func, "There is no DIAMETER_CAT in the frameset");
567
568 if ( !cpl_frameset_is_empty (pcacalib_frameset)) {
569 frame = cpl_frameset_get_position (pcacalib_frameset, 0);
570 pca_calib_data = gravi_data_load_frame (frame, used_frameset);
571 } else
572 cpl_msg_info (cpl_func, "There is no PHASE_PCA in the frameset");
573
574 CPLCHECK_CLEAN ("Error while loading the calibration maps");
575
576 /*
577 * Select the PRO CATG (based on first frame)
578 */
579
580 frame_tag = cpl_frame_get_tag (cpl_frameset_get_position (recipe_frameset, 0));
581
582 if ((strcmp(frame_tag, GRAVI_DUAL_CALIB_RAW) == 0)) {
583 redCatg = cpl_sprintf (GRAVI_P2VMRED_DUAL_CALIB);
584 proCatg = cpl_sprintf (GRAVI_VIS_DUAL_CALIB);
585 skyCatg = cpl_sprintf (GRAVI_DUAL_SKY_MAP);
586 mode = cpl_sprintf ("gravi_dual");
587 }
588 else if ((strcmp(frame_tag, GRAVI_DUAL_SCIENCE_RAW) == 0)) {
589 redCatg = cpl_sprintf (GRAVI_P2VMRED_DUAL_SCIENCE);
590 proCatg = cpl_sprintf (GRAVI_VIS_DUAL_SCIENCE);
591 skyCatg = cpl_sprintf (GRAVI_DUAL_SKY_MAP);
592 mode = cpl_sprintf ("gravi_dual");
593 }
594 else if ((strcmp(frame_tag, GRAVI_SINGLE_CALIB_RAW) == 0)) {
595 redCatg = cpl_sprintf (GRAVI_P2VMRED_SINGLE_CALIB);
596 proCatg = cpl_sprintf (GRAVI_VIS_SINGLE_CALIB);
597 skyCatg = cpl_sprintf (GRAVI_SINGLE_SKY_MAP);
598 mode = cpl_sprintf ("gravi_single");
599 }
600 else if ((strcmp(frame_tag, GRAVI_SINGLE_SCIENCE_RAW) == 0)) {
601 redCatg = cpl_sprintf (GRAVI_P2VMRED_SINGLE_SCIENCE);
602 proCatg = cpl_sprintf (GRAVI_VIS_SINGLE_SCIENCE);
603 skyCatg = cpl_sprintf (GRAVI_SINGLE_SKY_MAP);
604 mode = cpl_sprintf ("gravi_single");
605 }
606 else {
607 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
608 "Cannot recognize the input DO.CATG");
609 goto cleanup;
610 }
611
612 cpl_msg_info (cpl_func,"Mode of the first frame is: %s (will be used for all frames)", mode);
613
614 /*
615 * Mode for the SKY
616 */
617 int averageSky = gravi_param_get_bool (parlist,"gravity.preproc.average-sky");
618
619 /*
620 * Loop on input SKY frames to be reduced
621 */
622 nb_sky = cpl_frameset_get_size (sky_frameset);
623 sky_maps = cpl_calloc (CPL_MAX(nb_sky,1), sizeof(gravi_data*));
624
625 for (int isky = 0; isky < nb_sky; isky++){
626
627 /* Load the raw SKY */
628 cpl_msg_info (cpl_func, " ***** SKY %d over %d ***** ", isky+1, nb_sky);
629 frame = cpl_frameset_get_position (sky_frameset, isky);
630 data = gravi_data_load_rawframe (frame, used_frameset);
631 gravi_data_patch (data, patch_frameset);
632 gravi_data_detector_cleanup (data, parlist);
633
634 /* Compute the SKY map */
635 sky_maps[isky] = gravi_compute_dark (data);
636 FREE (gravi_data_delete, data);
637
638 CPLCHECK_CLEAN ("Error while computing the sky_map");
639
640 /* Save the SKY map */
641 if (averageSky == 0) {
642 char filename_suffix[20];
643 snprintf(filename_suffix, 16, "%d", isky);
644 gravi_data_save_new (sky_maps[isky], frameset, NULL, filename_suffix,
645 parlist, NULL, frame, "gravity_vis",
646 NULL, skyCatg);
647 CPLCHECK_CLEAN ("Could not save the sky");
648 }
649 }
650
651 /*
652 * Average the sky if requested
653 */
654
655 if (averageSky == 1) {
656 cpl_msg_info (cpl_func, "Do a MASTER SKY from the %d skys", nb_sky);
657
658 gravi_data * msky_map;
659 msky_map = gravi_average_dark (sky_maps, nb_sky);
660 CPLCHECK_CLEAN ("Cannot do master sky");
661
662 gravi_data_save_new (msky_map, frameset, NULL, NULL,
663 parlist, sky_frameset,
664 cpl_frameset_get_position (sky_frameset, 0),
665 "gravity_vis", NULL, skyCatg);
666 CPLCHECK_CLEAN ("Cannot save master sky");
667
668 /* Add all sky to used_frameset, and move pointers */
669 cpl_frameset_join (used_frameset, sky_frameset);
670 for (int isky = 0; isky < nb_sky; isky++)
671 FREE (gravi_data_delete, sky_maps[isky]);
672 sky_maps[0] = msky_map;
673 nb_sky = 1;
674 }
675
676 /*
677 * Loop on input RAW frames to be reduced
678 */
679
680 nb_frame = cpl_frameset_get_size (recipe_frameset);
681 p2vm_qcs = cpl_malloc(sizeof(cpl_propertylist*) * nb_frame);
682
683 for (int ivis = 0; ivis < nb_frame; ivis++){
684 p2vm_qcs[ivis] = cpl_propertylist_new();
685 int isky;
686 char filename_suffix[20];
687 snprintf(filename_suffix, 16, "%d", ivis);
688 current_frameset = cpl_frameset_duplicate (used_frameset);
689
690 cpl_msg_info (cpl_func, " ***** OBJECT %d over %d ***** ", ivis+1, nb_frame);
691
692 /*
693 * Identify the SKY for this OBJECT
694 */
695 isky = nb_sky>0 ? ivis % nb_sky : 0;
696
697 if (nb_sky == 0) {
698 /* No SKY */
699 cpl_msg_info (cpl_func, "There is no SKY in the frameset");
700 }
701 else if (averageSky) {
702 /* Use master SKY already computed, already in frameset */
703 cpl_msg_info (cpl_func, "Use MASTER SKY (already reduced)");
704 }
705 else {
706 /* SKY already computed, add in the used_frameset */
707 cpl_msg_info (cpl_func, "Use SKY %i over %i (already reduced)", isky+1, nb_sky);
708 frame = cpl_frameset_get_position (sky_frameset, isky);
709
710 /* Add this frame to the current_frameset as well */
711 cpl_frameset_insert (current_frameset, cpl_frame_duplicate (frame));
712 }
713
714 /*
715 * Reduce the OBJECT
716 */
717
718 frame = cpl_frameset_get_position (recipe_frameset, ivis);
719 /* Add this frame to the used frameset */
720 cpl_frameset_insert(used_frameset, cpl_frame_duplicate (frame));
721
722 /* Start processing */
723 data = gravi_data_load_rawframe (frame, current_frameset);
724 gravi_data_patch (data, patch_frameset);
725 gravi_data_detector_cleanup (data, parlist);
726
727 /* Option save the bias-subtracted file */
728 if (gravi_param_get_bool (parlist,"gravity.dfs.bias-subtracted-file")) {
729
730 gravi_data_save_new (data, frameset, NULL, filename_suffix, parlist,
731 current_frameset, frame, "gravity_vis",
732 NULL, "BIAS_SUBTRACTED");
733
734 CPLCHECK_CLEAN ("Cannot save the BIAS_SUBTRACTED product");
735 }
736
737 /* Check the shutters */
738 if ( !gravi_data_check_shutter_open (data) ) {
739 cpl_msg_warning (cpl_func, "Shutter problem in the OBJECT");
740 }
741
742 /* Extract spectrum */
743 preproc_data = gravi_extract_spectrum (data, profile_map, dark_map,
744 badpix_map, sky_maps[isky],
745 parlist, GRAVI_DET_ALL);
746 CPLCHECK_CLEAN ("Cannot extract spectrum");
747
748 /* Option save the spectrum file */
749 if (gravi_param_get_bool (parlist,"gravity.dfs.spectrum-file")) {
750 gravi_data_save_new (preproc_data, frameset, NULL, filename_suffix,
751 parlist, current_frameset, frame,
752 "gravity_vis", NULL, GRAVI_SPECTRUM);
753 CPLCHECK_CLEAN ("Cannot save the SPECTRUM product");
754 }
755
756 /* Rescale to common wavelength */
757 gravi_align_spectrum (preproc_data, wave_map, p2vm_map, GRAVI_DET_ALL);
758 CPLCHECK_CLEAN ("Cannot re-interpolate spectrum");
759
760 /* Option save the spectrum-aligned file */
761 if (gravi_param_get_bool (parlist,"gravity.dfs.spectrum-file")) {
762 gravi_data_save_new (preproc_data, frameset, NULL, filename_suffix,
763 parlist, current_frameset, frame,
764 "gravity_vis", NULL, GRAVI_SPECTRUM_ALIGNED);
765 CPLCHECK_CLEAN ("Cannot save the SPECTRUM_ALIGNED product");
766 }
767
768 /* Preproc the Acquisition Camera */
769 if (gravi_param_get_bool (parlist,"gravity.test.reduce-acq-cam")) {
770 gravi_preproc_acqcam (preproc_data, data, badpix_map);
771 CPLCHECK_CLEAN ("Cannot preproc ACQ");
772 }
773
774 /* Option save the preproc file */
775 if (gravi_param_get_bool (parlist,"gravity.dfs.preproc-file")) {
776 gravi_data_save_new (preproc_data, frameset, NULL, filename_suffix,
777 parlist, current_frameset, frame,
778 "gravity_vis", NULL, GRAVI_PREPROC);
779 CPLCHECK_CLEAN ("Cannot save the PREPROC product");
780 }
781
782 /* Copy metrology and subtract background to preproc */
783 gravi_data_move_ext (preproc_data, data, GRAVI_METROLOGY_EXT);
784 cpl_boolean subtract_met_dark = dark_map != NULL && cpl_parameter_get_bool(
785 cpl_parameterlist_find_const(parlist, "gravity.metrology.use-dark-offsets"));
786
787 if (subtract_met_dark)
788 gravi_subtract_met_dark (preproc_data, dark_map);
789
790 /* Demodulate the metrology if requested */
791 if (gravi_param_get_bool (parlist, "gravity.metrology.demodulate-metrology")) {
792 gravi_metrology_demodulate(preproc_data, subtract_met_dark);
793 CPLCHECK_CLEAN ("Cannot demodulate metrology");
794 }
795
796 /* Move extensions from raw_data and delete it */
797 gravi_data_move_ext (preproc_data, data, GRAVI_ARRAY_GEOMETRY_EXT);
798 gravi_data_move_ext (preproc_data, data, GRAVI_OPTICAL_TRAIN_EXT);
799 gravi_data_move_ext (preproc_data, data, GRAVI_OPDC_EXT);
800 gravi_data_move_ext (preproc_data, data, GRAVI_FDDL_EXT);
801 FREE (gravi_data_delete, data);
802 CPLCHECK_CLEAN ("Cannot move ext");
803
804 /* Compute the flux and visibilities for each telescope and
805 * per acquisition with the P2VM applied to preproc_data */
806 p2vmred_data = gravi_compute_p2vmred(preproc_data, p2vm_map, mode,
807 parlist);
808 CPLCHECK_CLEAN ("Cannot apply p2vm to the preproc data");
809
810 /* Reduce the Acquisition Camera and delete data */
811 if (gravi_param_get_bool (parlist,"gravity.test.reduce-acq-cam")) {
812 gravi_reduce_acqcam (p2vmred_data, preproc_data, sky_maps[isky], dark_map, static_param_data);
813 }
814
815 /* Move extensions and delete preproc */
816 gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_IMAGING_DATA_ACQ_EXT);
817 gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_METROLOGY_EXT);
818 gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_FDDL_EXT);
819 gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_OPDC_EXT);
820 FREE (gravi_data_delete, preproc_data);
821 CPLCHECK_CLEAN ("Cannot delete preproc");
822
823 /* Reduce the OPDC table */
824 gravi_compute_opdc_state (p2vmred_data);
825 CPLCHECK_CLEAN ("Cannot reduce OPDC");
826
827 /* Reduce the metrology into OI_VIS_MET */
828 gravi_metrology_reduce (p2vmred_data, eop_map, static_param_data, diodepos_data, parlist);
829 CPLCHECK_CLEAN ("Cannot reduce metrology");
830
831 /* Compute the uv and pointing directions with ERFA */
832 gravi_compute_pointing_uv (p2vmred_data, eop_map);
833 CPLCHECK_CLEAN ("Cannot compute pointing");
834
835 /* Compute the QC0 about tau0 from piezo signals */
836 gravi_compute_tau0 (p2vmred_data);
837 CPLCHECK_CLEAN ("Cannot compute QC for tau0");
838
839 /* Compute QC for the Fringe Tracker injection */
840 gravi_compute_qc_injection (p2vmred_data);
841 CPLCHECK_CLEAN ("Cannot compute QC for FT injection");
842
843 /* Compute QC for the Fringe Tracker OPD calculation */
845 CPLCHECK_CLEAN ("Cannot compute QC for FT OPD estimator");
846
847 /* Find outliers */
848 gravi_compute_outliers (p2vmred_data, parlist);
849 CPLCHECK_MSG ("Cannot compute outliers");
850
851 /* Compute the SNR_BOOT and GDELAY_BOOT */
852 gravi_compute_snr (p2vmred_data, parlist);
853 CPLCHECK_MSG ("Cannot compute SNR");
854
855 /* Compute the signals for averaging */
856 gravi_compute_signals (p2vmred_data, disp_map, parlist);
857 CPLCHECK_MSG ("Cannot compute signals");
858
859 /* Temporary copy to allow averaging over all frames */
860 gravi_copy_p2vm_qcs(p2vmred_data, p2vm_qcs[ivis]);
861 CPLCHECK_MSG ("Cannot copy QC for averaging");
862
863 /* Compute rejection flags for averaging */
864 gravi_compute_rejection (p2vmred_data, parlist);
865 CPLCHECK_MSG ("Cannot compute rejection flags signals");
866
867 /* Save the p2vmreduced file */
868 if (gravi_param_get_bool (parlist,"gravity.dfs.p2vmred-file")) {
869
870 gravi_data_save_new (p2vmred_data, frameset, NULL, filename_suffix,
871 parlist, current_frameset, frame,
872 "gravity_vis", NULL, redCatg);
873
874 CPLCHECK_CLEAN ("Cannot save the P2VMREDUCED product");
875 }
876
877 /* Loop on the wanted sub-integration */
878 cpl_size current_frame = 0;
879 while (current_frame >= 0)
880 {
881 /* Visibility and flux are averaged and the followings
882 * are saved in tables VIS, VIS2 and T3 */
883 tmpvis_data = gravi_compute_vis (p2vmred_data, parlist, &current_frame);
884 CPLCHECK_CLEAN ("Cannot average the P2VMRED frames into VIS");
885
886 /* Set the mean TIME and mean MJD if required */
887 if (gravi_param_get_bool (parlist, "gravity.vis.force-same-time") ) {
888 cpl_msg_info (cpl_func,"Force same time for all quantities/baselines");
889 gravi_vis_force_time (tmpvis_data);
890 CPLCHECK_CLEAN ("Cannot average the TIME in OI_VIS");
891 }
892
893 /* Copy the acquisition camera if requested. */
894 if (current_frame < 0 && gravi_param_get_bool (parlist, "gravity.test.reduce-acq-cam"))
895 {
896 cpl_msg_info (cpl_func, "Cppy ACQ into the VIS file");
898 }
899
900 /* Merge with already existing */
901 if (vis_data == NULL) {
902 vis_data = tmpvis_data; tmpvis_data = NULL;
903 }
904 else {
905 cpl_msg_info (cpl_func,"Merge with previous OI_VIS");
906 gravi_data_append (vis_data, tmpvis_data, 1);
907 FREE (gravi_data_delete, tmpvis_data);
908 }
909 }
910
911 /* Save the astro file, which is a lighter version of the p2vmreduced */
912 if (gravi_param_get_bool (parlist,"gravity.dfs.astro-file")) {
913
914 gravi_data_clean_for_astro (p2vmred_data);
915 gravi_data_save_new (p2vmred_data, frameset, NULL, filename_suffix,
916 parlist, current_frameset, frame,
917 "gravity_vis", NULL, GRAVI_ASTROREDUCED);
918
919 CPLCHECK_CLEAN ("Cannot save the ASTROREDUCED product");
920 }
921
922 cpl_msg_info (cpl_func,"Free the p2vmreduced");
923 FREE (cpl_frameset_delete, current_frameset);
924 FREE (gravi_data_delete, p2vmred_data);
925
926 }
927 /* End loop on the input files to reduce */
928
929 /* Use the PCA calibration to flatten the VISPHI */
930 if (gravi_param_get_bool (parlist, "gravity.vis.flatten-visphi")) {
931 cpl_msg_info (cpl_func, "Flatten VISPHI using PCA");
932 gravi_flatten_vis(vis_data, pca_calib_data);
933 CPLCHECK_CLEAN ("Cannot apply the VISPHI flattening");
934 }
935
936 /* Compute QC parameters */
937 cpl_msg_info (cpl_func, "Computing QC parameters for visibilities");
938 gravi_compute_vis_qc (vis_data, frameset, p2vm_qcs, nb_frame);
939 CPLCHECK_CLEAN ("Cannot compute VIS QCs");
940
941 /* Compute the QC parameters of the TF
942 * FIXME: compute QC TF only for CALIB star */
943 gravi_compute_tf_qc (vis_data, diamcat_data);
944
945 /* Eventually flatten the OI_FLUX */
946 if (gravi_param_get_bool (parlist, "gravity.vis.flat-flux")) {
947
948 cpl_msg_info (cpl_func, "Flatten the FLUX with the internal P2VM spectrum");
949 gravi_flat_flux (vis_data, p2vm_map);
950 CPLCHECK_CLEAN ("Cannot flat the OI_FLUX");
951
952 } else {
953 cpl_msg_info (cpl_func, "Don't flatten the FLUX with the internal P2VM spectrum");
954 }
955
956 /* Perform the normalisation of the SC vis2 and visamp
957 * to match those of the FT */
958 if (!strcmp (gravi_param_get_string (parlist, "gravity.vis.vis-correction-sc"), "FORCE")) {
959
960 cpl_msg_info (cpl_func, "Align the SC visibilities on the FT");
961 gravi_normalize_sc_to_ft (vis_data);
962
963 } else {
964 cpl_msg_info (cpl_func, "Don't align the SC visibilities on the FT");
965 }
966
967 /* Correct the wavelength due to target color shifting */
968 if (gravi_param_get_bool (parlist, "gravity.vis.color-wave-correction") ) {
969 cpl_msg_info (cpl_func,"Compute the wavelength shift due to target color");
970 gravi_wave_correct_color (vis_data);
971 CPLCHECK_CLEAN ("Cannot compute the wavelength in OI_VIS");
972 } else {
973 cpl_msg_info (cpl_func, "Don't compute the wavelength shift due to target color");
974 }
975
976 /* Co-add the observations if requested */
977 if (gravi_param_get_bool (parlist, "gravity.postprocess.average-vis")) {
978 gravi_average_vis (vis_data);
979
980 } else {
981 cpl_msg_info (cpl_func, "Don't average the different observation (if any)");
982 }
983
984 /* Recompute the TIME column from the MJD column
985 * in all OIFITS tables to follow standard */
986 gravi_vis_mjd_to_time (vis_data);
987
988 /* Save the output data file based on the first frame of the frameset in order of MJD-OBS*/
989 const cpl_frame *it_frame;
990 cpl_frameset * science_frames = gravi_frameset_extract_fringe_data(used_frameset);
991 cpl_frameset_iterator *it = cpl_frameset_iterator_new(science_frames);
992 double mjd_obs_first = DBL_MAX;
993 while ((it_frame = cpl_frameset_iterator_get(it)) != NULL) {
994 cpl_propertylist * this_frame_header = cpl_propertylist_load(cpl_frame_get_filename(it_frame), 0);
995 double mjd_obs = gravi_pfits_get_mjd(this_frame_header);
996 if (mjd_obs < mjd_obs_first)
997 {
998 mjd_obs_first = mjd_obs;
999 frame = cpl_frameset_iterator_get(it);
1000 }
1001 cpl_frameset_iterator_advance(it, 1);
1002 cpl_propertylist_delete(this_frame_header);
1003 }
1004 cpl_frameset_iterator_delete(it);
1005
1006 cpl_frameset_join (used_frameset, recipe_frameset);
1007
1008 if(gravi_param_get_bool (parlist, "gravity.vis.oifits2") ) {
1009 gravi_vis_copy_fluxdata(vis_data, 1);
1010 }
1011 gravi_data_save_new (vis_data, frameset, NULL, NULL, parlist,
1012 used_frameset, frame, "gravity_vis", NULL, proCatg);
1013 cpl_frameset_delete(science_frames);
1014
1015 CPLCHECK_CLEAN ("Cannot save the VIS product");
1016
1017 /* Terminate the function */
1018 goto cleanup;
1019
1020cleanup:
1021 /* Deallocation of all variables */
1022 cpl_msg_info(cpl_func,"Memory cleanup");
1023
1024 FREELOOP (gravi_data_delete,sky_maps,nb_sky);
1025 FREE (gravi_data_delete,dark_map);
1026 FREE (gravi_data_delete,data);
1027 FREE (gravi_data_delete,preproc_data);
1028 FREE (gravi_data_delete,profile_map);
1029 FREE (gravi_data_delete,disp_map);
1030 FREE (gravi_data_delete,wave_map);
1031 FREE (gravi_data_delete,badpix_map);
1032 FREE (gravi_data_delete,p2vm_map);
1033 FREE (gravi_data_delete,p2vmred_data);
1034 FREE (gravi_data_delete,vis_data);
1035 FREE (gravi_data_delete,tmpvis_data);
1036 FREE (gravi_data_delete,diamcat_data);
1037 FREE (gravi_data_delete,static_param_data);
1038 FREE (gravi_data_delete,diodepos_data);
1039 FREE (gravi_data_delete,pca_calib_data);
1040 FREE (gravi_data_delete,eop_map);
1041 FREE (cpl_frameset_delete,darkcalib_frameset);
1042 FREE (cpl_frameset_delete,wavecalib_frameset);
1043 FREE (cpl_frameset_delete,flatcalib_frameset);
1044 FREE (cpl_frameset_delete,badcalib_frameset);
1045 FREE (cpl_frameset_delete,p2vmcalib_frameset);
1046 FREE (cpl_frameset_delete,metpos_frameset);
1047 FREE (cpl_frameset_delete,dark_frameset);
1048 FREE (cpl_frameset_delete,diamcat_frameset);
1049 FREE (cpl_frameset_delete,sky_frameset);
1050 FREE (cpl_frameset_delete,dispcalib_frameset);
1051 FREE (cpl_frameset_delete,pcacalib_frameset);
1052 FREE (cpl_frameset_delete,eop_frameset);
1053 FREE (cpl_frameset_delete,patch_frameset);
1054 FREE (cpl_frameset_delete,static_param_frameset);
1055 FREE (cpl_frameset_delete,recipe_frameset);
1056 FREE (cpl_frameset_delete,current_frameset);
1057 FREE (cpl_frameset_delete,used_frameset);
1058 FREE (cpl_free,proCatg);
1059 FREE (cpl_free,redCatg);
1060 FREE (cpl_free,skyCatg);
1061 FREE (cpl_free,mode);
1062 FREELOOP(cpl_propertylist_delete, p2vm_qcs, nb_frame);
1063 //This is a workaround to aliviate PIPE-6316. For some reason the allocation
1064 //pattern of the recipe causes malloc to keep many pages in the allocation
1065 //arena which are not returned to the OS (typically calling brk()).
1066 //This causes issues if there is a fork() call, since then the whole
1067 //address space of the parent is duplicated in the child. This is actually
1068 //the case with the system() call in esorex.
1069 //malloc_trim() is specific to GLIBC and will ask malloc() to return
1070 //as many pages as possible. The code is not portable, hence the guards
1071#if defined(__linux__) && defined(__GLIBC__)
1072 malloc_trim(0);
1073#endif
1074
1075
1077 return (int)cpl_error_get_code();
1078}
typedefCPL_BEGIN_DECLS struct _gravi_data_ gravi_data
Definition: gravi_data.h:39
#define gravi_data_get_header(data)
Definition: gravi_data.h:75
cpl_error_code gravi_metrology_demodulate(gravi_data *met_data, cpl_boolean zero_subtracted)
Demodulate the metrology.
#define GRAVI_RECIPE_OUTPUT
Definition: gravi_dfs.h:39
#define GRAVI_P2VMRED_SINGLE_CALIB
Definition: gravi_dfs.h:63
#define GRAVI_SINGLE_SCIENCE_RAW
Definition: gravi_dfs.h:52
#define GRAVI_PREPROC
Definition: gravi_dfs.h:60
#define GRAVI_SINGLE_SKY_RAW
Definition: gravi_dfs.h:56
#define GRAVI_P2VM_MAP
Definition: gravi_dfs.h:76
#define GRAVI_P2VMRED_DUAL_CALIB
Definition: gravi_dfs.h:65
#define GRAVI_DIODE_POSITION
Definition: gravi_dfs.h:81
#define GRAVI_SINGLE_SKY_MAP
Definition: gravi_dfs.h:89
#define GRAVI_RECIPE_FLOW
Definition: gravi_dfs.h:37
#define GRAVI_VIS_DUAL_SCIENCE
Definition: gravi_dfs.h:98
#define GRAVI_VIS_SINGLE_SCIENCE
Definition: gravi_dfs.h:96
#define GRAVI_ASTROREDUCED
Definition: gravi_dfs.h:67
#define GRAVI_BAD_MAP
Definition: gravi_dfs.h:73
#define GRAVI_DUAL_CALIB_RAW
Definition: gravi_dfs.h:53
#define GRAVI_P2VMRED_SINGLE_SCIENCE
Definition: gravi_dfs.h:64
#define GRAVI_WAVE_MAP
Definition: gravi_dfs.h:75
#define GRAVI_DISP_MODEL
Definition: gravi_dfs.h:79
#define GRAVI_FLAT_MAP
Definition: gravi_dfs.h:74
#define GRAVI_DIAMETER_CAT
Definition: gravi_dfs.h:80
#define GRAVI_DARK_MAP
Definition: gravi_dfs.h:77
#define GRAVI_DUAL_SKY_MAP
Definition: gravi_dfs.h:90
#define GRAVI_RECIPE_INPUT
Definition: gravi_dfs.h:38
#define GRAVI_SINGLE_CALIB_RAW
Definition: gravi_dfs.h:51
#define GRAVI_VIS_DUAL_CALIB
Definition: gravi_dfs.h:99
#define GRAVI_DUAL_SCIENCE_RAW
Definition: gravi_dfs.h:54
#define GRAVI_SPECTRUM_ALIGNED
Definition: gravi_dfs.h:62
#define GRAVI_VIS_SINGLE_CALIB
Definition: gravi_dfs.h:97
#define GRAVI_SPECTRUM
Definition: gravi_dfs.h:61
#define GRAVI_P2VMRED_DUAL_SCIENCE
Definition: gravi_dfs.h:66
cpl_msg_info(cpl_func, "Compute WAVE_SCAN for %s", GRAVI_TYPE(type_data))
#define GRAVI_OPDC_EXT
Definition: gravi_pfits.h:62
#define GRAVI_FDDL_EXT
Definition: gravi_pfits.h:75
#define INSNAME_ACQ
Definition: gravi_pfits.h:199
@ GRAVI_DET_ALL
Definition: gravi_pfits.h:173
#define GRAVI_IMAGING_DATA_ACQ_EXT
Definition: gravi_pfits.h:41
#define GRAVI_ARRAY_GEOMETRY_EXT
Definition: gravi_pfits.h:84
#define GRAVI_METROLOGY_EXT
Definition: gravi_pfits.h:60
#define GRAVI_OPTICAL_TRAIN_EXT
Definition: gravi_pfits.h:85
#define CPLCHECK_CLEAN(msg)
Definition: gravi_utils.h:54
#define gravi_msg_function_exit(flag)
Definition: gravi_utils.h:85
#define FREE(function, variable)
Definition: gravi_utils.h:69
#define gravi_msg_function_start(flag)
Definition: gravi_utils.h:84
#define CPLCHECK_MSG(msg)
Definition: gravi_utils.h:45
#define gravi_data_check_shutter_open(data)
Definition: gravi_utils.h:91
#define FREELOOP(function, variable, n)
Definition: gravi_utils.h:72
static int gravity_vis_exec(cpl_plugin *)
Execute the plugin instance given by the interface.
Definition: gravity_vis.c:293
static char gravity_vis_description[]
Definition: gravity_vis.c:81
static int gravity_vis(cpl_frameset *, cpl_parameterlist *)
Compute the visibilities, and closure phase and create the io fits file.
Definition: gravity_vis.c:391
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
Definition: gravity_vis.c:128
static char gravity_vis_short[]
Definition: gravity_vis.c:80
static int gravity_vis_create(cpl_plugin *)
Setup the recipe options
Definition: gravity_vis.c:169
static int gravity_vis_destroy(cpl_plugin *)
Destroy what has been created by the 'create' function.
Definition: gravity_vis.c:358
cpl_error_code gravi_reduce_acqcam(gravi_data *output_data, gravi_data *input_data, gravi_data *sky_data, gravi_data *dark_data, gravi_data *static_param_data)
Reduce the ACQ camera images.
cpl_error_code gravi_preproc_acqcam(gravi_data *output_data, gravi_data *input_data, gravi_data *bad_map)
Preprocess the ACQ images: correct bad pixels, clean from pupil background via blinking,...
Definition: gravi_acqcam.c:208
cpl_error_code gravi_flatten_vis(gravi_data *vis_data, gravi_data *calib_data)
Use PCA model to flatten observed visphi. The flattened data are added to the existing VIS table.
Definition: gravi_calib.c:3279
gravi_data * gravi_average_dark(gravi_data **data, cpl_size ndata)
Average several DARK calibration map.
Definition: gravi_calib.c:457
gravi_data * gravi_compute_dark(gravi_data *raw_data)
Compute the DARK calibration map.
Definition: gravi_calib.c:125
int gravi_data_patch(gravi_data *file_to_patch, cpl_frameset *patch_frameset)
Load a RAW FITS file and create a gravi_data.
Definition: gravi_data.c:635
cpl_error_code gravi_data_clean_for_astro(gravi_data *data)
Clean the data to keep only OIFITS extensions related to SC.
Definition: gravi_data.c:2435
gravi_data * gravi_data_load_frame(cpl_frame *frame, cpl_frameset *used_frameset)
Load a FITS file and create a gravi_data.
Definition: gravi_data.c:599
cpl_error_code gravi_data_detector_cleanup(gravi_data *data, const cpl_parameterlist *parlist)
Perform self-bias correction to the SC raw data.
Definition: gravi_data.c:1232
gravi_data * gravi_data_load_rawframe(cpl_frame *frame, cpl_frameset *used_frameset)
Load a RAW FITS file and create a gravi_data.
Definition: gravi_data.c:716
cpl_error_code gravi_data_move_ext(gravi_data *output, gravi_data *input, const char *name)
Move extensions from one data to another.
Definition: gravi_data.c:1741
cpl_error_code gravi_data_append(gravi_data *first, const gravi_data *second, int force)
Append a gravi_data into another existing one.
Definition: gravi_data.c:308
cpl_error_code gravi_data_save_new(gravi_data *self, cpl_frameset *allframes, const char *filename, const char *suffix, const cpl_parameterlist *parlist, cpl_frameset *usedframes, cpl_frame *frame, const char *recipe, cpl_propertylist *applist, const char *proCatg)
Save a gravi data in a CPL-complian FITS file.
Definition: gravi_data.c:925
cpl_error_code gravi_data_copy_ext_insname(gravi_data *output, gravi_data *input, const char *name, const char *insname)
Copy extensions from one data to another.
Definition: gravi_data.c:1587
void gravi_data_delete(gravi_data *self)
Delete a gravi data.
Definition: gravi_data.c:146
cpl_frameset * gravi_frameset_extract_met_pos(cpl_frameset *frameset)
Definition: gravi_dfs.c:1356
cpl_parameter * gravi_parameter_add_astro_file(cpl_parameterlist *self)
Definition: gravi_dfs.c:569
int gravi_param_get_bool(const cpl_parameterlist *parlist, const char *name)
Definition: gravi_dfs.c:1537
cpl_parameter * gravi_parameter_add_static_name(cpl_parameterlist *self)
Definition: gravi_dfs.c:464
cpl_parameter * gravi_parameter_add_p2vmred_file(cpl_parameterlist *self)
Definition: gravi_dfs.c:539
cpl_parameter * gravi_parameter_add_metrology(cpl_parameterlist *self)
Definition: gravi_dfs.c:615
cpl_error_code gravi_parameter_add_rejection(cpl_parameterlist *self, int isCalib)
Add rejection parameters to the input parameter list.
Definition: gravi_dfs.c:864
cpl_frameset * gravi_frameset_extract_fringe_data(cpl_frameset *frameset)
Definition: gravi_dfs.c:1323
cpl_error_code gravi_parameter_add_compute_snr(cpl_parameterlist *self)
Definition: gravi_dfs.c:779
cpl_parameter * gravi_parameter_add_biasmethod(cpl_parameterlist *self)
Definition: gravi_dfs.c:584
cpl_frameset * gravi_frameset_extract_patch(cpl_frameset *frameset)
Definition: gravi_dfs.c:1426
cpl_parameter * gravi_parameter_add_average_vis(cpl_parameterlist *self)
Definition: gravi_dfs.c:714
cpl_frameset * gravi_frameset_extract_wave_map(cpl_frameset *frameset)
Definition: gravi_dfs.c:1410
const char * gravi_param_get_string(const cpl_parameterlist *parlist, const char *name)
Definition: gravi_dfs.c:1550
cpl_frameset * gravi_frameset_extract_bad_map(cpl_frameset *frameset)
Definition: gravi_dfs.c:1414
cpl_parameter * gravi_parameter_add_pca(cpl_parameterlist *self)
Add pca parameters to the input parameter list.
Definition: gravi_dfs.c:324
cpl_parameter * gravi_parameter_add_spectrum_file(cpl_parameterlist *self)
Definition: gravi_dfs.c:509
cpl_frameset * gravi_frameset_extract_pca_calib(cpl_frameset *frameset)
Definition: gravi_dfs.c:1438
cpl_frameset * gravi_frameset_extract_dark_map(cpl_frameset *frameset)
Definition: gravi_dfs.c:1406
cpl_error_code gravi_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: gravi_dfs.c:78
cpl_parameter * gravi_parameter_add_preproc_file(cpl_parameterlist *self)
Definition: gravi_dfs.c:524
cpl_frameset * gravi_frameset_extract_p2vm_map(cpl_frameset *frameset)
Definition: gravi_dfs.c:1398
cpl_frameset * gravi_frameset_extract_sky_data(cpl_frameset *frameset)
Definition: gravi_dfs.c:1336
cpl_frameset * gravi_frameset_extract_static_param(cpl_frameset *frameset)
Definition: gravi_dfs.c:1430
cpl_error_code gravi_parameter_add_compute_vis(cpl_parameterlist *self, int isCalib)
Definition: gravi_dfs.c:943
cpl_parameter * gravi_parameter_add_biassub_file(cpl_parameterlist *self)
Definition: gravi_dfs.c:494
cpl_frameset * gravi_frameset_extract_flat_map(cpl_frameset *frameset)
Definition: gravi_dfs.c:1402
cpl_frameset * gravi_frameset_extract_eop_map(cpl_frameset *frameset)
Definition: gravi_dfs.c:1422
cpl_frameset * gravi_frameset_extract_diamcat_map(cpl_frameset *frameset)
Definition: gravi_dfs.c:1319
cpl_frameset * gravi_frameset_extract_disp_map(cpl_frameset *frameset)
Definition: gravi_dfs.c:1352
void gravity_print_banner(void)
Definition: gravi_dfs.c:61
cpl_frameset * gravi_frameset_extract_dark_data(cpl_frameset *frameset)
Extract DARK_RAW frame from the input frameset.
Definition: gravi_dfs.c:1311
cpl_error_code gravi_parameter_add_compute_signal(cpl_parameterlist *self)
Definition: gravi_dfs.c:818
cpl_error_code gravi_compute_pointing_uv(gravi_data *p2vmred_data, gravi_data *eop_data)
Compute the pointing directions and projected baselines in OI_VIS.
Definition: gravi_eop.c:466
cpl_error_code gravi_metrology_reduce(gravi_data *data, gravi_data *eop_data, gravi_data *static_param_data, gravi_data *met_pos, const cpl_parameterlist *parlist)
Reduce the metrology.
cpl_error_code gravi_compute_qc_injection(gravi_data *data)
Compute the QC for the injection stability.
cpl_error_code gravi_compute_tau0(gravi_data *data)
Compute the QC TAU0 parameter.
cpl_error_code gravi_compute_opdc_state(gravi_data *p2vmred_data)
Compute the real-time tracking state from OPDC.
gravi_data * gravi_compute_p2vmred(gravi_data *preproc_data, gravi_data *p2vm_map, const char *mode, const cpl_parameterlist *parlist)
Converts preprocessed data into coherent fluxes using the P2VM.
cpl_error_code gravi_compute_qc_ft_opd_estimator(gravi_data *p2vmred_data)
Compute the QC for the FT linearity.
cpl_parameter * gravi_pfits_get_extrapixel_param(const cpl_propertylist *header)
Extract parameters from a product header.
Definition: gravi_pfits.c:1058
double gravi_pfits_get_mjd(const cpl_propertylist *plist)
Definition: gravi_pfits.c:526
cpl_error_code gravi_align_spectrum(gravi_data *spectrum_data, gravi_data *wave_map, gravi_data *p2vm_map, enum gravi_detector_type det_type)
Regrid the regions into a common wavelength (in-place)
gravi_data * gravi_extract_spectrum(gravi_data *raw_data, gravi_data *profile_map, gravi_data *dark_map, gravi_data *bad_map, gravi_data *sky_map, const cpl_parameterlist *parlist, enum gravi_detector_type det_type)
Create the SPECTRUM gravi_data with extracted spectrum per region.
cpl_error_code gravi_subtract_met_dark(gravi_data *preproc_data, gravi_data *dark_map)
Substract metrology dark.
cpl_error_code gravi_compute_snr(gravi_data *p2vmred_data, const cpl_parameterlist *parlist)
Compute real-time SNR and Group-Delay of the observation.
Definition: gravi_signal.c:620
cpl_error_code gravi_compute_signals(gravi_data *p2vmred_data, gravi_data *disp_data, const cpl_parameterlist *parlist)
Create intermediate signal in the P2VMREDUCED file.
cpl_error_code gravi_compute_outliers(gravi_data *p2vmred_data, const cpl_parameterlist *parlist)
Compute the outliers flags.
Definition: gravi_signal.c:536
cpl_error_code gravi_compute_rejection(gravi_data *p2vmred_data, const cpl_parameterlist *parlist)
Create rejection flags P2VMREDUCED file.
cpl_error_code gravi_copy_p2vm_qcs(gravi_data *p2vmred_data, cpl_propertylist *plist)
Copy PFACTOR and VFACTOR QCs so that they may be aggregated over all frames.
cpl_error_code gravi_compute_tf_qc(gravi_data *oi_vis, gravi_data *diamcat_data)
Fill QC parameters related to transfer function.
Definition: gravi_tf.c:1035
const char * gravi_get_license(void)
Get the pipeline copyright and license.
Definition: gravi_utils.c:104
cpl_error_code gravi_normalize_sc_to_ft(gravi_data *vis_data)
Align the SC visibilities on the FT visibilities.
Definition: gravi_vis.c:2602
gravi_data * gravi_compute_vis(gravi_data *p2vmred_data, const cpl_parameterlist *parlist, cpl_size *current_frame)
The function average the individual frames of a P2VMREDUCED file into a final, single observation per...
Definition: gravi_vis.c:1675
cpl_error_code gravi_vis_force_time(gravi_data *oi_data)
Force all data in OI_TABLE to have the same TIME and MJD.
Definition: gravi_vis.c:4170
cpl_error_code gravi_vis_mjd_to_time(gravi_data *vis_data)
Recompute the TIME column of all OIFITS extension from the MJD column, following the OIFITS standard ...
Definition: gravi_vis.c:2688
cpl_error_code gravi_vis_copy_fluxdata(gravi_data *oi_data, int delete_flux)
Duplicate the column FLUX into FLUXDATA, for OIFITS2 compliance.
Definition: gravi_vis.c:3682
cpl_error_code gravi_compute_vis_qc(gravi_data *vis_data, cpl_frameset *frameset, cpl_propertylist **frame_qcs, cpl_size nb_frame)
Compute the QC parameters for a VIS (averaged) data.
Definition: gravi_vis.c:2237
cpl_error_code gravi_flat_flux(gravi_data *vis_data, gravi_data *p2vm_map)
Divide the OI_FLUX by OI_FLUX from the P2VM (no checks, no time distance...)
Definition: gravi_vis.c:2742
cpl_error_code gravi_average_vis(gravi_data *oi_data)
Coadd the observations together.
Definition: gravi_vis.c:3036
cpl_error_code gravi_wave_correct_color(gravi_data *vis_data)
Create a OI_WAVELENGTH_CORR table with color corrected wavelength.
Definition: gravi_wave.c:1748