Viewing contents of file '../idllib/contrib/buie/backsub.pro'
;+
; NAME:
; backsub
; PURPOSE:
; Background subtraction from an image.
; DESCRIPTION:
; The background is determined from a robust fit of a line to each row
; or column in the image depending on the keywords. If neither keyword
; is set, then the robust mean is used. These lines or means are then
; subtracted from the input image.
;
; For each row (or column) that is fit, the 6 most extreme points (from
; the mean) are removed from the first pass fit. See the docs for
; GOODPOLY and the NEX keyword.
; CATEGORY:
; CCD data processing
; CALLING SEQUENCE:
; backsub,image, [ROW,COLUMN]
; INPUTS:
; image - Image (2-d or 3-d) to subtract background from, image is
; modified in place.
; OPTIONAL INPUT PARAMETERS:
; KEYWORD INPUT PARAMETERS:
; ROW - Flag, if set, program assumes that image is flat along a row.
; COLUMN - Flag, if set, program assumes that image is flat along a column.
;
; Default is to assume that the image is flat along rows and columns.
;
; EXCLUDE- Scalar item or vector list of rows to exclude from background
; fitting process.
; MAX_VALUE - The maximum value to be fitted. If this keyword is provided,
; data values greater than MAX_VALUE are treated as missing
; and are not used in the fit for the background.
; MIN_VALUE - The minimum value to be fitted. If this keyword is provided,
; data values greater than MIN_VALUE are treated as missing
; and are not used in the fit for the background.
; ORDER - Order of polynominal to fit to background (ROW and COLUMN only),
; the default is 0 (mean of direction), 1 is linear, etc.
; OUTPUTS:
; image - Background subtracted image.
; KEYWORD OUTPUT PARAMETERS:
; COMMON BLOCKS:
; SIDE EFFECTS:
; RESTRICTIONS:
; Only one of ROW and COLUMN can be set.
;
; PROCEDURE:
; MODIFICATION HISTORY:
; 93/11/12, Written by Marc W. Buie, Lowell Observatory
; 95/03/23, MWB, added ORDER keyword.
; 98/06/08, MWB, Added MIN/MAX_VALUE keywords.
;-
pro backsub,image, ROW=row_wise, COLUMN=col_wise, ORDER=order, $
EXCLUDE=exclude, MIN_VALUE=min_value, MAX_VALUE=max_value, $
MASK=mask
nex = 6
ret = string("12b) ;"
if badpar(image,[1,2,3,4,5],[2,3],CALLER='BACKSUB (array): ', $
rank=rank,dimen=dimen) then return
if badpar(order,[0,1,2,3],0,CALLER='BACKSUB (order): ',DEFAULT=0) then return
if badpar(min_value,[0,1,2,3,4,5],0,CALLER='BACKSUB (MIN_VALUE) ') then return
if badpar(max_value,[0,1,2,3,4,5],0,CALLER='BACKSUB (MAX_VALUE) ') then return
if badpar(mask,[0,1,2,3],2,CALLER='BACKSUB (MASK) ',DEFAULT=-1) then return
if keyword_set(row_wise) and keyword_set(col_wise) then begin
print,'BACKSUB: Error! Only one of ROW and COLUMN can be set.'
return
endif
ncols = dimen[0]
nrows = dimen[1]
if rank eq 3 then nframes=dimen[2] else nframes=1
icol = indgen(ncols)
irow = indgen(nrows)
; Create an empty mask if none provided.
if mask[0] eq -1 then begin
mask=bytarr(ncols,nrows)
inmask=0
endif else begin
inmask=1
endelse
; This takes care of fitting a line to each row and then subtracting.
if keyword_set(row_wise) then begin
include = indgen(ncols)
if keyword_set(exclude) then begin
intrsect,include,exclude,use,nfound,/nnot
if nfound gt 0 and nfound le ncols then include=use
endif
if rank eq 2 then begin
for i=0L,nrows-1 do begin
l_row = image[*,i]
l_bad = mask[*,i]
if order eq 0 then begin
robomean,l_row[include],3,.5,back,bad=l_bad[include]
image[*,i] = l_row - back
endif else begin
coeff=goodpoly(icol[include],l_row[include],order,3,f_row, $
EX=nex,MIN_VALUE=min_value,MAX_VALUE=max_value, $
bad=l_bad[include])
image[*,i] = l_row - poly(icol,coeff)
endelse
endfor
endif else begin
for k=0,nframes-1 do begin
if k mod 10 eq 0 then print,ret,nframes-k,format="($,a,i4)"
for i=0,nrows-1 do begin
l_row = image[*,i,k]
l_bad = mask[*,i]
if order eq 0 then begin
robomean,l_row[include],3,.5,back,bad=l_bad[include]
image[*,i,k] = l_row - back
endif else begin
coeff=goodpoly(icol[include],l_row[include],order,3,f_row, $
EX=nex,MIN_VALUE=min_value,MAX_VALUE=max_value, $
bad=l_bad[include])
image[*,i,k] = l_row - poly(icol,coeff)
endelse
endfor
endfor
print,' done'
endelse
endif
; This takes care of fitting a line to each column and then subtracting.
if keyword_set(col_wise) then begin
include = indgen(nrows)
if keyword_set(exclude) then begin
intrsect,include,exclude,use,nfound,/nnot
if nfound gt 0 and nfound le nrows then include=use
endif
if rank eq 2 then begin
for i=0,ncols-1 do begin
l_col = image[i,*]
l_bad = mask[i,*]
if order eq 0 then begin
robomean,l_col[include],3,.5,back,bad=l_bad[include]
image[i,*] = l_col - back
endif else begin
coeff=goodpoly(irow[include],l_col[include],order,3,f_col, $
EX=nex,MIN_VALUE=min_value,MAX_VALUE=max_value, $
bad=l_bad[include])
image[i,*] = l_col - poly(irow,coeff)
endelse
endfor
endif else begin
for k=0,nframes-1 do begin
if k mod 10 eq 0 then print,ret,nframes-k,format="($,a,i4)"
for i=0,ncols-1 do begin
l_col = image[i,*,k]
l_bad = mask[i,*]
if order eq 0 then begin
robomean,l_col,3,.5,back,bad=l_bad[include]
image[i,*,k] = l_col - back
endif else begin
coeff=goodpoly(irow[include],l_col[include],order,3,f_col, $
EX=nex,MIN_VALUE=min_value,MAX_VALUE=max_value, $
bad=l_bad[include])
image[i,*,k] = l_col - f_col
endelse
endfor
print,' done'
endfor
endelse
endif
; This takes care of finding the mean of each image and then subtracting.
if not keyword_set(col_wise) and not keyword_set(row_wise) then begin
if rank eq 2 then begin
if inmask then $
robomean,image,3,.5,back,bad=mask[*] $
else $
robomean,image,3,.5,back
image = image - back
endif else begin
for k=0,nframes-1 do begin
if k mod 10 eq 0 then print,nframes-k,format='($,i4)'
if inmask then $
robomean,image[*,*,k],3,.5,back,bad=mask[*] $
else $
robomean,image[*,*,k],3,.5,back
image[*,*,k] = limage[*,*,k] - back
endfor
print,' done'
endelse
endif
end