Beispiel #1
0
def _make_reference_gwcs_wcs(fits_hdr):
    hdr = fits.Header.fromfile(get_pkg_data_filename(fits_hdr))
    fw = fitswcs.WCS(hdr)

    unit_conv = Scale(1.0 / 3600.0, name='arcsec_to_deg_1D')
    unit_conv = unit_conv & unit_conv
    unit_conv.name = 'arcsec_to_deg_2D'

    unit_conv_inv = Scale(3600.0, name='deg_to_arcsec_1D')
    unit_conv_inv = unit_conv_inv & unit_conv_inv
    unit_conv_inv.name = 'deg_to_arcsec_2D'

    c2s = CartesianToSpherical(name='c2s', wrap_lon_at=180)
    s2c = SphericalToCartesian(name='s2c', wrap_lon_at=180)
    c2tan = ((Mapping((0, 1, 2), name='xyz') / Mapping(
        (0, 0, 0), n_inputs=3, name='xxx')) | Mapping((1, 2), name='xtyt'))
    c2tan.name = 'Cartesian 3D to TAN'

    tan2c = (Mapping((0, 0, 1), n_inputs=2, name='xtyt2xyz') |
             (Const1D(1, name='one') & Identity(2, name='I(2D)')))
    tan2c.name = 'TAN to cartesian 3D'

    tan2c.inverse = c2tan
    c2tan.inverse = tan2c

    aff = AffineTransformation2D(matrix=fw.wcs.cd)

    offx = Shift(-fw.wcs.crpix[0])
    offy = Shift(-fw.wcs.crpix[1])

    s = 5e-6
    scale = Scale(s) & Scale(s)

    det2tan = (offx & offy) | scale | tan2c | c2s | unit_conv_inv

    taninv = s2c | c2tan
    tan = Pix2Sky_TAN()
    n2c = RotateNative2Celestial(fw.wcs.crval[0], fw.wcs.crval[1], 180)
    wcslin = unit_conv | taninv | scale.inverse | aff | tan | n2c

    sky_frm = cf.CelestialFrame(reference_frame=coord.ICRS())
    det_frm = cf.Frame2D(name='detector')
    v2v3_frm = cf.Frame2D(name="v2v3",
                          unit=(u.arcsec, u.arcsec),
                          axes_names=('x', 'y'),
                          axes_order=(0, 1))
    pipeline = [(det_frm, det2tan), (v2v3_frm, wcslin), (sky_frm, None)]

    gw = gwcs.WCS(input_frame=det_frm,
                  output_frame=sky_frm,
                  forward_transform=pipeline)
    gw.crpix = fw.wcs.crpix
    gw.crval = fw.wcs.crval
    gw.bounding_box = ((-0.5, fw.pixel_shape[0] - 0.5),
                       (-0.5, fw.pixel_shape[1] - 0.5))

    return gw
def compute_va_effects(velocity_x, velocity_y, velocity_z, ra, dec):
    """ Computes constant scale factor due to velocity aberration as well as
    corrected ``RA`` and ``DEC`` values.

    Parameters
    ----------
    velocity_x, velocity_y, velocity_z: float
        The components of the velocity of JWST, in km / s with respect to
        the Sun.  These are celestial coordinates, with x toward the
        vernal equinox, y toward right ascension 90 degrees and declination
        0, z toward the north celestial pole.

    ra, dec: float
        The right ascension and declination of the target (or some other
        point, such as the center of a detector) in the barycentric coordinate
        system.  The equator and equinox should be the same as the coordinate
        system for the velocity.

    Returns
    -------
    scale_factor: float
        Multiply the nominal image scale (e.g. in degrees per pixel) by
        this value to obtain the image scale corrected for the "aberration
        of starlight" due to the velocity of JWST with respect to the Sun.

    apparent_ra: float
        Apparent star position in the moving telescope frame.

    apparent_dec: float
        Apparent star position in the moving telescope frame.

    """
    beta = np.array([velocity_x, velocity_y, velocity_z]) / SPEED_OF_LIGHT
    beta2 = np.dot(beta, beta)  # |beta|^2
    if beta2 == 0.0:
        logger.warning('Observatory speed is zero. Setting VA scale to 1.0')
        return 1.0, ra, dec

    u = np.asanyarray(SphericalToCartesian()(ra, dec))
    beta_u = np.dot(beta, u)
    igamma = np.sqrt(1.0 - beta2)  # inverse of usual gamma
    scale_factor = (1.0 + beta_u) / igamma

    # Algorithm below is from Colin Cox notebook.
    # Also see: Instrument Science Report OSG-CAL-97-06 by Colin Cox (1997).
    u_corr = (igamma * u + beta *
              (1.0 + (1.0 - igamma) * beta_u / beta2)) / (1.0 + beta_u)

    apparent_ra, apparent_dec = CartesianToSpherical()(*u_corr)
    return scale_factor, apparent_ra, apparent_dec
