OMEGA Pipeline Reference Manual  1.0.5
omega_illumination.c
1 /* $Id: omega_illumination.c,v 1.3 2011-11-21 10:20:01 agabasch Exp $
2  *
3  * This file is part of the OMEGA 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: agabasch $
23  * $Date: 2011-11-21 10:20:01 $
24  * $Revision: 1.3 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include "omega_recipe.h"
37 #include "omega_utils.h"
38 
58 /*-----------------------------------------------------------------------------
59  Functions prototypes
60  -----------------------------------------------------------------------------*/
61 
62 static int omega_illumination_create(cpl_plugin *) ;
63 static int omega_illumination_exec(cpl_plugin *) ;
64 static int omega_illumination_destroy(cpl_plugin *) ;
65 static int omega_illumination(cpl_frameset *, cpl_parameterlist *) ;
66 static cpl_image *omega_illum_process(cpl_frame *frame, cpl_parameterlist *pars, int ext);
67 static void omega_illum_init(void);
68 static void omega_illum_tidy(void);
69 
70 
71 /* Input and Output structures */
72 static struct {
73  /* Inputs. Parameters */
74  int extnum;
75 
76 }omega_illum_config;
77 
78 static struct {
79 
80  /* Calib frames */
81 
82  /* Products */
83  cpl_image *illum;
84 
85 }ps;
86 
87 #define RECIPE "omega_illumination"
88 
89 /*----------------------------------------------------------------------------*/
98 /*----------------------------------------------------------------------------*/
99 int cpl_plugin_get_info(cpl_pluginlist * list)
100 {
101  cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ;
102  cpl_plugin * plugin = &recipe->interface ;
103 
104  cpl_plugin_init(plugin,
105  CPL_PLUGIN_API,
106  OMEGA_BINARY_VERSION,
107  CPL_PLUGIN_TYPE_RECIPE,
108  "omega_illumination",
109  "OMEGA - Generates a valid illumination correction frame (Calfile 548).",
110  "This recipe is used to derive an illumination correction frame for one \n"
111  "particular chip and filter. The recipe always takes as input a fit of \n"
112  "the illumination correction over the full focal plane for a given filter. \n"
113  "A chip name should also be specified.",
114  "Sandra Castro",
115  "scastro@eso.org",
117  omega_illumination_create,
118  omega_illumination_exec,
119  omega_illumination_destroy) ;
120 
121  cpl_pluginlist_append(list, plugin) ;
122 
123  return 0;
124 }
125 
126 /*----------------------------------------------------------------------------*/
135 /*----------------------------------------------------------------------------*/
136 static int omega_illumination_create(cpl_plugin * plugin)
137 {
138  cpl_recipe * recipe;
139  cpl_parameter * p ;
140 
141  /* Do not create the recipe if an error code is already set */
142  if (cpl_error_get_code() != CPL_ERROR_NONE) {
143  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
144  cpl_func, __LINE__, cpl_error_get_where());
145  return (int)cpl_error_get_code();
146  }
147 
148  if (plugin == NULL) {
149  cpl_msg_error(cpl_func, "Null plugin");
150  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
151  }
152 
153  /* Verify plugin type */
154  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
155  cpl_msg_error(cpl_func, "Plugin is not a recipe");
156  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
157  }
158 
159  /* Get the recipe */
160  recipe = (cpl_recipe *)plugin;
161 
162  /* Create the parameters list in the cpl_recipe object */
163  recipe->parameters = cpl_parameterlist_new() ;
164  if (recipe->parameters == NULL) {
165  cpl_msg_error(cpl_func, "Parameter list allocation failed");
166  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT);
167  }
168 
169  /* Fill the parameters list */
170  p = cpl_parameter_new_value("omega.omega_illumination.ExtensionNumber",
171  CPL_TYPE_INT,
172  "FITS extension number to load (1 to 32). (-1 == all)",
173  "omega_nightsky_flat",
174  -1) ;
175 
176  cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,"ext") ;
177  cpl_parameterlist_append(recipe->parameters, p) ;
178 
179  /* Return */
180  return 0;
181 }
182 
183 /*----------------------------------------------------------------------------*/
189 /*----------------------------------------------------------------------------*/
190 static int omega_illumination_exec(cpl_plugin * plugin)
191 {
192  cpl_recipe * recipe;
193  int recipe_status;
194 
195  /* Return immediately if an error code is already set */
196  if (cpl_error_get_code() != CPL_ERROR_NONE) {
197  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s",
198  cpl_func, __LINE__, cpl_error_get_where());
199  return (int)cpl_error_get_code();
200  }
201 
202  if (plugin == NULL) {
203  cpl_msg_error(cpl_func, "Null plugin");
204  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
205  }
206 
207  /* Verify plugin type */
208  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
209  cpl_msg_error(cpl_func, "Plugin is not a recipe");
210  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
211  }
212 
213  /* Get the recipe */
214  recipe = (cpl_recipe *)plugin;
215 
216  /* Verify parameter and frame lists */
217  if (recipe->parameters == NULL) {
218  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list");
219  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
220  }
221  if (recipe->frames == NULL) {
222  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set");
223  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
224  }
225 
226  /* Invoke the recipe */
227  recipe_status = omega_illumination(recipe->frames, recipe->parameters);
228 
229  /* Ensure DFS-compliance of the products */
230  if (cpl_dfs_update_product_header(recipe->frames)) {
231  if (!recipe_status) recipe_status = (int)cpl_error_get_code();
232  }
233 
234  return recipe_status;
235 
236 }
237 
238 /*----------------------------------------------------------------------------*/
244 /*----------------------------------------------------------------------------*/
245 static int omega_illumination_destroy(cpl_plugin * plugin)
246 {
247  cpl_recipe * recipe;
248 
249  if (plugin == NULL) {
250  cpl_msg_error(cpl_func, "Null plugin");
251  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT);
252  }
253 
254  /* Verify plugin type */
255  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
256  cpl_msg_error(cpl_func, "Plugin is not a recipe");
257  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH);
258  }
259 
260  /* Get the recipe */
261  recipe = (cpl_recipe *)plugin;
262 
263  cpl_parameterlist_delete(recipe->parameters) ;
264 
265  return 0 ;
266 }
267 
268 /*----------------------------------------------------------------------------*/
275 /*----------------------------------------------------------------------------*/
276 static int omega_illumination(cpl_frameset *set, cpl_parameterlist *pars)
277 {
278  int j,jst,jfn,isfirst;
279  char *outfile = NULL;
280 
281  cpl_frame *frame, *product_frame;
282  cpl_parameter *par;
283  cpl_propertylist *qclist;
284 
285  /*Start the recipe */
286  if (!pars) {
287  cpl_msg_error (cpl_func, "Parameters list not found");
288  return -1;
289  }
290 
291  if (cpl_frameset_is_empty(set) == 1) {
292  cpl_msg_error (cpl_func, "Frameset not found");
293  return -1;
294  }
295 
296  /* Retrieve input parameters */
297  par = cpl_parameterlist_find(pars, "omega.omega_illumination.ExtensionNumber") ;
298  omega_illum_config.extnum = cpl_parameter_get_int(par) ;
299 
300  /* Identify the RAW and CALIB frames in the input frameset */
301  if (oc_dfs_set_groups(set)) {
302  cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames") ;
303  return -1 ;
304  }
305 
306  /*Initialized things*/
307  omega_illum_init();
308 
309  /* Verify the frameset contents. */
310  frame = cpl_frameset_find(set,OMEGA_CALIB_ILLFIT);
311  if(frame == NULL){
312  cpl_msg_error(cpl_func,"Cannot find coefficients table in input frameset");
313  omega_illum_tidy();
314  return -1;
315  }
316 
317  /* Loop for each of the image extensions */
318  omega_exten_range(omega_illum_config.extnum,&jst,&jfn);
319  if(omega_illum_config.extnum == 0){
320  cpl_msg_error(cpl_func,"Unsupported extension request, %d",omega_illum_config.extnum);
321  omega_illum_tidy();
322  return -1;
323  }
324 
325  for (j = jst; j <= jfn; j++) {
326  isfirst = (j == jst);
327  cpl_msg_indent_more();
328  cpl_msg_info(cpl_func,".....Working on extension %d.....",j);
329  cpl_msg_indent_less();
330 
331  /* Call processing routine */
332  ps.illum = omega_illum_process(frame, pars, j);
333  if(ps.illum == NULL){
334  cpl_msg_error(cpl_func,"Cannot create illumination correction frame");
335  freespace(outfile);
336  omega_illum_tidy();
337  return -1;
338  }
339 
340  /* Save illumination image */
341  if(isfirst){
342  outfile = cpl_sprintf("%s_%s.fits", INSTRUME,ILLUM_PROCATG);
343  product_frame = omega_product_frame(outfile, ILLUM_PROCATG, CPL_FRAME_TYPE_IMAGE);
344  }
345 
346  cpl_msg_info(cpl_func,"Saving Illumination frame");
347 
348  /* Save Illumination */
349  if(omega_save_image(ps.illum,set,pars,NULL,NULL,CPL_BPP_IEEE_FLOAT,outfile,
350  RECIPE,product_frame,NULL,isfirst) == -1){
351  cpl_msg_error(cpl_func,"Cannot save product %s",ILLUM_PROCATG);
352  freespace(outfile);
353  omega_illum_tidy();
354  return -1;
355  }
356 
357 /*
358  if(omega_illum_save(ps.illum, set, pars, NULL, NULL, outfile, product_frame, isfirst) == -1){
359  cpl_msg_error(cpl_func,"Cannot save product %s",ILLUM_PROCATG);
360  freespace(outfile);
361  omega_illum_tidy();
362  return -1;
363  }
364 */
365  freeimage(ps.illum);
366  ps.illum = NULL;
367 
368  } /* go to next extension */
369 
370  freespace(outfile);
371  omega_illum_tidy();
372 
373  return 0;
374 }
375 
386 static cpl_image *omega_illum_process(cpl_frame *frame, cpl_parameterlist *pars, int ext)
387 {
388 
389  int i = 0;
390  int status = 0;
391  int xsize, ysize;
392  cpl_size pows[2];
393  int dim = 2;
394  float cfs[6];
395  const char *chipid;
396 // cpl_propertylist *plist;
397  cpl_table *objects;
398  cpl_image *illum;
399  cpl_polynomial *poly;
400 
401  /* Assuming that the table has the HIERARCH ESO DET CHIP keywords */
402 // plist = cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),2,"CHIP", 0);
403 
404 /*
405  if((chipid = omega_pfits_get_chipid(plist)) == NULL){
406  cpl_msg_error(cpl_func,"Chip ID not found");
407  freeplist(plist);
408  return NULL;
409  }
410 */
411 
412  /* Another possibility is to get the CHIP ID of a FITS extension. TBD */
413  if((chipid = omega_get_extension_chipid(ext)) == NULL){
414  cpl_msg_error(cpl_func,"CHIP ID not found");
415 // freeplist(plist);
416  return NULL;
417  }
418  cpl_msg_info(cpl_func,"CHIP ID for this extension is %s",chipid);
419 
420  if((objects = cpl_table_load(cpl_frame_get_filename(frame), 1, 0)) == NULL){
421  cpl_msg_error(cpl_func,"NULL input OBJECTS table. %s",cpl_error_get_message());
422 // freeplist(plist);
423  return NULL;
424  }
425 
426  for(i = 0; i < cpl_table_get_nrow(objects); i++){
427  const char *name = cpl_table_get_string(objects,"chip_name",i);
428  status = strcmp(chipid,name);
429  if(status == 0){
430  cfs[0] = cpl_table_get_float(objects,"C_o", i, NULL);
431  cfs[1] = cpl_table_get_float(objects,"C_x", i, NULL);
432  cfs[2] = cpl_table_get_float(objects,"C_y", i, NULL);
433  cfs[3] = cpl_table_get_float(objects,"C_xx", i, NULL);
434  cfs[4] = cpl_table_get_float(objects,"C_xy", i, NULL);
435  cfs[5] = cpl_table_get_float(objects,"C_yy", i, NULL);
436  break;
437  }
438  }
439 
440  if(status != 0){
441  cpl_msg_error(cpl_func,"Cannot find CHIP ID in table");
442  freetable(objects);
443  return NULL;
444  }
445  freetable(objects);
446 
447  omega_pfits_get_chip_size(NULL, &xsize, &ysize);
448 // freeplist(plist);
449 
450  poly = cpl_polynomial_new(dim);
451  pows[0] = 0;
452  pows[1] = 0;
453  cpl_polynomial_set_coeff(poly, pows, cfs[0]);
454  pows[0] = 1;
455  pows[1] = 0;
456  cpl_polynomial_set_coeff(poly, pows, cfs[1]);
457  pows[0] = 0;
458  pows[1] = 1;
459  cpl_polynomial_set_coeff(poly, pows, cfs[2]);
460  pows[0] = 2;
461  pows[1] = 0;
462  cpl_polynomial_set_coeff(poly, pows, cfs[3]);
463  pows[0] = 1;
464  pows[1] = 1;
465  cpl_polynomial_set_coeff(poly, pows, cfs[4]);
466  pows[0] = 0;
467  pows[1] = 2;
468  cpl_polynomial_set_coeff(poly, pows, cfs[5]);
469 
470  illum = cpl_image_new(xsize, ysize, CPL_TYPE_FLOAT);
471  if(cpl_image_fill_polynomial(illum, poly,1,1,1,1) != CPL_ERROR_NONE){
472  cpl_msg_error(cpl_func,"Cannot fill polynomial. %s",cpl_error_get_message());
473  cpl_polynomial_delete(poly);
474  }
475 
476  cpl_polynomial_delete(poly);
477 
478  cpl_image_multiply_scalar(illum, -0.4);
479  cpl_image_exponential(illum, 10);
480 
481  return illum;
482 }
483 
484 
485 /* Initialize the pointers */
486 static void omega_illum_init(void)
487 {
488  ps.illum = NULL;
489 }
490 
491 /*
492  * Free any allocated memory
493  */
494 static void omega_illum_tidy(void)
495 {
496  freeimage(ps.illum);
497 }
498