42 #include "gravi_utils.h" 43 #include "gravi_pfits.h" 44 #include "gravi_data.h" 45 #include "gravi_dfs.h" 46 #include "gravi_calib.h" 47 #include "gravi_p2vmred.h" 48 #include "gravi_vis.h" 55 static int gravity_viscal_create(cpl_plugin *);
56 static int gravity_viscal_exec(cpl_plugin *);
57 static int gravity_viscal_destroy(cpl_plugin *);
58 static int gravity_viscal(cpl_frameset *,
const cpl_parameterlist *);
64 static char gravity_viscal_short[] =
"Calibrate visibilities from the transfer function.";
65 static char gravity_viscal_description[] =
66 "This recipe calibrates the visibilities acquired on science target using visibilities acquired on a calibrator target. If the DIAMETER_CAT is not provided, the recipe will use the diameter provided in the header to compute the transfer function QC parameters. The corresponding keywords are INS.SOBJ.DIAMETER and FT.ROBJ.DIAMETER. The OI_FLUX data are not yet calibrated." 68 "The tag in the DO category can be SINGLE/DUAL and CAL/SCI. The tag in the PRO.CATG category will be SINGLE/DUAL and CAL/SCI depending on the input tag.\n" 70 "* Loop on all input CALIB files, compute the TF for each of them and write the corresponding product\n" 71 "* Loop on all input SCIENCE files, interpolate the TF at that time, calibrate, and write the corresponding product\n" 72 GRAVI_RECIPE_INPUT
"\n" 73 GRAVI_VIS_SINGLE_SCIENCE
" (>=1) : visibilities on sciences\n" 74 GRAVI_VIS_SINGLE_CALIB
" (>=1) : visibilities on calibrators\n" 75 GRAVI_DIAMETER_CAT
" (opt) : catalog of stellar diameters\n" 76 GRAVI_RECIPE_OUTPUT
"\n" 77 GRAVI_VIS_SINGLE_CALIBRATED
" : calibrated science visibilities\n" 78 GRAVI_TF_SINGLE_CALIB
" : Transfer Function (TF) estimated on calibrators\n" 79 GRAVI_TF_SINGLE_SCIENCE
" : TF interpolated at the time of sciences\n" 97 int cpl_plugin_get_info(cpl_pluginlist * list)
99 cpl_recipe * recipe = cpl_calloc(1,
sizeof *recipe );
100 cpl_plugin * plugin = &recipe->interface;
102 if (cpl_plugin_init(plugin,
104 GRAVI_BINARY_VERSION,
105 CPL_PLUGIN_TYPE_RECIPE,
107 gravity_viscal_short,
108 gravity_viscal_description,
109 "Nabih Azouaoui, Vincent Lapeyrere, JB. Le Bouquin",
112 gravity_viscal_create,
114 gravity_viscal_destroy)) {
115 cpl_msg_error(cpl_func,
"Plugin initialization failed");
116 (void)cpl_error_set_where(cpl_func);
120 if (cpl_pluginlist_append(list, plugin)) {
121 cpl_msg_error(cpl_func,
"Error adding plugin to list");
122 (void)cpl_error_set_where(cpl_func);
138 static int gravity_viscal_create(cpl_plugin * plugin)
144 if (cpl_error_get_code() != CPL_ERROR_NONE) {
145 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
146 cpl_func, __LINE__, cpl_error_get_where());
147 return (
int)cpl_error_get_code();
150 if (plugin == NULL) {
151 cpl_msg_error(cpl_func,
"Null plugin");
152 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
156 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
157 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
158 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
162 recipe = (cpl_recipe *)plugin;
165 recipe->parameters = cpl_parameterlist_new();
166 if (recipe->parameters == NULL) {
167 cpl_msg_error(cpl_func,
"Parameter list allocation failed");
168 cpl_ensure_code(0, (
int)CPL_ERROR_ILLEGAL_OUTPUT);
172 gravi_parameter_add_static_name (recipe->parameters);
175 p = cpl_parameter_new_value (
"gravity.viscal.delta-time-calib", CPL_TYPE_DOUBLE,
176 "Delta time to interpolate the TF [s]",
177 "gravity.viscal", 3600.0);
178 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI,
"delta-time-calib");
179 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
180 cpl_parameterlist_append (recipe->parameters, p);
183 p = cpl_parameter_new_value (
"gravity.viscal.force-calib", CPL_TYPE_BOOL,
184 "Force the calibration, don't check setup",
185 "gravity.viscal", FALSE);
186 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI,
"force-calib");
187 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
188 cpl_parameterlist_append (recipe->parameters, p);
191 p = cpl_parameter_new_value (
"gravity.viscal.nsmooth-tfvis-sc", CPL_TYPE_INT,
192 "Smooth the TF spectrally by this number of " 193 "spectral bin, to enhance SNR (only " 194 "apply to VIS2, VISPHI, VISAMP, T3PHI, T3AMP). " 195 "This parameter is ignored in spectral mode LOW.",
196 "gravity.viscal", 0);
197 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI,
"nsmooth-tfvis-sc");
198 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
199 cpl_parameterlist_append (recipe->parameters, p);
201 p = cpl_parameter_new_value (
"gravity.viscal.nsmooth-tfflux-sc", CPL_TYPE_INT,
202 "Smooth the TF spectrally by this number of " 203 "spectral bin, to enhance SNR (only " 204 "apply to FLUX, RVIS, IVIS). " 205 "This parameter is ignored in spectral mode LOW.",
206 "gravity.viscal", 0);
207 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI,
"nsmooth-tfflux-sc");
208 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
209 cpl_parameterlist_append (recipe->parameters, p);
211 p = cpl_parameter_new_value (
"gravity.viscal.maxdeg-tfvis-sc", CPL_TYPE_INT,
212 "Fit the TF spectrally by a polynomial to enhance SNR " 213 "(only apply to VIS2, VISPHI, VISAMP, T3PHI, T3AMP). " 214 "This parameter is ignored in spectral mode LOW.",
215 "gravity.viscal", 5);
216 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI,
"maxdeg-tfvis-sc");
217 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
218 cpl_parameterlist_append (recipe->parameters, p);
220 p = cpl_parameter_new_value (
"gravity.viscal.calib-flux", CPL_TYPE_BOOL,
221 "Normalize the FLUX by the calibrator.",
222 "gravity.viscal", FALSE);
223 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI,
"calib-flux");
224 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
225 cpl_parameterlist_append (recipe->parameters, p);
237 static int gravity_viscal_exec(cpl_plugin * plugin)
242 cpl_errorstate initial_errorstate = cpl_errorstate_get();
245 if (cpl_error_get_code() != CPL_ERROR_NONE) {
246 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
247 cpl_func, __LINE__, cpl_error_get_where());
248 return (
int)cpl_error_get_code();
251 if (plugin == NULL) {
252 cpl_msg_error(cpl_func,
"Null plugin");
253 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
257 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
258 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
259 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
263 recipe = (cpl_recipe *)plugin;
266 if (recipe->parameters == NULL) {
267 cpl_msg_error(cpl_func,
"Recipe invoked with NULL parameter list");
268 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
270 if (recipe->frames == NULL) {
271 cpl_msg_error(cpl_func,
"Recipe invoked with NULL frame set");
272 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
276 recipe_status = gravity_viscal(recipe->frames, recipe->parameters);
280 if (cpl_dfs_update_product_header(recipe->frames)) {
282 recipe_status = (int)cpl_error_get_code();
286 if (!cpl_errorstate_is_equal(initial_errorstate)) {
289 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
292 return recipe_status;
302 static int gravity_viscal_destroy(cpl_plugin * plugin)
306 if (plugin == NULL) {
307 cpl_msg_error(cpl_func,
"Null plugin");
308 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
312 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
313 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
314 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
318 recipe = (cpl_recipe *)plugin;
320 cpl_parameterlist_delete(recipe->parameters);
335 static int gravity_viscal(cpl_frameset * frameset,
336 const cpl_parameterlist * parlist)
338 cpl_frameset * vis_calib_frameset = NULL, * vis_sci_frameset = NULL, *current_frameset = NULL;
339 cpl_frameset * tf_calib_frameset = NULL, * used_frameset = NULL, * diamcat_frameset = NULL;
340 cpl_frame * frame = NULL;
342 cpl_propertylist * applist = NULL;
344 cpl_errorstate errorstate;
346 gravi_data ** vis_calibs = NULL, *vis_calib = NULL, * zero_data = NULL, * tf_science = NULL;
347 gravi_data * calibrated = NULL, * vis_data = NULL, * diamcat_data = NULL;
349 int data_mode, nb_frame_tf = 0, nb_frame_calib = 0, nb_frame_sci, i, j, nb_calib = 0;
352 gravity_print_banner ();
353 cpl_msg_set_time_on();
354 cpl_msg_set_component_on();
355 gravi_msg_function_start(1);
359 cpl_error_get_code());
362 vis_calib_frameset = gravi_frameset_extract_vis_calib (frameset);
363 vis_sci_frameset = gravi_frameset_extract_vis_science (frameset);
364 tf_calib_frameset = gravi_frameset_extract_tf_calib (frameset);
365 diamcat_frameset = gravi_frameset_extract_diamcat_map (frameset);
369 if ( cpl_frameset_is_empty (vis_calib_frameset) &&
370 cpl_frameset_is_empty (tf_calib_frameset) ) {
371 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
372 "No VIS or TF file on the frameset") ;
377 nb_frame_tf = cpl_frameset_get_size (tf_calib_frameset);
378 nb_frame_calib = cpl_frameset_get_size (vis_calib_frameset);
379 nb_frame_sci = cpl_frameset_get_size (vis_sci_frameset);
382 vis_calibs = cpl_malloc ( (nb_frame_calib + nb_frame_tf) *
sizeof (gravi_data *));
383 for (j = 0; j < (nb_frame_calib + nb_frame_tf); j++) vis_calibs[j] = NULL;
391 if ( !cpl_frameset_is_empty (diamcat_frameset) ) {
392 frame = cpl_frameset_get_position (diamcat_frameset, 0);
397 used_frameset = cpl_frameset_new();
400 for (j = 0; j < nb_frame_calib; j++) {
401 errorstate = cpl_errorstate_get();
403 cpl_msg_info (cpl_func,
"*** Compute TF %i over %i ***", j+1, nb_frame_calib);
406 frame = cpl_frameset_get_position (vis_calib_frameset, j);
411 if ( !strcmp (gravi_data_get_spec_res (vis_calib),
"LOW")) {
412 cpl_msg_info (cpl_func,
"LOW spectral resolution -> don't smooth the TF");
414 cpl_size smooth_vis_sc = gravi_param_get_int (parlist,
"gravity.viscal.nsmooth-tfvis-sc");
415 cpl_size smooth_flx_sc = gravi_param_get_int (parlist,
"gravity.viscal.nsmooth-tfflux-sc");
416 cpl_size maxdeg_sc = gravi_param_get_int (parlist,
"gravity.viscal.maxdeg-tfvis-sc");
421 if (vis_calib == NULL) {
422 cpl_msg_error (cpl_func,
"Cannot compute this TF... continue");
426 CPLCHECK_GOTO (
"Cannot compute the TF", cleanup_rawtf);
429 data_mode = gravi_data_frame_get_mode (frame);
432 NULL, frame,
"gravity_vis",
433 NULL, GRAVI_TF_CALIB(data_mode));
435 CPLCHECK_GOTO (
"Cannot save the TF", cleanup_rawtf);
438 vis_calibs[nb_calib] = vis_calib;
443 frame = cpl_frame_duplicate (frame);
444 cpl_frame_set_group (frame, CPL_FRAME_GROUP_CALIB);
445 cpl_frameset_insert (used_frameset, frame);
451 cpl_errorstate_set (errorstate);
455 cpl_msg_info (cpl_func,
"*** Load already computed TF ***");
458 for (j = 0; j < nb_frame_tf; j++) {
459 errorstate = cpl_errorstate_get();
461 cpl_msg_info (cpl_func,
" %i over %i", j+1, nb_frame_tf);
463 frame = cpl_frameset_get_position (tf_calib_frameset, j);
466 CPLCHECK_GOTO(
"Cannot load the TF", cleanup_caltf);
469 vis_calibs[nb_calib] = vis_calib;
475 cpl_errorstate_set (errorstate);
479 cpl_msg_info (cpl_func,
"*** All TF computed or loaded ***");
481 cpl_msg_info (cpl_func,
"Load or create successfully %i TF over %i input CAL files", nb_calib, nb_frame_calib + nb_frame_tf);
487 if ( nb_calib > 1 ) {
488 errorstate = cpl_errorstate_get();
490 cpl_msg_info (cpl_func,
"*** Compute the zero of the metrology -- FIXME: to be done ***");
493 CPLCHECK_GOTO(
"Cannot compute ZP", cleanup_zp);
496 used_frameset, NULL,
"gravity_vis",
499 CPLCHECK_GOTO(
"Cannot save ZP", cleanup_zp);
503 cpl_errorstate_set (errorstate);
512 for (i = 0; i < nb_frame_sci; i++){
513 errorstate = cpl_errorstate_get();
514 current_frameset = cpl_frameset_duplicate (used_frameset);
516 cpl_msg_info (cpl_func,
"*** Calibration of file %i over %i ***", i+1, nb_frame_sci);
518 frame = cpl_frameset_get_position (vis_sci_frameset, i);
522 calibrated =
gravi_calibrate_vis (vis_data, vis_calibs, nb_calib, zero_data, tf_science, parlist);
524 CPLCHECK_GOTO(
"Cannot calibrate the visibility", cleanup_calib);
527 data_mode = gravi_data_frame_get_mode (frame);
530 current_frameset, frame,
"gravity_vis",
531 NULL, GRAVI_VIS_CALIBRATED(data_mode));
533 CPLCHECK_GOTO(
"Cannot save the calibrated visibility", cleanup_calib);
536 data_mode = gravi_data_frame_get_mode (frame);
539 current_frameset, frame,
"gravity_vis", NULL,
540 GRAVI_TF_SCIENCE(data_mode));
542 CPLCHECK_GOTO(
"Cannot save the TF interpolated for this visibility", cleanup_calib);
548 FREE (cpl_propertylist_delete,applist);
549 FREE (cpl_frameset_delete,current_frameset);
550 cpl_errorstate_set (errorstate);
559 cpl_msg_info(cpl_func,
"Memory cleanup");
563 FREE (cpl_frameset_delete,tf_calib_frameset);
564 FREE (cpl_frameset_delete,vis_calib_frameset);
565 FREE (cpl_frameset_delete,vis_sci_frameset);
566 FREE (cpl_frameset_delete,diamcat_frameset);
567 FREE (cpl_frameset_delete,current_frameset);
568 FREE (cpl_frameset_delete,used_frameset);
571 gravi_msg_function_exit(1);
572 return (
int)cpl_error_get_code();
gravi_data * gravi_data_load_frame(cpl_frame *frame, cpl_frameset *used_frameset)
Load a FITS file and create a gravi_data.
gravi_data * gravi_calibrate_vis(gravi_data *vis_data, gravi_data **tf_data, int num_tf, gravi_data *zero, gravi_data *tf_science, const cpl_parameterlist *parlist)
Computes the calibrated visibility from science a single data and several previously evaluated instru...
gravi_data * gravi_compute_zp(gravi_data **vis_calib, int num_calib)
Compute the ZP data.
cpl_error_code gravi_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
gravi_data * gravi_compute_tf(gravi_data *vis_data, gravi_data *diamcat_data)
This function evaluates the transfer function from the observation of a reference star whose diameter...
cpl_error_code gravi_vis_smooth(gravi_data *oi_data, cpl_size nsamp_vis, cpl_size nsamp_flx, cpl_size maxdeg)
Smooth the SC table by nsamp consecutive spectral bins.
const char * gravi_get_license(void)
Get the pipeline copyright and license.
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.
void gravi_data_delete(gravi_data *self)
Delete a gravi data.
gravi_data * gravi_data_duplicate(const gravi_data *self)
Create a copy of the gravi data.