Esempio n. 1
0
def fitswcs_nonlinear(header):
    """                                
    Create a WCS linear transform from a FITS header.
                                                                                   
    Parameters                                                                       
    ----------
    header : astropy.io.fits.Header or dict
        FITS Header or dict with basic FITS WCS keywords.
    """
    if isinstance(header, fits.Header):
        wcs_info = read_wcs_from_header(header)
    elif isinstance(header, dict):
        wcs_info = header
    else:
        raise TypeError("Expected a FITS Header or a dict.")

    projcode = get_projcode(wcs_info)
    projection = create_projection_transform(projcode).rename(projcode)

    # Create the sky rotation transform
    sky_axes, _ = get_axes(wcs_info)
    phip, lonp = [wcs_info['CRVAL'][i] for i in sky_axes]
    # TODO: write "def compute_lonpole(projcode, l)"
    # Set a defaul tvalue for now 
    thetap = 180
    n2c = astmodels.RotateNative2Celestial(phip, lonp, thetap, name="crval")
    return projection | n2c
def time_init_7_no_units():
    m = (models.Shift(-10.5) & models.Shift(-13.2) |
         models.AffineTransformation2D(matrix=[[1, 0], [0, 1]],
                                       translation=[0, 0]) |
         models.Scale(.01) & models.Scale(.04) |
         models.Pix2Sky_TAN() |
         models.RotateNative2Celestial(5.6, -72.05, 180))
Esempio n. 3
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)
Esempio n. 4
0
def gwcs_simple_imaging_units():
    shift_by_crpix = models.Shift(-2048 * u.pix) & models.Shift(-1024 * u.pix)
    matrix = np.array([[1.290551569736E-05, 5.9525007864732E-06],
                       [5.0226382102765E-06, -1.2644844123757E-05]])
    rotation = models.AffineTransformation2D(matrix * u.deg,
                                             translation=[0, 0] * u.deg)
    rotation.input_units_equivalencies = {
        "x": u.pixel_scale(1 * u.deg / u.pix),
        "y": u.pixel_scale(1 * u.deg / u.pix)
    }
    rotation.inverse = models.AffineTransformation2D(
        np.linalg.inv(matrix) * u.pix, translation=[0, 0] * u.pix)
    rotation.inverse.input_units_equivalencies = {
        "x": u.pixel_scale(1 * u.pix / u.deg),
        "y": u.pixel_scale(1 * u.pix / u.deg)
    }
    tan = models.Pix2Sky_TAN()
    celestial_rotation = models.RotateNative2Celestial(5.63056810618 * u.deg,
                                                       -72.05457184279 * u.deg,
                                                       180 * u.deg)
    det2sky = shift_by_crpix | rotation | tan | celestial_rotation
    det2sky.name = "linear_transform"

    detector_frame = cf.Frame2D(name="detector",
                                axes_names=("x", "y"),
                                unit=(u.pix, u.pix))
    sky_frame = cf.CelestialFrame(reference_frame=coord.ICRS(),
                                  name='icrs',
                                  unit=(u.deg, u.deg))
    pipeline = [(detector_frame, det2sky), (sky_frame, None)]
    return wcs.WCS(pipeline)
Esempio n. 5
0
 def setup(self):
     aff = models.AffineTransformation2D(matrix=[[1, 0], [0, 1]],
                                         translation=[0, 0])
     self.model = (models.Shift(-10.5) & models.Shift(-13.2) | aff
                   | models.Scale(.01) & models.Scale(.04)
                   | models.Pix2Sky_TAN()
                   | models.RotateNative2Celestial(5.6, -72.05, 180))
Esempio n. 6
0
def test_simple_gwcs():
    # https://gwcs.readthedocs.io/en/latest/#getting-started
    shift_by_crpix = models.Shift(-(2048 - 1) * u.pix) & models.Shift(-(1024 - 1) * u.pix)
    matrix = np.array([[1.290551569736E-05, 5.9525007864732E-06],
                       [5.0226382102765E-06, -1.2644844123757E-05]])
    rotation = models.AffineTransformation2D(matrix * u.deg, translation=[0, 0] * u.deg)
    rotation.input_units_equivalencies = {"x": u.pixel_scale(1 * (u.deg / u.pix)),
                                          "y": u.pixel_scale(1 * (u.deg / u.pix))}
    rotation.inverse = models.AffineTransformation2D(np.linalg.inv(matrix) * u.pix,
                                                     translation=[0, 0] * u.pix)
    rotation.inverse.input_units_equivalencies = {"x": u.pixel_scale(1 * (u.pix / u.deg)),
                                                  "y": u.pixel_scale(1 * (u.pix / u.deg))}
    tan = models.Pix2Sky_TAN()
    celestial_rotation = models.RotateNative2Celestial(
        5.63056810618 * u.deg, -72.05457184279 * u.deg, 180 * u.deg)
    det2sky = shift_by_crpix | rotation | tan | celestial_rotation
    det2sky.name = "linear_transform"
    detector_frame = cf.Frame2D(name="detector", axes_names=("x", "y"), unit=(u.pix, u.pix))
    sky_frame = cf.CelestialFrame(reference_frame=ICRS(), name='icrs', unit=(u.deg, u.deg))
    pipeline = [(detector_frame, det2sky), (sky_frame, None)]
    w = gwcs.wcs.WCS(pipeline)

    result = wcs_utils.get_compass_info(w, (1024, 2048), r_fac=0.25)
    assert_allclose(result[:-1], (1024.0, 512.0,
                                  1131.0265005852038, 279.446189124443,
                                  1262.0057201165127, 606.2863901330095,
                                  155.2870478938214, -86.89813081941797))
    assert not result[-1]
