Viewing contents of file '../idllib/astron/contrib/varosi/vlib/allpro/centroid.pro'
;+
; NAME:
; centroid
; PURPOSE:
; Compute centroid coordinates of a stellar image as in DAOPHOT FIND.
; CALLING SEQUENCE:
; centroid, image, XCEN, YCEN, XY_PEAK=[x,y], [FWHM=fwhm], [/PEAK_LOC]
; INPUTS:
; image - Two dimensional image array
; KEYWORDS:
; XY_PEAK = [x,y] vector of 2 integers giving approximate stellar center.
; Pixel at maximum in subimage will then be used to start.
; If not specified then max pixel of whole image is used.
; FWHM - floating scalar or 2 elements (for x & y), default FWHM = 3 pixels.
; Centroid computed in box of half width = 1.5*sigma = 0.637*FWHM
; /PEAK_LOCATE - causes the peak (maximum pixel) of image to be used
; as approximate stellar center (overrides XY_PEAK).
; OUTPUTS:
; XCEN - floating scalar, giving the computed X centroid position
; YCEN - floating scalar, giving the computed Y centroid position
; Values for XCEN and YCEN will not be computed if the
; centroid falls outside of the box, or if the computed derivatives
; are non-decreasing. If the centroid cannot be computed, then a
; message is displayed and XCEN and YCEN are set to -1.
; RESTRICTIONS:
; Program does not check if the input X and Y position falls within image.
; SYSTEM VARIABLES:
; !DEBUG - If set, the subarray used to compute the centroid is printed
; EXTERNAL CALLS:
; pro Locate_Peak, image, xmax, ymax
; PROCEDURE:
; Maximum pixel within distance from input pixel X, Y determined
; by FHWM is found and used as the center of a square, within
; which the centroid is computed as the value (XCEN,YCEN) at which
; the derivatives of the partial sums of the input image over (y,x),
; with respect to (x,y), equal zero.
; MODIFICATION HISTORY:
; Written 2/25/86, by J. K. Hill, S.A.S.C., following
; algorithm used by P. Stetson in DAOPHOT.
; Added vector subscripting, W. Landsman 5/21/87
; Mod: F.Varosi 1991-92, changed name from CNTRD to CENTROID, optimized,
; changed SUM calls to SUM_ARRAY, added keyword XY_PEAK=[x,y],
; option /PEAK_LOC to locate and use maximum,
; add 0.5 to centroid x & y values so it is in center of pixel.
; Edit: FV 1999, added more comments explaining keywords in header info.
;-
pro centroid, image, Xcen,Ycen, XY_PEAK=xy_peak, FWHM=fwhm, $
PEAK_LOCATE=peak_Loc, PLOT_PDERIV=plotd
IF N_PARAMS() LT 1 THEN BEGIN
PRINT,STRING(7B),$
"CALL: centroid ,image, xcen, ycen, XY_PEAK=[x,y], [FWHM=fwhm, /PEAK_LOCATE]"
RETURN
ENDIF
if N_elements( fwhm ) LE 0 then fwhm = [3,3]
if N_elements( fwhm ) eq 1 then fwhm = replicate( fwhm(0), 2 )
NHALF_xy = fix( 0.637 * fwhm + 0.5 ) > 2
NBOX_xy = 2*NHALF_xy+1 ;Width of box to be used to compute centroid
sim = size( image )
L = sim-1
if keyword_set( peak_Loc ) then begin
Locate_peak, image, xmax, ymax
xy_peak = [xmax,ymax]
endif else if N_elements( xy_peak ) EQ 2 then begin
X = xy_peak(0) ;Locate maximum pixel in subimage
Y = xy_peak(1) ; around the given (X,Y) pixel.
NHALFBIG = NHALF_xy +3 ;Extend box 3 pixels on each side
rX = ( [ X-NHALFBIG(0) , X+NHALFBIG(0) ] > 0 ) < L(1)
rY = ( [ Y-NHALFBIG(1) , Y+NHALFBIG(1) ] > 0 ) < L(2)
Locate_Peak, image( rX(0):rX(1), rY(0):rY(1) ), xmax, ymax
XMAX = rX(0) + xmax ;X coordinate in original image array
YMAX = rY(0) + ymax ;Y coordinate in original image array
endif else begin
Locate_Peak, image, xmax, ymax
xy_peak = [xmax,ymax]
if !DEBUG then print," using (x,y) peak: ",xy_peak
endelse
;extract subimage centered on maximum pixel
rx = [ XMAX-NHALF_xy(0), XMAX+NHALF_xy(0) ]
ry = [ YMAX-NHALF_xy(1), YMAX+NHALF_xy(1) ]
if (min( [rx,ry] ) LT 0) OR max( ([rx(1),ry(1)] GT L(1:2)) ) then begin
message,"not enough pixels around maximum to determine centroid",/INFO
xcen=xmax & ycen=ymax
return
endif else STARBOX = image( rx(0):rx(1), ry(0):ry(1) )
if !DEBUG then begin
PRINT,' Maximum pixel value is ',image(xmax,ymax),' at',xmax,ymax
PRINT,'Subarray used to compute centroid:'
PRINT,STARBOX
endif
; Find X centroid
NBOX = NBOX_xy(0)
NHALF = NHALF_xy(0)
DD = findgen( NBOX-1 ) + 0.5 - NHALF ; Weighting factor W unity in center,
W = 1 - (ABS(DD)-0.5)/(2*NHALF-1) ; 0.5 at end, and linear in between
wdfactor = total( W*DD^2 )/total( W )
PDERIV = SHIFT( STARBOX,-1,0 ) - STARBOX ;get partial derivatives resp. to X
NHALF = NHALF_xy(1)
IR = (NHALF-1) > 1
PDERIV = PDERIV( 0:NBOX-2, NHALF-IR:NHALF+IR ) ;eliminate edges of the array
PDERIV = W * total( PDERIV, 2 ) ;Sum X derivatives over Y direction
SUMD = total( PDERIV )
SUMXD = total( DD * PDERIV )
IF (SUMXD GE 0) THEN BEGIN
message,' X derivative not decreasing, could not find centroid',/INFO
XCEN=-1
ENDIF else begin
DX = wdfactor * (SUMD / SUMXD)
IF (ABS(DX) GT NHALF_xy(0)) THEN $
message,'computed X centroid outside box',/INFO
XCEN = XMAX - DX + 0.5 ;X centroid in original array
if keyword_set( plotd ) then begin
get_window,0,/SHOW
plot, PDERIV, PS=-4
oplot, [DX,DX],[-1,1]*1e33
endif
endelse
; Find Y Centroid
NBOX = NBOX_xy(1)
NHALF = NHALF_xy(1)
DD = findgen( NBOX-1 ) + 0.5 - NHALF ; Weighting factor W unity in center,
W = 1 - (ABS(DD)-0.5)/(2*NHALF-1) ; 0.5 at end, and linear in between
wdfactor = total( W*DD^2 )/total( W )
PDERIV = SHIFT( STARBOX,0,-1 ) - STARBOX
NHALF = NHALF_xy(0)
IR = (NHALF-1) > 1
PDERIV = PDERIV( NHALF-IR:NHALF+IR, 0:NBOX-2 )
PDERIV = W * total( PDERIV, 1 ) ;Sum Y derivatives over X direction
SUMD = total( PDERIV )
SUMXD = total( DD * PDERIV )
IF (SUMXD GE 0) THEN BEGIN
message,' Y derivative not decreasing, could not find centroid',/INFO
YCEN=-1
ENDIF else begin
DY = wdfactor * (SUMD / SUMXD)
IF (ABS(DY) GT NHALF_xy(1)) THEN $
message,'computed Y centroid outside box',/INFO
YCEN = YMAX - DY + 0.5
if keyword_set( plotd ) then begin
get_window,1,/SHOW
plot, PDERIV, PS=-4
oplot, [DY,DY],[-1,1]*1e33
print,dy
endif
endelse
IF !DEBUG THEN PRINT,' X Y POS. OF CENTROID = ',XCEN,YCEN
if !DEBUG GT 1 then stop
END