Пример #1
0
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
Пример #2
0
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
Пример #3
0
def icrs_to_gcrs(icrs_coo, gcrs_frame):
    # first set up the astrometry context for ICRS<->GCRS. There are a few steps...
    # get the position and velocity arrays for the observatory.  Need to
    # have xyz in last dimension, and pos/vel in one-but-last.
    # (Note could use np.stack once our minimum numpy version is >=1.10.)
    obs_pv = erfa.pav2pv(
        gcrs_frame.obsgeoloc.get_xyz(xyz_axis=-1).to_value(u.m),
        gcrs_frame.obsgeovel.get_xyz(xyz_axis=-1).to_value(u.m / u.s))

    # find the position and velocity of earth
    jd1, jd2 = get_jd12(gcrs_frame.obstime, 'tdb')
    earth_pv, earth_heliocentric = prepare_earth_position_vel(
        gcrs_frame.obstime)

    # get astrometry context object, astrom.
    astrom = erfa.apcs(jd1, jd2, obs_pv, earth_pv, earth_heliocentric)

    if icrs_coo.data.get_name(
    ) == 'unitspherical' or icrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just do the infinite-distance/no parallax calculation
        usrepr = icrs_coo.represent_as(UnitSphericalRepresentation)
        i_ra = usrepr.lon.to_value(u.radian)
        i_dec = usrepr.lat.to_value(u.radian)
        gcrs_ra, gcrs_dec = atciqz(i_ra, i_dec, astrom)

        newrep = UnitSphericalRepresentation(lat=u.Quantity(gcrs_dec,
                                                            u.radian,
                                                            copy=False),
                                             lon=u.Quantity(gcrs_ra,
                                                            u.radian,
                                                            copy=False),
                                             copy=False)
    else:
        # When there is a distance,  we first offset for parallax to get the
        # BCRS coordinate direction and *then* run the ERFA transform for no
        # parallax/PM. This ensures reversibility and is more sensible for
        # inside solar system objects
        astrom_eb = CartesianRepresentation(astrom['eb'],
                                            unit=u.au,
                                            xyz_axis=-1,
                                            copy=False)
        newcart = icrs_coo.cartesian - astrom_eb

        srepr = newcart.represent_as(SphericalRepresentation)
        i_ra = srepr.lon.to_value(u.radian)
        i_dec = srepr.lat.to_value(u.radian)
        gcrs_ra, gcrs_dec = atciqz(i_ra, i_dec, astrom)

        newrep = SphericalRepresentation(lat=u.Quantity(gcrs_dec,
                                                        u.radian,
                                                        copy=False),
                                         lon=u.Quantity(gcrs_ra,
                                                        u.radian,
                                                        copy=False),
                                         distance=srepr.distance,
                                         copy=False)

    return gcrs_frame.realize_frame(newrep)