Beispiel #3
0
def test_v2v3todet_roundtrips():
    s2c = (Scale(1.0 / 3600.0)
           & Scale(1.0 / 3600.0)) | SphericalToCartesian(wrap_lon_at=180)

    s = 1.0e-5
    crpix = np.random.random(2)
    alpha = 0.25 * np.pi * np.random.random()
    x, y = 1024 * np.random.random(2)
    v2, v3 = 45 * np.random.random(2)
    cd = [[s * np.cos(alpha), -s * np.sin(alpha)],
          [s * np.sin(alpha), s * np.cos(alpha)]]

    d2v = create_DetToV2V3(v2ref=123.0,
                           v3ref=500.0,
                           roll=15.0,
                           crpix=crpix,
                           cd=cd)
    v2d = create_V2V3ToDet(v2ref=123.0,
                           v3ref=500.0,
                           roll=15.0,
                           crpix=crpix,
                           cd=cd)

    assert np.allclose(d2v.inverse(*d2v(x, y)), (x, y),
                       rtol=1e3 * _ATOL,
                       atol=1e3 * _ATOL)

    assert (np.allclose(s2c(*v2d.inverse(*v2d(v2, v3))),
                        s2c(v2, v3),
                        rtol=1e3 * _ATOL,
                        atol=_ATOL)
            or np.allclose(-np.asanyarray(s2c(*v2d.inverse(*v2d(v2, v3)))),
                           s2c(v2, v3),
                           rtol=1e3 * _ATOL,
                           atol=_ATOL))
    assert np.allclose(v2d(*d2v(x, y)), (x, y),
                       rtol=1e5 * _ATOL,
                       atol=1e3 * _ATOL)

    assert (np.allclose(s2c(*d2v(*v2d(v2, v3))),
                        s2c(v2, v3),
                        rtol=1e3 * _ATOL,
                        atol=1e3 * _ATOL)
            or np.allclose(-np.asanyarray(s2c(*d2v(*v2d(v2, v3)))),
                           s2c(v2, v3),
                           rtol=1e3 * _ATOL,
                           atol=1e3 * _ATOL))
Beispiel #4
0
def v23tosky(input_model, wrap_v2_at=180, wrap_lon_at=360):
    v2_ref = input_model.meta.wcsinfo.v2_ref / 3600
    v3_ref = input_model.meta.wcsinfo.v3_ref / 3600
    roll_ref = input_model.meta.wcsinfo.roll_ref
    ra_ref = input_model.meta.wcsinfo.ra_ref
    dec_ref = input_model.meta.wcsinfo.dec_ref

    angles = np.array([v2_ref, -v3_ref, roll_ref, dec_ref, -ra_ref])
    axes = "zyxyz"
    rot = RotationSequence3D(angles, axes_order=axes)

    # The sky rotation expects values in deg.
    # This should be removed when models work with quantities.
    m = ((Scale(1 / 3600) & Scale(1 / 3600)) | SphericalToCartesian(wrap_lon_at=wrap_v2_at)
         | rot | CartesianToSpherical(wrap_lon_at=wrap_lon_at))
    m.name = 'v23tosky'
    return m
