UVES Pipeline Reference Manual  5.4.0
uves_remove_crh_single.c
1 /* *
2  * This file is part of the ESO X-shooter Pipeline *
3  * Copyright (C) 2006 European Southern Observatory *
4  * *
5  * This library is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the Free Software *
17  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA *
18  * */
19 
20 /*
21  * $Author: amodigli $
22 
23  * $Date: 2010-12-08 14:11:18 $
24  * $Revision: 1.8 $
25  * $Log: not supported by cvs2svn $
26  * Revision 1.7 2010/09/24 09:32:07 amodigli
27  * put back QFITS dependency to fix problem spot by NRI on FIBER mode (with MIDAS calibs) data
28  *
29  * Revision 1.5 2010/02/08 07:10:14 amodigli
30  * replace cpl_image_filter_median/linear by uves_image_filter_median/linear
31  *
32  * Revision 1.4 2010/01/07 08:12:09 amodigli
33  * saved old version
34  *
35  * Revision 1.2 2009/02/18 12:06:38 amodigli
36  * fixe compiler warning
37  *
38  * Revision 1.1 2009/01/02 08:31:34 amodigli
39  * copmmitted to CVS
40  *
41  *
42  */
43 
44 #ifdef HAVE_CONFIG_H
45 # include <config.h>
46 #endif
47 
48 /*----------------------------------------------------------------------------*/
55 /*----------------------------------------------------------------------------*/
58 /*-----------------------------------------------------------------------------
59  Includes
60 -----------------------------------------------------------------------------*/
61 
62 #include <math.h>
63 
64 //#include <xsh_drl.h>
65 //#include <xsh_data_pre.h>
66 //#include <xsh_dfs.h>
67 //#include <xsh_pfits.h>
68 #include <uves_error.h>
69 #include <uves_msg.h>
70 #include <uves_utils_wrappers.h>
71 #include <cpl.h>
72 //#include <xsh_badpixelmap.h>
73 //#include <xsh_parameters.h>
74 //#include <xsh_data_localization.h>
75 
76 /*-----------------------------------------------------------------------------
77  Functions prototypes
78  -----------------------------------------------------------------------------*/
79 
80 /*-----------------------------------------------------------------------------
81  Implementation
82  -----------------------------------------------------------------------------*/
83 
84 /* This should be defined in a more clever way, a parameter for example */
85 #define MAX_ITERATIONS 6
86 
87 
100 cpl_image * uves_remove_crh_single( cpl_image * sci_image,
101  double crh_frac_max,
102  double sigma_lim,
103  double f_lim,
104  int max_iter,
105  double gain,
106  double ron)
107 {
108  int i,j,k,l,m;
109  double frac = 0. ;
110  /* Only pointers */
111 
112  /* Need to be free */
113  //xsh_localization_list * loc_list = NULL ;
114  cpl_image* laplacian_image = NULL;
115  cpl_image* laplacian_redu_image = NULL;
116  cpl_image* two_sub_sample = NULL;
117  cpl_image* sci_median5_image = NULL;
118  cpl_image* noise_image = NULL;
119  cpl_image* s_image = NULL;
120  cpl_image* s_median_image = NULL;
121  cpl_image* s2_image = NULL;
122  cpl_image* sci_median3_image = NULL;
123  cpl_image* sci_median3_7_image = NULL;
124  cpl_image* f_image = NULL;
125  cpl_image* r_image = NULL;
126  int two_sub_sample_nx = 0;
127  int two_sub_sample_ny = 0;
128  /* Only pointers */
129  float* sci_data = NULL;
130  float* two_sub_sample_data = NULL;
131  float* laplacian_data = NULL;
132  float* laplacian_redu_data = NULL;
133  float* sci_median5_data = NULL;
134  float* sci_median3_data = NULL;
135  float* sci_median3_7_data = NULL;
136  float* noise_data = NULL;
137  float* s_data = NULL;
138  float* s_median_data = NULL;
139  float* s2_data = NULL;
140  float* f_data = NULL;
141  float* r_data = NULL;
142  /* Need to be free */
143  float* cosmic_data = NULL;
144 
145  cpl_matrix* laplacian_kernel = NULL;
146  cpl_matrix* median3_kernel = NULL;
147  cpl_matrix* median5_kernel = NULL;
148  cpl_matrix* median7_kernel = NULL;
149  int new_crh =1, nb_crh = 0;
150  int nbiter = 1 ;
151  cpl_vector* median = NULL;
152  /* const char * tag = NULL ; */
153  int nx=0;
154  int ny=0;
155  cpl_image* res_image=NULL;
156 
157  /* Check parameters */
158  cknull( sci_image,"null input image" ) ; ;
159 
160  uves_msg( "Entering uves_remove_crh_single");
161  uves_msg( " Params: frac_max %.1f, sigma_lim %.2f f_lim %.2f, iter %d",
162  crh_frac_max, sigma_lim, f_lim, max_iter);
163 
164  /* Preparing different kernels */
165  nx=cpl_image_get_size_x(sci_image);
166  ny=cpl_image_get_size_y(sci_image);
167 
168  /* Laplacian */
169  check_nomsg( laplacian_kernel = cpl_matrix_new(3,3));
170  cpl_matrix_set( laplacian_kernel,0,0,0.0);
171  cpl_matrix_set( laplacian_kernel,0,1,-1.0);
172  cpl_matrix_set( laplacian_kernel,0,2,0.0);
173  cpl_matrix_set( laplacian_kernel,1,0,-1.0);
174  cpl_matrix_set( laplacian_kernel,1,1,4.0);
175  cpl_matrix_set( laplacian_kernel,1,2,-1.0);
176  cpl_matrix_set( laplacian_kernel,2,0,0.0);
177  cpl_matrix_set( laplacian_kernel,2,1,-1.0);
178  cpl_matrix_set( laplacian_kernel,2,2,0.0);
179  cpl_matrix_divide_scalar( laplacian_kernel, 4.0);
180 /*
181  cpl_matrix_set( laplacian_kernel,0,0,-1.0);
182  cpl_matrix_set( laplacian_kernel,0,1,-1.0);
183  cpl_matrix_set( laplacian_kernel,0,2,-1.0);
184  cpl_matrix_set( laplacian_kernel,1,0,-1.0);
185  cpl_matrix_set( laplacian_kernel,1,1,8.0);
186  cpl_matrix_set( laplacian_kernel,1,2,-1.0);
187  cpl_matrix_set( laplacian_kernel,2,0,-1.0);
188  cpl_matrix_set( laplacian_kernel,2,1,-1.0);
189  cpl_matrix_set( laplacian_kernel,2,2,-1.0);
190  cpl_matrix_divide_scalar( laplacian_kernel, 8.0);
191 */
192  /* Median 3x3*/
193  check_nomsg( median3_kernel = cpl_matrix_new(3,3));
194  for(j=0; j< 3; j++){
195  for(i=0; i< 3; i++){
196  cpl_matrix_set( median3_kernel, i,j,1.0);
197  }
198  }
199 
200  /* Median 5x5 */
201  check_nomsg( median5_kernel = cpl_matrix_new(5,5));
202  for(j=0; j< 5; j++){
203  for(i=0; i< 5; i++){
204  cpl_matrix_set( median5_kernel, i,j,1.0);
205  }
206  }
207 
208  /* Median 7x7 */
209  check_nomsg( median7_kernel = cpl_matrix_new(7,7));
210  for(j=0; j< 7; j++){
211  for(i=0; i< 7; i++){
212  cpl_matrix_set( median7_kernel, i,j,1.0);
213  }
214  }
215 
216  check_nomsg (res_image = cpl_image_duplicate( sci_image));
217 
218  /* Allocate images and pointers */
219  check_nomsg (sci_data = cpl_image_get_data_float( res_image));
220 
221  two_sub_sample_nx = nx*2;
222  two_sub_sample_ny = ny*2;
223  check_nomsg( two_sub_sample = cpl_image_new( two_sub_sample_nx,
224  two_sub_sample_ny, CPL_TYPE_FLOAT));
225  check_nomsg(two_sub_sample_data = cpl_image_get_data_float( two_sub_sample));
226  check_nomsg( laplacian_redu_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
227  check_nomsg(laplacian_redu_data = cpl_image_get_data_float(
228  laplacian_redu_image));
229  check_nomsg( noise_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
230  check_nomsg( noise_data = cpl_image_get_data_float( noise_image));
231  check_nomsg( s_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
232  check_nomsg( s_data = cpl_image_get_data_float( s_image));
233  check_nomsg( s2_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
234  check_nomsg( s2_data = cpl_image_get_data_float( s2_image));
235  check_nomsg( f_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
236  check_nomsg( f_data = cpl_image_get_data_float( f_image));
237  check_nomsg( r_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
238  check_nomsg( r_data = cpl_image_get_data_float( r_image));
239  cosmic_data=cpl_calloc(nx*ny, sizeof(float));
240 
241  /* LGG - Added limit on frac_max AND limit on nb iterations */
242  while( new_crh > 0 && frac < crh_frac_max && nbiter <= max_iter ){
243  uves_msg("Iteration %d",nbiter );
244  /* Create a 2n x 2n images like this
245  | 1 | 2 | => | 1 | 1 | 2 | 2 |
246  | 3 | 4 | | 1 | 1 | 2 | 2 |
247  | 3 | 3 | 4 | 4 |
248  | 3 | 3 | 4 | 4 | */
249  uves_msg_debug("Create a 2n images");
250  for( j=0; j< ny; j++){
251  for( i=0; i< nx; i++){
252  float val = sci_data[i+j*nx];
253 
254  if ( val < 0. ) val = 0. ;
255  two_sub_sample_data[i*2+j*2*two_sub_sample_nx] = val;
256  two_sub_sample_data[i*2+1+j*2*two_sub_sample_nx] = val;
257  two_sub_sample_data[i*2+(j*2+1)*two_sub_sample_nx] = val;
258  two_sub_sample_data[i*2+1+(j*2+1)*two_sub_sample_nx] = val;
259  }
260  }
261  uves_msg_debug("Doing laplacian convolution");
262  /* Doing the laplacian convolution
263  0 -1 0
264  -1 4 -1
265  0 -1 0 */
266  check_nomsg(laplacian_image = uves_image_filter_linear( two_sub_sample,
267  laplacian_kernel));
268 
269  /* multiply by two to normalize correctly the laplacian [RD5]
270  and filter negative values */
271  uves_msg_debug("Normalize laplacian");
272  check_nomsg (laplacian_data = cpl_image_get_data_float( laplacian_image));
273  for ( i=0; i< two_sub_sample_nx*two_sub_sample_ny; i++){
274  if (laplacian_data[i] > 0.0){
275  laplacian_data[i] = 2.0 * laplacian_data[i];
276  }
277  else{
278  laplacian_data[i] = 0.0;
279  }
280  }
281  uves_msg_debug("Save Lpositive");
282  cpl_image_save(laplacian_image, "Lpositive.fits", CPL_BPP_IEEE_FLOAT, NULL,
283  CPL_IO_DEFAULT);
284 
285  /* resample to the original size
286  | 1 | 1 | 2 | 2 | | 1 | 2 |
287  | 1 | 1 | 2 | 2 | | 3 | 4 |
288  | 3 | 3 | 4 | 4 | =>
289  | 3 | 3 | 4 | 4 | */
290 
291  uves_msg_debug("Resample to the original size");
292 
293  for( j=0; j< ny; j++){
294  for( i=0; i< nx; i++){
295  laplacian_redu_data[i+j*nx] =
296  (laplacian_data[i*2+j*2*two_sub_sample_nx]+
297  laplacian_data[i*2+1+j*2*two_sub_sample_nx]+
298  laplacian_data[i*2+(j*2+1)*two_sub_sample_nx]+
299  laplacian_data[i*2+1+(j*2+1)*two_sub_sample_nx])/4.0;
300  }
301  }
302 
303  cpl_image_save(laplacian_redu_image, "Lplus.fits", CPL_BPP_IEEE_FLOAT,
304  NULL, CPL_IO_DEFAULT);
305 
306  uves_msg_debug("Apply median filter");
307  /* Apply 5x5 median filter on data */
308  check_nomsg( sci_median5_image = uves_image_filter_median( sci_image,
309  median5_kernel));
310  check_nomsg (sci_median5_data = cpl_image_get_data_float( sci_median5_image));
311 
312  uves_msg_debug("Compute noise");
313  /* computes the noise image */
314  for( i=0; i< nx*ny; i++){
315  noise_data[i] = sqrt(sci_median5_data[i]*gain+
316  ron*ron)/ gain;
317  }
318 
319  uves_msg_debug("Compute S");
320  /* compute S image */
321  for( i=0; i< nx*ny; i++){
322  s_data[i] = laplacian_redu_data[i] / (2.0*noise_data[i]);
323  }
324 
325  uves_msg_debug("Compute S median");
326  /* compute S median image */
327  check_nomsg( s_median_image = uves_image_filter_median( s_image,
328  median5_kernel));
329  check_nomsg( s_median_data = cpl_image_get_data_float( s_median_image));
330 
331  uves_msg_debug("Compute s2");
332  /* compute s2 */
333  for( i=0; i< nx*ny; i++){
334  s2_data[i] = s_data[i] -s_median_data[i];
335  }
336 
337  cpl_image_save( s2_image, "S2.fits", CPL_BPP_IEEE_FLOAT, NULL,
338  CPL_IO_DEFAULT);
339 
340  uves_msg_debug("Apply 3x3 filter");
341  /* Apply 3x3 median filter on data */
342  check_nomsg( sci_median3_image = uves_image_filter_median( sci_image,
343  median3_kernel));
344 
345  uves_msg_debug("Apply 7x7 filter");
346  /* Apply 7x7 median filter */
347  check_nomsg( sci_median3_7_image = uves_image_filter_median( sci_median3_image,
348  median7_kernel));
349  uves_msg_debug("Apply 7x7 filter ok");
350  check_nomsg ( sci_median3_data = cpl_image_get_data_float( sci_median3_image));
351  check_nomsg ( sci_median3_7_data = cpl_image_get_data_float(
352  sci_median3_7_image));
353 
354  uves_msg_debug("Compute F");
355  /* compute F */
356  for( i=0; i< nx*ny; i++){
357  f_data[i] = sci_median3_data[i] -sci_median3_7_data[i];
358  if (f_data[i] < 0.01){
359  f_data[i] = 0.01;
360  }
361  }
362  cpl_image_save( f_image, "F.fits", CPL_BPP_IEEE_FLOAT, NULL,
363  CPL_IO_DEFAULT);
364 
365  uves_msg_debug("Compute R");
366  /* compute R */
367  for( i=0; i< nx*ny; i++){
368  r_data[i] = laplacian_redu_data[i]/f_data[i];
369  }
370 
371  cpl_image_save( r_image, "R.fits", CPL_BPP_IEEE_FLOAT, NULL,
372  CPL_IO_DEFAULT);
373 
374  /* Search for cosmics */
375 
376  uves_msg_debug("Search for cosmic");
377  new_crh = 0;
378  median = cpl_vector_new(24);
379 
380  for( j=1; j< ny-1; j++){
381  double *data = NULL;
382  cpl_vector* med_vect = NULL;
383 
384  for( i=1; i< nx-1; i++){
385  if ( (s2_data[i+j*nx] >= sigma_lim) &&
386  (r_data[i+j*nx] >= f_lim)){
387  int li,lj,ui,uj;
388  cosmic_data[i+j*nx] = 1.0;
389  new_crh++;
390  li = i-2;
391  lj = j-2;
392  ui = i+2;
393  uj = j+2;
394  m = 0;
395  if (li < 0) li = 0;
396  if (ui >= nx) ui = nx-1;
397  if (lj < 0) lj = 0;
398  if (uj >= ny) uj = ny-1;
399  for( k=lj; k <= uj; k++){
400  for( l=li; l <= ui; l++){
401  //uves_msg("REGDEBUG k %d l %d m %d", k, l, m);
402  if ( k < j){
403  cpl_vector_set(median, m, sci_data[l+k*nx]);
404  m++;
405  }
406  else if ( (k == j) && ( l < i)){
407  cpl_vector_set(median, m, sci_data[l+k*nx]);
408  m++;
409  }
410  else if ( l!=i && k!=j && (s2_data[l+k*nx] < sigma_lim)
411  && (r_data[l+k*nx] < f_lim)){
412  cpl_vector_set(median, m, sci_data[l+k*nx]);
413  m++;
414  }
415  }
416  }
417  check_nomsg( data = cpl_vector_get_data( median));
418  uves_msg_debug("REGDEBUG i %d j %d m %d", i, j ,m);
419  check_nomsg( med_vect = cpl_vector_wrap( m, data));
420  check_nomsg( sci_data[i+j*nx] = cpl_vector_get_median( med_vect));
421  cpl_vector_unwrap( med_vect);
422  }
423  }
424  }
425  uves_free_vector( &median ) ;
426  nb_crh += new_crh;
427  frac = (double)nb_crh/(double)(nx*ny) ;
428  uves_msg(" new cosmics %d, total %d, frac %.4f [%d pixels]",new_crh,nb_crh,
429  frac, nx*ny);
430  nbiter++;
431  uves_free_image( &laplacian_image);
432  uves_free_image( &sci_median3_7_image ) ;
433  uves_free_image( &sci_median3_image ) ;
434  uves_free_image( &s_median_image ) ;
435  uves_free_image( &sci_median5_image ) ;
436  }
437  {
438  FILE *debug = NULL;
439 
440  debug = fopen("cosmic.log","w");
441 
442  for( j=0; j< ny; j++){
443  for( i=0; i< nx; i++){
444  if ( cosmic_data[i+j*nx] == 1.0){
445  fprintf(debug,"%.1f %.1f\n",i+1.0,j+1.0);
446  }
447  }
448  }
449  fclose(debug);
450  }
451 
452  //check_nomsg( res_frame = cpl_frame_duplicate( sci_frame ) ) ;
453  //uves_msg( "Saving Result Frame '%s'", res_name ) ;
454  //check_nomsg( add_qc_crh( sci_pre, nb_crh, 1, instrument ) ) ;
455  //check_nomsg( res_frame = xsh_pre_save( sci_pre, res_name, 1 ) ) ;
456  //tag = cpl_frame_get_tag( in_sci_frame ) ;
457  //check_nomsg( cpl_frame_set_tag( res_frame, tag ) ) ;
458 
459 
460  cleanup:
461  //xsh_pre_free( &sci_pre);
462  //xsh_localization_list_free( &loc_list ) ;
463 
464  /* free kernel */
465  uves_free_matrix( &laplacian_kernel);
466  uves_free_matrix( &median3_kernel);
467  uves_free_matrix( &median5_kernel);
468  uves_free_matrix( &median7_kernel);
469  /* free images */
470  uves_free_image( &laplacian_image);
471  uves_free_image( &laplacian_redu_image);
472  uves_free_image( &two_sub_sample);
473  uves_free_image( &sci_median5_image);
474  uves_free_image( &noise_image);
475  uves_free_image( &s_image);
476  uves_free_image( &s_median_image);
477  uves_free_image( &s2_image);
478  uves_free_image( &sci_median3_image);
479  uves_free_image( &sci_median3_7_image);
480  uves_free_image( &f_image);
481  uves_free_image( &r_image);
482  /* free vector */
483  uves_free_vector( &median);
484  /* free tab */
485  if(cosmic_data!=NULL) cpl_free( cosmic_data);
486  return res_image;
487 }