This page was created by the IDL library routine `mk_html_help2`.

Last modified: Sat Jul 26 18:17:38 2025.

# Directory Listing of Routines

# external/aacgm_v2

- AACGM_V2[1]
- AACGM_V2[2]
- AACGM_V2[2]
- TIMEYRSECTOYMDHMS
  Convert seconds of year to YMDHMS.
- TIMEYMDHMSTOYRSEC
  Convert YMDHMS to seconds of year.
- TIMEYMDHMSTOEPOCH
  Convert YMDHMS to seconds of epoch.
- TIMEEPOCHTOYMDHMS
  Convert seconds of epoch to YMDHMS.
- TIMEYMDHMSTOJULIAN
  Convert YMDHMS to Julian date.
- TIMEJULIANTOYMDHMS
  Convert Julian date to YMDHMS.
- AACGMIDL_V2[1]
- AACGMIDL_V2[2]
- AACGMLIB_V2[1]
- AACGMLIB_V2[2]
- AACGMLIB_V2[2]
- AACGMLIB_V2[3]
- AACGMLIB_V2[4]
- AACGMLIB_V2[5]
- AACGMLIB_V2[6]
- AACGMLIB_V2[7]
- AACGMLIB_V2[8]
- AACGMLIB_V2[9]
- ASTALG_DDAY
  Convert DHMS to decimal day.
- ASTALG_JDE
  Convert year,month, decimal day to Julian date.
- ASTALG_JDE2CALENDAR
  Convert Julian date to YMDHMS
- ASTALG_MEAN_SOLAR_ANOMALY
  Calculate mean solar anomaly.
- ASTALG_MEAN_LUNAR_LONGITUDE
  Calculate mean lunar longitude
- ASTALG_LUNAR_ASCENDING_NODE
  Calculate lunar ascending node
- ASTALG_MEAN_SOLAR_LONGITUDE
  Calculate mean solar longitude.
- ASTALG_MEAN_OBLIQUITY
  Calculate mean obliquity
- ASTALG_APPARENT_OBLIQUITY
  Calculate apparent obliquity
- ASTALG_GEOMETRIC_SOLAR_LONGITUDE
  Calculate geometric solar longitude.
- ASTALG_APPARENT_SOLAR_LONGITUDE
  Calculate apparent solar longitude.
- ASTALG_NUTATION_CORR
  Calculate correction factors for the nutation of the Earth's
- ASTALG_SOLAR_DECLINATION
  Calculate solar declination.
- ASTALG_SOLAR_RIGHT_ASCENSION
  Calculate solar right_ascension.
- ASTALG_EQUATION_OF_TIME
  Calculate solar equation of time.
- MLTCONVERT_V2
  Calculate Magnetic Local Time (MLT) using AACGM-v2 coordinates
- MLTCONVERTYMDHMS_V2
  Calculate Magnetic Local Time
- MLTCONVERTYRSEC_V2
  Calculate Magnetic Local Time
- MLTCONVERTEPOCH_V2
  Calculate Magnetic Local Time
- MLT_V2
  Legacy routine. Wrapper to compute Magnetic Local Time (MLT) using

# Routine Descriptions

## AACGMIDL_V2[1]

[Next Routine] [List of Routines]

    unction AACGM_v2_Dayno, yr,mo,dy, days=days
     ; works on an array. assume that all from same day
     ; WHAT IS THE POINT OF AN ARRAY OF THE SAME DAY?!

     mdays=[0,31,28,31,30,31,30,31,31,30,31,30,31]

     nelem = n_elements(yr)
     if (yr[0] ne yr[nelem-1]) or $
       (mo[0] ne mo[nelem-1]) or $
       (dy[0] ne dy[nelem-1]) then begin
       print, ''
       print, 'Not same day in AACGM_v2_Dayno'
       print, ''
       exit
     endif

     tyr = yr[0]
     ; leap year calculation
     if tyr mod 4 ne 0 then inc=0 $
     else if tyr mod 400 eq 0 then inc=1 $
     else if tyr mod 100 eq 0 then inc=0 $
     else inc=1
     mdays[2]=mdays[2]+inc

     if keyword_set(days) then days = fix(total(mdays))

     if nelem eq 1 then $
       doy = total(mdays[0:mo[0]-1])+dy[0] $
     else $
       doy = intarr(nelem) + total(mdays[0:mo[0]-1])+dy[0]

     return, fix(doy)
    nd

(See external/aacgm_v2/aacgmidl_v2.pro)

## AACGMIDL_V2[2]

[Previous Routine] [Next Routine] [List of Routines]

    ro AACGM_v2_Date, yr,dayno, mo,dy

     err = 0

     mdays=[0,31,28,31,30,31,30,31,31,30,31,30,31]

     ; leap year calculation
     if yr mod 4 ne 0 then inc=0 $
     else if yr mod 400 eq 0 then inc=1 $
     else if yr mod 100 eq 0 then inc=0 $
     else inc=1
     mdays[2]=mdays[2]+inc

     tots = intarr(13)
     for k=0,12 do tots[k] = total(mdays[0:k])

     q = where(tots ge dayno, nq)
     mo = q[0]
     dy = dayno - tots[q[0]-1]

    nd

(See external/aacgm_v2/aacgmidl_v2.pro)

## AACGMLIB_V2[1]

[Previous Routine] [Next Routine] [List of Routines]

(See external/aacgm_v2/aacgmlib_v2.pro)

## AACGMLIB_V2[2]

[Previous Routine] [Next Routine] [List of Routines]

    unction AACGM_v2_LoadCoef, units, order=ord
     common AACGM_v2_Com

     on_ioerror, iofail

     if keyword_set(ord) then order_v2 = ord else order_v2 = 10  ; default order
     kmax_v2 = (order_v2+1)*(order_v2+1)

     ncoord = 3    ; xyz
     nquart = 5    ; quartic altitude fit coefficients
     nflag  = 2    ; 0: GEO->AACGM; 1: AACGM->GEO

     ; interpolation in time, so need two sets of coefficients....
     coefs_v2 = dblarr(2,kmax_v2,ncoord,nquart,nflag)

     temp_coef = dblarr(kmax_v2,ncoord,nquart,nflag)
     readf, units[0],temp_coef
     coefs_v2[0,*,*,*,*] = temp_coef

     readf, units[1],temp_coef
     coefs_v2[1,*,*,*,*] = temp_coef

     coef_v2 = dblarr(kmax_v2,ncoord,nquart,nflag)
     cint_v2 = dblarr(kmax_v2,ncoord,nflag)
     leo_first_coeff_old = -1.

     sol_dec_old = 0       ; what the hell are these used for?!
     told = 1e12
     mslon1=0
     mslon2=0

     return, 0

    ofail:
     return, -1

    nd

