示例#1
0
def test_arraytransforms():
    """
    Test that transforms to/from ecliptic coordinates work on array coordinates
    (not testing for accuracy.)
    """
    ra = np.ones((4, ), dtype=float) * u.deg
    dec = 2*np.ones((4, ), dtype=float) * u.deg
    distance = np.ones((4, ), dtype=float) * u.au

    test_icrs = ICRS(ra=ra, dec=dec, distance=distance)
    test_gcrs = GCRS(test_icrs.data)

    bary_arr = test_icrs.transform_to(BarycentricTrueEcliptic)
    assert bary_arr.shape == ra.shape

    helio_arr = test_icrs.transform_to(HeliocentricTrueEcliptic)
    assert helio_arr.shape == ra.shape

    geo_arr = test_gcrs.transform_to(GeocentricTrueEcliptic)
    assert geo_arr.shape == ra.shape

    # now check that we also can go back the other way without shape problems
    bary_icrs = bary_arr.transform_to(ICRS)
    assert bary_icrs.shape == test_icrs.shape

    helio_icrs = helio_arr.transform_to(ICRS)
    assert helio_icrs.shape == test_icrs.shape

    geo_gcrs = geo_arr.transform_to(GCRS)
    assert geo_gcrs.shape == test_gcrs.shape
def test_gcrs_diffs():
    time = Time('J2017')
    gf = GCRS(obstime=time)
    sung = get_sun(time)  # should have very little vhelio

    # qtr-year off sun location should be the direction of ~ maximal vhelio
    qtrsung = get_sun(time-.25*u.year)

    # now we use those essentially as directions where the velocities should
    # be either maximal or minimal - with or perpendiculat to Earh's orbit
    msungr = CartesianRepresentation(-sung.cartesian.xyz).represent_as(SphericalRepresentation)
    suni = ICRS(ra=msungr.lon, dec=msungr.lat, distance=100*u.au,
                pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
                radial_velocity=0*u.km/u.s)
    qtrsuni = ICRS(ra=qtrsung.ra, dec=qtrsung.dec, distance=100*u.au,
                   pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
                   radial_velocity=0*u.km/u.s)

    # Now we transform those parallel- and perpendicular-to Earth's orbit
    # directions to GCRS, which should shift the velocity to either include
    # the Earth's velocity vector, or not (for parallel and perpendicular,
    # respectively).
    sung = suni.transform_to(gf)
    qtrsung = qtrsuni.transform_to(gf)

    # should be high along the ecliptic-not-sun sun axis and
    # low along the sun axis
    assert np.abs(qtrsung.radial_velocity) > 30*u.km/u.s
    assert np.abs(qtrsung.radial_velocity) < 40*u.km/u.s
    assert np.abs(sung.radial_velocity) < 1*u.km/u.s

    suni2 = sung.transform_to(ICRS)
    assert np.all(np.abs(suni2.data.differentials['s'].d_xyz) < 3e-5*u.km/u.s)
    qtrisun2 = qtrsung.transform_to(ICRS)
    assert np.all(np.abs(qtrisun2.data.differentials['s'].d_xyz) < 3e-5*u.km/u.s)
def test_gcrs_diffs():
    time = Time('J2017')
    gf = GCRS(obstime=time)
    sung = get_sun(time)  # should have very little vhelio

    # qtr-year off sun location should be the direction of ~ maximal vhelio
    qtrsung = get_sun(time-.25*u.year)

    # now we use those essentially as directions where the velocities should
    # be either maximal or minimal - with or perpendiculat to Earh's orbit
    msungr = CartesianRepresentation(-sung.cartesian.xyz).represent_as(SphericalRepresentation)
    suni = ICRS(ra=msungr.lon, dec=msungr.lat, distance=100*u.au,
                pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
                radial_velocity=0*u.km/u.s)
    qtrsuni = ICRS(ra=qtrsung.ra, dec=qtrsung.dec, distance=100*u.au,
                   pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
                   radial_velocity=0*u.km/u.s)

    # Now we transform those parallel- and perpendicular-to Earth's orbit
    # directions to GCRS, which should shift the velocity to either include
    # the Earth's velocity vector, or not (for parallel and perpendicular,
    # respectively).
    sung = suni.transform_to(gf)
    qtrsung = qtrsuni.transform_to(gf)

    # should be high along the ecliptic-not-sun sun axis and
    # low along the sun axis
    assert np.abs(qtrsung.radial_velocity) > 30*u.km/u.s
    assert np.abs(qtrsung.radial_velocity) < 40*u.km/u.s
    assert np.abs(sung.radial_velocity) < 1*u.km/u.s

    suni2 = sung.transform_to(ICRS)
    assert np.all(np.abs(suni2.data.differentials['s'].d_xyz) < 3e-5*u.km/u.s)
    qtrisun2 = qtrsung.transform_to(ICRS)
    assert np.all(np.abs(qtrisun2.data.differentials['s'].d_xyz) < 3e-5*u.km/u.s)
def test_lsr_sanity():

    # random numbers, but zero velocity in ICRS frame
    icrs = ICRS(ra=15.1241*u.deg, dec=17.5143*u.deg, distance=150.12*u.pc,
                pm_ra_cosdec=0*u.mas/u.yr, pm_dec=0*u.mas/u.yr,
                radial_velocity=0*u.km/u.s)
    lsr = icrs.transform_to(LSR)

    lsr_diff = lsr.data.differentials['s']
    cart_lsr_vel = lsr_diff.represent_as(CartesianRepresentation, base=lsr.data)
    lsr_vel = ICRS(cart_lsr_vel)
    gal_lsr = lsr_vel.transform_to(Galactic).cartesian.xyz
    assert allclose(gal_lsr.to(u.km/u.s, u.dimensionless_angles()),
                    lsr.v_bary.d_xyz)

    # moving with LSR velocity
    lsr = LSR(ra=15.1241*u.deg, dec=17.5143*u.deg, distance=150.12*u.pc,
              pm_ra_cosdec=0*u.mas/u.yr, pm_dec=0*u.mas/u.yr,
              radial_velocity=0*u.km/u.s)
    icrs = lsr.transform_to(ICRS)

    icrs_diff = icrs.data.differentials['s']
    cart_vel = icrs_diff.represent_as(CartesianRepresentation, base=icrs.data)
    vel = ICRS(cart_vel)
    gal_icrs = vel.transform_to(Galactic).cartesian.xyz
    assert allclose(gal_icrs.to(u.km/u.s, u.dimensionless_angles()),
                    -lsr.v_bary.d_xyz)
示例#5
0
def test_lsr_sanity():

    # random numbers, but zero velocity in ICRS frame
    icrs = ICRS(ra=15.1241*u.deg, dec=17.5143*u.deg, distance=150.12*u.pc,
                pm_ra_cosdec=0*u.mas/u.yr, pm_dec=0*u.mas/u.yr,
                radial_velocity=0*u.km/u.s)
    lsr = icrs.transform_to(LSR)

    lsr_diff = lsr.data.differentials['s']
    cart_lsr_vel = lsr_diff.represent_as(CartesianRepresentation, base=lsr.data)
    lsr_vel = ICRS(cart_lsr_vel)
    gal_lsr = lsr_vel.transform_to(Galactic).cartesian.xyz
    assert allclose(gal_lsr.to(u.km/u.s, u.dimensionless_angles()),
                    lsr.v_bary.d_xyz)

    # moving with LSR velocity
    lsr = LSR(ra=15.1241*u.deg, dec=17.5143*u.deg, distance=150.12*u.pc,
              pm_ra_cosdec=0*u.mas/u.yr, pm_dec=0*u.mas/u.yr,
              radial_velocity=0*u.km/u.s)
    icrs = lsr.transform_to(ICRS)

    icrs_diff = icrs.data.differentials['s']
    cart_vel = icrs_diff.represent_as(CartesianRepresentation, base=icrs.data)
    vel = ICRS(cart_vel)
    gal_icrs = vel.transform_to(Galactic).cartesian.xyz
    assert allclose(gal_icrs.to(u.km/u.s, u.dimensionless_angles()),
                    -lsr.v_bary.d_xyz)
