1"""Basic tests of the Skyfield API module and its contents.""" 2 3import numpy as np 4from assay import assert_raises 5from skyfield import api, positionlib 6from skyfield.api import Topos 7from skyfield.errors import EphemerisRangeError 8 9def ts(): 10 yield api.load.timescale() 11 12def test_sending_jd_that_is_not_a_julian_date(): 13 earth = api.load('de421.bsp')['earth'] 14 with assert_raises(ValueError, r"please provide the at\(\) method" 15 " with a Time instance as its argument," 16 " instead of the value 'blah'"): 17 earth.at('blah') 18 19def test_apparent_position_class(ts): 20 e = api.load('de421.bsp') 21 p = e['earth'].at(ts.utc(2014, 2, 9, 14, 50)).observe(e['mars']).apparent() 22 assert isinstance(p, positionlib.Apparent) 23 24def test_astrometric_position_class(ts): 25 e = api.load('de421.bsp') 26 p = e['earth'].at(ts.utc(2014, 2, 9, 14, 50)).observe(e['mars']) 27 assert isinstance(p, positionlib.Astrometric) 28 29def test_ephemeris_contains_method(ts): 30 e = api.load('de421.bsp') 31 assert (399 in e) is True 32 assert (398 in e) is False 33 assert ('earth' in e) is True 34 assert ('Earth' in e) is True 35 assert ('EARTH' in e) is True 36 assert ('ceres' in e) is False 37 38def test_exception_raised_for_dates_outside_ephemeris(ts): 39 eph = api.load('de421.bsp') 40 message = ( 41 'ephemeris segment only covers dates 1899-07-28 23:59:18Z' 42 ' through 2053-10-08 23:58:51Z UT' 43 ) 44 with assert_raises(EphemerisRangeError, message) as a: 45 eph['earth'].at(ts.tt(4096)) 46 47 e = a.exception 48 assert e.args == (message,) 49 assert e.start_time.tdb == 2414864.5 50 assert e.end_time.tdb == 2471184.5 51 assert e.time_mask == [True] 52 assert e.segment is eph['earth'].vector_functions[0].spk_segment 53 54def test_planet_position_class(ts): 55 e = api.load('de421.bsp') 56 p = e['mars'].at(ts.utc(2014, 2, 9, 14, 50)) 57 assert isinstance(p, positionlib.Barycentric) 58 59def test_star_position_class(ts): 60 e = api.load('de421.bsp') 61 star = api.Star(ra_hours=0, dec_degrees=0) 62 p = e['earth'].at(ts.utc(2014, 2, 9, 15, 1)).observe(star) 63 assert isinstance(p, positionlib.Astrometric) 64 65def test_star_vector_from_earth(ts): 66 t = ts.tt_jd(api.T0) 67 eph = api.load('de421.bsp') 68 e = eph['earth'].at(t) 69 70 star = api.Star(ra_hours=[1.0, 2.0], dec_degrees=[+3.0, +4.0]) 71 p = e.observe(star) 72 assert p.position.au.shape == (3, 2) 73 assert p.velocity.au_per_d.shape == (3, 2) 74 assert p.t.shape == (2,) 75 assert (p.t.tt == api.T0).all() 76 a = p.apparent() 77 78 a1 = e.observe(api.Star(ra_hours=1.0, dec_degrees=+3.0)).apparent() 79 a2 = e.observe(api.Star(ra_hours=2.0, dec_degrees=+4.0)).apparent() 80 assert (a1.position.au == a.position.au[:,0]).all() 81 assert (a2.position.au == a.position.au[:,1]).all() 82 83def test_star_vector_from_topos(ts): 84 t = ts.tt_jd(api.T0) 85 eph = api.load('de421.bsp') 86 boston = eph['earth'] + Topos('42.3583 N', '71.0636 W') 87 b = boston.at(t) 88 89 star = api.Star(ra_hours=[1.0, 2.0], dec_degrees=[+3.0, +4.0]) 90 p = b.observe(star) 91 assert p.position.au.shape == (3, 2) 92 assert p.velocity.au_per_d.shape == (3, 2) 93 assert p.t.shape == (2,) 94 assert (p.t.tt == api.T0).all() 95 a = p.apparent() 96 97 a1 = b.observe(api.Star(ra_hours=1.0, dec_degrees=+3.0)).apparent() 98 a2 = b.observe(api.Star(ra_hours=2.0, dec_degrees=+4.0)).apparent() 99 assert (a1.position.au == a.position.au[:,0]).all() 100 assert (a2.position.au == a.position.au[:,1]).all() 101 102def test_altaz_needs_topos(ts): 103 e = api.load('de421.bsp') 104 earth = e['earth'] 105 moon = e['moon'] 106 apparent = earth.at(ts.utc(2016)).observe(moon).apparent() 107 with assert_raises(ValueError, 'from a specific Earth location'): 108 apparent.altaz() 109 110def test_from_altaz_needs_topos(): 111 p = positionlib.ICRF([0.0, 0.0, 0.0]) 112 with assert_raises(ValueError, 'to compute an altazimuth position'): 113 p.from_altaz(alt_degrees=0, az_degrees=0) 114 115def test_from_altaz_parameters(ts): 116 usno = Topos('38.9215 N', '77.0669 W', elevation_m=92.0) 117 t = ts.tt(jd=api.T0) 118 p = usno.at(t) 119 a = api.Angle(degrees=10.0) 120 d = api.Distance(au=0.234) 121 with assert_raises(ValueError, 'the alt= parameter with an Angle'): 122 p.from_altaz(alt='Bad value', alt_degrees=0, az_degrees=0) 123 with assert_raises(ValueError, 'the az= parameter with an Angle'): 124 p.from_altaz(az='Bad value', alt_degrees=0, az_degrees=0) 125 p.from_altaz(alt=a, alt_degrees='bad', az_degrees=0) 126 p.from_altaz(az=a, alt_degrees=0, az_degrees='bad') 127 assert str(p.from_altaz(alt=a, az=a).distance()) == '0.1 au' 128 assert str(p.from_altaz(alt=a, az=a, distance=d).distance()) == '0.234 au' 129 130def test_github_81(ts): 131 t = ts.utc(1980, 1, 1) 132 assert t == t 133 assert (t == 61) is False # used to die with AttributeError for "tt" 134 135def test_github_500_does_zero_position_trigger_numpy_warnings(ts): 136 zero_vector = np.array([0.0, 0.0, 0.0]) 137 t = ts.utc(2020, 12, 14) 138 p = positionlib.Astrometric(zero_vector, zero_vector, t=t, center=0) 139 p._ephemeris = api.load('de421.bsp') 140 with np.errstate(all='raise'): 141 p.apparent().radec() 142