(See external/aacgm_v2/aacgmlib_v2.pro)

## AACGMLIB_V2[2]

[Previous Routine] [Next Routine] [List of Routines]

    unction AACGM_v2_Sgn, a, b
     if (a ge 0) then x = a else x = -a
     if (b ge 0) then return, x
     return, -x
    nd

(See external/aacgm_v2/aacgmlib_v2.pro)

## AACGMLIB_V2[3]

[Previous Routine] [Next Routine] [List of Routines]

    ro AACGM_v2_Rylm, colat,lon,order, ylmval

     ; Note: the recurrence relations are for the associated legendre polynomials.
     ;       SGS has added the normalization factor for the spherical harmonic
     ;       functions given by (6.8.2). See note about this above.

     cos_theta = cos(colat)
     sin_theta = sin(colat)

     cos_lon = cos(lon)
     sin_lon = sin(lon)

     d1    = -sin_theta
     z2    = dcomplex(cos_lon,sin_lon)
     z1    = d1*z2
     q_fac = z1

     ; Generate Zonal Harmonics (P_l^(m=0) for l = 1,order) using recursion
     ; relation (6.8.7), p. 252, Numerical Recipes in C, 2nd. ed., Press. W.
     ; et al. Cambridge University Press, 1992) for case where m = 0.
     ;
     ; l Pl = cos(theta) (2l-1) Pl-1 - (l-1) Pl-2          (6.8.7)
     ;
     ; where Pl = P_l^(m=0) are the associated Legendre polynomials

     ylmval[0] = 1.d         ; l = 0, m = 0
     ylmval[2] = cos_theta   ; l = 1, m = 0

     for l=2,order do begin
       ; indices for previous two values: k = l * (l+1) + m with m=0
       ia = (l-2)*(l-1)
       ib = (l-1)*l
       ic = l * (l+1)

       ylmval[ic] = (cos_theta * (2*l-1) * ylmval[ib] - (l-1)*ylmval[ia])/l
     endfor

     ; Generate P_l^l for l = 1 to (order+1)^2 using algorithm based upon (6.8.8)
     ; in Press et al., but incorporate longitude dependence, i.e., sin/cos (phi)
     ;
     ; Pll = (-1)^l (2l-1)!! (sin^2(theta))^(l/2)
     ;
     ; where Plm = P_l^m are the associated Legendre polynomials

     q_val = q_fac
     ylmval[3] = double(q_val)       ; l = 1, m = +1
     ylmval[1] = -imaginary(q_val)   ; l = 1, m = -1
     for l=2,order do begin
       d1    = l*2 - 1.
       z2    = d1*q_fac
       z1    = z2*q_val
       q_val = z1

       ; indices for previous two values: k = l * (l+1) + m
       ia = l*(l+2)    ; m = +l
       ib = l*l        ; m = -l

       ylmval[ia] = double(q_val)
       ylmval[ib] = -imaginary(q_val)
     endfor

     ; Generate P_l,l-1 to P_(order+1)^2,l-1 using algorithm based upon (6.8.9)
     ; in Press et al., but incorporate longitude dependence, i.e., sin/cos (phi)
     ;
     ; Pl,l-1 = cos(theta) (2l-1) Pl-1,l-1

     for l=2,order do begin
       l2 = l*l
       tl = 2*l
       ; indices for Pl,l-1; Pl-1,l-1; Pl,-(l-1); Pl-1,-(l-1)
       ia = l2 - 1
       ib = l2 - tl + 1
       ic = l2 + tl - 1
       id = l2 + 1

       fac = tl - 1
       ylmval[ic] = fac * cos_theta * ylmval[ia]     ; Pl,l-1
       ylmval[id] = fac * cos_theta * ylmval[ib]     ; Pl,-(l-1)
     endfor

     ; Generate remaining P_l+2,m to P_(order+1)^2,m for each m = 1 to order-2
     ; using algorithm based upon (6.8.7) in Press et al., but incorporate
     ; longitude dependence, i.e., sin/cos (phi).
     ;
     ; for each m value 1 to order-2 we have P_mm and P_m+1,m so we can compute
     ; P_m+2,m; P_m+3,m; etc.

     for m=1,order-2 do begin
       for l=m+2,order do begin
         ca = double(2.*l-1)/(l-m)
         cb = double(l+m-1.)/(l-m)

         l2 = l*l
         ic = l2 + l + m
         ib = l2 - l + m
         ia = l2 - l - l - l + 2 + m
         ; positive m
         ylmval[ic] = ca * cos_theta * ylmval[ib] - cb * ylmval[ia]

         ic -= (m+m)
         ib -= (m+m)
         ia -= (m+m)
         ; negative m
         ylmval[ic] = ca * cos_theta * ylmval[ib] - cb * ylmval[ia]
       endfor
     endfor

     ; Normalization added here (SGS)
     ;
     ; Note that this is NOT the standard spherical harmonic normalization factors
     ;
     ; The recursive algorithms above treat positive and negative values of m in
     ; the same manner. In order to use these algorithms the normalization must
     ; also be modified to reflect the symmetry.
     ;
     ; Output values have been checked against those obtained using the internal
     ; IDL legendre() function to obtain the various associated legendre
     ; polynomials.
     ;
     ; As stated above, I think that this normalization may be unnecessary. The
     ; important thing is that the various spherical harmonics are orthogonal,
     ; rather than orthonormal.

     fact = factorial(indgen(2*order+1))
     ffff = dblarr((order+1)*(order+1))
     for l=0,order do begin
       for m=0,l do begin
         k = l * (l+1) + m         ; 1D index for l,m
         ffff[k] = sqrt((2*l+1)/(4*!dpi) * fact[l-m]/fact[l+m])
       endfor
       for m=-l,-1 do begin
         k = l * (l+1) + m         ; 1D index for l,m
         kk = l * (l+1) - m
         ffff[k] = ffff[kk] * (-1)^(-m mod 2)
       endfor
     endfor

     ylmval *= ffff

     return
    nd

(See external/aacgm_v2/aacgmlib_v2.pro)

## AACGMLIB_V2[4]

