HAWKI Pipeline Reference Manual  1.8.12
hawki_step_apply_dist.c
1 /* $Id: hawki_step_apply_dist.c,v 1.10 2011/03/09 10:48:38 cgarcia Exp $
2  *
3  * This file is part of the HAWKI 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: cgarcia $
23  * $Date: 2011/03/09 10:48:38 $
24  * $Revision: 1.10 $
25  * $Name: hawki-1_8_12 $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include <math.h>
37 #include <cpl.h>
38 
39 #include "irplib_utils.h"
40 
41 #include "hawki_utils.h"
42 #include "hawki_pfits.h"
43 #include "hawki_dfs.h"
44 #include "hawki_load.h"
45 #include "hawki_save.h"
46 #include "hawki_distortion.h"
47 
48 /*-----------------------------------------------------------------------------
49  Functions prototypes
50  -----------------------------------------------------------------------------*/
51 
52 static int hawki_step_apply_dist_create(cpl_plugin *) ;
53 static int hawki_step_apply_dist_exec(cpl_plugin *) ;
54 static int hawki_step_apply_dist_destroy(cpl_plugin *) ;
55 static int hawki_step_apply_dist(cpl_parameterlist *, cpl_frameset *) ;
56 static int hawki_step_apply_dist_save
57 (cpl_imagelist * images,
58  int iserie,
59  cpl_parameterlist * recipe_parlist,
60  cpl_frameset * used_frameset,
61  cpl_frameset * recipe_frameset);
62 
63 int hawki_step_apply_dist_compute_and_save
64 (cpl_frameset * objects,
65  cpl_frameset * distortion_x,
66  cpl_frameset * distortion_y,
67  cpl_parameterlist * parlist,
68  cpl_frameset * recipe_frameset);
69 
70 /*-----------------------------------------------------------------------------
71  Static variables
72  -----------------------------------------------------------------------------*/
73 
74 static char hawki_step_apply_dist_description[] =
75 "hawki_step_apply_dist -- Distortion correction utility\n"
76 "This recipe accepts three types of frames:\n"
77 "object.fits Images to correct (PRO.CATG = "HAWKI_CALPRO_BKG_SUBTRACTED")\n"
78 "distmap_x.fits The image with the distortion in X.\n"
79 " (PRO CATG = "HAWKI_CALPRO_DISTORTION_X")\n"
80 "distmap_y.fits The image with the distortion in Y.\n"
81 " (PRO CATG = "HAWKI_CALPRO_DISTORTION_Y")\n"
82 "\n"
83 "This recipe produces:\n"
84 "hawki_step_apply_dist.fits: the corrected image.\n"
85 " (PRO CATG = "HAWKI_CALPRO_DIST_CORRECTED")\n" ;
86 
87 /*-----------------------------------------------------------------------------
88  Functions code
89  -----------------------------------------------------------------------------*/
90 
91 /*----------------------------------------------------------------------------*/
100 /*----------------------------------------------------------------------------*/
101 int cpl_plugin_get_info(cpl_pluginlist * list)
102 {
103  cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe ) ;
104  cpl_plugin * plugin = &recipe->interface ;
105 
106  cpl_plugin_init(plugin,
107  CPL_PLUGIN_API,
108  HAWKI_BINARY_VERSION,
109  CPL_PLUGIN_TYPE_RECIPE,
110  "hawki_step_apply_dist",
111  "Distortion correction utility",
112  hawki_step_apply_dist_description,
113  "Cesar Enrique Garcia Dabo",
114  PACKAGE_BUGREPORT,
116  hawki_step_apply_dist_create,
117  hawki_step_apply_dist_exec,
118  hawki_step_apply_dist_destroy) ;
119 
120  cpl_pluginlist_append(list, plugin) ;
121 
122  return 0;
123 }
124 
125 /*----------------------------------------------------------------------------*/
133 /*----------------------------------------------------------------------------*/
134 static int hawki_step_apply_dist_create(cpl_plugin * plugin)
135 {
136  cpl_recipe * recipe ;
137 
138  /* Check that the plugin is part of a valid recipe */
139  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
140  recipe = (cpl_recipe *)plugin ;
141  else return -1 ;
142 
143  /* Create the parameters list in the cpl_recipe object */
144  recipe->parameters = cpl_parameterlist_new() ;
145 
146  /* Return */
147  return 0;
148 }
149 
150 /*----------------------------------------------------------------------------*/
156 /*----------------------------------------------------------------------------*/
157 static int hawki_step_apply_dist_exec(cpl_plugin * plugin)
158 {
159  cpl_recipe * recipe ;
160 
161  /* Get the recipe out of the plugin */
162  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
163  recipe = (cpl_recipe *)plugin ;
164  else return -1 ;
165 
166  /* Issue a banner */
168 
169  return hawki_step_apply_dist(recipe->parameters, recipe->frames) ;
170 }
171 
172 /*----------------------------------------------------------------------------*/
178 /*----------------------------------------------------------------------------*/
179 static int hawki_step_apply_dist_destroy(cpl_plugin * plugin)
180 {
181  cpl_recipe * recipe ;
182 
183  /* Get the recipe out of the plugin */
184  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
185  recipe = (cpl_recipe *)plugin ;
186  else return -1 ;
187 
188  cpl_parameterlist_delete(recipe->parameters) ;
189  return 0 ;
190 }
191 
192 /*----------------------------------------------------------------------------*/
199 /*----------------------------------------------------------------------------*/
200 static int hawki_step_apply_dist(
201  cpl_parameterlist * parlist,
202  cpl_frameset * frameset)
203 {
204  cpl_frameset * objframes;
205  cpl_frameset * distortion_x;
206  cpl_frameset * distortion_y;
207 
208  /* Retrieve input parameters */
209 
210  /* Identify the RAW and CALIB frames in the input frameset */
211  if (hawki_dfs_set_groups(frameset)) {
212  cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
213  return -1 ;
214  }
215 
216  /* Identifying objects frames */
217  cpl_msg_info(__func__, "Identifying objects");
218  objframes = hawki_extract_frameset
219  (frameset, HAWKI_CALPRO_BKG_SUBTRACTED);
220  if (objframes == NULL)
221  {
222  cpl_msg_error(__func__, "No object frames provided (%s)",
223  HAWKI_CALPRO_BKG_SUBTRACTED);
224  return -1 ;
225  }
226 
227  /* Identifying distortion frames */
228  cpl_msg_info(__func__, "Identifying distortion maps");
229  distortion_x = hawki_extract_frameset
230  (frameset, HAWKI_CALPRO_DISTORTION_X);
231  distortion_y = hawki_extract_frameset
232  (frameset, HAWKI_CALPRO_DISTORTION_Y);
233  if(cpl_frameset_get_size(distortion_x) != 1 &&
234  cpl_frameset_get_size(distortion_y) != 1 )
235  {
236  cpl_msg_error(__func__, "One X-distortion frame and one Y-distortion "
237  "must be provided (%s, %s)",
238  HAWKI_CALPRO_DISTORTION_X, HAWKI_CALPRO_DISTORTION_Y);
239  cpl_frameset_delete(objframes);
240  cpl_frameset_delete(distortion_x);
241  cpl_frameset_delete(distortion_y);
242  return -1 ;
243  }
244 
245  /* Apply the correction and save */
246  if(hawki_step_apply_dist_compute_and_save
247  (objframes, distortion_x, distortion_y, parlist, frameset) == -1)
248  {
249  cpl_msg_error(__func__,"Could not correct the frames");
250  cpl_frameset_delete(objframes);
251  cpl_frameset_delete(distortion_x);
252  cpl_frameset_delete(distortion_y);
253  return -1;
254  }
255 
256  /* Free and return */
257  cpl_frameset_delete(objframes);
258  cpl_frameset_delete(distortion_x);
259  cpl_frameset_delete(distortion_y);
260 
261  /* Return */
262  if (cpl_error_get_code())
263  {
264  cpl_msg_error(__func__,
265  "HAWK-I pipeline could not recover from previous errors");
266  return -1 ;
267  }
268  else return 0 ;
269 }
270 
271 /*----------------------------------------------------------------------------*/
280 /*----------------------------------------------------------------------------*/
281 int hawki_step_apply_dist_compute_and_save
282 (cpl_frameset * objects,
283  cpl_frameset * distortion_x,
284  cpl_frameset * distortion_y,
285  cpl_parameterlist * parlist,
286  cpl_frameset * recipe_frameset)
287 {
288  const cpl_frame * distframe_x;
289  const cpl_frame * distframe_y;
290  cpl_image ** dist_x;
291  cpl_image ** dist_y;
292  cpl_image * first_image;
293  int nx;
294  int ny;
295  int iframe;
296  int nframes;
297  int idet;
298  int jdet;
299  cpl_errorstate error_prevstate = cpl_errorstate_get();
300 
301  /* Get the distortion filename and distortion maps */
302  cpl_msg_info(__func__,"Creating the distortion maps");
303  distframe_x = cpl_frameset_get_first_const(distortion_x);
304  distframe_y = cpl_frameset_get_first_const(distortion_y);
305  first_image = hawki_load_image(objects, 0, 1, CPL_TYPE_FLOAT);
306  nx = cpl_image_get_size_x(first_image);
307  ny = cpl_image_get_size_y(first_image);
308  cpl_image_delete(first_image);
309  dist_x = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_image *));
310  dist_y = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_image *));
311  for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
312  {
313  hawki_distortion * distortion;
314  dist_x[idet] = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
315  dist_y[idet] = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE) ;
316 
317  /* Load the distortion */
318  if ((distortion = hawki_distortion_load
319  (distframe_x, distframe_y , idet+1)) == NULL)
320  {
321  cpl_msg_error(__func__, "Cannot load the distortion for chip %d: %s",
322  idet+1, cpl_error_get_message());
323  for (jdet=0 ; jdet<=idet; jdet++)
324  {
325  cpl_image_delete(dist_x[jdet]);
326  cpl_image_delete(dist_y[jdet]);
327  }
328  cpl_free(dist_x);
329  cpl_free(dist_y);
330  return -1 ;
331  }
332  if (hawki_distortion_create_maps_detector
333  (distortion, dist_x[idet], dist_y[idet]))
334  {
335  cpl_msg_error(__func__, "Cannot create the distortion maps") ;
336  for (jdet=0 ; jdet<=idet; jdet++)
337  {
338  cpl_image_delete(dist_x[jdet]);
339  cpl_image_delete(dist_y[jdet]);
340  }
341  cpl_free(dist_x);
342  cpl_free(dist_y);
343  hawki_distortion_delete(distortion);
344  return -1;
345  }
346  hawki_distortion_delete(distortion);
347  }
348 
349  /* Loop on frames */
350  nframes = cpl_frameset_get_size(objects);
351  cpl_msg_info(__func__,"Number of frames to process: %d", nframes);
352  cpl_msg_indent_more();
353  for(iframe = 0 ; iframe < nframes; ++iframe)
354  {
355  cpl_imagelist * object_images;
356  cpl_frame * this_frame;
357  cpl_frameset * used_frameset;
358 
359  /* Msg */
360  cpl_msg_info(__func__,"Correcting distortion in frame %d",iframe+1);
361 
362  /* Load the HAWKI images */
363  this_frame = cpl_frameset_get_frame(objects, iframe);
364  if((object_images = hawki_load_frame(this_frame, CPL_TYPE_FLOAT)) == NULL)
365  {
366  cpl_msg_error(__func__,"Could not load input object images");
367  cpl_msg_indent_less();
368  for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
369  {
370  cpl_image_delete(dist_x[idet]);
371  cpl_image_delete(dist_y[idet]);
372  }
373  cpl_free(dist_x);
374  cpl_free(dist_y);
375  return -1;
376  }
377 
378  /* Apply the correction on the current image */
379  if (hawki_distortion_apply_maps(object_images, dist_x, dist_y) == -1)
380  {
381  cpl_msg_error(__func__, "Cannot correct distortion") ;
382  cpl_msg_indent_less();
383  cpl_imagelist_delete(object_images);
384  for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
385  {
386  cpl_image_delete(dist_x[idet]);
387  cpl_image_delete(dist_y[idet]);
388  }
389  cpl_free(dist_x);
390  cpl_free(dist_y);
391  return -1 ;
392  }
393 
394  /* Set the used frameset */
395  used_frameset = cpl_frameset_new();
396  cpl_frameset_insert(used_frameset, cpl_frame_duplicate(this_frame));
397  cpl_frameset_insert
398  (used_frameset,cpl_frame_duplicate
399  (cpl_frameset_get_first_const((distortion_x))));
400  cpl_frameset_insert
401  (used_frameset,cpl_frame_duplicate
402  (cpl_frameset_get_first_const((distortion_y))));
403 
404  /* Save the corrected image */
405  if (hawki_step_apply_dist_save
406  (object_images, iframe,
407  parlist, used_frameset, recipe_frameset) == -1)
408  {
409  cpl_errorstate_set(CPL_ERROR_NONE);
410  }
411 
412  /* Free resources */
413  cpl_frameset_delete(used_frameset);
414  cpl_imagelist_delete(object_images);
415 
416  }
417  cpl_msg_indent_less();
418 
419  for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
420  {
421  cpl_image_delete(dist_x[idet]);
422  cpl_image_delete(dist_y[idet]);
423  }
424  cpl_free(dist_x);
425  cpl_free(dist_y);
426  if(!cpl_errorstate_is_equal(error_prevstate))
427  {
428  cpl_msg_warning(__func__,"Probably some data could not be saved. "
429  "Check permisions or disk space");
430  }
431  return 0;
432 }
433 
434 /*----------------------------------------------------------------------------*/
443 /*----------------------------------------------------------------------------*/
444 static int hawki_step_apply_dist_save
445 (cpl_imagelist * images,
446  int iserie,
447  cpl_parameterlist * recipe_parlist,
448  cpl_frameset * used_frameset,
449  cpl_frameset * recipe_frameset)
450 {
451  const cpl_frame * raw_reference;
452  cpl_propertylist ** extproplists;
453  char filename[256] ;
454  cpl_propertylist * inputlist ;
455  int ext_nb ;
456  const char * recipe_name = "hawki_step_apply_dist";
457  int idet;
458 
459  /* Get the reference frame (the raw frame) */
460  raw_reference = irplib_frameset_get_first_from_group
461  (used_frameset, CPL_FRAME_GROUP_RAW);
462 
463  /* Create the prop lists */
464  cpl_msg_indent_more();
465  extproplists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*));
466  for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
467  {
468  /* Get the extension number */
470  (cpl_frame_get_filename(raw_reference), idet+1);
471 
472  /* Allocate this property list */
473  extproplists[idet] = cpl_propertylist_new();
474 
475  /* Propagate some keywords from input raw frame extensions */
476  inputlist = cpl_propertylist_load_regexp(
477  cpl_frame_get_filename(raw_reference), ext_nb,
478  HAWKI_HEADER_EXT_FORWARD, 0);
479  cpl_propertylist_append(extproplists[idet], inputlist);
480  cpl_propertylist_delete(inputlist);
481  inputlist = cpl_propertylist_load_regexp(
482  cpl_frame_get_filename(raw_reference), ext_nb,
483  HAWKI_HEADER_WCS, 0);
484  cpl_propertylist_append(extproplists[idet], inputlist);
485  cpl_propertylist_delete(inputlist);
486  }
487 
488  /* Write the image */
489  snprintf(filename, 256, "hawki_step_apply_dist_%03d.fits", iserie+1);
491  (recipe_frameset,
492  recipe_parlist,
493  used_frameset,
494  images,
495  recipe_name,
496  HAWKI_CALPRO_DIST_CORRECTED,
497  HAWKI_PROTYPE_DIST_CORRECTED,
498  NULL,
499  (const cpl_propertylist**)extproplists,
500  filename) != 0)
501  {
502  for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
503  cpl_propertylist_delete(extproplists[idet]) ;
504  cpl_free(extproplists) ;
505  cpl_msg_indent_less();
506  return -1;
507  }
508 
509  /* Free and return */
510  for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++) {
511  cpl_propertylist_delete(extproplists[idet]) ;
512  }
513  cpl_free(extproplists) ;
514  cpl_msg_indent_less();
515  return 0;
516 }
517