Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

import ephem
import numpy as np

bodies = [ephem.Sun(),
          ephem.Moon(),
          ephem.Mars(),
          ephem.Venus(),
          ephem.Mars(),
          ephem.Jupiter(),
          ephem.Saturn(),
          ephem.Uranus(),
          ephem.Neptune(),
          ephem.Pluto()]

mydate = '2026/1/1'  # can be changed to whatever

xdegrees=md0:d1:d2_{degrees} = m\,d_0\,:\,d_1\,:\,d_2

where m=±1m=\pm1

xdegrees=m(d0+d160+d23600)_{degrees} = m\,(d_0 + \frac{d_1}{60} + \frac{d_2}{3600})

xradians=_{radians} = np.deg2rads(xdegrees_{degrees})

def sexi2deci(sexi):
# convert sexigesimal to decimal using the above formula
    splits = str(sexi).split(':')
    deci = abs(int(splits[0])) + int(splits[1])/60 + float(splits[2])/3600
    if str(sexi)[0]=='-':
        deci = -deci
    return deci
# sanity check using values from https://rhodesmill.org/pyephem/tutorial.html
body = bodies[7]
body.compute('1781/3/13')
ra, dec, mag = str(body.ra), str(body.dec), body.mag
assert body.name=='Uranus' and ra=='5:35:45.28' and dec=='23:32:54.1' and mag==5.6
# quick-and-dirty demo: elongation, magnitude, phase and constellation
print('{:8s} {:>8s} {:>10s} {:>7s}  {}'.format('', 'ELONGATION', 'MAGNITUDE', 'PHASE', 'CONSTELLATION'))
print('{:8s} {:>8s} {:>10s} {:>7s}  {}'.format('', ' (radians)', '', '(%)', 'constellation'))
for body in bodies:
    body.compute(mydate)
    print('{:10s} {:>8.4f} {:>10.2f} {:7.2f}  {}'.format(body.name, body.elong, body.mag, body.phase, ephem.constellation(body)))
         ELONGATION  MAGNITUDE   PHASE  CONSTELLATION
          (radians)                (%)  constellation
Sun          0.0000     -26.80  100.00  ('Sgr', 'Sagittarius')
Moon         2.5449     -11.98   91.40  ('Tau', 'Taurus')
Mars         0.0401       1.26   99.98  ('Sgr', 'Sagittarius')
Venus       -0.0254      -3.79   99.97  ('Sgr', 'Sagittarius')
Mars         0.0401       1.26   99.98  ('Sgr', 'Sagittarius')
Jupiter     -2.9534      -2.51   99.97  ('Gem', 'Gemini')
Saturn       1.3196       1.16   99.75  ('Aqr', 'Aquarius')
Uranus       2.3976       5.63   99.97  ('Tau', 'Taurus')
Neptune      1.3777       7.90   99.97  ('Psc', 'Pisces')
Pluto        0.3918      14.57  100.00  ('Cap', 'Capricornus')
# RA: astrometric geocentric, apparent geocentric, apparent topocentric
print('{:10s} {:>20s} {:>22s} {:>23s}'.format('', 'ASTROMETRIC_GEOCENTRIC', 'APPARENT_GEOCENTRIC', 'APPARENT_TOPOCENTRIC'))
print('{:10s} {:>12s} {:5s} {:>12s} {:5s} {:>13s} {:5s}'.format('', '(degrees)', '(radians)', '(degrees)', '(radians)', '(degrees)', '(radians)'))
for body in bodies:
    body.compute(mydate)
    a_ra, g_ra, ra = body.a_ra, body.g_ra, body.ra
    print('{:10s} {:>12s} {:9.3f} {:>12s} {:9.3f} {:>13s} {:9.3f}'.format(body.name, str(a_ra), a_ra, str(g_ra), g_ra, str(ra), ra))
# not much difference between the three, as expected

# "Angles become strings when printed or given to str(), but otherwise act like Python floating point numbers." [https://rhodesmill.org/pyephem/tutorial.html]
           ASTROMETRIC_GEOCENTRIC    APPARENT_GEOCENTRIC    APPARENT_TOPOCENTRIC
              (degrees) (radians)    (degrees) (radians)     (degrees) (radians)
