def test_barycentric_velocity_consistency(body, pos_tol, vel_tol): # Tolerances are about 1.5 times the rms listed for plan94 and epv00, # except for Mercury (which nominally is 334 km rms) t = Time('2016-03-20T12:30:00') ep, ev = get_body_barycentric_posvel(body, t, ephemeris='builtin') dp, dv = get_body_barycentric_posvel(body, t, ephemeris='de432s') assert_quantity_allclose(ep.xyz, dp.xyz, atol=pos_tol) assert_quantity_allclose(ev.xyz, dv.xyz, atol=vel_tol) # Might as well test it with a multidimensional array too. t = Time('2016-03-20T12:30:00') + np.arange(8.).reshape(2, 2, 2) * u.yr / 2. ep, ev = get_body_barycentric_posvel(body, t, ephemeris='builtin') dp, dv = get_body_barycentric_posvel(body, t, ephemeris='de432s') assert_quantity_allclose(ep.xyz, dp.xyz, atol=pos_tol) assert_quantity_allclose(ev.xyz, dv.xyz, atol=vel_tol)
def test_barycentric_velocity_consistency(body, pos_tol, vel_tol): # Tolerances are about 1.5 times the rms listed for plan94 and epv00, # except for Mercury (which nominally is 334 km rms) t = Time('2016-03-20T12:30:00') ep, ev = get_body_barycentric_posvel(body, t, ephemeris='builtin') dp, dv = get_body_barycentric_posvel(body, t, ephemeris='de432s') assert_quantity_allclose(ep.xyz, dp.xyz, atol=pos_tol) assert_quantity_allclose(ev.xyz, dv.xyz, atol=vel_tol) # Might as well test it with a multidimensional array too. t = Time('2016-03-20T12:30:00') + np.arange(8.).reshape(2, 2, 2) * u.yr / 2. ep, ev = get_body_barycentric_posvel(body, t, ephemeris='builtin') dp, dv = get_body_barycentric_posvel(body, t, ephemeris='de432s') assert_quantity_allclose(ep.xyz, dp.xyz, atol=pos_tol) assert_quantity_allclose(ev.xyz, dv.xyz, atol=vel_tol)
def prepare_earth_position_vel(time): """ Get barycentric position and velocity, and heliocentric position of Earth Parameters ----------- time : `~astropy.time.Time` time at which to calculate position and velocity of Earth Returns -------- earth_pv : `np.ndarray` Barycentric position and velocity of Earth, in au and au/day earth_helio : `np.ndarray` Heliocentric position of Earth in au """ # this goes here to avoid circular import errors from astropy.coordinates.solar_system import (get_body_barycentric, get_body_barycentric_posvel) # get barycentric position and velocity of earth earth_p, earth_v = get_body_barycentric_posvel('earth', time) # get heliocentric position of earth, preparing it for passing to erfa. sun = get_body_barycentric('sun', time) earth_heliocentric = (earth_p - sun).get_xyz(xyz_axis=-1).to_value(u.au) # Also prepare earth_pv for passing to erfa, which wants it as # a structured dtype. earth_pv = erfa.pav2pv( earth_p.get_xyz(xyz_axis=-1).to_value(u.au), earth_v.get_xyz(xyz_axis=-1).to_value(u.au/u.d)) return earth_pv, earth_heliocentric
def print_planet_position(name, observer, time): """ Print information about the planets position Parameters ---------- name : str String name of planet (e.g. 'mercury' or 'jupiter') observer : astropy.coordinates.EarthLocation Observer object time : astropy.time.Time Time of the observation """ # Compute the observed coordinates of the object planet = solar_system.get_body(body=name, time=time) aa = AltAz(location=observer, obstime=time) obs = planet.transform_to(aa) icrs = planet.transform_to('icrs') cirs = planet.transform_to('cirs') # Compute the position/velocity of the object pos, vel = solar_system.get_body_barycentric_posvel(body=name, time=time) print( f"{name:8}: obs=({obs.az:20.16f},{obs.zen:20.16f}) | icrs=({icrs.ra:20.16f},{icrs.dec:20.16f})" ) print(f" cirs=({cirs.ra:20.16f},{cirs.dec:20.16f})") print(f" pos={pos}, vel={vel}")
def prepare_earth_position_vel(time): """ Get barycentric position and velocity, and heliocentric position of Earth Parameters ----------- time : `~astropy.time.Time` time at which to calculate position and velocity of Earth Returns -------- earth_pv : `np.ndarray` Barycentric position and velocity of Earth, in au and au/day earth_helio : `np.ndarray` Heliocentric position of Earth in au """ # this goes here to avoid circular import errors from astropy.coordinates.solar_system import (get_body_barycentric, get_body_barycentric_posvel) # get barycentric position and velocity of earth earth_p, earth_v = get_body_barycentric_posvel('earth', time) # get heliocentric position of earth, preparing it for passing to erfa. sun = get_body_barycentric('sun', time) earth_heliocentric = (earth_p - sun).get_xyz(xyz_axis=-1).to_value(u.au) # Also prepare earth_pv for passing to erfa, which wants it as # a structured dtype. earth_pv = erfa.pav2pv( earth_p.get_xyz(xyz_axis=-1).to_value(u.au), earth_v.get_xyz(xyz_axis=-1).to_value(u.au / u.d)) return earth_pv, earth_heliocentric
def test_earth_barycentric_velocity_rough(): # Check that a time near the equinox gives roughly the right result. ep, ev = get_body_barycentric_posvel('earth', Time('2016-03-20T12:30:00')) assert_quantity_allclose(ep.xyz, [-1., 0., 0.] * u.AU, atol=0.01 * u.AU) expected = u.Quantity( [0. * u.one, np.cos(23.5 * u.deg), np.sin(23.5 * u.deg)]) * -30. * u.km / u.s assert_quantity_allclose(ev.xyz, expected, atol=1. * u.km / u.s)
def test_earth_barycentric_velocity_rough(): # Check that a time near the equinox gives roughly the right result. ep, ev = get_body_barycentric_posvel('earth', Time('2016-03-20T12:30:00')) assert_quantity_allclose(ep.xyz, [-1., 0., 0.]*u.AU, atol=0.01*u.AU) expected = u.Quantity([0.*u.one, np.cos(23.5*u.deg), np.sin(23.5*u.deg)]) * -30. * u.km / u.s assert_quantity_allclose(ev.xyz, expected, atol=1.*u.km/u.s)
def geomotion_velocity(time, skycoord, frame="heliocentric"): """ Perform a barycentric/heliocentric velocity correction. For the correciton, this routine uses the ephemeris: astropy.coordinates.solar_system_ephemeris.set For more information see `~astropy.coordinates.solar_system_ephemeris`. Parameters ---------- time : astropy.time.Time The time of observation, including the location. skycoord: astropy.coordinates.SkyCoord The RA and DEC of the pointing, as a SkyCoord quantity. frame : str The reference frame that should be used for the calculation. Returns ------- vcorr : float The velocity correction that should be added to the original velocity. """ # Check that the RA/DEC of the object is ICRS compatible if not skycoord.is_transformable_to(ICRS()): msgs.error("Cannot transform RA/DEC of object to the ICRS") # Calculate ICRS position and velocity of Earth's geocenter ep, ev = solar_system.get_body_barycentric_posvel('earth', time) # Calculate GCRS position and velocity of observatory op, ov = time.location.get_gcrs_posvel(time) # ICRS and GCRS are axes-aligned. Can add the velocities velocity = ev + ov if frame == "heliocentric": # ICRS position and velocity of the Sun sp, sv = solar_system.get_body_barycentric_posvel('sun', time) velocity += sv # Get unit ICRS vector in direction of SkyCoord sc_cartesian = skycoord.icrs.represent_as( UnitSphericalRepresentation).represent_as(CartesianRepresentation) return sc_cartesian.dot(velocity).to(units.km / units.s).value
def prepare_earth_position_vel(time): """ Get barycentric position and velocity, and heliocentric position of Earth Parameters ----------- time : `~astropy.time.Time` time at which to calculate position and velocity of Earth Returns -------- earth_pv : `np.ndarray` Barycentric position and velocity of Earth, in au and au/day earth_helio : `np.ndarray` Heliocentric position of Earth in au """ # this goes here to avoid circular import errors from astropy.coordinates.solar_system import ( get_body_barycentric, get_body_barycentric_posvel, solar_system_ephemeris, ) # get barycentric position and velocity of earth ephemeris = solar_system_ephemeris.get() # if we are using the builtin erfa based ephemeris, # we can use the fact that epv00 already provides all we need. # This avoids calling epv00 twice, once # in get_body_barycentric_posvel('earth') and once in # get_body_barycentric('sun') if ephemeris == 'builtin': jd1, jd2 = get_jd12(time, 'tdb') earth_pv_heliocentric, earth_pv = erfa.epv00(jd1, jd2) earth_heliocentric = earth_pv_heliocentric['p'] # all other ephemeris providers probably don't have a shortcut like this else: earth_p, earth_v = get_body_barycentric_posvel('earth', time) # get heliocentric position of earth, preparing it for passing to erfa. sun = get_body_barycentric('sun', time) earth_heliocentric = (earth_p - sun).get_xyz(xyz_axis=-1).to_value( u.au) # Also prepare earth_pv for passing to erfa, which wants it as # a structured dtype. earth_pv = pav2pv( earth_p.get_xyz(xyz_axis=-1).to_value(u.au), earth_v.get_xyz(xyz_axis=-1).to_value(u.au / u.d)) return earth_pv, earth_heliocentric
def test_earth_barycentric_velocity_multi_d(): # Might as well test it with a multidimensional array too. t = Time('2016-03-20T12:30:00') + np.arange(8.).reshape(2, 2, 2) * u.yr / 2. ep, ev = get_body_barycentric_posvel('earth', t) # note: assert_quantity_allclose doesn't like the shape mismatch. # this is a problem with np.testing.assert_allclose. assert quantity_allclose(ep.get_xyz(xyz_axis=-1), [[-1., 0., 0.], [+1., 0., 0.]]*u.AU, atol=0.06*u.AU) expected = u.Quantity([0.*u.one, np.cos(23.5*u.deg), np.sin(23.5*u.deg)]) * ([[-30.], [30.]] * u.km / u.s) assert quantity_allclose(ev.get_xyz(xyz_axis=-1), expected, atol=2.*u.km/u.s)
def test_earth_barycentric_velocity_multi_d(): # Might as well test it with a multidimensional array too. t = Time('2016-03-20T12:30:00') + np.arange(8.).reshape(2, 2, 2) * u.yr / 2. ep, ev = get_body_barycentric_posvel('earth', t) # note: assert_quantity_allclose doesn't like the shape mismatch. # this is a problem with np.testing.assert_allclose. assert quantity_allclose(ep.get_xyz(xyz_axis=-1), [[-1., 0., 0.], [+1., 0., 0.]]*u.AU, atol=0.06*u.AU) expected = u.Quantity([0.*u.one, np.cos(23.5*u.deg), np.sin(23.5*u.deg)]) * ([[-30.], [30.]] * u.km / u.s) assert quantity_allclose(ev.get_xyz(xyz_axis=-1), expected, atol=2.*u.km/u.s)
def compute_barycentric_correction(mytime, skycoord, location=None): """Barycentric velocity correction. was named 'velcorr' Should return barycentric correction factor, in km/s, same sign convention as in jskycalc Uses the ephemeris set with ``astropy.coordinates.solar_system_ephemeris.set`` for corrections. For more information see `~astropy.coordinates.solar_system_ephemeris`. Parameters ---------- mytime : `~astropy.time.Time` The time of observation. skycoord: `~astropy.coordinates.SkyCoord` The sky location to calculate the correction for. location: `~astropy.coordinates.EarthLocation`, optional The location of the observatory to calculate the correction for. If no location is given, the ``location`` attribute of the Time object is used Returns ------- vel_corr : `~astropy.units.Quantity` The velocity correction to convert to Barycentric velocities. Should be added to the original velocity. """ if location is None: if mytime.location is None: raise ValueError('An EarthLocation needs to be set or passed ' 'in to calculate bary- or heliocentric ' 'corrections') location = mytime.location # ensure sky location is ICRS compatible if not skycoord.is_transformable_to(ICRS()): raise ValueError("Given skycoord is not transformable to the ICRS") ep, ev = solar_system.get_body_barycentric_posvel( 'earth', mytime) # ICRS position and velocity of Earth's geocenter op, ov = location.get_gcrs_posvel( mytime) # GCRS position and velocity of observatory # ICRS and GCRS are axes-aligned. Can add the velocities velocity = ev + ov # relies on PR5434 being merged # get unit ICRS vector in direction of SkyCoord sc_cartesian = skycoord.represent_as( coordinates.UnitSphericalRepresentation).represent_as( coordinates.CartesianRepresentation) return sc_cartesian.dot(velocity).to(u.km / u.s) # similarly requires PR5434
def icrs_to_hcrs(icrs_coo, hcrs_frame): # this is just an origin translation so without a distance it cannot go ahead if isinstance(icrs_coo.data, UnitSphericalRepresentation): raise u.UnitsError(_NEED_ORIGIN_HINT.format(icrs_coo.__class__.__name__)) if icrs_coo.data.differentials: from astropy.coordinates.solar_system import get_body_barycentric_posvel bary_sun_pos, bary_sun_vel = get_body_barycentric_posvel('sun', hcrs_frame.obstime) bary_sun_pos = -bary_sun_pos.with_differentials(-bary_sun_vel) else: from astropy.coordinates.solar_system import get_body_barycentric bary_sun_pos = -get_body_barycentric('sun', hcrs_frame.obstime) bary_sun_vel = None return None, bary_sun_pos
def hcrs_to_icrs(hcrs_coo, icrs_frame): # this is just an origin translation so without a distance it cannot go ahead if isinstance(hcrs_coo.data, UnitSphericalRepresentation): raise u.UnitsError(_NEED_ORIGIN_HINT.format(hcrs_coo.__class__.__name__)) if hcrs_coo.data.differentials: from astropy.coordinates.solar_system import get_body_barycentric_posvel bary_sun_pos, bary_sun_vel = get_body_barycentric_posvel('sun', hcrs_coo.obstime) bary_sun_vel = bary_sun_vel.represent_as(CartesianDifferential) bary_sun_pos = bary_sun_pos.with_differentials(bary_sun_vel) else: from astropy.coordinates.solar_system import get_body_barycentric bary_sun_pos = get_body_barycentric('sun', hcrs_coo.obstime) bary_sun_vel = None return None, bary_sun_pos
def compute_barycentric_correction(mytime, skycoord, location=None): """Barycentric velocity correction. was named 'velcorr' Should return barycentric correction factor, in km/s, same sign convention as in jskycalc Uses the ephemeris set with ``astropy.coordinates.solar_system_ephemeris.set`` for corrections. For more information see `~astropy.coordinates.solar_system_ephemeris`. Parameters ---------- mytime : `~astropy.time.Time` The time of observation. skycoord: `~astropy.coordinates.SkyCoord` The sky location to calculate the correction for. location: `~astropy.coordinates.EarthLocation`, optional The location of the observatory to calculate the correction for. If no location is given, the ``location`` attribute of the Time object is used Returns ------- vel_corr : `~astropy.units.Quantity` The velocity correction to convert to Barycentric velocities. Should be added to the original velocity. """ if location is None: if mytime.location is None: raise ValueError('An EarthLocation needs to be set or passed ' 'in to calculate bary- or heliocentric ' 'corrections') location = mytime.location # ensure sky location is ICRS compatible if not skycoord.is_transformable_to(ICRS()): raise ValueError("Given skycoord is not transformable to the ICRS") ep, ev = solar_system.get_body_barycentric_posvel('earth', mytime) # ICRS position and velocity of Earth's geocenter op, ov = location.get_gcrs_posvel(mytime) # GCRS position and velocity of observatory # ICRS and GCRS are axes-aligned. Can add the velocities velocity = ev + ov # relies on PR5434 being merged # get unit ICRS vector in direction of SkyCoord sc_cartesian = skycoord.represent_as(coordinates.UnitSphericalRepresentation).represent_as(coordinates.CartesianRepresentation) return sc_cartesian.dot(velocity).to(u.km/u.s) # similarly requires PR5434
def test_sun_from_barycenter_offset(): time = Time('2020-01-01') pos, vel = get_body_barycentric_posvel('sun', time) offset = get_offset_sun_from_barycenter(time) assert_quantity_allclose(offset.xyz, pos.xyz) assert not bool(offset.differentials) offset_with_vel = get_offset_sun_from_barycenter(time, include_velocity=True) assert_quantity_allclose(offset_with_vel.xyz, pos.xyz) assert_quantity_allclose(offset_with_vel.differentials['s'].d_xyz, vel.xyz) reverse = get_offset_sun_from_barycenter(time, reverse=True) assert_quantity_allclose(reverse.xyz, -pos.xyz) assert not bool(reverse.differentials) reverse_with_vel = get_offset_sun_from_barycenter(time, reverse=True, include_velocity=True) assert_quantity_allclose(reverse_with_vel.xyz, -pos.xyz) assert_quantity_allclose(reverse_with_vel.differentials['s'].d_xyz, -vel.xyz)
def test_helioecliptic_induced_velocity(frame): # Create a coordinate with zero speed in ICRS time = Time('2021-01-01') icrs = ICRS(ra=1 * u.deg, dec=2 * u.deg, distance=3 * u.AU, pm_ra_cosdec=0 * u.deg / u.s, pm_dec=0 * u.deg / u.s, radial_velocity=0 * u.m / u.s) # Transforming to a helioecliptic frame should give an induced speed equal to the Sun's speed transformed = icrs.transform_to(frame(obstime=time)) _, vel = get_body_barycentric_posvel('sun', time) assert quantity_allclose(transformed.velocity.norm(), vel.norm()) # Transforming back to ICRS should get back to zero speed back = transformed.transform_to(ICRS()) assert quantity_allclose(back.velocity.norm(), 0 * u.m / u.s, atol=1e-10 * u.m / u.s)
def get_offset_sun_from_barycenter(time, include_velocity=False, reverse=False): """ Returns the offset of the Sun center from the solar-system barycenter (SSB). Parameters ---------- time : `~astropy.time.Time` Time at which to calculate the offset include_velocity : `bool` If ``True``, attach the velocity as a differential. Defaults to ``False``. reverse : `bool` If ``True``, return the offset of the barycenter from the Sun. Defaults to ``False``. Returns ------- `~astropy.coordinates.CartesianRepresentation` The offset """ if include_velocity: # Import here to avoid a circular import from astropy.coordinates.solar_system import get_body_barycentric_posvel offset_pos, offset_vel = get_body_barycentric_posvel('sun', time) if reverse: offset_pos, offset_vel = -offset_pos, -offset_vel offset_vel = offset_vel.represent_as(CartesianDifferential) offset_pos = offset_pos.with_differentials(offset_vel) else: # Import here to avoid a circular import from astropy.coordinates.solar_system import get_body_barycentric offset_pos = get_body_barycentric('sun', time) if reverse: offset_pos = -offset_pos return offset_pos
def test_barycentric_pos_posvel_same(): # Check that the two routines give identical results. ep1 = get_body_barycentric('earth', Time('2016-03-20T12:30:00')) ep2, _ = get_body_barycentric_posvel('earth', Time('2016-03-20T12:30:00')) assert np.all(ep1.xyz == ep2.xyz)
def radial_velocity_correction(self, kind='barycentric', obstime=None, location=None): # Need to copy location parsing syntax first. # location validation timeloc = getattr(obstime, 'location', None) if location is None: if self.location is not None: location = self.location if timeloc is not None: raise ValueError('`location` cannot be in both the ' 'passed-in `obstime` and this `SkyCoord` ' 'because it is ambiguous which is meant ' 'for the radial_velocity_correction.') elif timeloc is not None: location = timeloc else: raise TypeError('Must provide a `location` to ' 'radial_velocity_correction, either as a ' 'SkyCoord frame attribute, as an attribute on ' 'the passed in `obstime`, or in the method ' 'call.') elif self.location is not None or timeloc is not None: raise ValueError('Cannot compute radial velocity correction if ' '`location` argument is passed in and there is ' 'also a `location` attribute on this SkyCoord or ' 'the passed-in `obstime`.') # Use parent method if given an EarthLocation if isinstance(location, EarthLocation): return super().radial_velocity_correction(kind=kind, obstime=obstime, location=location) from astropy.coordinates.solar_system import get_body_barycentric_posvel from astropy.coordinates import solar_system_ephemeris solar_system_ephemeris.set('jpl') # With a MoonLocation: # Get ICRS (barycentric) cartesian position and velocity of the Earth pos_moon, v_moon = get_body_barycentric_posvel('moon', obstime) if kind == 'barycentric': v_origin_to_moon = v_moon elif kind == 'heliocentric': v_sun = get_body_barycentric_posvel('sun', obstime)[1] v_origin_to_moon = v_moon - v_sun else: raise ValueError("`kind` argument to radial_velocity_correction must " "be 'barycentric' or 'heliocentric', but got " "'{}'".format(kind)) mcmf_p, mcmf_v = location.get_mcmf_posvel(obstime) # transforming to GCRS is not the correct thing to do here, since we don't want to # include aberration (or light deflection)? Instead, only apply parallax if necessary if self.data.__class__ is UnitSphericalRepresentation: targcart = self.mcmf.cartesian else: # skycoord has distances so apply parallax obs_mcmf_cart = pos_moon + mcmf_p mcmf_cart = self.mcmf.cartesian targcart = mcmf_cart - obs_mcmf_cart targcart /= targcart.norm() if kind == 'barycentric': beta_obs = (v_origin_to_moon + mcmf_v) / speed_of_light gamma_obs = 1 / sqrt(1 - beta_obs.norm()**2) gr = location.gravitational_redshift(obstime) # barycentric redshift according to eq 28 in Wright & Eastmann (2014), # neglecting Shapiro delay and effects of the star's own motion zb = gamma_obs * (1 + targcart.dot(beta_obs)) / (1 + gr / speed_of_light) - 1 return zb * speed_of_light else: # do a simpler correction ignoring time dilation and gravitational redshift # this is adequate since Heliocentric corrections shouldn't be used if # cm/s precision is required. return targcart.dot(v_origin_to_moon + mcmf_v)
def barycentric_correction(self, time=None, skycoord=None, location=None): """ Barycentric velocity correction, code from StuartLittlefair (https://gist.github.com/StuartLittlefair/5aaf476c5d7b52d20aa9544cfaa936a1) Uses the ephemeris set with ``astropy.coordinates.solar_system_ephemeris.set`` for corrections. For more information see `~astropy.coordinates.solar_system_ephemeris`. Will attempt to get the necessary info from the header if possible, otherwise requires time, skycoord, and location parameters to be set. Parameters ---------- time : `~astropy.time.Time` The time of observation, optional skycoord: `~astropy.coordinates.SkyCoord` The sky location to calculate the correction for, optional. location: `~astropy.coordinates.EarthLocation`, optional The location of the observatory to calculate the correction for. Returns ------- barycentric_velocity : `~astropy.units.Quantity` The velocity correction that was added to the wavelength arrays of each order. """ if self.time is not None: time = self.time else: assert time is not None, "Please provide a time." if self.header is not None: header = self.header if ('RA' in header) & ('DEC' in header) & ('EQUINOX' in header): if 'RADECSYS' in header: #assumes ICRS if not specified frame=header['RADECSYS'].lower() else: frame='icrs' skycoord = SkyCoord(header['RA'], header['DEC'], unit=(u.hourangle, u.deg), frame=frame, equinox=Time(header['EQUINOX'],format='jyear')) elif skycoord is None: raise KeyError("Either set 'RA', 'DEC','RADECSYS', 'EQUINOX' header keywords or provide a location") if 'OBSERVAT' in header: location = EarthLocation.of_site(header['OBSERVAT']) elif 'SITENAME' in header: location = EarthLocation.of_site(header['SITENAME']) elif location is None: raise KeyError("Either set 'OBSERVAT' header keyword or provide a location") else: assert (skycoord is not None) & (location is not None), "You need to manually provide object coordinates and observatory location." ep, ev = solar_system.get_body_barycentric_posvel('earth', time) # ICRS position and velocity of Earth's geocenter op, ov = location.get_gcrs_posvel(time) # GCRS position and velocity of observatory velocity = ev + ov # ICRS and GCRS are axes-aligned. Can add the velocities. sc_cartesian = skycoord.icrs.represent_as(UnitSphericalRepresentation).represent_as(CartesianRepresentation) #Put skycoord in same frame as velocity so we can get velocity component towards object barycentric_velocity = sc_cartesian.dot(velocity).to(u.km/u.s) #Velocity of earth, to be added directly to wavelength. So + should result in a redshift redshift = barycentric_velocity/c.c for spectrum in self.spectrum_list: spectrum.wavelength *= (1.0 + redshift) return barycentric_velocity
def test_barycentric_pos_posvel_same(): # Check that the two routines give identical results. ep1 = get_body_barycentric('earth', Time('2016-03-20T12:30:00')) ep2, _ = get_body_barycentric_posvel('earth', Time('2016-03-20T12:30:00')) assert np.all(ep1.xyz == ep2.xyz)