[Previous Routine] [Next Routine] [List of Routines]

    ro AACGM_v2_Alt2CGM, r_height_in, r_lat_alt, r_lat_adj
     common IGRF_v2_Com

     ; convert from at-altitude to AACGM coordinates
     eradius = 6371.2
     eps     = 1e-9
     unim    = 0.9999999

     r1 = cos(!pi*r_lat_alt/180.)
     ra = r1*r1
     if (ra lt eps) then ra = eps

     r0 = (r_height_in/RE + 1.) / ra
     if (r0 lt unim) then r0 = unim

     r1 = acos(sqrt(1./r0))
     r_lat_adj= AACGM_v2_Sgn(r1, r_lat_alt)*180.0/!pi

     return
    nd

(See external/aacgm_v2/aacgmlib_v2.pro)

## AACGMLIB_V2[5]

[Previous Routine] [Next Routine] [List of Routines]

    ro AACGM_v2_CGM2Alt, r_height_in,r_lat_in, r_lat_adj, error
     common IGRF_v2_Com

     ; convert from AACGM to at-altitude coordinates
     ;eradius = 6371.2
     unim    = 1
     error   = 0

     r1 = cos(!pi*r_lat_in/180.0)
     ra = (r_height_in/RE+ 1)*(r1*r1)
     if (ra gt unim) then begin
       ra = unim
       error = 1
     endif

     r1 = acos(sqrt(ra))
     r_lat_adj = AACGM_v2_Sgn(r1,r_lat_in)*180.0/!pi

     return
    nd

(See external/aacgm_v2/aacgmlib_v2.pro)

## AACGMLIB_V2[6]

[Previous Routine] [Next Routine] [List of Routines]

    ro AACGM_v2_ConvertGeoCoord, lat_in,lon_in,height_in, lat_out,lon_out, $
                                   error, geo=geo, trace=trace, $
                                   bad_idea=bad_idea, allow_trace=allow_trace, $
                                   eps=eps, at_alt=at_alt, verbose=verbose, $
                                   debug=debug
     common AACGM_v2_Com
     common IGRF_v2_Com

     ; need RE later on
     if (n_elements(RE) eq 0) then init_common

     if (height_in lt 0) then begin
       if ~keyword_set(verbose) || verbose ge 0 then $
         print, $
         'WARNING: coordinate transformations are not intended for altitudes < 0 km : ', $
         height_in
       error = -2
     endif

     if height_in gt 2000 and $
         not keyword_set(trace) and not keyword_set(bad_idea) and $
         not keyword_set(allow_trace) then begin
       ; the user is not using fieldline tracing or indicated that they know
       ; what they are doing by setting the 'bad_idea' keyword.
       print, 'ERROR: coefficients are not valid for altitudes above 2000 km.'
       print, '       Use fieldline tracing option [/trace] to perform fieldline'
       print, '       tracing at all altitudes, [/allow_trace] to perform'
       print, '       fieldline tracing only above 2000 km or indicate that you'
       print, '       want to use the coefficients for extrapolation and are aware'
       print, '       that the results can be nonsensical by setting the bad_idea'
       print, '       keyword.'
       error = -4
       return
     endif

     if (abs(lat_in) gt 90.) then begin
       print, 'ERROR: latitudes must be in the range -90 to +90 degrees'
       error = -8
       return
     endif

     SGS v2.3 removing requirement that longitude be 0 to 360. Does not seems to
              matter and is inconsistent with C version: -180 to 180.

     ; SGS - better checking of inputs needed here
     if lon_in lt 0 then lon_in += 360
     if ((lon_in lt 0) or (lon_in gt 360)) then begin
       print, 'ERROR: longitudes must be in the range 0 to 360 degrees'
       print, lon_in
       error = -16
       return
     endif

     SGS v2.3 geodetic to geocentric (and back) are done in AACGM_v2_Convert()

     ; field line tracing
     if keyword_set(trace) or (height_in gt 2000 and keyword_set(allow_trace)) $
     then begin
       if keyword_set(geo) then begin
         AACGM_v2_Trace_inv, lat_in,lon_in,height_in, tmp_lat,tmp_lon, error, $
                       fixed=fixed, ds=ds, eps=eps, max_ds=max_ds, $
                       verbose=verbose
           lat_out = tmp_lat
           lon_out = tmp_lon

       endif else begin
         AACGM_v2_Trace, lat_in,lon_in,height_in, tmp_lat,tmp_lon, error, $
                       fixed=fixed, ds=ds, eps=eps, max_ds=max_ds
         lat_out = tmp_lat
         lon_out = tmp_lon
       endelse
       return
     endif

     ; 20140827 SGS moved coefficient loading to Date/Time setting functions
     ; 20140827 SGS moved time interpolation to Date/Time setting functions

     flag = keyword_set(geo)

     ; determine the altitude dependence of the coefficients
     if (height_in ne height_old_v2[flag]) then begin
       print, '*** HEIGHT INTERPOLATION ***'
       alt_var    = height_in/2000.0   ; make this scaling height a variable?
       alt_var_sq = alt_var*alt_var
       alt_var_cu = alt_var*alt_var_sq
       alt_var_qu = alt_var*alt_var_cu

       for i=0,2 do begin    ; should this be variable, i.e. we only use x and y
         for j=0,kmax_v2-1 do begin
           cint_v2[j,i,flag] = coef_v2[j,i,0,flag] + $
                             coef_v2[j,i,1,flag] * alt_var + $
                             coef_v2[j,i,2,flag] * alt_var_sq + $
                             coef_v2[j,i,3,flag] * alt_var_cu + $
                             coef_v2[j,i,4,flag] * alt_var_qu
         endfor
       endfor
       height_old_v2[flag] = height_in
     endif

     x = double(0)
     y = double(0)
     z = double(0)

     lon_input = lon_in*!pi/180.0
     lon_input = lon_in*DTOR

     ; Intermediate coordinate. Only used for inverse transmformation
     if not keyword_set(at_alt) or (flag eq 0) then begin
     if not keyword_set(at_alt) and (flag eq 0) then begin
       colat_input = (90.-lat_in)*DTOR
     endif else begin
       ; convert from AACGM to at-altitude coordinates
       error = -64
       AACGM_v2_CGM2Alt, height_in,lat_in, lat_adj, errflg
       if (errflg ne 0) then return
       colat_input = (90. - lat_adj)*DTOR
     endelse

     ; SGS - remove this feature after timing tests
     if keyword_set(debug) then begin
       ; use the built-in legendre function to compute values of the spherical
       ; harmonic functions
       fact = factorial(indgen(2*order_v2+1))

       ylmval = dblarr(kmax_v2)
       for l=0,order_v2 do begin

         ; m < 0 terms
         for m=-l,-1 do begin
           plm = legendre(cos(colat_input), l, m, /double)
           ylm = sqrt((2*l+1)/(4*!dpi) * fact[l-m]/fact[l+m])*plm*sin(m*lon_input)
           k = l * (l+1) + m         ; 1D index for l,m
           ylmval[k] = ylm
           x += cint_v2[k,0,flag] * ylm
           y += cint_v2[k,1,flag] * ylm
           z += cint_v2[k,2,flag] * ylm
         endfor

         ; m = 0 term
         plm = legendre(cos(colat_input), l, 0, /double)
         ylm = sqrt((2*l+1)/(4*!dpi)) * plm
         k = l * (l+1)               ; 1D index for l,m
         ylmval[k] = ylm
         x += cint_v2[k,0,flag] * ylm
         y += cint_v2[k,1,flag] * ylm
         z += cint_v2[k,2,flag] * ylm

         ; m > 0 terms
         for m=1,l do begin
           plm = legendre(cos(colat_input), l, m, /double)
           ylm = sqrt((2*l+1)/(4*!dpi) * fact[l-m]/fact[l+m])*plm*cos(m*lon_input)
           k = l * (l+1) + m         ; 1D index for l,m
           ylmval[k] = ylm
           x += cint_v2[k,0,flag] * ylm
           y += cint_v2[k,1,flag] * ylm
           z += cint_v2[k,2,flag] * ylm
         endfor

       endfor
       ;print, 'legendre()'
       ;print, ylmval
     endif else begin
       ; use the Rylm function (adapted to orthonormal functions; SGS) to compute
       ; values of the spherical harmonic functions

       ylmval = dblarr(kmax_v2)
       AACGM_v2_Rylm, colat_input,lon_input, order_v2,ylmval

       for l = 0,order_v2 do begin
         for m = -l,l do begin
           k = l * (l+1) + m

           x += cint_v2[k,0,flag]*ylmval[k]
           y += cint_v2[k,1,flag]*ylmval[k]
           z += cint_v2[k,2,flag]*ylmval[k]    ; SGS - need this for sign...
         endfor
       endfor
     ;print, 'Rylm'
     ;print, ylmval
     endelse

     ; COMMENT: SGS
     ;
     ; This answers one of my questions about how the coordinates for AACGM are
     ; guaranteed to be on the unit sphere. Here they compute xyz indpendently
     ; using the SH coefficients for each coordinate. They reject anything that
     ; is +/- .1 Re from the surface of the Earth. They then scale each xyz
     ; coordinate by the computed radial distance. This is a TERRIBLE way to do
     ; things... but necessary for the inverse transformation.

     ; SGS - new method that ensures position is on unit sphere and results in a
     ;       much better fit. Uses z coordinate only for sign, i.e., hemisphere.
     if (flag eq 0) then begin
       fac = x*x + y*y
       if fac gt 1. then begin
         ; we are in the forbidden region and the solution is undefined
         lat_out = !values.f_nan
         lon_out = !values.f_nan
         error = -64
         return
       endif

       ztmp = sqrt(1. - fac)
       if z lt 0 then z = -ztmp else z = ztmp

       colat_temp = acos(z)

     endif else begin
     ; SGS - for inverse the old normalization produces lower overall errors...
       r = sqrt(x*x + y*y + z*z)
       if ((r lt 0.9) or (r gt 1.1)) then begin
         ; too much variation in the radial component
         lat_out = !values.f_nan
         lon_out = !values.f_nan
         error = -32
         return
       endif

       z /= r
       x /= r
       y /= r

       ; SGS - this is for cases where abs(z) > 1.
       if (z ge 1.) then colat_temp = 0 $
       else if (z lt -1.) then colat_temp = !dpi $
       else colat_temp = acos(z)
     endelse

     ; SGS - check these values
     if ((abs(x) lt 1e-8) and (abs(y) lt 1e-8)) then $
       lon_temp = 0 $
     else $
       lon_temp = atan(y,x)

     lon_output = lon_temp

     if keyword_set(at_alt) and (flag eq 0) then begin
       lat_alt = 90 - colat_temp/DTOR
       AACGM_v2_Alt2CGM, height_in,lat_alt, lat_adj
       colat_output = (90. - lat_adj) * DTOR; * !pi/180.0
     endif else $
       colat_output = colat_temp

     lat_out = 90. - colat_output/DTOR ;*180.0/!pi
     lon_out = lon_output/DTOR ;*180.0/!pi

     error = 0
     return
    nd

