Viewing contents of file '../idllib/contrib/buie/decstr.pro'
;+
; NAME:
;    decstr
; PURPOSE: (one line)
;    Convert declination in radians to an ASCII string.
; DESCRIPTION:
;
; CATEGORY:
;    Astronomy
; CALLING SEQUENCE:
;    decstr, declination, places, str
; INPUTS:
;    declination - Declination, in radians, to be converted to a string.  May
;                  a vector, in which case the output will be a vector.
;    places      - Resolution of output string.
;             = -7     nearest hour.                    +DD
;             = -6     nearest 30 minutes.              +DD:(00,30)
;             = -5     nearest 15 minutes.              +DD:(00,15,30,45)
;             = -4     nearest 10 minutes.              +DD:M0
;             = -3     nearest 5 minutes.               +DD:M(0,5)
;             = -2     nearest minute.                  +DD:MM
;             = -1     nearest ten seconds.             +DD:MM:S0
;             =  0     nearest second.                  +DD:MM:SS
;             =  1     nearest tenth of a second.       +DD:MM:SS.s
;             =  2     nearest hundredth of a second.   +DD:MM:SS.ss
;             =  3     nearest thousandth of a second.  +DD:MM:SS.sss
; OPTIONAL INPUT PARAMETERS:
;
; KEYWORD PARAMETERS:
;
; OUTPUTS:
;    str         - Output string for the converted declination.
; COMMON BLOCKS:
;
; SIDE EFFECTS:
;
; RESTRICTIONS:
;
; PROCEDURE:
;    Declination (in the range [-pi/2,pi/2]) is converted to a string.
;    The sign of the declination is always provided and there are no imbedded
;    blanks.  PLACES indicates the reported precision of the string.
;    Calls external routine radtodms.
; MODIFICATION HISTORY:
;  Copyright (C) 1987,91, by Marc W. Buie
;  Version dated 91/8/5
;  Ported by Doug Loucks, Lowell Observatory, August 11, 1993, from the
; C-Language version written by Marc Buie.
;-
;
; ------------------------------------------------------------------------------
; Local procedure d_adjust
; ------------------------------------------------------------------------------
PRO d_adjust, deg, mm
i = WHERE( mm EQ 60, count )
IF count NE 0 THEN BEGIN
   deg[i] = deg[i] + 1
   mm[i] =  0
ENDIF
END

; ------------------------------------------------------------------------------
; Local procedure m_adjust
; ------------------------------------------------------------------------------
PRO m_adjust, mm, ss
i = WHERE( ss GE 60.0, count )
IF count NE 0 THEN BEGIN
   mm[i] = mm[i] + 1
   ss[i] = 0.0
ENDIF
END

; ------------------------------------------------------------------------------
; Main Procedure decstr
; ------------------------------------------------------------------------------
PRO decstr, declination, places, str

IF N_PARAMS() NE 3 THEN BEGIN
   ; Display the calling sequence.
   PRINT, 'decstr, declination, places, str'
  RETURN
ENDIF

; Allow declination parameter to be integer, long, float, or double, and
; scalar or vector.
IF badpar( declination, [2,3,4,5], [0,1], CALLER='BADPAR ' ) THEN RETURN

pi_2 = !dpi / 2.0

; Initialize the output string to null.
str = ''

i = WHERE( (declination GT pi_2) OR (declination LT -pi_2), count )
IF count NE 0 THEN BEGIN
   MESSAGE, 'Declination out of range, |dec| > pi/2.', /INFO
   RETURN
ENDIF

; First, convert to numerical values of degrees, minutes, seconds.
radtodms, declination, sgn, dd, mm, ss

sign = STRING( FIX( sgn EQ 1 ), FORMAT='(I1)' )
p = WHERE( sign EQ '1', count )
IF count NE 0 THEN sign[p] = '+'
n = WHERE( sign EQ '0', count )
IF count NE 0 THEN sign[n] = '-'

deg = ABS( dd )

; This is the big decision table that generates the requested format.