Esempio n. 7
0
def generate_s3d_wcs():
    """ create a fake gwcs for a cube """
    # create input /output frames
    detector = cf.CoordinateFrame(name='detector', axes_order=(0,1,2), axes_names=['x', 'y', 'z'],
                                  axes_type=['spatial', 'spatial', 'spatial'], naxes=3,
                                  unit=['pix', 'pix', 'pix'])
    sky = cf.CelestialFrame(reference_frame=coord.ICRS(), name='sky', axes_names=("RA", "DEC"))
    spec = cf.SpectralFrame(name='spectral', unit=['um'], axes_names=['wavelength'], axes_order=(2,))
    world = cf.CompositeFrame(name="world", frames=[sky, spec])

    # create fake transform to at least get a bounding box
    # for the s3d jwst loader

    # shape 30,10,10 (spec, y, x)
    crpix1, crpix2, crpix3 = 5, 5, 15  # (x, y, spec)
    crval1, crval2, crval3 = 1, 1, 1
    cdelt1, cdelt2, cdelt3 = 0.01, 0.01, 0.05

    shift = models.Shift(-crpix2) & models.Shift(-crpix1)
    scale = models.Multiply(cdelt2) & models.Multiply(cdelt1)
    proj = models.Pix2Sky_TAN()
    skyrot = models.RotateNative2Celestial(crval2, 90 + crval1, 180)
    celestial = shift | scale | proj | skyrot
    wave_model = models.Shift(-crpix3) | models.Multiply(cdelt3) | models.Shift(crval3)
    transform = models.Mapping((2, 0, 1)) | celestial & wave_model | models.Mapping((1, 2, 0))
    # bounding box based on shape (30,10,10) in test
    transform.bounding_box = ((0, 29), (0, 9), (0, 9))

    # create final wcs
    pipeline = [(detector, transform),
                (world, None)]
    return WCS(pipeline)
def test1(tmpdir, ret=False):
    shift_by_crpix = models.Shift(-2048 * u.pix) & models.Shift(-1024 * u.pix)
    matrix = np.array([[1.290551569736E-05, 5.9525007864732E-06],
                       [5.0226382102765E-06, -1.2644844123757E-05]])
    rotation = models.AffineTransformation2D(matrix * u.deg,
                                             translation=[0, 0] * u.deg)
    rotation.input_units_equivalencies = {
        "x": u.pixel_scale(1 * u.deg / u.pix),
        "y": u.pixel_scale(1 * u.deg / u.pix)
    }
    rotation.inverse = models.AffineTransformation2D(
        np.linalg.inv(matrix) * u.pix, translation=[0, 0] * u.pix)
    rotation.inverse.input_units_equivalencies = {
        "x": u.pixel_scale(1 * u.pix / u.deg),
        "y": u.pixel_scale(1 * u.pix / u.deg)
    }
    tan = models.Pix2Sky_TAN()
    celestial_rotation = models.RotateNative2Celestial(5.63056810618 * u.deg,
                                                       -72.05457184279 * u.deg,
                                                       180 * u.deg)
    det2sky = shift_by_crpix | rotation | tan | celestial_rotation
    det2sky.name = "linear_transform"
    detector_frame = cf.Frame2D(name="detector",
                                axes_names=("x", "y"),
                                unit=(u.pix, u.pix))
    sky_frame = cf.CelestialFrame(reference_frame=coords.ICRS(),
                                  name='icrs',
                                  unit=(u.deg, u.deg))
    pipeline = [(detector_frame, det2sky), (sky_frame, None)]
    wcsobj = gwcs.wcs.WCS(pipeline)
    wcs_set = WcsSet(default=wcsobj, extra=wcsobj)
    tree = {'wcs_set': wcs_set}
    if ret:
        return wcs_set
    helpers.assert_roundtrip_tree(tree, tmpdir)