Beispiel #5
0
    def _tpcorr_init(v2_ref, v3_ref, roll_ref):
        s2c = SphericalToCartesian(name='s2c', wrap_lon_at=180)
        c2s = CartesianToSpherical(name='c2s', wrap_lon_at=180)

        unit_conv = Scale(1.0 / 3600.0, name='arcsec_to_deg_1D')
        unit_conv = unit_conv & unit_conv
        unit_conv.name = 'arcsec_to_deg_2D'

        unit_conv_inv = Scale(3600.0, name='deg_to_arcsec_1D')
        unit_conv_inv = unit_conv_inv & unit_conv_inv
        unit_conv_inv.name = 'deg_to_arcsec_2D'

        affine = AffineTransformation2D(name='tp_affine')
        affine_inv = AffineTransformation2D(name='tp_affine_inv')

        rot = RotationSequence3D([v2_ref, -v3_ref, roll_ref],
                                 'zyx',
                                 name='det_to_optic_axis')
        rot_inv = rot.inverse
        rot_inv.name = 'optic_axis_to_det'

        # projection submodels:
        c2tan = ((Mapping((0, 1, 2), name='xyz') / Mapping(
            (0, 0, 0), n_inputs=3, name='xxx')) | Mapping((1, 2), name='xtyt'))
        c2tan.name = 'Cartesian 3D to TAN'
        tan2c = (Mapping((0, 0, 1), n_inputs=2, name='xtyt2xyz') |
                 (Const1D(1, name='one') & Identity(2, name='I(2D)')))
        tan2c.name = 'TAN to cartesian 3D'

        total_corr = (unit_conv | s2c | rot | c2tan | affine | tan2c | rot_inv
                      | c2s | unit_conv_inv)
        total_corr.name = 'JWST tangent-plane linear correction. v1'

        inv_total_corr = (unit_conv | s2c | rot | c2tan | affine_inv | tan2c
                          | rot_inv | c2s | unit_conv_inv)
        inv_total_corr.name = 'Inverse JWST tangent-plane linear correction. v1'

        # TODO
        # re-enable circular inverse definitions once
        # https://github.com/spacetelescope/asdf/issues/744 or
        # https://github.com/spacetelescope/asdf/issues/745 are resolved.
        #
        # inv_total_corr.inverse = total_corr
        total_corr.inverse = inv_total_corr

        return total_corr
Beispiel #6
0
def test_v23_to_sky():
    """
    Test taken from INS report.
    """
    ra_ref = 165  # in deg
    dec_ref = 54  # in deg
    v2_ref = -503.654472 / 3600  # in deg
    v3_ref = -318.742464 / 3600  # in deg
    r0 = 37  # in deg

    v2 = 210  # in deg
    v3 = -75  # in deg
    expected_ra_dec = (107.12810484789563, -35.97940247128502)  # in deg
    angles = [v2_ref, -v3_ref, r0, dec_ref, -ra_ref]
    axes = "zyxyz"

    rot = RotationSequence3D(angles, axes_order=axes)
    v2s = SphericalToCartesian() | rot | CartesianToSpherical()
    radec = v2s(v2, v3)
    assert_allclose(radec, expected_ra_dec, atol=1e-10)
Beispiel #7
0
)
from astropy.modeling.fitting import LinearLSQFitter
from gwcs import wcstools, WCS
from gwcs import coordinate_frames as cf
from gwcs.geometry import SphericalToCartesian

from ..assign_wcs.util import wrap_ra
from .. import datamodels
from . import resample_utils
from .resample import ResampleData


log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)

_S2C = SphericalToCartesian()