(See external/aacgm_v2/aacgmlib_v2.pro)

## AACGMLIB_V2[7]

[Previous Routine] [Next Routine] [List of Routines]

    unction AACGM_v2_Convert, in_lat,in_lon,height, out_lat,out_lon,r, geo=geo, $
                               trace=trace, bad_idea=bad_idea, $
                               eps=eps, allow_trace=allow_trace, $
                               gcentric=gcentric, $
                               verbose=verbose, debug=debug

     common IGRF_v2_Com

     geo = keyword_set(geo)
     if n_elements(in_lat) ne 1 then begin
       n       = n_elements(in_lat)
       sze     = size(in_lat)
       out_lat = dblarr(sze[1:sze[0]])
       out_lon = dblarr(sze[1:sze[0]])
       r       = dblarr(sze[1:sze[0]])
       tmp_lat = 0.d
       tmp_lon = 0.d
       for i=0, n-1 do begin

         ; convert geodetic to geocentric
         if not keyword_set(gcentric) and not keyword_set(geo) then begin
           rtp = geod2geoc(in_lat[i], in_lon[i], height[i])

           ;* modify lat/lon/alt to geocentric values */
           in_lat[i] = 90.d - rtp[1]/DTOR
           in_lon[i] = rtp[2]/DTOR
           height[i] = (rtp[0]-1.d)*RE
         endif

         AACGM_v2_ConvertGeoCoord, in_lat[i],in_lon[i],height[i], $
                                   tmp_lat,tmp_lon, error, geo=geo, $
                                   trace=trace, bad_idea=bad_idea, $
                                   allow_trace=allow_trace, eps=eps, $
                                   verbose=verbose, debug=debug
         out_lat[i] = tmp_lat
         out_lon[i] = tmp_lon

         if not keyword_set(geo) then begin
           r[i] = (height[i] + RE)/RE    ; geocentric radial distance in RE
         endif else begin
           if not keyword_set(gcentric) then begin
             p = geoc2geod(out_lat[i],out_lon[i],(RE+height[i])/RE)
             out_lat[i] = p[0]
             height[i] = p[2]
           endif
           r[i] = height[i]
         endelse
       endfor
     endif else begin
       out_lat = 0.d
       out_lon = 0.d

       ; convert geodetic to geocentric
       if not keyword_set(gcentric) and not keyword_set(geo) then begin
         rtp = geod2geoc(in_lat, in_lon, height)

         ;* modify lat/lon/alt to geocentric values */
         in_lat = 90.d - rtp[1]/DTOR
         in_lon = rtp[2]/DTOR
         height = (rtp[0]-1.d)*RE
       endif

       AACGM_v2_ConvertGeoCoord, in_lat,in_lon,height, $
                                 out_lat,out_lon, error, geo=geo, $
                                 trace=trace, bad_idea=bad_idea, $
                                 allow_trace=allow_trace, eps=eps, $
                                 verbose=verbose, debug=debug

       if not keyword_set(geo) then begin
         r = (height + RE)/RE    ; geocentric radial distance in RE
       endif else begin
         if not keyword_set(gcentric) then begin
           p = geoc2geod(out_lat,out_lon,(RE+height)/RE)

           out_lat = p[0]
           height = p[2]
         endif
         r = height
       endelse
     endelse

     return, error
    nd