Esempio n. 9
0
def generate_celestial_transform(crpix: Union[Iterable[float], u.Quantity],
                                 cdelt: Union[Iterable[float], u.Quantity],
                                 pc: Union[ArrayLike, u.Quantity],
                                 crval: Union[Iterable[float], u.Quantity],
                                 lon_pole: Union[float, u.Quantity] = None,
                                 projection: Model = m.Pix2Sky_TAN()) -> CompoundModel:
    """
    Create a simple celestial transform from FITS like parameters.

    Supports unitful or unitless parameters, but if any parameters have units
    all must have units, if parameters are unitless they are assumed to be in
    degrees.

    Parameters
    ----------
    crpix
        The reference pixel (a length two array).
    crval
        The world coordinate at the reference pixel (a length two array).
    pc
        The rotation matrix for the affine transform. If specifying parameters
        with units this should have celestial (``u.deg``) units.
    lon_pole
        The longitude of the celestial pole, defaults to 180 degrees.
    projection
        The map projection to use, defaults to ``TAN``.

    Notes
    -----

    This function has not been tested with more complex projections. Ensure
    that your lon_pole is correct for your projection.
    """
    spatial_unit = None
    if hasattr(crval[0], "unit"):
        spatial_unit = crval[0].unit
    # TODO: Note this assumption is only valid for certain projections.
    if lon_pole is None:
        lon_pole = 180
    if spatial_unit is not None:
        lon_pole = u.Quantity(lon_pole, unit=spatial_unit)

    # Make translation unitful if all parameters have units
    translation = (0, 0)
    if spatial_unit is not None:
        translation *= pc.unit
        # If we have units then we need to convert all things to Quantity
        # as they might be Parameter classes
        crpix = u.Quantity(crpix)
        cdelt = u.Quantity(cdelt)
        crval = u.Quantity(crval)
        lon_pole = u.Quantity(lon_pole)
        pc = u.Quantity(pc)

    shift = m.Shift(-crpix[0]) & m.Shift(-crpix[1])
    scale = m.Multiply(cdelt[0]) & m.Multiply(cdelt[1])
    rot = m.AffineTransformation2D(pc, translation=translation)
    skyrot = m.RotateNative2Celestial(crval[0], crval[1], lon_pole)
    return shift | scale | rot | projection | skyrot
Esempio n. 10
0
def gwcs_7d_complex_mapping():
    """
    Useful features of this WCS (axes indices here are 0-based):
        - includes two celestial axes: input (0, 1) maps to world (2 - RA, 1 - Dec)
        - includes one separable frame with one axis: 4 -> 2
        - includes one frame with 3 input and 4 output axes (1 degenerate),
          with separable world axes (3, 5) and (0, 6).
    """
    offx = models.Shift(-64, name='x_translation')
    offy = models.Shift(-32, name='y_translation')
    cd = np.array([[1.2906, 0.59532], [0.50222, -1.2645]])
    aff = models.AffineTransformation2D(matrix=1e-5 * cd, name='rotation')
    aff2 = models.AffineTransformation2D(matrix=cd, name='rotation2')

    wcslin = (offx & offy) | aff
    tan = models.Pix2Sky_TAN(name='tangent_projection')
    n2c = models.RotateNative2Celestial(5.630568, -72.0546, 180, name='skyrot')
    icrs = cf.CelestialFrame(reference_frame=coord.ICRS(),
                             name='sky',
                             axes_order=(2, 1))
    spec = cf.SpectralFrame(name='wave',
                            unit=[u.m],
                            axes_order=(4, ),
                            axes_names=('lambda', ))
    cmplx = cf.CoordinateFrame(
        name="complex",
        naxes=4,
        axes_order=(3, 5, 0, 6),
        axis_physical_types=(['em.wl', 'em.wl', 'time', 'time']),
        axes_type=("SPATIAL", "SPATIAL", "TIME", "TIME"),
        axes_names=("x", "y", "t", 'tau'),
        unit=(u.m, u.m, u.second, u.second))

    comp_frm = cf.CompositeFrame(frames=[icrs, spec, cmplx], name='TEST 7D')
    wcs_forward = (
        (wcslin & models.Shift(-3.14) & models.Scale(2.7) & aff2) |
        (tan & models.Identity(1) & models.Identity(1) & models.Identity(2)) |
        (n2c & models.Identity(1) & models.Identity(1) & models.Identity(2))
        | models.Mapping((3, 1, 0, 4, 2, 5, 3)))

    detector_frame = cf.CoordinateFrame(name="detector",
                                        naxes=6,
                                        axes_order=(0, 1, 2, 3, 4, 5),
                                        axes_type=("pixel", "pixel", "pixel",
                                                   "pixel", "pixel", "pixel"),
                                        unit=(u.pix, u.pix, u.pix, u.pix,
                                              u.pix, u.pix))

    pipeline = [('detector', wcs_forward), (comp_frm, None)]
    w = wcs.WCS(forward_transform=wcs_forward,
                output_frame=comp_frm,
                input_frame=detector_frame)
    w.bounding_box = ((0, 15), (0, 31), (0, 20), (0, 10), (0, 10), (0, 1))

    w.array_shape = (2, 11, 11, 21, 32, 16)
    w.pixel_shape = (16, 32, 21, 11, 11, 2)

    return w
 def setup(self):
     aff = models.AffineTransformation2D(matrix=[[1, 0], [0, 1]] * u.arcsec,
                                         translation=[0, 0] * u.arcsec)
     aff.input_units_equivalencies = {'x': u.pixel_scale(1 * u.arcsec/u.pix),
                                      'y': u.pixel_scale(1 * u.arcsec/u.pix)}
     self.model = (models.Shift(-10.5 * u.pix) & models.Shift(-13.2 * u.pix) |
                   aff |
                   models.Scale(.01 * u.arcsec) & models.Scale(.04 * u.deg) |
                   models.Pix2Sky_TAN() |
                   models.RotateNative2Celestial(5.6 * u.deg, -72.05 * u.deg, 180 * u.deg))
