DETMON Pipeline Reference Manual  1.3.0
irplib_oddeven.c
1 /* $Id: irplib_oddeven.c,v 1.9 2012-01-12 11:50:41 llundin Exp $
2  *
3  * This file is part of the irplib package
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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: llundin $
23  * $Date: 2012-01-12 11:50:41 $
24  * $Revision: 1.9 $
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 <math.h>
37 #include <cpl.h>
38 
39 #include "irplib_oddeven.h"
40 
41 /*-----------------------------------------------------------------------------
42  Functions prototypes
43  -----------------------------------------------------------------------------*/
44 
45 static cpl_imagelist * irplib_oddeven_cube_conv_xy_rtheta(cpl_imagelist *) ;
46 static cpl_imagelist * irplib_oddeven_cube_conv_rtheta_xy(cpl_imagelist *) ;
47 
48 /*----------------------------------------------------------------------------*/
52 /*----------------------------------------------------------------------------*/
53 
56 /*----------------------------------------------------------------------------*/
64 /*----------------------------------------------------------------------------*/
66  const cpl_image * in,
67  int iquad,
68  double * r_even)
69 {
70  cpl_image * extracted ;
71  cpl_image * labels ;
72  int * plabels ;
73  int llx, lly, urx, ury ;
74  int nx, ny ;
75  double f_even, f_tot ;
76  cpl_apertures * aperts ;
77  int i, j ;
78 
79  /* Test entries */
80  if (in == NULL || r_even == NULL) return -1 ;
81  nx = cpl_image_get_size_x(in) ;
82  ny = cpl_image_get_size_y(in) ;
83 
84  switch (iquad){
85  case 1:
86  llx = 1 ; lly = 1 ; urx = nx/2 ; ury = ny/2 ; break ;
87  case 2:
88  llx = (nx/2)+1 ; lly = 1 ; urx = nx ; ury = ny/2 ; break ;
89  case 3:
90  llx = 1 ; lly = (ny/2)+1 ; urx = nx/2 ; ury = ny ; break ;
91  case 4:
92  llx = (nx/2)+1 ; lly = (ny/2)+1 ; urx = nx ; ury = ny ; break ;
93  case 0:
94  llx = 1 ; lly = 1 ; urx = nx ; ury = ny ; break ;
95  default:
96  cpl_msg_error(cpl_func, "Unsupported mode") ;
97  *r_even = 0.0 ;
98  return -1 ;
99  }
100 
101  /* Extract quadrant */
102  if ((extracted = cpl_image_extract(in, llx, lly, urx, ury)) == NULL) {
103  cpl_msg_error(cpl_func, "Cannot extract quadrant") ;
104  *r_even = 0.0 ;
105  return -1 ;
106  }
107  nx = cpl_image_get_size_x(extracted) ;
108  ny = cpl_image_get_size_y(extracted) ;
109 
110  /* Get f_tot */
111  f_tot = cpl_image_get_median(extracted) ;
112  if (fabs(f_tot) < 1e-6) {
113  cpl_msg_warning(cpl_func, "Quadrant median is 0.0") ;
114  cpl_image_delete(extracted) ;
115  *r_even = 0.0 ;
116  return -1 ;
117  }
118 
119  /* Create the label image to define the even columns */
120  labels = cpl_image_new(nx, ny, CPL_TYPE_INT) ;
121  plabels = cpl_image_get_data_int(labels) ;
122  for (i=0 ; i<nx ; i++) {
123  if (i % 2) for (j=0 ; j<ny ; j++) plabels[i+j*nx] = 0 ;
124  else for (j=0 ; j<ny ; j++) plabels[i+j*nx] = 1 ;
125  }
126 
127  /* Get the median of even columns */
128  if ((aperts = cpl_apertures_new_from_image(extracted, labels)) == NULL) {
129  cpl_msg_error(cpl_func, "Cannot compute the even columns median") ;
130  cpl_image_delete(extracted) ;
131  cpl_image_delete(labels) ;
132  *r_even = 0.0 ;
133  return -1 ;
134  }
135  cpl_image_delete(extracted) ;
136  cpl_image_delete(labels) ;
137  f_even = cpl_apertures_get_median(aperts, 1) ;
138  cpl_apertures_delete(aperts) ;
139 
140  /* Compute the even rate and return */
141  *r_even = f_even / f_tot ;
142  return 0 ;
143 }
144 
145 /*----------------------------------------------------------------------------*/
151 /*----------------------------------------------------------------------------*/
152 cpl_image * irplib_oddeven_correct(const cpl_image * in)
153 {
154  cpl_image * in_real ;
155  cpl_image * in_imag ;
156  cpl_imagelist * freq_i ;
157  cpl_imagelist * freq_i_amp ;
158  cpl_image * cur_im ;
159  double * pcur_im ;
160  cpl_image * cleaned ;
161  int nx ;
162  cpl_vector * hf_med ;
163 
164  /* Test entries */
165  if (in==NULL) return NULL ;
166 
167  nx = cpl_image_get_size_x(in) ;
168 
169  /* Local copy of the input image in DOUBLE */
170  in_real = cpl_image_cast(in, CPL_TYPE_DOUBLE) ;
171  in_imag = cpl_image_duplicate(in_real) ;
172  cpl_image_multiply_scalar(in_imag, 0.0) ;
173 
174  /* Apply FFT to input image */
175  cpl_image_fft(in_real, in_imag, CPL_FFT_DEFAULT) ;
176 
177  /* Put the result in an image list */
178  freq_i = cpl_imagelist_new() ;
179  cpl_imagelist_set(freq_i, in_real, 0) ;
180  cpl_imagelist_set(freq_i, in_imag, 1) ;
181 
182  /* Convert to amplitude/phase */
183  freq_i_amp = irplib_oddeven_cube_conv_xy_rtheta(freq_i);
184  cpl_imagelist_delete(freq_i) ;
185 
186  /* Correct the odd-even frequency */
187  cur_im = cpl_imagelist_get(freq_i_amp, 0) ;
188  pcur_im = cpl_image_get_data_double(cur_im) ;
189  /* Odd-even frequency will be replaced by
190  the median of the 5 values around */
191  hf_med = cpl_vector_new(5);
192 
193  cpl_vector_set(hf_med, 0, pcur_im[nx/2 + 1]);
194  cpl_vector_set(hf_med, 1, pcur_im[nx/2 + 2]);
195  cpl_vector_set(hf_med, 2, pcur_im[nx/2 + 3]);
196  cpl_vector_set(hf_med, 3, pcur_im[nx/2 ]);
197  cpl_vector_set(hf_med, 4, pcur_im[nx/2 -1]);
198 
199  pcur_im[nx / 2 + 1] = cpl_vector_get_median(hf_med);
200  cpl_vector_delete(hf_med);
201 
202  /* Convert to X/Y */
203  freq_i = irplib_oddeven_cube_conv_rtheta_xy(freq_i_amp) ;
204  cpl_imagelist_delete(freq_i_amp) ;
205  /* FFT back to image space */
206  cpl_image_fft(cpl_imagelist_get(freq_i, 0), cpl_imagelist_get(freq_i, 1),
207  CPL_FFT_INVERSE) ;
208  cleaned = cpl_image_cast(cpl_imagelist_get(freq_i, 0), CPL_TYPE_FLOAT) ;
209  cpl_imagelist_delete(freq_i) ;
210  return cleaned ;
211 }
212 
215 /*----------------------------------------------------------------------------*/
226 /*----------------------------------------------------------------------------*/
227 static cpl_imagelist * irplib_oddeven_cube_conv_xy_rtheta(
228  cpl_imagelist * cube_in)
229 {
230  cpl_imagelist * cube_out ;
231  double re, im ;
232  double mod, phase ;
233  int nx, ny, np ;
234  cpl_image * tmp_im ;
235  double * pim1 ;
236  double * pim2 ;
237  double * pim3 ;
238  double * pim4 ;
239  int i, j ;
240 
241  /* Error handling : test entries */
242  if (cube_in == NULL) return NULL ;
243  np = cpl_imagelist_get_size(cube_in) ;
244  if (np != 2) return NULL ;
245 
246  /* Initialise */
247  tmp_im = cpl_imagelist_get(cube_in, 0) ;
248  pim1 = cpl_image_get_data_double(tmp_im) ;
249  nx = cpl_image_get_size_x(tmp_im) ;
250  ny = cpl_image_get_size_y(tmp_im) ;
251  tmp_im = cpl_imagelist_get(cube_in, 1) ;
252  pim2 = cpl_image_get_data_double(tmp_im) ;
253 
254  /* Allocate cube_out */
255  cube_out = cpl_imagelist_duplicate(cube_in) ;
256 
257  tmp_im = cpl_imagelist_get(cube_out, 0) ;
258  pim3 = cpl_image_get_data_double(tmp_im) ;
259  tmp_im = cpl_imagelist_get(cube_out, 1) ;
260  pim4 = cpl_image_get_data_double(tmp_im) ;
261  /* Convert */
262  for (j=0 ; j<ny ; j++) {
263  for (i=0 ; i<nx ; i++) {
264  re = (double)pim1[i+j*nx] ;
265  im = (double)pim2[i+j*nx] ;
266  mod = (double)(sqrt(re*re + im*im)) ;
267  if (re != 0.0)
268  phase = (double)atan2(im, re) ;
269  else
270  phase = 0.0 ;
271  pim3[i+j*nx] = mod ;
272  pim4[i+j*nx] = phase ;
273  }
274  }
275  return cube_out ;
276 }
277 
278 /*----------------------------------------------------------------------------*/
291 /*----------------------------------------------------------------------------*/
292 static cpl_imagelist * irplib_oddeven_cube_conv_rtheta_xy(
293  cpl_imagelist * cube_in)
294 {
295  cpl_imagelist * cube_out ;
296  double re, im ;
297  double mod, phase ;
298  int nx, ny, np ;
299  cpl_image * tmp_im ;
300  double * pim1 ;
301  double * pim2 ;
302  double * pim3 ;
303  double * pim4 ;
304  int i, j ;
305 
306  /* Error handling : test entries */
307  if (cube_in == NULL) return NULL ;
308  np = cpl_imagelist_get_size(cube_in) ;
309  if (np != 2) return NULL ;
310 
311  /* Initialise */
312  tmp_im = cpl_imagelist_get(cube_in, 0) ;
313  pim1 = cpl_image_get_data_double(tmp_im) ;
314  nx = cpl_image_get_size_x(tmp_im) ;
315  ny = cpl_image_get_size_y(tmp_im) ;
316  tmp_im = cpl_imagelist_get(cube_in, 1) ;
317  pim2 = cpl_image_get_data_double(tmp_im) ;
318 
319  /* Allocate cube_out */
320  cube_out = cpl_imagelist_duplicate(cube_in) ;
321 
322  tmp_im = cpl_imagelist_get(cube_out, 0) ;
323  pim3 = cpl_image_get_data_double(tmp_im) ;
324  tmp_im = cpl_imagelist_get(cube_out, 1) ;
325  pim4 = cpl_image_get_data_double(tmp_im) ;
326  /* Convert */
327  for (j=0 ; j<ny ; j++) {
328  for (i=0 ; i<nx ; i++) {
329  mod = (double)pim1[i+j*nx] ;
330  phase = (double)pim2[i+j*nx] ;
331  re = (double)(mod * cos(phase));
332  im = (double)(mod * sin(phase));
333  pim3[i+j*nx] = re ;
334  pim4[i+j*nx] = im ;
335  }
336  }
337  return cube_out ;
338 }
int irplib_oddeven_monitor(const cpl_image *in, int iquad, double *r_even)
Estimate the odd/even rate in an image quadrant.
cpl_image * irplib_oddeven_correct(const cpl_image *in)
Correct the odd/even in an image.