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 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. They should reflect the 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" 69 GRAVI_RECIPE_INPUT
"\n" 70 GRAVI_VIS_SINGLE_SCIENCE
" (>=1) : visibilities on sciences\n" 71 GRAVI_VIS_SINGLE_CALIB
" (>=1) : visibilities on calibrators\n" 72 GRAVI_DIAMETER_CAT
" (opt) : catalog of diameter\n" 73 GRAVI_RECIPE_OUTPUT
"\n" 74 GRAVI_VIS_SINGLE_CALIBRATED
" : calibrated science visibilities\n" 75 GRAVI_TF_SINGLE_CALIB
" : Transfer Function (TF) estimated on calibrators\n" 76 GRAVI_TF_SINGLE_SCIENCE
" : TF interpolated at the time of sciences\n" 94 int cpl_plugin_get_info(cpl_pluginlist * list)
96 cpl_recipe * recipe = cpl_calloc(1,
sizeof *recipe );
97 cpl_plugin * plugin = &recipe->interface;
99 if (cpl_plugin_init(plugin,
101 GRAVI_BINARY_VERSION,
102 CPL_PLUGIN_TYPE_RECIPE,
104 gravity_viscal_short,
105 gravity_viscal_description,
106 "Nabih Azouaoui, Vincent Lapeyrere, JB. Le Bouquin",
109 gravity_viscal_create,
111 gravity_viscal_destroy)) {
112 cpl_msg_error(cpl_func,
"Plugin initialization failed");
113 (void)cpl_error_set_where(cpl_func);
117 if (cpl_pluginlist_append(list, plugin)) {
118 cpl_msg_error(cpl_func,
"Error adding plugin to list");
119 (void)cpl_error_set_where(cpl_func);
135 static int gravity_viscal_create(cpl_plugin * plugin)
141 if (cpl_error_get_code() != CPL_ERROR_NONE) {
142 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
143 cpl_func, __LINE__, cpl_error_get_where());
144 return (
int)cpl_error_get_code();
147 if (plugin == NULL) {
148 cpl_msg_error(cpl_func,
"Null plugin");
149 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
153 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
154 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
155 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
159 recipe = (cpl_recipe *)plugin;
162 recipe->parameters = cpl_parameterlist_new();
163 if (recipe->parameters == NULL) {
164 cpl_msg_error(cpl_func,
"Parameter list allocation failed");
165 cpl_ensure_code(0, (
int)CPL_ERROR_ILLEGAL_OUTPUT);
169 gravi_parameter_add_static_name (recipe->parameters);
172 p = cpl_parameter_new_value (
"gravity.viscal.delta-time-calib", CPL_TYPE_DOUBLE,
173 "Delta time to interpolate the TF [s]",
174 "gravity.viscal", 3600.0);
175 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI,
"delta-time-calib");
176 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
177 cpl_parameterlist_append (recipe->parameters, p);
180 p = cpl_parameter_new_value (
"gravity.viscal.force-calib", CPL_TYPE_BOOL,
181 "Force the calibration, don't check setup",
182 "gravity.viscal", FALSE);
183 cpl_parameter_set_alias (p, CPL_PARAMETER_MODE_CLI,
"force-calib");
184 cpl_parameter_disable (p, CPL_PARAMETER_MODE_ENV);
185 cpl_parameterlist_append (recipe->parameters, p);
197 static int gravity_viscal_exec(cpl_plugin * plugin)
202 cpl_errorstate initial_errorstate = cpl_errorstate_get();
205 if (cpl_error_get_code() != CPL_ERROR_NONE) {
206 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
207 cpl_func, __LINE__, cpl_error_get_where());
208 return (
int)cpl_error_get_code();
211 if (plugin == NULL) {
212 cpl_msg_error(cpl_func,
"Null plugin");
213 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
217 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
218 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
219 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
223 recipe = (cpl_recipe *)plugin;
226 if (recipe->parameters == NULL) {
227 cpl_msg_error(cpl_func,
"Recipe invoked with NULL parameter list");
228 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
230 if (recipe->frames == NULL) {
231 cpl_msg_error(cpl_func,
"Recipe invoked with NULL frame set");
232 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
236 recipe_status = gravity_viscal(recipe->frames, recipe->parameters);
240 if (cpl_dfs_update_product_header(recipe->frames)) {
242 recipe_status = (int)cpl_error_get_code();
246 if (!cpl_errorstate_is_equal(initial_errorstate)) {
249 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
252 return recipe_status;
262 static int gravity_viscal_destroy(cpl_plugin * plugin)
266 if (plugin == NULL) {
267 cpl_msg_error(cpl_func,
"Null plugin");
268 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
272 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
273 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
274 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
278 recipe = (cpl_recipe *)plugin;
280 cpl_parameterlist_delete(recipe->parameters);
295 static int gravity_viscal(cpl_frameset * frameset,
296 const cpl_parameterlist * parlist)
298 cpl_frameset * vis_calib_frameset = NULL, * vis_sci_frameset = NULL, *current_frameset = NULL;
299 cpl_frameset * tf_calib_frameset = NULL, * used_frameset = NULL, * diamcat_frameset = NULL;
300 cpl_frame * frame = NULL;
302 cpl_propertylist * applist = NULL;
304 cpl_errorstate errorstate;
306 gravi_data ** vis_calibs = NULL, *vis_calib = NULL, * zero_data = NULL, * tf_science = NULL;
307 gravi_data * calibrated = NULL, * vis_data = NULL, * diamcat_data = NULL;
309 int data_mode, nb_frame_tf = 0, nb_frame_calib = 0, nb_frame_sci, i, j, nb_calib = 0;
312 gravity_print_banner ();
313 cpl_msg_set_time_on();
314 cpl_msg_set_component_on();
315 gravi_msg_function_start(1);
318 cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
319 cpl_error_get_code());
322 vis_calib_frameset = gravi_frameset_extract_vis_calib (frameset);
323 vis_sci_frameset = gravi_frameset_extract_vis_science (frameset);
324 tf_calib_frameset = gravi_frameset_extract_tf_calib (frameset);
325 diamcat_frameset = gravi_frameset_extract_diamcat_map (frameset);
330 if ( cpl_frameset_is_empty (vis_calib_frameset) &&
331 cpl_frameset_is_empty (tf_calib_frameset) ) {
332 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
333 "No VIS or TF file on the frameset") ;
338 nb_frame_tf = cpl_frameset_get_size (tf_calib_frameset);
339 nb_frame_calib = cpl_frameset_get_size (vis_calib_frameset);
340 nb_frame_sci = cpl_frameset_get_size (vis_sci_frameset);
343 vis_calibs = cpl_malloc ( (nb_frame_calib + nb_frame_tf) *
sizeof (gravi_data *));
344 for (j = 0; j < (nb_frame_calib + nb_frame_tf); j++) vis_calibs[j] = NULL;
352 if ( !cpl_frameset_is_empty (diamcat_frameset) ) {
353 frame = cpl_frameset_get_position (diamcat_frameset, 0);
354 diamcat_data = gravi_data_load_frame (frame, NULL);
358 used_frameset = cpl_frameset_new();
361 for (j = 0; j < nb_frame_calib; j++) {
362 errorstate = cpl_errorstate_get();
364 cpl_msg_info (cpl_func,
"*** Compute TF %i over %i ***", j+1, nb_frame_calib);
367 frame = cpl_frameset_get_position (vis_calib_frameset, j);
368 vis_data = gravi_data_load_frame (frame, NULL);
369 vis_calib = gravi_compute_tf (vis_data, diamcat_data);
372 if (vis_calib == NULL) {
373 cpl_msg_error (cpl_func,
"Cannot compute this TF... continue");
377 CPLCHECK_GOTO (
"Cannot compute the TF", cleanup_rawtf);
380 data_mode = gravi_data_frame_get_mode (frame);
382 gravi_data_save_new (vis_calib, frameset, NULL, parlist,
383 NULL, frame,
"gravity_vis",
384 NULL, GRAVI_TF_CALIB(data_mode));
386 CPLCHECK_GOTO (
"Cannot save the TF", cleanup_rawtf);
389 vis_calibs[nb_calib] = vis_calib;
394 frame = cpl_frame_duplicate (frame);
395 cpl_frame_set_group (frame, CPL_FRAME_GROUP_CALIB);
396 cpl_frameset_insert (used_frameset, frame);
400 FREE (gravi_data_delete, vis_data);
401 FREE (gravi_data_delete, vis_calib);
402 cpl_errorstate_set (errorstate);
406 cpl_msg_info (cpl_func,
"*** Load already computed TF ***");
409 for (j = 0; j < nb_frame_tf; j++) {
410 errorstate = cpl_errorstate_get();
412 cpl_msg_info (cpl_func,
" %i over %i", j+1, nb_frame_tf);
414 frame = cpl_frameset_get_position (tf_calib_frameset, j);
415 vis_calib = gravi_data_load_frame (frame, used_frameset);
417 CPLCHECK_GOTO(
"Cannot load the TF", cleanup_caltf);
420 vis_calibs[nb_calib] = vis_calib;
425 FREE (gravi_data_delete,vis_calib);
426 cpl_errorstate_set (errorstate);
430 cpl_msg_info (cpl_func,
"*** All TF computed or loaded ***");
432 cpl_msg_info (cpl_func,
"Load or create successfully %i TF over %i input CAL files", nb_calib, nb_frame_calib + nb_frame_tf);
438 if ( nb_calib > 1 ) {
439 errorstate = cpl_errorstate_get();
441 cpl_msg_info (cpl_func,
"*** Compute the zero of the metrology -- FIXME: to be done ***");
442 zero_data = gravi_compute_zp (vis_calibs, nb_calib);
444 CPLCHECK_GOTO(
"Cannot compute ZP", cleanup_zp);
446 gravi_data_save_new (zero_data, frameset,
"output.fits", parlist,
447 used_frameset, NULL,
"gravity_vis",
450 CPLCHECK_GOTO(
"Cannot save ZP", cleanup_zp);
453 FREE (gravi_data_delete,zero_data);
454 cpl_errorstate_set (errorstate);
462 for (i = 0; i < nb_frame_sci; i++){
463 errorstate = cpl_errorstate_get();
464 current_frameset = cpl_frameset_duplicate (used_frameset);
466 cpl_msg_info (cpl_func,
"*** Calibration of file %i over %i ***", i+1, nb_frame_sci);
468 frame = cpl_frameset_get_position (vis_sci_frameset, i);
469 vis_data = gravi_data_load_frame (frame, current_frameset);
471 tf_science = gravi_data_duplicate (vis_data);
472 calibrated = gravi_calibrate_vis (vis_data, vis_calibs, nb_calib, zero_data, tf_science, parlist);
474 CPLCHECK_GOTO(
"Cannot calibrate the visibility", cleanup_calib);
477 data_mode = gravi_data_frame_get_mode (frame);
479 gravi_data_save_new (calibrated, frameset, NULL, parlist,
480 current_frameset, frame,
"gravity_vis",
481 NULL, GRAVI_VIS_CALIBRATED(data_mode));
483 CPLCHECK_GOTO(
"Cannot save the calibrated visibility", cleanup_calib);
486 data_mode = gravi_data_frame_get_mode (frame);
488 gravi_data_save_new (tf_science, frameset, NULL, parlist,
489 current_frameset, frame,
"gravity_vis", NULL,
490 GRAVI_TF_SCIENCE(data_mode));
492 CPLCHECK_GOTO(
"Cannot save the TF interpolated for this visibility", cleanup_calib);
495 FREE (gravi_data_delete,vis_data);
496 FREE (gravi_data_delete,tf_science);
497 FREE (gravi_data_delete,calibrated);
498 FREE (cpl_propertylist_delete,applist);
499 FREE (cpl_frameset_delete,current_frameset);
500 cpl_errorstate_set (errorstate);
509 cpl_msg_info(cpl_func,
"Memory cleanup");
511 FREE (gravi_data_delete,diamcat_data);
512 FREE (gravi_data_delete,zero_data);
513 FREE (cpl_frameset_delete,tf_calib_frameset);
514 FREE (cpl_frameset_delete,vis_calib_frameset);
515 FREE (cpl_frameset_delete,vis_sci_frameset);
516 FREE (cpl_frameset_delete,diamcat_frameset);
517 FREE (cpl_frameset_delete,current_frameset);
518 FREE (cpl_frameset_delete,used_frameset);
519 FREELOOP (gravi_data_delete,vis_calibs,nb_frame_calib+nb_frame_tf);
521 gravi_msg_function_exit(1);
522 return (
int)cpl_error_get_code();