class transfunc: rep = r.CartesianRepresentation(np.arange(3)*u.pc) dif = r.CartesianDifferential(*np.arange(3, 6)*u.pc/u.Myr) rep0 = r.CartesianRepresentation(np.zeros(3)*u.pc) @classmethod def both(cls, coo, fr): # exchange x <-> z and offset M = np.array([[0., 0., 1.], [0., 1., 0.], [1., 0., 0.]]) return M, cls.rep.with_differentials(cls.dif) @classmethod def just_matrix(cls, coo, fr): # exchange x <-> z and offset M = np.array([[0., 0., 1.], [0., 1., 0.], [1., 0., 0.]]) return M, None @classmethod def no_matrix(cls, coo, fr): return None, cls.rep.with_differentials(cls.dif) @classmethod def no_pos(cls, coo, fr): return None, cls.rep0.with_differentials(cls.dif) @classmethod def no_vel(cls, coo, fr): return None, cls.rep
def setup_class(self): self.x = np.array([3., 5., 0.]) << u.m self.y = np.array([4., 12., 1.]) << u.m self.z = np.array([0., 0., 1.]) << u.m self.c = r.CartesianRepresentation(self.x, self.y, self.z) self.mask = np.array([False, False, True]) self.mx = Masked(self.x, self.mask) self.my = Masked(self.y, self.mask) self.mz = Masked(self.z, self.mask) self.mc = r.CartesianRepresentation(self.mx, self.my, self.mz)
def test_concatenate_representations_different_units(): from astropy.coordinates.funcs import concatenate_representations from astropy.coordinates import representation as r reps = [r.CartesianRepresentation([1, 2, 3.]*u.pc), r.CartesianRepresentation([1, 2, 3.]*u.kpc)] concat = concatenate_representations(reps) assert concat.shape == (2,) assert np.all(concat.xyz == ([[1., 2., 3.], [1000., 2000., 3000.]] * u.pc).T)
def test_transform_decos(): """ Tests the decorator syntax for creating transforms """ c1 = TCoo1(ra=1*u.deg, dec=2*u.deg) @frame_transform_graph.transform(t.FunctionTransform, TCoo1, TCoo2) def trans(coo1, f): return TCoo2(ra=coo1.ra, dec=coo1.dec * 2) c2 = c1.transform_to(TCoo2()) assert_allclose(c2.ra.degree, 1) assert_allclose(c2.dec.degree, 4) c3 = TCoo1(r.CartesianRepresentation(x=1*u.pc, y=1*u.pc, z=2*u.pc)) @frame_transform_graph.transform(t.StaticMatrixTransform, TCoo1, TCoo2) def matrix(): return [[2, 0, 0], [0, 1, 0], [0, 0, 1]] c4 = c3.transform_to(TCoo2()) assert_allclose(c4.cartesian.x, 2*u.pc) assert_allclose(c4.cartesian.y, 1*u.pc) assert_allclose(c4.cartesian.z, 2*u.pc)
def test_vel_transformation_obstime_err(): # TODO: replace after a final decision on PR #6280 from astropy.coordinates.sites import get_builtin_sites diff = r.CartesianDifferential([.1, .2, .3]*u.km/u.s) rep = r.CartesianRepresentation([1, 2, 3]*u.au, differentials=diff) loc = get_builtin_sites()['example_site'] aaf = AltAz(obstime='J2010', location=loc) aaf2 = AltAz(obstime=aaf.obstime + 3*u.day, location=loc) aaf3 = AltAz(obstime=aaf.obstime + np.arange(3)*u.day, location=loc) aaf4 = AltAz(obstime=aaf.obstime, location=loc) aa = aaf.realize_frame(rep) with pytest.raises(NotImplementedError) as exc: aa.transform_to(aaf2) assert 'cannot transform' in exc.value.args[0] with pytest.raises(NotImplementedError) as exc: aa.transform_to(aaf3) assert 'cannot transform' in exc.value.args[0] aa.transform_to(aaf4) aa.transform_to(ICRS())
def lsr_to_icrs(lsr_coord, icrs_frame): v_bary_gal = Galactic(lsr_coord.v_bary.to_cartesian()) v_bary_icrs = v_bary_gal.transform_to(icrs_frame) v_offset = v_bary_icrs.data.represent_as(r.CartesianDifferential) offset = r.CartesianRepresentation([0, 0, 0] * u.au, differentials=-v_offset) return None, offset
def test_representation_with_multiple_differentials(): from astropy.coordinates.builtin_frames import ICRS dif1 = r.CartesianDifferential([1, 2, 3]*u.km/u.s) dif2 = r.CartesianDifferential([1, 2, 3]*u.km/u.s**2) rep = r.CartesianRepresentation([1, 2, 3]*u.pc, differentials={'s': dif1, 's2': dif2}) # check warning is raised for a scalar with pytest.raises(ValueError): ICRS(rep)
def test_affine_transform_fail(transfunc): diff = r.CartesianDifferential(8, 9, 10, unit=u.pc/u.Myr) rep = r.CartesianRepresentation(5, 6, 7, unit=u.pc, differentials=diff) c = TCoo1(rep) # register and do the transformation and check against expected trans = t.AffineTransform(transfunc, TCoo1, TCoo2) trans.register(frame_transform_graph) with pytest.raises(ValueError): c.transform_to(TCoo2()) trans.unregister(frame_transform_graph)
def _get_matrix_vectors(gal_frame, inverse=False): """ Utility function: use the ``inverse`` argument to get the inverse transformation, matrix and offsets to go from external galaxy frame to ICRS. """ # this is based on the astropy Galactocentric class code # shorthand gcf = gal_frame # rotation matrix to align x(ICRS) with the vector to the galaxy center mat0 = np.array([[0., 1., 0.], [0., 0., 1.], [1., 0., 0.]]) # relabel axes so x points in RA, y in dec, z away from us mat1 = rotation_matrix(-gcf.gal_coord.dec, 'y') mat2 = rotation_matrix(gcf.gal_coord.ra, 'z') # construct transformation matrix and use it R = matrix_product(mat0, mat1, mat2) # Now define translation by distance to galaxy center - best defined in current sky coord system defined by R translation = r.CartesianRepresentation(gcf.gal_distance * [0., 0., 1.]) # Now rotate galaxy to right orientation pa_rot = rotation_matrix(-gcf.PA, 'z') inc_rot = rotation_matrix(gcf.inclination, 'y') H = matrix_product(inc_rot, pa_rot) # compute total matrices A = matrix_product(H, R) # Now we transform the translation vector between sky-aligned and galaxy-aligned frames offset = -translation.transform(H) if inverse: # the inverse of a rotation matrix is a transpose, which is much faster # and more stable to compute A = matrix_transpose(A) offset = (-offset).transform(A) # galvel is given in sky-aligned coords, need to transform to ICRS, so use R transpose R = matrix_transpose(R) offset_v = r.CartesianDifferential.from_cartesian( (gcf.galvel_heliocentric).to_cartesian().transform(R)) offset = offset.with_differentials(offset_v) else: # galvel is given in sky-aligned coords, need to transform to gal frame, so use H offset_v = r.CartesianDifferential.from_cartesian( (-gcf.galvel_heliocentric).to_cartesian().transform(H)) offset = offset.with_differentials(offset_v) return A, offset
def test_shorthand_representations(): from astropy.coordinates.builtin_frames import ICRS rep = r.CartesianRepresentation([1, 2, 3] * u.pc) dif = r.CartesianDifferential([1, 2, 3] * u.km / u.s) rep = rep.with_differentials(dif) icrs = ICRS(rep) sph = icrs.spherical assert isinstance(sph, r.SphericalRepresentation) assert isinstance(sph.differentials['s'], r.SphericalDifferential) sph = icrs.sphericalcoslat assert isinstance(sph, r.SphericalRepresentation) assert isinstance(sph.differentials['s'], r.SphericalCosLatDifferential)
def get_matrix_vectors(galactocentric_frame, inverse=False): """ Use the ``inverse`` argument to get the inverse transformation, matrix and offsets to go from Galactocentric to ICRS. """ # shorthand gcf = galactocentric_frame # rotation matrix to align x(ICRS) with the vector to the Galactic center mat1 = rotation_matrix(-gcf.galcen_coord.dec, 'y') mat2 = rotation_matrix(gcf.galcen_coord.ra, 'z') # extra roll away from the Galactic x-z plane mat0 = rotation_matrix(gcf.get_roll0() - gcf.roll, 'x') # construct transformation matrix and use it R = matrix_product(mat0, mat1, mat2) # Now need to translate by Sun-Galactic center distance around x' and # rotate about y' to account for tilt due to Sun's height above the plane translation = r.CartesianRepresentation(gcf.galcen_distance * [1., 0., 0.]) z_d = gcf.z_sun / gcf.galcen_distance H = rotation_matrix(-np.arcsin(z_d), 'y') # compute total matrices A = matrix_product(H, R) # Now we re-align the translation vector to account for the Sun's height # above the midplane offset = -translation.transform(H) if inverse: # the inverse of a rotation matrix is a transpose, which is much faster # and more stable to compute A = matrix_transpose(A) offset = (-offset).transform(A) offset_v = r.CartesianDifferential.from_cartesian( (-gcf.galcen_v_sun).to_cartesian().transform(A)) offset = offset.with_differentials(offset_v) else: offset = offset.with_differentials(gcf.galcen_v_sun) return A, offset
def test_too_many_differentials(): dif1 = r.CartesianDifferential(*np.arange(3, 6)*u.pc/u.Myr) dif2 = r.CartesianDifferential(*np.arange(3, 6)*u.pc/u.Myr**2) rep = r.CartesianRepresentation(np.arange(3)*u.pc, differentials={'s': dif1, 's2': dif2}) with pytest.raises(ValueError): c = TCoo1(rep) # register and do the transformation and check against expected trans = t.AffineTransform(transfunc.both, TCoo1, TCoo2) trans.register(frame_transform_graph) # Check that if frame somehow gets through to transformation, multiple # differentials are caught c = TCoo1(rep.without_differentials()) c._data = c._data.with_differentials({'s': dif1, 's2': dif2}) with pytest.raises(ValueError): c.transform_to(TCoo2()) trans.unregister(frame_transform_graph)
def galacticlsr_to_galactic(lsr_coord, galactic_frame): v_bary_gal = Galactic(lsr_coord.v_bary.to_cartesian()) v_offset = v_bary_gal.data.represent_as(r.CartesianDifferential) offset = r.CartesianRepresentation([0, 0, 0]*u.au, differentials=-v_offset) return None, offset
peculiar motion of the sun relative to the LSRK. """ # NOTE: To avoid a performance penalty at import time, we hard-code the ICRS # offsets here. The code to generate the offsets is provided for reproducibility. # GORDON1975_V_BARY = 20*u.km/u.s # GORDON1975_DIRECTION = FK4(ra=270*u.deg, dec=30*u.deg, equinox='B1900') # V_OFFSET_LSRK = ((GORDON1975_V_BARY * GORDON1975_DIRECTION.transform_to(ICRS()).data) # .represent_as(r.CartesianDifferential)) V_OFFSET_LSRK = r.CartesianDifferential([0.28999706839034606, -17.317264789717928, 10.00141199546947]*u.km/u.s) ICRS_LSRK_OFFSET = r.CartesianRepresentation([0, 0, 0]*u.au, differentials=V_OFFSET_LSRK) LSRK_ICRS_OFFSET = r.CartesianRepresentation([0, 0, 0]*u.au, differentials=-V_OFFSET_LSRK) @frame_transform_graph.transform(AffineTransform, ICRS, LSRK) def icrs_to_lsrk(icrs_coord, lsr_frame): return None, ICRS_LSRK_OFFSET @frame_transform_graph.transform(AffineTransform, LSRK, ICRS) def lsrk_to_icrs(lsr_coord, icrs_frame): return None, LSRK_ICRS_OFFSET # ------------------------------------------------------------------------------
return None, cls.rep.with_differentials(cls.dif) @classmethod def no_pos(cls, coo, fr): return None, cls.rep0.with_differentials(cls.dif) @classmethod def no_vel(cls, coo, fr): return None, cls.rep @pytest.mark.parametrize('transfunc', [transfunc.both, transfunc.no_matrix, transfunc.no_pos, transfunc.no_vel, transfunc.just_matrix]) @pytest.mark.parametrize('rep', [ r.CartesianRepresentation(5, 6, 7, unit=u.pc), r.CartesianRepresentation(5, 6, 7, unit=u.pc, differentials=r.CartesianDifferential(8, 9, 10, unit=u.pc/u.Myr)), r.CartesianRepresentation(5, 6, 7, unit=u.pc, differentials=r.CartesianDifferential(8, 9, 10, unit=u.pc/u.Myr)) .represent_as(r.CylindricalRepresentation, r.CylindricalDifferential) ]) def test_affine_transform_succeed(transfunc, rep): c = TCoo1(rep) # compute expected output M, offset = transfunc(c, TCoo2) _rep = rep.to_cartesian()
@classmethod def no_pos(cls, coo, fr): return None, cls.rep0.with_differentials(cls.dif) @classmethod def no_vel(cls, coo, fr): return None, cls.rep @pytest.mark.parametrize('transfunc', [ transfunc.both, transfunc.no_matrix, transfunc.no_pos, transfunc.no_vel, transfunc.just_matrix ]) @pytest.mark.parametrize('rep', [ r.CartesianRepresentation(5, 6, 7, unit=u.pc), r.CartesianRepresentation(5, 6, 7, unit=u.pc, differentials=r.CartesianDifferential( 8, 9, 10, unit=u.pc / u.Myr)), r.CartesianRepresentation(5, 6, 7, unit=u.pc, differentials=r.CartesianDifferential( 8, 9, 10, unit=u.pc / u.Myr)).represent_as( r.CylindricalRepresentation, r.CylindricalDifferential) ])
def test_concatenate_representations(): from astropy.coordinates.funcs import concatenate_representations from astropy.coordinates import representation as r reps = [r.CartesianRepresentation([1, 2, 3.]*u.kpc), r.SphericalRepresentation(lon=1*u.deg, lat=2.*u.deg, distance=10*u.pc), r.UnitSphericalRepresentation(lon=1*u.deg, lat=2.*u.deg), r.CartesianRepresentation(np.ones((3, 100)) * u.kpc), r.CartesianRepresentation(np.ones((3, 16, 8)) * u.kpc)] reps.append(reps[0].with_differentials( r.CartesianDifferential([1, 2, 3.] * u.km/u.s))) reps.append(reps[1].with_differentials( r.SphericalCosLatDifferential(1*u.mas/u.yr, 2*u.mas/u.yr, 3*u.km/u.s))) reps.append(reps[2].with_differentials( r.SphericalCosLatDifferential(1*u.mas/u.yr, 2*u.mas/u.yr, 3*u.km/u.s))) reps.append(reps[2].with_differentials( r.UnitSphericalCosLatDifferential(1*u.mas/u.yr, 2*u.mas/u.yr))) reps.append(reps[2].with_differentials( {'s': r.RadialDifferential(1*u.km/u.s)})) reps.append(reps[3].with_differentials( r.CartesianDifferential(*np.ones((3, 100)) * u.km/u.s))) reps.append(reps[4].with_differentials( r.CartesianDifferential(*np.ones((3, 16, 8)) * u.km/u.s))) # Test that combining all of the above with itself succeeds for rep in reps: if not rep.shape: expected_shape = (2, ) else: expected_shape = (2 * rep.shape[0], ) + rep.shape[1:] tmp = concatenate_representations((rep, rep)) assert tmp.shape == expected_shape if 's' in rep.differentials: assert tmp.differentials['s'].shape == expected_shape # Try combining 4, just for something different for rep in reps: if not rep.shape: expected_shape = (4, ) else: expected_shape = (4 * rep.shape[0], ) + rep.shape[1:] tmp = concatenate_representations((rep, rep, rep, rep)) assert tmp.shape == expected_shape if 's' in rep.differentials: assert tmp.differentials['s'].shape == expected_shape # Test that combining pairs fails with pytest.raises(TypeError): concatenate_representations((reps[0], reps[1])) with pytest.raises(ValueError): concatenate_representations((reps[0], reps[5])) # Check that passing in a single object fails with pytest.raises(TypeError): concatenate_representations(reps[0])