UVES Pipeline Reference Manual  5.5.5b3
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  *
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 
32 /*----------------------------------------------------------------------------*/
38 /*----------------------------------------------------------------------------*/
41 /*-----------------------------------------------------------------------------
42  Includes
43  -----------------------------------------------------------------------------*/
44 
45 #include "uves_corrbadpix.h"
46 
47 #include <uves_pfits.h>
48 #include <uves_dump.h>
49 #include <uves_error.h>
50 #include <uves_msg.h>
51 
52 #include <cpl.h>
53 
54 #include <stdbool.h>
55 /*-----------------------------------------------------------------------------
56  Functions prototypes
57  -----------------------------------------------------------------------------*/
58 static int
59 uves_correct_badpix(cpl_image *master_bias, uves_propertylist *header, int **badmap,
60  bool mark_bad);
61 
62 /*-----------------------------------------------------------------------------
63  Implementation
64  -----------------------------------------------------------------------------*/
65 
66 
67 /*----------------------------------------------------------------------------*/
84 /*----------------------------------------------------------------------------*/
85 int
86 uves_correct_badpix_all(cpl_image *master_bias, uves_propertylist *mbias_header,
87  enum uves_chip chip,
88  int binx, int biny, int mark_bad, bool red_ccd_new)
89 {
90  int badpixels_cleaned = -1; /* result */
91 
92  int **badmap = NULL;
93 
94  check( badmap = uves_get_badpix(chip, binx, biny, mark_bad,red_ccd_new),
95  "Could not get bad pixel map");
96 
97  check( badpixels_cleaned =
98  uves_correct_badpix(master_bias, mbias_header, badmap, mark_bad),
99  "Error cleaning bad pixels");
100 
101  cleanup:
102  uves_badmap_free(&badmap);
103  return badpixels_cleaned;
104 }
105 
106 
107 /*----------------------------------------------------------------------------*/
112 /*----------------------------------------------------------------------------*/
113 void
114 uves_badmap_free(int ***badmap)
115 {
116  if (badmap != NULL)
117  {
118  if (*badmap != NULL)
119  {
120  int row;
121  for (row = 0;
122  (*badmap)[row][0] != -1;
123  row++)
124  {
125  cpl_free((*badmap)[row]);
126  }
127  cpl_free((*badmap)[row]);
128 
129  cpl_free(*badmap);
130  *badmap = NULL;
131  }
132  }
133 }
134 
135 /*----------------------------------------------------------------------------*/
141 /*----------------------------------------------------------------------------*/
142 static int **
143 dup_map(int badmap[][4])
144 {
145  int **map = NULL;
146  int row;
147  bool finished = false;
148 
149  /* The execution time is O(n*n) which is okay, due to the low number
150  of entries */
151 
152  for (row = 0; !finished; row++)
153  {
154  map = cpl_realloc(map, (row+1)*sizeof(int *));
155  /* First time equivalent to: malloc(sizeof(int *)) */
156 
157  map[row] = cpl_calloc(4, sizeof(int));
158  map[row][0] = badmap[row][0];
159  map[row][1] = badmap[row][1];
160  map[row][2] = badmap[row][2];
161  map[row][3] = badmap[row][3];
162 
163  finished = (badmap[row][0] == -1);
164  }
165 
166  return map;
167 }
168 
169 
170 /*----------------------------------------------------------------------------*/
184 /*----------------------------------------------------------------------------*/
185 int **
186 uves_get_badpix(enum uves_chip chip,
187  int binx, int biny, int mark_bad,bool red_ccd_new)
188 {
189  int **map = NULL;
190 
191  if (chip == UVES_CHIP_REDL)
192  {
193  if (binx == 1 && biny == 1)
194  {
195  if(red_ccd_new) {
196 
197  int badmap[][4] = {{1,4,2088,4},
198  {1,63,2282,63},
199  {1,108,1778,108},
200  {1,176,2443,176},
201  {1,196,2021,196},
202  {1,285,1974,285},
203  {1,352,1942,352},
204  {-1,-1,-1,-1}};
205 
206  if (!mark_bad)
207  {
208  badmap[2][0] = -1;
209  badmap[2][1] = -1;
210  badmap[2][2] = -1;
211  badmap[2][3] = -1;
212  }
213 
214 /*
215  int badmap[][4] = {{1,4,2088,4},
216  {1,63,2282,63},
217  {1,176,2443,176},
218  {1,196,2021,196},
219  {1,285,1974,285},
220  {1,352,1942,352},
221  {-1,-1,-1,-1}};
222 */
223  map = dup_map(badmap);
224 
225  } else {
226  int badmap[][4] = {{1,4,2088,4},
227  {1,63,2282,63},
228  {1,108,1778,108},
229  {1,176,2443,176},
230  {1,196,2021,196},
231  {1,285,1974,285},
232  {1,352,1942,352},
233  {-1,-1,-1,-1}};
234  map = dup_map(badmap);
235 
236  }
237 
238  }
239  else if (binx == 1 && biny == 2)
240  {
241 
242 
243  if(red_ccd_new) {
244 
245  int badmap[][4] = {{1,4,1045,4},
246  {1,63,1141,63},
247  {1,108,894,108},
248  {1,176,1222,176},
249  {1,196,1011,196},
250  {1,285,988,285},
251  {1,352,971,352},
252  {-1,-1,-1,-1}};
253  map = dup_map(badmap);
254  } else {
255 
256  int badmap[][4] = {{1,4,1044,4},
257  {1,63,1141,63},
258  {1,108,894,108},
259  {1,176,1222,176},
260  {1,196,1011,196},
261  {1,285,988,285},
262  {1,352,971,352},
263  {-1,-1,-1,-1}};
264 
265  map = dup_map(badmap);
266  }
267  }
268  else if (binx == 2 && biny == 2)
269  {
270  if(red_ccd_new) {
271 
272  int badmap[][4] = {{1,4,1045,4},
273  {1,14,1255,14},
274  {1,33,1141,33},
275  {1,89,1222,89},
276  {1,99,1011,100},
277  {1,144,988,144},
278  {1,177,971,178},
279  {-1,-1,-1,-1}};
280 
281  map = dup_map(badmap);
282  } else {
283  int badmap[][4] = {{1,3,1044,3},
284  {1,33,1141,33},
285  {1,55,894,56},
286  {1,89,1222,90},
287  {1,99,1011,100},
288  {1,144,988,145},
289  {1,177,971,178},
290  {-1,-1,-1,-1}};
291  map = dup_map(badmap);
292  }
293  }
294  else if (binx == 2 && biny == 3)
295  {
296 
297  if(red_ccd_new) {
298 
299  int badmap[][4] = {{1,3,696,3},
300  {1,14,836,15},
301  {1,33,761,33},
302  {1,55,596,56},
303  {1,89,814,90},
304  {1,97,805,90},
305  {1,99,674,100},
306  {1,144,658,144},
307  {1,156,784,156},
308  {1,168,759,168},
309  {1,177,647,178},
310  {1,203,826,203},
311  {1,263,714,263},
312  {-1,-1,-1,-1}};
313  map = dup_map(badmap);
314  } else {
315 
316  int badmap[][4] = {{1,3,696,3},
317  {1,33,761,33},
318  {1,55,592,56},
319  {1,89,814,90},
320  {1,99,674,100},
321  {1,144,658,144},
322  {1,177,647,178},
323  {-1,-1,-1,-1}};
324 
325  map = dup_map(badmap);
326  }
327  }
328  else
329  {
330  assure( false, CPL_ERROR_ILLEGAL_INPUT,
331  "Don't know bad pixel map for %dx%d binning, red, lower chip",
332  binx, biny);
333  }
334  }
335  else if (chip == UVES_CHIP_REDU)
336  {
337  /* Use different bad pixels maps for bias and
338  orderpos recipes !
339  */
340  if (binx == 1 && biny ==1)
341  {
342  if(red_ccd_new) {
343 
344  int badmap[][4] = {
345  {1,845,1268,845},
346  {-1,-1,-1,-1}};
347 
348  if (!mark_bad)
349  {
350  badmap[2][0] = -1;
351  badmap[2][1] = -1;
352  badmap[2][2] = -1;
353  badmap[2][3] = -1;
354  }
355  map = dup_map(badmap);
356  } else {
357 
358  int badmap[][4] = {
359  {1,2030,1268,2033},
360  {1269,2033,4096,2033},
361  {1201, 491, 3271, 492},
362  {-1,-1,-1,-1}};
363 
364  if (!mark_bad)
365  {
366  badmap[2][0] = -1;
367  badmap[2][1] = -1;
368  badmap[2][2] = -1;
369  badmap[2][3] = -1;
370  }
371  map = dup_map(badmap);
372  }
373  }
374  else if (binx == 1 && biny == 2)
375  {
376 
377  if(red_ccd_new) {
378 
379  int badmap[][4] = {{1,1396,845,1396},
380  {-1,-1,-1,-1}};
381 
382  if (!mark_bad)
383  {
384  badmap[2][0] = -1;
385  badmap[2][1] = -1;
386  badmap[2][2] = -1;
387  badmap[2][3] = -1;
388  }
389  map = dup_map(badmap);
390  } else {
391 
392  int badmap[][4] = {{1,2030,634,2033},
393  {635,2033,2048,2033},
394  {600, 491,1635, 492},
395  {-1,-1,-1,-1}};
396 
397  if (!mark_bad)
398  {
399  badmap[2][0] = -1;
400  badmap[2][1] = -1;
401  badmap[2][2] = -1;
402  badmap[2][3] = -1;
403  }
404  map = dup_map(badmap);
405  }
406  }
407  else if (binx == 2 && biny == 2)
408  {
409 
410  if(red_ccd_new) {
411 
412  int badmap[][4] = {{1,422,1526,422},
413  {-1,-1,-1,-1}};
414 
415  if (!mark_bad)
416  {
417  badmap[2][0] = -1;
418  badmap[2][1] = -1;
419  badmap[2][2] = -1;
420  badmap[2][3] = -1;
421  }
422  map = dup_map(badmap);
423  } else {
424 
425  int badmap[][4] = {{1,1013,634,1016},
426  {635,1015,2048,1016},
427  {600, 244,1635, 245},
428  {-1,-1,-1,-1}};
429 
430  if (!mark_bad)
431  {
432  badmap[2][0] = -1;
433  badmap[2][1] = -1;
434  badmap[2][2] = -1;
435  badmap[2][3] = -1;
436  }
437  map = dup_map(badmap);
438  }
439  }
440  else if (binx == 2 && biny == 3)
441  {
442 
443  if(red_ccd_new) {
444  int badmap[][4] = {{1,61,287,62},
445  {1,422,1051,422},
446  {400, 872,1265, 872},
447  {-1,-1,-1,-1}};
448 
449  if (!mark_bad)
450  {
451  badmap[2][0] = -1;
452  badmap[2][1] = -1;
453  badmap[2][2] = -1;
454  badmap[2][3] = -1;
455  }
456  map = dup_map(badmap);
457 
458  } else {
459 
460  int badmap[][4] = {{1,1013,423,1016},
461  {424,1015,1365,1016},
462  {400, 244,1090, 245},
463  {-1,-1,-1,-1}};
464 
465  if (!mark_bad)
466  {
467  badmap[2][0] = -1;
468  badmap[2][1] = -1;
469  badmap[2][2] = -1;
470  badmap[2][3] = -1;
471  }
472  map = dup_map(badmap);
473 
474 
475  }
476  }
477  else
478  {
479  assure( false, CPL_ERROR_ILLEGAL_INPUT,
480  "Don't know bad pixel map for %dx%d binning, red, upper chip",
481  binx, biny);
482  }
483  }
484  else
485  {
486  /* No blue chip bad pixels */
487  int badmap[][4] = {{-1,-1,-1,-1}};
488 
489  map = dup_map(badmap);
490  }
491 
492  cleanup:
493  return map;
494 }
495 
496 
497 
498 /*----------------------------------------------------------------------------*/
513 /*----------------------------------------------------------------------------*/
514 static int
515 uves_correct_badpix(cpl_image *master_bias, uves_propertylist *header, int **badmap,
516  bool mark_bad)
517 {
518  int ncorrect = 0; /* Result */
519  int xstart, ystart, xend, yend;
520  int row;
521  bool finished = false;
522  int nx, ny;
523  cpl_mask *image_bad = NULL;
524  cpl_binary*image_bpm = NULL;
525  cpl_type type=0;
526 
527  type=cpl_image_get_type(master_bias);
528  assure( (type == CPL_TYPE_DOUBLE) || (type == CPL_TYPE_FLOAT),
529  CPL_ERROR_UNSUPPORTED_MODE,
530  "Image type must be float or double. It is %s",
531  uves_tostring_cpl_type(cpl_image_get_type(master_bias)));
532 
533  image_bad = cpl_image_get_bpm(master_bias);
534  image_bpm = cpl_mask_get_data(image_bad);
535 
536  nx = cpl_image_get_size_x(master_bias);
537  ny = cpl_image_get_size_y(master_bias);
538 
539  row = 0;
540  while (!finished)
541  {
542  xstart = badmap[row][0];
543  ystart = badmap[row][1];
544  xend = badmap[row][2];
545  yend = badmap[row][3];
546 
547  if (xstart > 0)
548  {
549  int ylow, yhigh;
550  int x, y;
551 
552  assure( 1 <= xstart && xstart <= nx &&
553  1 <= xend && xend <= nx &&
554  1 <= ystart && ystart <= ny &&
555  1 <= yend && yend <= ny, CPL_ERROR_ILLEGAL_INPUT,
556  "Illegal window (%d, %d) - (%d, %d). Image size = %dx%d",
557  xstart, ystart, xend, yend, nx, ny);
558 
559  if ( ystart < 3 )
560  {
561  assure( yend + 2 <= ny, CPL_ERROR_ILLEGAL_INPUT,
562  "Too large range in y: %d - %d", ystart, yend);
563 
564  ylow = yend + 1;
565  yhigh = yend + 2;
566  }
567  else if (yend > ny - 3 )
568  {
569  assure( ystart - 2 >= 1, CPL_ERROR_ILLEGAL_INPUT,
570  "Too large range in y: %d - %d", ystart, yend);
571 
572  ylow = ystart - 2;
573  yhigh = ystart - 1;
574  }
575  else
576  {
577  ylow = ystart - 2;
578  yhigh = yend + 2;
579  }
580 
581  uves_msg("Correcting window (%d, %d)-(%d, %d)", xstart, ystart, xend, yend);
582 
583  if(type == CPL_TYPE_DOUBLE) {
584 
585  for (x = xstart; x <= xend; x++) {
586  for (y = ystart; y <= yend; y++) {
587  int pis_rejected;
588 
589  if (mark_bad)
590  {
591  /* This is extremely slow with CPL2:
592  cpl_image_reject(master_bias, x, y);
593  */
594  image_bpm[(x-1) + (y-1)*nx] = CPL_BINARY_1;
595  }
596  else
597  /* interpolate */
598  {
599  double *master_bias_data;
600 
601  double i1 = cpl_image_get(master_bias, x, ylow , &pis_rejected);
602  double i2 = cpl_image_get(master_bias, x, yhigh, &pis_rejected);
603 
604  /* Write average */
605 
606  /* This will make the bpm invalid:
607  cpl_image_set(master_bias, x, y, (i1+i2)/2);
608  */
609  master_bias_data = cpl_image_get_data_double(master_bias);
610  master_bias_data[(x-1) + (y-1)*nx] = (i1+i2)/2;
611  }
612  ncorrect += 1;
613  }
614 
615  }
616 
617  } else {
618 
619  for (x = xstart; x <= xend; x++) {
620  for (y = ystart; y <= yend; y++) {
621  int pis_rejected;
622  if (mark_bad)
623  {
624  /* This is extremely slow with CPL2:
625  cpl_image_reject(master_bias, x, y);
626  */
627  image_bpm[(x-1) + (y-1)*nx] = CPL_BINARY_1;
628  }
629  else
630  /* interpolate */
631  {
632  float *master_bias_data;
633 
634  float i1 = cpl_image_get(master_bias, x, ylow , &pis_rejected);
635  float i2 = cpl_image_get(master_bias, x, yhigh, &pis_rejected);
636 
637  /* Write average */
638 
639  /* This will make the bpm invalid:
640  cpl_image_set(master_bias, x, y, (i1+i2)/2);
641  */
642  master_bias_data = cpl_image_get_data_float(master_bias);
643  master_bias_data[(x-1) + (y-1)*nx] = (i1+i2)/2;
644  }
645  ncorrect += 1;
646  }
647 
648  }
649 
650  }
651 
652  }
653  else
654  {
655  finished = true;
656  }
657  row++;
658  }
659 
660  /* Update product header */
661  if (ncorrect > 0)
662  {
663  check( uves_pfits_set_badpixcorr(header, "true"),
664  "Error updating product header");
665  }
666 
667  cleanup:
668  return ncorrect;
669 }
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