Esempio n. 12
0
def test_to_fits_sip_pc_normalization(gwcs_simple_imaging_units, matrix_type):
    y, x = np.mgrid[:1024:10, :1024:10]
    xflat = np.ravel(x[1:-1, 1:-1])
    yflat = np.ravel(y[1:-1, 1:-1])
    bounding_box = ((0, 1024), (0, 1024))

    # create a simple imaging WCS without distortions:
    cdmat = np.array([[1.29e-5, 5.95e-6], [5.02e-6, -1.26e-5]])
    aff = models.AffineTransformation2D(matrix=cdmat, name='rotation')

    offx = models.Shift(-501, name='x_translation')
    offy = models.Shift(-501, name='y_translation')

    wcslin = (offx & offy) | aff

    n2c = models.RotateNative2Celestial(5.63, -72.05, 180, name='sky_rotation')
    tan = models.Pix2Sky_TAN(name='tangent_projection')

    wcs_forward = wcslin | tan | n2c

    sky_cs = cf.CelestialFrame(reference_frame=coord.ICRS(), name='sky')
    pipeline = [('detector', wcs_forward), (sky_cs, None)]

    wcs_lin = wcs.WCS(
        input_frame=cf.Frame2D(name='detector'),
        output_frame=sky_cs,
        forward_transform=pipeline
    )

    _, _, celestial_group = wcs_lin._separable_groups(detect_celestial=True)
    fits_wcs = wcs_lin._to_fits_sip(
        celestial_group=celestial_group,
        keep_axis_position=False,
        bounding_box=bounding_box,
        max_pix_error=0.1,
        degree=None,
        max_inv_pix_error=0.1,
        inv_degree=None,
        npoints=32,
        crpix=None,
        projection='TAN',
        matrix_type=matrix_type,
        verbose=False
    )
    fitssip = astwcs.WCS(fits_wcs)

    fitsvalx, fitsvaly = fitssip.wcs_pix2world(xflat, yflat, 0)
    inv_fitsvalx, inv_fitsvaly = fitssip.wcs_world2pix(fitsvalx, fitsvaly, 0)
    gwcsvalx, gwcsvaly = wcs_lin(xflat, yflat)

    assert_allclose(gwcsvalx, fitsvalx, atol=4e-11, rtol=0)
    assert_allclose(gwcsvaly, fitsvaly, atol=4e-11, rtol=0)

    assert_allclose(xflat, inv_fitsvalx, atol=5e-9, rtol=0)
    assert_allclose(yflat, inv_fitsvaly, atol=5e-9, rtol=0)
Esempio n. 13
0
def gwcs_spec_cel_time_4d():
    """
    A complex 4D mixed celestial + spectral + time WCS.
    """
    # spectroscopic frame:
    wave_model = models.Shift(-5) | models.Multiply(3.7) | models.Shift(20)
    wave_model.bounding_box = (7, 50)
    wave_frame = cf.SpectralFrame(name='wave',
                                  unit=u.m,
                                  axes_order=(0, ),
                                  axes_names=('lambda', ))

    # time frame:
    time_model = models.Identity(1)  # models.Linear1D(10, 0)
    time_frame = cf.TemporalFrame(Time("2010-01-01T00:00"),
                                  name='time',
                                  unit=u.s,
                                  axes_order=(3, ))

    # Values from data/acs.hdr:
    crpix = (12, 13)
    crval = (5.63, -72.05)
    cd = [[1.291E-05, 5.9532E-06], [5.02215E-06, -1.2645E-05]]
    aff = models.AffineTransformation2D(matrix=cd, name='rotation')
    offx = models.Shift(-crpix[0], name='x_translation')
    offy = models.Shift(-crpix[1], name='y_translation')
    wcslin = models.Mapping((1, 0)) | (offx & offy) | aff
    tan = models.Pix2Sky_TAN(name='tangent_projection')
    n2c = models.RotateNative2Celestial(*crval, 180, name='sky_rotation')
    cel_model = wcslin | tan | n2c
    icrs = cf.CelestialFrame(reference_frame=coord.ICRS(),
                             name='sky',
                             axes_order=(2, 1))

    wcs_forward = wave_model & cel_model & time_model

    comp_frm = cf.CompositeFrame(frames=[wave_frame, icrs, time_frame],
                                 name='TEST 4D FRAME')

    detector_frame = cf.CoordinateFrame(name="detector",
                                        naxes=4,
                                        axes_order=(0, 1, 2, 3),
                                        axes_type=("pixel", "pixel", "pixel",
                                                   "pixel"),
                                        unit=(u.pix, u.pix, u.pix, u.pix))

    w = wcs.WCS(forward_transform=wcs_forward,
                output_frame=comp_frm,
                input_frame=detector_frame)

    w.bounding_box = ((0, 63), (0, 127), (0, 255), (0, 9))
    w.array_shape = (10, 256, 128, 64)
    w.pixel_shape = (64, 128, 256, 10)
    return w
Esempio n. 14
0
def _sky_transform(skycoord, projection):
    """
    A sky transform is a projection, followed by a rotation on the sky.
    """
    _verify_projection(projection)
    lon_pole = _compute_lon_pole(skycoord, projection)
    if isinstance(skycoord, coord.SkyCoord):
        lon, lat = skycoord.spherical.lon, skycoord.spherical.lat
    else:
        lon, lat = skycoord
    sky_rotation = models.RotateNative2Celestial(lon, lat, lon_pole)
    return projection | sky_rotation
