def test_varying_transform_pc(): varying_matrix_lt = [ rotation_matrix(a)[:2, :2] for a in np.linspace(0, 90, 10) ] * u.arcsec vct = VaryingCelestialTransform(crpix=(5, 5) * u.pix, cdelt=(1, 1) * u.arcsec / u.pix, crval_table=(0, 0) * u.arcsec, pc_table=varying_matrix_lt, lon_pole=180 * u.deg) trans5 = vct.transform_at_index(5) assert isinstance(trans5, CompoundModel) # Verify that we have the 5th matrix in the series affine = trans5.left.left.right assert isinstance(affine, m.AffineTransformation2D) assert u.allclose(affine.matrix, varying_matrix_lt[5]) # x.shape=(1,), y.shape=(1,), z.shape=(1,) pixel = (0 * u.pix, 0 * u.pix, 5 * u.pix) world = vct(*pixel) assert np.array(world[0]).shape == () assert u.allclose(world, (359.99804329 * u.deg, 0.00017119 * u.deg)) assert u.allclose(vct.inverse(*world, 5 * u.pix), pixel[:2], atol=0.01 * u.pix)
def test_vct_errors(): with pytest.raises(ValueError, match="pc table should be"): VaryingCelestialTransform(crpix=(5, 5), cdelt=(1, 1), crval_table=(0, 0), pc_table=[[1, 2, 3], [4, 4, 6], [7, 8, 9]], lon_pole=180) with pytest.raises(ValueError, match="crval table should be"): VaryingCelestialTransform(crpix=(5, 5), cdelt=(1, 1), crval_table=((0, 0, 0), ), pc_table=[[1, 2], [4, 4]], lon_pole=180) with pytest.raises( ValueError, match="The shape of the pc and crval tables should match"): VaryingCelestialTransform(crpix=(5, 5), cdelt=(1, 1), crval_table=((0, 0), (1, 1), (2, 2)), pc_table=[[[1, 2], [4, 4]], [[1, 2], [3, 4]]], lon_pole=180) with pytest.raises(TypeError, match="projection keyword should"): VaryingCelestialTransform(crpix=(5, 5), cdelt=(1, 1), crval_table=((0, 0), (1, 1)), pc_table=[[[1, 2], [4, 4]], [[1, 2], [3, 4]]], lon_pole=180, projection=ValueError)
def test_varying_transform_pc_unitless(): varying_matrix_lt = [ rotation_matrix(a)[:2, :2] for a in np.linspace(0, 90, 10) ] vct = VaryingCelestialTransform( crpix=(5, 5), # without units everything is deg, so make this arcsec in deg cdelt=((1, 1) * u.arcsec).to_value(u.deg), crval_table=(0, 0), pc_table=varying_matrix_lt, lon_pole=180) trans5 = vct.transform_at_index(5) assert isinstance(trans5, CompoundModel) # Verify that we have the 5th matrix in the series affine = trans5.left.left.right assert isinstance(affine, m.AffineTransformation2D) assert u.allclose(affine.matrix, varying_matrix_lt[5]) pixel = (0, 0, 5) world = vct(*pixel) assert np.allclose(world, (359.99804329, 0.00017119)) assert np.allclose(vct.inverse(*world, 5), pixel[:2], atol=0.01)
def test_varying_transform_pc_shapes(pixel, lon_shape): varying_matrix_lt = [ rotation_matrix(a)[:2, :2] for a in np.linspace(0, 90, 10) ] * u.arcsec vct = VaryingCelestialTransform(crpix=(5, 5) * u.pix, cdelt=(1, 1) * u.arcsec / u.pix, crval_table=(0, 0) * u.arcsec, pc_table=varying_matrix_lt, lon_pole=180 * u.deg) world = vct(*pixel) assert np.array(world[0]).shape == lon_shape new_pixel = vct.inverse(*world, pixel[-1]) assert u.allclose(new_pixel, np.broadcast_arrays(*pixel, subok=True)[:2], atol=0.01 * u.pix)
def test_vct_shape_errors(): pc_table = [rotation_matrix(a)[:2, :2] for a in np.linspace(0, 90, 15)] * u.arcsec pc_table = pc_table.reshape((5, 3, 2, 2)) crval_table = list(zip(np.arange(1, 16), np.arange(16, 31))) * u.arcsec crval_table = crval_table.reshape((5, 3, 2)) kwargs = dict(crpix=(5, 5) * u.pix, cdelt=(1, 1) * u.arcsec / u.pix, lon_pole=180 * u.deg) with pytest.raises(ValueError, match="only be constructed with a one dimensional"): VaryingCelestialTransform(crval_table=crval_table, pc_table=pc_table, **kwargs) with pytest.raises(ValueError, match="only be constructed with a one dimensional"): VaryingCelestialTransformSlit(crval_table=crval_table, pc_table=pc_table, **kwargs) with pytest.raises(ValueError, match="only be constructed with a two dimensional"): VaryingCelestialTransform2D(crval_table=crval_table[0], pc_table=pc_table[0], **kwargs) with pytest.raises(ValueError, match="only be constructed with a two dimensional"): VaryingCelestialTransformSlit2D(crval_table=crval_table[0], pc_table=pc_table[0], **kwargs)
def vct_crval(): crval_table = ((0, 1), (2, 3), (4, 5)) * u.arcsec return VaryingCelestialTransform(crpix=(5, 5) * u.pix, cdelt=(1, 1) * u.arcsec / u.pix, crval_table=crval_table, pc_table=np.identity(2) * u.arcsec, lon_pole=180 * u.deg)
def test_roundtrip_vct(): varying_matrix_lt = [ rotation_matrix(a)[:2, :2] for a in np.linspace(0, 90, 10) ] * u.arcsec vct = VaryingCelestialTransform(crpix=(5, 5) * u.pix, cdelt=(1, 1) * u.arcsec / u.pix, crval_table=(0, 0) * u.arcsec, pc_table=varying_matrix_lt, lon_pole=180 * u.deg) new_vct = roundtrip_object(vct) assert isinstance(new_vct, VaryingCelestialTransform) new_ivct = roundtrip_object(vct.inverse) assert isinstance(new_ivct, InverseVaryingCelestialTransform) assert u.allclose(u.Quantity(new_vct.crpix), (5, 5) * u.pix) assert u.allclose(u.Quantity(new_ivct.crpix), (5, 5) * u.pix) assert u.allclose(u.Quantity(new_vct.pc_table), varying_matrix_lt) assert u.allclose(u.Quantity(new_ivct.pc_table), varying_matrix_lt) pixel = (0 * u.pix, 0 * u.pix, 5 * u.pix) world = new_vct(*pixel) assert u.allclose(world, (359.99804329 * u.deg, 0.00017119 * u.deg)) assert u.allclose(new_ivct(*world, 5 * u.pix), pixel[:2], atol=0.01 * u.pix)
def test_varying_transform_crval(): crval_table = ((0, 1), (2, 3), (4, 5)) * u.arcsec vct = VaryingCelestialTransform(crpix=(5, 5) * u.pix, cdelt=(1, 1) * u.arcsec / u.pix, crval_table=crval_table, pc_table=np.identity(2) * u.arcsec, lon_pole=180 * u.deg) trans2 = vct.transform_at_index(2) assert isinstance(trans2, CompoundModel) # Verify that we have the 2nd crval pair in the series crval1 = trans2.right.lon crval2 = trans2.right.lat assert u.allclose(crval1, crval_table[2][0]) assert u.allclose(crval2, crval_table[2][1]) pixel = (0 * u.pix, 0 * u.pix, 2 * u.pix) world = vct(*pixel) assert u.allclose(world, (3.59999722e+02, 2.78325906e-13) * u.deg) assert u.allclose(vct.inverse(*world, 2 * u.pix), pixel[:2], atol=0.01 * u.pix)
def test_coupled_sep(linear_time): if not hasattr(Model, "_calculate_separability_matrix"): pytest.skip() crval_table = ((0, 1), (2, 3), (4, 5)) * u.arcsec vct = VaryingCelestialTransform(crpix=(5, 5) * u.pix, cdelt=(1, 1) * u.arcsec / u.pix, crval_table=crval_table, pc_table=np.identity(2) * u.arcsec, lon_pole=180 * u.deg) tfrm = CoupledCompoundModel("&", vct, linear_time, shared_inputs=1) smatrix = separability_matrix(tfrm) assert np.allclose( smatrix, np.array([[True, True, True], [True, True, True], [False, False, True]]))