Exemple #1
0
def abl_to_v2v3l(input_model, reference_files):
    """
    Create the transform from "alpha_beta" to "v2v3" frame.

    Transform description:
    forward transform
      RegionsSelector
        label_mapper is LabelMapperDict()
        {channel_wave_range (): channel_number}
        selector is {channel_number: ab2v2 & ab2v3}
    bacward_transform
      RegionsSelector
        label_mapper is LabelMapperDict()
        {channel_wave_range (): channel_number}
        selector is {channel_number: v22ab & v32ab}
    """
    band = input_model.meta.instrument.band
    channel = input_model.meta.instrument.channel
    # used to read the wavelength range
    channels = [c + band for c in channel]

    with DistortionMRSModel(reference_files['distortion']) as dist:
        v23 = dict(zip(dist.abv2v3_model.channel_band,
                       dist.abv2v3_model.model))

    with WavelengthrangeModel(reference_files['wavelengthrange']) as f:
        wr = dict(zip(f.waverange_selector, f.wavelengthrange))

    dict_mapper = {}
    sel = {}
    # Since there are two channels in each reference file we need to loop over them
    for c in channels:
        ch = int(c[0])
        dict_mapper[tuple(wr[c])] = (models.Mapping(
            (2, ), name="mapping_lam") | models.Const1D(ch, name="channel #"))
        ident1 = models.Identity(1, name='identity_lam')
        ident1._inputs = ('lam', )
        chan_v23 = v23[c]

        v23chan_backward = chan_v23.inverse
        del chan_v23.inverse
        v23_spatial = chan_v23
        v23_spatial.inverse = v23chan_backward
        # Tack on passing the third wavelength component
        v23c = v23_spatial & ident1
        sel[ch] = v23c

    wave_range_mapper = selector.LabelMapperRange(
        ('alpha', 'beta', 'lam'),
        dict_mapper,
        inputs_mapping=models.Mapping([
            2,
        ]))
    wave_range_mapper.inverse = wave_range_mapper.copy()
    abl2v2v3l = selector.RegionsSelector(('alpha', 'beta', 'lam'),
                                         ('v2', 'v3', 'lam'),
                                         label_mapper=wave_range_mapper,
                                         selector=sel)

    return abl2v2v3l
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)
Exemple #3
0
def remap_distortion_model(model, dispersion_axis):
    """
    Remaps the distortion model so it can return a 2D array.

    Parameters
    ----------
    model : :class:`~astropy.modeling.models.Model`
        A model that receives 2D data and returns 1D data.

    dispersion_axis : {0 or 1}
        Define distortion model along the rows (0) or along the columns (1).

    Returns
    -------
    :class:`~astropy.modeling.models.Model`
        A model that receives and returns 2D data.

    See also
    --------
    - https://docs.astropy.org/en/stable/modeling/compound-models.html#advanced-mappings

    """
    m = models.Identity(2)

    if dispersion_axis == 0:
        m.inverse = models.Mapping((0, 1, 1)) | (model & models.Identity(1))
    else:
        m.inverse = models.Mapping((0, 0, 1)) | (models.Identity(1) & model)

    return m
    def _generate_wcs_transform(dispaxis):
        """Create mock gwcs.WCS object for resampled s2d data"""
        detector = cf.Frame2D(name='detector',
                              axes_order=(0, 1),
                              unit=(u.pix, u.pix))
        icrs = cf.CelestialFrame(name='icrs',
                                 reference_frame=coord.ICRS(),
                                 axes_order=(0, 1),
                                 unit=(u.deg, u.deg),
                                 axes_names=('RA', 'DEC'))
        spec = cf.SpectralFrame(name='spec',
                                axes_order=(2, ),
                                unit=(u.micron, ),
                                axes_names=('lambda', ))
        world = cf.CompositeFrame(name="world", frames=[icrs, spec])

        if dispaxis == 1:
            mapping = models.Mapping((0, 1, 0))
        if dispaxis == 2:
            mapping = models.Mapping((0, 1, 1))

        transform = mapping | (models.Const1D(42) & models.Const1D(42)
                               & (models.Shift(30) | models.Scale(0.1)))
        pipeline = [(detector, transform), (world, None)]
        wcs = WCS(pipeline)

        return wcs