Пример #4
0
def gcrs_to_hcrs(gcrs_coo, hcrs_frame):

    if np.any(gcrs_coo.obstime != hcrs_frame.obstime):
        # if they GCRS obstime and HCRS obstime are not the same, we first
        # have to move to a GCRS where they are.
        frameattrs = gcrs_coo.get_frame_attr_names()
        frameattrs['obstime'] = hcrs_frame.obstime
        gcrs_coo = gcrs_coo.transform_to(GCRS(**frameattrs))

    srepr = gcrs_coo.represent_as(SphericalRepresentation)
    gcrs_ra = srepr.lon.to_value(u.radian)
    gcrs_dec = srepr.lat.to_value(u.radian)

    # set up the astrometry context for ICRS<->GCRS and then convert to ICRS
    # coordinate direction
    obs_pv = erfa.pav2pv(
        gcrs_coo.obsgeoloc.get_xyz(xyz_axis=-1).to_value(u.m),
        gcrs_coo.obsgeovel.get_xyz(xyz_axis=-1).to_value(u.m / u.s))

    jd1, jd2 = get_jd12(hcrs_frame.obstime, 'tdb')
    earth_pv, earth_heliocentric = prepare_earth_position_vel(gcrs_coo.obstime)
    astrom = erfa.apcs(jd1, jd2, obs_pv, earth_pv, earth_heliocentric)

    i_ra, i_dec = aticq(gcrs_ra, gcrs_dec, astrom)

    # convert to Quantity objects
    i_ra = u.Quantity(i_ra, u.radian, copy=False)
    i_dec = u.Quantity(i_dec, u.radian, copy=False)
    if gcrs_coo.data.get_name(
    ) == 'unitspherical' or gcrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just use the coordinate direction to yield the
        # infinite-distance/no parallax answer
        newrep = UnitSphericalRepresentation(lat=i_dec, lon=i_ra, copy=False)
    else:
        # When there is a distance, apply the parallax/offset to the
        # Heliocentre as the last step to ensure round-tripping with the
        # hcrs_to_gcrs transform

        # Note that the distance in intermedrep is *not* a real distance as it
        # does not include the offset back to the Heliocentre
        intermedrep = SphericalRepresentation(lat=i_dec,
                                              lon=i_ra,
                                              distance=srepr.distance,
                                              copy=False)

        # astrom['eh'] and astrom['em'] contain Sun to observer unit vector,
        # and distance, respectively. Shapes are (X) and (X,3), where (X) is the
        # shape resulting from broadcasting the shape of the times object
        # against the shape of the pv array.
        # broadcast em to eh and scale eh
        eh = astrom['eh'] * astrom['em'][..., np.newaxis]
        eh = CartesianRepresentation(eh, unit=u.au, xyz_axis=-1, copy=False)

        newrep = intermedrep.to_cartesian() + eh

    return hcrs_frame.realize_frame(newrep)
Пример #5
0
def gcrs_to_hcrs(gcrs_coo, hcrs_frame):

    if np.any(gcrs_coo.obstime != hcrs_frame.obstime):
        # if they GCRS obstime and HCRS obstime are not the same, we first
        # have to move to a GCRS where they are.
        frameattrs = gcrs_coo.get_frame_attr_names()
        frameattrs['obstime'] = hcrs_frame.obstime
        gcrs_coo = gcrs_coo.transform_to(GCRS(**frameattrs))

    srepr = gcrs_coo.represent_as(SphericalRepresentation)
    gcrs_ra = srepr.lon.to_value(u.radian)
    gcrs_dec = srepr.lat.to_value(u.radian)

    # set up the astrometry context for ICRS<->GCRS and then convert to ICRS
    # coordinate direction
    obs_pv = erfa.pav2pv(
        gcrs_coo.obsgeoloc.get_xyz(xyz_axis=-1).to_value(u.m),
        gcrs_coo.obsgeovel.get_xyz(xyz_axis=-1).to_value(u.m/u.s))

    jd1, jd2 = get_jd12(hcrs_frame.obstime, 'tdb')
    earth_pv, earth_heliocentric = prepare_earth_position_vel(gcrs_coo.obstime)
    astrom = erfa.apcs(jd1, jd2, obs_pv, earth_pv, earth_heliocentric)

    i_ra, i_dec = aticq(gcrs_ra, gcrs_dec, astrom)

    # convert to Quantity objects
    i_ra = u.Quantity(i_ra, u.radian, copy=False)
    i_dec = u.Quantity(i_dec, u.radian, copy=False)
    if gcrs_coo.data.get_name() == 'unitspherical' or gcrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just use the coordinate direction to yield the
        # infinite-distance/no parallax answer
        newrep = UnitSphericalRepresentation(lat=i_dec, lon=i_ra, copy=False)
    else:
        # When there is a distance, apply the parallax/offset to the
        # Heliocentre as the last step to ensure round-tripping with the
        # hcrs_to_gcrs transform

        # Note that the distance in intermedrep is *not* a real distance as it
        # does not include the offset back to the Heliocentre
        intermedrep = SphericalRepresentation(lat=i_dec, lon=i_ra,
                                              distance=srepr.distance,
                                              copy=False)

        # astrom['eh'] and astrom['em'] contain Sun to observer unit vector,
        # and distance, respectively. Shapes are (X) and (X,3), where (X) is the
        # shape resulting from broadcasting the shape of the times object
        # against the shape of the pv array.
        # broadcast em to eh and scale eh
        eh = astrom['eh'] * astrom['em'][..., np.newaxis]
        eh = CartesianRepresentation(eh, unit=u.au, xyz_axis=-1, copy=False)

        newrep = intermedrep.to_cartesian() + eh

    return hcrs_frame.realize_frame(newrep)
