SINFONI Pipeline Reference Manual  2.5.2
sinfo_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: 2012-03-03 10:18:26 $
24  * $Revision: 1.5 $
25  *
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 
33 /*----------------------------------------------------------------------------*/
40 /*----------------------------------------------------------------------------*/
41 
42 /*-----------------------------------------------------------------------------
43  Includes
44 -----------------------------------------------------------------------------*/
45 
46 #include <math.h>
47 
48 
49 #include <sinfo_error.h>
50 #include <sinfo_msg.h>
51 #include <sinfo_utils_wrappers.h>
52 #include <cpl.h>
53 #include "sinfo_utilities.h"
54 /*-----------------------------------------------------------------------------
55  Functions prototypes
56  -----------------------------------------------------------------------------*/
57 cpl_image * sinfo_remove_crh_single( cpl_image * sci_image,
58  double crh_frac_max,
59  double sigma_lim,
60  double f_lim,
61  int max_iter,
62  double gain,
63  double ron);
64 /*-----------------------------------------------------------------------------
65  Implementation
66  -----------------------------------------------------------------------------*/
67 
68 /* This should be defined in a more clever way, a parameter for example */
69 #define MAX_ITERATIONS 6
70 
71 
93 cpl_image * sinfo_remove_crh_single( cpl_image * sci_image,
94  double crh_frac_max,
95  double sigma_lim,
96  double f_lim,
97  int max_iter,
98  double gain,
99  double ron)
100 {
101  int i,j,k,l,m;
102  double frac = 0. ;
103  /* Only pointers */
104 
105  /* Need to be free */
106  //xsh_localization_list * loc_list = NULL ;
107  cpl_image* laplacian_image = NULL;
108  cpl_image* laplacian_redu_image = NULL;
109  cpl_image* two_sub_sample = NULL;
110  cpl_image* sci_median5_image = NULL;
111  cpl_image* noise_image = NULL;
112  cpl_image* s_image = NULL;
113  cpl_image* s_median_image = NULL;
114  cpl_image* s2_image = NULL;
115  cpl_image* sci_median3_image = NULL;
116  cpl_image* sci_median3_7_image = NULL;
117  cpl_image* f_image = NULL;
118  cpl_image* r_image = NULL;
119  int two_sub_sample_nx = 0;
120  int two_sub_sample_ny = 0;
121  /* Only pointers */
122  float* sci_data = NULL;
123  float* two_sub_sample_data = NULL;
124  float* laplacian_data = NULL;
125  float* laplacian_redu_data = NULL;
126  float* sci_median5_data = NULL;
127  float* sci_median3_data = NULL;
128  float* sci_median3_7_data = NULL;
129  float* noise_data = NULL;
130  float* s_data = NULL;
131  float* s_median_data = NULL;
132  float* s2_data = NULL;
133  float* f_data = NULL;
134  float* r_data = NULL;
135  /* Need to be free */
136  float* cosmic_data = NULL;
137 
138  cpl_matrix* laplacian_kernel = NULL;
139  cpl_matrix* median3_kernel = NULL;
140  cpl_matrix* median5_kernel = NULL;
141  cpl_matrix* median7_kernel = NULL;
142  int new_crh =1, nb_crh = 0;
143  int nbiter = 1 ;
144  cpl_vector* median = NULL;
145  //const char * tag = NULL ;
146  int nx=0;
147  int ny=0;
148  cpl_image* res_image=NULL;
149 
150  /* Check parameters */
151  cknull( sci_image,"null input image" ) ; ;
152 
153  sinfo_msg( "Entering sinfo_remove_crh_single");
154  sinfo_msg( " Params: frac_max %.1f, sigma_lim %.2f f_lim %.2f, iter %d",
155  crh_frac_max, sigma_lim, f_lim, max_iter);
156 
157  /* Preparing different kernels */
158  nx=cpl_image_get_size_x(sci_image);
159  ny=cpl_image_get_size_y(sci_image);
160 
161  /* Laplacian */
162  check_nomsg( laplacian_kernel = cpl_matrix_new(3,3));
163  cpl_matrix_set( laplacian_kernel,0,0,0.0);
164  cpl_matrix_set( laplacian_kernel,0,1,-1.0);
165  cpl_matrix_set( laplacian_kernel,0,2,0.0);
166  cpl_matrix_set( laplacian_kernel,1,0,-1.0);
167  cpl_matrix_set( laplacian_kernel,1,1,4.0);
168  cpl_matrix_set( laplacian_kernel,1,2,-1.0);
169  cpl_matrix_set( laplacian_kernel,2,0,0.0);
170  cpl_matrix_set( laplacian_kernel,2,1,-1.0);
171  cpl_matrix_set( laplacian_kernel,2,2,0.0);
172  cpl_matrix_divide_scalar( laplacian_kernel, 4.0);
173  /*
174  cpl_matrix_set( laplacian_kernel,0,0,-1.0);
175  cpl_matrix_set( laplacian_kernel,0,1,-1.0);
176  cpl_matrix_set( laplacian_kernel,0,2,-1.0);
177  cpl_matrix_set( laplacian_kernel,1,0,-1.0);
178  cpl_matrix_set( laplacian_kernel,1,1,8.0);
179  cpl_matrix_set( laplacian_kernel,1,2,-1.0);
180  cpl_matrix_set( laplacian_kernel,2,0,-1.0);
181  cpl_matrix_set( laplacian_kernel,2,1,-1.0);
182  cpl_matrix_set( laplacian_kernel,2,2,-1.0);
183  cpl_matrix_divide_scalar( laplacian_kernel, 8.0);
184  */
185  /* Median 3x3*/
186  check_nomsg( median3_kernel = cpl_matrix_new(3,3));
187  for(j=0; j< 3; j++){
188  for(i=0; i< 3; i++){
189  cpl_matrix_set( median3_kernel, i,j,1.0);
190  }
191  }
192 
193  /* Median 5x5 */
194  check_nomsg( median5_kernel = cpl_matrix_new(5,5));
195  for(j=0; j< 5; j++){
196  for(i=0; i< 5; i++){
197  cpl_matrix_set( median5_kernel, i,j,1.0);
198  }
199  }
200 
201  /* Median 7x7 */
202  check_nomsg( median7_kernel = cpl_matrix_new(7,7));
203  for(j=0; j< 7; j++){
204  for(i=0; i< 7; i++){
205  cpl_matrix_set( median7_kernel, i,j,1.0);
206  }
207  }
208 
209  check_nomsg (res_image = cpl_image_duplicate( sci_image));
210 
211  /* Allocate images and pointers */
212  check_nomsg (sci_data = cpl_image_get_data_float( res_image));
213 
214  two_sub_sample_nx = nx*2;
215  two_sub_sample_ny = ny*2;
216  check_nomsg( two_sub_sample = cpl_image_new( two_sub_sample_nx,
217  two_sub_sample_ny, CPL_TYPE_FLOAT));
218  check_nomsg(two_sub_sample_data = cpl_image_get_data_float( two_sub_sample));
219  check_nomsg( laplacian_redu_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
220  check_nomsg(laplacian_redu_data = cpl_image_get_data_float(
221  laplacian_redu_image));
222  check_nomsg( noise_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
223  check_nomsg( noise_data = cpl_image_get_data_float( noise_image));
224  check_nomsg( s_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
225  check_nomsg( s_data = cpl_image_get_data_float( s_image));
226  check_nomsg( s2_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
227  check_nomsg( s2_data = cpl_image_get_data_float( s2_image));
228  check_nomsg( f_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
229  check_nomsg( f_data = cpl_image_get_data_float( f_image));
230  check_nomsg( r_image = cpl_image_new(nx,ny, CPL_TYPE_FLOAT));
231  check_nomsg( r_data = cpl_image_get_data_float( r_image));
232  cosmic_data=cpl_calloc(nx*ny, sizeof(float));
233 
234  /* LGG - Added limit on frac_max AND limit on nb iterations */
235  while( new_crh > 0 && frac < crh_frac_max && nbiter <= max_iter ){
236  sinfo_msg("Iteration %d",nbiter );
237  /* Create a 2n x 2n images like this
238  | 1 | 2 | => | 1 | 1 | 2 | 2 |
239  | 3 | 4 | | 1 | 1 | 2 | 2 |
240  | 3 | 3 | 4 | 4 |
241  | 3 | 3 | 4 | 4 | */
242  sinfo_msg_debug("Create a 2n images");
243  for( j=0; j< ny; j++){
244  for( i=0; i< nx; i++){
245  float val = sci_data[i+j*nx];
246 
247  if ( val < 0. ) val = 0. ;
248  two_sub_sample_data[i*2+j*2*two_sub_sample_nx] = val;
249  two_sub_sample_data[i*2+1+j*2*two_sub_sample_nx] = val;
250  two_sub_sample_data[i*2+(j*2+1)*two_sub_sample_nx] = val;
251  two_sub_sample_data[i*2+1+(j*2+1)*two_sub_sample_nx] = val;
252  }
253  }
254  sinfo_msg_debug("Doing laplacian convolution");
255  /* Doing the laplacian convolution
256  0 -1 0
257  -1 4 -1
258  0 -1 0 */
259  laplacian_image = sinfo_image_filter_linear( two_sub_sample,
260  laplacian_kernel);
261 
262  /* multiply by two to normalize correctly the laplacian [RD5]
263  and filter negative values */
264  sinfo_msg_debug("Normalize laplacian");
265  check_nomsg (laplacian_data = cpl_image_get_data_float( laplacian_image));
266  for ( i=0; i< two_sub_sample_nx*two_sub_sample_ny; i++){
267  if (laplacian_data[i] > 0.0){
268  laplacian_data[i] = 2.0 * laplacian_data[i];
269  }
270  else{
271  laplacian_data[i] = 0.0;
272  }
273  }
274  sinfo_msg_debug("Save Lpositive");
275  cpl_image_save(laplacian_image, "Lpositive.fits", CPL_BPP_IEEE_FLOAT, NULL,
276  CPL_IO_DEFAULT);
277 
278  /* resample to the original size
279  | 1 | 1 | 2 | 2 | | 1 | 2 |
280  | 1 | 1 | 2 | 2 | | 3 | 4 |
281  | 3 | 3 | 4 | 4 | =>
282  | 3 | 3 | 4 | 4 | */
283 
284  sinfo_msg_debug("Resample to the original size");
285 
286  for( j=0; j< ny; j++){
287  for( i=0; i< nx; i++){
288  laplacian_redu_data[i+j*nx] =
289  (laplacian_data[i*2+j*2*two_sub_sample_nx]+
290  laplacian_data[i*2+1+j*2*two_sub_sample_nx]+
291  laplacian_data[i*2+(j*2+1)*two_sub_sample_nx]+
292  laplacian_data[i*2+1+(j*2+1)*two_sub_sample_nx])/4.0;
293  }
294  }
295 
296  cpl_image_save(laplacian_redu_image, "Lplus.fits", CPL_BPP_IEEE_FLOAT,
297  NULL, CPL_IO_DEFAULT);
298 
299  sinfo_msg_debug("Apply median filter");
300  /* Apply 5x5 median filter on data */
301  check_nomsg( sci_median5_image = sinfo_image_filter_median( sci_image,
302  median5_kernel));
303  check_nomsg (sci_median5_data = cpl_image_get_data_float( sci_median5_image));
304 
305  sinfo_msg_debug("Compute noise");
306  /* computes the noise image */
307  for( i=0; i< nx*ny; i++){
308  noise_data[i] = sqrt(sci_median5_data[i]*gain+
309  ron*ron)/ gain;
310  }
311 
312  sinfo_msg_debug("Compute S");
313  /* compute S image */
314  for( i=0; i< nx*ny; i++){
315  s_data[i] = laplacian_redu_data[i] / (2.0*noise_data[i]);
316  }
317 
318  sinfo_msg_debug("Compute S median");
319  /* compute S median image */
320  check_nomsg( s_median_image = sinfo_image_filter_median( s_image,
321  median5_kernel));
322  check_nomsg( s_median_data = cpl_image_get_data_float( s_median_image));
323 
324  sinfo_msg_debug("Compute s2");
325  /* compute s2 */
326  for( i=0; i< nx*ny; i++){
327  s2_data[i] = s_data[i] -s_median_data[i];
328  }
329 
330  cpl_image_save( s2_image, "S2.fits", CPL_BPP_IEEE_FLOAT, NULL,
331  CPL_IO_DEFAULT);
332 
333  sinfo_msg_debug("Apply 3x3 filter");
334  /* Apply 3x3 median filter on data */
335  check_nomsg( sci_median3_image = sinfo_image_filter_median( sci_image,
336  median3_kernel));
337 
338  sinfo_msg_debug("Apply 7x7 filter");
339  /* Apply 7x7 median filter */
340  check_nomsg( sci_median3_7_image = sinfo_image_filter_median( sci_median3_image,
341  median7_kernel));
342  sinfo_msg_debug("Apply 7x7 filter ok");
343  check_nomsg ( sci_median3_data = cpl_image_get_data_float( sci_median3_image));
344  check_nomsg ( sci_median3_7_data = cpl_image_get_data_float(
345  sci_median3_7_image));
346 
347  sinfo_msg_debug("Compute F");
348  /* compute F */
349  for( i=0; i< nx*ny; i++){
350  f_data[i] = sci_median3_data[i] -sci_median3_7_data[i];
351  if (f_data[i] < 0.01){
352  f_data[i] = 0.01;
353  }
354  }
355  cpl_image_save( f_image, "F.fits", CPL_BPP_IEEE_FLOAT, NULL,
356  CPL_IO_DEFAULT);
357 
358  sinfo_msg_debug("Compute R");
359  /* compute R */
360  for( i=0; i< nx*ny; i++){
361  r_data[i] = laplacian_redu_data[i]/f_data[i];
362  }
363 
364  cpl_image_save( r_image, "R.fits", CPL_BPP_IEEE_FLOAT, NULL,
365  CPL_IO_DEFAULT);
366 
367  /* Search for cosmics */
368 
369  sinfo_msg_debug("Search for cosmic");
370  new_crh = 0;
371  median = cpl_vector_new(24);
372 
373  for( j=1; j< ny-1; j++){
374  double *data = NULL;
375  cpl_vector* med_vect = NULL;
376 
377  for( i=1; i< nx-1; i++){
378  if ( (s2_data[i+j*nx] >= sigma_lim) &&
379  (r_data[i+j*nx] >= f_lim)){
380  int li,lj,ui,uj;
381  cosmic_data[i+j*nx] = 1.0;
382  new_crh++;
383  li = i-2;
384  lj = j-2;
385  ui = i+2;
386  uj = j+2;
387  m = 0;
388  if (li < 0) li = 0;
389  if (ui >= nx) ui = nx-1;
390  if (lj < 0) lj = 0;
391  if (uj >= ny) uj = ny-1;
392  for( k=lj; k <= uj; k++){
393  for( l=li; l <= ui; l++){
394  //sinfo_msg("REGDEBUG k %d l %d m %d", k, l, m);
395  if ( k < j){
396  cpl_vector_set(median, m, sci_data[l+k*nx]);
397  m++;
398  }
399  else if ( (k == j) && ( l < i)){
400  cpl_vector_set(median, m, sci_data[l+k*nx]);
401  m++;
402  }
403  else if ( l!=i && k!=j && (s2_data[l+k*nx] < sigma_lim)
404  && (r_data[l+k*nx] < f_lim)){
405  cpl_vector_set(median, m, sci_data[l+k*nx]);
406  m++;
407  }
408  }
409  }
410  check_nomsg( data = cpl_vector_get_data( median));
411  sinfo_msg_debug("REGDEBUG i %d j %d m %d", i, j ,m);
412  check_nomsg( med_vect = cpl_vector_wrap( m, data));
413  check_nomsg( sci_data[i+j*nx] = cpl_vector_get_median( med_vect));
414  cpl_vector_unwrap( med_vect);
415  }
416  }
417  }
418  sinfoni_free_vector( &median ) ;
419  nb_crh += new_crh;
420  frac = (double)nb_crh/(double)(nx*ny) ;
421  sinfo_msg(" new cosmics %d, total %d, frac %.4f [%d pixels]",new_crh,nb_crh,
422  frac, nx*ny);
423  nbiter++;
424  sinfo_free_image( &laplacian_image);
425  sinfo_free_image( &sci_median3_7_image ) ;
426  sinfo_free_image( &sci_median3_image ) ;
427  sinfo_free_image( &s_median_image ) ;
428  sinfo_free_image( &sci_median5_image ) ;
429  }
430  {
431  FILE *debug = NULL;
432 
433  debug = fopen("cosmic.log","w");
434 
435  for( j=0; j< ny; j++){
436  for( i=0; i< nx; i++){
437  if ( cosmic_data[i+j*nx] == 1.0){
438  fprintf(debug,"%.1f %.1f\n",i+1.0,j+1.0);
439  }
440  }
441  }
442  fclose(debug);
443  }
444 
445  //check_nomsg( res_frame = cpl_frame_duplicate( sci_frame ) ) ;
446  //sinfo_msg( "Saving Result Frame '%s'", res_name ) ;
447  //check_nomsg( add_qc_crh( sci_pre, nb_crh, 1, instrument ) ) ;
448  //check_nomsg( res_frame = xsh_pre_save( sci_pre, res_name, 1 ) ) ;
449  //tag = cpl_frame_get_tag( in_sci_frame ) ;
450  //check_nomsg( cpl_frame_set_tag( res_frame, tag ) ) ;
451 
452  cleanup:
453  //xsh_pre_free( &sci_pre);
454  //xsh_localization_list_free( &loc_list ) ;
455 
456  /* free kernel */
457  sinfoni_free_matrix( &laplacian_kernel);
458  sinfoni_free_matrix( &median3_kernel);
459  sinfoni_free_matrix( &median5_kernel);
460  sinfoni_free_matrix( &median7_kernel);
461  /* free images */
462  sinfo_free_image( &laplacian_image);
463  sinfo_free_image( &laplacian_redu_image);
464  sinfo_free_image( &two_sub_sample);
465  sinfo_free_image( &sci_median5_image);
466  sinfo_free_image( &noise_image);
467  sinfo_free_image( &s_image);
468  sinfo_free_image( &s_median_image);
469  sinfo_free_image( &s2_image);
470  sinfo_free_image( &sci_median3_image);
471  sinfo_free_image( &sci_median3_7_image);
472  sinfo_free_image( &f_image);
473  sinfo_free_image( &r_image);
474  /* free vector */
475  sinfoni_free_vector( &median);
476  /* free tab */
477  if(cosmic_data!=NULL) cpl_free( cosmic_data);
478  return res_image;
479 }