示例#6
0
def test_arraytransforms():
    """
    Test that transforms to/from ecliptic coordinates work on array coordinates
    (not testing for accuracy.)
    """
    ra = np.ones((4, ), dtype=float) * u.deg
    dec = 2 * np.ones((4, ), dtype=float) * u.deg
    distance = np.ones((4, ), dtype=float) * u.au

    test_icrs = ICRS(ra=ra, dec=dec, distance=distance)
    test_gcrs = GCRS(test_icrs.data)

    bary_arr = test_icrs.transform_to(BarycentricTrueEcliptic)
    assert bary_arr.shape == ra.shape

    helio_arr = test_icrs.transform_to(HeliocentricTrueEcliptic)
    assert helio_arr.shape == ra.shape

    geo_arr = test_gcrs.transform_to(GeocentricTrueEcliptic)
    assert geo_arr.shape == ra.shape

    # now check that we also can go back the other way without shape problems
    bary_icrs = bary_arr.transform_to(ICRS)
    assert bary_icrs.shape == test_icrs.shape

    helio_icrs = helio_arr.transform_to(ICRS)
    assert helio_icrs.shape == test_icrs.shape

    geo_gcrs = geo_arr.transform_to(GCRS)
    assert geo_gcrs.shape == test_gcrs.shape
示例#7
0
def test_galactocentric():
    # when z_sun=0, transformation should be very similar to Galactic
    icrs_coord = ICRS(ra=np.linspace(0, 360, 10) * u.deg,
                      dec=np.linspace(-90, 90, 10) * u.deg,
                      distance=1. * u.kpc)

    g_xyz = icrs_coord.transform_to(Galactic).cartesian.xyz
    with galactocentric_frame_defaults.set('pre-v4.0'):
        gc_xyz = icrs_coord.transform_to(Galactocentric(z_sun=0 *
                                                        u.kpc)).cartesian.xyz
    diff = np.abs(g_xyz - gc_xyz)

    assert allclose(diff[0], 8.3 * u.kpc, atol=1E-5 * u.kpc)
    assert allclose(diff[1:], 0 * u.kpc, atol=1E-5 * u.kpc)

    # generate some test coordinates
    g = Galactic(l=[0, 0, 45, 315] * u.deg,
                 b=[-45, 45, 0, 0] * u.deg,
                 distance=[np.sqrt(2)] * 4 * u.kpc)
    with galactocentric_frame_defaults.set('pre-v4.0'):
        xyz = g.transform_to(
            Galactocentric(galcen_distance=1. * u.kpc,
                           z_sun=0. * u.pc)).cartesian.xyz
    true_xyz = np.array([[0, 0, -1.], [0, 0, 1], [0, 1, 0], [0, -1, 0]
                         ]).T * u.kpc
    assert allclose(xyz.to(u.kpc), true_xyz.to(u.kpc), atol=1E-5 * u.kpc)

    # check that ND arrays work

    # from Galactocentric to Galactic
    x = np.linspace(-10., 10., 100) * u.kpc
    y = np.linspace(-10., 10., 100) * u.kpc
    z = np.zeros_like(x)

    # from Galactic to Galactocentric
    l = np.linspace(15, 30., 100) * u.deg
    b = np.linspace(-10., 10., 100) * u.deg
    d = np.ones_like(l.value) * u.kpc

    with galactocentric_frame_defaults.set('latest'):
        g1 = Galactocentric(x=x, y=y, z=z)
        g2 = Galactocentric(x=x.reshape(100, 1, 1),
                            y=y.reshape(100, 1, 1),
                            z=z.reshape(100, 1, 1))

        g1t = g1.transform_to(Galactic)
        g2t = g2.transform_to(Galactic)

        assert_allclose(g1t.cartesian.xyz, g2t.cartesian.xyz[:, :, 0, 0])

        g1 = Galactic(l=l, b=b, distance=d)
        g2 = Galactic(l=l.reshape(100, 1, 1),
                      b=b.reshape(100, 1, 1),
                      distance=d.reshape(100, 1, 1))

        g1t = g1.transform_to(Galactocentric)
        g2t = g2.transform_to(Galactocentric)

        np.testing.assert_almost_equal(g1t.cartesian.xyz.value,
                                       g2t.cartesian.xyz.value[:, :, 0, 0])
示例#8
0
def test_faux_lsr(dt, symmetric):
    class LSR2(LSR):
        obstime = TimeAttribute(default=J2000)

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     ICRS,
                                     LSR2,
                                     finite_difference_dt=dt,
                                     symmetric_finite_difference=symmetric)
    def icrs_to_lsr(icrs_coo, lsr_frame):
        dt = lsr_frame.obstime - J2000
        offset = lsr_frame.v_bary * dt.to(u.second)
        return lsr_frame.realize_frame(icrs_coo.data.without_differentials() +
                                       offset)

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     LSR2,
                                     ICRS,
                                     finite_difference_dt=dt,
                                     symmetric_finite_difference=symmetric)
    def lsr_to_icrs(lsr_coo, icrs_frame):
        dt = lsr_coo.obstime - J2000
        offset = lsr_coo.v_bary * dt.to(u.second)
        return icrs_frame.realize_frame(lsr_coo.data - offset)

    ic = ICRS(ra=12.3 * u.deg,
              dec=45.6 * u.deg,
              distance=7.8 * u.au,
              pm_ra_cosdec=0 * u.marcsec / u.yr,
              pm_dec=0 * u.marcsec / u.yr,
              radial_velocity=0 * u.km / u.s)
    lsrc = ic.transform_to(LSR2())

    assert quantity_allclose(ic.cartesian.xyz, lsrc.cartesian.xyz)

    idiff = ic.cartesian.differentials['s']
    ldiff = lsrc.cartesian.differentials['s']
    change = (ldiff.d_xyz - idiff.d_xyz).to(u.km / u.s)
    totchange = np.sum(change**2)**0.5
    assert quantity_allclose(totchange, np.sum(lsrc.v_bary.d_xyz**2)**0.5)

    ic2 = ICRS(ra=120.3 * u.deg,
               dec=45.6 * u.deg,
               distance=7.8 * u.au,
               pm_ra_cosdec=0 * u.marcsec / u.yr,
               pm_dec=10 * u.marcsec / u.yr,
               radial_velocity=1000 * u.km / u.s)
    lsrc2 = ic2.transform_to(LSR2())
    ic2_roundtrip = lsrc2.transform_to(ICRS)

    tot = np.sum(lsrc2.cartesian.differentials['s'].d_xyz**2)**0.5
    assert np.abs(tot.to('km/s') - 1000 * u.km / u.s) < 20 * u.km / u.s

    assert quantity_allclose(ic2.cartesian.xyz, ic2_roundtrip.cartesian.xyz)
示例#9
0
def test_ecliptic_true_mean(trueframe, meanframe):
    """
    Check that the ecliptic true/mean transformations at least roundtrip
    """
    icrs = ICRS(1 * u.deg, 2 * u.deg, distance=1.5 * R_sun)

    truecoo = icrs.transform_to(trueframe)
    meancoo = icrs.transform_to(meanframe)
    truecoo2 = icrs.transform_to(trueframe)

    assert not quantity_allclose(truecoo.cartesian.xyz, meancoo.cartesian.xyz)
    assert quantity_allclose(truecoo.cartesian.xyz, truecoo2.cartesian.xyz)
示例#10
0
def test_ecliptic_true_mean(trueframe, meanframe):
    """
    Check that the ecliptic true/mean transformations at least roundtrip
    """
    icrs = ICRS(1*u.deg, 2*u.deg, distance=1.5*R_sun)

    truecoo = icrs.transform_to(trueframe)
    meancoo = icrs.transform_to(meanframe)
    truecoo2 = icrs.transform_to(trueframe)

    assert not quantity_allclose(truecoo.cartesian.xyz, meancoo.cartesian.xyz)
    assert quantity_allclose(truecoo.cartesian.xyz, truecoo2.cartesian.xyz)
