예제 #1
0
def test_roundtrip_sky_rotaion(inp):
    lon, lat, lon_pole = 42 * u.deg, (43 * u.deg).to(
        u.arcsec), (44 * u.deg).to(u.rad)
    n2c = models.RotateNative2Celestial(lon, lat, lon_pole)
    c2n = models.RotateCelestial2Native(lon, lat, lon_pole)
    assert_quantity_allclose(n2c.inverse(*n2c(*inp)), inp, atol=1e-13 * u.deg)
    assert_quantity_allclose(c2n.inverse(*c2n(*inp)), inp, atol=1e-13 * u.deg)
예제 #2
0
def test_against_wcslib(inp):
    w = wcs.WCS()
    crval = [202.4823228, 47.17511893]
    w.wcs.crval = crval
    w.wcs.ctype = ['RA---TAN', 'DEC--TAN']

    lonpole = 180
    tan = models.Pix2Sky_TAN()
    n2c = models.RotateNative2Celestial(crval[0], crval[1], lonpole)
    c2n = models.RotateCelestial2Native(crval[0], crval[1], lonpole)
    m = tan | n2c
    minv = c2n | tan.inverse

    radec = w.wcs_pix2world(inp[0], inp[1], 1)
    xy = w.wcs_world2pix(radec[0], radec[1], 1)

    assert_allclose(m(*inp), radec, atol=1e-12)
    assert_allclose(minv(*radec), xy, atol=1e-12)
예제 #3
0
test_models = [
    astmodels.Identity(2),
    astmodels.Polynomial1D(2, c0=1, c1=2, c2=3),
    astmodels.Polynomial2D(1, c0_0=1, c0_1=2, c1_0=3),
    astmodels.Shift(2.),
    astmodels.Hermite1D(2, c0=2, c1=3, c2=0.5),
    astmodels.Legendre1D(2, c0=2, c1=3, c2=0.5),
    astmodels.Chebyshev1D(2, c0=2, c1=3, c2=0.5),
    astmodels.Chebyshev2D(1, 1, c0_0=1, c0_1=2, c1_0=3),
    astmodels.Legendre2D(1, 1, c0_0=1, c0_1=2, c1_0=3),
    astmodels.Hermite2D(1, 1, c0_0=1, c0_1=2, c1_0=3),
    astmodels.Scale(3.4),
    astmodels.RotateNative2Celestial(5.63, -72.5, 180),
    astmodels.Multiply(3),
    astmodels.Multiply(10 * u.m),
    astmodels.RotateCelestial2Native(5.63, -72.5, 180),
    astmodels.EulerAngleRotation(23, 14, 2.3, axes_order='xzx'),
    astmodels.Mapping((0, 1), n_inputs=3),
    astmodels.Shift(2. * u.deg),
    astmodels.Scale(3.4 * u.deg),
    astmodels.RotateNative2Celestial(5.63 * u.deg, -72.5 * u.deg, 180 * u.deg),
    astmodels.RotateCelestial2Native(5.63 * u.deg, -72.5 * u.deg, 180 * u.deg),
    astmodels.RotationSequence3D([1.2, 2.3, 3.4, .3], 'xyzx'),
    astmodels.SphericalRotationSequence([1.2, 2.3, 3.4, .3], 'xyzy'),
    custom_and_analytical_inverse(),
]

math_models = []

for kl in astmodels.math.__all__:
    klass = getattr(astmodels.math, kl)
