예제 #1
0
def test_AffineTransformation2D_inverse():
    # Test non-invertible model
    model1 = projections.AffineTransformation2D(matrix=[[1, 1], [1, 1]])

    with pytest.raises(InputParameterError):
        model1.inverse

    model2 = projections.AffineTransformation2D(matrix=[[1.2, 3.4], [5.6,
                                                                     7.8]],
                                                translation=[9.1, 10.11])

    # Coordinates for vertices of a rectangle
    rect = [[0, 0], [1, 0], [0, 3], [1, 3]]

    x, y = zip(*rect)

    x_new, y_new = model2.inverse(*model2(x, y))
    assert_allclose([x, y], [x_new, y_new], atol=1e-10)

    model3 = projections.AffineTransformation2D(
        matrix=[[1.2, 3.4], [5.6, 7.8]] * u.m, translation=[9.1, 10.11] * u.m)

    x_new, y_new = model3.inverse(*model3(x * u.m, y * u.m))
    assert_allclose([x, y], [x_new, y_new], atol=1e-10)

    model4 = projections.AffineTransformation2D(
        matrix=[[1.2, 3.4], [5.6, 7.8]] * u.m, translation=[9.1, 10.11] * u.km)
    with pytest.raises(ValueError) as err:
        model4.inverse(*model4(x * u.m, y * u.m))
    assert str(err.value) ==\
        "matrix and translation must have the same units."
예제 #2
0
def test_affine_with_quantities():
    x = 1
    y = 2
    xdeg = (x * u.pix).to(u.deg, equivalencies=u.pixel_scale(2.5 * u.deg / u.pix))
    ydeg = (y * u.pix).to(u.deg, equivalencies=u.pixel_scale(2.5 * u.deg / u.pix))
    xpix = x * u.pix
    ypix = y * u.pix

    # test affine with matrix only
    qaff = projections.AffineTransformation2D(matrix=[[1, 2], [2, 1]] * u.deg)
    with pytest.raises(ValueError):
        qx1, qy1 = qaff(xpix, ypix, equivalencies={
            'x': u.pixel_scale(2.5 * u.deg / u.pix),
            'y': u.pixel_scale(2.5 * u.deg / u.pix)})

    # test affine with matrix and translation
    qaff = projections.AffineTransformation2D(matrix=[[1, 2], [2, 1]] * u.deg,
                                              translation=[1, 2] * u.deg)
    qx1, qy1 = qaff(xpix, ypix, equivalencies={
        'x': u.pixel_scale(2.5 * u.deg / u.pix),
        'y': u.pixel_scale(2.5 * u.deg / u.pix)})
    aff = projections.AffineTransformation2D(matrix=[[1, 2], [2, 1]], translation=[1, 2])
    x1, y1 = aff(xdeg.value, ydeg.value)
    assert_quantity_allclose(qx1, x1 * u.deg)
    assert_quantity_allclose(qy1, y1 * u.deg)

    # test the case of WCS PC and CDELT transformations
    pc = np.array([[0.86585778922708, 0.50029020461607],
                   [-0.50029020461607, 0.86585778922708]])
    cdelt = np.array([[1, 3.0683055555556E-05], [3.0966944444444E-05, 1]])
    matrix = cdelt * pc
    qaff = projections.AffineTransformation2D(matrix=matrix * u.deg,
                                              translation=[0, 0] * u.deg)

    inv_matrix = np.linalg.inv(matrix)
    inv_qaff = projections.AffineTransformation2D(matrix=inv_matrix * u.pix,
                                                  translation=[0, 0] * u.pix)
    qaff.inverse = inv_qaff
    qx1, qy1 = qaff(xpix, ypix, equivalencies={
            'x': u.pixel_scale(1 * u.deg / u.pix),
            'y': u.pixel_scale(1 * u.deg / u.pix)})
    x1, y1 = qaff.inverse(qx1, qy1, equivalencies={
        'x': u.pixel_scale(1 * u.deg / u.pix),
        'y': u.pixel_scale(1 * u.deg / u.pix)})
    assert_quantity_allclose(x1, xpix)
    assert_quantity_allclose(y1, ypix)
