GRAVI Pipeline Reference Manual  1.2.3
gravity_image.c
1 /* $Id: gravity_image.c,v 1.29 2009/02/10 09:16:12 llundin 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: llundin $
23  * $Date: 2009/02/10 09:16:12 $
24  * $Revision: 1.29 $
25  * $Name: HEAD $
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 <ctype.h>
38 
39 #include "gravi_utils.h"
40 #include "gravi_pfits.h"
41 #include "gravi_dfs.h"
42 #include "gravi_image.h"
43 
44 /*-----------------------------------------------------------------------------
45  Private function prototypes
46  -----------------------------------------------------------------------------*/
47 
48 static int gravity_image_create(cpl_plugin *);
49 static int gravity_image_exec(cpl_plugin *);
50 static int gravity_image_destroy(cpl_plugin *);
51 static int gravity_image(cpl_frameset *, const cpl_parameterlist *);
52 
53 /*-----------------------------------------------------------------------------
54  Static variables
55  -----------------------------------------------------------------------------*/
56 static char gravity_image_short[] = GRAVI_UNOFFERED"Reconstruct an image from visibilities.";
57 static char gravity_image_description[] = GRAVI_UNOFFERED
58 "This recipe launch a Yorick batch executing mira-script.i to process an\n"
59 "input OIFITS file to produce an image in fits file.\n"
60 "The input frame is an OIFITS file :\n"
61 "GRAVI-GRAVI_MIRA-input-file.oifits " GRAVI_MIRA_INPUT_PROCATG "\n"
62 "and the recipe generates a fits image\n"
63 "GRAVI-GRAVI_MIRA-image-file.fits " GRAVI_MIRA_OUTPUT_PROCATG "\n";
64 
65 /*-----------------------------------------------------------------------------
66  Function code
67  -----------------------------------------------------------------------------*/
68 
69 /*----------------------------------------------------------------------------*/
79 /*----------------------------------------------------------------------------*/
80 int cpl_plugin_get_info(cpl_pluginlist * list)
81 {
82  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe );
83  cpl_plugin * plugin = &recipe->interface;
84 
85  if (cpl_plugin_init(plugin,
86  CPL_PLUGIN_API,
87  GRAVI_BINARY_VERSION,
88  CPL_PLUGIN_TYPE_RECIPE,
89  "gravity_image",
90  gravity_image_short,
91  gravity_image_description,
92  "Vincent Lapeyrere",
93  PACKAGE_BUGREPORT,
95  gravity_image_create,
96  gravity_image_exec,
97  gravity_image_destroy)) {
98  cpl_msg_error(cpl_func, "Plugin initialization failed");
99  (void)cpl_error_set_where(cpl_func);
100  return 1;
101  }
102 
103  if (cpl_pluginlist_append(list, plugin)) {
104  cpl_msg_error(cpl_func, "Error adding plugin to list");
105  (void)cpl_error_set_where(cpl_func);
106  return 1;
107  }
108 
109  return 0;
110 }
111 
112 /*----------------------------------------------------------------------------*/
120 /*----------------------------------------------------------------------------*/
121 static int gravity_image_create(cpl_plugin * plugin)
122 {
123  cpl_recipe * recipe;
124  // cpl_parameter * p;
125 
126  /* Do not create the recipe if an error code is already set */
127  if (cpl_error_get_code() != CPL_ERROR_NONE) {
128  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
129  cpl_func, __LINE__, cpl_error_get_where());
130  return (int)cpl_error_get_code();
131  }
132 
133  if (plugin == NULL) {
134  cpl_msg_error(cpl_func, "Null plugin");
135  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
136  }
137 
138  /* Verify plugin type */
139  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
140  cpl_msg_error(cpl_func, "Plugin is not a recipe");
141  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
142  }
143 
144  /* Get the recipe */
145  recipe = (cpl_recipe *)plugin;
146 
147  /* Create the parameters list in the cpl_recipe object */
148  recipe->parameters = cpl_parameterlist_new();
149  if (recipe->parameters == NULL) {
150  cpl_msg_error(cpl_func, "Parameter list allocation failed");
151  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
152  }
153 
154  gravi_parameter_add_image (recipe->parameters);
155 
156  return 0;
157 }
158 
159 /*----------------------------------------------------------------------------*/
165 /*----------------------------------------------------------------------------*/
166 static int gravity_image_exec(cpl_plugin * plugin)
167 {
168 
169  cpl_recipe * recipe;
170  int recipe_status;
171  cpl_errorstate initial_errorstate = cpl_errorstate_get();
172 
173  /* Return immediately if an error code is already set */
174  if (cpl_error_get_code() != CPL_ERROR_NONE) {
175  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
176  cpl_func, __LINE__, cpl_error_get_where());
177  return (int)cpl_error_get_code();
178  }
179 
180  if (plugin == NULL) {
181  cpl_msg_error(cpl_func, "Null plugin");
182  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
183  }
184 
185  /* Verify plugin type */
186  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
187  cpl_msg_error(cpl_func, "Plugin is not a recipe");
188  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
189  }
190 
191  /* Get the recipe */
192  recipe = (cpl_recipe *)plugin;
193 
194  /* Verify parameter and frame lists */
195  if (recipe->parameters == NULL) {
196  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
197  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
198  }
199  if (recipe->frames == NULL) {
200  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
201  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
202  }
203 
204  /* Invoke the recipe */
205  recipe_status = gravity_image(recipe->frames, recipe->parameters);
206 
207  /* Ensure DFS-compliance of the products */
208  if (cpl_dfs_update_product_header(recipe->frames)) {
209  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
210  }
211 
212  if (!cpl_errorstate_is_equal(initial_errorstate)) {
213  /* Dump the error history since recipe execution start.
214  At this point the recipe cannot recover from the error */
215  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL);
216  }
217 
218  return recipe_status;
219 }
220 
221 /*----------------------------------------------------------------------------*/
227 /*----------------------------------------------------------------------------*/
228 static int gravity_image_destroy(cpl_plugin * plugin)
229 {
230  cpl_recipe * recipe;
231 
232  if (plugin == NULL) {
233  cpl_msg_error(cpl_func, "Null plugin");
234  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
235  }
236 
237  /* Verify plugin type */
238  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
239  cpl_msg_error(cpl_func, "Plugin is not a recipe");
240  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
241  }
242 
243  /* Get the recipe */
244  recipe = (cpl_recipe *)plugin;
245 
246  cpl_parameterlist_delete(recipe->parameters);
247 
248  return 0;
249 }
250 
251 /*----------------------------------------------------------------------------*/
258 /*----------------------------------------------------------------------------*/
259 //#define YORICK_BIN 1
260 static int gravity_image(cpl_frameset * frameset,
261  const cpl_parameterlist * parlist)
262 {
263 #ifdef YORICK_BIN
264  const cpl_frame * rawframe;
265  double qc_param = 0.0;
266  cpl_propertylist * applist;
267  cpl_image * image;
268  cpl_frameset * usedframes;
269 
270  /* Use the errorstate to detect an error in a function that does not
271  return an error code. */
272  cpl_errorstate prestate = cpl_errorstate_get();
273 
274  /* RETRIEVE INPUT PARAMETERS */
275  /* No input param to retrieve */
276  if (!cpl_errorstate_is_equal(prestate)) {
277  return (int)cpl_error_set_message(cpl_func, cpl_error_get_code(),
278  "Could not retrieve the input "
279  "parameters");
280  }
281 
282  /* Identify the RAW and CALIB frames in the input frameset */
283  cpl_ensure_code(gravi_dfs_set_groups(frameset) == CPL_ERROR_NONE,
284  cpl_error_get_code());
285 
286  /* ACCESS INPUT DATA */
287  /* Get the image reconstruction INPUT file */
288  rawframe = cpl_frameset_find_const(frameset, GRAVI_MIRA_INPUT_PROCATG);
289  if (rawframe == NULL) {
290  /* cpl_frameset_find_const() does not set an error code, when a frame
291  is not found, so we will set one here. */
292  return (int)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
293  "SOF does not have any file tagged "
294  "with %s", GRAVI_MIRA_INPUT_PROCATG);
295  }
296 
297  /* Check for a change in the CPL error state */
298  /* - if it did change then propagate the error and return */
299  cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code());
300 
301  cpl_msg_set_component_on();
302 
303  /* get file information */
304  const char * filename = cpl_frame_get_filename(rawframe);
305  gravi_data * input_data = gravi_data_load_ext(filename, "OI_TARGET");
306  cpl_table * oi_target_table = gravi_data_get_table(input_data, "OI_TARGET");
307  int n_target = cpl_table_get_nrow(oi_target_table);
308 
309  /* loop on targets */
310  for (int i_target = 0; i_target < n_target; i_target++) {
311 
312  /* NOW PERFORMING THE DATA REDUCTION */
313  /* Execute the gravi_image function */
314  const char *target_name = cpl_table_get_string(oi_target_table, "TARGET", i_target);
315  image = gravi_image(rawframe, parlist, target_name);
316 
317  if (image == NULL) {
318  /* cpl_frameset_find_const() does not set an error code, when a frame
319  is not found, so we will set one here. */
320  return (int)cpl_error_set_message(cpl_func, CPL_ERROR_NULL_INPUT,
321  "The gravi_image function return NULL pointer");
322  }
323 
324  applist = cpl_propertylist_new();
325 
326  /* Add the product category */
327  char proCatg[100];
328  sprintf(proCatg, "%s", GRAVI_MIRA_OUTPUT_PROCATG);
329  cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, proCatg);
330  /* Select the name extension depending on this catg */
331  char catg_ext[100];
332  int i, j=0;
333  for(i = 0; proCatg[i]; i++) if (proCatg[i]!='_') { catg_ext[j] = tolower(proCatg[i]); j++; }
334  catg_ext[j] = '\0';
335 
336  /* Add a QC parameter */
337  cpl_propertylist_append_double(applist, "ESO QC QCPARAM", qc_param);
338 
339  /* SAVE A DFS-COMPLIANT PRODUCT TO DISK*/
340  gravi_dfs_set_groups(frameset);
341 
342  /* create product */
343  usedframes = cpl_frameset_new();
344  cpl_frameset_insert(usedframes, cpl_frame_duplicate(rawframe));
345 
346  cpl_msg_info(cpl_func, "Writing image_out.fits");
347 
348  /* if (cpl_dfs_save_propertylist (frameset, NULL, parlist, usedframes,
349  rawframe, "gravity_image", applist, NULL,
350  PACKAGE "/" PACKAGE_VERSION , "image_out.fits" ) != CPL_ERROR_NONE){
351  cpl_error_set_message(cpl_func, cpl_error_get_code(),
352  "Cannot save the first extension primary header");
353  cpl_image_delete(image);
354  cpl_propertylist_delete(applist);
355  cpl_frameset_delete(usedframes);
356  return cpl_error_get_code();
357  }
358  */
359  /* Save the image extensions */
360  /* if (cpl_image_save(image, "image_out.fits", CPL_BPP_IEEE_DOUBLE,
361  applist, CPL_IO_EXTEND) != CPL_ERROR_NONE){
362  cpl_error_set_message(cpl_func, cpl_error_get_code(),
363  "Cannot save the image extension");
364  cpl_image_delete(image);
365  cpl_propertylist_delete(applist);
366  cpl_frameset_delete(usedframes);
367  return cpl_error_get_code();
368  }
369  */
370 
371  /* Use either the input filename or a name based on recipe */
372  char * product_name = NULL;
373 
374  if ( cpl_parameterlist_find_const (parlist,"gravity.dfs.static-name") &&
375  gravi_param_get_bool (parlist,"gravity.dfs.static-name")) {
376 
377  /* Use the recipe name and add the selected catg_ext */
378  product_name = cpl_sprintf ("%s_%s_%s.fits", "gravity_image", catg_ext, target_name);
379  }
380  else {
381 
382  /* Remove the extension (last '.') and add the selected catg_ext */
383  char * filenoext = cpl_strdup (FILESHORT(filename));
384  char * lastdot = strrchr (filenoext, '.');
385  if (lastdot != NULL) *lastdot = '\0';
386  product_name = cpl_sprintf ("%s_%s_%s.fits", filenoext, catg_ext, target_name);
387  FREE (cpl_free, filenoext);
388  }
389 
390  cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
391  rawframe, image, CPL_BPP_IEEE_DOUBLE,
392  "gravity_image", applist, NULL,
393  PACKAGE "/" PACKAGE_VERSION , product_name);
394  cpl_msg_info(cpl_func, "Reconstructed image saved in image_out.fits");
395 
396  /* free memory */
397  cpl_image_delete(image);
398  cpl_propertylist_delete(applist);
399  cpl_frameset_delete(usedframes);
400  FREE (cpl_free, product_name);
401  } // end loop on target
402  gravi_data_delete(input_data);
403 
404 
405  return (int)cpl_error_get_code();
406 #else
407  return (int)cpl_error_set_message(cpl_func, CPL_ERROR_NULL_INPUT,
408  "This recipe is only available if "
409  "the pipeline was compiled with yorick "
410  "support. Check configure --help");
411 #endif
412 }
gravi_data * gravi_data_load_ext(const char *filename, const char *extensions_regexp)
Low-level function to load FITS file.
Definition: gravi_data.c:448
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_table * gravi_data_get_table(gravi_data *self, const char *extname)
Return a pointer on a table extension by its EXTNAME.
Definition: gravi_data.c:1716
const char * gravi_get_license(void)
Get the pipeline copyright and license.
Definition: gravi_utils.c:104
void gravi_data_delete(gravi_data *self)
Delete a gravi data.
Definition: gravi_data.c:137