Esempio n. 1
0
def test_pixel_to_pixel_correlated():

    wcs_in = WCS(naxis=2)
    wcs_in.wcs.ctype = 'DEC--TAN', 'RA---TAN'
    wcs_in.wcs.set()

    wcs_out = WCS(naxis=2)
    wcs_out.wcs.ctype = 'GLON-CAR', 'GLAT-CAR'
    wcs_out.wcs.set()

    # First try with scalars
    x, y = pixel_to_pixel(wcs_in, wcs_out, 1, 2)
    assert x.shape == ()
    assert y.shape == ()

    # Now try with broadcasted arrays
    x = np.linspace(10, 20, 10)
    y = np.linspace(10, 20, 20)
    Y1, X1 = np.meshgrid(y, x, indexing='ij', copy=False)
    Y2, X2 = pixel_to_pixel(wcs_in, wcs_out, X1, Y1)

    # The final arrays should have the correct shape
    assert X2.shape == (20, 10)
    assert Y2.shape == (20, 10)

    # and there are no efficiency gains here since the celestial axes are correlated
    assert unbroadcast(X2).shape == (20, 10)
Esempio n. 2
0
def test_pixel_to_pixel_1d():

    # Simple test to make sure that when WCS only returns one world coordinate
    # this still works correctly (since this requires special treatment behind
    # the scenes).

    wcs_in = WCS(naxis=1)
    wcs_in.wcs.ctype = 'COORD1',
    wcs_in.wcs.cunit = 'nm',
    wcs_in.wcs.set()

    wcs_out = WCS(naxis=1)
    wcs_out.wcs.ctype = 'COORD2',
    wcs_out.wcs.cunit = 'cm',
    wcs_out.wcs.set()

    # First try with a scalar
    x = pixel_to_pixel(wcs_in, wcs_out, 1)
    assert x.shape == ()

    # Next with a regular array
    x = np.linspace(10, 20, 10)
    x = pixel_to_pixel(wcs_in, wcs_out, x)
    assert x.shape == (10, )

    # And now try with a broadcasted array
    x = np.broadcast_to(np.linspace(10, 20, 10), (4, 10))
    x = pixel_to_pixel(wcs_in, wcs_out, x)
    assert x.shape == (4, 10)

    # The broadcasting of the input should be retained
    assert unbroadcast(x).shape == (10, )
Esempio n. 3
0
def test_pixel_to_pixel():

    wcs_in = WCS(naxis=3)
    wcs_in.wcs.ctype = 'DEC--TAN', 'FREQ', 'RA---TAN'
    wcs_in.wcs.set()

    wcs_out = WCS(naxis=3)
    wcs_out.wcs.ctype = 'GLON-CAR', 'GLAT-CAR', 'FREQ'
    wcs_out.wcs.set()

    # First try with scalars
    with pytest.warns(AstropyUserWarning, match='No observer defined on WCS'):
        x, y, z = pixel_to_pixel(wcs_in, wcs_out, 1, 2, 3)
    assert x.shape == ()
    assert y.shape == ()
    assert z.shape == ()

    # Now try with broadcasted arrays
    x = np.linspace(10, 20, 10)
    y = np.linspace(10, 20, 20)
    z = np.linspace(10, 20, 30)
    Z1, Y1, X1 = np.meshgrid(z, y, x, indexing='ij', copy=False)
    with pytest.warns(AstropyUserWarning, match='No observer defined on WCS'):
        X2, Y2, Z2 = pixel_to_pixel(wcs_in, wcs_out, X1, Y1, Z1)

    # The final arrays should have the correct shape
    assert X2.shape == (30, 20, 10)
    assert Y2.shape == (30, 20, 10)
    assert Z2.shape == (30, 20, 10)

    # But behind the scenes should also be broadcasted
    assert unbroadcast(X2).shape == (30, 1, 10)
    assert unbroadcast(Y2).shape == (30, 1, 10)
    assert unbroadcast(Z2).shape == (20, 1)

    # We can put the values back through the function to ensure round-tripping
    with pytest.warns(AstropyUserWarning, match='No observer defined on WCS'):
        X3, Y3, Z3 = pixel_to_pixel(wcs_out, wcs_in, X2, Y2, Z2)

    # The final arrays should have the correct shape
    assert X2.shape == (30, 20, 10)
    assert Y2.shape == (30, 20, 10)
    assert Z2.shape == (30, 20, 10)

    # But behind the scenes should also be broadcasted
    assert unbroadcast(X3).shape == (30, 1, 10)
    assert unbroadcast(Y3).shape == (20, 1)
    assert unbroadcast(Z3).shape == (30, 1, 10)

    # And these arrays should match the input
    assert_allclose(X1, X3)
    assert_allclose(Y1, Y3)
    assert_allclose(Z1, Z3)