示例#11
0
def test_converting_units():
    import re
    from astropy.coordinates.baseframe import RepresentationMapping
    from astropy.coordinates.builtin_frames import ICRS, FK5

    # this is a regular expression that with split (see below) removes what's
    # the decimal point  to fix rounding problems
    rexrepr = re.compile(r'(.*?=\d\.).*?( .*?=\d\.).*?( .*)')

    # Use values that aren't subject to rounding down to X.9999...
    i2 = ICRS(ra=2. * u.deg, dec=2. * u.deg)
    i2_many = ICRS(ra=[2., 4.] * u.deg, dec=[2., -8.1] * u.deg)

    # converting from FK5 to ICRS and back changes the *internal* representation,
    # but it should still come out in the preferred form

    i4 = i2.transform_to(FK5).transform_to(ICRS)
    i4_many = i2_many.transform_to(FK5).transform_to(ICRS)

    ri2 = ''.join(rexrepr.split(repr(i2)))
    ri4 = ''.join(rexrepr.split(repr(i4)))
    assert ri2 == ri4
    assert i2.data.lon.unit != i4.data.lon.unit  # Internal repr changed

    ri2_many = ''.join(rexrepr.split(repr(i2_many)))
    ri4_many = ''.join(rexrepr.split(repr(i4_many)))

    assert ri2_many == ri4_many
    assert i2_many.data.lon.unit != i4_many.data.lon.unit  # Internal repr changed

    # but that *shouldn't* hold if we turn off units for the representation
    class FakeICRS(ICRS):
        frame_specific_representation_info = {
            'spherical': [
                RepresentationMapping('lon', 'ra', u.hourangle),
                RepresentationMapping('lat', 'dec', None),
                RepresentationMapping('distance', 'distance')
            ]  # should fall back to default of None unit
        }

    fi = FakeICRS(i4.data)
    ri2 = ''.join(rexrepr.split(repr(i2)))
    rfi = ''.join(rexrepr.split(repr(fi)))
    rfi = re.sub('FakeICRS', 'ICRS', rfi)  # Force frame name to match
    assert ri2 != rfi

    # the attributes should also get the right units
    assert i2.dec.unit == i4.dec.unit
    # unless no/explicitly given units
    assert i2.dec.unit != fi.dec.unit
    assert i2.ra.unit != fi.ra.unit
    assert fi.ra.unit == u.hourangle
示例#12
0
def test_transform():
    """
    This test just makes sure the transform architecture works, but does *not*
    actually test all the builtin transforms themselves are accurate
    """
    from astropy.coordinates.builtin_frames import ICRS, FK4, FK5, Galactic
    from astropy.time import Time

    i = ICRS(ra=[1, 2] * u.deg, dec=[3, 4] * u.deg)
    f = i.transform_to(FK5)
    i2 = f.transform_to(ICRS)

    assert i2.data.__class__ == r.UnitSphericalRepresentation

    assert_allclose(i.ra, i2.ra)
    assert_allclose(i.dec, i2.dec)

    i = ICRS(ra=[1, 2] * u.deg, dec=[3, 4] * u.deg, distance=[5, 6] * u.kpc)
    f = i.transform_to(FK5)
    i2 = f.transform_to(ICRS)

    assert i2.data.__class__ != r.UnitSphericalRepresentation

    f = FK5(ra=1 * u.deg, dec=2 * u.deg, equinox=Time('J2001'))
    f4 = f.transform_to(FK4)
    f4_2 = f.transform_to(FK4(equinox=f.equinox))

    # make sure attributes are copied over correctly
    assert f4.equinox == FK4.get_frame_attr_names()['equinox']
    assert f4_2.equinox == f.equinox

    # make sure self-transforms also work
    i = ICRS(ra=[1, 2] * u.deg, dec=[3, 4] * u.deg)
    i2 = i.transform_to(ICRS)

    assert_allclose(i.ra, i2.ra)
    assert_allclose(i.dec, i2.dec)

    f = FK5(ra=1 * u.deg, dec=2 * u.deg, equinox=Time('J2001'))
    f2 = f.transform_to(FK5)  # default equinox, so should be *different*
    assert f2.equinox == FK5().equinox
    with pytest.raises(AssertionError):
        assert_allclose(f.ra, f2.ra)
    with pytest.raises(AssertionError):
        assert_allclose(f.dec, f2.dec)

    # finally, check Galactic round-tripping
    i1 = ICRS(ra=[1, 2] * u.deg, dec=[3, 4] * u.deg)
    i2 = i1.transform_to(Galactic).transform_to(ICRS)

    assert_allclose(i1.ra, i2.ra)
    assert_allclose(i1.dec, i2.dec)
示例#13
0
def test_transform():
    """
    This test just makes sure the transform architecture works, but does *not*
    actually test all the builtin transforms themselves are accurate
    """
    from astropy.coordinates.builtin_frames import ICRS, FK4, FK5, Galactic
    from astropy.time import Time

    i = ICRS(ra=[1, 2]*u.deg, dec=[3, 4]*u.deg)
    f = i.transform_to(FK5)
    i2 = f.transform_to(ICRS)

    assert i2.data.__class__ == r.UnitSphericalRepresentation

    assert_allclose(i.ra, i2.ra)
    assert_allclose(i.dec, i2.dec)

    i = ICRS(ra=[1, 2]*u.deg, dec=[3, 4]*u.deg, distance=[5, 6]*u.kpc)
    f = i.transform_to(FK5)
    i2 = f.transform_to(ICRS)

    assert i2.data.__class__ != r.UnitSphericalRepresentation

    f = FK5(ra=1*u.deg, dec=2*u.deg, equinox=Time('J2001'))
    f4 = f.transform_to(FK4)
    f4_2 = f.transform_to(FK4(equinox=f.equinox))

    # make sure attributes are copied over correctly
    assert f4.equinox == FK4.get_frame_attr_names()['equinox']
    assert f4_2.equinox == f.equinox

    # make sure self-transforms also work
    i = ICRS(ra=[1, 2]*u.deg, dec=[3, 4]*u.deg)
    i2 = i.transform_to(ICRS)

    assert_allclose(i.ra, i2.ra)
    assert_allclose(i.dec, i2.dec)

    f = FK5(ra=1*u.deg, dec=2*u.deg, equinox=Time('J2001'))
    f2 = f.transform_to(FK5)  # default equinox, so should be *different*
    assert f2.equinox == FK5().equinox
    with pytest.raises(AssertionError):
        assert_allclose(f.ra, f2.ra)
    with pytest.raises(AssertionError):
        assert_allclose(f.dec, f2.dec)

    # finally, check Galactic round-tripping
    i1 = ICRS(ra=[1, 2]*u.deg, dec=[3, 4]*u.deg)
    i2 = i1.transform_to(Galactic).transform_to(ICRS)

    assert_allclose(i1.ra, i2.ra)
    assert_allclose(i1.dec, i2.dec)
class TestHCRS():
    """
    Check HCRS<->ICRS coordinate conversions.

    Uses ICRS Solar positions predicted by get_body_barycentric; with `t1` and
    `tarr` as defined below, the ICRS Solar positions were predicted using, e.g.
    coord.ICRS(coord.get_body_barycentric(tarr, 'sun')).
    """
    def setup(self):
        self.t1 = Time("2013-02-02T23:00")
        self.t2 = Time("2013-08-02T23:00")
        self.tarr = Time(["2013-02-02T23:00", "2013-08-02T23:00"])

        self.sun_icrs_scalar = ICRS(ra=244.52984668 * u.deg,
                                    dec=-22.36943723 * u.deg,
                                    distance=406615.66347377 * u.km)
        # array of positions corresponds to times in `tarr`
        self.sun_icrs_arr = ICRS(ra=[244.52989062, 271.40976248] * u.deg,
                                 dec=[-22.36943605, -25.07431079] * u.deg,
                                 distance=[406615.66347377, 375484.13558956] *
                                 u.km)

        # corresponding HCRS positions
        self.sun_hcrs_t1 = HCRS(CartesianRepresentation([0.0, 0.0, 0.0] *
                                                        u.km),
                                obstime=self.t1)
        twod_rep = CartesianRepresentation(
            [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0]] * u.km)
        self.sun_hcrs_tarr = HCRS(twod_rep, obstime=self.tarr)
        self.tolerance = 5 * u.km

    def test_from_hcrs(self):
        # test scalar transform
        transformed = self.sun_hcrs_t1.transform_to(ICRS())
        separation = transformed.separation_3d(self.sun_icrs_scalar)
        assert_allclose(separation, 0 * u.km, atol=self.tolerance)

        # test non-scalar positions and times
        transformed = self.sun_hcrs_tarr.transform_to(ICRS())
        separation = transformed.separation_3d(self.sun_icrs_arr)
        assert_allclose(separation, 0 * u.km, atol=self.tolerance)

    def test_from_icrs(self):
        # scalar positions
        transformed = self.sun_icrs_scalar.transform_to(HCRS(obstime=self.t1))
        separation = transformed.separation_3d(self.sun_hcrs_t1)
        assert_allclose(separation, 0 * u.km, atol=self.tolerance)
        # nonscalar positions
        transformed = self.sun_icrs_arr.transform_to(HCRS(obstime=self.tarr))
        separation = transformed.separation_3d(self.sun_hcrs_tarr)
        assert_allclose(separation, 0 * u.km, atol=self.tolerance)