Esempio n. 15
0
def load_wcs(input_model, reference_files={}):
    """
    Create a gWCS object and store it in ``Model.meta``.

    Parameters
    ----------
    input_model : `~jwst.datamodels.DataModel`
        The exposure.
    reference_files : dict
        A dict {reftype: reference_file_name} containing all
        reference files that apply to this exposure.
    """

    if "wcsinfo" not in input_model.meta:
        input_model.meta.cal_step.assign_wcs = "SKIPPED"
        log.warning("assign_wcs: SKIPPED")
        return input_model
    else:
        output_model = input_model.copy()
        shift_by_crpix = models.Shift(
            -(input_model.meta.wcsinfo.crpix1 - 1) * u.pix
        ) & models.Shift(-(input_model.meta.wcsinfo.crpix2 - 1) * u.pix)
        pix2sky = getattr(
            models, "Pix2Sky_{}".format(input_model.meta.wcsinfo.ctype1[-3:])
        )()
        celestial_rotation = models.RotateNative2Celestial(
            input_model.meta.wcsinfo.crval1 * u.deg,
            input_model.meta.wcsinfo.crval2 * u.deg,
            180 * u.deg,
        )
        pix2sky.input_units_equivalencies = {
            "x": u.pixel_scale(input_model.meta.wcsinfo.cdelt1 * u.deg / u.pix),
            "y": u.pixel_scale(input_model.meta.wcsinfo.cdelt2 * u.deg / u.pix),
        }
        det2sky = shift_by_crpix | pix2sky | celestial_rotation
        det2sky.name = "linear_transform"
        detector_frame = cf.Frame2D(
            name="detector", axes_names=("x", "y"), unit=(u.pix, u.pix)
        )
        sky_frame = cf.CelestialFrame(
            reference_frame=getattr(
                coord, input_model.meta.coordinates.reference_frame
            )(),
            name="sky_frame",
            unit=(u.deg, u.deg),
        )
        pipeline = [(detector_frame, det2sky), (sky_frame, None)]

        wcs = WCS(pipeline)
        output_model.meta.wcs = wcs
        output_model.meta.cal_step.assign_wcs = "COMPLETE"
    return output_model
Esempio n. 16
0
def gwcs_cube_with_separable_time(request):
    """
    A mixed celestial + time WCS.
    """
    cube_size = (64, 32, 128)

    axes_order = request.param
    time_axes_order = (axes_order.index(2), )
    cel_axes_order = (axes_order.index(0), axes_order.index(1))

    detector_frame = cf.CoordinateFrame(name="detector",
                                        naxes=3,
                                        axes_order=(0, 1, 2),
                                        axes_type=("pixel", "pixel", "pixel"),
                                        unit=(u.pix, u.pix, u.pix))

    # time frame:
    time_model = models.Identity(1)  # models.Linear1D(10, 0)
    time_frame = cf.TemporalFrame(Time("2010-01-01T00:00"),
                                  name='time',
                                  unit=u.s,
                                  axes_order=time_axes_order)

    # Values from data/acs.hdr:
    crpix = (12, 13)
    crval = (5.63, -72.05)
    cd = [[1.291E-05, 5.9532E-06], [5.02215E-06, -1.2645E-05]]
    aff = models.AffineTransformation2D(matrix=cd, name='rotation')
    offx = models.Shift(-crpix[0], name='x_translation')
    offy = models.Shift(-crpix[1], name='y_translation')
    wcslin = models.Mapping((1, 0)) | (offx & offy) | aff
    tan = models.Pix2Sky_TAN(name='tangent_projection')
    n2c = models.RotateNative2Celestial(*crval, 180, name='sky_rotation')
    cel_model = wcslin | tan | n2c
    icrs = cf.CelestialFrame(reference_frame=coord.ICRS(),
                             name='sky',
                             axes_order=cel_axes_order)

    wcs_forward = (cel_model & time_model) | models.Mapping(axes_order)

    comp_frm = cf.CompositeFrame(frames=[icrs, time_frame],
                                 name='TEST 3D FRAME WITH TIME')

    w = wcs.WCS(forward_transform=wcs_forward,
                output_frame=comp_frm,
                input_frame=detector_frame)

    w.bounding_box = tuple((0, k - 1) for k in cube_size)
    w.pixel_shape = cube_size
    w.array_shape = w.pixel_shape[::-1]
    return w
Esempio n. 17
0
def test_attributes():
    n2c = models.RotateNative2Celestial(20016 * u.arcsec, -72.3 * u.deg,
                                        np.pi * u.rad)
    assert_allclose(n2c.lat.value, -72.3)
    assert_allclose(n2c.lat._raw_value, -1.2618730491919001)
    assert_allclose(n2c.lon.value, 20016)
    assert_allclose(n2c.lon._raw_value, 0.09704030641088472)
    assert_allclose(n2c.lon_pole.value, np.pi)
    assert_allclose(n2c.lon_pole._raw_value, np.pi)
    assert (n2c.lon.unit is u.Unit("arcsec"))
    assert (n2c._param_metrics['lon']['raw_unit'] is u.Unit("rad"))
    assert (n2c.lat.unit is u.Unit("deg"))
    assert (n2c._param_metrics['lat']['raw_unit'] is u.Unit("rad"))
    assert (n2c.lon_pole.unit is u.Unit("rad"))
    assert (n2c._param_metrics['lon_pole']['raw_unit'] is u.Unit("rad"))
