GRAVI Pipeline Reference Manual  0.7.12
gravi_all_viscal.c
1 /* $Id: gravi_all_viscal.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 <math.h>
40 #include "gravi_utils.h"
41 #include "gravi_pfits.h"
42 #include "gravi_dfs.h"
43 #include "gravi_calib.h"
44 #include "gravi_vis.h"
45 #include "gravi_data.h"
46 
47 /*-----------------------------------------------------------------------------
48  Private function prototypes
49  -----------------------------------------------------------------------------*/
50 
51 static int gravi_all_viscal_create(cpl_plugin *);
52 static int gravi_all_viscal_exec(cpl_plugin *);
53 static int gravi_all_viscal_destroy(cpl_plugin *);
54 static int gravi_all_viscal(cpl_frameset *, const cpl_parameterlist *);
55 
56 /*-----------------------------------------------------------------------------
57  Static variables
58  -----------------------------------------------------------------------------*/
59 
60 static char gravi_all_viscal_description[] =
61 "This recipe calibrate the visibilities acquired on sicence target using \n"
62 "visibilities acquired on calibrator target. It is used in single mode.\n"
63 "The insput file tags are " VIS_SINGLE_CALIB " and " VIS_SINGLE_SCIENCE "\n"
64 "The output FITS file is an OI_FITS with tag " VIS_SINGLE_CALIBRATED ". It contains , \n"
65 "the values of the visibility complex, squared visibility and the cloture phase.\n"
66 "\n"
67 "Additionally, it should describe functionality of the expected output."
68 "\n";
69 
70 /*-----------------------------------------------------------------------------
71  Function code
72  -----------------------------------------------------------------------------*/
73 
74 /*----------------------------------------------------------------------------*/
84 /*----------------------------------------------------------------------------*/
85 int cpl_plugin_get_info(cpl_pluginlist * list)
86 {
87  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
88  cpl_plugin * plugin = &recipe->interface;
89 
90  if (cpl_plugin_init(plugin,
91  CPL_PLUGIN_API,
92  GRAVI_BINARY_VERSION,
93  CPL_PLUGIN_TYPE_RECIPE,
94  "gravi_all_viscal",
95  "This recipe is used to calibrate the visibilities",
96  gravi_all_viscal_description,
97  "Firstname Lastname",
98  PACKAGE_BUGREPORT,
99  gravi_get_license(),
100  gravi_all_viscal_create,
101  gravi_all_viscal_exec,
102  gravi_all_viscal_destroy)) {
103  cpl_msg_error(cpl_func, "Plugin initialization failed");
104  (void)cpl_error_set_where(cpl_func);
105  return 1;
106  }
107 
108  if (cpl_pluginlist_append(list, plugin)) {
109  cpl_msg_error(cpl_func, "Error adding plugin to list");
110  (void)cpl_error_set_where(cpl_func);
111  return 1;
112  }
113 
114  return 0;
115 }
116 
117 /*----------------------------------------------------------------------------*/
125 /*----------------------------------------------------------------------------*/
126 static int gravi_all_viscal_create(cpl_plugin * plugin)
127 {
128  cpl_recipe * recipe;
129  cpl_parameter * p;
130 
131  /* Do not create the recipe if an error code is already set */
132  if (cpl_error_get_code() != CPL_ERROR_NONE) {
133  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
134  cpl_func, __LINE__, cpl_error_get_where());
135  return (int)cpl_error_get_code();
136  }
137 
138  if (plugin == NULL) {
139  cpl_msg_error(cpl_func, "Null plugin");
140  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
141  }
142 
143  /* Verify plugin type */
144  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
145  cpl_msg_error(cpl_func, "Plugin is not a recipe");
146  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
147  }
148 
149  /* Get the recipe */
150  recipe = (cpl_recipe *)plugin;
151 
152  /* Create the parameters list in the cpl_recipe object */
153  recipe->parameters = cpl_parameterlist_new();
154  if (recipe->parameters == NULL) {
155  cpl_msg_error(cpl_func, "Parameter list allocation failed");
156  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
157  }
158 
159  /* Fill the parameters list */
160 
161  /* --SNR threshold for fringe DET in FT */
162  p = cpl_parameter_new_value("gravi.delta-time-calib",
163  CPL_TYPE_DOUBLE, "Delta time to interpolate the TF [s]", "gravi.gravi_all_viscal", 3600.0);
164  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "delta-time-calib");
165  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
166  cpl_parameterlist_append(recipe->parameters, p);
167 
168  /* --Save the preproc files */
169  p = cpl_parameter_new_value("gravi.force-calib",
170  CPL_TYPE_BOOL, "Force the calibration, don't check setup", "gravi.gravi_all_viscal", FALSE);
171  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "force-calib");
172  cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
173  cpl_parameterlist_append(recipe->parameters, p);
174 
175 
176  return 0;
177 }
178 
179 /*----------------------------------------------------------------------------*/
185 /*----------------------------------------------------------------------------*/
186 static int gravi_all_viscal_exec(cpl_plugin * plugin)
187 {
188 
189  cpl_recipe * recipe;
190  int recipe_status;
191  cpl_errorstate initial_errorstate = cpl_errorstate_get();
192 
193  /* Return immediately if an error code is already set */
194  if (cpl_error_get_code() != CPL_ERROR_NONE) {
195  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
196  cpl_func, __LINE__, cpl_error_get_where());
197  return (int)cpl_error_get_code();
198  }
199 
200  if (plugin == NULL) {
201  cpl_msg_error(cpl_func, "Null plugin");
202  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
203  }
204 
205  /* Verify plugin type */
206  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
207  cpl_msg_error(cpl_func, "Plugin is not a recipe");
208  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
209  }
210 
211  /* Get the recipe */
212  recipe = (cpl_recipe *)plugin;
213 
214  /* Verify parameter and frame lists */
215  if (recipe->parameters == NULL) {
216  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
217  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
218  }
219  if (recipe->frames == NULL) {
220  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
221  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
222  }
223 
224  /* Invoke the recipe */
225  recipe_status = gravi_all_viscal(recipe->frames, recipe->parameters);
226 
227  /* Ensure DFS-compliance of the products */
228 
229  if (cpl_dfs_update_product_header(recipe->frames)) {
230  if (!recipe_status){
231  recipe_status = (int)cpl_error_get_code();
232  }
233  }
234 
235  if (!cpl_errorstate_is_equal(initial_errorstate)) {
236  /* Dump the error history since recipe execution start.
237  At this point the recipe cannot recover from the error */
238  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
239  }
240 
241  return recipe_status;
242 }
243 
244 /*----------------------------------------------------------------------------*/
250 /*----------------------------------------------------------------------------*/
251 static int gravi_all_viscal_destroy(cpl_plugin * plugin)
252 {
253  cpl_recipe * recipe;
254 
255  if (plugin == NULL) {
256  cpl_msg_error(cpl_func, "Null plugin");
257  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
258  }
259 
260  /* Verify plugin type */
261  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
262  cpl_msg_error(cpl_func, "Plugin is not a recipe");
263  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
264  }
265 
266  /* Get the recipe */
267  recipe = (cpl_recipe *)plugin;
268 
269  cpl_parameterlist_delete(recipe->parameters);
270 
271  return 0;
272 }
273 
274 
275 /*----------------------------------------------------------------------------*/
283 /*----------------------------------------------------------------------------*/
284 static int gravi_all_viscal(cpl_frameset * frameset,
285  const cpl_parameterlist * parlist)
286 {
287  cpl_frameset * vis_calib_frameset = NULL, * vis_sci_frameset = NULL, *used_frame = NULL;
288  cpl_frameset * tf_calib_frameset = NULL, * calib_frameset = NULL;
289  cpl_frame * frame = NULL;
290  cpl_propertylist * applist = NULL, * primary_hdr = NULL;
291 
292  cpl_errorstate errorstate;
293 
294  const char * filename = NULL;
295  char * tmp = NULL;
296 
297  gravi_data ** vis_calibs = NULL, *vis_calib = NULL, * zero_data = NULL, * tf_science = NULL;
298  gravi_data * calibrated = NULL, * vis_data = NULL;
299 
300  int nb_frame_tf, nb_frame_calib, nb_frame_sci, i, j, nb_calib = 0;
301  int data_mode;
302 
303  /* Message */
304  cpl_msg_set_time_on();
305  cpl_msg_set_component_on();
306  cpl_msg_info(cpl_func,"Start function");
307 
308  /* Identify the RAW and CALIB frames in the input frameset */
309  cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
310  cpl_error_get_code());
311 
312  /* Extract a set of vis_calib and vis_sci data frameset */
313  vis_calib_frameset = gravi_frameset_extract_vis_calib (frameset);
314  vis_sci_frameset = gravi_frameset_extract_vis_science (frameset);
315  tf_calib_frameset = gravi_frameset_extract_tf_calib (frameset);
316 
317  /* To use this recipe the frameset must contain
318  * at least one VIS_*_CAL frame or TF_*_CAL frame. */
319  if ( cpl_frameset_is_empty(vis_calib_frameset) &&
320  cpl_frameset_is_empty(tf_calib_frameset) ) {
321  FREE (cpl_frameset_delete,vis_calib_frameset);
322  FREE (cpl_frameset_delete,vis_sci_frameset);
323  return (int)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
324  "No VIS_*_CAL frames in the input ");
325  }
326 
327  /* Get the number of the frames contained in the frameset */
328  nb_frame_tf = cpl_frameset_get_size(tf_calib_frameset);
329  nb_frame_calib = cpl_frameset_get_size(vis_calib_frameset);
330  nb_frame_sci = cpl_frameset_get_size(vis_sci_frameset);
331 
332  /*
333  * Load or compute of the transfer function
334  */
335 
336  /* Init memory */
337  vis_calibs = cpl_malloc ( (nb_frame_calib + nb_frame_tf) * sizeof (gravi_data *));
338  for (j = 0; j < (nb_frame_calib + nb_frame_tf); j++) vis_calibs[j] = NULL;
339 
340  /* Init the frameset for all calibration (TF computed and loaded) */
341  calib_frameset = cpl_frameset_new();
342 
343  /* Loop on the TF to compute */
344  for (j = 0; j < nb_frame_calib; j++) {
345  frame = cpl_frameset_get_position (vis_calib_frameset, j);
346  filename = cpl_frame_get_filename (frame);
347 
348  cpl_msg_info (cpl_func, "*** Compute TF: %s (%i over %i) ***", FILESHORT(filename), j+1, nb_frame_calib);
349  errorstate = cpl_errorstate_get();
350 
351  /* Load the VIS data and compute TF */
352  vis_data = gravi_data_load (filename);
353  vis_calib = gravi_compute_tf(vis_data);
354 
355  if ( cpl_error_get_code() != CPL_ERROR_NONE ){
356  cpl_msg_warning(cpl_func, "Cannot compute the TF for file %s", FILESHORT(filename));
357  FREE (gravi_data_delete, vis_data);
358  FREE (gravi_data_delete, vis_calib);
359  cpl_errorstate_set (errorstate);
360  continue;
361  }
362 
363  /* Set PRO.CATG and OIFITS Keywords */
364  primary_hdr = gravi_data_get_propertylist(vis_calib, GRAVI_PRIMARY_HDR_NAME_EXT);
365  applist = gravi_propertylist_get_qc (primary_hdr);
366  data_mode=gravi_data_frame_get_mode(frame);
367  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, TF_CAL_SWITCH(data_mode));
368 
369  /* We use only the current frame to build this product */
370  used_frame = cpl_frameset_new();
371  cpl_frameset_insert(used_frame, cpl_frame_duplicate (frame));
372 
373  /* Save the TF file */
374  // tmp = cpl_sprintf("tf_calib.%s", FILESHORT(filename) );
375  tmp = gravi_data_product_name (filename, "tfcal");
376  gravi_data_save(vis_calib, frameset, tmp, parlist,
377  used_frame, frame, "gravi_all_viscal", applist);
378  cpl_free( tmp );
379 
380  if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
381  cpl_msg_warning(cpl_func, "Cannot save the TF for file %s", FILESHORT(filename));
382  FREE (gravi_data_delete,vis_data);
383  FREE (gravi_data_delete,vis_calib);
384  FREE (cpl_frameset_delete,used_frame);
385  FREE (cpl_propertylist_delete,applist);
386  cpl_errorstate_set (errorstate);
387  continue;
388  }
389 
390  /* Store this successfull TF */
391  vis_calibs[nb_calib] = vis_calib;
392  nb_calib++;
393 
394  /* Update the calib_frameset */
395  /* Update the calib_frameset -- now used as calibration */
396  frame = cpl_frame_duplicate (frame);
397  cpl_frame_set_group (frame, CPL_FRAME_GROUP_CALIB);
398  cpl_frameset_insert (calib_frameset, frame);
399 
400  /* Clean memory of the loop */
401  FREE (gravi_data_delete,vis_data);
402  FREE (cpl_propertylist_delete,applist);
403  FREE (cpl_frameset_delete,used_frame);
404  }
405  /* End loop on the TF to compute */
406 
407  /* Loop on the TF to load */
408  cpl_msg_info (cpl_func,"*** Load already computed TF ***");
409  for (j = 0; j < nb_frame_tf; j++) {
410  frame = cpl_frameset_get_position (tf_calib_frameset, j);
411  filename = cpl_frame_get_filename (frame);
412 
413  cpl_msg_info( cpl_func," %s (%i over %i)", FILESHORT(filename), j+1, nb_frame_tf);
414  errorstate = cpl_errorstate_get();
415 
416  /* Load the TF data */
417  vis_calib = gravi_data_load (filename);
418 
419  if ( cpl_error_get_code() != CPL_ERROR_NONE ){
420  cpl_msg_warning (cpl_func, "Cannot load the TF file %s", FILESHORT(filename));
421  FREE (gravi_data_delete,vis_calib);
422  cpl_errorstate_set (errorstate);
423  continue;
424  }
425 
426  /* Store this successfull TF */
427  vis_calibs[nb_calib] = vis_calib;
428  nb_calib++;
429 
430  /* Update the calib_frameset -- now used as calibration */
431  frame = cpl_frame_duplicate (frame);
432  cpl_frame_set_group (frame, CPL_FRAME_GROUP_CALIB);
433  cpl_frameset_insert (calib_frameset, frame);
434  }
435  /* End loop on TF to load */
436 
437 
438  cpl_msg_info(cpl_func, "Load or create successfully %i TF over %i input CAL files", nb_calib, nb_frame_calib + nb_frame_tf);
439 
440  /*
441  * Compute the zero of the metrology if several TF are availables
442  */
443 
444  if ( nb_calib > 1 ) {
445  errorstate = cpl_errorstate_get();
446 
447  cpl_msg_info (cpl_func, "*** Compute the zero of the metrology -- FIXME: to be done ***");
448  zero_data = gravi_compute_zp (vis_calibs, nb_calib);
449 
450  primary_hdr = gravi_data_get_propertylist(zero_data, GRAVI_PRIMARY_HDR_NAME_EXT);
451  applist = gravi_propertylist_get_qc (primary_hdr);
452 
453  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, ZP_CAL);
454  gravi_data_save(zero_data, frameset, "zero_metrology.fits", parlist,
455  calib_frameset, NULL, "gravi_all_viscal", applist);
456 
457  if ( cpl_error_get_code() != CPL_ERROR_NONE) {
458  cpl_msg_warning(cpl_func, "Cannot save the zero_metrology.fits");
459  FREE (gravi_data_delete,zero_data);
460  cpl_errorstate_set (errorstate);
461  }
462 
463  FREE (cpl_propertylist_delete,applist);
464  }
465 
466  /*
467  * Apply the TF to the SCIENCE files of the frameset
468  */
469 
470  /* Loop on the SCI files to calibrate */
471  for (i = 0; i < nb_frame_sci; i++){
472  frame = cpl_frameset_get_position (vis_sci_frameset, i);
473  filename = cpl_frame_get_filename (frame);
474 
475  cpl_msg_info (cpl_func, "*** Calibration of file %s (%i over %i) ***", FILESHORT(filename), i+1, nb_frame_sci);
476  errorstate = cpl_errorstate_get();
477 
478  vis_data = gravi_data_load (filename);
479  tf_science = gravi_data_duplicate (vis_data);
480  calibrated = gravi_calib_vis (vis_data, vis_calibs, nb_calib, zero_data, tf_science, parlist);
481 
482  if ( cpl_error_get_code() != CPL_ERROR_NONE){
483  cpl_msg_warning(cpl_func, "Cannot calibrate the visibility of file %s", FILESHORT(filename));
484  FREE (gravi_data_delete,vis_data);
485  FREE (gravi_data_delete,tf_science);
486  FREE (gravi_data_delete,calibrated);
487  FREE (cpl_frameset_delete,used_frame);
488  cpl_errorstate_set (errorstate);
489  continue;
490  }
491 
492  /* Used frames are the RAW and all TF */
493  used_frame = cpl_frameset_duplicate (calib_frameset);
494  cpl_frameset_insert (used_frame, cpl_frame_duplicate (frame));
495 
496  /* Set PRO.CATG and OIFITS Keywords */
497  primary_hdr = gravi_data_get_propertylist(calibrated, GRAVI_PRIMARY_HDR_NAME_EXT);
498  applist = gravi_propertylist_get_qc (primary_hdr);
499 
500  if (!strcmp(cpl_frame_get_tag (frame), VIS_SINGLE_SCIENCE))
501  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, VIS_SINGLE_CALIBRATED);
502  else if (!strcmp(cpl_frame_get_tag (frame), VIS_DUAL_SCIENCE))
503  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, VIS_DUAL_CALIBRATED);
504 
505  cpl_propertylist_update_int(gravi_data_get_propertylist(calibrated, GRAVI_OI_VIS_SC_EXT), "OI_REVN", 1);
506  cpl_propertylist_update_int(gravi_data_get_propertylist(calibrated, GRAVI_OI_VIS2_SC_EXT), "OI_REVN", 1);
507  cpl_propertylist_update_int(gravi_data_get_propertylist(calibrated, GRAVI_OI_T3_SC_EXT), "OI_REVN", 1);
508  cpl_propertylist_update_int(gravi_data_get_propertylist(calibrated, GRAVI_OI_WAVELENGTH_SC_EXT), "OI_REVN", 1);
509  cpl_propertylist_update_int(gravi_data_get_propertylist(calibrated, GRAVI_OI_ARRAY_EXT), "OI_REVN", 1);
510 
511  /* Save calibrated visibilities */
512  // tmp = cpl_sprintf("vis_calibrated.%s", FILESHORT(filename) );
513  tmp = gravi_data_product_name (filename, "calibrated");
514  gravi_data_save(calibrated, frameset, tmp, parlist, used_frame, frame, "gravi_all_viscal", applist);
515  FREE (cpl_free,tmp);
516 
517  if( cpl_error_get_code() != CPL_ERROR_NONE) {
518  cpl_msg_warning(cpl_func, "Cannot save the calibrated visibilities for file %s", FILESHORT(filename));
519  FREE (gravi_data_delete,vis_data);
520  FREE (gravi_data_delete,tf_science);
521  FREE (gravi_data_delete,calibrated);
522  FREE (cpl_propertylist_delete,applist);
523  FREE (cpl_frameset_delete,used_frame);
524  cpl_errorstate_set (errorstate);
525  continue;
526  }
527 
528  /* Save TF interpolated at the science visibilities */
529  // tmp = cpl_sprintf("tf_science.%s", FILESHORT(filename) );
530  tmp = gravi_data_product_name (filename, "tfsci");
531  data_mode=gravi_data_frame_get_mode(frame);
532  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, TF_SCI_SWITCH(data_mode));
533  gravi_data_save(tf_science, frameset, tmp, parlist,
534  used_frame, frame, "gravi_all_viscal", applist);
535  FREE (cpl_free,tmp);
536 
537  if ( cpl_error_get_code() != CPL_ERROR_NONE) {
538  cpl_msg_warning(cpl_func, "Cannot save the TF interpolated for file %s", FILESHORT(filename));
539  FREE (gravi_data_delete,vis_data);
540  FREE (gravi_data_delete,tf_science);
541  FREE (gravi_data_delete,calibrated);
542  FREE (cpl_propertylist_delete,applist);
543  FREE (cpl_frameset_delete,used_frame);
544  cpl_errorstate_set (errorstate);
545  continue;
546  }
547 
548  FREE (gravi_data_delete,vis_data);
549  FREE (gravi_data_delete,tf_science);
550  FREE (gravi_data_delete,calibrated);
551  FREE (cpl_propertylist_delete,applist);
552  FREE (cpl_frameset_delete,used_frame);
553  }
554  /* End loop on VIS_*_SCI files to calibrate */
555 
556  /* Deallocation of all remaining variables */
557  FREE (gravi_data_delete,zero_data);
558  FREE (cpl_frameset_delete,tf_calib_frameset);
559  FREE (cpl_frameset_delete,vis_calib_frameset);
560  FREE (cpl_frameset_delete,vis_sci_frameset);
561  FREE (cpl_frameset_delete,used_frame);
562  FREELOOP (gravi_data_delete,vis_calibs,nb_frame_calib+nb_frame_tf);
563 
564  cpl_msg_info(cpl_func,"Exit function");
565  return (int)cpl_error_get_code();
566 }
567 
568