def abtov2v3model(channel,**kwargs):
    # Construct the reference data model in general JWST imager type
    input_model = datamodels.ImageModel()
    # Convert input of type '1A' into the band and channel that pipeline needs
    theband,thechan=bandchan(channel)
    # Set the filter in the data model meta header
    input_model.meta.instrument.band = theband
    input_model.meta.instrument.channel = thechan
 
    # If passed input refs keyword, unpack and use it
    if ('refs' in kwargs):
      therefs=kwargs['refs']
    # Otherwise use default reference files
    else:
      therefs=get_fitsreffile(channel)

    # The pipeline transform actually uses the triple
    # (alpha,beta,lambda) -> (v2,v3,lambda)
    basedistortion = miri.abl_to_v2v3l(input_model, therefs)
    distortion = basedistortion

    # Therefore we need to hack a reasonable wavelength onto our input, run transform,
    # then hack it back off again

    thewave=midwave(channel)
    # Duplicate the beta value at first, then replace with wavelength value
    map=models.Mapping((0,1,1)) | models.Identity(1) & models.Identity(1) & models.Const1D(thewave)
    map.inverse=models.Mapping((0,1),n_inputs=3)

    allmap= map | distortion | map.inverse
    allmap.inverse= map | distortion.inverse | map.inverse

    # Return the distortion object that can then be queried
    return allmap
Exemple #6
0
def alpha_beta2XanYan(input_model, reference_files):
    """
    Create the transform from detector to Xan, Yan frame.

    forward transform:
      RegionsSelector
        label_mapper is LabelMapperDict()
        {channel_wave_range (): channel_number}
        selector is {channel_number: ab2Xan & ab2Yan}
    bacward_transform
      RegionsSelector
        label_mapper is LabelMapperDict()
        {channel_wave_range (): channel_number}
        selector is {channel_number: Xan2ab & Yan2ab}
    """
    band = input_model.meta.instrument.band
    channel = input_model.meta.instrument.channel
    # used to read the wavelength range
    channels = [c + band for c in channel]

    f = AsdfFile.open(reference_files['v2v3'])
    v23 = f.tree['model']
    f.close()
    f = AsdfFile.open(reference_files['wavelengthrange'])
    # the following should go in the asdf reader
    wave_range = f.tree['wavelengthrange'].copy()
    wave_channels = f.tree['channels']
    wr = {}
    for ch, r in zip(wave_channels, wave_range):
        wr[ch] = r
    f.close()

    dict_mapper = {}
    sel = {}
    for c in channels:
        ch = int(c[0])
        dict_mapper[tuple(wr[c])] = models.Mapping((2,), name="mapping_lam") | \
                   models.Const1D(ch, name="channel #")
        map1 = models.Mapping((1, 0, 1, 0), name='map2poly')
        map1._outputs = ('alpha', 'beta', 'alpha', 'beta')
        map1._inputs = ('alpha', 'beta')
        map1.inverse = models.Mapping((0, 1))
        ident1 = models.Identity(1, name='identity_lam')
        ident1._inputs = ('lam',)
        chan_v23 = v23[c]
        v23chan_backward = chan_v23.inverse
        del chan_v23.inverse
        v23_spatial = map1 | chan_v23
        v23_spatial.inverse = map1 | v23chan_backward
        v23c = v23_spatial & ident1
        sel[ch] = v23c

    wave_range_mapper = selector.LabelMapperRange(('alpha', 'beta', 'lam'), dict_mapper,
                                                  inputs_mapping=models.Mapping([2, ]))
    wave_range_mapper.inverse = wave_range_mapper.copy()
    ab2xyan = selector.RegionsSelector(('alpha', 'beta', 'lam'), ('v2', 'v3', 'lam'),
                                      label_mapper=wave_range_mapper,
                                      selector=sel)

    return ab2xyan
