FUNCTION HSI_VIS_SORT, visin, CONJUGATE=conjugate, TOL=tol, IGNOREMAG=ignoremag
;
; Given a standard visibility structure with NVIS elements, HSI_VIS_SORT returns an N-ELEMENT 'uvindex' vector which
; assigns a 'uvindex' value to each visibility.  This can be used for forming subsequent combining of like visibilities.
; All visibility points with the same uvindex value correspond to the same location in the uv plane.
; Visibiltiy points with different uvindex values correspond to different locations in the uv plane.
; Input visibility structure, visin, is not changed.
;
; If /CONJUGATE switch is set, then conjugate uv points are considered equivalent.
; TOL = the approximate fractional tolerance for considering uv points to be equivalent
; If /IGNOREMAG is set, then (u^2+v^2) is ignored and sorting is done solely on the basis of the uv plane polar angle.
;
; 31-Jul-20 	Initial version (ghurford@ssl.berkeley.edu)
;  1-Sep-05 gh	Added IGNOREMAG switch
;
DEFAULT, tol, 0.01
angtol 	= 180./!PI*tol				; corresponding angular tolerance (degrees)
;
nvis 	= N_ELEMENTS(visin)
uvindex = INTARR(nvis)
uv 		= SQRT(visin.u^2 + visin.v^2)			; save uv radius in case comparison uses uv and pa
IF KEYWORD_SET(ignoremag) THEN uv = FLTARR(nvis)+1.		; If /IGNOREMAG, then set all uv to be the same
i 		= hsi_vis_select(visin, PAOUT=pa)				; calculates pa in range [0, 360.]
IF KEYWORD_SET(conjugate) THEN BEGIN
	neg = WHERE(pa GE 180., nneg)
	IF nneg GT 0 THEN pa[neg] = pa[neg] - 180.				; Optionally make conjugate points equivalent
ENDIF
;
; Prepare to sort into groups.
result 	= INTARR(nvis)-1			; will store group numbers for each visibility.  Preset to -1 ==> unassigned
uvgroup = FLTARR(nvis)				; will store reference uv and pa for each group
pagroup = FLTARR(nvis)
;
; Assign first visibility to first group.
result[0] 	= 0
uvgroup[0] 	= uv[0]
pagroup[0] 	= pa[0]
igroup 		= 1					; Next group to be assigned
;
; Begin loop over remaining visibilities
FOR n=1, nvis-1 DO BEGIN
	FOR i = 0, igroup-1 DO BEGIN
		IF ABS(ALOG(uv[n]/uvgroup[i])) LT tol AND ABS(pa[n]-pagroup[i]) LT angtol THEN BEGIN 	; true if match
			result[n] = i
			BREAK					; Exit inner loop if match found.
		ENDIF
	ENDFOR
	IF result[n] LT 0 THEN BEGIN		; No match - create a new group
		result[n] 		= igroup
		uvgroup[igroup] = uv[n]
		pagroup[igroup] = pa[n]
		igroup 			= igroup + 1
	ENDIF
ENDFOR
RETURN, result							; Note that MAX(result)+1 = number of unique groups.
END