HAWKI Pipeline Reference Manual  1.8.12
hawki_step_subtract_bkg.c
1 /* $Id: hawki_step_subtract_bkg.c,v 1.18 2012/11/30 14:50:51 cgarcia Exp $
2  *
3  * This file is part of the HAWKI Pipeline
4  * Copyright (C) 2008 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: 2012/11/30 14:50:51 $
24  * $Revision: 1.18 $
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 <string.h>
37 #include <math.h>
38 #include <cpl.h>
39 
40 #include "irplib_utils.h"
41 #include "hawki_utils.h"
42 #include "hawki_load.h"
43 #include "hawki_save.h"
44 #include "hawki_pfits.h"
45 #include "hawki_dfs.h"
46 #include "hawki_calib.h"
47 
48 /*-----------------------------------------------------------------------------
49  Structs
50  -----------------------------------------------------------------------------*/
51 
52 /*-----------------------------------------------------------------------------
53  Functions prototypes
54  -----------------------------------------------------------------------------*/
55 
56 #ifdef __cplusplus
57 extern "C"
58 #endif
59 int cpl_plugin_get_info(cpl_pluginlist * list);
60 
61 static int hawki_step_subtract_bkg_create(cpl_plugin *) ;
62 static int hawki_step_subtract_bkg_exec(cpl_plugin *) ;
63 static int hawki_step_subtract_bkg_destroy(cpl_plugin *) ;
64 static int hawki_step_subtract_bkg(cpl_parameterlist *, cpl_frameset *) ;
65 
66 static int hawki_step_subtract_bkg_apply_one_to_one_save
67 (cpl_frameset * objframes,
68  cpl_frameset * bkgframes,
69  cpl_parameterlist * parlist,
70  cpl_frameset * recipe_framelist);
71 
72 static int hawki_step_subtract_bkg_apply_one_to_all_save
73 (cpl_frameset * objframes,
74  cpl_frameset * bkgframes,
75  cpl_parameterlist * recipe_parlist,
76  cpl_frameset * recipe_framelist);
77 
78 static int hawki_step_subtract_bkg_save
79 (cpl_imagelist * obj_images,
80  int iserie,
81  cpl_frameset * used_frameset,
82  cpl_parameterlist * recipe_parlist,
83  cpl_frameset * recipe_framelist);
84 
85 /*-----------------------------------------------------------------------------
86  Static variables
87  -----------------------------------------------------------------------------*/
88 
89 static char hawki_step_subtract_bkg_description[] =
90 "hawki_step_subtract_bkg -- hawki background subtraction utility.\n"
91 "This recipe will subtract the given background to the science images.\n"
92 "The background can be obtained from the sky or object images\n"
93 "using the hawki_util_compute_bkg utility.\n"
94 "There are two modes of operation:\n"
95 "One single background image that it is subtracted to all object images.\n"
96 "As many background images as objects. A one to one relationship is applied.\n"
97 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
98 "obj_basic_cal-file.fits "HAWKI_CALPRO_BASICCALIBRATED" or\n"
99 "background-file.fits "HAWKI_CALPRO_BKGIMAGE" \n";
100 
101 /*-----------------------------------------------------------------------------
102  Functions code
103  -----------------------------------------------------------------------------*/
104 
105 /*----------------------------------------------------------------------------*/
113 /*----------------------------------------------------------------------------*/
114 int cpl_plugin_get_info(cpl_pluginlist * list)
115 {
116  cpl_recipe * recipe = cpl_calloc(1, sizeof(*recipe)) ;
117  cpl_plugin * plugin = &recipe->interface ;
118 
119  cpl_plugin_init(plugin,
120  CPL_PLUGIN_API,
121  HAWKI_BINARY_VERSION,
122  CPL_PLUGIN_TYPE_RECIPE,
123  "hawki_step_subtract_bkg",
124  "Background subtraction utility",
125  hawki_step_subtract_bkg_description,
126  "Cesar Enrique Garcia Dabo",
127  PACKAGE_BUGREPORT,
129  hawki_step_subtract_bkg_create,
130  hawki_step_subtract_bkg_exec,
131  hawki_step_subtract_bkg_destroy) ;
132 
133  cpl_pluginlist_append(list, plugin) ;
134 
135  return 0;
136 }
137 
138 /*----------------------------------------------------------------------------*/
147 /*----------------------------------------------------------------------------*/
148 static int hawki_step_subtract_bkg_create(cpl_plugin * plugin)
149 {
150  cpl_recipe * recipe ;
151  //cpl_parameter * p ;
152 
153  /* Get the recipe out of the plugin */
154  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
155  recipe = (cpl_recipe *)plugin ;
156  else return -1 ;
157 
158  /* Create the parameters list in the cpl_recipe object */
159  recipe->parameters = cpl_parameterlist_new() ;
160  if (recipe->parameters == NULL)
161  return 1;
162 
163  /* Fill the parameters list */
164  /* None.. */
165 
166  /* Return */
167  return 0;
168 }
169 
170 /*----------------------------------------------------------------------------*/
176 /*----------------------------------------------------------------------------*/
177 static int hawki_step_subtract_bkg_exec(cpl_plugin * plugin)
178 {
179  cpl_recipe * recipe ;
180 
181  /* Get the recipe out of the plugin */
182  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
183  recipe = (cpl_recipe *)plugin ;
184  else return -1 ;
185 
186  /* Issue a banner */
188 
189  return hawki_step_subtract_bkg(recipe->parameters, recipe->frames) ;
190 }
191 
192 /*----------------------------------------------------------------------------*/
198 /*----------------------------------------------------------------------------*/
199 static int hawki_step_subtract_bkg_destroy(cpl_plugin * plugin)
200 {
201  cpl_recipe * recipe ;
202 
203  /* Get the recipe out of the plugin */
204  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
205  recipe = (cpl_recipe *)plugin ;
206  else return -1 ;
207 
208  cpl_parameterlist_delete(recipe->parameters) ;
209  return 0 ;
210 }
211 
212 /*----------------------------------------------------------------------------*/
219 /*----------------------------------------------------------------------------*/
220 static int hawki_step_subtract_bkg(
221  cpl_parameterlist * parlist,
222  cpl_frameset * framelist)
223 {
224  int nobj;
225  int nbkg;
226  cpl_frameset * objframes;
227  cpl_frameset * bkgframes;
228 
229 
230  /* Identify the RAW and CALIB frames in the input frameset */
231  if (hawki_dfs_set_groups(framelist))
232  {
233  cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
234  return -1 ;
235  }
236 
237  /* Identifying objects and bkg data frames */
238  cpl_msg_info(__func__, "Identifying objects and background data");
239  objframes = hawki_extract_frameset
240  (framelist, HAWKI_CALPRO_BASICCALIBRATED);
241  if (objframes == NULL)
242  {
243  cpl_msg_error(__func__, "No object frames provided (%s)",
244  HAWKI_CALPRO_BASICCALIBRATED);
245  return -1 ;
246  }
247  /* Retrieve bkg frames */
248  bkgframes = hawki_extract_frameset
249  (framelist, HAWKI_CALPRO_BKGIMAGE);
250  if (bkgframes == NULL)
251  {
252  cpl_msg_error(__func__, "No background frames provided (%s)",
253  HAWKI_CALPRO_BKGIMAGE);
254  cpl_frameset_delete(objframes);
255  return -1 ;
256  }
257 
258  /* Subtract the background */
259  nobj = cpl_frameset_get_size(objframes);
260  nbkg = cpl_frameset_get_size(bkgframes);
261  if(nobj == nbkg)
262  hawki_step_subtract_bkg_apply_one_to_one_save
263  (objframes, bkgframes, parlist, framelist);
264  else if(nbkg == 1)
265  hawki_step_subtract_bkg_apply_one_to_all_save
266  (objframes, bkgframes, parlist, framelist);
267  else
268  {
269  cpl_msg_error(__func__,"Incompatible number of science and background"
270  " images.");
271  cpl_msg_error(__func__,"Supply only 1 bkg frame or as many as objects");
272  cpl_frameset_delete(objframes);
273  cpl_frameset_delete(bkgframes);
274  return -1;
275  }
276 
277  /* Free resources */
278  cpl_frameset_delete(objframes);
279  cpl_frameset_delete(bkgframes);
280 
281  /* Return */
282  if (cpl_error_get_code())
283  {
284  cpl_msg_error(__func__,
285  "HAWK-I pipeline could not recover from previous errors");
286  return -1 ;
287  }
288  else return 0 ;
289 }
290 
291 /*----------------------------------------------------------------------------*/
300 /*----------------------------------------------------------------------------*/
301 static int hawki_step_subtract_bkg_apply_one_to_one_save
302 (cpl_frameset * objframes,
303  cpl_frameset * bkgframes,
304  cpl_parameterlist * recipe_parlist,
305  cpl_frameset * recipe_framelist)
306 {
307  int iobj;
308  int nobjs;
309 
310  /* Subtract the background to each object frame */
311  cpl_msg_info(__func__,"Using a one to one relation btw objects and bkgs");
312  nobjs = cpl_frameset_get_size(objframes);
313  for(iobj = 0; iobj < nobjs; ++iobj)
314  {
315  cpl_frame * obj_frame = NULL;
316  cpl_frame * bkg_frame = NULL;
317  cpl_imagelist * obj_images = NULL;
318  cpl_imagelist * bkg_images = NULL;
319  cpl_frameset * used_frameset;
320 
321  /* Allocate resources */
322  used_frameset = cpl_frameset_new();
323 
324  /* Read the object frame */
325  cpl_msg_indent_more();
326  cpl_msg_info(__func__, "Applying correction to object %d", iobj+1) ;
327  obj_frame = cpl_frameset_get_frame(objframes, iobj);
328  cpl_frameset_insert(used_frameset, cpl_frame_duplicate(obj_frame));
329  if(obj_frame != NULL)
330  obj_images = hawki_load_frame(obj_frame, CPL_TYPE_FLOAT);
331  if(obj_images == NULL)
332  {
333  cpl_msg_indent_less();
334  cpl_msg_error(__func__, "Error reading obj image") ;
335  cpl_frameset_delete(used_frameset);
336  return -1;
337  }
338 
339  /* Read the bkg */
340  bkg_frame = cpl_frameset_get_frame(bkgframes, iobj);
341  cpl_frameset_insert(used_frameset, cpl_frame_duplicate(bkg_frame));
342  if(bkg_frame != NULL)
343  bkg_images = hawki_load_frame(bkg_frame, CPL_TYPE_FLOAT);
344  if(bkg_images == NULL)
345  {
346  cpl_msg_error(__func__, "Error reading background image") ;
347  cpl_msg_indent_less();
348  cpl_imagelist_delete(obj_images);
349  cpl_frameset_delete(used_frameset);
350  return -1;
351  }
352 
353  /* Make the correction */
354  hawki_bkg_imglist_calib(obj_images, bkg_images);
355 
356  /* Save the subtracted frame */
357  if(hawki_step_subtract_bkg_save(obj_images,
358  iobj,
359  used_frameset,
360  recipe_parlist,
361  recipe_framelist) != 0)
362  cpl_msg_warning(__func__,"Some data could not be saved. "
363  "Check permisions or disk space");
364 
365  /* Free in loop */
366  cpl_msg_indent_less();
367  cpl_imagelist_delete(obj_images);
368  cpl_imagelist_delete(bkg_images);
369  cpl_frameset_delete(used_frameset);
370  }
371 
372  /* Exit */
373  return 0;
374 }
375 
376 /*----------------------------------------------------------------------------*/
385 /*----------------------------------------------------------------------------*/
386 static int hawki_step_subtract_bkg_apply_one_to_all_save
387 (cpl_frameset * objframes,
388  cpl_frameset * bkgframes,
389  cpl_parameterlist * recipe_parlist,
390  cpl_frameset * recipe_framelist)
391 {
392  int iobj;
393  int nobjs;
394  cpl_frame * bkg_frame;
395  cpl_imagelist * bkg_images = NULL;
396 
397  /* Read the bkg */
398  cpl_msg_info(__func__,"Using the same bkg for all the objects");
399  bkg_frame = cpl_frameset_get_first(bkgframes);
400  if(bkg_frame != NULL)
401  bkg_images = hawki_load_frame(bkg_frame, CPL_TYPE_FLOAT);
402  if(bkg_images == NULL)
403  {
404  cpl_msg_error(__func__, "Error reading background image");
405  return -1;
406  }
407 
408  /* Subtract the background to each object frame */
409  nobjs = cpl_frameset_get_size(objframes);
410  for(iobj = 0; iobj < nobjs; ++iobj)
411  {
412  cpl_frame * obj_frame;
413  cpl_imagelist * obj_images = NULL;
414  cpl_frameset * used_frameset;
415 
416  /* Allocate resources */
417  used_frameset = cpl_frameset_new();
418 
419  /* Read the object frame */
420  cpl_msg_indent_more();
421  cpl_msg_info(__func__, "Applying correction to object %d", iobj+1) ;
422  obj_frame = cpl_frameset_get_frame(objframes, iobj);
423  if(obj_frame != NULL)
424  obj_images = hawki_load_frame(obj_frame, CPL_TYPE_FLOAT);
425  cpl_frameset_insert(used_frameset, cpl_frame_duplicate(obj_frame));
426  cpl_frameset_insert(used_frameset, cpl_frame_duplicate(bkg_frame));
427  if(obj_images == NULL)
428  {
429  cpl_msg_indent_less();
430  cpl_msg_error(__func__, "Error reading obj image") ;
431  cpl_frameset_delete(used_frameset);
432  return -1;
433  }
434 
435  /* Make the correction */
436  hawki_bkg_imglist_calib(obj_images, bkg_images);
437 
438  /* Save the subtracted frame */
439  hawki_step_subtract_bkg_save(obj_images,
440  iobj,
441  used_frameset,
442  recipe_parlist,
443  recipe_framelist);
444 
445  /* Free in loop */
446  cpl_msg_indent_less();
447  cpl_imagelist_delete(obj_images);
448  cpl_frameset_delete(used_frameset);
449  }
450 
451  /* Free and return */
452  cpl_imagelist_delete(bkg_images);
453  return 0;
454 }
455 
456 /*----------------------------------------------------------------------------*/
466 /*----------------------------------------------------------------------------*/
467 static int hawki_step_subtract_bkg_save
468 (cpl_imagelist * obj_images,
469  int iserie,
470  cpl_frameset * used_frameset,
471  cpl_parameterlist * recipe_parlist,
472  cpl_frameset * recipe_framelist)
473 {
474  const cpl_frame * raw_reference;
475  cpl_propertylist ** extproplists;
476  char filename[256] ;
477  cpl_propertylist * inputlist ;
478  int ext_nb ;
479  const char * recipe_name = "hawki_step_subtract_bkg";
480  int idet;
481  cpl_errorstate error_prevstate = cpl_errorstate_get();
482 
483  /* Get the reference frame (the raw frame) */
484  raw_reference = irplib_frameset_get_first_from_group
485  (used_frameset, CPL_FRAME_GROUP_RAW);
486 
487  /* Create the prop lists */
488  cpl_msg_indent_more();
489  cpl_msg_info(__func__, "Creating the keywords list") ;
490  extproplists = cpl_malloc(HAWKI_NB_DETECTORS * sizeof(cpl_propertylist*));
491  for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
492  {
493  /* Get the extension number */
495  (cpl_frame_get_filename(raw_reference), idet+1);
496 
497  /* Allocate this property list */
498  extproplists[idet] = cpl_propertylist_new();
499 
500  /* Propagate some keywords from input raw frame extensions */
501  inputlist = cpl_propertylist_load_regexp(
502  cpl_frame_get_filename(raw_reference), ext_nb,
503  HAWKI_HEADER_EXT_FORWARD, 0);
504  cpl_propertylist_append(extproplists[idet], inputlist);
505  cpl_propertylist_delete(inputlist);
506  inputlist = cpl_propertylist_load_regexp(
507  cpl_frame_get_filename(raw_reference), ext_nb,
508  HAWKI_HEADER_WCS, 0);
509  cpl_propertylist_append(extproplists[idet], inputlist);
510  cpl_propertylist_delete(inputlist);
511  }
512 
513  /* Write the image */
514  snprintf(filename, 256, "hawki_step_subtract_bkg_%04d.fits", iserie+1);
515  hawki_imagelist_save(recipe_framelist,
516  recipe_parlist,
517  used_frameset,
518  obj_images,
519  recipe_name,
520  HAWKI_CALPRO_BKG_SUBTRACTED,
521  HAWKI_PROTYPE_BKG_SUBTRACTED,
522  NULL,
523  (const cpl_propertylist**)extproplists,
524  filename);
525 
526  /* Free and return */
527  cpl_msg_indent_less();
528  for (idet=0 ; idet<HAWKI_NB_DETECTORS ; idet++)
529  {
530  cpl_propertylist_delete(extproplists[idet]) ;
531  }
532  cpl_free(extproplists) ;
533  if(!cpl_errorstate_is_equal(error_prevstate))
534  {
535  cpl_errorstate_set(CPL_ERROR_NONE);
536  return -1;
537  }
538  return 0;
539 }