Exemple #7
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
def create_channel_selector(alpha, lam, channel, beta, ch_v2, ch_v3):
    if channel == 1:
        nslice = range(101, 122)  #21
    elif channel == 2:
        nslice = range(201, 218)  #17
    elif channel == 3:
        nslice = 16
    elif channel == 4:
        nslice = 12
    else:
        raise ValueError("Incorrect channel #")

    # transformation from local system (alpha, beta) to V2/V3
    p_v2 = models.Polynomial2D(2)
    p_v3 = models.Polynomial2D(2)
    p_v2.c0_0, p_v2.c0_1, p_v2.c1_0, p_v2.c1_1 = ch_v2[1:]
    p_v3.c0_0, p_v3.c0_1, p_v3.c1_0, p_v3.c1_1 = ch_v3[1:]
    ab_v2v3 = p_v2 & p_v3

    ind = []
    for i in range(5):
        for j in range(5):
            ind.append((i, j))

    selector = {}
    # In the paper the formula is (x-xs)^j*y^i, so the 'x' corresponds
    # to y in modeling. - swapped in Mapping
    axs = alpha.field('x_s')
    lxs = lam.field('x_s')
    #for i in range(nslice):
    for i, sl in enumerate(nslice):
        ashift = models.Shift(axs[i])
        lshift = models.Shift(lxs[i])
        palpha = models.Polynomial2D(8)
        plam = models.Polynomial2D(8)
        for index, coeff in zip(ind, alpha[i][1:]):
            setattr(palpha, 'c{0}_{1}'.format(index[0], index[1]), coeff)
        for index, coeff in zip(ind, lam[i][1:]):
            setattr(plam, 'c{0}_{1}'.format(index[0], index[1]), coeff)
        alpha_model = ashift & models.Identity(1) | palpha
        lam_model = lshift & models.Identity(1) | plam
        beta_model = models.Const1D(beta[0] + (i - 1) * beta[1])
        # Note swapping of axes
        a_b_l = models.Mapping(
            (1, 0, 0, 1, 0)) | alpha_model & beta_model & lam_model
        v2_v3_l = a_b_l | models.Mapping(
            (0, 1, 0, 1, 2)) | ab_v2v3 & models.Identity(1)
        selector[sl] = v2_v3_l
    # return alpha, beta, lambda
    return selector
Exemple #9
0
def miri_models():
    reg_models3 = miri_ifu_ref_tools.make_channel_models(3)
    reg_models4 = miri_ifu_ref_tools.make_channel_models(4)
    reg_models = {}

    for reg in reg_models3:
        lam_model, alpha_model, beta_model, _ = reg_models3[reg]
        model = models.Mapping((0, 1, 0, 0, 1)) | alpha_model & beta_model & lam_model
        reg_models[reg] = model
    for reg in reg_models4:
        lam_model, alpha_model, beta_model, _ = reg_models4[reg]
        model = models.Mapping((0, 1, 0, 0, 1)) | alpha_model & beta_model & lam_model
        reg_models[reg] = model
    return reg_models
def test_with_bounding_box():
    """
    Test the option to evaluate a model respecting
    its bunding_box.
    """
    p = models.Polynomial2D(2) & models.Polynomial2D(2)
    m = models.Mapping((0, 1, 0, 1)) | p
    with NumpyRNGContext(1234567):
        m.parameters = np.random.rand(12)

    m.bounding_box = ((3, 9), (1, 8))
    x, y = np.mgrid[:10, :10]
    a, b = m(x, y)
    aw, bw = m(x, y, with_bounding_box=True)
    ind = (~np.isnan(aw)).nonzero()
    assert_allclose(a[ind], aw[ind])
    assert_allclose(b[ind], bw[ind])

    aw, bw = m(x, y, with_bounding_box=True, fill_value=1000)
    ind = (aw != 1000).nonzero()
    assert_allclose(a[ind], aw[ind])
    assert_allclose(b[ind], bw[ind])

    # test the order of bbox is not reversed for 1D models
    p = models.Polynomial1D(1, c0=12, c1=2.3)
    p.bounding_box = (0, 5)
    assert (p(1) == p(1, with_bounding_box=True))
def miri_old_model():
    d2c = fits.open('polyd2c_1A_01.00.00.fits')
    slices = d2c[1].data
    rids = np.unique(slices).tolist()
    rids.remove(0)

    shiftx = models.Shift(-d2c[0].header['CENTERX'])
    shifty = models.Shift(-d2c[0].header['CENTERY'])
    scalex = models.Scale(1. / d2c[0].header['NORMX'])
    scaley = models.Scale(1. / d2c[0].header['NORMY'])

    b1 = d2c[1].header['B_DEL']
    b0 = d2c[1].header['B_MIN']

    coeffs = d2c[2].data
    channel_selector = {}
    for i in rids:
        palpha = fits_column_to_model(coeffs.field("alpha_" + str(int(i))), 4,
                                      4)
        plam = fits_column_to_model(coeffs.field("lambda_" + str(int(i))), 4,
                                    4)
        malpha = (shiftx & shifty) | (scalex & scaley) | palpha
        mlam = (shiftx & shifty) | (scalex & scaley) | plam

        beta = models.Const1D(b0 + i * b1)

        channel_selector[i] = models.Mapping(
            (0, 1, 0, 0, 1)) | malpha & beta & mlam
    return channel_selector
