def test_from_ephem_raises_warning_if_time_is_not_tdb_with_proper_time(recwarn): body = Earth epoch = Time("2017-09-29 07:31:26", scale="utc") expected_epoch_string = "2017-09-29 07:32:35.182" # epoch.tdb.value Orbit.from_body_ephem(body, epoch) w = recwarn.pop(TimeScaleWarning) assert expected_epoch_string in str(w.message)
def test_from_ephem_raises_warning_if_time_is_not_tdb_with_proper_time(recwarn): body = Earth epoch = Time("2017-09-29 07:31:26", scale="utc") expected_epoch_string = "2017-09-29 07:32:35.182" # epoch.tdb.value Orbit.from_body_ephem(body, epoch) w = recwarn.pop(TimeScaleWarning) assert expected_epoch_string in str(w.message)
def test_plot_trajectory_sets_label(): op = OrbitPlotter() earth = Orbit.from_body_ephem(Earth) mars = Orbit.from_body_ephem(Mars) trajectory = earth.sample() op.plot(mars, label="Mars") op.plot_trajectory(trajectory, label="Earth") legend = plt.gca().get_legend() assert legend.get_texts()[1].get_text() == "Earth"
def test_plot_trajectory_sets_label(): op = OrbitPlotter() earth = Orbit.from_body_ephem(Earth) mars = Orbit.from_body_ephem(Mars) trajectory = earth.sample() op.plot(mars, label="Mars") op.plot_trajectory(trajectory, label="Earth") legend = plt.gca().get_legend() assert legend.get_texts()[1].get_text() == "Earth"
def test_redraw_keeps_trajectories(): # See https://github.com/poliastro/poliastro/issues/518 op = StaticOrbitPlotter() earth = Orbit.from_body_ephem(Earth) mars = Orbit.from_body_ephem(Mars) trajectory = earth.sample() op.plot(mars, label="Mars") op.plot_trajectory(trajectory, label="Earth") assert len(op.trajectories) == 2 op.set_frame(*mars.pqw()) assert len(op.trajectories) == 2
def plot_solar_system(outer=True, epoch=None): """ Plots the whole solar system in one single call. .. versionadded:: 0.9.0 Parameters ------------ outer : bool, optional Whether to print the outer Solar System, default to True. epoch: ~astropy.time.Time, optional Epoch value of the plot, default to J2000. """ bodies = [Mercury, Venus, Earth, Mars] if outer: bodies.extend([Jupiter, Saturn, Uranus, Neptune]) op = OrbitPlotter() for body in bodies: orb = Orbit.from_body_ephem(body, epoch) op.plot(orb, label=str(body)) # Sets frame to the orbit of the Earth by default # TODO: Wait until https://github.com/poliastro/poliastro/issues/316 # op.set_frame(*Orbit.from_body_ephem(Earth, epoch).pqw()) return op
def plot_solar_system(outer=True, epoch=None): """ Plots the whole solar system in one single call. .. versionadded:: 0.9.0 Parameters ------------ outer : bool, optional Whether to print the outer Solar System, default to True. epoch: ~astropy.time.Time, optional Epoch value of the plot, default to J2000. """ bodies = [Mercury, Venus, Earth, Mars] if outer: bodies.extend([Jupiter, Saturn, Uranus, Neptune]) op = OrbitPlotter() for body in bodies: orb = Orbit.from_body_ephem(body, epoch) op.plot(orb, label=str(body)) # Sets frame to the orbit of the Earth by default # TODO: Wait until https://github.com/poliastro/poliastro/issues/316 # op.set_frame(*Orbit.from_body_ephem(Earth, epoch).pqw()) return op
def hill_radius(body, a=None, e=None): """Approximated radius of the Hill Sphere of Influence (SOI) for a body. Parameters ---------- body : `~poliastro.bodies.Body` Astronomical body which the SOI's radius is computed for. a : float, optional Semimajor axis of the body's orbit, default to None (will be computed from ephemerides). e : float, optional Eccentricity of the body's orbit, default to 0 (will be computed from ephemerides). Returns ------- astropy.units.quantity.Quantity Approximated radius of the Sphere of Influence (SOI) [m] """ # Compute semimajor and eccentricity axis at epoch J2000 for the body if it was not # introduced by the user if a is None or e is None: # https://github.com/poliastro/poliastro/pull/679#issuecomment-503902597 from poliastro.twobody.orbit import Orbit ss = Orbit.from_body_ephem(body, J2000_TDB) a = a if a is not None else ss.a e = e if e is not None else ss.ecc mass_ratio = body.k / (3 * body.parent.k) r_SOI = a * (1 - e) * (mass_ratio**(1 / 3)) return r_SOI.decompose()
def laplace_radius(body, a=None): """Approximated radius of the Laplace Sphere of Influence (SOI) for a body. Parameters ---------- body : `~poliastro.bodies.Body` Astronomical body which the SOI's radius is computed for. a : float, optional Semimajor axis of the body's orbit, default to None (will be computed from ephemerides). Returns ------- astropy.units.quantity.Quantity Approximated radius of the Sphere of Influence (SOI) [m] """ # Compute semimajor axis at epoch J2000 for the body if it was not # introduced by the user if a is None: # https://github.com/poliastro/poliastro/pull/679#issuecomment-503902597 from poliastro.twobody.orbit import Orbit a = Orbit.from_body_ephem(body, J2000_TDB).a r_SOI = a * (body.k / body.parent.k)**(2 / 5) return r_SOI.decompose()
def test_show_calls_prepare_plot(mock_prepare_plot, mock_iplot): m = OrbitPlotter2D() earth = Orbit.from_body_ephem(Earth) m.plot(orbit=earth, label="Obj") m.show() assert mock_iplot.call_count == 1 mock_prepare_plot.assert_called_once_with()
def test_set_frame_plots_same_colors(): op = plot_solar_system() jupiter = Orbit.from_body_ephem(Jupiter) op.plot(jupiter) colors1 = [orb[2] for orb in op._orbits] op.set_frame(*jupiter.pqw()) colors2 = [orb[2] for orb in op._orbits] assert colors1 == colors2
def test_show_calls_prepare_plot(plotter_class): with mock.patch.object(plotter_class, "_prepare_plot") as mock_prepare_plot: m = plotter_class() earth = Orbit.from_body_ephem(Earth) m.plot(orbit=earth, label="Object") m.show() mock_prepare_plot.assert_called_with()
def test_set_frame_plots_same_colors(): # TODO: Review op = StaticOrbitPlotter() jupiter = Orbit.from_body_ephem(Jupiter) op.plot(jupiter) colors1 = [orb[2] for orb in op.trajectories] op.set_frame(*jupiter.pqw()) colors2 = [orb[2] for orb in op.trajectories] assert colors1 == colors2
def test_savefig_calls_prepare_plot(mock_prepare_plot, mock_export): m = OrbitPlotter2D() earth = Orbit.from_body_ephem(Earth) m.plot(orbit=earth, label="Obj") with tempfile.NamedTemporaryFile() as fp: m.savefig(filename=fp.name + ".jpeg") assert mock_export.call_count == 1 mock_prepare_plot.assert_called_once_with()
def test_plot_trajectory_plots_a_trajectory(): frame = OrbitPlotter2D() assert len(frame._data) == 0 earth = Orbit.from_body_ephem(Earth) _, trajectory = earth.sample() frame.set_attractor(Sun) frame.plot_trajectory(trajectory) assert len(frame._data) == 1 assert frame._attractor == Sun
def test_plot_trajectory_plots_a_trajectory(): frame = OrbitPlotter2D() assert len(frame._data) == 0 earth = Orbit.from_body_ephem(Earth) trajectory = earth.sample() frame.set_attractor(Sun) frame.plot_trajectory(trajectory) assert len(frame._data) == 1 assert frame._attractor == Sun
def test_show_calls_prepare_plot(): patcher = mock.patch.object(OrbitPlotter3D, '_prepare_plot') patched = patcher.start() m = OrbitPlotter3D() earth = Orbit.from_body_ephem(Earth) m.plot(orbit=earth, label="Object") m.show() assert patched.call_count == 1 patched.assert_called_with()
def test_savefig_calls_prepare_plot(): patcher = mock.patch.object(OrbitPlotter2D, '_prepare_plot') patched = patcher.start() m = OrbitPlotter2D() earth = Orbit.from_body_ephem(Earth) m.plot(orbit=earth, label="Obj") m.savefig(filename="a.jpeg") assert patched.call_count == 1 patched.assert_called_with()
def test_savefig_calls_prepare_plot(mock_export, plotter_class): with mock.patch.object(plotter_class, "_prepare_plot") as mock_prepare_plot: m = plotter_class() earth = Orbit.from_body_ephem(Earth) m.plot(orbit=earth, label="Object") with tempfile.NamedTemporaryFile() as fp: m.savefig(filename=fp.name + ".jpeg") assert mock_export.call_count == 1 mock_prepare_plot.assert_called_with()
def test_plot_2d_trajectory_plots_a_trajectory(): frame = OrbitPlotter2D() assert len(frame.trajectories) == 0 earth = Orbit.from_body_ephem(Earth) trajectory = earth.sample() frame.set_attractor(Sun) frame.set_frame(*earth.pqw()) frame.plot_trajectory(trajectory) assert len(frame.trajectories) == 1 assert frame._attractor == Sun
def test_savefig_calls_prepare_plot(): patcher = mock.patch.object(OrbitPlotter3D, '_prepare_plot') patched = patcher.start() m = OrbitPlotter3D() earth = Orbit.from_body_ephem(Earth) m.plot(orbit=earth, label="Object") with tempfile.NamedTemporaryFile() as fp: m.savefig(filename=fp.name + ".jpeg") assert patched.call_count == 1 patched.assert_called_with()
def build_ephem_interpolant(body, period, t_span, rtol=1e-5): h = period * rtol t_values = np.linspace(t_span[0], t_span[1] + 0.01, int((t_span[1] - t_span[0]) / h)) r_values = np.zeros((t_values.shape[0], 3)) for i, t in enumerate(t_values): epoch = Time(t, format='jd', scale='tdb') body_t = Orbit.from_body_ephem(body, epoch) body_t = transform(body_t, ICRS, GCRS) r_values[i] = body_t.r t_values = ((t_values - t_span[0]) * u.day).to(u.s).value return interp1d(t_values, r_values, kind='cubic', axis=0, assume_sorted=True)
def test_orbit_from_ephem_is_in_icrs_frame(body): ss = Orbit.from_body_ephem(body) assert ss.frame.is_equivalent_frame(ICRS())
def test_from_ephem_raises_error_for_pluto_moon(body): with pytest.raises(RuntimeError) as excinfo: Orbit.from_body_ephem(body) assert "To compute the position and velocity" in excinfo.exconly()
def test_orbit_from_ephem_with_no_epoch_is_today(): # This is not that obvious http://stackoverflow.com/q/6407362/554319 body = Earth ss = Orbit.from_body_ephem(body) assert (Time.now() - ss.epoch).sec < 1
def plot_object(objectplo): obj = Orbit.from_body_ephem(objectplo) a = OrbitPlotter3D() a.plot(orbit=obj, label=str(objectplo)) return a.figure
def test_orbit_from_ephem_with_no_epoch_is_today(): # This is not that obvious http://stackoverflow.com/q/6407362/554319 body = Earth ss = Orbit.from_body_ephem(body) assert (Time.now() - ss.epoch).sec < 1
def test_orbit_from_ephem_is_in_icrs_frame(body): ss = Orbit.from_body_ephem(body) assert ss.frame.is_equivalent_frame(ICRS())
def test_from_ephem_raises_error_for_pluto_moon(body): with pytest.raises(RuntimeError) as excinfo: Orbit.from_body_ephem(body) assert "To compute the position and velocity" in excinfo.exconly()