OMEGA Pipeline Reference Manual  1.0.5
omega_flats.c
1 /* $Id: omega_flats.c,v 1.2 2012-01-31 13:38:50 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: 2012-01-31 13:38:50 $
24  * $Revision: 1.2 $
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 <string.h>
37 
38 
39 #include "omega_flats.h"
40 #include "omega_fftw.h"
41 #include "omega_dfs.h"
42 #include "omega_pfits.h"
43 #include "omega_utils.h"
44 #include "omega_stats.h"
45 
73 cpl_image *omega_make_mflat(cpl_image *dome, cpl_image *twil,
74  cpl_mask *bpmmap, cpl_parameterlist *pars)
75 {
76 
77  int dx = 0;
78  int dy = 0;
79 
80  double gausfilt = 9.0;
81 
82  cpl_image *dome_comp;
83  cpl_image *dome_low_image;
84  cpl_image *twil_comp;
85  cpl_parameter *par;
86 
87  if((dome == NULL) || (twil == NULL) || (pars == NULL))
88  return NULL;
89 
90 
91  /* Retrieve input parameters */
92  par = cpl_parameterlist_find(pars, "omega.omega_mflat.GaussianFiltSize") ;
93  gausfilt = cpl_parameter_get_double(par) ;
94 
95  par = cpl_parameterlist_find(pars, "omega.omega_mflat.MirrorXpix") ;
96  dx = cpl_parameter_get_int(par) ;
97 
98  par = cpl_parameterlist_find(pars, "omega.omega_mflat.MirrorYpix") ;
99  dy = cpl_parameter_get_int(par) ;
100 
101  /* Get low spatial frequency from twilight flat */
102  cpl_msg_info (cpl_func,"Working on low spatial frequency component of flat.");
103  twil_comp = omega_get_spatial_freq(twil, bpmmap, gausfilt, dx, dy);
104  /* twil_comp = cpl_image_duplicate(twil);*/
105 
106  if (twil_comp == NULL) {
107  cpl_msg_error (cpl_func, "Error in low spatial frequency calculation");
108  return NULL;
109  }
110 
111  /*Get high spatial frequency from dome flat */
112  cpl_msg_info (cpl_func,"Working on high spatial frequency component of flat");
113  dome_low_image = omega_get_spatial_freq(dome, bpmmap, gausfilt, dx, dy);
114  if (dome_low_image == NULL) {
115  cpl_msg_error (cpl_func, "Error in high spatial frequency calculation");
116  freeimage(twil_comp);
117  return NULL;
118  }
119 
120  dome_comp = cpl_image_divide_create(dome, dome_low_image);
121  if (dome_comp == NULL) {
122  cpl_msg_error(cpl_func,"Error in division. <%s>",cpl_error_get_message());
123  freeimage(twil_comp);
124  freeimage(dome_low_image);
125  return NULL;
126  }
127  freeimage(dome_low_image);
128 
129  /*Combine the two contributions*/
130  cpl_image_multiply(twil_comp, dome_comp);
131  freeimage(dome_comp);
132 
133  if(bpmmap != NULL)
134  cpl_image_reject_from_mask(twil_comp, bpmmap);
135 
136 
137  /* Normalize the image */
138  if (cpl_image_normalise(twil_comp, CPL_NORM_MEAN) != CPL_ERROR_NONE){
139  cpl_msg_error (cpl_func, "Image is NULL in normalization step. <%s>",cpl_error_get_message());
140  freeimage(twil_comp);
141  return NULL;
142  }
143 
144  return twil_comp;
145 
146 }
147 
148 
161 int omega_fringecor(cpl_image *sci, const cpl_image *fringe, const cpl_image *bpm,
162  const cpl_parameterlist *fpars)
163 {
164 
165  int i = 0;
166  int N = 0;
167  int npars = 0;
168  double a = 0.0;
169  double FF = 0.0;
170  double hthre = 5.0;
171  double lthre = 1.5;
172  double mean_F = 0.0;
173  double mean_R = 0.0;
174  double median = 0.0;
175  double RF = 0.0;
176  double scale = 5.0;
177  double stdev = 0.0;
178  const char *text = NULL;
179 
180  const cpl_parameter *par;
181  cpl_stats *stats;
182  cpl_stats *stats_F;
183  cpl_stats *stats_R;
184  cpl_image *image;
185  cpl_image *ff;
186  // cpl_image *fringed;
187  cpl_mask *map, *bpmap;
188  cpl_mask *bin1;
189  cpl_mask *bin2;
190  cpl_error_code code;
191 
192  if((sci == NULL) || (fringe == NULL) || (bpm == NULL) || (fpars == NULL))
193  return -1;
194 
195  /*Retrieve fringing parameters*/
196  par = cpl_parameterlist_get_first_const(fpars);
197 
198  for(i=0; i<npars; i++) {
199  text = cpl_parameter_get_alias(par,CPL_PARAMETER_MODE_CLI);
200  if(strcmp("sigma-fringes", text) == 0) {
201  scale = cpl_parameter_get_double(par) ;
202  }
203  else if(strcmp("lfringes", text) == 0) {
204  lthre = cpl_parameter_get_double(par) ;
205  }
206  else if(strcmp("hfringes", text) == 0) {
207  hthre = cpl_parameter_get_double(par) ;
208  }
209 
210  par = cpl_parameterlist_get_next_const(fpars);
211 
212  }
213 
214  /* Get statistics of science image */
215  stats = cpl_stats_new_from_image(sci, CPL_STATS_ALL);
216  if(stats == NULL)
217  return -1;
218 
219  median = cpl_stats_get_median(stats);
220  stdev = cpl_stats_get_stdev(stats);
221 
222  /*it sounds like & is a bitwise AND*/
223  bpmap = cpl_mask_threshold_image_create(bpm, 0.5, 1.5);
224  map = cpl_mask_threshold_image_create(sci,median-(scale*stdev),median+(scale*stdev));
225  cpl_mask_and(bpmap, map);
226  cpl_mask_delete(map);
227  freestats(stats);
228 
229 
230  /* Get statistics of fringe image */
231  ff = cpl_image_duplicate(fringe);
232  stats = cpl_stats_new_from_image(ff, CPL_STATS_ALL);
233  if(stats == NULL)
234  return -1;
235 
236  median = cpl_stats_get_median(stats);
237  stdev = cpl_stats_get_stdev(stats);
238 
239  /*Do an OR then an AND for next step*/
240  bin1 = cpl_mask_threshold_image_create(ff, median-(hthre*stdev), median-(lthre*stdev));
241  bin2 = cpl_mask_threshold_image_create(ff, median+(lthre*stdev), median+(hthre*stdev));
242 
243  code = cpl_mask_or(bin1, bin2);
244  if(code != CPL_ERROR_NONE) {
245  cpl_msg_debug(cpl_func,"Error in bit-wise OR operation");
246  freemask(bin1);
247  freemask(bin2);
248  freemask(bpmap);
249  freestats(stats);
250  return -1;
251  }
252 
253  code = cpl_mask_and(bpmap, bin1);
254  if(code != CPL_ERROR_NONE) {
255  cpl_msg_debug(cpl_func,"Error in bit-wise AND operation");
256  freemask(bin1);
257  freemask(bin2);
258  freestats(stats);
259  return -1;
260  }
261 
262  freemask(bin1);
263  freemask(bin2);
264  freestats(stats);
265 
266  /*
267  * Calculate statistics only on good pixels, on the two images
268  */
269 
270  /* Sets bad pixels in the fringe image as defined in mask */
271  code = cpl_image_reject_from_mask(ff, bpmap);
272  if(code != CPL_ERROR_NONE)
273  cpl_msg_warning(cpl_func,"Cannot set BP in fringe image");
274 
275  stats_F = cpl_stats_new_from_image(ff, CPL_STATS_ALL);
276  mean_F = cpl_stats_get_mean(stats_F);
277 
278  /* Sets bad pixels in the image as defined in mask */
279  code = cpl_image_reject_from_mask(sci, bpmap);
280  if(code != CPL_ERROR_NONE)
281  cpl_msg_warning(cpl_func,"Cannot set BP in image");
282 
283  stats_R = cpl_stats_new_from_image(sci, CPL_STATS_ALL);
284  mean_R = cpl_stats_get_mean(stats_R);
285 
286  N = cpl_stats_get_npix(stats_F);
287 
288  image = cpl_image_multiply_create(sci, ff);
289  stats = cpl_stats_new_from_image(image, CPL_STATS_ALL);
290  RF = cpl_stats_get_flux(stats);
291 
292  freeimage(image);
293  freestats(stats);
294 
295  image = cpl_image_multiply_create(ff, ff);
296  stats = cpl_stats_new_from_image(image, CPL_STATS_ALL);
297  FF = cpl_stats_get_flux(stats);
298 
299  a = (RF - N*mean_R*mean_F) / (FF - N*mean_F*mean_F);
300  /* cpl_msg_info("","The measured scale factor is %f", a);*/
301 
302  cpl_image_multiply_scalar(ff, a);
303 
304  cpl_image_subtract(sci, ff);
305 
306  /*Clean up*/
307 
308  freeimage(ff);
309  freeimage(image);
310  freestats(stats);
311  freestats(stats_F);
312  freestats(stats_R);
313 
314  return 0;
315 }
316 
326 int omega_flatcor(cpl_image *image, const cpl_image *flat, const cpl_image *nsky)
327 {
328  cpl_image *mflat;
329 
330  if((image == NULL) || (flat == NULL))
331  return -1;
332 
333  /* If there is a night sky flat, use it. */
334  if(nsky != NULL){
335  mflat = cpl_image_multiply_create(flat, nsky);
336  cpl_image_divide(image, mflat);
337  freeimage(mflat);
338  }
339  else {
340  cpl_image_divide(image, flat);
341  }
342 
343  return 0;
344 
345 }
346 
358 cpl_image *omega_nsky_create(cpl_imagelist *ilist,cpl_image *bpm, int n)
359 {
360 
361  int i;
362  cpl_image *nsky;
363 
364  if(ilist == NULL)
365  return NULL;
366 
367  for(i = 0; i < n; i++){
368  cpl_image *img = cpl_imagelist_get(ilist, i);
369  if(bpm != NULL){
370  cpl_mask *mask = cpl_mask_threshold_image_create(img, 0.5, 1.5);
371  cpl_image_reject_from_mask(img, mask);
372  freemask(mask);
373  }
374  double median = cpl_image_get_median(img);
375  cpl_image_divide_scalar(img, median);
376  }
377 
378  /* Create median image */
379  nsky = cpl_imagelist_collapse_median_create(ilist);
380 
381  /* Normalize it */
382  cpl_image_normalise(nsky,CPL_NORM_MEAN);
383 
384  if(bpm != NULL)
385  cpl_image_multiply(nsky, bpm);
386 
387  return nsky;
388 }
389 
401 cpl_image *omega_fringes_create(cpl_imagelist *ilist, cpl_image *bpm, int n)
402 {
403  cpl_image *fringes;
404 
405  if(ilist == NULL)
406  return NULL;
407 
408 
409  fringes = omega_nsky_create(ilist, bpm, n);
410  cpl_image_subtract_scalar(fringes, 1.0);
411 
412  return fringes;
413 
414 }
415