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 whateverx
where
x
x np.deg2rads(x)
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