GRAVI Pipeline Reference Manual 1.9.0
Loading...
Searching...
No Matches
gravity_postprocess.c
Go to the documentation of this file.
1/* $Id: gravity_postprocess.c,v 1.29 2011/12/3 09:16:12 nazouaoui Exp $
2 *
3 * This file is part of the GRAVI Pipeline
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: nazouaoui $
23 * $Date: 2011/12/3 09:16:12 $
24 * $Revision: 1.29 $
25 * $Name: $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32/*-----------------------------------------------------------------------------
33 Includes
34 -----------------------------------------------------------------------------*/
35
36#include <cpl.h>
37#include <stdio.h>
38#include <string.h>
39#include <time.h>
40
41#include "gravi_data.h"
42#include "gravi_pfits.h"
43#include "gravi_dfs.h"
44
45#include "gravi_utils.h"
46
47#include "gravi_calib.h"
48#include "gravi_p2vmred.h"
49#include "gravi_eop.h"
50#include "gravi_metrology.h"
51
52#include "gravi_vis.h"
53#include "gravi_tf.h"
54
55#include "gravi_preproc.h"
56
57/*-----------------------------------------------------------------------------
58 Private function prototypes
59 -----------------------------------------------------------------------------*/
60
61static int gravity_postprocess_create(cpl_plugin *);
62static int gravity_postprocess_exec(cpl_plugin *);
63static int gravity_postprocess_destroy(cpl_plugin *);
64static int gravity_postprocess(cpl_frameset *, const cpl_parameterlist *);
65
66/*-----------------------------------------------------------------------------
67 Static variables
68 -----------------------------------------------------------------------------*/
69
70static char gravity_postprocess_short[] = "Post-process the products, to fine-tune their content.";
72 "This recipe allows to manipulate the product of the GRAVITY pipeline, mostly the VIS. It permits to merge several files together into a single VIS file with all observations; to average the observations of one or several VIS file to increse the SNR; to remove some data (FT, SC); and to resample the SC observation with spectral binning.\n"
73 "\n"
74 "The list of input files can be P2VMRED, VIS, VIS_CALIBRATED (or even RAW for some parameters). However they should all be compatible in term of setup and observed objets !! Note that the recipe performs only litle checks of the input file content and structure. Thus the user shall ensure the input files are conformable (same polarisation and spectral mode for instante)\n"
76 "* Load the files\n"
77 "* Execute request from user\n"
78 "* Write product\n"
80 "Input files : see above\n"
82 "POSTPROCESSED : Output file\n"
83 "";
84
85/*-----------------------------------------------------------------------------
86 Function code
87 -----------------------------------------------------------------------------*/
88
89/*----------------------------------------------------------------------------*/
99/*----------------------------------------------------------------------------*/
100int cpl_plugin_get_info(cpl_pluginlist * list)
101{
102 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
103 cpl_plugin * plugin = &recipe->interface;
104
105 if (cpl_plugin_init(plugin,
106 CPL_PLUGIN_API,
107 GRAVI_BINARY_VERSION,
108 CPL_PLUGIN_TYPE_RECIPE,
109 "gravity_postprocess",
112 "Nabih Azouaoui, Vincent Lapeyrere, JB. Le Bouquin",
113 PACKAGE_BUGREPORT,
118 cpl_msg_error(cpl_func, "Plugin initialization failed");
119 (void)cpl_error_set_where(cpl_func);
120 return 1;
121 }
122
123 if (cpl_pluginlist_append(list, plugin)) {
124 cpl_msg_error(cpl_func, "Error adding plugin to list");
125 (void)cpl_error_set_where(cpl_func);
126 return 1;
127 }
128
129 return 0;
130}
131
132/*----------------------------------------------------------------------------*/
140/*----------------------------------------------------------------------------*/
141static int gravity_postprocess_create(cpl_plugin * plugin)
142{
143 cpl_recipe * recipe;
144 cpl_parameter * p;
145
146 /* Do not create the recipe if an error code is already set */
147 if (cpl_error_get_code() != CPL_ERROR_NONE) {
148 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
149 cpl_func, __LINE__, cpl_error_get_where());
150 return (int)cpl_error_get_code();
151 }
152
153 if (plugin == NULL) {
154 cpl_msg_error(cpl_func, "Null plugin");
155 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
156 }
157
158 /* Verify plugin type */
159 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
160 cpl_msg_error(cpl_func, "Plugin is not a recipe");
161 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
162 }
163
164 /* Get the recipe */
165 recipe = (cpl_recipe *)plugin;
166
167 /* Create the parameters list in the cpl_recipe object */
168 recipe->parameters = cpl_parameterlist_new();
169 if (recipe->parameters == NULL) {
170 cpl_msg_error(cpl_func, "Parameter list allocation failed");
171 cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
172 }
173
174 /* Fill the parameters list */
175
176 /* Averaging */
177 gravi_parameter_add_average_vis (recipe->parameters);
178 gravi_parameter_add_force_uncertainties (recipe->parameters);
179
180 /* Copy fluxdata */
181 gravi_parameter_copy_fluxdata (recipe->parameters);
182
183 /* Force */
184 p = cpl_parameter_new_value ("gravity.postprocess.force-merge", CPL_TYPE_BOOL,
185 "Force merging even if inconsistent data",
186 "gravity.postprocess", FALSE);
187 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI, "force-merge");
188 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
189 cpl_parameterlist_append (recipe->parameters, p);
190
191 /* Remove FT */
192 p = cpl_parameter_new_value ("gravity.postprocess.remove-ft", CPL_TYPE_BOOL,
193 "Remove FT extensions",
194 "gravity.postprocess", FALSE);
195 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI, "remove-ft");
196 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
197 cpl_parameterlist_append (recipe->parameters, p);
198
199 /* Remove SC */
200 p = cpl_parameter_new_value ("gravity.postprocess.remove-sc", CPL_TYPE_BOOL,
201 "Remove SC extensions",
202 "gravity.postprocess", FALSE);
203 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI, "remove-sc");
204 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
205 cpl_parameterlist_append (recipe->parameters, p);
206
207 /* Remove OPDC */
208 p = cpl_parameter_new_value ("gravity.postprocess.remove-opdc", CPL_TYPE_BOOL,
209 "Remove OPDC extensions",
210 "gravity.postprocess", FALSE);
211 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI, "remove-opdc");
212 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
213 cpl_parameterlist_append (recipe->parameters, p);
214
215 /* Remove MET */
216 p = cpl_parameter_new_value ("gravity.postprocess.remove-met", CPL_TYPE_BOOL,
217 "Remove METROLOGY related extensions",
218 "gravity.postprocess", FALSE);
219 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI, "remove-met");
220 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
221 cpl_parameterlist_append (recipe->parameters, p);
222
223 /* Resamp SC */
224 p = cpl_parameter_new_value ("gravity.postprocess.nbin-lambda-sc", CPL_TYPE_INT,
225 "Bin SC extensions in spectral dimension",
226 "gravity.postprocess", 0);
227 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI, "nbin-lambda-sc");
228 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
229 cpl_parameterlist_append (recipe->parameters, p);
230
231 return 0;
232}
233
234/*----------------------------------------------------------------------------*/
240/*----------------------------------------------------------------------------*/
241static int gravity_postprocess_exec(cpl_plugin * plugin)
242{
243
244 cpl_recipe * recipe;
245 int recipe_status;
246 cpl_errorstate initial_errorstate = cpl_errorstate_get();
247
248
249 /* Return immediately if an error code is already set */
250 if (cpl_error_get_code() != CPL_ERROR_NONE) {
251 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
252 cpl_func, __LINE__, cpl_error_get_where());
253 return (int)cpl_error_get_code();
254 }
255
256 if (plugin == NULL) {
257 cpl_msg_error(cpl_func, "Null plugin");
258 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
259 }
260
261 /* Verify plugin type */
262 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
263 cpl_msg_error(cpl_func, "Plugin is not a recipe");
264 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
265 }
266
267 /* Get the recipe */
268 recipe = (cpl_recipe *)plugin;
269
270 /* Verify parameter and frame lists */
271 if (recipe->parameters == NULL) {
272 cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
273 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
274 }
275 if (recipe->frames == NULL) {
276 cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
277 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
278 }
279
280 /* Invoke the recipe */
281 recipe_status = gravity_postprocess(recipe->frames, recipe->parameters);
282
283 /* Ensure DFS-compliance of the products */
284 if (cpl_dfs_update_product_header(recipe->frames)) {
285 if (!recipe_status){
286 recipe_status = (int)cpl_error_get_code();
287 }
288 }
289
290 if (!cpl_errorstate_is_equal(initial_errorstate)) {
291 /* Dump the error history since recipe execution start.
292 At this point the recipe cannot recover from the error */
293 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
294 }
295
296 return recipe_status;
297}
298
299/*----------------------------------------------------------------------------*/
305/*----------------------------------------------------------------------------*/
306static int gravity_postprocess_destroy(cpl_plugin * plugin)
307{
308 cpl_recipe * recipe;
309
310 if (plugin == NULL) {
311 cpl_msg_error(cpl_func, "Null plugin");
312 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
313 }
314
315 /* Verify plugin type */
316 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
317 cpl_msg_error(cpl_func, "Plugin is not a recipe");
318 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
319 }
320
321 /* Get the recipe */
322 recipe = (cpl_recipe *)plugin;
323
324 cpl_parameterlist_delete(recipe->parameters);
325
326 return 0;
327}
328
329
330/*----------------------------------------------------------------------------*/
338/*----------------------------------------------------------------------------*/
339static int gravity_postprocess(cpl_frameset * frameset,
340 const cpl_parameterlist * parlist)
341{
342 cpl_frameset *used_frameset=NULL;
343 cpl_frame * frame=NULL, *frame_merged=NULL;
344
345 gravi_data * data_merged=NULL, * data=NULL;
346
347 /* Message */
350
351 cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
352 cpl_error_get_code());
353
354 cpl_size nframe = cpl_frameset_get_size (frameset);
355 int force = gravi_param_get_bool (parlist, "gravity.postprocess.force-merge");
356
357 /* To use this recipe the frameset must not be
358 * empty and have at least two frames */
359 if ( nframe<1 ) {
360 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
361 "Not enough frames in the frameset");
362 goto cleanup;
363 }
364
365 /* Check the frame have all the same TAG
366 * (cannot merge different type of frame) */
367
368 /* Insert calibration frame into the used frameset */
369 used_frameset = cpl_frameset_new();
370
371
372 /* Loop on other frames to append them*/
373 for (cpl_size f = 0; f < nframe ; f++ ) {
374
375 /* Load the frame */
376 frame = cpl_frameset_get_position (frameset, f);
377 data = gravi_data_load_frame (frame, used_frameset);
378
379 /* Remove some data */
380 if (gravi_param_get_bool (parlist, "gravity.postprocess.remove-ft")) {
381 cpl_msg_info (cpl_func, "Erase FT");
382 gravi_data_erase_type (data, "_FT");
383 CPLCHECK_CLEAN ("Cannot delete FT");
384 }
385
386 if (gravi_param_get_bool (parlist, "gravity.postprocess.remove-sc")) {
387 cpl_msg_info (cpl_func, "Erase SC");
388 gravi_data_erase_type (data, "_SC");
389 CPLCHECK_CLEAN ("Cannot delete SC");
390 }
391
392 if (gravi_param_get_bool (parlist, "gravity.postprocess.remove-opdc")) {
393 cpl_msg_info (cpl_func, "Erase OPDC");
394 gravi_data_erase_type (data, "OPDC");
395 CPLCHECK_CLEAN ("Cannot delete OPDC");
396 }
397
398 if (gravi_param_get_bool (parlist, "gravity.postprocess.remove-met")) {
399 cpl_msg_info (cpl_func, "Erase MET");
400 gravi_data_erase_type (data, "METROLOGY");
401 gravi_data_erase_type (data, "VIS_MET");
402 CPLCHECK_CLEAN ("Cannot delete MET");
403 }
404
405 /* Force uncertainties */
406 gravi_force_uncertainties (data, parlist);
407 CPLCHECK_CLEAN ("Cannot force uncertainties");
408
409
410 if (f == 0) {
411 /* Use the first frame for merging */
412 frame_merged = frame;
413 data_merged = data; data = NULL;
414 }
415 else {
416 /* Merge for first frame */
417 gravi_data_append (data_merged, data, force);
418 FREE (gravi_data_delete, data);
419 }
420
421 CPLCHECK_CLEAN ("Cannot append frames");
422 }
423
424
425 /* Co-add them if required (FIXME: and if VIS) */
426 if (gravi_param_get_bool (parlist, "gravity.postprocess.average-vis")) {
427
428 gravi_msg_warning ("FIXME", "Average the different observations = EXPERIMENTAL");
429 gravi_average_vis (data_merged);
430
431 CPLCHECK_CLEAN ("Cannot average VIS");
432 }
433
434 /* Resample them if required (FIXME: and if VIS) */
435 cpl_size resamp_sc = gravi_param_get_int (parlist, "gravity.postprocess.nbin-lambda-sc");
436 if ( resamp_sc > 1) {
437
438 gravi_msg_warning ("FIXME", "Resamp the SC data = EXPERIMENTAL");
439 gravi_vis_resamp (data_merged, resamp_sc);
440
441 CPLCHECK_CLEAN ("Cannot resamp SC");
442 }
443
444 /* Add the FLUXDATA column for OIFITS2 standard */
445 if (gravi_param_get_bool (parlist, "gravity.postprocess.copy-fluxdata"))
446 {
447 gravi_vis_copy_fluxdata (data_merged, 0);
448 }
449
450 /* Recompute the TIME column from the MJD column
451 * in all OIFITS tables to follow standard */
452 gravi_vis_mjd_to_time (data_merged);
453
454 /* Save the output data file based on the first frame of the frameset */
455 gravi_data_save_new (data_merged, frameset, NULL, NULL, parlist,
456 used_frameset, frame_merged, "gravity_postprocess",
457 NULL, "POSTPROCESSED");
458
459 CPLCHECK_CLEAN ("Cannot save the POSTPROCESSED product");
460
461 /* Terminate the function */
462 goto cleanup;
463
464cleanup:
465 /* Deallocation of all variables */
466 cpl_msg_info(cpl_func,"Memory cleanup");
467
468 FREE (gravi_data_delete,data);
469 FREE (gravi_data_delete,data_merged);
470 FREE (cpl_frameset_delete,used_frameset);
471
473 return (int)cpl_error_get_code();
474}
typedefCPL_BEGIN_DECLS struct _gravi_data_ gravi_data
Definition: gravi_data.h:39
#define GRAVI_RECIPE_OUTPUT
Definition: gravi_dfs.h:39
#define GRAVI_RECIPE_FLOW
Definition: gravi_dfs.h:37
#define GRAVI_RECIPE_INPUT
Definition: gravi_dfs.h:38
cpl_msg_info(cpl_func, "Compute WAVE_SCAN for %s", GRAVI_TYPE(type_data))
#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
static int gravity_postprocess_exec(cpl_plugin *)
Execute the plugin instance given by the interface.
static char gravity_postprocess_description[]
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
static int gravity_postprocess_destroy(cpl_plugin *)
Destroy what has been created by the 'create' function.
static char gravity_postprocess_short[]
static int gravity_postprocess_create(cpl_plugin *)
Setup the recipe options
static int gravity_postprocess(cpl_frameset *, const cpl_parameterlist *)
Compute the visibilities, and closure phase and create the io fits file.
cpl_error_code gravi_data_erase_type(gravi_data *self, const char *type)
Erase all extension related to an instrument (SC, FT, MET...)
Definition: gravi_data.c:2247
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_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
void gravi_data_delete(gravi_data *self)
Delete a gravi data.
Definition: gravi_data.c:146
int gravi_param_get_bool(const cpl_parameterlist *parlist, const char *name)
Definition: gravi_dfs.c:1537
cpl_parameter * gravi_parameter_copy_fluxdata(cpl_parameterlist *self)
Definition: gravi_dfs.c:729
cpl_parameter * gravi_parameter_add_average_vis(cpl_parameterlist *self)
Definition: gravi_dfs.c:714
int gravi_param_get_int(const cpl_parameterlist *parlist, const char *name)
Definition: gravi_dfs.c:1524
cpl_parameter * gravi_parameter_add_force_uncertainties(cpl_parameterlist *self)
Definition: gravi_dfs.c:743
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
void gravity_print_banner(void)
Definition: gravi_dfs.c:61
cpl_error_code gravi_msg_warning(const char *component, const char *msg)
Definition: gravi_utils.c:127
const char * gravi_get_license(void)
Get the pipeline copyright and license.
Definition: gravi_utils.c:104
cpl_error_code gravi_force_uncertainties(gravi_data *oi_data, const cpl_parameterlist *parlist)
Force uncertainties.
Definition: gravi_vis.c:2908
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:3635
cpl_error_code gravi_vis_resamp(gravi_data *oi_data, cpl_size nsamp)
Re-bin the SC table by nsamp consecutive spectral bins.
Definition: gravi_vis.c:3538
cpl_error_code gravi_average_vis(gravi_data *oi_data)
Coadd the observations together.
Definition: gravi_vis.c:2998