OMEGA Pipeline Reference Manual  1.0.5
omega_bpm.c
1 /* $Id: omega_bpm.c,v 1.6 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.6 $
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 <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 
40 #include "omega_dfs.h"
41 #include "omega_stats.h"
42 #include "omega_utils.h"
43 #include "omega_bpm.h"
44 #include "omega_trim.h"
45 
62 /*----------------------------------------------------------------------------*/
65 /*----------------------------------------------------------------------------*/
83 /*----------------------------------------------------------------------------*/
84 cpl_image * clean_deadpix_median(cpl_image *dirty, cpl_mask *dead, int boxsize)
85 {
86 
87  int i = 0;
88  int j = 0;
89  int k = 0;
90  int l = 0;
91  int nx = 0;
92  int ny = 0;
93  int lx = 0;
94  int ly = 0;
95  int pixelpos = 0;
96  int numgood = 0;
97  double replace = 0.0;
98  float *goodpix;
99  float *cleandata;
100  float *dirtydata;
101 
102  const char *_id = "clean_deadpix_median";
103 
104  cpl_binary *deaddata;
105  cpl_image *cleaned;
106 
107 
108  if(dirty == NULL){
109  cpl_msg_error(_id,"Null input image");
110  return NULL;
111  }
112 
113  lx = cpl_image_get_size_x(dirty);
114  ly = cpl_image_get_size_y(dirty);
115 
116  dirtydata = (float *)cpl_image_get_data(dirty);
117 
118  cleaned = cpl_image_new(lx,ly,CPL_TYPE_FLOAT);
119  cleandata = (float *)cpl_image_get_data(cleaned);
120 
121  goodpix = calloc((boxsize+1)*(boxsize+1), sizeof(float));
122  if(goodpix == NULL){
123  cpl_msg_error(_id,"Error in allocating memory");
124  cpl_image_delete(cleaned);
125  return NULL;
126  }
127 
128  boxsize = boxsize/2;
129 
130  deaddata = cpl_mask_get_data(dead);
131 
132 /*Replace dead pixels by interpolated value*/
133  for(j=0; j<ly; j++){
134  for(i=0; i<lx; i++){
135  pixelpos = i + j*lx;
136 
137  if(deaddata[pixelpos] == CPL_BINARY_1){
138  cleandata[pixelpos] = dirtydata[pixelpos];
139  }
140  else{
141  numgood = 0;
142  replace = 0.0;
143  for(l=-boxsize; l<=boxsize; l++){
144  ny = j+l;
145  for(k=-boxsize; k<=boxsize; k++){
146  nx = i+k;
147  /*Check neighbour id it is inside image
148  and pixel is valid in mask*/
149 
150  if((nx >= 0) && (nx < lx) &&
151  (ny >= 0) && (ny < ly) &&
152  (deaddata[nx+ny*lx] == CPL_BINARY_1)){
153 
154  goodpix[numgood] = (double)dirtydata[nx+ny*lx];
155  numgood++;
156  }
157  }
158  }
159  /*Take the median value over the good neighbours*/
160  if(numgood <=1){
161  cleandata[pixelpos] = (float)0;
162  }
163  else{
164 /* cleandata[pixelpos] = cpl_tools_get_median_float(goodpix, numgood);*/
165  cleandata[pixelpos] = get_median_float(goodpix, numgood);
166  }
167  }
168  }
169  }
170 
171  free(goodpix);
172 
173  return cleaned;
174 
175 }
176 
177 /*----------------------------------------------------------------------------*/
190 /*----------------------------------------------------------------------------*/
191 cpl_mask *makebpm(const cpl_frame *hot, const cpl_frame *cold, int cxn)
192 {
193  cpl_image *hot_img;
194  cpl_image *cold_img;
195  cpl_mask *bpm;
196  cpl_mask *mask;
197 
198  if((hot == NULL) && (cold == NULL))
199  return NULL;
200 
201  /* FIXME: Maybe I need to do a OR instead */
202  if((hot != NULL) && (cold != NULL)){
203  hot_img = cpl_image_load(cpl_frame_get_filename(hot), CPL_TYPE_INT, 0, cxn);
204  cold_img = cpl_image_load(cpl_frame_get_filename(cold), CPL_TYPE_INT, 0, cxn);
205  bpm = cpl_mask_threshold_image_create(hot_img, 0.5, 1.5) ;
206  mask = cpl_mask_threshold_image_create(cold_img, 0.5, 1.5) ;
207 /* cpl_mask_and(bpm, mask);*/
208  cpl_mask_or(bpm, mask);
209 
210  cpl_image_delete(hot_img);
211  cpl_image_delete(cold_img);
212  cpl_mask_delete(mask);
213  }
214  else if((hot == NULL) && (cold != NULL)){
215  cold_img = cpl_image_load(cpl_frame_get_filename(cold), CPL_TYPE_INT, 0, cxn);
216  bpm = cpl_mask_threshold_image_create(cold_img, 0.5, 1.5) ;
217  cpl_image_delete(cold_img);
218  }
219  else if((hot != NULL) && (cold == NULL)){
220  hot_img = cpl_image_load(cpl_frame_get_filename(hot), CPL_TYPE_INT, 0, cxn);
221  bpm = cpl_mask_threshold_image_create(hot_img, 0.5, 1.5) ;
222  cpl_image_delete(hot_img);
223  }
224  else {
225  return NULL;
226  }
227 
228  return bpm;
229 
230 }
231 
244 cpl_mask * create_saturated_map(const cpl_frame *frame, int oc, int ext, cpl_parameterlist *spars)
245 {
246 
247  int i = 0;
248  int npars = 0;
249  double low = 0.0;
250  double high = 0.0;
251  const char *alias = NULL;
252 
253  cpl_image *trim;
254  cpl_mask *mask ;
255  cpl_parameter *par;
256 
257 
258  if((frame == NULL) || (spars == NULL)){
259  cpl_msg_error(cpl_func,"Input image or parameter list is NULL");
260  return NULL;
261  }
262 
263 
264  npars = cpl_parameterlist_get_size(spars);
265  par = cpl_parameterlist_get_first(spars);
266 
267  for(i=0; i<npars; i++) {
268  alias = cpl_parameter_get_alias(par, CPL_PARAMETER_MODE_CLI);
269  if(strcmp ("lt-satu", alias) == 0){
270  low = cpl_parameter_get_double(par);
271  }
272  else if(strcmp ("ht-satu", alias) == 0){
273  high = cpl_parameter_get_double(par);
274  }
275  par = cpl_parameterlist_get_next(spars);
276  }
277 
278  trim = TrimOscanCorrect(frame, oc, ext);
279  if (trim == NULL) {
280  cpl_msg_error(cpl_func,"Cannot trim image");
281  return NULL;
282  }
283  mask = cpl_mask_threshold_image_create(trim, low, high);
284  cpl_mask_not(mask);
285 
286  freeimage(trim);
287 
288 
289 /*FIXME: how to count number of saturated pixels?*/
290 
291  return mask;
292 }
293 
304 cpl_mask * omega_saturated_map(cpl_image *trim, int oc, cpl_parameterlist *spars)
305 {
306 
307  int i = 0;
308  int npars = 0;
309  double low = 0.0;
310  double high = 0.0;
311  const char *alias = NULL;
312  double imsize=0.0;
313  double badpixel=0.0;
314  cpl_mask *mask ;
315  cpl_parameter *par;
316 
317 
318  if((trim == NULL) || (spars == NULL))
319  return NULL;
320 
321 
322  npars = cpl_parameterlist_get_size(spars);
323  par = cpl_parameterlist_get_first(spars);
324 
325  for(i=0; i<npars; i++) {
326  alias = cpl_parameter_get_alias(par, CPL_PARAMETER_MODE_CLI);
327  if(strcmp ("lt-satu", alias) == 0){
328  low = cpl_parameter_get_double(par);
329  }
330  else if(strcmp ("ht-satu", alias) == 0){
331  high = cpl_parameter_get_double(par);
332  }
333  par = cpl_parameterlist_get_next(spars);
334  }
335 
336  mask = cpl_mask_threshold_image_create(trim, low, high);
337  cpl_mask_not(mask);
338 
339  imsize=cpl_image_get_size_x(trim)*cpl_image_get_size_y(trim);
340  badpixel=cpl_mask_count(mask);
341 
342  cpl_msg_debug(cpl_func,"Ratio of saturated pixel: %g", badpixel/imsize);
343 
344  cpl_msg_debug(cpl_func,"Detected %g saturated pixels in image",badpixel);
345 
346  if(badpixel/imsize > 0.95) {
347  cpl_msg_warning(cpl_func," %g percent of the pixels are saturated!",
348  badpixel/imsize*100.);
349  }
350 
351  return mask;
352 }
353 
354 /*----------------------------------------------------------------------------*/
369 /*----------------------------------------------------------------------------*/
370 cpl_image * create_weightframe(cpl_image *flat, cpl_image *bpmsatu,
371  cpl_mask *cosmic,cpl_mask *satellite)
372 {
373 
374  int count = 0;
375  int nx = 0;
376  int ny = 0;
377 
378  cpl_image *mask_img;
379  cpl_image *weight;
380  cpl_mask *bpm;
381 
382 
383  if((flat == NULL) || (bpmsatu == NULL)) {
384  cpl_msg_debug(cpl_func,"NULL input frame");
385  return NULL;
386  }
387 
388  /*Create a mask from the combined BPM and Saturated images*/
389  bpm = cpl_mask_threshold_image_create(bpmsatu, 0.5, 1.5);
390 
391  if(cosmic != NULL)
392  cpl_mask_or(bpm, cosmic);
393 
394  if(satellite != NULL)
395  cpl_mask_or(bpm, satellite);
396 
397  nx = cpl_mask_get_size_x(bpm);
398  ny = cpl_mask_get_size_y(bpm);
399 
400  /* Count the bad pixels which have value CP_BINARY_1 */
401  cpl_msg_debug(cpl_func,"Weight of % " CPL_SIZE_FORMAT " bad pixels is set to 0", cpl_mask_count(bpm));
402 
403  /*Convert mask to INT*/
404  /* The weight will be multiplied by the image, therefore
405  * the bad pixels need to be set to CPL_BINARY_0
406  */
407  cpl_mask_not(bpm);
408  mask_img = cpl_image_new_from_mask(bpm);
409 
410  /*Convert INT to FLOAT*/
411  weight = cpl_image_cast(mask_img, CPL_TYPE_FLOAT);
412 
413  freeimage(mask_img);
414 
415  cpl_image_multiply(weight, flat);
416 
417  freemask(bpm);
418 
419  return weight;
420 
421 }
422 
423 /*----------------------------------------------------------------------------*/
428 /*----------------------------------------------------------------------------*/
429 
430 cpl_mask *omega_bpm_create(cpl_image *img, cpl_parameterlist *pars)
431 {
432  int i,n;
433  double low,high;
434  const char *name = "omega_temp.fits";
435  const char *bname = "omega_back.fits";
436  const char *text;
437  cpl_parameter *par;
438  cpl_image *norm, *back;
439  cpl_mask *bpm;
440 
441  if(img == NULL)
442  return NULL;
443 
444  /* Get parameters */
445  par = cpl_parameterlist_get_first(pars);
446 
447  for(i=0; i<cpl_parameterlist_get_size(pars); i++) {
448  text = cpl_parameter_get_alias(par, CPL_PARAMETER_MODE_CLI);
449  if(strcmp("low", text) == 0) {
450  low = cpl_parameter_get_double(par) ;
451  n++;
452  }
453  else if(strcmp("high", text) == 0){
454  high = cpl_parameter_get_double(par);
455  n++;
456  }
457  if (n == 2)
458  break;
459 
460  par = cpl_parameterlist_get_next(pars);
461  }
462 
463 
464  /* Save image to disk */
465  cpl_image_save(img, name, CPL_BPP_IEEE_FLOAT, NULL, CPL_IO_CREATE);
466 
467  /* Call function to create background image*/
468  if(omega_create_background(pars, name, bname) != 0){
469  cpl_msg_warning(cpl_func,"Error in creating background image");
470  return NULL;
471  }
472 
473  if((back = cpl_image_load(bname, CPL_TYPE_FLOAT, 0, 0)) == NULL)
474  return NULL;
475 
476  norm = cpl_image_divide_create(img, back);
477  freeimage(back);
478 
479  bpm = cpl_mask_threshold_image_create(norm, low, high);
480  freeimage(norm);
481 
482 // cpl_mask_not(bpm);
483 
484  return bpm;
485 
486 }
487