class ResampleSpecData(ResampleData):
    """
    This is the controlling routine for the resampling process.

    Notes
    -----
    This routine performs the following operations::

      1. Extracts parameter settings from input model, such as pixfrac,
         weight type, exposure time (if relevant), and kernel, and merges
         them with any user-provided values.
      2. Creates output WCS based on input images and define mapping function
         between all input arrays and the output array.
Beispiel #8
0
def _make_gwcs_wcs(fits_hdr):
    hdr = fits.Header.fromfile(get_pkg_data_filename(fits_hdr))
    fw = fitswcs.WCS(hdr)

    a_order = hdr['A_ORDER']
    a_coeff = {}
    for i in range(a_order + 1):
        for j in range(a_order + 1 - i):
            key = 'A_{:d}_{:d}'.format(i, j)
            if key in hdr:
                a_coeff[key] = hdr[key]

    b_order = hdr['B_ORDER']
    b_coeff = {}
    for i in range(b_order + 1):
        for j in range(b_order + 1 - i):
            key = 'B_{:d}_{:d}'.format(i, j)
            if key in hdr:
                b_coeff[key] = hdr[key]

    cx = {"c" + k[2:]: v for k, v in a_coeff.items()}
    cy = {"c" + k[2:]: v for k, v in b_coeff.items()}
    sip_distortion = ((Shift(-fw.wcs.crpix[0]) & Shift(-fw.wcs.crpix[1]))
                      | Mapping((0, 1, 0, 1))
                      | (polynomial.Polynomial2D(a_order, **cx, c1_0=1)
                         & polynomial.Polynomial2D(b_order, **cy, c0_1=1))
                      | (Shift(fw.wcs.crpix[0]) & Shift(fw.wcs.crpix[1])))

    y, x = np.indices(fw.array_shape)

    unit_conv = Scale(1.0 / 3600.0, name='arcsec_to_deg_1D')
    unit_conv = unit_conv & unit_conv
    unit_conv.name = 'arcsec_to_deg_2D'

    unit_conv_inv = Scale(3600.0, name='deg_to_arcsec_1D')
    unit_conv_inv = unit_conv_inv & unit_conv_inv
    unit_conv_inv.name = 'deg_to_arcsec_2D'

    c2s = CartesianToSpherical(name='c2s', wrap_lon_at=180)
    s2c = SphericalToCartesian(name='s2c', wrap_lon_at=180)
    c2tan = ((Mapping((0, 1, 2), name='xyz') / Mapping(
        (0, 0, 0), n_inputs=3, name='xxx')) | Mapping((1, 2), name='xtyt'))
    c2tan.name = 'Cartesian 3D to TAN'

    tan2c = (Mapping((0, 0, 1), n_inputs=2, name='xtyt2xyz') |
             (Const1D(1, name='one') & Identity(2, name='I(2D)')))
    tan2c.name = 'TAN to cartesian 3D'

    tan2c.inverse = c2tan
    c2tan.inverse = tan2c

    aff = AffineTransformation2D(matrix=fw.wcs.cd)

    offx = Shift(-fw.wcs.crpix[0])
    offy = Shift(-fw.wcs.crpix[1])

    s = 5e-6
    scale = Scale(s) & Scale(s)

    sip_distortion |= (offx & offy) | scale | tan2c | c2s | unit_conv_inv

    taninv = s2c | c2tan
    tan = Pix2Sky_TAN()
    n2c = RotateNative2Celestial(fw.wcs.crval[0], fw.wcs.crval[1], 180)
    wcslin = unit_conv | taninv | scale.inverse | aff | tan | n2c

    sky_frm = cf.CelestialFrame(reference_frame=coord.ICRS())
    det_frm = cf.Frame2D(name='detector')
    v2v3_frm = cf.Frame2D(name="v2v3",
                          unit=(u.arcsec, u.arcsec),
                          axes_names=('x', 'y'),
                          axes_order=(0, 1))
    pipeline = [(det_frm, sip_distortion), (v2v3_frm, wcslin), (sky_frm, None)]

    gw = gwcs.WCS(input_frame=det_frm,
                  output_frame=sky_frm,
                  forward_transform=pipeline)
    gw.crpix = fw.wcs.crpix
    gw.crval = fw.wcs.crval
    gw.bounding_box = ((-0.5, fw.pixel_shape[0] - 0.5),
                       (-0.5, fw.pixel_shape[1] - 0.5))

    # sanity check:
    for _ in range(100):
        x = np.random.randint(1, fw.pixel_shape[0])
        y = np.random.randint(1, fw.pixel_shape[1])
        assert np.allclose(gw(x, y),
                           fw.all_pix2world(x, y, 1),
                           rtol=0,
                           atol=1e-11)

    return gw
A module containing unit tests for the `wcsutil` module.

Licensed under a 3-clause BSD style license - see LICENSE.rst

"""
import math
import numpy as np
from astropy.modeling import Model, Parameter
from astropy.modeling.models import AffineTransformation2D, Identity
from astropy import coordinates as coord
from astropy import units as u
import gwcs
from gwcs.geometry import CartesianToSpherical, SphericalToCartesian
from tweakwcs.tpwcs import TPWCS, JWSTgWCS

_S2C = SphericalToCartesian(name='s2c', wrap_lon_at=180)
_C2S = CartesianToSpherical(name='c2s', wrap_lon_at=180)


class DummyTPWCS(TPWCS):
    def set_correction(self,
                       matrix=[[1, 0], [0, 1]],
                       shift=[0, 0],
                       ref_tpwcs=None,
                       meta=None,
                       **kwargs):
        super().set_correction(matrix=matrix,
                               shift=shift,
                               ref_tpwcs=ref_tpwcs,
                               meta=meta,
                               **kwargs)