def test_galactocentric():
    # when z_sun=0, transformation should be very similar to Galactic
    icrs_coord = ICRS(ra=np.linspace(0, 360, 10)*u.deg,
                      dec=np.linspace(-90, 90, 10)*u.deg,
                      distance=1.*u.kpc)

    g_xyz = icrs_coord.transform_to(Galactic).cartesian.xyz
    gc_xyz = icrs_coord.transform_to(Galactocentric(z_sun=0*u.kpc)).cartesian.xyz
    diff = np.abs(g_xyz - gc_xyz)

    assert allclose(diff[0], 8.3*u.kpc, atol=1E-5*u.kpc)
    assert allclose(diff[1:], 0*u.kpc, atol=1E-5*u.kpc)

    # generate some test coordinates
    g = Galactic(l=[0, 0, 45, 315]*u.deg, b=[-45, 45, 0, 0]*u.deg,
                 distance=[np.sqrt(2)]*4*u.kpc)
    xyz = g.transform_to(Galactocentric(galcen_distance=1.*u.kpc, z_sun=0.*u.pc)).cartesian.xyz
    true_xyz = np.array([[0, 0, -1.], [0, 0, 1], [0, 1, 0], [0, -1, 0]]).T*u.kpc
    assert allclose(xyz.to(u.kpc), true_xyz.to(u.kpc), atol=1E-5*u.kpc)

    # check that ND arrays work

    # from Galactocentric to Galactic
    x = np.linspace(-10., 10., 100) * u.kpc
    y = np.linspace(-10., 10., 100) * u.kpc
    z = np.zeros_like(x)

    g1 = Galactocentric(x=x, y=y, z=z)
    g2 = Galactocentric(x=x.reshape(100, 1, 1), y=y.reshape(100, 1, 1),
                        z=z.reshape(100, 1, 1))

    g1t = g1.transform_to(Galactic)
    g2t = g2.transform_to(Galactic)

    assert_allclose(g1t.cartesian.xyz, g2t.cartesian.xyz[:, :, 0, 0])

    # from Galactic to Galactocentric
    l = np.linspace(15, 30., 100) * u.deg
    b = np.linspace(-10., 10., 100) * u.deg
    d = np.ones_like(l.value) * u.kpc

    g1 = Galactic(l=l, b=b, distance=d)
    g2 = Galactic(l=l.reshape(100, 1, 1), b=b.reshape(100, 1, 1),
                  distance=d.reshape(100, 1, 1))

    g1t = g1.transform_to(Galactocentric)
    g2t = g2.transform_to(Galactocentric)

    np.testing.assert_almost_equal(g1t.cartesian.xyz.value,
                                   g2t.cartesian.xyz.value[:, :, 0, 0])
def test_frame_affinetransform(kwargs, expect_success):
    """There are already tests in test_transformations.py that check that
    an AffineTransform fails without full-space data, but this just checks that
    things work as expected at the frame level as well.
    """
    with galactocentric_frame_defaults.set('latest'):
        icrs = ICRS(**kwargs)

        if expect_success:
            _ = icrs.transform_to(Galactocentric)

        else:
            with pytest.raises(ConvertError):
                icrs.transform_to(Galactocentric)
示例#17
0
def test_frame_affinetransform(kwargs, expect_success):
    """There are already tests in test_transformations.py that check that
    an AffineTransform fails without full-space data, but this just checks that
    things work as expected at the frame level as well.
    """

    icrs = ICRS(**kwargs)

    if expect_success:
        gc = icrs.transform_to(Galactocentric)

    else:
        with pytest.raises(ConvertError):
            icrs.transform_to(Galactocentric)
示例#18
0
def test_converting_units():
    import re
    from astropy.coordinates.baseframe import RepresentationMapping
    from astropy.coordinates.builtin_frames import ICRS, FK5

    # this is a regular expression that with split (see below) removes what's
    # the decimal point  to fix rounding problems
    rexrepr = re.compile(r'(.*?=\d\.).*?( .*?=\d\.).*?( .*)')

    # Use values that aren't subject to rounding down to X.9999...
    i2 = ICRS(ra=2.*u.deg, dec=2.*u.deg)
    i2_many = ICRS(ra=[2., 4.]*u.deg, dec=[2., -8.1]*u.deg)

    # converting from FK5 to ICRS and back changes the *internal* representation,
    # but it should still come out in the preferred form

    i4 = i2.transform_to(FK5).transform_to(ICRS)
    i4_many = i2_many.transform_to(FK5).transform_to(ICRS)

    ri2 = ''.join(rexrepr.split(repr(i2)))
    ri4 = ''.join(rexrepr.split(repr(i4)))
    assert ri2 == ri4
    assert i2.data.lon.unit != i4.data.lon.unit  # Internal repr changed

    ri2_many = ''.join(rexrepr.split(repr(i2_many)))
    ri4_many = ''.join(rexrepr.split(repr(i4_many)))

    assert ri2_many == ri4_many
    assert i2_many.data.lon.unit != i4_many.data.lon.unit  # Internal repr changed

    # but that *shouldn't* hold if we turn off units for the representation
    class FakeICRS(ICRS):
        frame_specific_representation_info = {
            'spherical': [RepresentationMapping('lon', 'ra', u.hourangle),
                          RepresentationMapping('lat', 'dec', None),
                          RepresentationMapping('distance', 'distance')]  # should fall back to default of None unit
        }

    fi = FakeICRS(i4.data)
    ri2 = ''.join(rexrepr.split(repr(i2)))
    rfi = ''.join(rexrepr.split(repr(fi)))
    rfi = re.sub('FakeICRS', 'ICRS', rfi)  # Force frame name to match
    assert ri2 != rfi

    # the attributes should also get the right units
    assert i2.dec.unit == i4.dec.unit
    # unless no/explicitly given units
    assert i2.dec.unit != fi.dec.unit
    assert i2.ra.unit != fi.ra.unit
    assert fi.ra.unit == u.hourangle
class TestHCRS():
    """
    Check HCRS<->ICRS coordinate conversions.

    Uses ICRS Solar positions predicted by get_body_barycentric; with `t1` and
    `tarr` as defined below, the ICRS Solar positions were predicted using, e.g.
    coord.ICRS(coord.get_body_barycentric(tarr, 'sun')).
    """

    def setup(self):
        self.t1 = Time("2013-02-02T23:00")
        self.t2 = Time("2013-08-02T23:00")
        self.tarr = Time(["2013-02-02T23:00", "2013-08-02T23:00"])

        self.sun_icrs_scalar = ICRS(ra=244.52984668*u.deg,
                                    dec=-22.36943723*u.deg,
                                    distance=406615.66347377*u.km)
        # array of positions corresponds to times in `tarr`
        self.sun_icrs_arr = ICRS(ra=[244.52989062, 271.40976248]*u.deg,
                                 dec=[-22.36943605, -25.07431079]*u.deg,
                                 distance=[406615.66347377, 375484.13558956]*u.km)

        # corresponding HCRS positions
        self.sun_hcrs_t1 = HCRS(CartesianRepresentation([0.0, 0.0, 0.0] * u.km),
                                obstime=self.t1)
        twod_rep = CartesianRepresentation([[0.0, 0.0], [0.0, 0.0], [0.0, 0.0]] * u.km)
        self.sun_hcrs_tarr = HCRS(twod_rep, obstime=self.tarr)
        self.tolerance = 5*u.km

    def test_from_hcrs(self):
        # test scalar transform
        transformed = self.sun_hcrs_t1.transform_to(ICRS())
        separation = transformed.separation_3d(self.sun_icrs_scalar)
        assert_allclose(separation, 0*u.km, atol=self.tolerance)

        # test non-scalar positions and times
        transformed = self.sun_hcrs_tarr.transform_to(ICRS())
        separation = transformed.separation_3d(self.sun_icrs_arr)
        assert_allclose(separation, 0*u.km, atol=self.tolerance)

    def test_from_icrs(self):
        # scalar positions
        transformed = self.sun_icrs_scalar.transform_to(HCRS(obstime=self.t1))
        separation = transformed.separation_3d(self.sun_hcrs_t1)
        assert_allclose(separation, 0*u.km, atol=self.tolerance)
        # nonscalar positions
        transformed = self.sun_icrs_arr.transform_to(HCRS(obstime=self.tarr))
        separation = transformed.separation_3d(self.sun_hcrs_tarr)
        assert_allclose(separation, 0*u.km, atol=self.tolerance)