(See external/aacgm_v2/aacgmlib_v2.pro)

## AACGMLIB_V2[8]

[Previous Routine] [Next Routine] [List of Routines]

    ro AACGM_v2_Trace, lat_in,lon_in,height_in, lat_out,lon_out, error, $
                       fixed=fixed, ds=ds, eps=eps, max_ds=max_ds
     common AACGM_v2_Com
     common IGRF_v2_Com

     err = IGRF_SetDateTime(aacgm_v2_datetime.year, aacgm_v2_datetime.month, $
                       aacgm_v2_datetime.day,  aacgm_v2_datetime.hour,  $
                       aacgm_v2_datetime.minute, aacgm_v2_datetime.second)
     if (err ne 0) then return

     if not keyword_set(ds) then $
       ds  = 1.                  ; 1 km default starting stepsize
     dsRE  = ds/RE
     dsRE0 = dsRE
     if not keyword_set(eps) then $
       eps = 1e-4/RE             ; global error (RE)

     ; if user wants to fix maximum step size then let them by turning off
     ; radial step size dependence that is default
     if keyword_set(max_ds) then RRds = 0 else RRds = 1

     rtp = dblarr(3)
     rtp[0] = (RE + height_in)/RE  ; 1.0 is surface of Earth
     rtp[1] = (90.-lat_in)*DTOR    ; colatitude in radians
     rtp[2] = lon_in*DTOR          ; longitude  in radians

     ; convert position to Cartesian coords
     xyzg = sph2car(rtp)

     ; convert to magnetic Dipole coordinates
     xyzm = geo2mag(xyzg)

     if xyzm[2] gt 0 then idir = -1 else idir = 1    ; N or S hemisphere

     dsRE = dsRE0

     ; trace to magnetic equator
     ;
     ; Note that there is the possibility that the magnetic equator lies
     ; at an altitude above the surface of the Earth but below the starting
     ; altitude. I am not certain of the definition of CGM, but these
     ; fieldlines map to very different locations than the solutions that
     ; lie above the starting altitude. I am considering the solution for
     ; this set of fieldlines as undefined; just like those that lie below
     ; the surface of the Earth.

     ; Added a check for when tracing goes below altitude so as not to contiue
     ; tracing beyond what is necessary.
     ;
     ; Also making sure that stepsize does not go to zero

     below = 0
     niter = 0
     while (~below && (idir*xyzm[2] lt 0)) do begin

       xyzp = xyzg

       ; x,y,z are passed by reference and modified here...
       AACGM_v2_RK45, xyzg, idir, dsRE, eps

       ; make sure that stepsize does not go to zero
       if (dsRE*RE lt 1e-2) then dsRE = 1e-2/RE

       ; convert to magnetic Dipole coordinates
       xyzm = geo2mag(xyzg)

       below = (total(xyzg*xyzg) lt (RE+height_in)*(RE+height_in)/(RE*RE))

       niter++
     endwhile

     xyzc = xyzp
     if (~below && niter gt 1) then begin
       ; now bisect stepsize (fixed) to land on magnetic equator w/in 1 meter

       while dsRE gt 1e-3/RE do begin
         dsRE *= .5
         xyzp = xyzc
         AACGM_v2_RK45, xyzc, idir, dsRE, eps, /fixed
         xyzm = geo2mag(xyzc)

         ; Is it possible that resetting here causes a doubling of the tol?
         if idir * xyzm[2] gt 0 then xyzc = xyzp
       endwhile
     endif

     ; 'trace' back to surface along Dipole field lines
     Lshell = sqrt(total(xyzc*xyzc))
     if Lshell lt (RE+height_in)/RE then begin
       ; Magnetic equator is below your...
       lat_out = !values.f_nan
       lon_out = !values.f_nan
       error   = 1
     endif else begin
       xyzm = geo2mag(xyzc)
       rtp  = car2sph(xyzm)

       lat_out = -idir*acos(sqrt(1./Lshell))/DTOR
       lon_out = rtp[2]/DTOR
       if lon_out gt 180 then lon_out -= 360   ; SGS - make consistent with output
                                               ; from coefficient functions
       error   = 0
     endelse

    nd

(See external/aacgm_v2/aacgmlib_v2.pro)

## AACGMLIB_V2[9]

