Viewing contents of file '../idllib/contrib/buie/getannul.pro'
;+
; NAME:
; getannul
; PURPOSE: (one line)
; Extract an annulus from a 2-D array.
; DESCRIPTION:
;
; CATEGORY:
; CCD data processing
; CALLING SEQUENCE:
; Getannul, image, xcen, ycen, inradius, outradius, data
;
; INPUTS:
; image : CCD image array.
; xcen,ycen : Center of annulus.
; inradius : Radius of inner circle.
; outradius : Radius of outer circle.
;
; OPTIONAL INPUT PARAMETERS:
;
; KEYWORD PARAMETERS:
; OUTPUTS:
; data : Array of data from the image array.
; idx : Optional output of 1D indices (in image) of data.
;
; COMMON BLOCKS:
;
; SIDE EFFECTS:
;
; RESTRICTIONS:
;
; PROCEDURE:
;
; MODIFICATION HISTORY:
; Written by Doug Loucks, Lowell Observatory, April, 1993.
; Reference: getannul.c by Marc Buie.
; This version is completely different than the previous version and
; somewhat faster.
; 5/12/93, DWL, Fixed a bug involving fringe pixels. In certain cases,
; the determination of the row indices led to a bad array
; subscript range.
; 1/5/94, DWL, Added optional output parameter idx.
; 95/06/12, MWB, Fixed bug, base needed to be LONG for large sky apertures
;-
PRO Getannul, image, xcen, ycen, inradius, outradius, data, idx
data = 0
; Get input image array size.
image_size = SIZE( image )
xsize = image_size[ 1 ]
ysize = image_size[ 2 ]
; Compute the exact area of the annulus and reserve enough space for the pixel
; index arrays.
r1 = inradius
r2 = outradius + 1
npts = LONG( !PI * ( r2*r2 - r1*r1 ) )
x = INTARR( npts )
y = INTARR( npts )
base = 0L
IF ( 0 LE inradius ) AND ( inradius LT outradius ) THEN BEGIN
; Compute the y-range limits.
r2 = outradius
r1 = inradius
r2sq = r2 * r2
r1sq = r1 * r1
yp = ycen - r2
outy0 = FIX( yp )
IF outy0 LT yp THEN outy0=outy0+1
yp = ycen + r2
outy3 = FIX( yp + 1 )
IF outy3 GT yp THEN outy3=outy3 - 1
FOR yp = outy0, outy3 DO BEGIN
; Step through each row and compute the x-range (or ranges).
dy = yp - ycen
dysq = dy * dy
dx2 = SQRT( r2sq - dysq )
xp = xcen - dx2
outx0 = FIX( xp )
IF outx0 LT xp THEN outx0=outx0+1
xp = xcen + dx2
outx3 = FIX( xp + 1 )
IF outx3 GT xp THEN outx3=outx3-1
IF dysq GT r1sq THEN BEGIN
; No intersection with inner radius.
n = outx3 - outx0 + 1
IF n EQ 0 THEN n = 1
x[ base : base+n-1 ] = outx0 + INDGEN( n )
y[ base : base+n-1 ] = REPLICATE( yp, n )
base = base + n
ENDIF ELSE BEGIN
; Passing through the inner circle. Select two parts.
dx1 = SQRT( r1sq - dysq )
xp = xcen - dx1
inx0 = FIX( xp + 1 )
IF inx0 GT xp THEN inx0 = inx0 - 1
xp = xcen + dx1
inx3 = FIX( xp )
IF inx3 LT xp THEN inx3=inx3+1
n1 = inx0 - outx0 + 1
n2 = outx3 - inx3 + 1
IF n1 EQ 0 THEN n1 = 1
IF n2 EQ 0 THEN n2 = 1
x[ base : base+n1-1 ] = outx0 + INDGEN( n1 )
y[ base : base+n1-1 ] = REPLICATE( yp, n1 )
base = base + n1
x[ base : base+n2-1 ] = inx3 + INDGEN( n2 )
y[ base : base+n2-1 ] = REPLICATE( yp, n2 )
base = base + n2
ENDELSE
ENDFOR
; Final verification and selection.
t = WHERE( x[0:base-1] LT 0 OR x[0:base-1] GE xsize OR $
y[0:base-1] LT 0 OR y[0:base-1] GE ysize, count )
IF count GT 0 THEN BEGIN
t = WHERE( x[0:base-1] GE 0 AND x[0:base-1] LT xsize AND $
y[0:base-1] GE 0 AND y[0:base-1] LT ysize, count )
data = image[ x[t], y[t] ]
IF N_PARAMS() EQ 7 THEN idx = x[t] + xsize * y[t]
ENDIF ELSE BEGIN
data = image[ x[0:base-1], y[0:base-1] ]
IF N_PARAMS() EQ 7 THEN idx = x[0:base-1] + xsize * y[0:base-1]
ENDELSE
ENDIF
END