Пример #6
0
def gcrs_to_icrs(gcrs_coo, icrs_frame):
    srepr = gcrs_coo.represent_as(SphericalRepresentation)
    gcrs_ra = srepr.lon.to_value(u.radian)
    gcrs_dec = srepr.lat.to_value(u.radian)

    # set up the astrometry context for ICRS<->GCRS and then convert to BCRS
    # coordinate direction
    obs_pv = erfa.pav2pv(
        gcrs_coo.obsgeoloc.get_xyz(xyz_axis=-1).to_value(u.m),
        gcrs_coo.obsgeovel.get_xyz(xyz_axis=-1).to_value(u.m / u.s))

    jd1, jd2 = get_jd12(gcrs_coo.obstime, 'tdb')

    earth_pv, earth_heliocentric = prepare_earth_position_vel(gcrs_coo.obstime)
    astrom = erfa.apcs(jd1, jd2, obs_pv, earth_pv, earth_heliocentric)

    i_ra, i_dec = aticq(gcrs_ra, gcrs_dec, astrom)

    if gcrs_coo.data.get_name(
    ) == 'unitspherical' or gcrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just use the coordinate direction to yield the
        # infinite-distance/no parallax answer
        newrep = UnitSphericalRepresentation(lat=u.Quantity(i_dec,
                                                            u.radian,
                                                            copy=False),
                                             lon=u.Quantity(i_ra,
                                                            u.radian,
                                                            copy=False),
                                             copy=False)
    else:
        # When there is a distance, apply the parallax/offset to the SSB as the
        # last step - ensures round-tripping with the icrs_to_gcrs transform

        # the distance in intermedrep is *not* a real distance as it does not
        # include the offset back to the SSB
        intermedrep = SphericalRepresentation(lat=u.Quantity(i_dec,
                                                             u.radian,
                                                             copy=False),
                                              lon=u.Quantity(i_ra,
                                                             u.radian,
                                                             copy=False),
                                              distance=srepr.distance,
                                              copy=False)

        astrom_eb = CartesianRepresentation(astrom['eb'],
                                            unit=u.au,
                                            xyz_axis=-1,
                                            copy=False)
        newrep = intermedrep + astrom_eb

    return icrs_frame.realize_frame(newrep)