Exemple #12
0
    def __init__(self,
                 inputs,
                 mapper,
                 no_label=np.nan,
                 inputs_mapping=None,
                 name=None,
                 **kwargs):
        self._no_label = no_label
        self._inputs = inputs
        self._n_inputs = len(inputs)
        self._outputs = tuple(
            ['x{0}'.format(ind) for ind in list(range(mapper.n_outputs))])
        if isinstance(inputs_mapping, tuple):
            inputs_mapping = astmodels.Mapping(inputs_mapping)
        elif inputs_mapping is not None and not isinstance(
                inputs_mapping, astmodels.Mapping):
            raise TypeError(
                "inputs_mapping must be an instance of astropy.modeling.Mapping."
            )

        self._inputs_mapping = inputs_mapping
        self._mapper = mapper
        self._input_units_strict = {key: False for key in self._inputs}
        self._input_units_allow_dimensionless = {
            key: False
            for key in self._inputs
        }
        super(_LabelMapper, self).__init__(name=name, **kwargs)
        self.outputs = ('label', )
Exemple #13
0
def miri_models():
    # Use channels 3 and 4 for this example
    reg_models3 = make_channel_models(3)
    reg_models4 = make_channel_models(4)
    reg_models = {}

    for reg in reg_models3:
        lam_model, alpha_model, beta_model, _ = reg_models3[reg]
        model = models.Mapping(
            (0, 1, 0, 0, 1)) | alpha_model & beta_model & lam_model
        reg_models[reg] = model
    for reg in reg_models4:
        lam_model, alpha_model, beta_model, _ = reg_models4[reg]
        model = models.Mapping(
            (0, 1, 0, 0, 1)) | alpha_model & beta_model & lam_model
        reg_models[reg] = model
    return reg_models
Exemple #14
0
def test_LabelMapperDict():
    dmapper = create_scalar_mapper()
    sel = selector.LabelMapperDict(('x', 'y'),
                                   dmapper,
                                   atol=10**-3,
                                   inputs_mapping=models.Mapping((0, ),
                                                                 n_inputs=2))
    assert (sel(-1.9580, 2) == dmapper[-1.95805483](-1.95805483, 2))
Exemple #15
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
Exemple #16
0
def make_fitswcs_transform(header):
    """
    Create a basic FITS WCS transform.
    It does not include distortions.

    Parameters
    ----------
    header : `astropy.io.fits.Header` or dict
        FITS Header (or dict) with basic WCS information

    """
    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.")

    # If a pixel axis maps directly to an output axis, we want to have that
    # model completely self-contained, so don't put all the CRPIXj shifts
    # in a single CompoundModel at the beginning
    transforms = []

    # The tricky stuff!
    sky_model = fitswcs_image(wcs_info)
    linear_models = fitswcs_linear(wcs_info)
    all_models = linear_models
    if sky_model:
        all_models.append(sky_model)

    # Now arrange the models so the inputs and outputs are in the right places
    all_models.sort(key=lambda m: m.meta['output_axes'][0])
    input_axes = [ax for m in all_models for ax in m.meta['input_axes']]
    output_axes = [ax for m in all_models for ax in m.meta['output_axes']]
    if input_axes != list(range(len(input_axes))):
        input_mapping = models.Mapping(input_axes)
        transforms.append(input_mapping)

    transforms.append(functools.reduce(core._model_oper('&'), all_models))

    if output_axes != list(range(len(output_axes))):
        output_mapping = models.Mapping(output_axes)
        transforms.append(output_mapping)

    return functools.reduce(core._model_oper('|'), transforms)
Exemple #17
0
def gwcs_2d_spatial_reordered():
    """
    A simple one step spatial WCS, in ICRS with a 1 and 2 px shift.
    """
    out_frame = cf.CelestialFrame(reference_frame=coord.ICRS(),
                                  axes_order=(1, 0))
    return wcs.WCS(model_2d_shift | models.Mapping((1, 0)),
                   input_frame=detector_2d,
                   output_frame=out_frame)
Exemple #18
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
Exemple #19
0
    def inverse(self):
        left_inverse = self.left.inverse
        right_inverse = self.right.inverse

        total_inputs = self.n_outputs
        n_left_only_inputs = total_inputs - self.shared_inputs

        # Pass through arguments to the left model unchanged while computing the right output
        mapping = list(range(n_left_only_inputs))
        step1 = m.Mapping(mapping) & right_inverse

        # Now pass through the right outputs unchanged while also feeding them into the left model

        # This mapping duplicates the output of the right inverse to be fed
        # into the left and also out unmodified at the end of the transform
        inter_mapping = mapping + list(range(max(mapping) + 1, max(mapping) + 1 + right_inverse.n_outputs)) * 2
        step2 = m.Mapping(inter_mapping) | (left_inverse & m.Identity(right_inverse.n_outputs))

        return step1 | step2