示例#20
0
def test_roundtrip_scalar():
    icrs = ICRS(ra=1*u.deg, dec=2*u.deg, distance=3*u.au)
    gcrs = GCRS(icrs.cartesian)

    bary = icrs.transform_to(BarycentricTrueEcliptic)
    helio = icrs.transform_to(HeliocentricTrueEcliptic)
    geo = gcrs.transform_to(GeocentricTrueEcliptic)

    bary_icrs = bary.transform_to(ICRS)
    helio_icrs = helio.transform_to(ICRS)
    geo_gcrs = geo.transform_to(GCRS)

    assert quantity_allclose(bary_icrs.cartesian.xyz, icrs.cartesian.xyz)
    assert quantity_allclose(helio_icrs.cartesian.xyz, icrs.cartesian.xyz)
    assert quantity_allclose(geo_gcrs.cartesian.xyz, gcrs.cartesian.xyz)
示例#21
0
def test_roundtrip_scalar():
    icrs = ICRS(ra=1 * u.deg, dec=2 * u.deg, distance=3 * u.au)
    gcrs = GCRS(icrs.cartesian)

    bary = icrs.transform_to(BarycentricTrueEcliptic)
    helio = icrs.transform_to(HeliocentricTrueEcliptic)
    geo = gcrs.transform_to(GeocentricTrueEcliptic)

    bary_icrs = bary.transform_to(ICRS)
    helio_icrs = helio.transform_to(ICRS)
    geo_gcrs = geo.transform_to(GCRS)

    assert quantity_allclose(bary_icrs.cartesian.xyz, icrs.cartesian.xyz)
    assert quantity_allclose(helio_icrs.cartesian.xyz, icrs.cartesian.xyz)
    assert quantity_allclose(geo_gcrs.cartesian.xyz, gcrs.cartesian.xyz)
示例#22
0
def test_altaz_diffs():
    time = Time('J2015') + np.linspace(-1, 1, 1000) * u.day
    loc = get_builtin_sites()['greenwich']
    aa = AltAz(obstime=time, location=loc)

    icoo = ICRS(np.zeros_like(time) * u.deg,
                10 * u.deg,
                100 * u.au,
                pm_ra_cosdec=np.zeros_like(time) * u.marcsec / u.yr,
                pm_dec=0 * u.marcsec / u.yr,
                radial_velocity=0 * u.km / u.s)

    acoo = icoo.transform_to(aa)

    # Make sure the change in radial velocity over ~2 days isn't too much
    # more than the rotation speed of the Earth - some excess is expected
    # because the orbit also shifts the RV, but it should be pretty small
    # over this short a time.
    assert np.ptp(acoo.radial_velocity) / 2 < (2 * np.pi * constants.R_earth /
                                               u.day) * 1.2  # MAGIC NUMBER

    cdiff = acoo.data.differentials['s'].represent_as(CartesianDifferential,
                                                      acoo.data)

    # The "total" velocity should be > c, because the *tangential* velocity
    # isn't a True velocity, but rather an induced velocity due to the Earth's
    # rotation at a distance of 100 AU
    assert np.all(np.sum(cdiff.d_xyz**2, axis=0)**0.5 > constants.c)
def test_all_arg_options(kwargs):
    # Above is a list of all possible valid combinations of arguments.
    # Here we do a simple thing and just verify that passing them in, we have
    # access to the relevant attributes from the resulting object
    icrs = ICRS(**kwargs)
    gal = icrs.transform_to(Galactic)
    repr_gal = repr(gal)

    for k in kwargs:
        if k == 'differential_type':
            continue
        getattr(icrs, k)

    if 'pm_ra_cosdec' in kwargs:  # should have both
        assert 'pm_l_cosb' in repr_gal
        assert 'pm_b' in repr_gal
        assert 'mas / yr' in repr_gal

        if 'radial_velocity' not in kwargs:
            assert 'radial_velocity' not in repr_gal

    if 'radial_velocity' in kwargs:
        assert 'radial_velocity' in repr_gal
        assert 'km / s' in repr_gal

        if 'pm_ra_cosdec' not in kwargs:
            assert 'pm_l_cosb' not in repr_gal
            assert 'pm_b' not in repr_gal
def test_altaz_diffs():
    time = Time('J2015') + np.linspace(-1, 1, 1000)*u.day
    loc = get_builtin_sites()['greenwich']
    aa = AltAz(obstime=time, location=loc)

    icoo = ICRS(np.zeros_like(time)*u.deg, 10*u.deg, 100*u.au,
                pm_ra_cosdec=np.zeros_like(time)*u.marcsec/u.yr,
                pm_dec=0*u.marcsec/u.yr,
                radial_velocity=0*u.km/u.s)

    acoo = icoo.transform_to(aa)

    # Make sure the change in radial velocity over ~2 days isn't too much
    # more than the rotation speed of the Earth - some excess is expected
    # because the orbit also shifts the RV, but it should be pretty small
    # over this short a time.
    assert np.ptp(acoo.radial_velocity)/2 < (2*np.pi*constants.R_earth/u.day)*1.2  # MAGIC NUMBER

    cdiff = acoo.data.differentials['s'].represent_as(CartesianDifferential,
                                                    acoo.data)

    # The "total" velocity should be > c, because the *tangential* velocity
    # isn't a True velocity, but rather an induced velocity due to the Earth's
    # rotation at a distance of 100 AU
    assert np.all(np.sum(cdiff.d_xyz**2, axis=0)**0.5 > constants.c)
def test_skyoffset_functional_ra():
    # we do the 12)[1:-1] business because sometimes machine precision issues
    # lead to results that are either ~0 or ~360, which mucks up the final
    # comparison and leads to spurious failures.  So this just avoids that by
    # staying away from the edges
    input_ra = np.linspace(0, 360, 12)[1:-1]
    input_dec = np.linspace(-90, 90, 12)[1:-1]
    icrs_coord = ICRS(ra=input_ra*u.deg,
                      dec=input_dec*u.deg,
                      distance=1.*u.kpc)

    for ra in np.linspace(0, 360, 24):
        # expected rotation
        expected = ICRS(ra=np.linspace(0-ra, 360-ra, 12)[1:-1]*u.deg,
                        dec=np.linspace(-90, 90, 12)[1:-1]*u.deg,
                        distance=1.*u.kpc)
        expected_xyz = expected.cartesian.xyz

        # actual transformation to the frame
        skyoffset_frame = SkyOffsetFrame(origin=ICRS(ra*u.deg, 0*u.deg))
        actual = icrs_coord.transform_to(skyoffset_frame)
        actual_xyz = actual.cartesian.xyz

        # back to ICRS
        roundtrip = actual.transform_to(ICRS)
        roundtrip_xyz = roundtrip.cartesian.xyz

        # Verify
        assert_allclose(actual_xyz, expected_xyz, atol=1E-5*u.kpc)
        assert_allclose(icrs_coord.ra, roundtrip.ra, atol=1E-5*u.deg)
        assert_allclose(icrs_coord.dec, roundtrip.dec, atol=1E-5*u.deg)
        assert_allclose(icrs_coord.distance, roundtrip.distance, atol=1E-5*u.kpc)