Пример #7
0
def icrs_to_gcrs(icrs_coo, gcrs_frame):
    # first set up the astrometry context for ICRS<->GCRS. There are a few steps...
    # get the position and velocity arrays for the observatory.  Need to
    # have xyz in last dimension, and pos/vel in one-but-last.
    # (Note could use np.stack once our minimum numpy version is >=1.10.)
    obs_pv = erfa.pav2pv(
        gcrs_frame.obsgeoloc.get_xyz(xyz_axis=-1).to_value(u.m),
        gcrs_frame.obsgeovel.get_xyz(xyz_axis=-1).to_value(u.m/u.s))

    # find the position and velocity of earth
    jd1, jd2 = get_jd12(gcrs_frame.obstime, 'tdb')
    earth_pv, earth_heliocentric = prepare_earth_position_vel(gcrs_frame.obstime)

    # get astrometry context object, astrom.
    astrom = erfa.apcs(jd1, jd2, obs_pv, earth_pv, earth_heliocentric)

    if icrs_coo.data.get_name() == 'unitspherical' or icrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just do the infinite-distance/no parallax calculation
        usrepr = icrs_coo.represent_as(UnitSphericalRepresentation)
        i_ra = usrepr.lon.to_value(u.radian)
        i_dec = usrepr.lat.to_value(u.radian)
        gcrs_ra, gcrs_dec = atciqz(i_ra, i_dec, astrom)

        newrep = UnitSphericalRepresentation(lat=u.Quantity(gcrs_dec, u.radian, copy=False),
                                             lon=u.Quantity(gcrs_ra, u.radian, copy=False),
                                             copy=False)
    else:
        # When there is a distance,  we first offset for parallax to get the
        # BCRS coordinate direction and *then* run the ERFA transform for no
        # parallax/PM. This ensures reversibility and is more sensible for
        # inside solar system objects
        astrom_eb = CartesianRepresentation(astrom['eb'], unit=u.au,
                                            xyz_axis=-1, copy=False)
        newcart = icrs_coo.cartesian - astrom_eb

        srepr = newcart.represent_as(SphericalRepresentation)
        i_ra = srepr.lon.to_value(u.radian)
        i_dec = srepr.lat.to_value(u.radian)
        gcrs_ra, gcrs_dec = atciqz(i_ra, i_dec, astrom)

        newrep = SphericalRepresentation(lat=u.Quantity(gcrs_dec, u.radian, copy=False),
                                         lon=u.Quantity(gcrs_ra, u.radian, copy=False),
                                         distance=srepr.distance, copy=False)

    return gcrs_frame.realize_frame(newrep)
Пример #8
0
def gcrs_to_icrs(gcrs_coo, icrs_frame):
    srepr = gcrs_coo.represent_as(SphericalRepresentation)
    gcrs_ra = srepr.lon.to_value(u.radian)
    gcrs_dec = srepr.lat.to_value(u.radian)

    # set up the astrometry context for ICRS<->GCRS and then convert to BCRS
    # coordinate direction
    obs_pv = erfa.pav2pv(
        gcrs_coo.obsgeoloc.get_xyz(xyz_axis=-1).to_value(u.m),
        gcrs_coo.obsgeovel.get_xyz(xyz_axis=-1).to_value(u.m/u.s))

    jd1, jd2 = get_jd12(gcrs_coo.obstime, 'tdb')

    earth_pv, earth_heliocentric = prepare_earth_position_vel(gcrs_coo.obstime)
    astrom = erfa.apcs(jd1, jd2, obs_pv, earth_pv, earth_heliocentric)

    i_ra, i_dec = aticq(gcrs_ra, gcrs_dec, astrom)

    if gcrs_coo.data.get_name() == 'unitspherical' or gcrs_coo.data.to_cartesian().x.unit == u.one:
        # if no distance, just use the coordinate direction to yield the
        # infinite-distance/no parallax answer
        newrep = UnitSphericalRepresentation(lat=u.Quantity(i_dec, u.radian, copy=False),
                                             lon=u.Quantity(i_ra, u.radian, copy=False),
                                             copy=False)
    else:
        # When there is a distance, apply the parallax/offset to the SSB as the
        # last step - ensures round-tripping with the icrs_to_gcrs transform

        # the distance in intermedrep is *not* a real distance as it does not
        # include the offset back to the SSB
        intermedrep = SphericalRepresentation(lat=u.Quantity(i_dec, u.radian, copy=False),
                                              lon=u.Quantity(i_ra, u.radian, copy=False),
                                              distance=srepr.distance,
                                              copy=False)

        astrom_eb = CartesianRepresentation(astrom['eb'], unit=u.au,
                                            xyz_axis=-1, copy=False)
        newrep = intermedrep + astrom_eb

    return icrs_frame.realize_frame(newrep)