예제 #4
0
def wcs_from_points(xy,
                    world_coordinates,
                    fiducial,
                    projection=projections.Sky2Pix_TAN(),
                    degree=4,
                    polynomial_type="polynomial"):
    """
    Given two matching sets of coordinates on detector and sky, compute the WCS.

    Notes
    -----
    This function implements the following algorithm:
    ``world_coordinates`` are transformed to a projection plane using the specified projection.
    A polynomial fits ``xy`` and the projected coordinates.
    The fitted polynomials and the projection transforms are combined into a tranform
    from detector to sky.
    The input coordinate frame is set to ``detector``.
    The output coordinate frame is initialized based on the frame in the fiducial.


    Parameters
    ----------
    xy : tuple of 2 ndarrays
        Points in the input cooridnate frame - x, y inputs.
    world_coordinates : tuple of 2 ndarrays
        Points in the output coordinate frame.
        The order matches the order of ``xy``.
    fiducial_point : `~astropy.coordinates.SkyCoord`
        A fiducial point in the output coordinate frame.
    projection : `~astropy.modeling.projections.Projection`
        A projection type. One of the projections in `~astropy.modeling.projections.projcode`.
    degree : int
        Degree of Polynpomial model to be fit to data.
    polynomial_type : str
        one of "polynomial", "chebyshev", "legendre"

    Returns
    -------
    wcsobj : `~gwcs.wcs.WCS`
        a WCS object for this observation.
    """
    supported_poly_types = {
        "polynomial": models.Polynomial2D,
        "chebyshev": models.Chebyshev2D,
        "legendre": models.Legendre2D
    }
    x, y = xy
    lon, lat = world_coordinates

    if not isinstance(projection, projections.Projection):
        raise UnsupportedProjectionError(
            "Unsupported projection code {0}".format(projection))
    if polynomial_type not in supported_poly_types.keys():
        raise ValueError("Unsupported polynomial_type: {}. "
                         "Only one of {} is supported.".format(
                             polynomial_type, supported_poly_types.keys()))
    skyrot = models.RotateCelestial2Native(fiducial.data.lon,
                                           fiducial.data.lat, 180 * u.deg)
    trans = (skyrot | projection)
    projection_x, projection_y = trans(lon, lat)
    poly = supported_poly_types[polynomial_type](degree)
    fitter = fitting.LevMarLSQFitter()
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        poly_x = fitter(poly, x, y, projection_x)
        poly_y = fitter(poly, x, y, projection_y)
    transform = models.Mapping(
        (0, 1, 0, 1)) | poly_x & poly_y | projection.inverse | skyrot.inverse

    skyframe = CelestialFrame(reference_frame=fiducial.frame)
    detector = Frame2D(name="detector")
    pipeline = [(detector, transform), (skyframe, None)]
    return WCS(pipeline)
예제 #5
0
try:
    import astropy
except ImportError:
    HAS_ASTROPY = False
    test_models = []
else:
    HAS_ASTROPY = True
    from astropy.utils import minversion
    ASTROPY_13 = minversion(astropy, "1.3.dev16506")
    from astropy.modeling import models as astmodels

    test_models = [astmodels.Identity(2), astmodels.Polynomial1D(2, c0=1, c1=2, c2=3),
                   astmodels.Polynomial2D(1, c0_0=1, c0_1=2, c1_0=3), astmodels.Shift(2.),
                   astmodels.Scale(3.4), astmodels.RotateNative2Celestial(5.63, -72.5, 180),
                   astmodels.RotateCelestial2Native(5.63, -72.5, 180),
                   astmodels.EulerAngleRotation(23, 14, 2.3, axes_order='xzx'),
                   astmodels.Mapping((0, 1), n_inputs=3)]

import pytest

from ....tests import helpers
from .... import util

from ..basic import DomainType