def test_skyoffset_functional_ra():
    # we do the 12)[1:-1] business because sometimes machine precision issues
    # lead to results that are either ~0 or ~360, which mucks up the final
    # comparison and leads to spurious failures.  So this just avoids that by
    # staying away from the edges
    input_ra = np.linspace(0, 360, 12)[1:-1]
    input_dec = np.linspace(-90, 90, 12)[1:-1]
    icrs_coord = ICRS(ra=input_ra * u.deg,
                      dec=input_dec * u.deg,
                      distance=1. * u.kpc)

    for ra in np.linspace(0, 360, 24):
        # expected rotation
        expected = ICRS(ra=np.linspace(0 - ra, 360 - ra, 12)[1:-1] * u.deg,
                        dec=np.linspace(-90, 90, 12)[1:-1] * u.deg,
                        distance=1. * u.kpc)
        expected_xyz = expected.cartesian.xyz

        # actual transformation to the frame
        skyoffset_frame = SkyOffsetFrame(origin=ICRS(ra * u.deg, 0 * u.deg))
        actual = icrs_coord.transform_to(skyoffset_frame)
        actual_xyz = actual.cartesian.xyz

        # back to ICRS
        roundtrip = actual.transform_to(ICRS())
        roundtrip_xyz = roundtrip.cartesian.xyz

        # Verify
        assert_allclose(actual_xyz, expected_xyz, atol=1E-5 * u.kpc)
        assert_allclose(icrs_coord.ra, roundtrip.ra, atol=1E-5 * u.deg)
        assert_allclose(icrs_coord.dec, roundtrip.dec, atol=1E-5 * u.deg)
        assert_allclose(icrs_coord.distance,
                        roundtrip.distance,
                        atol=1E-5 * u.kpc)
示例#27
0
def test_all_arg_options(kwargs):
    # Above is a list of all possible valid combinations of arguments.
    # Here we do a simple thing and just verify that passing them in, we have
    # access to the relevant attributes from the resulting object
    icrs = ICRS(**kwargs)
    gal = icrs.transform_to(Galactic)
    repr_gal = repr(gal)

    for k in kwargs:
        if k == 'differential_type':
            continue
        getattr(icrs, k)

    if 'pm_ra_cosdec' in kwargs: # should have both
        assert 'pm_l_cosb' in repr_gal
        assert 'pm_b' in repr_gal
        assert 'mas / yr' in repr_gal

        if 'radial_velocity' not in kwargs:
            assert 'radial_velocity' not in repr_gal

    if 'radial_velocity' in kwargs:
        assert 'radial_velocity' in repr_gal
        assert 'km / s' in repr_gal

        if 'pm_ra_cosdec' not in kwargs:
            assert 'pm_l_cosb' not in repr_gal
            assert 'pm_b' not in repr_gal
示例#28
0
def test_transform_to_nonscalar_nodata_frame():
    # https://github.com/astropy/astropy/pull/5254#issuecomment-241592353
    from astropy.coordinates.builtin_frames import ICRS, FK5
    from astropy.time import Time
    times = Time('2016-08-23') + np.linspace(0, 10, 12)*u.day
    coo1 = ICRS(ra=[[0.], [10.], [20.]]*u.deg,
                dec=[[-30.], [30.], [60.]]*u.deg)
    coo2 = coo1.transform_to(FK5(equinox=times))
    assert coo2.shape == (3, 12)
def test_skyoffset_velocity():
    c = ICRS(ra=170.9*u.deg, dec=-78.4*u.deg,
             pm_ra_cosdec=74.4134*u.mas/u.yr,
             pm_dec=-93.2342*u.mas/u.yr)
    skyoffset_frame = SkyOffsetFrame(origin=c)
    c_skyoffset = c.transform_to(skyoffset_frame)

    assert_allclose(c_skyoffset.pm_lon_coslat, c.pm_ra_cosdec)
    assert_allclose(c_skyoffset.pm_lat, c.pm_dec)
示例#30
0
def test_ecliptic_heliobary():
    """
    Check that the ecliptic transformations for heliocentric and barycentric
    at least more or less make sense
    """
    icrs = ICRS(1*u.deg, 2*u.deg, distance=1.5*R_sun)

    bary = icrs.transform_to(BarycentricTrueEcliptic)
    helio = icrs.transform_to(HeliocentricTrueEcliptic)

    # make sure there's a sizable distance shift - in 3d hundreds of km, but
    # this is 1D so we allow it to be somewhat smaller
    assert np.abs(bary.distance - helio.distance) > 1*u.km

    # now make something that's got the location of helio but in bary's frame.
    # this is a convenience to allow `separation` to work as expected
    helio_in_bary_frame = bary.realize_frame(helio.cartesian)
    assert bary.separation(helio_in_bary_frame) > 1*u.arcmin
示例#31
0
def test_ecliptic_heliobary():
    """
    Check that the ecliptic transformations for heliocentric and barycentric
    at least more or less make sense
    """
    icrs = ICRS(1 * u.deg, 2 * u.deg, distance=1.5 * R_sun)

    bary = icrs.transform_to(BarycentricTrueEcliptic)
    helio = icrs.transform_to(HeliocentricTrueEcliptic)

    # make sure there's a sizable distance shift - in 3d hundreds of km, but
    # this is 1D so we allow it to be somewhat smaller
    assert np.abs(bary.distance - helio.distance) > 1 * u.km

    # now make something that's got the location of helio but in bary's frame.
    # this is a convenience to allow `separation` to work as expected
    helio_in_bary_frame = bary.realize_frame(helio.cartesian)
    assert bary.separation(helio_in_bary_frame) > 1 * u.arcmin
def test_skyoffset_velocity():
    c = ICRS(ra=170.9*u.deg, dec=-78.4*u.deg,
             pm_ra_cosdec=74.4134*u.mas/u.yr,
             pm_dec=-93.2342*u.mas/u.yr)
    skyoffset_frame = SkyOffsetFrame(origin=c)
    c_skyoffset = c.transform_to(skyoffset_frame)

    assert_allclose(c_skyoffset.pm_lon_coslat, c.pm_ra_cosdec)
    assert_allclose(c_skyoffset.pm_lat, c.pm_dec)
def test_rotation(rotation, expectedlatlon):
    origin = ICRS(45*u.deg, 45*u.deg)
    target = ICRS(45*u.deg, 46*u.deg)

    aframe = SkyOffsetFrame(origin=origin, rotation=rotation)
    trans = target.transform_to(aframe)

    assert_allclose([trans.lon.wrap_at(180*u.deg), trans.lat],
                    expectedlatlon, atol=1e-10*u.deg)
示例#34
0
def test_transform_to_nonscalar_nodata_frame():
    # https://github.com/astropy/astropy/pull/5254#issuecomment-241592353
    from astropy.coordinates.builtin_frames import ICRS, FK5
    from astropy.time import Time
    times = Time('2016-08-23') + np.linspace(0, 10, 12) * u.day
    coo1 = ICRS(ra=[[0.], [10.], [20.]] * u.deg,
                dec=[[-30.], [30.], [60.]] * u.deg)
    coo2 = coo1.transform_to(FK5(equinox=times))
    assert coo2.shape == (3, 12)
def test_rotation(rotation, expectedlatlon):
    origin = ICRS(45*u.deg, 45*u.deg)
    target = ICRS(45*u.deg, 46*u.deg)

    aframe = SkyOffsetFrame(origin=origin, rotation=rotation)
    trans = target.transform_to(aframe)

    assert_allclose([trans.lon.wrap_at(180*u.deg), trans.lat],
                    expectedlatlon, atol=1e-10*u.deg)
def test_faux_lsr(dt, symmetric):
    class LSR2(LSR):
        obstime = TimeAttribute(default=J2000)

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     ICRS, LSR2, finite_difference_dt=dt,
                                     symmetric_finite_difference=symmetric)
    def icrs_to_lsr(icrs_coo, lsr_frame):
        dt = lsr_frame.obstime - J2000
        offset = lsr_frame.v_bary * dt.to(u.second)
        return lsr_frame.realize_frame(icrs_coo.data.without_differentials() + offset)

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     LSR2, ICRS, finite_difference_dt=dt,
                                     symmetric_finite_difference=symmetric)
    def lsr_to_icrs(lsr_coo, icrs_frame):
        dt = lsr_coo.obstime - J2000
        offset = lsr_coo.v_bary * dt.to(u.second)
        return icrs_frame.realize_frame(lsr_coo.data - offset)

    ic = ICRS(ra=12.3*u.deg, dec=45.6*u.deg, distance=7.8*u.au,
              pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
              radial_velocity=0*u.km/u.s)
    lsrc = ic.transform_to(LSR2())

    assert quantity_allclose(ic.cartesian.xyz, lsrc.cartesian.xyz)

    idiff = ic.cartesian.differentials['s']
    ldiff = lsrc.cartesian.differentials['s']
    change = (ldiff.d_xyz - idiff.d_xyz).to(u.km/u.s)
    totchange = np.sum(change**2)**0.5
    assert quantity_allclose(totchange, np.sum(lsrc.v_bary.d_xyz**2)**0.5)

    ic2 = ICRS(ra=120.3*u.deg, dec=45.6*u.deg, distance=7.8*u.au,
               pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=10*u.marcsec/u.yr,
               radial_velocity=1000*u.km/u.s)
    lsrc2 = ic2.transform_to(LSR2())
    ic2_roundtrip = lsrc2.transform_to(ICRS)

    tot = np.sum(lsrc2.cartesian.differentials['s'].d_xyz**2)**0.5
    assert np.abs(tot.to('km/s') - 1000*u.km/u.s) < 20*u.km/u.s

    assert quantity_allclose(ic2.cartesian.xyz,
                             ic2_roundtrip.cartesian.xyz)
