;+
; NAME:
;	V4XCART2SPH
; PURPOSE:
;	Convert Cartesian to associated Spherical coordinates
;	(normally called by V4XFORM based on the v4xforms structure)
; CALLING SEQUENCE:
;	out = V4XCART2SPH(in,/verbose,index=ix,outdex=ox,ocoord=ocoord)
; INPUTS:
;	in - a V4 structure containing the Cartesian co-ordinates to 
;	     transform to spherical
; RETURNS:
;	The transformed vector (or array)
; KEYWORDS:
;	VERBOSE - Be chatty
;	INDEX   - A 4-array that re-orders the input vector
;	OUTDEX  - A 4-array that re-orders the output vector
;	OCOORD  - The coordinate system name for the output coordinates 
; 
; METHOD:
;	The "standard interpretation" is as follows:
;	I0 = time		O0 = time		
;	I1 = X			O1 = longitude		
;	I2 = Y			O2 = latitude		
;	I3 = Z			O3 = radius		
; The pole points along the Z axis; the central meridian is through the X axis;
; and the Y axis forms a right-handed co-ordinate system.
;
; AUTHOR:
;	Craig DeForest
; HISTORY: 
;	Initial implementation, 7-Oct-1997
;
; NOTES: 
;	CV_COORD would work as the engine.  But the real utility
;	here isn't in the transformation -- it's in the bookkeeping of
;	units and stuff.
;-
function V4XCART2SPH,in,verbose=v,index=ix,outdex=ox,ocoords=ocoords

;;;
;;; Check out input keywords for existence...
;;;
if not isvalid(ix) then ix=[0,1,2,3]
if not isvalid(ox) then ox=[0,1,2,3]
v = keyword_set(v)

iu = ix+5
ou = ox+5

;;;
;;; Convert to uniform distances, in a spare copy of the input...
i2 = in
out = i2

z2 = zunits(i2.(iu(2)),i2.(iu(1)))
z3 = zunits(i2.(iu(3)),i2.(iu(1)))

if total((z2*z3) eq 0) gt 0 then message,"V4xcart2sph: Non-compatible units in the cartesian frame!"
i2.(ix(2)) = i2.(ix(2))/z2
i2.(ix(3)) = i2.(ix(3))/z3

i2.(iu(2))=i2.(iu(1))
i2.(iu(3))=i2.(iu(1))

;;;
;;; Copy the time co-ordinate and, if desired, the coords keyword
out.(ox(0))   	= in.(ix(0))
out.(ou(0))	= in.(iu(0))
if isvalid(ocoords) then out.coords=ocoords

;;;
;;; Do the actual transformation...
r1 = sqrt(i2.(ix(1))*i2.(ix(1)) + i2.(ix(2))*i2.(ix(2)))

out.(ox(1)) = atan(i2.(ix(2)) , i2.(ix(1))) * !radeg
out.(ox(2)) = atan(i2.(ix(3)) , r1)         * !radeg
out.(ox(3)) = sqrt(r1*r1 + i2.(ix(3))*i2.(ix(3)))

;;;
;;; Put the radial units in place...
out.(ou(1)) = "degrees"
out.(ou(2)) = "degrees"
out.(ou(3)) = i2.(iu(3))

return,out

end
