def test_light(orbit, mode): listeners = [LightListener(), LightListener('penumbra')] events = iter_listeners(orbit, listeners, mode) # Maybe the difference of date precision between 'exit' and 'entry' while computing from # a Ephem can be explained by the fact that the 'entry' events are further from # a point of the ephemeris than the 'exit' ones. p = next(events) assert abs(p.date - Date(2018, 4, 5, 17, 5, 57, 760757)).total_seconds() <= 8e-6 assert p.event.info == "Umbra exit" p = next(events) assert abs(p.date - Date(2018, 4, 5, 17, 6, 6, 20177)).total_seconds() <= 8e-6 assert p.event.info == "Penumbra exit" p = next(events) assert abs(p.date - Date(2018, 4, 5, 18, 2, 37, 568025)).total_seconds() <= 16e-6 assert p.event.info == "Penumbra entry" p = next(events) assert abs(p.date - Date(2018, 4, 5, 18, 2, 45, 814490)).total_seconds() <= 16e-6 assert p.event.info == "Umbra entry" with raises(StopIteration): next(events)
def test_duty_cycle(orbit_kepler): with mock_step(orbit_kepler) as mock: date = Date(2018, 5, 4, 15) orbit_kepler.propagate(date) assert mock.call_count == count_steps(orbit_kepler.date - date, orbit_kepler.propagator.step) assert mock.call_count == 100 with mock_step(orbit_kepler) as mock: date = orbit_kepler.date - timedelta(seconds=652) orbit_kepler.propagate(date) assert mock.call_count == count_steps(orbit_kepler.date - date, orbit_kepler.propagator.step) assert mock.call_count == 11 with mock_step(orbit_kepler) as mock: start = Date(2018, 5, 4, 13) stop = start + timedelta(minutes=90) data = [] for p in orbit_kepler.iter(start=start, stop=stop): data.append(p) assert len(data) == 91 assert data[0].date == start assert data[-1].date == stop assert mock.call_count == ( count_steps(orbit_kepler.date - start, orbit_kepler.propagator.step) + count_steps(stop - start, orbit_kepler.propagator.step, False) )
def test_propagate_rk4(orbit_kepler): orbit_kepler.propagator.method = KeplerNum.RK4 assert orbit_kepler.date == Date(2018, 5, 4, 13, 20, 47, 630976) # simple propagation with a Date object orb2 = orbit_kepler.propagate(orbit_kepler.date + timedelta(minutes=121, seconds=12)) assert orb2.date == Date(2018, 5, 4, 15, 21, 59, 630976) assert orb2.propagator.orbit is None # brand new propagator # simple propagation with a timedelta object orb3 = orb2.propagate(timedelta(minutes=12, seconds=5)) # Check if the propagator.orbit is initializd for orb2 # and not yet initialized for orb3 assert orb3.date == Date(2018, 5, 4, 15, 34, 4, 630976) assert orb2.propagator.orbit is not None assert orb3.propagator.orbit is None assert np.allclose( orb3, [-2267347.5906591383, 3865612.1569156954, -5093932.5567979375, -5238.634675262262, -5326.282920539333, -1708.6895889357945] ) # simple propagation with a negative step orb4 = orb3.propagate(timedelta(minutes=-15)) assert orb4.date == orb3.date - timedelta(minutes=15)
def test_find_event_two_calls_bis(orbit): # This case, where we search for the 90 deg Argument of Latitude # does not crash unexpectedly. kwargs = { "start": Date(2018, 4, 5, 16, 50), "stop": timedelta(minutes=200), "step": timedelta(minutes=3), "listeners": AnomalyListener(np.pi / 2, "aol") } orb_iterator = orbit.iter(**kwargs) p1 = find_event(orb_iterator, "Argument of Latitude = 90.00") assert abs(p1.date - Date(2018, 4, 5, 17, 57, 7, 129464)).total_seconds() < 1.8e-5 assert p1.event.info == "Argument of Latitude = 90.00" orb_iterator2 = orbit.iter(**kwargs) p2 = find_event(orb_iterator2, "Argument of Latitude = 90.00", offset=1) assert abs(p2.date - Date(2018, 4, 5, 19, 29, 42, 991221)).total_seconds() < 1.8e-5 assert p2.event.info == "Argument of Latitude = 90.00" orb_iterator3 = orbit.iter(**kwargs) with raises(RuntimeError): find_event(orb_iterator3, "Argument of Latitude = 90.00", offset=2)
def test_true_anomaly(molniya, mode): if isinstance(molniya, Ephem): stop = molniya[0].infos.period else: stop = molniya.infos.period step = timedelta(minutes=10) events = iter_listeners(molniya, AnomalyListener(np.pi), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 18, 14, 7, 743079)).total_seconds() < 3.7e-5 assert p.event.info == "True Anomaly = 180.00" with raises(StopIteration): p = next(events) events = iter_listeners(molniya, AnomalyListener(3 * np.pi / 2), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 21, 33, 10, 712900)).total_seconds() < 3.7e-5 assert p.event.info == "True Anomaly = 270.00" with raises(StopIteration): p = next(events) events = iter_listeners(molniya, AnomalyListener(0), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 22, 0, 2, 409409)).total_seconds() < 8e-6 assert p.event.info == "True Anomaly = 0.00" with raises(StopIteration): next(events) events = iter_listeners(molniya, AnomalyListener(np.pi / 2), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 22, 26, 54, 209357)).total_seconds() < 3.7e-5 assert p.event.info == "True Anomaly = 90.00" with raises(StopIteration): p = next(events)
def test_mean_anomaly(molniya, mode): if isinstance(molniya, Ephem): stop = molniya[0].infos.period else: stop = molniya.infos.period step = timedelta(minutes=10) events = iter_listeners(molniya, AnomalyListener(np.pi, "mean"), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 18, 14, 7, 743079)).total_seconds() < 3.7e-5 assert p.event.info == "Mean Anomaly = 180.00" with raises(StopIteration): p = next(events) events = iter_listeners(molniya, AnomalyListener(3 * np.pi / 2, "mean"), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 20, 7, 5, 494487)).total_seconds() < 3.7e-5 assert p.event.info == "Mean Anomaly = 270.00" with raises(StopIteration): p = next(events) events = iter_listeners(molniya, AnomalyListener(0, "mean"), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 22, 0, 2, 409409)).total_seconds() < 8e-6 assert p.event.info == "Mean Anomaly = 0.00" with raises(StopIteration): next(events) events = iter_listeners(molniya, AnomalyListener(np.pi / 2, "mean"), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 23, 52, 59, 555389)).total_seconds() < 3.7e-5 assert p.event.info == "Mean Anomaly = 90.00" with raises(StopIteration): p = next(events)
def test_propagate(jplfiles): venus = get_orbit('VenusBarycenter', Date(2018, 1, 14)) venus = venus.propagate(Date(2018, 1, 15, 12, 27)) assert abs(32.18435609745404946124835987575 + venus.date._offset) <= np.finfo(float).eps assert str(venus.frame) == "SolarSystemBarycenter" assert str(venus.form) == "cartesian" assert np.allclose(venus, [ 5.23110445e+10, -8.51235950e+10, -4.16279990e+10, 3.05086795e+04, 1.58745616e+04, 5.21182159e+03 ])
def test_listener(orbit_kepler): with mock_step(orbit_kepler) as mock: start = Date(2018, 5, 4, 13) stop = start + timedelta(minutes=90) data = [] for p in orbit_kepler.iter(start=start, stop=stop, listeners=LightListener()): data.append(p) assert len(data) == 93 assert mock.call_count == ( count_steps(orbit_kepler.date - start, orbit_kepler.propagator.step) + count_steps(stop - start, orbit_kepler.propagator.step, False)) # assert mock.call_count == 111 events = [x for x in data if x.event] assert len(events) == 2 assert events[0].date == Date(2018, 5, 4, 13, 8, 38, 869126) assert events[0].event.info == "Umbra exit" assert events[1].date == Date(2018, 5, 4, 14, 5, 21, 256923) assert events[1].event.info == "Umbra entry" with mock_step(orbit_kepler) as mock: start = Date(2018, 5, 4, 13) stop = start + timedelta(minutes=90) data = [] for p in orbit_kepler.iter(start=start, stop=stop, listeners=ApsideListener()): data.append(p) assert len(data) == 93 assert mock.call_count == ( count_steps(orbit_kepler.date - start, orbit_kepler.propagator.step) + count_steps(stop - start, orbit_kepler.propagator.step, False)) # assert mock.call_count == 125 events = [x for x in data if x.event] assert len(events) == 2 assert str(events[0].date) == "2018-05-04T13:08:30.765145 UTC" assert events[0].event.info == "Periapsis" assert str(events[1].date) == "2018-05-04T13:54:50.178231 UTC" assert events[1].event.info == "Apoapsis"
def test_event_iterator(orbit): kwargs = { "start": Date(2018, 4, 5, 16, 50), "stop": timedelta(minutes=100), "step": timedelta(minutes=3), "listeners": [ AnomalyListener(3 * np.pi / 2, "aol"), AnomalyListener(np.pi / 2, "aol"), ApsideListener(), ] } # iterate over the orbit, but filter only the AoL events, leaving # apsides events out orb_iterator = orbit.iter(**kwargs) events = [ "Argument of Latitude = 270.00", "Argument of Latitude = 90.00", ] iterator = events_iterator(orb_iterator, *events) p = next(iterator) assert abs(p.date - Date(2018, 4, 5, 17, 10, 49, 816867)).total_seconds() < 1.8e-5 assert p.event.info == "Argument of Latitude = 270.00" p = next(iterator) assert abs(p.date - Date(2018, 4, 5, 17, 57, 7, 129464)).total_seconds() < 1.8e-5 assert p.event.info == "Argument of Latitude = 90.00" # No more events to filter in the iterator with raises(StopIteration): p = next(iterator) # Same iterator construction, but this time we filter only apsudes events iterator = events_iterator(orbit.iter(**kwargs), "Apoapsis") p = next(iterator) assert abs(p.date - Date(2018, 4, 5, 16, 58, 54, 546919)).total_seconds() < 4e-5 assert p.event.info == "Apoapsis" # No more events to filter in the iterator with raises(StopIteration): p = next(iterator)
def orbit_man(orbit): orbit = orbit.copy() orbit.propagator = KeplerNum(get_body("Earth"), timedelta(seconds=60)) orbit.maneuvers = [ ImpulsiveMan( Date(2008, 9, 20, 12, 41, 9, 984493), [280, 0, 0], frame="TNW", comment="Maneuver 1", ), ImpulsiveMan(Date(2008, 9, 20, 13, 33, 11, 374985), [270, 0, 0], frame="TNW"), ] return orbit
def test_terminator(orbit, mode): events = iter_listeners(orbit, TerminatorListener(), mode) p = next(events) assert abs(p.date - Date(2018, 4, 5, 17, 11, 13, 908911)).total_seconds() <= 2e-5 assert p.event.info == "Day Terminator" p = next(events) assert abs(p.date - Date(2018, 4, 5, 17, 57, 33, 123730)).total_seconds() <= 2.5e-5 assert p.event.info == "Night Terminator"
def test_units(): ephem1 = load(folder.joinpath("tess_kms.txt").open()) assert ephem1.start == Date(2019, 4, 29, scale="TDB") assert ephem1.stop == Date(2019, 5, 29, scale="TDB") assert len(ephem1) == 31 ephem2 = load(folder.joinpath("tess_kmd.txt").open()) assert ephem2.start == Date(2019, 4, 29, scale="TDB") assert ephem2.stop == Date(2019, 5, 29, scale="TDB") assert len(ephem2) == 31 assert np.allclose(ephem1, ephem2)
def measureset(orbit, station): path = "{0} {1} {0}".format(station.name, orbit.cospar_id).split() aos = Date(2008, 9, 20, 18, 16, 3, 690790) los = Date(2008, 9, 20, 18, 24, 58, 852563) measures = MeasureSet([]) for orb in orbit.iter(start=aos, stop=los, step=timedelta(seconds=5)): sph = orb.copy(frame=station, form='spherical') measures.append(Range(path, orb.date, sph.r * 2)) measures.append(Azimut(path, orb.date, sph.theta)) measures.append(Elevation(path, orb.date, sph.phi)) return measures
def test_find_event_offset(orbit): kwargs = { "start": Date(2018, 4, 5, 16, 50), "stop": timedelta(minutes=200), "step": timedelta(minutes=3), "listeners": AnomalyListener(3 * np.pi / 2, "aol") } orb_iterator = orbit.iter(**kwargs) p = find_event(orb_iterator, "Argument of Latitude = 270.00", offset=1) assert abs(p.date - Date(2018, 4, 5, 18, 43, 25, 683360)).total_seconds() < 1.8e-5 assert p.event.info == "Argument of Latitude = 270.00"
def test_station_no_mask(orbit, station): station.mask = np.array([[ 1.97222205, 2.11184839, 2.53072742, 2.74016693, 3.00196631, 3.42084533, 3.71755131, 4.15388362, 4.71238898, 6.28318531 ], [ 0.35255651, 0.34906585, 0.27401669, 0.18675023, 0.28099801, 0.16580628, 0.12915436, 0.03490659, 0.62831853, 1.3962634 ]]) listeners = stations_listeners(station) station.mask = None points = station.visibility( orbit, start=Date(2018, 4, 5, 21), stop=timedelta(minutes=30), step=timedelta(seconds=30), events=listeners, ) with raises(ValueError): points = list(points)
def test_ltan2raan(common_env): date = Date(2020, 1, 29, 18, 27) assert abs(ltan.ltan2raan(date, 22.5 * 3600) - 1.8496591694176407) < eps assert abs(ltan.ltan2raan(date, 22.5 * 3600, "true") - 1.901700132311372) < eps
def test_tolerant(ephem): # Test for out of range starting and stoping points start = Date(2008, 9, 20, 12, 15) stop = timedelta(minutes=24) with raises(ValueError): ephem.ephem(start=start, stop=stop) with raises(ValueError): ephem.ephem(stop=timedelta(hours=2)) subephem = ephem.ephem(start=start, stop=stop, strict=False) assert subephem.start == ephem.start assert subephem.stop == start + stop subephem = ephem.ephem(stop=timedelta(hours=2), strict=False) assert subephem.start == ephem.start assert subephem.stop == ephem.stop # Case where both start and stop are BEFORE the first date of the initial ephem subephem = ephem.ephem(start=start, stop=timedelta(minutes=6), strict=False) assert len(subephem) == 0 # Case where both start and stop are AFTER the last date of the initial ephem subephem = ephem.ephem(start=ephem.start + timedelta(hours=2), stop=timedelta(minutes=6), strict=False) assert len(subephem) == 0 # Case where start is before and stop is after subephem = ephem.ephem(start=start, stop=timedelta(hours=1, minutes=45), strict=False) assert subephem.start == ephem.start assert subephem.stop == ephem.stop
def test_apside(orbit, mode): events = iter_listeners(orbit, ApsideListener(), mode) p = next(events) assert abs(p.date - Date(2018, 4, 5, 16, 58, 54, 546919)).total_seconds() <= 37e-6 assert p.event.info == "Apoapsis" p = next(events) assert abs(p.date - Date(2018, 4, 5, 17, 54, 54, 87860)).total_seconds() <= 13e-6 assert p.event.info == "Periapsis" with raises(StopIteration): next(events)
def test_node(orbit, mode): events = iter_listeners(orbit, NodeListener(), mode) p = next(events) assert abs(p.date - Date(2018, 4, 5, 17, 33, 59, 488549)).total_seconds() <= 20e-6 assert p.event.info == "Asc Node" p = next(events) assert abs(p.date - Date(2018, 4, 5, 18, 20, 15, 389928)).total_seconds() <= 17e-6 assert p.event.info == "Desc Node" with raises(StopIteration): next(events)
def test_station(station, helper): # lines = """ISS (ZARYA) # 1 25544U 98067A 16038.20499631 .00009950 00000-0 15531-3 0 9993 # 2 25544 51.6445 351.2284 0006997 89.9621 48.8570 15.54478078984606""" # orb = Tle(lines).orbit() # orb = orb.propagate(Date(2016, 2, 7, 16, 55)) # from beyond.dates.eop import get_pole # print(get_pole(Date(2016, 2, 7, 16, 55).mjd)) # assert False orb = Orbit([ 4225679.11976, 2789527.13836, 4497182.71156, -5887.93077439, 3748.50929999, 3194.45322378 ], Date(2016, 2, 7, 16, 55), 'cartesian', 'TEME', 'Sgp4') archive = orb.copy() assert station.orientation.name == "Toulouse" orb.frame = station orb.form = 'spherical' # azimuth assert np.isclose(-np.degrees(orb.theta), 159.75001561831209) # elevation assert np.isclose(np.degrees(orb.phi), 57.894234049230583) # range assert np.isclose(orb.r, 471467.65510239213) orb.frame = archive.frame orb.form = archive.form helper.assert_vector(archive, orb)
def tangential(propagator): return Orbit( propagator._mat6 @ [0, -100, 0, 0, 0, 0], Date(2020, 5, 24), "cartesian", "Hill", propagator, )
def test_ecliptic(): ref_ephem = load(folder.joinpath("mro_equatorial.txt").open()) assert ref_ephem.start == Date(2019, 4, 29, scale="TDB") assert ref_ephem.stop == Date(2019, 5, 29, scale="TDB") assert len(ref_ephem) == 31 ephem = load(folder.joinpath("mro_ecliptic.txt").open()) # Identical values along X, because the X axis (the vernal point) # is the same in equatorial and equatorial representation assert np.allclose(ref_ephem[:, 0], ephem[:, 0]) # There is slight differences between how the Horizon's # conversion and our own, but it is globally consistent assert np.allclose(ref_ephem[:, 1], ephem[:, 1], rtol=1e-4) assert np.allclose(ref_ephem[:, 2], ephem[:, 2], rtol=1e-3)
def test_station_visibility(orbit, station): station.mask = np.array([ [1.97222205, 2.11184839, 2.53072742, 2.74016693, 3.00196631, 3.42084533, 3.71755131, 4.15388362, 4.71238898, 6.28318531], [0.35255651, 0.34906585, 0.27401669, 0.18675023, 0.28099801, 0.16580628, 0.12915436, 0.03490659, 0.62831853, 1.3962634]]) points = list(station.visibility(orbit, start=Date(2018, 4, 5, 21), stop=timedelta(minutes=30), step=timedelta(seconds=30))) assert len(points) == 21 points = list(station.visibility(orbit, start=Date(2018, 4, 5, 21), stop=Date(2018, 4, 5, 21, 30), step=timedelta(seconds=30))) assert len(points) == 21 # Events (AOS, MAX and LOS) points = list(station.visibility(orbit, start=Date(2018, 4, 5, 21), stop=timedelta(minutes=70), step=timedelta(seconds=30), events=True)) # Three more points than precedently, due to the events computation assert len(points) == 26 assert isinstance(points[0].event, SignalEvent) assert points[0].event.info == 'AOS' assert points[0].event.elev == 0 assert abs(points[0].phi) < 1e-5 assert points[0].event.station == station assert (points[0].date - Date(2018, 4, 5, 21, 4, 41, 789681)).total_seconds() <= 1e-5 assert isinstance(points[10].event, MaskEvent) assert points[10].event.info == "AOS" assert points[10].event.elev == "Mask" assert points[10].event.station == station assert (points[10].date - Date(2018, 4, 5, 21, 9, 4, 977230)).total_seconds() <= 1e-5 assert isinstance(points[13].event, MaxEvent) assert points[13].event.info == "MAX" assert points[13].event.station == station assert (points[13].date - Date(2018, 4, 5, 21, 10, 2, 884540)).total_seconds() <= 1e-5 assert isinstance(points[23].event, MaskEvent) assert points[23].event.info == "LOS" assert points[23].event.elev == "Mask" assert points[23].event.station == station assert (points[23].date - Date(2018, 4, 5, 21, 14, 33, 978945)).total_seconds() <= 5e-5 assert isinstance(points[-1].event, SignalEvent) assert points[-1].event.info == 'LOS' assert points[-1].event.elev == 0 assert abs(points[-1].phi) < 1e-5 assert points[-1].event.station == station assert (points[-1].date - Date(2018, 4, 5, 21, 15, 25, 169655)).total_seconds() <= 1e-5
def orbit_continuous_man(orbit): orbit = orbit.copy() orbit.propagator = KeplerNum(get_body("Earth"), timedelta(seconds=60)) orbit.maneuvers = [ ContinuousMan( Date(2008, 9, 20, 12, 41, 9, 984493), timedelta(minutes=3), dv=[280, 0, 0], frame="TNW", comment="Maneuver 1", ), ContinuousMan( Date(2008, 9, 20, 13, 33, 11, 374985), timedelta(minutes=3), dv=[270, 0, 0], frame="TNW", ), ] return orbit
def test_radial_velocity(station, orbit, mode): events = iter_listeners(orbit, RadialVelocityListener(station), mode) p = next(events) assert abs(p.date - Date(2018, 4, 5, 17, 7, 29, 581221)).total_seconds() <= 2e-5 assert p.event.info == "Radial Velocity" p = next(events) assert abs(p.date - Date(2018, 4, 5, 17, 56, 5, 511934)).total_seconds() <= 3.5e-5 assert p.event.info == "Radial Velocity" # Test for RadialVelocity triggered only when in sight of the station events = list( iter_listeners(orbit, RadialVelocityListener(station, sight=True), mode)) assert len(events) == 1
def test_station_signal(station, orbit, mode): listeners = stations_listeners(station) events = iter_listeners(orbit, listeners, mode) p = next(events) assert abs(p.date - Date(2018, 4, 5, 17, 51, 6, 475978)).total_seconds() <= 502e-6 assert p.event.info == "AOS" p = next(events) assert abs(p.date - Date(2018, 4, 5, 17, 56, 5, 542270)).total_seconds() <= 715e-6 assert p.event.info == "MAX" p = next(events) assert abs(p.date - Date(2018, 4, 5, 18, 1, 4, 828355)).total_seconds() <= 859e-6 assert p.event.info == "LOS"
def test_transform(jplfiles): mars = get_orbit('Mars', Date(2018, 2, 25)) mars.frame = "SolarSystemBarycenter" mars.form = "keplerian" assert mars.frame.center.name == "Sun" assert mars.frame.center.m > 1.9e30 assert 1.3 * AU <= mars.a <= 1.7 * AU
def test_tle(tle, ccsds_format): # Check that a TLE and its OMM representation are the same txt = dumps(tle, fmt=ccsds_format) orb = loads(txt) new_tle = Tle.from_orbit(orb) assert str(tle.tle) == str(new_tle) assert all(tle == orb) date = Date(2020, 9, 30) assert all(tle.propagate(date) == orb.propagate(date))
def lower_circular(propagator): """Define an orbit 600 m below the target, and 1500 behind """ return Orbit( propagator._mat6 @ [-600, -1500, 0, 0, 1.5 * propagator.n * 600, 0], Date(2020, 5, 24), "cartesian", "Hill", propagator, )
def test_propagate_dopri(orbit_kepler): orbit_kepler.propagator.method = KeplerNum.DOPRI54 assert orbit_kepler.date == Date(2018, 5, 4, 13, 20, 47, 630976) orb2 = orbit_kepler.propagate(orbit_kepler.date + timedelta(minutes=121, seconds=12)) assert orb2.date == Date(2018, 5, 4, 15, 21, 59, 630976) assert orb2.propagator.orbit is None # brand new propagator orb3 = orb2.propagate(timedelta(minutes=12, seconds=5)) assert orb3.date == Date(2018, 5, 4, 15, 34, 4, 630976) assert orb2.propagator.orbit is not None # This propagator has been used assert orb3.propagator.orbit is None # This one not assert np.allclose( np.array(orb3), [-2267319.8725340427, 3865646.423538732, -5093927.810461366, -5238.647479926973, -5326.249640066392, -1708.7264386468821] )