@pytest.mark.skipif('not HAS_ASTROPY')
def test_transforms_compound(tmpdir):
    tree = {
        'compound':
예제 #6
0
def test_roundtrip_sky_rotation(inp):
    lon, lat, lon_pole = 42, 43, 44
    n2c = models.RotateNative2Celestial(lon, lat, lon_pole)
    c2n = models.RotateCelestial2Native(lon, lat, lon_pole)
    assert_allclose(n2c.inverse(*n2c(*inp)), inp, atol=1e-13)
    assert_allclose(c2n.inverse(*c2n(*inp)), inp, atol=1e-13)
예제 #7
0
def wcs_from_points(xy,
                    world_coords,
                    proj_point='center',
                    projection=projections.Sky2Pix_TAN(),
                    poly_degree=4,
                    polynomial_type='polynomial'):
    """
    Given two matching sets of coordinates on detector and sky, compute the WCS.

    Notes
    -----
    This function implements the following algorithm:
    ``world_coords`` are transformed to a projection plane using the specified
    projection. A polynomial fits ``xy`` and the projected coordinates.
    The fitted polynomials and the projection transforms are combined into a
    tranform from detector to sky. The input coordinate frame is set to
    ``detector``. The output coordinate frame is initialized based on the frame
    in the fiducial.


    Parameters
    ----------
    xy : tuple of 2 ndarrays
        Points in the input cooridnate frame - x, y inputs.
    world_coords : `~astropy.coordinates.SkyCoord`
        Points in the output coordinate frame.
        The order matches the order of ``xy``.
    proj_point : `~astropy.coordinates.SkyCoord`
        A fiducial point in the output coordinate frame. If set to 'center'
        (default), the geometric center of input world
        coordinates will be used as the projection point. To specify an exact
        point for the projection, a Skycoord object with a coordinate pair can
        be passed in.
    projection : `~astropy.modeling.projections.Projection`
        A projection type. One of the projections in
        `~astropy.modeling.projections.projcode`. Defaults to TAN projection
        (`projections.Sky2Pix_TAN()`).
    poly_degree : int
        Degree of polynomial model to be fit to data. Defaults to 4.
    polynomial_type : str
        one of "polynomial", "chebyshev", "legendre". Defaults to "polynomial".

    Returns
    -------
    wcsobj : `~gwcs.wcs.WCS`
        a WCS object for this observation.
    """
    from .wcs import WCS

    supported_poly_types = {
        "polynomial": models.Polynomial2D,
        "chebyshev": models.Chebyshev2D,
        "legendre": models.Legendre2D
    }

    x, y = xy

    if not isinstance(world_coords, coord.SkyCoord):
        raise TypeError(
            '`world_coords` must be an `~astropy.coordinates.SkyCoord`')
    try:
        lon, lat = world_coords.data.lon.deg, world_coords.data.lat.deg
    except AttributeError:
        unit_sph = world_coords.unit_spherical
        lon, lat = unit_sph.lon.deg, unit_sph.lat.deg

    if isinstance(proj_point, coord.SkyCoord):
        assert proj_point.size == 1
        proj_point.transform_to(world_coords)
        crval = (proj_point.data.lon, proj_point.data.lat)
        frame = proj_point.frame
    elif proj_point == 'center':  # use center of input points
        sc1 = SkyCoord(lon.min() * u.deg, lat.max() * u.deg)
        sc2 = SkyCoord(lon.max() * u.deg, lat.min() * u.deg)
        pa = sc1.position_angle(sc2)
        sep = sc1.separation(sc2)
        midpoint_sc = sc1.directional_offset_by(pa, sep / 2)
        crval = (midpoint_sc.data.lon, midpoint_sc.data.lat)
        frame = sc1.frame
    else:
        raise ValueError("`proj_point` must be set to 'center', or an" +
                         "`~astropy.coordinates.SkyCoord` object with " +
                         "a pair of points.")

    if not isinstance(projection, projections.Projection):
        raise UnsupportedProjectionError(
            "Unsupported projection code {0}".format(projection))

    if polynomial_type not in supported_poly_types.keys():
        raise ValueError("Unsupported polynomial_type: {}. "
                         "Only one of {} is supported.".format(
                             polynomial_type, supported_poly_types.keys()))

    skyrot = models.RotateCelestial2Native(crval[0], crval[1], 180 * u.deg)
    trans = (skyrot | projection)
    projection_x, projection_y = trans(lon, lat)
    poly = supported_poly_types[polynomial_type](poly_degree)

    fitter = fitting.LevMarLSQFitter()
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        poly_x = fitter(poly, x, y, projection_x)
        poly_y = fitter(poly, x, y, projection_y)
        distortion = models.Mapping((0, 1, 0, 1)) | poly_x & poly_y

        poly_x_inverse = fitter(poly, projection_x, projection_y, x)
        poly_y_inverse = fitter(poly, projection_x, projection_y, y)
        distortion.inverse = models.Mapping(
            (0, 1, 0, 1)) | poly_x_inverse & poly_y_inverse

    transform = distortion | projection.inverse | skyrot.inverse

    skyframe = CelestialFrame(reference_frame=frame)
    detector = Frame2D(name="detector")
    pipeline = [(detector, transform), (skyframe, None)]

    return WCS(pipeline)