GRAVI Pipeline Reference Manual 1.9.2
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
411 int nb_frame, nb_sky;
412
413 /* Message */
416
417 cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
418 cpl_error_get_code()) ;
419
420 /* Dispatch the frameset */
421 p2vmcalib_frameset = gravi_frameset_extract_p2vm_map (frameset);
422 darkcalib_frameset = gravi_frameset_extract_dark_map (frameset);
423 wavecalib_frameset = gravi_frameset_extract_wave_map (frameset);
424 dark_frameset = gravi_frameset_extract_dark_data (frameset);
425 flatcalib_frameset = gravi_frameset_extract_flat_map (frameset);
426 badcalib_frameset = gravi_frameset_extract_bad_map (frameset);
427 dispcalib_frameset = gravi_frameset_extract_disp_map (frameset);
428 pcacalib_frameset = gravi_frameset_extract_pca_calib (frameset);
429 metpos_frameset = gravi_frameset_extract_met_pos (frameset);
430 diamcat_frameset = gravi_frameset_extract_diamcat_map (frameset);
431 eop_frameset = gravi_frameset_extract_eop_map (frameset);
432 patch_frameset = gravi_frameset_extract_patch (frameset);
433 static_param_frameset = gravi_frameset_extract_static_param (frameset);
434
435 recipe_frameset = gravi_frameset_extract_fringe_data (frameset);
436 sky_frameset = gravi_frameset_extract_sky_data (frameset);
437
438 /* To use this recipe the frameset must contain the p2vm, wave and
439 * gain calibration file. */
440 if ( cpl_frameset_get_size (p2vmcalib_frameset) !=1 ||
441 cpl_frameset_get_size (wavecalib_frameset) !=1 ||
442 cpl_frameset_get_size (flatcalib_frameset) !=1 ||
443 cpl_frameset_get_size (badcalib_frameset) != 1 ||
444 cpl_frameset_get_size (recipe_frameset) < 1 ||
445 (cpl_frameset_is_empty (dark_frameset) &&
446 cpl_frameset_is_empty (darkcalib_frameset) &&
447 cpl_frameset_is_empty (sky_frameset)) ) {
448 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
449 "Illegal number of P2VM, FLAT, WAVE, BAD, DARK or SKY, OBJECT file on the frameset");
450 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
451 "See online help: esorex --man gravity_vis");
452 goto cleanup;
453 }
454
455 /* Force some options if phase flattening is to be performed */
456 if (gravi_param_get_bool (parlist, "gravity.vis.flatten-visphi")) {
457 cpl_parameter *phase_ref = cpl_parameterlist_find (parlist, "gravity.vis.phase-ref-sc");
458 cpl_parameter *output_phase = cpl_parameterlist_find (parlist, "gravity.vis.output-phase-sc");
459
460 if (strcmp (cpl_parameter_get_string(phase_ref), "SELF_REF") != 0) {
461 cpl_msg_warning (cpl_func, "VISPHI flattening requires phase-ref-sc=SELF_REF, forcing");
462 cpl_parameter_set_string (phase_ref, "SELF_REF");
463 }
464
465 if (strcmp (cpl_parameter_get_string(output_phase), "SELF_VISPHI") != 0) {
466 cpl_msg_warning (cpl_func, "VISPHI flattening requires output-phase-sc=SELF_VISPHI, forcing");
467 cpl_parameter_set_string (output_phase, "SELF_VISPHI");
468 }
469 }
470
471 /* Insert calibration frame into the used frameset */
472 used_frameset = cpl_frameset_new();
473
474 /*
475 * Identify the DARK in the input frameset
476 */
477
478 if (!cpl_frameset_is_empty (dark_frameset)) {
479
480 frame = cpl_frameset_get_position (dark_frameset, 0);
481 data = gravi_data_load_rawframe (frame, used_frameset);
482 gravi_data_patch (data, patch_frameset);
483 gravi_data_detector_cleanup (data, parlist);
484
485 /* Compute dark */
486 dark_map = gravi_compute_dark (data);
487 FREE (gravi_data_delete, data);
488
489 CPLCHECK_CLEAN ("Could not compute the DARK map");
490
491 /* Save the dark map */
492 gravi_data_save_new (dark_map, frameset, NULL, NULL, parlist,
493 NULL, frame, "gravity_vis",
494 NULL, GRAVI_DARK_MAP);
495
496 CPLCHECK_CLEAN ("Could not save the DARK map");
497 }
498 else if (!cpl_frameset_is_empty (darkcalib_frameset)) {
499
500 frame = cpl_frameset_get_position (darkcalib_frameset, 0);
501 dark_map = gravi_data_load_frame (frame, used_frameset);
502
503 CPLCHECK_CLEAN ("Could not load the DARK map");
504 }
505 else
506 cpl_msg_info (cpl_func, "There is no DARK in the frame set");
507
508 /* Identify the BAD in the input frameset */
509 frame = cpl_frameset_get_position (badcalib_frameset, 0);
510 badpix_map = gravi_data_load_frame (frame, used_frameset);
511
512 /* Identify the FLAT in the input frameset */
513 frame = cpl_frameset_get_position (flatcalib_frameset, 0);
514 profile_map = gravi_data_load_frame (frame, used_frameset);
515
516 /* Identify the WAVE in the input frameset */
517 frame = cpl_frameset_get_position (wavecalib_frameset, 0);
518 wave_map = gravi_data_load_frame (frame, used_frameset);
519
520 /* Identify the P2VM in the input frameset */
521 frame = cpl_frameset_get_position (p2vmcalib_frameset, 0);
522 p2vm_map = gravi_data_load_frame (frame, used_frameset);
523 cpl_parameter * param_extrapixel = gravi_pfits_get_extrapixel_param(gravi_data_get_header(p2vm_map));
524 cpl_parameterlist_append(parlist, param_extrapixel);
525
526 /* Load the DISP_MODEL in the input frameset */
527 if (!cpl_frameset_is_empty (dispcalib_frameset)) {
528 frame = cpl_frameset_get_position (dispcalib_frameset, 0);
529 disp_map = gravi_data_load_frame (frame, used_frameset);
530 }
531 else
532 cpl_msg_info (cpl_func, "There is no DISP_MODEL in the frameset");
533
534 /* Load the DIODE_POSITION in the input frameset */
535 if (!cpl_frameset_is_empty (metpos_frameset)) {
536 frame = cpl_frameset_get_position (metpos_frameset, 0);
537 diodepos_data = gravi_data_load_frame (frame, used_frameset);
538 }
539 else
540 cpl_msg_info (cpl_func, "There is no DIODE_POSITION in the frameset");
541
542 /* Load the EOP_PARAM */
543 if ( !cpl_frameset_is_empty (eop_frameset) ) {
544 frame = cpl_frameset_get_position (eop_frameset, 0);
545 eop_map = gravi_data_load_frame (frame, used_frameset);
546 }
547 else
548 cpl_msg_info (cpl_func, "There is no EOP_PARAM in the frameset");
549
550 /* START EKW 12/11/2018 read constant parameter from calibration file */
551 /* Load the STATIC_PARAM Parameter */
552 if (!cpl_frameset_is_empty (static_param_frameset)) {
553 frame = cpl_frameset_get_position (static_param_frameset, 0);
554 static_param_data = gravi_data_load_frame (frame, used_frameset);
555 }
556 else
557 cpl_msg_info (cpl_func, "There is no STATIC_PARAM in the frameset");
558
559 /* Load the DIAMETER_CAT */
560 if ( !cpl_frameset_is_empty (diamcat_frameset) ) {
561 frame = cpl_frameset_get_position (diamcat_frameset, 0);
562 diamcat_data = gravi_data_load_frame (frame, used_frameset);
563 }
564 else
565 cpl_msg_info (cpl_func, "There is no DIAMETER_CAT in the frameset");
566
567 if ( !cpl_frameset_is_empty (pcacalib_frameset)) {
568 frame = cpl_frameset_get_position (pcacalib_frameset, 0);
569 pca_calib_data = gravi_data_load_frame (frame, used_frameset);
570 } else
571 cpl_msg_info (cpl_func, "There is no PHASE_PCA in the frameset");
572
573 CPLCHECK_CLEAN ("Error while loading the calibration maps");
574
575 /*
576 * Select the PRO CATG (based on first frame)
577 */
578
579 frame_tag = cpl_frame_get_tag (cpl_frameset_get_position (recipe_frameset, 0));
580
581 if ((strcmp(frame_tag, GRAVI_DUAL_CALIB_RAW) == 0)) {
582 redCatg = cpl_sprintf (GRAVI_P2VMRED_DUAL_CALIB);
583 proCatg = cpl_sprintf (GRAVI_VIS_DUAL_CALIB);
584 skyCatg = cpl_sprintf (GRAVI_DUAL_SKY_MAP);
585 mode = cpl_sprintf ("gravi_dual");
586 }
587 else if ((strcmp(frame_tag, GRAVI_DUAL_SCIENCE_RAW) == 0)) {
588 redCatg = cpl_sprintf (GRAVI_P2VMRED_DUAL_SCIENCE);
589 proCatg = cpl_sprintf (GRAVI_VIS_DUAL_SCIENCE);
590 skyCatg = cpl_sprintf (GRAVI_DUAL_SKY_MAP);
591 mode = cpl_sprintf ("gravi_dual");
592 }
593 else if ((strcmp(frame_tag, GRAVI_SINGLE_CALIB_RAW) == 0)) {
594 redCatg = cpl_sprintf (GRAVI_P2VMRED_SINGLE_CALIB);
595 proCatg = cpl_sprintf (GRAVI_VIS_SINGLE_CALIB);
596 skyCatg = cpl_sprintf (GRAVI_SINGLE_SKY_MAP);
597 mode = cpl_sprintf ("gravi_single");
598 }
599 else if ((strcmp(frame_tag, GRAVI_SINGLE_SCIENCE_RAW) == 0)) {
600 redCatg = cpl_sprintf (GRAVI_P2VMRED_SINGLE_SCIENCE);
601 proCatg = cpl_sprintf (GRAVI_VIS_SINGLE_SCIENCE);
602 skyCatg = cpl_sprintf (GRAVI_SINGLE_SKY_MAP);
603 mode = cpl_sprintf ("gravi_single");
604 }
605 else {
606 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
607 "Cannot recognize the input DO.CATG");
608 goto cleanup;
609 }
610
611 cpl_msg_info (cpl_func,"Mode of the first frame is: %s (will be used for all frames)", mode);
612
613 /*
614 * Mode for the SKY
615 */
616 int averageSky = gravi_param_get_bool (parlist,"gravity.preproc.average-sky");
617
618 /*
619 * Loop on input SKY frames to be reduced
620 */
621 nb_sky = cpl_frameset_get_size (sky_frameset);
622 sky_maps = cpl_calloc (CPL_MAX(nb_sky,1), sizeof(gravi_data*));
623
624 for (int isky = 0; isky < nb_sky; isky++){
625
626 /* Load the raw SKY */
627 cpl_msg_info (cpl_func, " ***** SKY %d over %d ***** ", isky+1, nb_sky);
628 frame = cpl_frameset_get_position (sky_frameset, isky);
629 data = gravi_data_load_rawframe (frame, used_frameset);
630 gravi_data_patch (data, patch_frameset);
631 gravi_data_detector_cleanup (data, parlist);
632
633 /* Compute the SKY map */
634 sky_maps[isky] = gravi_compute_dark (data);
635 FREE (gravi_data_delete, data);
636
637 CPLCHECK_CLEAN ("Error while computing the sky_map");
638
639 /* Save the SKY map */
640 if (averageSky == 0) {
641 char filename_suffix[20];
642 snprintf(filename_suffix, 16, "%d", isky);
643 gravi_data_save_new (sky_maps[isky], frameset, NULL, filename_suffix,
644 parlist, NULL, frame, "gravity_vis",
645 NULL, skyCatg);
646 CPLCHECK_CLEAN ("Could not save the sky");
647 }
648 }
649
650 /*
651 * Average the sky if requested
652 */
653
654 if (averageSky == 1) {
655 cpl_msg_info (cpl_func, "Do a MASTER SKY from the %d skys", nb_sky);
656
657 gravi_data * msky_map;
658 msky_map = gravi_average_dark (sky_maps, nb_sky);
659 CPLCHECK_CLEAN ("Cannot do master sky");
660
661 gravi_data_save_new (msky_map, frameset, NULL, NULL,
662 parlist, sky_frameset,
663 cpl_frameset_get_position (sky_frameset, 0),
664 "gravity_vis", NULL, skyCatg);
665 CPLCHECK_CLEAN ("Cannot save master sky");
666
667 /* Add all sky to used_frameset, and move pointers */
668 cpl_frameset_join (used_frameset, sky_frameset);
669 for (int isky = 0; isky < nb_sky; isky++)
670 FREE (gravi_data_delete, sky_maps[isky]);
671 sky_maps[0] = msky_map;
672 nb_sky = 1;
673 }
674
675 /*
676 * Loop on input RAW frames to be reduced
677 */
678
679 nb_frame = cpl_frameset_get_size (recipe_frameset);
680
681 for (int ivis = 0; ivis < nb_frame; ivis++){
682 int isky;
683 char filename_suffix[20];
684 snprintf(filename_suffix, 16, "%d", ivis);
685 current_frameset = cpl_frameset_duplicate (used_frameset);
686
687 cpl_msg_info (cpl_func, " ***** OBJECT %d over %d ***** ", ivis+1, nb_frame);
688
689 /*
690 * Identify the SKY for this OBJECT
691 */
692 isky = nb_sky>0 ? ivis % nb_sky : 0;
693
694 if (nb_sky == 0) {
695 /* No SKY */
696 cpl_msg_info (cpl_func, "There is no SKY in the frameset");
697 }
698 else if (averageSky) {
699 /* Use master SKY already computed, already in frameset */
700 cpl_msg_info (cpl_func, "Use MASTER SKY (already reduced)");
701 }
702 else {
703 /* SKY already computed, add in the used_frameset */
704 cpl_msg_info (cpl_func, "Use SKY %i over %i (already reduced)", isky+1, nb_sky);
705 frame = cpl_frameset_get_position (sky_frameset, isky);
706
707 /* Add this frame to the current_frameset as well */
708 cpl_frameset_insert (current_frameset, cpl_frame_duplicate (frame));
709 }
710
711 /*
712 * Reduce the OBJECT
713 */
714
715 frame = cpl_frameset_get_position (recipe_frameset, ivis);
716 /* Add this frame to the used frameset */
717 cpl_frameset_insert(used_frameset, cpl_frame_duplicate (frame));
718
719 /* Start processing */
720 data = gravi_data_load_rawframe (frame, current_frameset);
721 gravi_data_patch (data, patch_frameset);
722 gravi_data_detector_cleanup (data, parlist);
723
724 /* Option save the bias-subtracted file */
725 if (gravi_param_get_bool (parlist,"gravity.dfs.bias-subtracted-file")) {
726
727 gravi_data_save_new (data, frameset, NULL, filename_suffix, parlist,
728 current_frameset, frame, "gravity_vis",
729 NULL, "BIAS_SUBTRACTED");
730
731 CPLCHECK_CLEAN ("Cannot save the BIAS_SUBTRACTED product");
732 }
733
734 /* Check the shutters */
735 if ( !gravi_data_check_shutter_open (data) ) {
736 cpl_msg_warning (cpl_func, "Shutter problem in the OBJECT");
737 }
738
739 /* Extract spectrum */
740 preproc_data = gravi_extract_spectrum (data, profile_map, dark_map,
741 badpix_map, sky_maps[isky],
742 parlist, GRAVI_DET_ALL);
743 CPLCHECK_CLEAN ("Cannot extract spectrum");
744
745 /* Option save the spectrum file */
746 if (gravi_param_get_bool (parlist,"gravity.dfs.spectrum-file")) {
747 gravi_data_save_new (preproc_data, frameset, NULL, filename_suffix,
748 parlist, current_frameset, frame,
749 "gravity_vis", NULL, GRAVI_SPECTRUM);
750 CPLCHECK_CLEAN ("Cannot save the SPECTRUM product");
751 }
752
753 /* Rescale to common wavelength */
754 gravi_align_spectrum (preproc_data, wave_map, p2vm_map, GRAVI_DET_ALL);
755 CPLCHECK_CLEAN ("Cannot re-interpolate spectrum");
756
757 /* Option save the spectrum-aligned file */
758 if (gravi_param_get_bool (parlist,"gravity.dfs.spectrum-file")) {
759 gravi_data_save_new (preproc_data, frameset, NULL, filename_suffix,
760 parlist, current_frameset, frame,
761 "gravity_vis", NULL, GRAVI_SPECTRUM_ALIGNED);
762 CPLCHECK_CLEAN ("Cannot save the SPECTRUM_ALIGNED product");
763 }
764
765 /* Preproc the Acquisition Camera */
766 if (gravi_param_get_bool (parlist,"gravity.test.reduce-acq-cam")) {
767 gravi_preproc_acqcam (preproc_data, data, badpix_map);
768 CPLCHECK_CLEAN ("Cannot preproc ACQ");
769 }
770
771 /* Option save the preproc file */
772 if (gravi_param_get_bool (parlist,"gravity.dfs.preproc-file")) {
773 gravi_data_save_new (preproc_data, frameset, NULL, filename_suffix,
774 parlist, current_frameset, frame,
775 "gravity_vis", NULL, GRAVI_PREPROC);
776 CPLCHECK_CLEAN ("Cannot save the PREPROC product");
777 }
778
779 /* Copy metrology and subtract background to preproc */
780 gravi_data_move_ext (preproc_data, data, GRAVI_METROLOGY_EXT);
781 cpl_boolean subtract_met_dark = dark_map != NULL && cpl_parameter_get_bool(
782 cpl_parameterlist_find_const(parlist, "gravity.metrology.use-dark-offsets"));
783
784 if (subtract_met_dark)
785 gravi_subtract_met_dark (preproc_data, dark_map);
786
787 /* Demodulate the metrology if requested */
788 if (gravi_param_get_bool (parlist, "gravity.metrology.demodulate-metrology")) {
789 gravi_metrology_demodulate(preproc_data, subtract_met_dark);
790 CPLCHECK_CLEAN ("Cannot demodulate metrology");
791 }
792
793 /* Move extensions from raw_data and delete it */
794 gravi_data_move_ext (preproc_data, data, GRAVI_ARRAY_GEOMETRY_EXT);
795 gravi_data_move_ext (preproc_data, data, GRAVI_OPTICAL_TRAIN_EXT);
796 gravi_data_move_ext (preproc_data, data, GRAVI_OPDC_EXT);
797 gravi_data_move_ext (preproc_data, data, GRAVI_FDDL_EXT);
798 FREE (gravi_data_delete, data);
799 CPLCHECK_CLEAN ("Cannot move ext");
800
801 /* Compute the flux and visibilities for each telescope and
802 * per acquisition with the P2VM applied to preproc_data */
803 p2vmred_data = gravi_compute_p2vmred(preproc_data, p2vm_map, mode,
804 parlist);
805 CPLCHECK_CLEAN ("Cannot apply p2vm to the preproc data");
806
807 /* Reduce the Acquisition Camera and delete data */
808 if (gravi_param_get_bool (parlist,"gravity.test.reduce-acq-cam")) {
809 gravi_reduce_acqcam (p2vmred_data, preproc_data, sky_maps[isky], dark_map, static_param_data);
810 }
811
812 /* Move extensions and delete preproc */
813 gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_IMAGING_DATA_ACQ_EXT);
814 gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_METROLOGY_EXT);
815 gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_FDDL_EXT);
816 gravi_data_move_ext (p2vmred_data, preproc_data, GRAVI_OPDC_EXT);
817 FREE (gravi_data_delete, preproc_data);
818 CPLCHECK_CLEAN ("Cannot delete preproc");
819
820 /* Reduce the OPDC table */
821 gravi_compute_opdc_state (p2vmred_data);
822 CPLCHECK_CLEAN ("Cannot reduce OPDC");
823
824 /* Reduce the metrology into OI_VIS_MET */
825 gravi_metrology_reduce (p2vmred_data, eop_map, static_param_data, diodepos_data, parlist);
826 CPLCHECK_CLEAN ("Cannot reduce metrology");
827
828 /* Compute the uv and pointing directions with ERFA */
829 gravi_compute_pointing_uv (p2vmred_data, eop_map);
830 CPLCHECK_CLEAN ("Cannot compute pointing");
831
832 /* Compute the QC0 about tau0 from piezo signals */
833 gravi_compute_tau0 (p2vmred_data);
834 CPLCHECK_CLEAN ("Cannot compute QC for tau0");
835
836 /* Compute QC for the Fringe Tracker injection */
837 gravi_compute_qc_injection (p2vmred_data);
838 CPLCHECK_CLEAN ("Cannot compute QC for FT injection");
839
840 /* Compute QC for the Fringe Tracker OPD calculation */
842 CPLCHECK_CLEAN ("Cannot compute QC for FT OPD estimator");
843
844 /* Find outliers */
845 gravi_compute_outliers (p2vmred_data, parlist);
846 CPLCHECK_MSG ("Cannot compute outliers");
847
848 /* Compute the SNR_BOOT and GDELAY_BOOT */
849 gravi_compute_snr (p2vmred_data, parlist);
850 CPLCHECK_MSG ("Cannot compute SNR");
851
852 /* Compute the signals for averaging */
853 gravi_compute_signals (p2vmred_data, disp_map, parlist);
854 CPLCHECK_MSG ("Cannot compute signals");
855
856 /* Compute rejection flags for averaging */
857 gravi_compute_rejection (p2vmred_data, parlist);
858 CPLCHECK_MSG ("Cannot compute rejection flags signals");
859
860 /* Save the p2vmreduced file */
861 if (gravi_param_get_bool (parlist,"gravity.dfs.p2vmred-file")) {
862
863 gravi_data_save_new (p2vmred_data, frameset, NULL, filename_suffix,
864 parlist, current_frameset, frame,
865 "gravity_vis", NULL, redCatg);
866
867 CPLCHECK_CLEAN ("Cannot save the P2VMREDUCED product");
868 }
869
870 /* Loop on the wanted sub-integration */
871 cpl_size current_frame = 0;
872 while (current_frame >= 0)
873 {
874 /* Visibility and flux are averaged and the followings
875 * are saved in tables VIS, VIS2 and T3 */
876 tmpvis_data = gravi_compute_vis (p2vmred_data, parlist, &current_frame);
877 CPLCHECK_CLEAN ("Cannot average the P2VMRED frames into VIS");
878
879 /* Set the mean TIME and mean MJD if required */
880 if (gravi_param_get_bool (parlist, "gravity.vis.force-same-time") ) {
881 cpl_msg_info (cpl_func,"Force same time for all quantities/baselines");
882 gravi_vis_force_time (tmpvis_data);
883 CPLCHECK_CLEAN ("Cannot average the TIME in OI_VIS");
884 }
885
886 /* Copy the acquisition camera if requested. */
887 if (current_frame < 0 && gravi_param_get_bool (parlist, "gravity.test.reduce-acq-cam"))
888 {
889 cpl_msg_info (cpl_func, "Cppy ACQ into the VIS file");
891 }
892
893 /* Merge with already existing */
894 if (vis_data == NULL) {
895 vis_data = tmpvis_data; tmpvis_data = NULL;
896 }
897 else {
898 cpl_msg_info (cpl_func,"Merge with previous OI_VIS");
899 gravi_data_append (vis_data, tmpvis_data, 1);
900 FREE (gravi_data_delete, tmpvis_data);
901 }
902 }
903
904 /* Save the astro file, which is a lighter version of the p2vmreduced */
905 if (gravi_param_get_bool (parlist,"gravity.dfs.astro-file")) {
906
907 gravi_data_clean_for_astro (p2vmred_data);
908 gravi_data_save_new (p2vmred_data, frameset, NULL, filename_suffix,
909 parlist, current_frameset, frame,
910 "gravity_vis", NULL, GRAVI_ASTROREDUCED);
911
912 CPLCHECK_CLEAN ("Cannot save the ASTROREDUCED product");
913 }
914
915 cpl_msg_info (cpl_func,"Free the p2vmreduced");
916 FREE (cpl_frameset_delete, current_frameset);
917 FREE (gravi_data_delete, p2vmred_data);
918
919 }
920 /* End loop on the input files to reduce */
921
922 /* Use the PCA calibration to flatten the VISPHI */
923 if (gravi_param_get_bool (parlist, "gravity.vis.flatten-visphi")) {
924 cpl_msg_info (cpl_func, "Flatten VISPHI using PCA");
925 gravi_flatten_vis(vis_data, pca_calib_data);
926 CPLCHECK_CLEAN ("Cannot apply the VISPHI flattening");
927 }
928
929 /* Compute QC parameters */
930 cpl_msg_info (cpl_func, "Computing QC parameters for visibilities");
931 gravi_compute_vis_qc (vis_data, frameset);
932
933 /* Compute the QC parameters of the TF
934 * FIXME: compute QC TF only for CALIB star */
935 gravi_compute_tf_qc (vis_data, diamcat_data);
936
937 /* Eventually flatten the OI_FLUX */
938 if (gravi_param_get_bool (parlist, "gravity.vis.flat-flux")) {
939
940 cpl_msg_info (cpl_func, "Flatten the FLUX with the internal P2VM spectrum");
941 gravi_flat_flux (vis_data, p2vm_map);
942 CPLCHECK_CLEAN ("Cannot flat the OI_FLUX");
943
944 } else {
945 cpl_msg_info (cpl_func, "Don't flatten the FLUX with the internal P2VM spectrum");
946 }
947
948 /* Perform the normalisation of the SC vis2 and visamp
949 * to match those of the FT */
950 if (!strcmp (gravi_param_get_string (parlist, "gravity.vis.vis-correction-sc"), "FORCE")) {
951
952 cpl_msg_info (cpl_func, "Align the SC visibilities on the FT");
953 gravi_normalize_sc_to_ft (vis_data);
954
955 } else {
956 cpl_msg_info (cpl_func, "Don't align the SC visibilities on the FT");
957 }
958
959 /* Correct the wavelength due to target color shifting */
960 if (gravi_param_get_bool (parlist, "gravity.vis.color-wave-correction") ) {
961 cpl_msg_info (cpl_func,"Compute the wavelength shift due to target color");
962 gravi_wave_correct_color (vis_data);
963 CPLCHECK_CLEAN ("Cannot compute the wavelength in OI_VIS");
964 } else {
965 cpl_msg_info (cpl_func, "Don't compute the wavelength shift due to target color");
966 }
967
968 /* Co-add the observations if requested */
969 if (gravi_param_get_bool (parlist, "gravity.postprocess.average-vis")) {
970 gravi_average_vis (vis_data);
971
972 } else {
973 cpl_msg_info (cpl_func, "Don't average the different observation (if any)");
974 }
975
976 /* Recompute the TIME column from the MJD column
977 * in all OIFITS tables to follow standard */
978 gravi_vis_mjd_to_time (vis_data);
979
980 /* Save the output data file based on the first frame of the frameset in order of MJD-OBS*/
981 const cpl_frame *it_frame;
982 cpl_frameset * science_frames = gravi_frameset_extract_fringe_data(used_frameset);
983 cpl_frameset_iterator *it = cpl_frameset_iterator_new(science_frames);
984 double mjd_obs_first = DBL_MAX;
985 while ((it_frame = cpl_frameset_iterator_get(it)) != NULL) {
986 cpl_propertylist * this_frame_header = cpl_propertylist_load(cpl_frame_get_filename(it_frame), 0);
987 double mjd_obs = gravi_pfits_get_mjd(this_frame_header);
988 if (mjd_obs < mjd_obs_first)
989 {
990 mjd_obs_first = mjd_obs;
991 frame = cpl_frameset_iterator_get(it);
992 }
993 cpl_frameset_iterator_advance(it, 1);
994 cpl_propertylist_delete(this_frame_header);
995 }
996 cpl_frameset_iterator_delete(it);
997
998 cpl_frameset_join (used_frameset, recipe_frameset);
999
1000 if(gravi_param_get_bool (parlist, "gravity.vis.oifits2") ) {
1001 gravi_vis_copy_fluxdata(vis_data, 1);
1002 }
1003 gravi_data_save_new (vis_data, frameset, NULL, NULL, parlist,
1004 used_frameset, frame, "gravity_vis", NULL, proCatg);
1005 cpl_frameset_delete(science_frames);
1006
1007 CPLCHECK_CLEAN ("Cannot save the VIS product");
1008
1009 /* Terminate the function */
1010 goto cleanup;
1011
1012cleanup:
1013 /* Deallocation of all variables */
1014 cpl_msg_info(cpl_func,"Memory cleanup");
1015
1016 FREELOOP (gravi_data_delete,sky_maps,nb_sky);
1017 FREE (gravi_data_delete,dark_map);
1018 FREE (gravi_data_delete,data);
1019 FREE (gravi_data_delete,preproc_data);
1020 FREE (gravi_data_delete,profile_map);
1021 FREE (gravi_data_delete,disp_map);
1022 FREE (gravi_data_delete,wave_map);
1023 FREE (gravi_data_delete,badpix_map);
1024 FREE (gravi_data_delete,p2vm_map);
1025 FREE (gravi_data_delete,p2vmred_data);
1026 FREE (gravi_data_delete,vis_data);
1027 FREE (gravi_data_delete,tmpvis_data);
1028 FREE (gravi_data_delete,diamcat_data);
1029 FREE (gravi_data_delete,static_param_data);
1030 FREE (gravi_data_delete,diodepos_data);
1031 FREE (gravi_data_delete,pca_calib_data);
1032 FREE (gravi_data_delete,eop_map);
1033 FREE (cpl_frameset_delete,darkcalib_frameset);
1034 FREE (cpl_frameset_delete,wavecalib_frameset);
1035 FREE (cpl_frameset_delete,flatcalib_frameset);
1036 FREE (cpl_frameset_delete,badcalib_frameset);
1037 FREE (cpl_frameset_delete,p2vmcalib_frameset);
1038 FREE (cpl_frameset_delete,metpos_frameset);
1039 FREE (cpl_frameset_delete,dark_frameset);
1040 FREE (cpl_frameset_delete,diamcat_frameset);
1041 FREE (cpl_frameset_delete,sky_frameset);
1042 FREE (cpl_frameset_delete,dispcalib_frameset);
1043 FREE (cpl_frameset_delete,pcacalib_frameset);
1044 FREE (cpl_frameset_delete,eop_frameset);
1045 FREE (cpl_frameset_delete,patch_frameset);
1046 FREE (cpl_frameset_delete,static_param_frameset);
1047 FREE (cpl_frameset_delete,recipe_frameset);
1048 FREE (cpl_frameset_delete,current_frameset);
1049 FREE (cpl_frameset_delete,used_frameset);
1050 FREE (cpl_free,proCatg);
1051 FREE (cpl_free,redCatg);
1052 FREE (cpl_free,skyCatg);
1053 FREE (cpl_free,mode);
1054 //This is a workaround to aliviate PIPE-6316. For some reason the allocation
1055 //pattern of the recipe causes malloc to keep many pages in the allocation
1056 //arena which are not returned to the OS (typically calling brk()).
1057 //This causes issues if there is a fork() call, since then the whole
1058 //address space of the parent is duplicated in the child. This is actually
1059 //the case with the system() call in esorex.
1060 //malloc_trim() is specific to GLIBC and will ask malloc() to return
1061 //as many pages as possible. The code is not portable, hence the guards
1062#if defined(__linux__) && defined(__GLIBC__)
1063 malloc_trim(0);
1064#endif
1065
1066
1068 return (int)cpl_error_get_code();
1069}
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_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:2564
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:4132
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:2650
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:3644
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:2704
cpl_error_code gravi_average_vis(gravi_data *oi_data)
Coadd the observations together.
Definition: gravi_vis.c:2998
cpl_error_code gravi_compute_vis_qc(gravi_data *vis_data, cpl_frameset *frameset)
The function compute the QC parameters for a VIS (averaged) data.
Definition: gravi_vis.c:2234
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