示例#37
0
def get_body(body, time, location=None, ephemeris=None):
    """
    Get a `~astropy.coordinates.SkyCoord` for a solar system body as observed
    from a location on Earth in the `~astropy.coordinates.GCRS` reference
    system.

    Parameters
    ----------
    body : str or other
        The solar system body for which to calculate positions.  Can also be a
        kernel specifier (list of 2-tuples) if the ``ephemeris`` is a JPL
        kernel.
    time : `~astropy.time.Time`
        Time of observation.
    location : `~astropy.coordinates.EarthLocation`, optional
        Location of observer on the Earth.  If not given, will be taken from
        ``time`` (if not present, a geocentric observer will be assumed).
    ephemeris : str, optional
        Ephemeris to use.  If not given, use the one set with
        ``astropy.coordinates.solar_system_ephemeris.set`` (which is
        set to 'builtin' by default).

    Returns
    -------
    skycoord : `~astropy.coordinates.SkyCoord`
        GCRS Coordinate for the body

    Notes
    -----
    """
    if location is None:
        location = time.location

    cartrep = _get_apparent_body_position(body, time, ephemeris)
    icrs = ICRS(cartrep)
    if location is not None:
        obsgeoloc, obsgeovel = location.get_gcrs_posvel(time)
        gcrs = icrs.transform_to(
            GCRS(obstime=time, obsgeoloc=obsgeoloc, obsgeovel=obsgeovel))
    else:
        gcrs = icrs.transform_to(GCRS(obstime=time))
    return SkyCoord(gcrs)
def test_skyoffset_functional_ra_dec():
    # we do the 12)[1:-1] business because sometimes machine precision issues
    # lead to results that are either ~0 or ~360, which mucks up the final
    # comparison and leads to spurious failures.  So this just avoids that by
    # staying away from the edges
    input_ra = np.linspace(0, 360, 12)[1:-1]
    input_dec = np.linspace(-90, 90, 12)[1:-1]
    input_ra_rad = np.deg2rad(input_ra)
    input_dec_rad = np.deg2rad(input_dec)
    icrs_coord = ICRS(ra=input_ra * u.deg,
                      dec=input_dec * u.deg,
                      distance=1. * u.kpc)

    for ra in np.linspace(0, 360, 10):
        for dec in np.linspace(-90, 90, 5):
            # expected rotation
            dec_rad = -np.deg2rad(dec)
            ra_rad = np.deg2rad(ra)
            expected_x = (-np.sin(input_dec_rad) * np.sin(dec_rad) +
                          np.cos(input_ra_rad) * np.cos(input_dec_rad) *
                          np.cos(dec_rad) * np.cos(ra_rad) +
                          np.sin(input_ra_rad) * np.cos(input_dec_rad) *
                          np.cos(dec_rad) * np.sin(ra_rad))
            expected_y = (
                np.sin(input_ra_rad) * np.cos(input_dec_rad) * np.cos(ra_rad) -
                np.cos(input_ra_rad) * np.cos(input_dec_rad) * np.sin(ra_rad))
            expected_z = (np.sin(input_dec_rad) * np.cos(dec_rad) +
                          np.sin(dec_rad) * np.cos(ra_rad) *
                          np.cos(input_ra_rad) * np.cos(input_dec_rad) +
                          np.sin(dec_rad) * np.sin(ra_rad) *
                          np.sin(input_ra_rad) * np.cos(input_dec_rad))
            expected = SkyCoord(x=expected_x,
                                y=expected_y,
                                z=expected_z,
                                unit='kpc',
                                representation_type='cartesian')
            expected_xyz = expected.cartesian.xyz

            # actual transformation to the frame
            skyoffset_frame = SkyOffsetFrame(
                origin=ICRS(ra * u.deg, dec * u.deg))
            actual = icrs_coord.transform_to(skyoffset_frame)
            actual_xyz = actual.cartesian.xyz

            # back to ICRS
            roundtrip = actual.transform_to(ICRS())

            # Verify
            assert_allclose(actual_xyz, expected_xyz, atol=1E-5 * u.kpc)
            assert_allclose(icrs_coord.ra, roundtrip.ra, atol=1E-4 * u.deg)
            assert_allclose(icrs_coord.dec, roundtrip.dec, atol=1E-5 * u.deg)
            assert_allclose(icrs_coord.distance,
                            roundtrip.distance,
                            atol=1E-5 * u.kpc)
示例#39
0
def test_icrs_fk5():
    lines = get_pkg_data_contents('data/icrs_fk5.csv').split('\n')
    t = Table.read(lines, format='ascii', delimiter=',', guess=False)

    if N_ACCURACY_TESTS >= len(t):
        idxs = range(len(t))
    else:
        idxs = np.random.randint(len(t), size=N_ACCURACY_TESTS)

    diffarcsec1 = []
    diffarcsec2 = []
    for i in idxs:
        # Extract row
        r = t[int(i)]  # int here is to get around a py 3.x astropy.table bug

        # ICRS to FK5
        c1 = ICRS(ra=r['ra_in'] * u.deg, dec=r['dec_in'] * u.deg)
        c2 = c1.transform_to(FK5(equinox=Time(r['equinox_fk5'])))

        # Find difference
        diff = angular_separation(c2.ra.radian, c2.dec.radian,
                                  np.radians(r['ra_fk5']),
                                  np.radians(r['dec_fk5']))

        diffarcsec1.append(np.degrees(diff) * 3600.)

        # FK5 to ICRS
        c1 = FK5(ra=r['ra_in'] * u.deg,
                 dec=r['dec_in'] * u.deg,
                 equinox=Time(r['equinox_fk5']))
        c2 = c1.transform_to(ICRS)

        # Find difference
        diff = angular_separation(c2.ra.radian, c2.dec.radian,
                                  np.radians(r['ra_icrs']),
                                  np.radians(r['dec_icrs']))

        diffarcsec2.append(np.degrees(diff) * 3600.)

    np.testing.assert_array_less(diffarcsec1, TOLERANCE)
    np.testing.assert_array_less(diffarcsec2, TOLERANCE)
示例#40
0
def test_icrs_fk5():
    lines = get_pkg_data_contents('data/icrs_fk5.csv').split('\n')
    t = Table.read(lines, format='ascii', delimiter=',', guess=False)

    if N_ACCURACY_TESTS >= len(t):
        idxs = range(len(t))
    else:
        idxs = np.random.randint(len(t), size=N_ACCURACY_TESTS)

    diffarcsec1 = []
    diffarcsec2 = []
    for i in idxs:
        # Extract row
        r = t[int(i)]  # int here is to get around a py 3.x astropy.table bug

        # ICRS to FK5
        c1 = ICRS(ra=r['ra_in']*u.deg, dec=r['dec_in']*u.deg)
        c2 = c1.transform_to(FK5(equinox=Time(r['equinox_fk5'], scale='utc')))

        # Find difference
        diff = angular_separation(c2.ra.radian, c2.dec.radian,
                                  np.radians(r['ra_fk5']),
                                  np.radians(r['dec_fk5']))

        diffarcsec1.append(np.degrees(diff) * 3600.)

        # FK5 to ICRS
        c1 = FK5(ra=r['ra_in']*u.deg, dec=r['dec_in']*u.deg,
                 equinox=Time(r['equinox_fk5'], scale='utc'))
        c2 = c1.transform_to(ICRS)

        # Find difference
        diff = angular_separation(c2.ra.radian, c2.dec.radian,
                                  np.radians(r['ra_icrs']),
                                  np.radians(r['dec_icrs']))

        diffarcsec2.append(np.degrees(diff) * 3600.)

    np.testing.assert_array_less(diffarcsec1, TOLERANCE)
    np.testing.assert_array_less(diffarcsec2, TOLERANCE)