Esempio n. 18
0
def gwcs_cube_with_separable_spectral(request):
    cube_size = (128, 64, 100)

    axes_order = request.param
    spectral_axes_order = (axes_order.index(2), )
    cel_axes_order = (axes_order.index(0), axes_order.index(1))

    # Values from data/acs.hdr:
    crpix = (64, 32)
    crval = (5.63056810618, -72.0545718428)
    cd = [[1.29058667557984E-05, 5.95320245884555E-06],
          [5.02215195623825E-06, -1.2645010396976E-05]]

    aff = models.AffineTransformation2D(matrix=cd, name='rotation')
    offx = models.Shift(-crpix[0], name='x_translation')
    offy = models.Shift(-crpix[1], name='y_translation')

    wcslin = (offx & offy) | aff
    tan = models.Pix2Sky_TAN(name='tangent_projection')
    n2c = models.RotateNative2Celestial(*crval, 180, name='sky_rotation')
    icrs = cf.CelestialFrame(reference_frame=coord.ICRS(),
                             name='sky',
                             axes_order=cel_axes_order)
    spec = cf.SpectralFrame(name='wave',
                            unit=[
                                u.m,
                            ],
                            axes_order=spectral_axes_order,
                            axes_names=('lambda', ))
    comp_frm = cf.CompositeFrame(frames=[icrs, spec],
                                 name='TEST 3D FRAME WITH SPECTRAL AXIS')
    wcs_forward = ((wcslin & models.Identity(1)) | (tan & models.Identity(1)) |
                   (n2c & models.Identity(1)) | models.Mapping(axes_order))

    detector_frame = cf.CoordinateFrame(name="detector",
                                        naxes=3,
                                        axes_order=(0, 1, 2),
                                        axes_type=("pixel", "pixel", "pixel"),
                                        unit=(u.pix, u.pix, u.pix))

    w = wcs.WCS(forward_transform=wcs_forward,
                output_frame=comp_frm,
                input_frame=detector_frame)
    w.bounding_box = tuple((0, k - 1) for k in cube_size)
    w.pixel_shape = cube_size
    w.array_shape = w.pixel_shape[::-1]

    return w, axes_order
Esempio n. 19
0
    def setup_class(self):
        hdr = fits.Header.fromtextfile(get_pkg_data_filename("data/acs.hdr"),
                                       endcard=False)
        #warnings.filterwarnings("ignore", message="^The WCS transformation has more axes (2)",
        #                        module="astropy.wcs.wcs")
        self.fitsw = astwcs.WCS(hdr)
        a_coeff = hdr['A_*']
        a_order = a_coeff.pop('A_ORDER')
        b_coeff = hdr['B_*']
        b_order = b_coeff.pop('B_ORDER')

        crpix = [hdr['CRPIX1'], hdr['CRPIX2']]
        distortion = models.SIP(
            crpix, a_order, b_order, a_coeff, b_coeff,
            name='sip_distorion') + models.Identity(2)

        cdmat = np.array([[hdr['CD1_1'], hdr['CD1_2']],
                          [hdr['CD2_1'], hdr['CD2_2']]])
        aff = models.AffineTransformation2D(matrix=cdmat, name='rotation')

        offx = models.Shift(-hdr['CRPIX1'], name='x_translation')
        offy = models.Shift(-hdr['CRPIX2'], name='y_translation')

        wcslin = (offx & offy) | aff

        phi = hdr['CRVAL1']
        lon = hdr['CRVAL2']
        theta = 180
        n2c = models.RotateNative2Celestial(phi,
                                            lon,
                                            theta,
                                            name='sky_rotation')

        tan = models.Pix2Sky_TAN(name='tangent_projection')
        sky_cs = cf.CelestialFrame(reference_frame=coord.ICRS(), name='sky')
        det = cf.Frame2D('detector')
        wcs_forward = wcslin | tan | n2c
        pipeline = [('detector', distortion), ('focal', wcs_forward),
                    (sky_cs, None)]

        self.wcs = wcs.WCS(input_frame=det,
                           output_frame=sky_cs,
                           forward_transform=pipeline)
        nx, ny = (5, 2)
        x = np.linspace(0, 1, nx)
        y = np.linspace(0, 1, ny)
        self.xv, self.yv = np.meshgrid(x, y)
Esempio n. 20
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)
Esempio n. 21
0
def create_asdf_ref_files(fname):
    #f = fits.open('../j94f05bgq_flt.fits')
    f = fits.open(fname)
    from gwcs import util
    whdr = util.read_wcs_from_header(f[1].header)
    crpix = whdr['CRPIX']
    shift = models.Shift(crpix[0]) & models.Shift(crpix[1])
    rotation = models.AffineTransformation2D(matrix=whdr['PC'])
    cdelt = whdr['CDELT']
    scale = models.Scale(cdelt[0]) & models.Scale(cdelt[1])
    #print util.get_projcode(whdr['CTYPE'][0])
    tan = models.Pix2Sky_TAN()
    crval = whdr['CRVAL']
    n2c = models.RotateNative2Celestial(crval[0], crval[1], 180)
    foc2sky = (shift | rotation | scale | tan | n2c).rename('foc2sky')
    fasdf = AsdfFile()
    fasdf.tree = {'model': foc2sky}
    fasdf.write_to('foc2sky.asdf')