예제 #3
0
def test_AffineTransformation2D():
    # Simple test with a scale and translation
    model = projections.AffineTransformation2D(matrix=[[2, 0], [0, 2]],
                                               translation=[1, 1])

    # Coordinates for vertices of a rectangle
    rect = [[0, 0], [1, 0], [0, 3], [1, 3]]

    x, y = zip(*rect)

    new_rect = np.vstack(model(x, y)).T

    assert np.all(new_rect == [[1, 1], [3, 1], [1, 7], [3, 7]])

    # Matrix validation error
    with pytest.raises(InputParameterError) as err:
        model.matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    assert str(err.value) ==\
        "Expected transformation matrix to be a 2x2 array"

    # Translation validation error
    with pytest.raises(InputParameterError) as err:
        model.translation = [1, 2, 3]
    assert str(err.value) ==\
        "Expected translation vector to be a 2 element row or column vector array"
    with pytest.raises(InputParameterError) as err:
        model.translation = [[1], [2]]
    assert str(err.value) ==\
        "Expected translation vector to be a 2 element row or column vector array"
    with pytest.raises(InputParameterError) as err:
        model.translation = [[1, 2, 3]]
    assert str(err.value) ==\
        "Expected translation vector to be a 2 element row or column vector array"

    # Incompatible shape error
    a = np.array([[1], [2], [3], [4]])
    b = a.ravel()
    with mk.patch.object(np, 'vstack', autospec=True,
                         side_effect=[a, b]) as mk_vstack:
        message = "Incompatible input shapes"
        with pytest.raises(ValueError) as err:
            model(x, y)
        assert str(err.value) == message
        with pytest.raises(ValueError) as err:
            model(x, y)
        assert str(err.value) == message

        assert mk_vstack.call_count == 2

    # Input shape evaluation error
    x = np.array([1, 2])
    y = np.array([1, 2, 3])
    with pytest.raises(ValueError) as err:
        model.evaluate(x, y, model.matrix, model.translation)
    assert str(err.value) ==\
        "Expected input arrays to have the same shape"
예제 #4
0
def test_AffineTransformation2D_inverse():
    # Test non-invertible model
    model1 = projections.AffineTransformation2D(
        matrix=[[1, 1], [1, 1]])

    with pytest.raises(InputParameterError):
        model1.inverse

    model2 = projections.AffineTransformation2D(
        matrix=[[1.2, 3.4], [5.6, 7.8]], translation=[9.1, 10.11])

    # Coordinates for vertices of a rectangle
    rect = [[0, 0], [1, 0], [0, 3], [1, 3]]

    x, y = zip(*rect)

    x_new, y_new = model2.inverse(*model2(x, y))

    assert_allclose([x, y], [x_new, y_new], atol=1e-10)
예제 #5
0
def test_AffineTransformation2D():
    # Simple test with a scale and translation
    model = projections.AffineTransformation2D(
        matrix=[[2, 0], [0, 2]], translation=[1, 1])

    # Coordinates for vertices of a rectangle
    rect = [[0, 0], [1, 0], [0, 3], [1, 3]]

    x, y = zip(*rect)

    new_rect = np.vstack(model(x, y)).T

    assert np.all(new_rect == [[1, 1], [3, 1], [1, 7], [3, 7]])
예제 #6
0
    def from_tree_transform(self, node):
        matrix = node['matrix']
        translation = node['translation']
        if matrix.shape != (2, 2):
            raise NotImplementedError(
                "asdf currently only supports 2x2 (2D) rotation transformation "
                "matrices")
        if translation.shape != (2, ):
            raise NotImplementedError(
                "asdf currently only supports 2D translation transformations.")

        return projections.AffineTransformation2D(matrix=matrix,
                                                  translation=translation)