def test_api():
    # transform observed Barycentric velocities to full-space Galactocentric
    with galactocentric_frame_defaults.set('latest'):
        gc_frame = Galactocentric()
        icrs = ICRS(ra=151. * u.deg,
                    dec=-16 * u.deg,
                    distance=101 * u.pc,
                    pm_ra_cosdec=21 * u.mas / u.yr,
                    pm_dec=-71 * u.mas / u.yr,
                    radial_velocity=71 * u.km / u.s)
        icrs.transform_to(gc_frame)

        # transform a set of ICRS proper motions to Galactic
        icrs = ICRS(ra=151. * u.deg,
                    dec=-16 * u.deg,
                    pm_ra_cosdec=21 * u.mas / u.yr,
                    pm_dec=-71 * u.mas / u.yr)
        icrs.transform_to(Galactic)

        # transform a Barycentric RV to a GSR RV
        icrs = ICRS(ra=151. * u.deg,
                    dec=-16 * u.deg,
                    distance=1. * u.pc,
                    pm_ra_cosdec=0 * u.mas / u.yr,
                    pm_dec=0 * u.mas / u.yr,
                    radial_velocity=71 * u.km / u.s)
        icrs.transform_to(Galactocentric)
def test_xhip_galactic(hip, ra, dec, pmra, pmdec, glon, glat, dist, pmglon, pmglat, rv, U, V, W):
    i = ICRS(ra*u.deg, dec*u.deg, dist*u.pc,
             pm_ra_cosdec=pmra*u.marcsec/u.yr, pm_dec=pmdec*u.marcsec/u.yr,
             radial_velocity=rv*u.km/u.s)
    g = i.transform_to(Galactic)

    # precision is limited by 2-deciimal digit string representation of pms
    assert quantity_allclose(g.pm_l_cosb, pmglon*u.marcsec/u.yr, atol=.01*u.marcsec/u.yr)
    assert quantity_allclose(g.pm_b, pmglat*u.marcsec/u.yr, atol=.01*u.marcsec/u.yr)

    # make sure UVW also makes sense
    uvwg = g.cartesian.differentials['s']
    # precision is limited by 1-decimal digit string representation of vels
    assert quantity_allclose(uvwg.d_x, U*u.km/u.s, atol=.1*u.km/u.s)
    assert quantity_allclose(uvwg.d_y, V*u.km/u.s, atol=.1*u.km/u.s)
    assert quantity_allclose(uvwg.d_z, W*u.km/u.s, atol=.1*u.km/u.s)
def test_numerical_limits(distance):
    """
    Tests the numerical stability of the default settings for the finite
    difference transformation calculation.  This is *known* to fail for at
    >~1kpc, but this may be improved in future versions.
    """
    time = Time('J2017') + np.linspace(-.5, .5, 100)*u.year

    icoo = ICRS(ra=0*u.deg, dec=10*u.deg, distance=distance,
                pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
                radial_velocity=0*u.km/u.s)
    gcoo = icoo.transform_to(GCRS(obstime=time))
    rv = gcoo.radial_velocity.to('km/s')

    # if its a lot bigger than this - ~the maximal velocity shift along
    # the direction above with a small allowance for noise - finite-difference
    # rounding errors have ruined the calculation
    assert np.ptp(rv) < 65*u.km/u.s
def test_numerical_limits(distance):
    """
    Tests the numerical stability of the default settings for the finite
    difference transformation calculation.  This is *known* to fail for at
    >~1kpc, but this may be improved in future versions.
    """
    time = Time('J2017') + np.linspace(-.5, .5, 100)*u.year

    icoo = ICRS(ra=0*u.deg, dec=10*u.deg, distance=distance,
                pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
                radial_velocity=0*u.km/u.s)
    gcoo = icoo.transform_to(GCRS(obstime=time))
    rv = gcoo.radial_velocity.to('km/s')

    # if its a lot bigger than this - ~the maximal velocity shift along
    # the direction above with a small allowance for noise - finite-difference
    # rounding errors have ruined the calculation
    assert np.ptp(rv) < 65*u.km/u.s
def test_skyoffset_functional_ra_dec():
    # we do the 12)[1:-1] business because sometimes machine precision issues
    # lead to results that are either ~0 or ~360, which mucks up the final
    # comparison and leads to spurious failures.  So this just avoids that by
    # staying away from the edges
    input_ra = np.linspace(0, 360, 12)[1:-1]
    input_dec = np.linspace(-90, 90, 12)[1:-1]
    input_ra_rad = np.deg2rad(input_ra)
    input_dec_rad = np.deg2rad(input_dec)
    icrs_coord = ICRS(ra=input_ra*u.deg,
                      dec=input_dec*u.deg,
                      distance=1.*u.kpc)

    for ra in np.linspace(0, 360, 10):
        for dec in np.linspace(-90, 90, 5):
            # expected rotation
            dec_rad = -np.deg2rad(dec)
            ra_rad = np.deg2rad(ra)
            expected_x = (-np.sin(input_dec_rad) * np.sin(dec_rad) +
                           np.cos(input_ra_rad) * np.cos(input_dec_rad) * np.cos(dec_rad) * np.cos(ra_rad) +
                           np.sin(input_ra_rad) * np.cos(input_dec_rad) * np.cos(dec_rad) * np.sin(ra_rad))
            expected_y = (np.sin(input_ra_rad) * np.cos(input_dec_rad) * np.cos(ra_rad) -
                          np.cos(input_ra_rad) * np.cos(input_dec_rad) * np.sin(ra_rad))
            expected_z = (np.sin(input_dec_rad) * np.cos(dec_rad) +
                          np.sin(dec_rad) * np.cos(ra_rad) * np.cos(input_ra_rad) * np.cos(input_dec_rad) +
                          np.sin(dec_rad) * np.sin(ra_rad) * np.sin(input_ra_rad) * np.cos(input_dec_rad))
            expected = SkyCoord(x=expected_x,
                                y=expected_y,
                                z=expected_z, unit='kpc', representation_type='cartesian')
            expected_xyz = expected.cartesian.xyz

            # actual transformation to the frame
            skyoffset_frame = SkyOffsetFrame(origin=ICRS(ra*u.deg, dec*u.deg))
            actual = icrs_coord.transform_to(skyoffset_frame)
            actual_xyz = actual.cartesian.xyz

            # back to ICRS
            roundtrip = actual.transform_to(ICRS)

            # Verify
            assert_allclose(actual_xyz, expected_xyz, atol=1E-5*u.kpc)
            assert_allclose(icrs_coord.ra, roundtrip.ra, atol=1E-4*u.deg)
            assert_allclose(icrs_coord.dec, roundtrip.dec, atol=1E-5*u.deg)
            assert_allclose(icrs_coord.distance, roundtrip.distance, atol=1E-5*u.kpc)
示例#46
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)
示例#47
0
def test_api():
    # transform observed Barycentric velocities to full-space Galactocentric
    gc_frame = Galactocentric()
    icrs = ICRS(ra=151.*u.deg, dec=-16*u.deg, distance=101*u.pc,
                pm_ra_cosdec=21*u.mas/u.yr, pm_dec=-71*u.mas/u.yr,
                radial_velocity=71*u.km/u.s)
    icrs.transform_to(gc_frame)

    # transform a set of ICRS proper motions to Galactic
    icrs = ICRS(ra=151.*u.deg, dec=-16*u.deg,
                pm_ra_cosdec=21*u.mas/u.yr, pm_dec=-71*u.mas/u.yr)
    icrs.transform_to(Galactic)

    # transform a Barycentric RV to a GSR RV
    icrs = ICRS(ra=151.*u.deg, dec=-16*u.deg, distance=1.*u.pc,
                pm_ra_cosdec=0*u.mas/u.yr, pm_dec=0*u.mas/u.yr,
                radial_velocity=71*u.km/u.s)
    icrs.transform_to(Galactocentric)