The calibration step uses an algorithm to calculate replacement values for defective pixels. The available algorithms are specified in the configuration file ldrs.cfg. In this file, a special procedure group is defined in which each entry gives the name of an existing IDL procedure. The code snippet in source 1 shows a sample part of the configuration file:
PGROUP3.TAG = "BPMC" PGROUP3.LABEL = "Bad Pixel Compensation" PGROUP3.PROC1.TAG = "NONE" PGROUP3.PROC1.LABEL = "None" PGROUP3.PROC1.PRO = "LDRS_BPM_NONE" PGROUP3.PROC2.TAG = "STD" PGROUP3.PROC2.LABEL = "Nearest Pairs Interpolation" PGROUP3.PROC2.PRO = "LDRS_BPM_PAIR_INTERPOLATION" |
The tag BPMC is used in the framework and must not be changed. The label Bad Pixel Compensation is used in the graphical user interface and can be changed to a different string. The tags for the available procedures (NONE, STD, ...) should not be modified or the existing parameter files will be jeopardized. The standard distribution of the LN DRS contains two methods:
The template in source 2 can be used as a starting point to implement a new defective pixel interpolation method.
; INOUT data : FLTARR(nx,ny) ; IN bpm : PTR_NEW(FLTARR(nx,ny)) PRO <MY_PRO_NAME>, data, bpm ; check the dimensions of the data and the bpm ds = SIZE(data, /DIMENSIONS) bs = SIZE(*bpm, /DIMENSIONS) IF (ds[0] NE bs[0]) OR (ds[1] NE bs[1]) THEN BEGIN ; the dimensions differ => not compatible PRINT, '<MY_PRO_NAME>: dimensions of data and BPM differ!' RETURN ENDIF nx = ds[0] ny = ds[1] ; bi are the 1-dimensional indices of the bad pixels bi = WHERE(*bpm EQ 0.0, count) ... END |
In the configuration file, the following excerpt must be appended immediately after the last method concerning the defective pixel interpolation (see source 1).
PGROUP3.PROC<N>.TAG = "<MY_TAG>" PGROUP3.PROC<N>.LABEL = "<MY_LABEL>" PGROUP3.PROC<N>.PRO = "<MY_PRO_NAME>" |
The placeholders <MY_PRO_NAME>, <MY_TAG>, <MY_LABEL>, and <N> must be replaced with the correct values.
In the LN DRS distribution, two methods to calculate replacement values for defective pixels exist:
This method uses up to two pairs of good pixels to calculate a replacement value for a defective pixel. The pixels of a pair are on either side of the defective pixel. The algorithm is described in the following code snippets.
; replacement pixels are positioned horizontal, vertical, or ; diagonal relative to the bad pixel: ; 0 | 1 | 2 ; 3 | X | 4 ; 5 | 6 | 7 ; the 2-dimensional indices of a bad pixel are (bx,by) rpf = INTARR(8) ; replacement pixel flag rpw = FLTARR(8) ; replacement pixel weight/dist rpv = FLTARR(8) ; replacement pixel value rpdx = [-1,0,1,-1,1,-1,0,1] rpdy = [1,1,1,0,0,-1,-1,-1] ; search the replacement pixels FOR j=0,7 DO BEGIN rx = bx + rpdx[j] ry = by + rpdy[j] rpw[j] = 1.0 WHILE rpf[j] EQ 0 DO BEGIN IF (rx LT 0) OR (rx GE nx) THEN BREAK IF (ry LT 0) OR (ry GE ny) THEN BREAK IF (*bpm)[rx,ry] EQ 0.0 THEN BEGIN ; the replacement pixel is also a bad pixel ; => move to the next replacement pixel rx += rpdx[j] ry += rpdy[j] rpw[j] += 1.0 CONTINUE ENDIF ; we found a useful replacement pixel rpf[j] = 1 rpv[j] = data[rx,ry] ENDWHILE ENDFOR |
; recalculate the replacement values and weights for pairs FOR j=0,3 DO BEGIN k = 7 - j IF rpf[j] EQ 1 THEN BEGIN IF rpf[k] EQ 1 THEN BEGIN ; we have a pair, recalculate the value and weight rpv[j] = (rpv[j]*rpw[k] + rpv[k]*rpw[j])/(rpw[j] + rpw[k]) rpw[j] = rpw[j]^2 + rpw[k]^2 ; remove the weight at k rpf[k] = 0 rpw[k] = !VALUES.F_NAN rpv[k] = 0.0 ENDIF ELSE BEGIN ; only a value at j exists, recalculate the weight rpw[j] = 2*rpw[j]^2 + 1 ; a little bit worse than a pair! ; remove the weight at k rpw[k] = !VALUES.F_NAN ENDELSE ENDIF ELSE BEGIN IF rpf[k] EQ 1 THEN BEGIN ; only a value at k exists, recalculate the weight rpw[k] = 2*rpw[k]^2 + 1 ; a little bit worse than a pair! ; remove the weight at j rpw[j] = !VALUES.F_NAN ENDIF ELSE BEGIN ; no value at j or k, remove both weights rpw[j] = !VALUES.F_NAN rpw[k] = !VALUES.F_NAN ENDELSE ENDELSE ENDFOR |
; find the values with the smallest weights and use up to 2 values vl = SORT(rpw) ; we have to distinguish between three different cases: ; 1. no replacement value exists (extremely rare) ; 2. only one replacement value exists (very rare) ; 3. two or more replacement values exist (normal case) IF rpf[vl[0]] NE !VALUES.F_NAN THEN BEGIN v1 = rpv[vl[0]] w1 = rpw[vl[0]] IF rpf[vl[1]] NE !VALUES.F_NAN THEN BEGIN v2 = rpv[vl[1]] w2 = rpw[vl[1]] data[bx,by] = (v1*w2 + v2*w1)/(w1 + w2) ENDIF ELSE BEGIN data[bx,by] = v1 ENDELSE ENDIF |