Exemple #20
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
Exemple #21
0
def test_LabelMapperDict():
    dmapper = create_scalar_mapper()
    sel = selector.LabelMapperDict(('x', 'y'), dmapper, atol=10**-3,
                                   inputs_mapping=models.Mapping((0,), n_inputs=2))
    assert(sel(-1.9580, 2) == dmapper[-1.95805483](-1.95805483, 2))

    with pytest.raises(TypeError):
        selector.LabelMapperDict(('x', 'y'),
                                 mapper={1: models.Rotation2D(23),
                                         2: models.Shift(1)
                                         }
                                 )
Exemple #22
0
def test_prepare_outputs_complex_reshape():
    x = np.array([[1,  2,  3,  4,  5],
                  [6,  7,  8,  9,  10],
                  [11, 12, 13, 14, 15]])
    y = np.array([[16, 17, 18, 19, 20],
                  [21, 22, 23, 24, 25],
                  [26, 27, 28, 29, 30]])

    m = models.Identity(3) | models.Mapping((2, 1, 0))
    m.bounding_box = ((0, 100), (0, 200), (0, 50))
    mf = models.fix_inputs(m, {2: 22})
    t = mf | models.Mapping((2, 1), n_inputs=3)

    output = mf(1, 2)
    assert output == (22, 2, 1)

    output = t(1, 2)
    assert output == (1, 2)

    output = t(x, y)
    assert len(output) == 2
    np.testing.assert_array_equal(output[0], x)
    np.testing.assert_array_equal(output[1], y)

    m = models.Identity(3) | models.Mapping((0, 1, 2))
    m.bounding_box = ((0, 100), (0, 200), (0, 50))
    mf = models.fix_inputs(m, {2: 22})
    t = mf | models.Mapping((0, 1), n_inputs=3)

    output = mf(1, 2)
    assert output == (1, 2, 22)

    output = t(1, 2)
    assert output == (1, 2)

    output = t(x, y)
    assert len(output) == 2
    np.testing.assert_array_equal(output[0], x)
    np.testing.assert_array_equal(output[1], y)
Exemple #23
0
def create_beta_models(b0, bdel, channel, nslices):
    beta = {}
    slices = {}
    for s in range(nslices):
        sl = channel * 100 + s + 1
        beta_s = b0 + s * bdel
        m = models.Const1D(beta_s, name='det2local')  #xy2beta and xy2lam
        beta[sl] = m
        inv = models.Const1D(sl)
        slices[beta_s] = models.Mapping([
            1,
        ]) | inv
    return beta, slices
Exemple #24
0
def _generate_compound_model(*lookup_tables, mesh=True):
    """
    Takes a set of quantities and returns a ND compound model.
    """
    model = _generate_tabular(lookup_tables[0])
    for lt in lookup_tables[1:]:
        model = model & _generate_tabular(lt)

    if mesh:
        return model

    # If we are not meshing the inputs duplicate the inputs across all models
    mapping = list(range(lookup_tables[0].ndim)) * len(lookup_tables)
    return models.Mapping(mapping) | model
Exemple #25
0
def lrs(input_model, reference_files):
    """
    Create the WCS pipeline for a MIRI fixed slit observation.

    reference_files = {"specwcs": 'MIRI_FM_MIRIMAGE_P750L_DISTORTION_04.02.00.fits'}
    """
    detector = cf.Frame2D(name='detector',
                          axes_order=(0, 1),
                          unit=(u.pix, u.pix))
    focal_spatial = cf.Frame2D(name='focal',
                               axes_order=(0, 1),
                               unit=(u.arcmin, u.arcmin))
    sky = cf.CelestialFrame(reference_frame=coord.ICRS())
    spec = cf.SpectralFrame(name='wavelength',
                            axes_order=(2, ),
                            unit=(u.micron, ),
                            axes_names=('lambda', ))
    focal = cf.CompositeFrame([focal_spatial, spec])

    ref = fits.open(reference_files['specwcs'])
    ldata = ref[1].data
    if input_model.meta.exposure.type.lower() == 'mir_lrs-fixedslit':
        zero_point = ref[1].header['imx'], ref[1].header['imy']
    elif input_model.meta.exposure.type.lower() == 'mir_lrs-slitless':
        #zero_point = ref[1].header['imysltl'], ref[1].header['imxsltl']
        #zero point in reference file is wrong
        # This should eb moved eventually to the reference file.
        zero_point = [35, 442]  #[35, 763] # account for subarray
    lrsdata = np.array([l for l in ldata])
    x0 = lrsdata[:, 3]
    x1 = lrsdata[:, 5]
    y0 = lrsdata[:, 4]
    domain = [{
        'lower': x0.min() + zero_point[0],
        'upper': x1.max() + zero_point[0]
    }, {
        'lower': (y0.min() + zero_point[1]),
        'upper': (y0.max() + zero_point[1])
    }]
    log.info("Setting domain to {0}".format(domain))
    lrs_wav_model = jwmodels.LRSWavelength(lrsdata, zero_point)
    ref.close()
    angle = np.arctan(0.00421924)
    spatial = models.Rotation2D(angle)
    det2focal = models.Mapping((0, 1, 0, 1)) | spatial & lrs_wav_model
    det2focal.meta['domain'] = domain
    pipeline = [(detector, det2focal), (focal, None)]
    #(sky, None)
    #]
    return pipeline
