def test_time_inputs(): """ Test validation and conversion of inputs for equinox and obstime attributes. """ from astropy.time import Time from astropy.coordinates.builtin_frames import FK4 c = FK4(1 * u.deg, 2 * u.deg, equinox='J2001.5', obstime='2000-01-01 12:00:00') assert c.equinox == Time('J2001.5') assert c.obstime == Time('2000-01-01 12:00:00') with pytest.raises(ValueError) as err: c = FK4(1 * u.deg, 2 * u.deg, equinox=1.5) assert 'Invalid time input' in str(err.value) with pytest.raises(ValueError) as err: c = FK4(1 * u.deg, 2 * u.deg, obstime='hello') assert 'Invalid time input' in str(err.value) # A vector time should work if the shapes match, but we don't automatically # broadcast the basic data (just like time). FK4([1, 2] * u.deg, [2, 3] * u.deg, obstime=['J2000', 'J2001']) with pytest.raises(ValueError) as err: FK4(1 * u.deg, 2 * u.deg, obstime=['J2000', 'J2001']) assert 'shape' in str(err.value)
def test_setitem_velocities(): """Test different flavors of item setting for a Frame with a velocity. """ from astropy.coordinates.builtin_frames import FK4 sc0 = FK4([1, 2]*u.deg, [3, 4]*u.deg, radial_velocity=[1, 2]*u.km/u.s, obstime='B1950') sc2 = FK4([10, 20]*u.deg, [30, 40]*u.deg, radial_velocity=[10, 20]*u.km/u.s, obstime='B1950') sc1 = sc0.copy() sc1[1] = sc2[0] assert np.allclose(sc1.ra.to_value(u.deg), [1, 10]) assert np.allclose(sc1.dec.to_value(u.deg), [3, 30]) assert np.allclose(sc1.radial_velocity.to_value(u.km / u.s), [1, 10]) assert sc1.obstime == sc2.obstime assert sc1.name == 'fk4' sc1 = sc0.copy() sc1[:] = sc2[0] assert np.allclose(sc1.ra.to_value(u.deg), [10, 10]) assert np.allclose(sc1.dec.to_value(u.deg), [30, 30]) assert np.allclose(sc1.radial_velocity.to_value(u.km / u.s), [10, 10]) sc1 = sc0.copy() sc1[:] = sc2[:] assert np.allclose(sc1.ra.to_value(u.deg), [10, 20]) assert np.allclose(sc1.dec.to_value(u.deg), [30, 40]) assert np.allclose(sc1.radial_velocity.to_value(u.km / u.s), [10, 20]) sc1 = sc0.copy() sc1[[1, 0]] = sc2[:] assert np.allclose(sc1.ra.to_value(u.deg), [20, 10]) assert np.allclose(sc1.dec.to_value(u.deg), [40, 30]) assert np.allclose(sc1.radial_velocity.to_value(u.km / u.s), [20, 10])
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)
def test_create_nodata_frames(): from astropy.coordinates.builtin_frames import ICRS, FK4, FK5 i = ICRS() assert len(i.get_frame_attr_names()) == 0 f5 = FK5() assert f5.equinox == FK5.get_frame_attr_names()['equinox'] f4 = FK4() assert f4.equinox == FK4.get_frame_attr_names()['equinox'] # obstime is special because it's a property that uses equinox if obstime is not set assert f4.obstime in (FK4.get_frame_attr_names()['obstime'], FK4.get_frame_attr_names()['equinox'])
def test_equivalent_frames(): from astropy.coordinates import SkyCoord from astropy.coordinates.builtin_frames import ICRS, FK4, FK5, AltAz i = ICRS() i2 = ICRS(1 * u.deg, 2 * u.deg) assert i.is_equivalent_frame(i) assert i.is_equivalent_frame(i2) with pytest.raises(TypeError): assert i.is_equivalent_frame(10) with pytest.raises(TypeError): assert i2.is_equivalent_frame(SkyCoord(i2)) f0 = FK5() # this J2000 is TT f1 = FK5(equinox='J2000') f2 = FK5(1 * u.deg, 2 * u.deg, equinox='J2000') f3 = FK5(equinox='J2010') f4 = FK4(equinox='J2010') assert f1.is_equivalent_frame(f1) assert not i.is_equivalent_frame(f1) assert f0.is_equivalent_frame(f1) assert f1.is_equivalent_frame(f2) assert not f1.is_equivalent_frame(f3) assert not f3.is_equivalent_frame(f4) aa1 = AltAz() aa2 = AltAz(obstime='J2010') assert aa2.is_equivalent_frame(aa2) assert not aa1.is_equivalent_frame(i) assert not aa1.is_equivalent_frame(aa2)
def test_m31_coord_transforms(fromsys, tosys, fromcoo, tocoo): """ This tests a variety of coordinate conversions for the Chandra point-source catalog location of M31 from NED. """ coo1 = fromsys(ra=fromcoo[0] * u.deg, dec=fromcoo[1] * u.deg, distance=m31_dist) coo2 = coo1.transform_to(tosys) if tosys is FK4: coo2_prec = coo2.transform_to(FK4(equinox=Time('B1950', scale='utc'))) assert (coo2_prec.spherical.lon - tocoo[0] * u.deg) < convert_precision # <1 arcsec assert (coo2_prec.spherical.lat - tocoo[1] * u.deg) < convert_precision else: assert (coo2.spherical.lon - tocoo[0] * u.deg) < convert_precision # <1 arcsec assert (coo2.spherical.lat - tocoo[1] * u.deg) < convert_precision assert coo1.distance.unit == u.kpc assert coo2.distance.unit == u.kpc assert m31_dist.unit == u.kpc assert (coo2.distance - m31_dist) < dist_precision # check round-tripping coo1_2 = coo2.transform_to(fromsys) assert (coo1_2.spherical.lon - fromcoo[0] * u.deg) < roundtrip_precision assert (coo1_2.spherical.lat - fromcoo[1] * u.deg) < roundtrip_precision assert (coo1_2.distance - m31_dist) < dist_precision
def test_setitem_no_velocity(): """Test different flavors of item setting for a Frame without a velocity. """ from astropy.coordinates.builtin_frames import FK4 obstime = 'B1955' sc0 = FK4([1, 2]*u.deg, [3, 4]*u.deg, obstime=obstime) sc2 = FK4([10, 20]*u.deg, [30, 40]*u.deg, obstime=obstime) sc1 = sc0.copy() sc1_repr = repr(sc1) assert 'representation' in sc1.cache sc1[1] = sc2[0] assert sc1.cache == {} assert repr(sc2) != sc1_repr assert np.allclose(sc1.ra.to_value(u.deg), [1, 10]) assert np.allclose(sc1.dec.to_value(u.deg), [3, 30]) assert sc1.obstime == sc2.obstime assert sc1.name == 'fk4' sc1 = sc0.copy() sc1[:] = sc2[0] assert np.allclose(sc1.ra.to_value(u.deg), [10, 10]) assert np.allclose(sc1.dec.to_value(u.deg), [30, 30]) sc1 = sc0.copy() sc1[:] = sc2[:] assert np.allclose(sc1.ra.to_value(u.deg), [10, 20]) assert np.allclose(sc1.dec.to_value(u.deg), [30, 40]) sc1 = sc0.copy() sc1[[1, 0]] = sc2[:] assert np.allclose(sc1.ra.to_value(u.deg), [20, 10]) assert np.allclose(sc1.dec.to_value(u.deg), [40, 30]) # Works for array-valued obstime so long as they are considered equivalent sc1 = FK4(sc0.ra, sc0.dec, obstime=[obstime, obstime]) sc1[0] = sc2[0] # Multidimensional coordinates sc1 = FK4([[1, 2], [3, 4]] * u.deg, [[5, 6], [7, 8]] * u.deg) sc2 = FK4([[10, 20], [30, 40]] * u.deg, [[50, 60], [70, 80]] * u.deg) sc1[0] = sc2[0] assert np.allclose(sc1.ra.to_value(u.deg), [[10, 20], [3, 4]]) assert np.allclose(sc1.dec.to_value(u.deg), [[50, 60], [7, 8]])
def test_setitem_exceptions(): from astropy.coordinates.builtin_frames import FK4, Galactic obstime = 'B1950' sc0 = FK4([1, 2]*u.deg, [3, 4]*u.deg) sc2 = FK4([10, 20]*u.deg, [30, 40]*u.deg, obstime=obstime) sc1 = Galactic(sc0.ra, sc0.dec) with pytest.raises(TypeError, match='can only set from object of same class: ' 'Galactic vs. FK4'): sc1[0] = sc2[0] sc1 = FK4(sc0.ra, sc0.dec, obstime='B2001') with pytest.raises(ValueError, match='can only set frame item from an equivalent frame'): sc1[0] = sc2[0] sc1 = FK4(sc0.ra[0], sc0.dec[0], obstime=obstime) with pytest.raises(TypeError, match="scalar 'FK4' frame object does not support " 'item assignment'): sc1[0] = sc2[0] sc1 = FK4(obstime=obstime) with pytest.raises(ValueError, match='cannot set frame which has no data'): sc1[0] = sc2[0] sc1 = FK4(sc0.ra, sc0.dec, obstime=[obstime, 'B1980']) with pytest.raises(ValueError, match='can only set frame item from an equivalent frame'): sc1[0] = sc2[0] # Wrong shape sc1 = FK4([sc0.ra], [sc0.dec], obstime=[obstime, 'B1980']) with pytest.raises(ValueError, match='can only set frame item from an equivalent frame'): sc1[0] = sc2[0]
def test_precession(): """ Ensures that FK4 and FK5 coordinates precess their equinoxes """ j2000 = Time('J2000') b1950 = Time('B1950') j1975 = Time('J1975') b1975 = Time('B1975') fk4 = FK4(ra=1*u.radian, dec=0.5*u.radian) assert fk4.equinox.byear == b1950.byear fk4_2 = fk4.transform_to(FK4(equinox=b1975)) assert fk4_2.equinox.byear == b1975.byear fk5 = FK5(ra=1*u.radian, dec=0.5*u.radian) assert fk5.equinox.jyear == j2000.jyear fk5_2 = fk5.transform_to(FK4(equinox=j1975)) assert fk5_2.equinox.jyear == j1975.jyear
def test_obstime(): """ Checks to make sure observation time is accounted for at least in FK4 <-> ICRS transformations """ b1950 = Time('B1950') j1975 = Time('J1975') fk4_50 = FK4(ra=1*u.deg, dec=2*u.deg, obstime=b1950) fk4_75 = FK4(ra=1*u.deg, dec=2*u.deg, obstime=j1975) icrs_50 = fk4_50.transform_to(ICRS()) icrs_75 = fk4_75.transform_to(ICRS()) # now check that the resulting coordinates are *different* - they should be, # because the obstime is different assert icrs_50.ra.degree != icrs_75.ra.degree assert icrs_50.dec.degree != icrs_75.dec.degree
def test_fk4_no_e_fk4(): lines = get_pkg_data_contents('data/fk4_no_e_fk4.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 # FK4 to FK4NoETerms c1 = FK4(ra=r['ra_in'] * u.deg, dec=r['dec_in'] * u.deg, obstime=Time(r['obstime'])) c2 = c1.transform_to(FK4NoETerms()) # Find difference diff = angular_separation(c2.ra.radian, c2.dec.radian, np.radians(r['ra_fk4ne']), np.radians(r['dec_fk4ne'])) diffarcsec1.append(np.degrees(diff) * 3600.) # FK4NoETerms to FK4 c1 = FK4NoETerms(ra=r['ra_in'] * u.deg, dec=r['dec_in'] * u.deg, obstime=Time(r['obstime'])) c2 = c1.transform_to(FK4()) # Find difference diff = angular_separation(c2.ra.radian, c2.dec.radian, np.radians(r['ra_fk4']), np.radians(r['dec_fk4'])) diffarcsec2.append(np.degrees(diff) * 3600.) np.testing.assert_array_less(diffarcsec1, TOLERANCE) np.testing.assert_array_less(diffarcsec2, TOLERANCE)
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)
def test_fk5_galactic(): """ Check that FK5 -> Galactic gives the same as FK5 -> FK4 -> Galactic. """ fk5 = FK5(ra=1*u.deg, dec=2*u.deg) direct = fk5.transform_to(Galactic()) indirect = fk5.transform_to(FK4()).transform_to(Galactic()) assert direct.separation(indirect).degree < 1.e-10 direct = fk5.transform_to(Galactic()) indirect = fk5.transform_to(FK4NoETerms()).transform_to(Galactic()) assert direct.separation(indirect).degree < 1.e-10
def test_celestial_frame_to_wcs(): # Import astropy.coordinates here to avoid circular imports from astropy.coordinates import ICRS, ITRS, FK5, FK4, FK4NoETerms, Galactic, BaseCoordinateFrame class FakeFrame(BaseCoordinateFrame): pass frame = FakeFrame() with pytest.raises(ValueError) as exc: celestial_frame_to_wcs(frame) assert exc.value.args[0] == ("Could not determine WCS corresponding to " "the specified coordinate frame.") frame = ICRS() mywcs = celestial_frame_to_wcs(frame) mywcs.wcs.set() assert tuple(mywcs.wcs.ctype) == ('RA---TAN', 'DEC--TAN') assert mywcs.wcs.radesys == 'ICRS' assert np.isnan(mywcs.wcs.equinox) assert mywcs.wcs.lonpole == 180 assert mywcs.wcs.latpole == 0 frame = FK5(equinox='J1987') mywcs = celestial_frame_to_wcs(frame) assert tuple(mywcs.wcs.ctype) == ('RA---TAN', 'DEC--TAN') assert mywcs.wcs.radesys == 'FK5' assert mywcs.wcs.equinox == 1987. frame = FK4(equinox='B1982') mywcs = celestial_frame_to_wcs(frame) assert tuple(mywcs.wcs.ctype) == ('RA---TAN', 'DEC--TAN') assert mywcs.wcs.radesys == 'FK4' assert mywcs.wcs.equinox == 1982. frame = FK4NoETerms(equinox='B1982') mywcs = celestial_frame_to_wcs(frame) assert tuple(mywcs.wcs.ctype) == ('RA---TAN', 'DEC--TAN') assert mywcs.wcs.radesys == 'FK4-NO-E' assert mywcs.wcs.equinox == 1982. frame = Galactic() mywcs = celestial_frame_to_wcs(frame) assert tuple(mywcs.wcs.ctype) == ('GLON-TAN', 'GLAT-TAN') assert mywcs.wcs.radesys == '' assert np.isnan(mywcs.wcs.equinox) frame = Galactic() mywcs = celestial_frame_to_wcs(frame, projection='CAR') assert tuple(mywcs.wcs.ctype) == ('GLON-CAR', 'GLAT-CAR') assert mywcs.wcs.radesys == '' assert np.isnan(mywcs.wcs.equinox) frame = Galactic() mywcs = celestial_frame_to_wcs(frame, projection='CAR') mywcs.wcs.crval = [100, -30] mywcs.wcs.set() assert_allclose((mywcs.wcs.lonpole, mywcs.wcs.latpole), (180, 60)) frame = ITRS(obstime=Time('2017-08-17T12:41:04.43')) mywcs = celestial_frame_to_wcs(frame, projection='CAR') assert tuple(mywcs.wcs.ctype) == ('TLON-CAR', 'TLAT-CAR') assert mywcs.wcs.radesys == 'ITRS' assert mywcs.wcs.dateobs == '2017-08-17T12:41:04.430' frame = ITRS() mywcs = celestial_frame_to_wcs(frame, projection='CAR') assert tuple(mywcs.wcs.ctype) == ('TLON-CAR', 'TLAT-CAR') assert mywcs.wcs.radesys == 'ITRS' assert mywcs.wcs.dateobs == Time('J2000').utc.fits