Esempio n. 22
0
def gwcs_3d_galactic_spectral():
    """
    This fixture has the axes ordered as lat, spectral, lon.
    """
    #                       lat,wav,lon
    crpix1, crpix2, crpix3 = 29, 39, 44
    crval1, crval2, crval3 = 10, 20, 25
    cdelt1, cdelt2, cdelt3 = -0.01, 0.5, 0.01

    shift = models.Shift(-crpix3) & models.Shift(-crpix1)
    scale = models.Multiply(cdelt3) & models.Multiply(cdelt1)
    proj = models.Pix2Sky_CAR()
    skyrot = models.RotateNative2Celestial(crval3, 90 + crval1, 180)
    celestial = shift | scale | proj | skyrot

    wave_model = models.Shift(-crpix2) | models.Multiply(
        cdelt2) | models.Shift(crval2)

    transform = models.Mapping(
        (2, 0, 1)) | celestial & wave_model | models.Mapping((1, 2, 0))
    transform.bounding_box = ((5, 50), (-2, 45), (-1, 35))

    sky_frame = cf.CelestialFrame(axes_order=(2, 0),
                                  reference_frame=coord.Galactic(),
                                  axes_names=("Longitude", "Latitude"))
    wave_frame = cf.SpectralFrame(axes_order=(1, ),
                                  unit=u.Hz,
                                  axes_names=("Frequency", ))

    frame = cf.CompositeFrame([sky_frame, wave_frame])

    detector_frame = cf.CoordinateFrame(name="detector",
                                        naxes=3,
                                        axes_order=(0, 1, 2),
                                        axes_type=("pixel", "pixel", "pixel"),
                                        unit=(u.pix, u.pix, u.pix))

    owcs = wcs.WCS(forward_transform=transform,
                   output_frame=frame,
                   input_frame=detector_frame)
    owcs.array_shape = (30, 20, 10)
    owcs.pixel_shape = (10, 20, 30)

    return owcs
Esempio n. 23
0
    def from_file(cls, header, dist_json):
        """
        header : fits.Header
        dist_json : json file

        """
        if not isinstance(header, fits.Header):
            raise TypeError("Header must be a fits.Header object")
        fitswcs = util.read_wcs_from_header(header)

        wcs_linear = WCSLinearTransform.from_header(header)
        projection = create_projection_transform(fitswcs)

        # Create a RotateNative2Celestial transform using the Euler angles
        phip, lonp = fitswcs['CRVAL']
        # Expand this - currently valid for zenithal projections only
        thetap = 180 # write "def compute_lonpole(projcode, l)"
        n2c = astmodels.RotateNative2Celestial(phip, lonp, thetap)
        if dist_json is not None:
            distortion = transform_from_json(dist_info['regions'][0])
        else:
            distortion = None

        return cls(wcs_linear, projection, n2c, distortion)
Esempio n. 24
0
    return m1


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 = []
Esempio n. 25
0
try:
    import astropy
except ImportError:
    HAS_ASTROPY = False
    test_models = []
else:
    HAS_ASTROPY = True
    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):
Esempio n. 26
0
def make_gwcs(shape, galactic=False):
    """
    Create a simple celestial gWCS object in the ICRS coordinate frame.

    This function requires the `gwcs
    <https://github.com/spacetelescope/gwcs>`_ package.

    Parameters
    ----------
    shape : 2-tuple of int
        The shape of the 2D array to be used with the output
        `~gwcs.wcs.WCS` object.

    galactic : bool, optional
        If `True`, then the output WCS will be in the Galactic
        coordinate frame.  If `False` (default), then the output WCS
        will be in the ICRS coordinate frame.

    Returns
    -------
    wcs : `gwcs.wcs.WCS` object
        The generalized world coordinate system (WCS) transformation.

    See Also
    --------
    make_wcs, make_imagehdu

    Notes
    -----
    The `make_wcs` function returns an equivalent WCS transformation to
    this one, but as an `astropy.wcs.WCS` object.

    Examples
    --------
    >>> from photutils.datasets import make_gwcs
    >>> shape = (100, 100)
    >>> gwcs = make_gwcs(shape)
    >>> print(gwcs)
      From      Transform
    -------- ----------------
    detector linear_transform
        icrs             None
    """

    from gwcs import wcs as gwcs_wcs
    from gwcs import coordinate_frames as cf

    rho = np.pi / 3.
    scale = 0.1 / 3600.  # 0.1 arcsec/pixel in deg/pix

    shift_by_crpix = (models.Shift((-shape[1] / 2) + 1)
                      & models.Shift((-shape[0] / 2) + 1))

    cd_matrix = np.array([[-scale * np.cos(rho), scale * np.sin(rho)],
                          [scale * np.sin(rho), scale * np.cos(rho)]])

    rotation = models.AffineTransformation2D(cd_matrix, translation=[0, 0])
    rotation.inverse = models.AffineTransformation2D(np.linalg.inv(cd_matrix),
                                                     translation=[0, 0])

    tan = models.Pix2Sky_TAN()
    celestial_rotation = models.RotateNative2Celestial(197.8925, -1.36555556,
                                                       180.0)

    det2sky = shift_by_crpix | rotation | tan | celestial_rotation
    det2sky.name = 'linear_transform'

    detector_frame = cf.Frame2D(name='detector',
                                axes_names=('x', 'y'),
                                unit=(u.pix, u.pix))

    if galactic:
        sky_frame = cf.CelestialFrame(reference_frame=coord.Galactic(),
                                      name='galactic',
                                      unit=(u.deg, u.deg))
    else:
        sky_frame = cf.CelestialFrame(reference_frame=coord.ICRS(),
                                      name='icrs',
                                      unit=(u.deg, u.deg))

    pipeline = [(detector_frame, det2sky), (sky_frame, None)]

    return gwcs_wcs.WCS(pipeline)