[Previous Routine] [Next Routine] [List of Routines]

    ro AACGM_v2_Trace_inv, lat_in,lon_in,height_in, lat_out,lon_out, error, $
                       fixed=fixed, ds=ds, eps=eps, max_ds=max_ds, verbose=verbose
     common AACGM_v2_Com
     common IGRF_v2_Com

     err = IGRF_SetDateTime(aacgm_v2_datetime.year, aacgm_v2_datetime.month, $
                       aacgm_v2_datetime.day,  aacgm_v2_datetime.hour,  $
                       aacgm_v2_datetime.minute, aacgm_v2_datetime.second)
     if (err ne 0) then return

     if not keyword_set(ds) then $
       ds  = 1.                  ; 1 km default starting stepsize
     dsRE  = ds/RE
     dsRE0 = dsRE
     if not keyword_set(eps) then $
       eps   = 1e-4/RE           ; global error (RE)

     ; if user wants to fix maximum step size then let them by turning off
     ; radial step size dependence that is default
     if keyword_set(max_ds) then RRds = 0 else RRds = 1

     ; INV: for inverse we must first map AACGM to magnetic equator along
     ;      the dipole field line that passes through the Earth at lat/lon
     if (abs(lat_in - 90.d) lt 1e-6) then lat_in = 90-1e-6
     Lshell = 1.d/(cos(lat_in*DTOR)*cos(lat_in*DTOR))

     if keyword_set(verbose) then print, Lshell

     if Lshell lt (RE + height_in)/RE then begin
       ; solution does not exist, the starting position at the magnetic
       ; equator is below the altitude of interest
       lat_out = !values.f_nan
       lon_out = !values.f_nan
       error   = 1
     endif else begin
       phim = lon_in

       ; magnetic Cartesian coordinates of fieldline trace starting point
       xyzm = dblarr(3)
       xyzm[0] = Lshell*cos(phim*DTOR)
       xyzm[1] = Lshell*sin(phim*DTOR)
       xyzm[2] = 0.d

       ; geographic Cartesian coordinates of starting point
       xyzg = mag2geo(xyzm)

       ; geographic spherical coordinates of starting point
       rtp = car2sph(xyzg)

       ; direction of trace is determined by the starting hemisphere?
       if lat_in gt 0 then idir = 1 else idir = -1   ; N or S hemisphere

       dsRE = dsRE0

       ; trace back to altitude above Earth
       niter = 0
       while rtp[0] gt (RE + height_in)/RE do begin

         xyzp = xyzg
         if keyword_set(verbose) then print, 'xyz: ', xyzg, dsRE
         AACGM_v2_RK45, xyzg, idir, dsRE, eps, $
                                 fixed=fixed, max_ds=max_ds, RRds=RRds, $
                                 verbose=verbose
         if keyword_set(verbose) then print, 'xyz: ', xyzg, dsRE

         ; make sure that stepsize does not go to zero
         if (dsRE*RE lt 5e-1) then dsRE = 5e-1/RE

         rtp = car2sph(xyzg)

         niter++
         if keyword_set(verbose) then stop
       endwhile

       ; now bisect stepsize (fixed) to land on magnetic equator w/in 1 meter
       xyzc = xyzp

       if niter gt 1 then begin
         while dsRE gt 1e-3/RE do begin
           dsRE *= .5
           xyzp = xyzc
           AACGM_v2_RK45, xyzc, idir, dsRE, eps, /fixed

           rtp = car2sph(xyzc)

           if rtp[0] lt (RE + height_in)/RE then xyzc = xyzp
         endwhile
       endif

       ; record lat/lon and xyz
       lat_out = 90. - rtp[1]/DTOR
       lon_out = rtp[2]/DTOR
       if lon_out gt 180 then lon_out -= 360   ; SGS - make consistent with output
                                               ; from coefficient functions
       error   = 0
     endelse

    nd

(See external/aacgm_v2/aacgmlib_v2.pro)

## AACGM_V2[1]

[Previous Routine] [Next Routine] [List of Routines]

    unction AACGM_v2_SetDateTime, year,month,day,hour,minute,second

     common AACGM_v2_Com
     common IGRF_v2_Com

     ; set defaults if not all parameters are passed in
     np = n_params()
     if np lt 6 then second = 0
     if np lt 5 then minute = 0
     if np lt 4 then hour   = 0
     if np lt 3 then day    = 1
     if np lt 2 then month  = 1
     if np lt 1 then return, -1

     days = -1
     doy  = AACGM_v2_Dayno(year,month,day, days=days)
     fyear = year + ((doy-1) + $
               (hour + (minute + second/60.)/60.)/24.) / days

     if n_elements(IGRF_FIRST_EPOCH) eq 0 then init_common
     if (fyear lt IGRF_FIRST_EPOCH or fyear ge IGRF_LAST_EPOCH+5) then begin
       print, ''
       print, 'Date range for AACGM-v2 is ',IGRF_FIRST_EPOCH,'-',IGRF_LAST_EPOCH+5
       print, ''
       return, -1
     endif

     aacgm_v2_datetime = {year:-1, month:-1, day:-1, hour:-1, minute:-1, $
                           second:-1, dayno:-1, daysinyear:-1}

     aacgm_v2_datetime.year       = year
     aacgm_v2_datetime.month      = month
     aacgm_v2_datetime.day        = day
     aacgm_v2_datetime.hour       = hour
     aacgm_v2_datetime.minute     = minute
     aacgm_v2_datetime.second     = second
     aacgm_v2_datetime.dayno      = doy
     aacgm_v2_datetime.daysinyear = days

     err = AACGM_v2_TimeInterp()

     return, err

    nd

(See external/aacgm_v2/aacgm_v2.pro)

## AACGM_V2[2]

[Previous Routine] [Next Routine] [List of Routines]

    unction AACGM_v2_SetNow

     common AACGM_v2_Com
     common IGRF_v2_Com

     aacgm_v2_datetime = {year:-1, month:-1, day:-1, hour:-1, minute:-1, $
                           second:-1, dayno:-1, daysinyear:-1}

     ; use current time (in UT)
     caldat, systime(/julian, /utc), month,day,year, hour,minute,second

     days = -1
     doy  = AACGM_v2_Dayno(year,month,day, days=days)
     fyear = year + ((doy-1) + $
               (hour + (minute + second/60.)/60.)/24.) / days

     if n_elements(IGRF_FIRST_EPOCH) eq 0 then init_common
     if (fyear lt IGRF_FIRST_EPOCH or fyear ge IGRF_LAST_EPOCH+5) then begin
       print, ''
       print, 'Date range for AACGM-v2 is ',IGRF_FIRST_EPOCH,'-',IGRF_LAST_EPOCH+5
       print, ''
       return, -1
     endif

     aacgm_v2_datetime.year       = year
     aacgm_v2_datetime.month      = month
     aacgm_v2_datetime.day        = day
     aacgm_v2_datetime.hour       = hour
     aacgm_v2_datetime.minute     = minute
     aacgm_v2_datetime.second     = second
     aacgm_v2_datetime.dayno      = doy
     aacgm_v2_datetime.daysinyear = days

     err = AACGM_v2_TimeInterp()

     return, err

    nd