Esempio n. 4
0
File: io.py Progetto: ivvv/herspy
def _pixel_to_pixel(pixels, wcs):
    """
    Convenience function that wraps astropy.wcs.utils.pixel_to_pixel and maps
    SLW cube pixels to nearest SSW cube pixels and vice versa.

    Parameters
    ----------
    pixels : dictionary
        Dictionary containing the SLW and SSW pixels to be mapped. Format
        should be {'SLW': [[cols], [rows]], 'SSW': [[cols], [rows]]} for
        multiple pixels, or {'SLW': [col, row], 'SSW': [col, row]} for
        a single pixel. Both SPIRE bands are not required.
    wcs : dictionary of WCS
        Dictionary of WCS for SLW and SSW bands. see `_make_wcs`.

    Returns
    -------
    output : dictionary
        Dictionary of mapped pixels. Format matches `pixels` with reciprocal
        SPIRE band keys.
    """
    swap = {'SLW': 'SSW', 'SSW': 'SLW'}
    output = dict()
    for ary, pix in pixels.items():
        pix = np.array(pix)
        output[swap[ary]] = np.round(
            pixel_to_pixel(wcs[ary], wcs[swap[ary]], *pix),
            0).astype(int).tolist()
    return output
Esempio n. 5
0
def identify_invariant_axes(source_wcs,
                            target_wcs,
                            input_shape,
                            atol=1e-6,
                            rtol=1e-6):
    """
    Performs a pixel to pixel transformation to identify if there are any invariant axes
    between the given source and target WCS objects.

    Parameters
    ----------
    source_wcs: `astropy.wcs.wcsapi.BaseHighLevelWCS` or `astropy.wcs.wcsapi.BaseLowLevelWCS`

    target_wcs: `astropy.wcs.wcsapi.BaseHighLevelWCS` or `astropy.wcs.wcsapi.BaseLowLevelWCS`

    input_shape: `tuple`
        The array shape of the data.

    atol: `float`
        The absolute tolerance parameter for comparison.

    rtol: `float`
        The relative tolerance parameter for comparison.

    Returns
    -------
    result: `list`
        A list of booleans denoting whether the axis is invariant or not.
        Follows the WCS ordering.
    """

    input_pixel_coords = np.meshgrid(*[np.arange(n) for n in input_shape])

    output_pixel_coords = pixel_to_pixel(source_wcs, target_wcs,
                                         *input_pixel_coords)

    return [
        np.allclose(input_coord, output_coord, atol=atol,
                    rtol=rtol) for input_coord, output_coord in zip(
                        input_pixel_coords, output_pixel_coords)
    ]
Esempio n. 6
0
 def backwards(*pixel_input):
     return pixel_to_pixel(wcs2, wcs1, *pixel_input)
Esempio n. 7
0
 def forwards(*pixel_input):
     return pixel_to_pixel(wcs1, wcs2, *pixel_input)
Esempio n. 8
0
def add_single_spectra_to_map(
    spectra_map,
    *,
    header,
    data,
    spec_info=None,
    wcs_info=None,
    units_info=None,
    purpose_prefix=None,
    all_standard_units,
    all_keywords,
    valid_wcs,
    index=None,
):
    spec_wcs_info = {}
    spec_units_info = {}
    if wcs_info is not None:
        spec_wcs_info.update(wcs_info)
    if units_info is not None:
        spec_units_info.update(units_info)

    if spec_info is not None:
        spec_wcs_info.update(spec_info.get("wcs", {}))
        spec_units_info.update(spec_info.get("units", {}))
        purpose = spec_info.get("purpose")
    else:
        purpose = None

    purpose = get_purpose(
        header,
        purpose=purpose,
        purpose_prefix=purpose_prefix,
        all_keywords=all_keywords,
        index=index,
    )

    if purpose == Purpose.SKIP:
        return None

    if valid_wcs or not spec_wcs_info:
        wcs = WCS(header)
    else:
        wcs = compute_wcs_from_keys_and_values(header, **spec_wcs_info)

    if all_standard_units:
        spec_units_info = {"flux_unit_keyword": "BUNIT"}
    flux_unit = get_flux_units_from_keys_and_values(header, **spec_units_info)
    flux = data * flux_unit

    meta = {"header": header, "purpose": PURPOSE_SPECTRA_MAP[purpose]}

    if purpose in CREATE_SPECTRA:
        spectrum = Spectrum1D(wcs=wcs, flux=flux, meta=meta)
        spectra_map[PURPOSE_SPECTRA_MAP[purpose]].append(spectrum)
    elif purpose in ERROR_PURPOSES:
        try:
            spectrum = spectra_map[PURPOSE_SPECTRA_MAP[purpose]][-1]
        except IndexError:
            raise ValueError(f"No spectra to associate with {purpose}")
        aligned_flux = pixel_to_pixel(wcs, spectrum.wcs, flux)
        spectrum.uncertainty = UNCERTAINTY_MAP[purpose](aligned_flux)
        spectrum.meta["uncertainty_header"] = header

    # We never actually want to return something, this just flags it to pylint
    # that we know we're breaking out of the function when skip is selected
    return None