CASE places OF
   -7 : BEGIN     ; +DD, Nearest degree.
      i = WHERE( FLOAT(mm) + ss/60.0 GE 30.0, count )
      IF count NE 0 THEN deg[i] = deg[i] + 1
      str = sign + STRING( deg, FORMAT='(I2.2)' )
   END

   -6 : BEGIN     ;  +DD:(00,30), Nearest 30 minutes.
      mm = nint( ( mm + ss/60.0 ) / 30.0 ) * 30.0
      d_adjust, deg, mm
      str = sign + STRING( deg, FORMAT='(I2.2)' ) + ':' + $
      STRING( mm, FORMAT='(I2.2)' )
   END

   -5 : BEGIN     ;  +DD:(00,15,30,45), Nearest 15 minutes.
      mm = nint( ( mm + ss/60.0 ) / 15.0 ) * 15.0
      d_adjust, deg, mm
      str = sign + STRING( deg, FORMAT='(I2.2)' ) + ':' + $
      STRING( mm, FORMAT='(I2.2)' )
   END

   -4 : BEGIN     ;  +DD:M0, Nearest 10 minutes.
      mm = nint( ( mm + ss/60.0 ) / 10.0 ) * 10.0
      d_adjust, deg, mm
      str = sign + STRING( deg, FORMAT='(I2.2)' ) + ':' + $
      STRING( mm, FORMAT='(I2.2)' )
   END

   -3 : BEGIN     ;  +DD:M(0,5), Nearest 5 minutes.
      mm = nint( ( mm + ss/60.0 ) / 5.0 ) * 5.0
      d_adjust, deg, mm
      str = sign + STRING( deg, FORMAT='(I2.2)' ) + ':' + $
      STRING( mm, FORMAT='(I2.2)' )
   END

   -2 : BEGIN     ;  +DD:MM, Nearest minute.
      mm = nint( mm + ss/60.0 )
      d_adjust, deg, mm
      str = sign + STRING( deg, FORMAT='(I2.2)' ) + ':' + $
      STRING( mm, FORMAT='(I2.2)' )
   END

   -1 : BEGIN     ;  +DD:MM:S0, Nearest 10 seconds.
      ss = nint( ss / 10.0 ) * 10.0
      d_adjust, mm, ss
      d_adjust, deg, mm
      str = sign + STRING( deg, FORMAT='(I2.2)' ) + ':' + $
      STRING( mm, FORMAT='(I2.2)' ) + ':' + $
      STRING( ss, FORMAT='(I2.2)' )
   END

   0  : BEGIN     ;  +DD:MM:SS, Nearest second.
      ss = nint( ss )
      d_adjust, mm, ss
      d_adjust, deg, mm
      str = sign + STRING( deg, FORMAT='(I2.2)' ) + ':' + $
      STRING( mm, FORMAT='(I2.2)' ) + ':' + $
      STRING( ss, FORMAT='(I2.2)' )
   END

   1  : BEGIN     ;  +DD:MM:SS.s, Nearest tenth of a second.
      ss = nint( ss / 0.1 ) * 0.1
      ; Save the fractional part of seconds.
      fss = ss - FIX( ss )
      m_adjust, mm, ss
      d_adjust, deg, mm
      str = sign + STRING( deg, FORMAT='(I2.2)' ) + ':' + $
      STRING( mm, FORMAT='(I2.2)' ) + ':' + $
      STRING( ss, FORMAT='(I2.2)' ) + $
      STRMID( STRING( fss, FORMAT='(F3.1)' ), 1, 2 )
   END

   2  : BEGIN     ;  +DD:MM:SS.ss, Nearest hundredth of a second.
      ss = nint( ss / 0.01 ) * 0.01
      ; Save the fractional part of seconds.
      fss = ss - FIX( ss )
      m_adjust, mm, ss
      d_adjust, deg, mm
      str = sign + STRING( deg, FORMAT='(I2.2)' ) + ':' + $
      STRING( mm, FORMAT='(I2.2)' ) + ':' + $
      STRING( ss, FORMAT='(I2.2)' ) + $
      STRMID( STRING( fss, FORMAT='(F4.2)' ), 1, 3 )
   END

   3  : BEGIN     ;  +DD:MM:SS.sss, Nearest thousandth of a second.
      ss = nint( ss / 0.001, /LONG ) * 0.001
      ; Save the fractional part of seconds.
      fss = ss - FIX( ss )
      m_adjust, mm, ss
      d_adjust, deg, mm
      str = sign + STRING( deg, FORMAT='(I2.2)' ) + ':' + $
      STRING( mm, FORMAT='(I2.2)' ) + ':' + $
      STRING( ss, FORMAT='(I2.2)' ) + $
      STRMID( STRING( fss, FORMAT='(F5.3)' ), 1, 4 )
   END

   ELSE : BEGIN
      MESSAGE, 'PLACES parameter must be in the range -7 to +3.', /INFO
      RETURN
   END
ENDCASE

END