コード例 #1
0
ファイル: test_solar_system.py プロジェクト: Cadair/astropy
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)
コード例 #2
0
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)
コード例 #3
0
ファイル: utils.py プロジェクト: Cadair/astropy
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
コード例 #4
0
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}")
コード例 #5
0
ファイル: utils.py プロジェクト: zkurtz/astropy
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
コード例 #6
0
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)
コード例 #7
0
ファイル: test_solar_system.py プロジェクト: Cadair/astropy
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)
コード例 #8
0
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
コード例 #9
0
ファイル: utils.py プロジェクト: MukendiMputu/Tic-Tac-Toe
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
コード例 #10
0
ファイル: test_solar_system.py プロジェクト: anpfeife/astropy
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)
コード例 #11
0
ファイル: test_solar_system.py プロジェクト: Cadair/astropy
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)
コード例 #12
0
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
コード例 #13
0
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
コード例 #14
0
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
コード例 #15
0
ファイル: barycen.py プロジェクト: janerigby/jrr
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
コード例 #16
0
ファイル: test_utils.py プロジェクト: Gabriel-p/astropy
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)
コード例 #17
0
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)
コード例 #18
0
ファイル: utils.py プロジェクト: MukendiMputu/Tic-Tac-Toe
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
コード例 #19
0
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)
コード例 #20
0
ファイル: sky_coordinate.py プロジェクト: bhazelton/lunarsky
    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)
コード例 #21
0
   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
コード例 #22
0
ファイル: test_solar_system.py プロジェクト: Cadair/astropy
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)