예제 #7
0
def convert_wcs(fitswcs):
    '''
    Accepts an astropy.wcs wcs object (based on the FITS standard).

    Returns the GWCS equivalent WCS object.
    '''
    # this first version only handles non distorted ra,dec tangent projections
    # check that it is that case
    radesys_dict = {
        'ICRS': coord.ICRS,
        'FK5': coord.FK5,
        'FK4': coord.FK4,
    }
    projection_dict = {
        'TAN': projections.Pix2Sky_TAN(),
        'SIN': projections.Pix2Sky_SIN()
    }
    fctypes = fitswcs.wcs.ctype
    fcrval = fitswcs.wcs.crval
    fcrpix = fitswcs.wcs.crpix
    if fitswcs.naxis != 2:
        raise ValueError("currently only handles 2d images")
    print(fctypes)
    ptypes = [ct[5:8] for ct in fctypes]
    for ptype in ptypes:
        print(ptype)
        if ptype not in ['TAN', 'SIN']:
            raise ValueError("currently only supports TAN and SIN projections")
        tptype = ptype  # temporary since this part is only for celestial coordinates
    if fitswcs.cpdis1 or fitswcs.cpdis2:  ### error here
        raise ValueError("currently doesn't support distortion")

    # Check for SIP correction
    fsip = fitswcs.sip
    if fsip:
        sipa = Polynomial2D(fsip.a_order)
        sipb = Polynomial2D(fsip.b_order)
        assign_coefficients(sipa, fsip.a)
        assign_coefficients(sipb, fsip.b)
        # now the inverse, if it exists
        if fsip.ap_order and fsip.bp_order:
            sipap = Polynomial2D(fsip.ap_order)
            sipbp = Polynomial2D(fsip.bp_order)
            assign_coefficients(sipap, fsip.ap)
            assign_coefficients(sipbp, fsip.bp)
        else:
            sipap = None
        siptrans = Identity(2) + (Mapping((0, 1, 0, 1)) | (sipa & sipb))
        if sipap:
            siptrans.inverse = Identity(2) + (Mapping(
                (0, 1, 0, 1)) | (sipap & sipbp))
    # construct transformation
    if fitswcs.wcs.has_cd():
        trans1 = (Shift(-fcrpix[0]) & Shift(-fcrpix[1]))
        trans2 = (projections.AffineTransformation2D(fitswcs.wcs.cd)
                  | projection_dict[tptype] | rotations.RotateNative2Celestial(
                      fcrval[0], fcrval[1], 180.))
    elif fitswcs.wcs.has_pc():
        trans1 = (Shift(-fcrpix[0]) & Shift(-fcrpix[1]))
        pcmatrix = np.array(fitswcs.wcs.cdelt) * fitswcs.wcs.pc
        trans2 = (projections.AffineTransformation2D(pcmatrix)
                  | projection_dict[tptype] | rotations.RotateNative2Celestial(
                      fcrval[0], fcrval[1], 180.))
    else:
        cdelt = fitswcs.wcs.cdelt
        crota2 = fitswcs.wcs.crota[1] * np.pi / 180  # unware of any crota1 case
        pscale_ratio = cdelt[1] / cdelt[0]
        pcmatrix = np.array(
            [[np.cos(crota2) * cdelt[0], -np.sin(crota2) * cdelt[1]],
             [np.sin(crota2) * cdelt[0],
              np.cos(crota2) * cdelt[1]]])
        trans1 = (Shift(-fcrpix[0]) & Shift(-fcrpix[1]))
        trans2 = (projections.AffineTransformation2D(pcmatrix)
                  | projection_dict[tptype] | rotations.RotateNative2Celestial(
                      fcrval[0], fcrval[1], 180.))
    if fsip:
        trans = trans1 | siptrans | trans2
    else:
        trans = trans1 | trans2
    detector_frame = cf.Frame2D(name="detector",
                                axes_names=('x', 'y'),
                                unit=(u.pix, u.pix))
    # Now see if a standard frame is referenced.
    if fitswcs.wcs.radesys:
        if fitswcs.wcs.radesys in radesys_dict:
            reference_frame = radesys_dict[fitswcs.wcs.radesys]()
            sky_frame = cf.CelestialFrame(reference_frame=reference_frame,
                                          name=fitswcs.wcs.radesys.lower())
    else:
        sky_frame = ''  # or None?

    wcsobj = ggwcs.WCS(forward_transform=trans,
                       input_frame=detector_frame,
                       output_frame=sky_frame)
    return wcsobj