GRAVI Pipeline Reference Manual  1.2.3
gravi_image.c
1 /* $Id: gravi_dfs.c,v 1.6 2011/04/31 06:10:40 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 
29 /*-----------------------------------------------------------------------------
30  Includes
31  -----------------------------------------------------------------------------*/
32 
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36 
37 #include <string.h>
38 #include <math.h>
39 #include <cpl.h>
40 #include <time.h>
41 #include <sys/wait.h>
42 #include <signal.h>
43 
44 #include "gravi_image.h"
45 #include "gravi_utils.h"
46 
47 const int GRAVI_ERROR_TIMEOUT = 0 + CPL_ERROR_EOL;
48 
49 /*-----------------------------------------------------------------------------
50  Functions code
51  -----------------------------------------------------------------------------*/
52 
53 
54 /*----------------------------------------------------------------------------*/
65 /*----------------------------------------------------------------------------*/
66 
67 #ifdef YORICK_BIN
68 cpl_image * gravi_image(const cpl_frame * input_frame,
69  const cpl_parameterlist * input_param,
70  const char* target_name)
71 {
72  //cpl_errorstate prestate = cpl_errorstate_get();
73  cpl_image * reconstruct_image;
74  const char *input_filename;
75  int status;
76  char path[1035];
77  int dim=0;
78  double * image_buffer=NULL;
79  int pid; // No process
80  int cf_pipe[2]; // Child to father pipe
81  char* pixelsize_option, *dim_option, *regul_option, *regul_mu_option,
82  *maxeval_option;
83  const cpl_parameter * param;
84  double val;
85  int i;
86  char *yorick_argv[21];
87  int argv_i;
88  double timeout;
89  char * s;
90 
91  /* get the raw file name */
92  input_filename=cpl_frame_get_filename(input_frame);
93  cpl_msg_info(cpl_func, "Input filename ok %s", input_filename);
94  if (input_filename==NULL) {
95  cpl_error_set_message(cpl_func, cpl_error_get_code(),
96  "Could not retrieve the input "
97  "filename");
98  return(NULL);
99  }
100 
101  /* generate the yorick argument table */
102  argv_i=0;
103  yorick_argv[argv_i++] = cpl_sprintf("%s",YORICK_BIN);
104  yorick_argv[argv_i++] = cpl_sprintf("-batch");
105  FILE *file;
106  file=fopen(YORICK_MIRA,"r");
107  if(file!=NULL) {
108  // file exists
109  yorick_argv[argv_i++] = cpl_sprintf("%s",YORICK_MIRA);
110  cpl_msg_info(cpl_func, "Mira is there: %s", yorick_argv[argv_i-1]);
111  fclose(file);
112  }
113  else {
114  yorick_argv[argv_i++] = cpl_sprintf("%s/mira-script.i",MIRADIR);
115  cpl_msg_info(cpl_func, "Mira is there: %s", yorick_argv[argv_i-1]);
116  //File not found
117  }
118  //yorick_argv[argv_i++] = cpl_sprintf("%s",YORICK_MIRA);
119 
120  /* RETRIEVE INPUT PARAMETERS */
121  cpl_errorstate prestate = cpl_errorstate_get();
122 
123  /* --pixelsize */
124  param = cpl_parameterlist_find_const(input_param,
125  "gravi.gravity_image.pixelsize");
126  pixelsize_option=cpl_sprintf("-pixelsize=%g",
127  cpl_parameter_get_double(param));
128  yorick_argv[argv_i++]=pixelsize_option;
129 
130  /* --dim */
131  param = cpl_parameterlist_find_const(input_param,
132  "gravi.gravity_image.dim");
133  dim=cpl_parameter_get_int(param);
134  dim_option=cpl_sprintf("-dim=%d", dim);
135  yorick_argv[argv_i++]=dim_option;
136 
137  /* --regul */
138  param = cpl_parameterlist_find_const(input_param,
139  "gravi.gravity_image.regul");
140  regul_option=cpl_sprintf("--regul=%s", cpl_parameter_get_string(param));
141  yorick_argv[argv_i++]=regul_option;
142 
143  /* --regul_mu */
144  param = cpl_parameterlist_find_const(input_param,
145  "gravi.gravity_image.regul_mu");
146  regul_mu_option=cpl_sprintf("--regul_mu=%g",
147  cpl_parameter_get_double(param));
148  yorick_argv[argv_i++]=regul_mu_option;
149 
150  /* --maxeval */
151  param = cpl_parameterlist_find_const(input_param,
152  "gravi.gravity_image.maxeval");
153  maxeval_option=cpl_sprintf("-maxeval=%d", cpl_parameter_get_int(param));
154  yorick_argv[argv_i++]=maxeval_option;
155 
156  if (!cpl_errorstate_is_equal(prestate)) {
157  cpl_error_set_message(cpl_func, cpl_error_get_code(),
158  "Could not retrieve the input "
159  "parameters");
160  for (i=0; i<argv_i-1; i++) cpl_free(yorick_argv[i]);
161  return(NULL);
162  }
163 
164  /* Other arguments */
165  yorick_argv[argv_i++] = cpl_sprintf("-regul_isotropic");
166  yorick_argv[argv_i++] = cpl_sprintf("-ftol=0");
167  yorick_argv[argv_i++] = cpl_sprintf("-gtol=0");
168  yorick_argv[argv_i++] = cpl_sprintf("-overwrite");
169  yorick_argv[argv_i++] = cpl_sprintf("-normalization=1.0");
170  yorick_argv[argv_i++] = cpl_sprintf("-xmin=0.0");
171  yorick_argv[argv_i++] = cpl_sprintf("-target=%s", target_name);
172  yorick_argv[argv_i++] = cpl_sprintf("%s",input_filename);
173  yorick_argv[argv_i++] = cpl_sprintf("./output_temp.fits"); // not used by mira-script.i
174  yorick_argv[argv_i++] = NULL;
175 
176  /* Get the timeout parameter */
177  param = cpl_parameterlist_find_const(input_param,
178  "gravi.gravity_image.timeout");
179  timeout=cpl_parameter_get_double(param);
180 
181  /* Create the pipe */
182  if (pipe(cf_pipe) != 0)
183  {
184  cpl_error_set_message(cpl_func, CPL_ERROR_ASSIGNING_STREAM,
185  "Could not create pipe for Yorick process.");
186  for (i=0; i<argv_i-1; i++) cpl_free(yorick_argv[i]);
187  return NULL;
188  }
189 
190  /* Create the child process to execute Yorick/Mira */
191  switch(pid=fork())
192  {
193  /* Fork error */
194  case (-1): // fork error
195  cpl_error_set_message(cpl_func, CPL_ERROR_UNSPECIFIED,
196  "Could not create the fork Yorick process.");
197  for (i=0; i<argv_i-1; i++) cpl_free(yorick_argv[i]);
198  return NULL;
199 
200  /* Child process (Yorick mira) : stdout to pipe*/
201  case 0:
202  cpl_msg_info(cpl_func, "Start Yorick process (pid: %u)", getpid());
203 
204  /* Close the unused side */
205  close(cf_pipe[0]);
206 
207  /* redirect stdout to the pipe */
208  dup2(cf_pipe[1], STDOUT_FILENO);
209 
210  /* Execute the mira script */
211  if (execv(yorick_argv[0], yorick_argv) == -1 ){
212  cpl_msg_error("MIRA/Yorick", "Error in Yorick call (%s)",
213  YORICK_BIN);
214  }
215 
216  // Child process stop
217  printf("Child process (%d) - Stop\n", getpid());
218  fflush(NULL);
219  exit(0);
220 
221  /* Parent process : stdin from pipe */
222  default:
223 
224  /* Close the unused side of the pipe */
225  close(cf_pipe[1]);
226 
227  /* Redirect the pipe output to STDIN */
228  dup2(cf_pipe[0], STDIN_FILENO);
229 
230  /* Read the output a line at a time - output it. */
231  time_t ticks1, ticks2;
232 
233 
234  ticks1=time(NULL);
235  while (fgets(path, sizeof(path)-1, stdin) != NULL) {
236  /* IMAGE */
237 
238  /* delete the trailing \n */
239  if ( (s=strrchr(path, '\n') )) s[0]='\0';
240 
241  if (strncmp(path, "START_IMAGE", strlen(path)-1) == 0){
242  cpl_msg_info(cpl_func, "Receive image");
243  image_buffer=cpl_malloc(sizeof(double)*dim*dim);
244  /* get the image pixels */
245  i=0;
246  while (fgets(path, sizeof(path)-1, stdin) != NULL &&
247  strncmp(path, "END_IMAGE", strlen(path)-1) != 0){
248  sscanf(path, "%lg", &val);
249  image_buffer[i++]=val;
250  }
251  //printf("Image end \n");
252  }
253  /* MIRA WARNING */
254  else if (strncmp(path, "WARNING", 7) == 0){
255  cpl_msg_warning("MIRA/Yorick", "%s", path);
256  }
257  /* MIRA WARNING */
258  else if (strncmp(path, "# warning", 9) == 0){
259  cpl_msg_warning("MIRA/Yorick", "%s", path);
260  }
261  /* MIRA ERROR */
262  else if (strncmp(path, "ERROR", 5) == 0){
263  cpl_msg_error("MIRA/Yorick", "%s", path);
264  }
265  /* MIRA INFO */
266  else {
267  cpl_msg_info("MIRA/Yorick", "%s", path);
268  }
269 
270  ticks2=time(NULL);
271  if (difftime(ticks2,ticks1) > timeout)
272  {
273  cpl_error_set_message(cpl_func, GRAVI_ERROR_TIMEOUT,
274  "Timeout (%g s) MIRA/Yorick process "
275  "killed. Use --timeout option to change it.", timeout);
276  cpl_msg_error(cpl_func, "Timeout MIRA/Yorick process Killed");
277  kill((pid_t) pid, SIGKILL);
278  }
279  }
280  /* wait end of child process */
281  wait(&status);
282  cpl_msg_info(cpl_func, "End of Yorick process (pid: %u with satus %d)",
283  pid, status);
284  /* Create reconstructed image */
285  if (image_buffer==NULL){
286  cpl_error_set_message(cpl_func, CPL_ERROR_NULL_INPUT,
287  "Could not get image from Yorick process.");
288  for (i=0; i<argv_i-1; i++) cpl_free(yorick_argv[i]);
289  return(NULL);
290  }
291  reconstruct_image = cpl_image_wrap_double(dim, dim, image_buffer);
292  }
293 
294  for (i=0; i<argv_i-1; i++) cpl_free(yorick_argv[i]);
295  return reconstruct_image;
296 }
297 #endif
298