(See external/aacgm_v2/aacgm_v2.pro)

## AACGM_V2[2]

[Previous Routine] [Next Routine] [List of Routines]

    unction AACGM_v2_GetDateTime, year, month=month, day=day, $
                                 hour=hour, minute=minute, second=second, $
                                 dyno=dayno, silent=silent

     common AACGM_v2_Com

     if (n_elements(aacgm_v2_datetime) eq 0) then begin
       if not keyword_set(silent) then $
         print, "Date and Time are not currently set"
       return, -1
     endif

     year   = aacgm_v2_datetime.year
     month  = aacgm_v2_datetime.month
     day    = aacgm_v2_datetime.day
     hour   = aacgm_v2_datetime.hour
     minute = aacgm_v2_datetime.minute
     second = aacgm_v2_datetime.second
     dayno  = aacgm_v2_datetime.dayno

     return, 0

    nd

(See external/aacgm_v2/aacgm_v2.pro)

## ASTALG_APPARENT_OBLIQUITY

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_apparent_obliquity

     PURPOSE:
           Calculate apparent obliquity

     CALLING SEQUENCE:
           eps = AstAlg_apparent_obliquity(jd)

           All the arguments must be given.

           The time is given as the julian date
           The returned value is the apparent obliquity.

(See external/aacgm_v2/astalg.pro)

## ASTALG_APPARENT_SOLAR_LONGITUDE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_apparent_solar_longitude

     PURPOSE:
           Calculate apparent solar longitude.

     CALLING SEQUENCE:
           asl = AstAlg_apparent_solar_longitude(jd)

           All the arguments must be given.

           The time is given as the julian date
           The returned value is the apparent solar longitude.

(See external/aacgm_v2/astalg.pro)

## ASTALG_DDAY

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_dday

     PURPOSE:
           Convert DHMS to decimal day.

     CALLING SEQUENCE:
           dday = AstAlg_dday(day,hour,minute,second)

           All the arguments must be given.

           Day is the day of month ranging from 0-31.
           The returned value is the decimal day of month.

(See external/aacgm_v2/astalg.pro)

## ASTALG_EQUATION_OF_TIME

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_equation_of_time

     PURPOSE:
           Calculate solar equation of time.

     CALLING SEQUENCE:
           asl = AstAlg_equation_of_time(jd)

           All the arguments must be given.

           The time is given as the julian date
           The returned value is the equation of time.

(See external/aacgm_v2/astalg.pro)

## ASTALG_GEOMETRIC_SOLAR_LONGITUDE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_geometric_solar_longitude

     PURPOSE:
           Calculate geometric solar longitude.

     CALLING SEQUENCE:
           asl = AstAlg_geometric_solar_longitude(jd)

           All the arguments must be given.

           The time is given as the julian date
           The returned value is the geometric solar longitude.

(See external/aacgm_v2/astalg.pro)

## ASTALG_JDE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_jde

     PURPOSE:
           Convert year,month, decimal day to Julian date.

     CALLING SEQUENCE:
           jde = AstAlg_jde(year,month,day)

           All the arguments must be given.

           The returned value is the julian date.

(See external/aacgm_v2/astalg.pro)

## ASTALG_JDE2CALENDAR

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_jde2calendar

     PURPOSE:
           Convert Julian date to YMDHMS

     CALLING SEQUENCE:
           jde = AstAlg_jde2calendar(jd,year,month,day,hour,minute,second)

           All the arguments must be given.

           The returned value is zero on success.

(See external/aacgm_v2/astalg.pro)

## ASTALG_LUNAR_ASCENDING_NODE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_lunar_ascending_node

     PURPOSE:
           Calculate lunar ascending node

     CALLING SEQUENCE:
           asl = AstAlg_lunar_ascending_node(jd)

           All the arguments must be given.

           The time is given as the julian date
           The returned value is the lunar ascending node.

(See external/aacgm_v2/astalg.pro)

## ASTALG_MEAN_LUNAR_LONGITUDE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_mean_lunar_longitude

     PURPOSE:
           Calculate mean lunar longitude

     CALLING SEQUENCE:
           asl = AstAlg_mean_lunar_longitude(jd)

           All the arguments must be given.

           The time is given as the julian date
           The returned value is the lunar ascending node.

(See external/aacgm_v2/astalg.pro)

## ASTALG_MEAN_OBLIQUITY

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_mean_obliquity

     PURPOSE:
           Calculate mean obliquity

     CALLING SEQUENCE:
           asl = AstAlg_mean_obliquity(jd)

           All the arguments must be given.

           The time is given as the julian date
           The returned value is the mean obliquity.

(See external/aacgm_v2/astalg.pro)

## ASTALG_MEAN_SOLAR_ANOMALY

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_mean_solar_anomaly

     PURPOSE:
           Calculate mean solar anomaly.

     CALLING SEQUENCE:
           asl = AstAlg_mean_solar_anomaly(jd)

           All the arguments must be given.

           The time is given as the julian date
           The returned value is the mean solar anomaly.

(See external/aacgm_v2/astalg.pro)

## ASTALG_MEAN_SOLAR_LONGITUDE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_mean_solar_longitude

     PURPOSE:
           Calculate mean solar longitude.

     CALLING SEQUENCE:
           asl = AstAlg_mean_solar_longitude(jd)

           All the arguments must be given.

           The time is given as the julian date
           The returned value is the mean solar longitude.

(See external/aacgm_v2/astalg.pro)

## ASTALG_NUTATION_CORR

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_nutation_corr

     PURPOSE:
           Calculate correction factors for the nutation of the Earth's
           spin.

     CALLING SEQUENCE:
           asl = AstAlg_nutation_corr(jd,slong_corr,obliq_corr)

           All the arguments must be given.

           The time is given as the julian date
           The returned values are the correction factors

(See external/aacgm_v2/astalg.pro)

## ASTALG_SOLAR_DECLINATION

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_solar_declination

     PURPOSE:
           Calculate solar declination.

     CALLING SEQUENCE:
           asl = AstAlg_solar_declination(jd)

           All the arguments must be given.

           The time is given as the julian date
           The returned value is the solar declination.

(See external/aacgm_v2/astalg.pro)

