UVES Pipeline Reference Manual  5.4.6
uves_corrbadpix.c
1 /* *
2  * This file is part of the ESO UVES Pipeline *
3  * Copyright (C) 2004,2005 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  * $Date: 2010-09-24 09:32:02 $
23  * $Revision: 1.26 $
24  * $Name: not supported by cvs2svn $
25  * $Log: not supported by cvs2svn $
26  * Revision 1.24 2009/10/29 17:47:15 amodigli
27  * set location of new red ccd's traps
28  *
29  * Revision 1.23 2007/08/21 13:08:26 jmlarsen
30  * Removed irplib_access module, largely deprecated by CPL-4
31  *
32  * Revision 1.22 2007/07/23 06:37:44 amodigli
33  * we now support also input data type CPL_TYPE_FLOAT
34  *
35  * Revision 1.21 2007/06/06 08:17:33 amodigli
36  * replace tab with 4 spaces
37  *
38  * Revision 1.20 2007/04/24 12:50:29 jmlarsen
39  * Replaced cpl_propertylist -> uves_propertylist which is much faster
40  *
41  * Revision 1.19 2007/01/16 10:26:52 jmlarsen
42  * Fixed calloc -> cpl_calloc
43  *
44  * Revision 1.18 2007/01/15 15:10:01 jmlarsen
45  * Fixed memory bug in deallocator
46  *
47  * Revision 1.17 2007/01/15 13:57:20 jmlarsen
48  * Fixed crashing BLUE chips
49  *
50  * Revision 1.16 2007/01/10 12:35:59 jmlarsen
51  * Added uves_get_badpix
52  *
53  * Revision 1.15 2006/11/15 15:02:14 jmlarsen
54  * Implemented const safe workarounds for CPL functions
55  *
56  * Revision 1.13 2006/11/15 14:04:08 jmlarsen
57  * Removed non-const version of parameterlist_get_first/last/next which is already
58  * in CPL, added const-safe wrapper, unwrapper and deallocator functions
59  *
60  * Revision 1.12 2006/11/06 15:19:41 jmlarsen
61  * Removed unused include directives
62  *
63  * Revision 1.11 2006/08/17 13:56:52 jmlarsen
64  * Reduced max line length
65  *
66  * Revision 1.10 2006/08/17 09:16:30 jmlarsen
67  * Removed CPL2 code
68  *
69  * Revision 1.9 2006/08/14 12:15:26 jmlarsen
70  * Update to CPL3
71  *
72  * Revision 1.8 2006/08/10 10:49:06 jmlarsen
73  * Removed workaround for cpl_image_get_bpm
74  *
75  * Revision 1.7 2006/08/08 11:27:18 amodigli
76  * upgrade to CPL3
77  *
78  * Revision 1.6 2006/07/07 06:45:23 amodigli
79  * added doc
80  *
81  * Revision 1.5 2006/07/03 14:20:39 jmlarsen
82  * Exclude bad pixels from order tracing
83  *
84  * Revision 1.4 2006/07/03 12:58:34 jmlarsen
85  * Support flagging instead of interpolating bad pixels
86  *
87  * Revision 1.3 2006/04/06 08:29:56 jmlarsen
88  * Include self
89  *
90  * Revision 1.2 2005/12/19 16:17:56 jmlarsen
91  * Replaced bool -> int
92  *
93  * Revision 1.1 2005/11/11 13:18:54 jmlarsen
94  * Reorganized code, renamed source files
95  *
96  */
97 
98 #ifdef HAVE_CONFIG_H
99 # include <config.h>
100 #endif
101 
102 /*----------------------------------------------------------------------------*/
108 /*----------------------------------------------------------------------------*/
111 /*-----------------------------------------------------------------------------
112  Includes
113  -----------------------------------------------------------------------------*/
114 
115 #include "uves_corrbadpix.h"
116 
117 #include <uves_pfits.h>
118 #include <uves_dump.h>
119 #include <uves_error.h>
120 #include <uves_msg.h>
121 
122 #include <cpl.h>
123 
124 #include <stdbool.h>
125 /*-----------------------------------------------------------------------------
126  Functions prototypes
127  -----------------------------------------------------------------------------*/
128 static int
129 uves_correct_badpix(cpl_image *master_bias, uves_propertylist *header, int **badmap,
130  bool mark_bad);
131 
132 /*-----------------------------------------------------------------------------
133  Implementation
134  -----------------------------------------------------------------------------*/
135 
136 
137 /*----------------------------------------------------------------------------*/
154 /*----------------------------------------------------------------------------*/
155 int
156 uves_correct_badpix_all(cpl_image *master_bias, uves_propertylist *mbias_header,
157  enum uves_chip chip,
158  int binx, int biny, int mark_bad, bool red_ccd_new)
159 {
160  int badpixels_cleaned = -1; /* result */
161 
162  int **badmap = NULL;
163 
164  check( badmap = uves_get_badpix(chip, binx, biny, mark_bad,red_ccd_new),
165  "Could not get bad pixel map");
166 
167  check( badpixels_cleaned =
168  uves_correct_badpix(master_bias, mbias_header, badmap, mark_bad),
169  "Error cleaning bad pixels");
170 
171  cleanup:
172  uves_badmap_free(&badmap);
173  return badpixels_cleaned;
174 }
175 
176 
177 /*----------------------------------------------------------------------------*/
182 /*----------------------------------------------------------------------------*/
183 void
184 uves_badmap_free(int ***badmap)
185 {
186  if (badmap != NULL)
187  {
188  if (*badmap != NULL)
189  {
190  int row;
191  for (row = 0;
192  (*badmap)[row][0] != -1;
193  row++)
194  {
195  cpl_free((*badmap)[row]);
196  }
197  cpl_free((*badmap)[row]);
198 
199  cpl_free(*badmap);
200  *badmap = NULL;
201  }
202  }
203 }
204 
205 /*----------------------------------------------------------------------------*/
211 /*----------------------------------------------------------------------------*/
212 static int **
213 dup_map(int badmap[][4])
214 {
215  int **map = NULL;
216  int row;
217  bool finished = false;
218 
219  /* The execution time is O(n*n) which is okay, due to the low number
220  of entries */
221 
222  for (row = 0; !finished; row++)
223  {
224  map = cpl_realloc(map, (row+1)*sizeof(int *));
225  /* First time equivalent to: malloc(sizeof(int *)) */
226 
227  map[row] = cpl_calloc(4, sizeof(int));
228  map[row][0] = badmap[row][0];
229  map[row][1] = badmap[row][1];
230  map[row][2] = badmap[row][2];
231  map[row][3] = badmap[row][3];
232 
233  finished = (badmap[row][0] == -1);
234  }
235 
236  return map;
237 }
238 
239 
240 /*----------------------------------------------------------------------------*/
254 /*----------------------------------------------------------------------------*/
255 int **
256 uves_get_badpix(enum uves_chip chip,
257  int binx, int biny, int mark_bad,bool red_ccd_new)
258 {
259  int **map = NULL;
260 
261  if (chip == UVES_CHIP_REDL)
262  {
263  if (binx == 1 && biny == 1)
264  {
265  if(red_ccd_new) {
266 
267  int badmap[][4] = {{1,4,2088,4},
268  {1,63,2282,63},
269  {1,108,1778,108},
270  {1,176,2443,176},
271  {1,196,2021,196},
272  {1,285,1974,285},
273  {1,352,1942,352},
274  {-1,-1,-1,-1}};
275 
276  if (!mark_bad)
277  {
278  badmap[2][0] = -1;
279  badmap[2][1] = -1;
280  badmap[2][2] = -1;
281  badmap[2][3] = -1;
282  }
283 
284 /*
285  int badmap[][4] = {{1,4,2088,4},
286  {1,63,2282,63},
287  {1,176,2443,176},
288  {1,196,2021,196},
289  {1,285,1974,285},
290  {1,352,1942,352},
291  {-1,-1,-1,-1}};
292 */
293  map = dup_map(badmap);
294 
295  } else {
296  int badmap[][4] = {{1,4,2088,4},
297  {1,63,2282,63},
298  {1,108,1778,108},
299  {1,176,2443,176},
300  {1,196,2021,196},
301  {1,285,1974,285},
302  {1,352,1942,352},
303  {-1,-1,-1,-1}};
304  map = dup_map(badmap);
305 
306  }
307 
308  }
309  else if (binx == 1 && biny == 2)
310  {
311 
312 
313  if(red_ccd_new) {
314 
315  int badmap[][4] = {{1,4,1045,4},
316  {1,63,1141,63},
317  {1,108,894,108},
318  {1,176,1222,176},
319  {1,196,1011,196},
320  {1,285,988,285},
321  {1,352,971,352},
322  {-1,-1,-1,-1}};
323  map = dup_map(badmap);
324  } else {
325 
326  int badmap[][4] = {{1,4,1044,4},
327  {1,63,1141,63},
328  {1,108,894,108},
329  {1,176,1222,176},
330  {1,196,1011,196},
331  {1,285,988,285},
332  {1,352,971,352},
333  {-1,-1,-1,-1}};
334 
335  map = dup_map(badmap);
336  }
337  }
338  else if (binx == 2 && biny == 2)
339  {
340  if(red_ccd_new) {
341 
342  int badmap[][4] = {{1,4,1045,4},
343  {1,14,1255,14},
344  {1,33,1141,33},
345  {1,89,1222,89},
346  {1,99,1011,100},
347  {1,144,988,144},
348  {1,177,971,178},
349  {-1,-1,-1,-1}};
350 
351  map = dup_map(badmap);
352  } else {
353  int badmap[][4] = {{1,3,1044,3},
354  {1,33,1141,33},
355  {1,55,894,56},
356  {1,89,1222,90},
357  {1,99,1011,100},
358  {1,144,988,145},
359  {1,177,971,178},
360  {-1,-1,-1,-1}};
361  map = dup_map(badmap);
362  }
363  }
364  else if (binx == 2 && biny == 3)
365  {
366 
367  if(red_ccd_new) {
368 
369  int badmap[][4] = {{1,3,696,3},
370  {1,14,836,15},
371  {1,33,761,33},
372  {1,55,596,56},
373  {1,89,814,90},
374  {1,97,805,90},
375  {1,99,674,100},
376  {1,144,658,144},
377  {1,156,784,156},
378  {1,168,759,168},
379  {1,177,647,178},
380  {1,203,826,203},
381  {1,263,714,263},
382  {-1,-1,-1,-1}};
383  map = dup_map(badmap);
384  } else {
385 
386  int badmap[][4] = {{1,3,696,3},
387  {1,33,761,33},
388  {1,55,592,56},
389  {1,89,814,90},
390  {1,99,674,100},
391  {1,144,658,144},
392  {1,177,647,178},
393  {-1,-1,-1,-1}};
394 
395  map = dup_map(badmap);
396  }
397  }
398  else
399  {
400  assure( false, CPL_ERROR_ILLEGAL_INPUT,
401  "Don't know bad pixel map for %dx%d binning, red, lower chip",
402  binx, biny);
403  }
404  }
405  else if (chip == UVES_CHIP_REDU)
406  {
407  /* Use different bad pixels maps for bias and
408  orderpos recipes !
409  */
410  if (binx == 1 && biny ==1)
411  {
412  if(red_ccd_new) {
413 
414  int badmap[][4] = {
415  {1,845,1268,845},
416  {-1,-1,-1,-1}};
417 
418  if (!mark_bad)
419  {
420  badmap[2][0] = -1;
421  badmap[2][1] = -1;
422  badmap[2][2] = -1;
423  badmap[2][3] = -1;
424  }
425  map = dup_map(badmap);
426  } else {
427 
428  int badmap[][4] = {
429  {1,2030,1268,2033},
430  {1269,2033,4096,2033},
431  {1201, 491, 3271, 492},
432  {-1,-1,-1,-1}};
433 
434  if (!mark_bad)
435  {
436  badmap[2][0] = -1;
437  badmap[2][1] = -1;
438  badmap[2][2] = -1;
439  badmap[2][3] = -1;
440  }
441  map = dup_map(badmap);
442  }
443  }
444  else if (binx == 1 && biny == 2)
445  {
446 
447  if(red_ccd_new) {
448 
449  int badmap[][4] = {{1,1396,845,1396},
450  {-1,-1,-1,-1}};
451 
452  if (!mark_bad)
453  {
454  badmap[2][0] = -1;
455  badmap[2][1] = -1;
456  badmap[2][2] = -1;
457  badmap[2][3] = -1;
458  }
459  map = dup_map(badmap);
460  } else {
461 
462  int badmap[][4] = {{1,2030,634,2033},
463  {635,2033,2048,2033},
464  {600, 491,1635, 492},
465  {-1,-1,-1,-1}};
466 
467  if (!mark_bad)
468  {
469  badmap[2][0] = -1;
470  badmap[2][1] = -1;
471  badmap[2][2] = -1;
472  badmap[2][3] = -1;
473  }
474  map = dup_map(badmap);
475  }
476  }
477  else if (binx == 2 && biny == 2)
478  {
479 
480  if(red_ccd_new) {
481 
482  int badmap[][4] = {{1,422,1526,422},
483  {-1,-1,-1,-1}};
484 
485  if (!mark_bad)
486  {
487  badmap[2][0] = -1;
488  badmap[2][1] = -1;
489  badmap[2][2] = -1;
490  badmap[2][3] = -1;
491  }
492  map = dup_map(badmap);
493  } else {
494 
495  int badmap[][4] = {{1,1013,634,1016},
496  {635,1015,2048,1016},
497  {600, 244,1635, 245},
498  {-1,-1,-1,-1}};
499 
500  if (!mark_bad)
501  {
502  badmap[2][0] = -1;
503  badmap[2][1] = -1;
504  badmap[2][2] = -1;
505  badmap[2][3] = -1;
506  }
507  map = dup_map(badmap);
508  }
509  }
510  else if (binx == 2 && biny == 3)
511  {
512 
513  if(red_ccd_new) {
514  int badmap[][4] = {{1,61,287,62},
515  {1,422,1051,422},
516  {400, 872,1265, 872},
517  {-1,-1,-1,-1}};
518 
519  if (!mark_bad)
520  {
521  badmap[2][0] = -1;
522  badmap[2][1] = -1;
523  badmap[2][2] = -1;
524  badmap[2][3] = -1;
525  }
526  map = dup_map(badmap);
527 
528  } else {
529 
530  int badmap[][4] = {{1,1013,423,1016},
531  {424,1015,1365,1016},
532  {400, 244,1090, 245},
533  {-1,-1,-1,-1}};
534 
535  if (!mark_bad)
536  {
537  badmap[2][0] = -1;
538  badmap[2][1] = -1;
539  badmap[2][2] = -1;
540  badmap[2][3] = -1;
541  }
542  map = dup_map(badmap);
543 
544 
545  }
546  }
547  else
548  {
549  assure( false, CPL_ERROR_ILLEGAL_INPUT,
550  "Don't know bad pixel map for %dx%d binning, red, upper chip",
551  binx, biny);
552  }
553  }
554  else
555  {
556  /* No blue chip bad pixels */
557  int badmap[][4] = {{-1,-1,-1,-1}};
558 
559  map = dup_map(badmap);
560  }
561 
562  cleanup:
563  return map;
564 }
565 
566 
567 
568 /*----------------------------------------------------------------------------*/
583 /*----------------------------------------------------------------------------*/
584 static int
585 uves_correct_badpix(cpl_image *master_bias, uves_propertylist *header, int **badmap,
586  bool mark_bad)
587 {
588  int ncorrect = 0; /* Result */
589  int xstart, ystart, xend, yend;
590  int row;
591  bool finished = false;
592  int nx, ny;
593  cpl_mask *image_bad = NULL;
594  cpl_binary*image_bpm = NULL;
595  cpl_type type=0;
596 
597  type=cpl_image_get_type(master_bias);
598  assure( (type == CPL_TYPE_DOUBLE) || (type == CPL_TYPE_FLOAT),
599  CPL_ERROR_UNSUPPORTED_MODE,
600  "Image type must be float or double. It is %s",
601  uves_tostring_cpl_type(cpl_image_get_type(master_bias)));
602 
603  image_bad = cpl_image_get_bpm(master_bias);
604  image_bpm = cpl_mask_get_data(image_bad);
605 
606  nx = cpl_image_get_size_x(master_bias);
607  ny = cpl_image_get_size_y(master_bias);
608 
609  row = 0;
610  while (!finished)
611  {
612  xstart = badmap[row][0];
613  ystart = badmap[row][1];
614  xend = badmap[row][2];
615  yend = badmap[row][3];
616 
617  if (xstart > 0)
618  {
619  int ylow, yhigh;
620  int x, y;
621 
622  assure( 1 <= xstart && xstart <= nx &&
623  1 <= xend && xend <= nx &&
624  1 <= ystart && ystart <= ny &&
625  1 <= yend && yend <= ny, CPL_ERROR_ILLEGAL_INPUT,
626  "Illegal window (%d, %d) - (%d, %d). Image size = %dx%d",
627  xstart, ystart, xend, yend, nx, ny);
628 
629  if ( ystart < 3 )
630  {
631  assure( yend + 2 <= ny, CPL_ERROR_ILLEGAL_INPUT,
632  "Too large range in y: %d - %d", ystart, yend);
633 
634  ylow = yend + 1;
635  yhigh = yend + 2;
636  }
637  else if (yend > ny - 3 )
638  {
639  assure( ystart - 2 >= 1, CPL_ERROR_ILLEGAL_INPUT,
640  "Too large range in y: %d - %d", ystart, yend);
641 
642  ylow = ystart - 2;
643  yhigh = ystart - 1;
644  }
645  else
646  {
647  ylow = ystart - 2;
648  yhigh = yend + 2;
649  }
650 
651  uves_msg("Correcting window (%d, %d)-(%d, %d)", xstart, ystart, xend, yend);
652 
653 
654  if(type == CPL_TYPE_DOUBLE) {
655 
656  for (x = xstart; x <= xend; x++) {
657  for (y = ystart; y <= yend; y++) {
658  int pis_rejected;
659  double i1, i2;
660 
661  if (mark_bad)
662  {
663  /* This is extremely slow with CPL2:
664  cpl_image_reject(master_bias, x, y);
665  */
666  image_bpm[(x-1) + (y-1)*nx] = CPL_BINARY_1;
667  }
668  else
669  /* interpolate */
670  {
671  double *master_bias_data;
672 
673  i1 = cpl_image_get(master_bias, x, ylow , &pis_rejected);
674  i2 = cpl_image_get(master_bias, x, yhigh, &pis_rejected);
675 
676  /* Write average */
677 
678  /* This will make the bpm invalid:
679  cpl_image_set(master_bias, x, y, (i1+i2)/2);
680  */
681  master_bias_data = cpl_image_get_data_double(master_bias);
682  master_bias_data[(x-1) + (y-1)*nx] = (i1+i2)/2;
683  }
684  ncorrect += 1;
685  }
686  }
687 
688 
689  } else {
690 
691 
692  for (x = xstart; x <= xend; x++) {
693  for (y = ystart; y <= yend; y++) {
694  int pis_rejected;
695  float i1, i2;
696 
697  if (mark_bad)
698  {
699  /* This is extremely slow with CPL2:
700  cpl_image_reject(master_bias, x, y);
701  */
702  image_bpm[(x-1) + (y-1)*nx] = CPL_BINARY_1;
703  }
704  else
705  /* interpolate */
706  {
707  float *master_bias_data;
708 
709  i1 = cpl_image_get(master_bias, x, ylow , &pis_rejected);
710  i2 = cpl_image_get(master_bias, x, yhigh, &pis_rejected);
711 
712  /* Write average */
713 
714  /* This will make the bpm invalid:
715  cpl_image_set(master_bias, x, y, (i1+i2)/2);
716  */
717  master_bias_data = cpl_image_get_data_float(master_bias);
718  master_bias_data[(x-1) + (y-1)*nx] = (i1+i2)/2;
719  }
720  ncorrect += 1;
721  }
722  }
723 
724 
725  }
726 
727 
728  }
729  else
730  {
731  finished = true;
732  }
733  row++;
734  }
735 
736  /* Update product header */
737  if (ncorrect > 0)
738  {
739  check( uves_pfits_set_badpixcorr(header, "true"),
740  "Error updating product header");
741  }
742 
743  cleanup:
744  return ncorrect;
745 }
static int uves_correct_badpix(cpl_image *master_bias, uves_propertylist *header, int **badmap, bool mark_bad)
Correct bad pixels.
cpl_error_code uves_pfits_set_badpixcorr(uves_propertylist *plist, const char *corr)
Write the object keyword.
Definition: uves_pfits.c:2571
void uves_badmap_free(int ***badmap)
Deallocate bpm position.
int ** uves_get_badpix(enum uves_chip chip, int binx, int biny, int mark_bad, bool red_ccd_new)
Get hard-coded bpm map.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
Definition: uves_msg.h:119
static int ** dup_map(int badmap[][4])
Copy bpm to heap.
const char * uves_tostring_cpl_type(cpl_type t)
Convert a CPL type to a string.
Definition: uves_dump.c:378
int uves_correct_badpix_all(cpl_image *master_bias, uves_propertylist *mbias_header, enum uves_chip chip, int binx, int biny, int mark_bad, bool red_ccd_new)
Correct all bad pixels on a chip.
#define check(CMD,...)
Definition: uves_error.h:198