Exemple #26
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
Exemple #27
0
def test_compound_model_with_bounding_box_true_and_single_output():
    """Regression test for issue #12373"""

    model = models.Mapping((1,)) | models.Shift(1)
    x = [1, 2]
    y = [3, 4]

    # Check baseline
    assert_equal(model(x, y), [4, 5])
    # Check with_bounding_box=True should be the same
    assert_equal(model(x, y, with_bounding_box=True), [4, 5])

    model.bounding_box = ((-np.inf, np.inf), (-np.inf, np.inf))
    # Check baseline
    assert_equal(model(x, y), [4, 5])
    # Check with_bounding_box=True should be the same
    assert_equal(model(x, y, with_bounding_box=True), [4, 5])
def test_coordinates_composite():
    spec = cf.SpectralFrame(name='wavelength',
                            unit=(u.micron, ),
                            axes_order=(2, ),
                            axes_names=('lambda', ))
    icrs = cf.CelestialFrame(reference_frame=coord.ICRS(), axes_order=(0, 1))
    frame = cf.CompositeFrame([icrs, spec])
    transform = models.Mapping(
        [0, 0, 1]) | models.Identity(2) & models.Polynomial1D(1, c0=.2, c1=.3)
    w = wcs.WCS(forward_transform=transform,
                output_frame=frame,
                input_frame=det)
    x = np.arange(3)
    result = getattr(w, w.output_frame).coordinates(x, x)
    assert_allclose(result[0].ra.value, w(x, x)[0])
    assert_allclose(result[0].ra.value, w(x, x)[1])
    assert_allclose(result[1].value, w(x, x)[2])
Exemple #29
0
def create_range_mapper():
    m = []
    for i in np.arange(9) * .1:
        c0_0, c1_0, c0_1, c1_1 = np.ones((4, )) * i
        m.append(
            models.Polynomial2D(2, c0_0=c0_0, c1_0=c1_0, c0_1=c0_1, c1_1=c1_1))
    keys = np.array([[4.88, 5.64], [5.75, 6.5], [6.67, 7.47], [7.7, 8.63],
                     [8.83, 9.96], [10.19, 11.49], [11.77, 13.28],
                     [13.33, 15.34], [15.56, 18.09]])

    rmapper = {}
    for k, v in zip(keys, m):
        rmapper[tuple(k)] = v

    sel = selector.LabelMapperRange(('x', 'y'),
                                    rmapper,
                                    inputs_mapping=models.Mapping((0, ),
                                                                  n_inputs=2))
    return sel
Exemple #30
0
    def __init__(self,
                 inputs,
                 mapper,
                 no_label=np.nan,
                 inputs_mapping=None,
                 name=None,
                 **kwargs):
        self._no_label = no_label
        self.inputs = inputs
        self.outputs = tuple(
            ['x{0}'.format(ind) for ind in list(range(mapper.n_outputs))])
        if isinstance(inputs_mapping, tuple):
            inputs_mapping = astmodels.Mapping(inputs_mapping)
        elif inputs_mapping is not None and not isinstance(
                inputs_mapping, astmodels.Mapping):
            raise TypeError(
                "inputs-mapping must be an instance of astropy.modeling.Mapping."
            )

        self._inputs_mapping = inputs_mapping
        self._mapper = mapper
        super(_LabelMapper, self).__init__(name=name, **kwargs)