## ASTALG_SOLAR_RIGHT_ASCENSION

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           AstAlg_solar_right_ascension

     PURPOSE:
           Calculate solar right_ascension.

     CALLING SEQUENCE:
           asl = AstAlg_solar_right_ascension(jd)

           All the arguments must be given.

           The time is given as the julian date
           The returned value is the solar right ascension.

(See external/aacgm_v2/astalg.pro)

## MLTCONVERTEPOCH_V2

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           MLTConvertEpoch_v2

     PURPOSE:
           Calculate Magnetic Local Time

     CALLING SEQUENCE:
           mlt = MLTConvertEpoch_v2(epoch,mlon [, /MLT2mlon])

           This function calculates magnetic local time.

(See external/aacgm_v2/mlt_v2.pro)

## MLTCONVERTYMDHMS_V2

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           MLTConvertYMDHMS_v2

     PURPOSE:
           Calculate Magnetic Local Time

     CALLING SEQUENCE:
           mlt = MLTConvertYMDHMS_v2(yr,mo,dy,hr,mt,sc,mlon [, /MLT2mlon])

           This function calculates magnetic local time.

(See external/aacgm_v2/mlt_v2.pro)

## MLTCONVERTYRSEC_V2

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           MLTConvertYrsec_v2

     PURPOSE:
           Calculate Magnetic Local Time

     CALLING SEQUENCE:
           mlt = MLTConvertYrsec_v2(yr,yrsec,mlon [, /MLT2mlon])

           This function calculates magnetic local time.

(See external/aacgm_v2/mlt_v2.pro)

## MLTCONVERT_V2

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           MLTConvert_v2

     PURPOSE:
           Calculate Magnetic Local Time (MLT) using AACGM-v2 coordinates

     CALLING SEQUENCE:
           mlt = MLTConvert_v2(yr,mo,dy,hr,mt,sc, mlon [, sstrace=sstrace] $
                                [, ssheight=ssheight] [, anti=anti] [, err=err] $
                                [, dday_bug=dday_bug] [, /MLT2mlon]

           mlon     - AACGM-v2 magnetic longitude of desired location
           sstrace  - use field-line tracing option for reference longitude. Note,
                      this is an advanced feature and can result in undefined
                      results. Not recommended.
           ssheight - use a different height when computing the reference longitude
                      of the subsolar point.
           err      - error code. 0 for success.
           anti     - use antisolar point for reference longitude
           MLT2mlon - set keyword for inverse calculation. mlon is taken to be MLT
                      in this case.

(See external/aacgm_v2/mlt_v2.pro)

## MLT_V2

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           mlt_v2

     PURPOSE:
           Legacy routine. Wrapper to compute Magnetic Local Time (MLT) using
           AACGM-v2 coordinates and time specified using keywords or the
           current AACGM-v2 time.

     CALLING SEQUENCE:
           mlt = mlt_v2(mlon [, year=yr] [, month=mo] [, day=dy] [, hour=hr] $
                              [, minute=mt] [, second=sc] [, err=err] $
                              [, sstrace=sstrace] [, ssheight=ssheight] $
                              [, /MLT2mlon]

        mlon       - AACGM-v2 magnetic longitude of desired location
        date/time  - optional date and time, current AACGM-v2 time used by default
                      so must be already set.
        sstrace    - use field-line tracing option for reference longitude. Note,
                      this is an advanced feature and can result in undefined
                      results. NOT RECOMMENDED.
        ssheight   - use a different height when computing the reference longitude
                      of the subsolar point.
        err        - error code. 0 for success.
        anti       - use antisolar point for reference longitude. NOT RECOMMENDED.
        MLT2mlon   - set keyword for inverse calculation. In this case mlon is
                      MLT.

(See external/aacgm_v2/mlt_v2.pro)

## TIMEEPOCHTOYMDHMS

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           TimeEpochToYMDHMS

     PURPOSE:
           Convert seconds of epoch to YMDHMS.

     CALLING SEQUENCE:
           status = TimeEpochToYMDHMS(yr,mo,dy,hr,mt,sc,epoch)

           All the arguments must be given.

           The returned value is zero for success, or -1 for failure

(See external/aacgm_v2/aacgmidl_v2.pro)

## TIMEJULIANTOYMDHMS

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           TimeJulianToYMDHMS

     PURPOSE:
           Convert Julian date to YMDHMS.

     CALLING SEQUENCE:
           status = TimeJulianToYMDHMS(yr,mo,dy,hr,mt,sc,epoch)

           All the arguments must be given.

           The returned value is zero for success, or -1 for failure

(See external/aacgm_v2/aacgmidl_v2.pro)

## TIMEYMDHMSTOEPOCH

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           TimeYMDHMSToEpoch

     PURPOSE:
           Convert YMDHMS to seconds of epoch.

     CALLING SEQUENCE:
           epoch = TimeYMDHMSToEpoch(yr,mo,dy,hr,mt,sc)

           All the arguments must be given.

           The returned value is the number of seconds since 0:00UT
           January 1, 1970 for success, or -1 for failure

(See external/aacgm_v2/aacgmidl_v2.pro)

## TIMEYMDHMSTOJULIAN

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           TimeYMDHMSToJulian

     PURPOSE:
           Convert YMDHMS to Julian date.

     CALLING SEQUENCE:
           julian = TimeYMDHMStoJulian(yr,mo,dy,hr,mt,sc)

           All the arguments must be given.

           The returned value is the julian time for success,
           or -1 for failure

(See external/aacgm_v2/aacgmidl_v2.pro)

## TIMEYMDHMSTOYRSEC

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           TimeYMDHMSToYrsec

     PURPOSE:
           Convert YMDHMS to seconds of year.

     CALLING SEQUENCE:
           yrsec = TimeYMDHMSToYrSec(yr,mo,dy,hr,mt,sc)

           All the arguments must be given.

           The returned value is the number of seconds past the
           start of the year for success, or -1 for failure

(See external/aacgm_v2/aacgmidl_v2.pro)

## TIMEYRSECTOYMDHMS

[Previous Routine] [List of Routines]

     NAME:
           TimeYrsectoYMDHMS

     PURPOSE:
           Convert seconds of year to YMDHMS.

     CALLING SEQUENCE:
           status = TimeYrsecToYMDHMS(yr,mo,dy,hr,mt,sc,yrsec)

           All the arguments must be given.

           The returned value is zero for success, or -1 for failure

(See external/aacgm_v2/aacgmidl_v2.pro)