Sun         18:44:25.38     4.906  18:45:58.77     4.913   18:45:58.77     4.913
Moon         4:14:05.41     1.109   4:15:41.08     1.116    4:15:41.08     1.116
Mars        18:53:57.38     4.948  18:55:31.15     4.955   18:55:31.15     4.955
Venus       18:38:39.72     4.881  18:40:13.59     4.888   18:40:13.59     4.888
Mars        18:53:57.38     4.948  18:55:31.15     4.955   18:55:31.15     4.955
Jupiter      7:30:55.05     1.967   7:32:29.84     1.974    7:32:29.84     1.974
Saturn      23:48:11.32     6.232  23:49:31.45     6.237   23:49:31.45     6.237
Uranus       3:41:25.42     0.966   3:42:56.81     0.973    3:42:56.81     0.973
Neptune     23:58:58.64     6.279   0:00:18.71     0.001    0:00:18.71     0.001
Pluto       20:22:12.79     5.333  20:23:44.05     5.340   20:23:44.05     5.340
# RA: manually convert degrees to radians, just to get a feel
print('{:10s} {:>32s}'.format('', 'APPARENT_TOPOCENTRIC'))
print('{:10s} {:>12s} {:5s} {:5s}'.format('', '(degrees)', '(radians)', '(radians)'))
for body in bodies:
    body.compute(mydate)
    ra = body.ra
    manual = 15*sexi2deci(ra)
    print('{:10s} {:>12s} {:9.3f} {:9.3f}'.format(body.name, str(ra), ra, np.deg2rad(manual)))
                       APPARENT_TOPOCENTRIC
              (degrees) (radians) (radians)
Sun         18:45:58.77     4.913     4.913
Moon         4:15:41.08     1.116     1.116
Mars        18:55:31.15     4.955     4.955
Venus       18:40:13.59     4.888     4.888
Mars        18:55:31.15     4.955     4.955
Jupiter      7:32:29.84     1.974     1.974
Saturn      23:49:31.45     6.237     6.237
Uranus       3:42:56.81     0.973     0.973
Neptune      0:00:18.71     0.001     0.001
Pluto       20:23:44.05     5.340     5.340
# Dec: manually convert degrees to radians, just to get a feel
print('{:10s} {:>32s}'.format('', 'DECLINATION'))
print('{:10s} {:>12s} {:5s} {:5s}'.format('', '(degrees)', '(radians)', '(radians)'))
for body in bodies:
    body.compute(mydate)
    dec = body.dec
    manual = np.deg2rad(sexi2deci(dec))
    assert np.allclose(dec, manual, rtol=1e-4)
    print('{:10s} {:>12s} {:>9.3f} {:>9.3f}'.format(body.name, str(dec), dec, manual))
                                DECLINATION
              (degrees) (radians) (radians)
Sun         -23:01:02.0    -0.402    -0.402
Moon         26:24:13.8     0.461     0.461
Mars        -23:43:11.9    -0.414    -0.414
Venus       -23:37:20.7    -0.412    -0.412
Mars        -23:43:11.9    -0.414    -0.414
Jupiter      21:58:44.9     0.384     0.384
Saturn       -3:35:46.9    -0.063    -0.063
Uranus       19:30:34.4     0.341     0.341
Neptune      -1:25:06.3    -0.025    -0.025
Pluto       -23:13:11.6    -0.405    -0.405
# heliocentric vs geocentric separations
# manually calculate geocentric separation, just to get a feel
for body in bodies:
    body.compute(mydate)
    xx, sun = body, bodies[0]   # bodies[0] is the sun
    xx_ra, xx_dec, sun_ra, sun_dec = xx.ra, xx.dec, sun.ra, sun.dec

    # Haversine formula
    manual = np.sin(xx_dec)*np.sin(sun_dec) + np.cos(xx_dec)*np.cos(sun_dec)*np.cos(xx_ra-sun_ra)
    manual = np.rad2deg(np.arccos(manual))
    
    print('{:8s} {:>12s} [{:6.2f}] \t {:>12s}'.format(body.name, str(ephem.separation(xx, sun)), manual,
                                               str(ephem.separation((xx.hlon, xx.hlat), (sun.hlon, sun.hlat)))))
Sun         0:00:00.0 [  0.00] 	    0:00:00.0
Moon      145:49:03.4 [145.82] 	   34:11:16.8
Mars        2:17:57.4 [  2.30] 	  176:06:39.0
Venus       1:27:10.1 [  1.45] 	  176:35:50.8
Mars        2:17:57.4 [  2.30] 	  176:06:39.0
Jupiter   169:12:30.8 [169.21] 	    8:45:35.5
Saturn     75:36:36.1 [ 75.61] 	   98:38:58.3
Uranus    137:22:47.1 [137.38] 	   40:40:14.7
Neptune    78:56:29.5 [ 78.94] 	   99:12:41.2
Pluto      22:27:01.2 [ 22.45] 	  156:56:30.1