Esempio n. 27
0
    def _attach_static_distortion(self, adinputs=None):
        """
        This primitive modifies the WCS of its input AD objects to include the
        static distortion read from the lookup table. It will ignore any ADs
        which have CoordinateFrames named "static" on all the extensions, and
        raise an OSError if any ADs have "static" on some (but not all)
        extensions.
        """
        log = self.log

        # Check the inputs haven't been mosaicked or tiled
        mosaic_kws = {
            self.timestamp_keys[prim]
            for prim in ("mosaicDetectors", "tileArrays")
        }
        if any(mosaic_kws.intersection(ad.phu) for ad in adinputs):
            raise ValueError(f"Inputs to {self.myself()} must not have been "
                             "mosaicked or tiled.")

        static_corrections = gsdi.STATIC_CORRECTIONS
        sdmodels = []
        sdsubmodels = {}
        for direction in ("forward", "backward"):
            sdsubmodels[direction] = []
            for component in static_corrections[direction]:
                model_type = getattr(models, component["model"])
                for arr in component["parameters"]:
                    for ordinate in "xy":
                        pars = arr[ordinate]
                        max_xpower = max([int(k[1]) for k in pars])
                        max_ypower = max([int(k[-1]) for k in pars])
                        if component["model"] == "Polynomial2D":
                            degree = {"degree": max(max_xpower, max_ypower)}
                        else:
                            degree = {
                                "xdegree": max_xpower,
                                "ydegree": max_ypower
                            }
                        sdsubmodels[direction].append(
                            model_type(**degree, **pars))
        for index, pixref in enumerate(static_corrections["pixel_references"]):
            sdmodel = (models.Mapping((0, 1, 0, 1)) | (reduce(
                Model.__add__, sdsubmodels["forward"][index * 2::8]) & reduce(
                    Model.__add__, sdsubmodels["forward"][index * 2 + 1::8])))
            sdmodel.inverse = (models.Mapping((0, 1, 0, 1)) | (reduce(
                Model.__add__, sdsubmodels["backward"][index * 2::8]) & reduce(
                    Model.__add__, sdsubmodels["backward"][index * 2 + 1::8])))
            xref, yref = sdmodel.inverse(0, 0)
            if 0 < xref < 2048 and 0 < yref < 2048:
                ref_location = (index, xref - 1, yref - 1
                                )  # store 0-indexed pixel location
            sdmodels.append(sdmodel)

        for ad in adinputs:
            applied_static = sum("static" in ext.wcs.available_frames
                                 for ext in ad)
            if applied_static not in (0, len(ad)):
                raise OSError(
                    f"Some (but not all) extensions in {ad.filename}"
                    " have had the static disortion correction applied")
            # No-op silently
            if applied_static == len(ad):
                continue
            ref_wcs = ad[ref_location[0]].wcs
            ra, dec = ref_wcs(*ref_location[1:])
            for ext, arrsec, sdmodel in zip(ad, ad.array_section(), sdmodels):
                # Include ROI shift
                sdmodel = (models.Shift(arrsec.x1 + 1)
                           & models.Shift(arrsec.y1 + 1) | sdmodel)
                static_frame = cf.Frame2D(unit=(u.arcsec, u.arcsec),
                                          name="static")
                sky_model = models.Scale(1 / 3600) & models.Scale(1 / 3600)
                # the PA header keyword isn't good enough
                wcs_dict = adwcs.gwcs_to_fits(ad[ref_location[0]].nddata)
                pa = np.arctan2(wcs_dict["CD2_1"] - wcs_dict["CD1_2"],
                                wcs_dict["CD1_1"] + wcs_dict["CD2_2"])
                if abs(pa) > 0.00175:  # radians ~ 0.01 degrees
                    # Rotation2D() breaks things because it explicitly converts
                    # the Column objects to Quantity objects, which retain units
                    # of "pix" that Pix2Sky objects to. The AffineTransformation2D
                    # does some multiplications (like Scale) which are agnostic to
                    # the presence or absence of units.
                    sky_model |= models.AffineTransformation2D(
                        matrix=[[math.cos(pa), -math.sin(pa)],
                                [math.sin(pa), math.cos(pa)]])
                sky_model |= models.Pix2Sky_TAN(
                ) | models.RotateNative2Celestial(ra, dec, 180)
                ext.wcs = gWCS([(ext.wcs.input_frame, sdmodel),
                                (static_frame, sky_model),
                                (ext.wcs.output_frame, None)])

        return adinputs
Esempio n. 28
0
import numpy as np

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 = {
Esempio n. 29
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)
Esempio n. 30
0
def test_native_celestial_lat90():
    n2c = models.RotateNative2Celestial(1, 90, 0)
    alpha, delta = n2c(1, 1)
    assert_allclose(delta, 1)
    assert_allclose(alpha, 182)