예제 #1
0
def test_sample_lm_broadcast(
        aperture_plane_model: primary_beam.PrimaryBeamAperturePlane) -> None:
    l = np.array([0.01, 0.02])
    m = np.array([0.03, -0.04, 0.01])
    frequency = 1500 * u.MHz

    actual = aperture_plane_model.sample(l[np.newaxis, :], m[:, np.newaxis],
                                         frequency, primary_beam.AltAzFrame(),
                                         primary_beam.OutputType.JONES_HV)

    expected = np.zeros((len(m), len(l), 2, 2), np.complex64)
    for i in range(len(m)):
        for j in range(len(l)):
            expected[i, j] = aperture_plane_model.sample(
                l[j], m[i], frequency, primary_beam.AltAzFrame(),
                primary_beam.OutputType.JONES_HV)

    # It isn't exact, presumably because the matrix multiplications sum
    # in a different order depending on size.
    np.testing.assert_allclose(actual, expected, atol=1e-7)

    # Also check with RADecFrame
    actual = aperture_plane_model.sample(
        -l[np.newaxis, :], m[:, np.newaxis], frequency,
        primary_beam.RADecFrame.from_parallactic_angle(0 * u.deg),
        primary_beam.OutputType.JONES_HV)
    np.testing.assert_allclose(actual, expected, atol=1e-7)
예제 #2
0
def test_sample_scalar_lm(
        aperture_plane_model: primary_beam.PrimaryBeamAperturePlane) -> None:
    l = 0.01
    m = 0.02
    frequency = 1500 * u.MHz

    scalar = aperture_plane_model.sample(l, m, frequency,
                                         primary_beam.AltAzFrame(),
                                         primary_beam.OutputType.JONES_HV)
    vector = aperture_plane_model.sample(np.array([l]), np.array([m]),
                                         frequency, primary_beam.AltAzFrame(),
                                         primary_beam.OutputType.JONES_HV)
    assert scalar.shape == (2, 2)
    np.testing.assert_array_equal(scalar, vector[0])
예제 #3
0
def test_sample_radec(
        aperture_plane_model: primary_beam.PrimaryBeamAperturePlane,
        lat: u.Quantity) -> None:
    model = aperture_plane_model
    location = EarthLocation.from_geodetic(18 * u.deg,
                                           lat=lat,
                                           height=100 * u.m)
    obstime = Time('2021-04-22T13:00:00Z')
    frequency = 1 * u.GHz
    altaz_frame = AltAz(obstime=obstime, location=location)
    target_altaz = SkyCoord(alt=70 * u.deg, az=150 * u.deg, frame=altaz_frame)

    l_altaz = [-0.002, 0.001, 0.0, 0.0, 0.0]
    m_altaz = [0.0, 0.02, 0.0, -0.03, 0.01]
    coords_altaz = _lm_to_coords(l_altaz, m_altaz, target_altaz)

    target_icrs = target_altaz.icrs
    coords_icrs = coords_altaz.icrs
    l_icrs, m_icrs = _coords_to_lm(coords_icrs, target_icrs)

    out_radec = model.sample(
        l_icrs, m_icrs, frequency,
        primary_beam.RADecFrame.from_sky_coord(target_icrs),
        primary_beam.OutputType.JONES_HV)
    out_altaz = model.sample(l_altaz, m_altaz, frequency,
                             primary_beam.AltAzFrame(),
                             primary_beam.OutputType.JONES_HV)
    # Tolerance is high because RADecFrame doesn't account for aberration
    np.testing.assert_allclose(out_radec, out_altaz, atol=1e-4)
예제 #4
0
def test_sample_out_of_range(
        aperture_plane_model: primary_beam.PrimaryBeamAperturePlane, l: float,
        m: float, frequency: u.Quantity) -> None:
    actual = aperture_plane_model.sample(l, m, frequency,
                                         primary_beam.AltAzFrame(),
                                         primary_beam.OutputType.JONES_HV)
    expected = np.full((2, 2), np.nan)
    np.testing.assert_array_equal(actual, expected)
예제 #5
0
def test_sample_multi_dim_lm(
        aperture_plane_model: primary_beam.PrimaryBeamAperturePlane) -> None:
    rs = np.random.RandomState(1)
    shape = (2, 3, 4)
    l = rs.random(shape) * 0.05
    m = rs.random(shape) * 0.05
    frequency = 1500 * u.MHz

    multi = aperture_plane_model.sample(l, m, frequency,
                                        primary_beam.AltAzFrame(),
                                        primary_beam.OutputType.JONES_HV)
    flat = aperture_plane_model.sample(l.ravel(), m.ravel(), frequency,
                                       primary_beam.AltAzFrame(),
                                       primary_beam.OutputType.JONES_HV)
    np.testing.assert_array_equal(multi, flat.reshape(multi.shape))
    # Make sure that we're comparing meaningful values, not just NaNs
    assert not np.any(np.isnan(multi))
예제 #6
0
def test_sample_lm_np_flags(
        aperture_plane_model: primary_beam.PrimaryBeamAperturePlane) -> None:
    """Check that flags on l and m arrays are not modified."""
    l = np.array([0.01, 0.02])
    m = np.array([0.03, 0.04])
    aperture_plane_model.sample(l, m, 1500 * u.MHz, primary_beam.AltAzFrame(),
                                primary_beam.OutputType.JONES_HV)
    assert l.flags.writeable
    assert m.flags.writeable
예제 #7
0
def test_sample_frequency_array(
        aperture_plane_model: primary_beam.PrimaryBeamAperturePlane) -> None:
    l = np.array([0.01])
    m = np.array([0.02])
    frequency = np.array([[1000, 1200], [1100, 1500]]) * u.MHz

    # Evaluate one frequency at a time
    expected = np.zeros(frequency.shape + (1, 2, 2), np.complex64)
    # Astropy units don't work with np.ndenumerate, hence npindex instead
    for idx in np.ndindex(frequency.shape):
        expected[idx] = aperture_plane_model.sample(
            l, m, frequency[idx], primary_beam.AltAzFrame(),
            primary_beam.OutputType.JONES_HV)
    # Evaluate them all together
    actual = aperture_plane_model.sample(l, m, frequency,
                                         primary_beam.AltAzFrame(),
                                         primary_beam.OutputType.JONES_HV)

    np.testing.assert_array_equal(actual, expected)
예제 #8
0
def test_sample_bad_out(
        aperture_plane_model: primary_beam.PrimaryBeamAperturePlane,
        out: np.ndarray, expectation) -> None:
    model = aperture_plane_model
    l = np.array([0.01])
    m = np.array([0.02])
    frequency = np.array([[1000, 1200], [1100, 1500]]) * u.MHz
    with expectation:
        model.sample(l,
                     m,
                     frequency,
                     primary_beam.AltAzFrame(),
                     primary_beam.OutputType.JONES_HV,
                     out=out)
예제 #9
0
def test_sample_interp_scalar_freq(
        aperture_plane_model: primary_beam.PrimaryBeamAperturePlane) -> None:
    model = aperture_plane_model
    l = [0.0, 0.05, -0.02]
    m = [0.0, 0.03, 0.04]
    frequency_idx = 50
    frequency = np.mean(model.frequency[frequency_idx:frequency_idx + 2])

    actual = aperture_plane_model.sample(l, m, frequency,
                                         primary_beam.AltAzFrame(),
                                         primary_beam.OutputType.JONES_HV)

    samples = np.mean(model.samples[frequency_idx:frequency_idx + 2], axis=0)
    expected = _compute_expected(model, samples, l, m, frequency)

    # atol is more appropriate than rtol since there is cancellation of small terms
    np.testing.assert_allclose(actual, expected, rtol=0, atol=1e-6)
    # Check that we get identity matrix at the origin
    np.testing.assert_allclose(actual[0], np.eye(2), rtol=0, atol=1e-6)
예제 #10
0
def test_sample_partially_out_of_range(
        aperture_plane_model: primary_beam.PrimaryBeamAperturePlane) -> None:
    model = aperture_plane_model
    l = [0.1, -0.19, 0.21]  # 0.2 is (roughly) the limit at 1.5 GHz
    m = [0.0]
    frequency = [1000, 1500, 1630, 2000] * u.MHz
    actual = model.sample(l, m, frequency, primary_beam.AltAzFrame(),
                          primary_beam.OutputType.JONES_HV)

    expected_nan = np.array([
        [False, False, False],
        [False, False, True],
        [False, True, True],
        [True, True, True]  # frequency is out of range
    ])

    for i in range(2):
        for j in range(2):
            np.testing.assert_array_equal(np.isnan(actual[..., i, j]),
                                          expected_nan)
예제 #11
0
from astropy.coordinates import EarthLocation, AltAz, SkyCoord, CartesianRepresentation
from astropy.time import Time
import numpy as np
try:
    from numpy.typing import ArrayLike
except ImportError:
    ArrayLike = Any  # type: ignore
import h5py
import pytest

from katsdpmodels import models, primary_beam
import katsdpmodels.fetch.requests as fetch_requests

FRAME_OUTPUT_TYPE_COMBOS = [
    (frame, output_type) for frame in [
        primary_beam.AltAzFrame(),
        primary_beam.RADecFrame.from_parallactic_angle(40 * u.deg),
        primary_beam.RADecFrame.from_parallactic_angle([[40], [80]] * u.deg)
    ] for output_type in primary_beam.OutputType
    if (isinstance(frame, primary_beam.RADecFrame) or output_type in {
        primary_beam.OutputType.JONES_HV,
        primary_beam.OutputType.UNPOLARIZED_POWER
    })
]


@pytest.fixture
def aperture_plane_model_file(tmp_path) -> h5py.File:
    """Create an aperture-plane model for testing.

    It writes the model directly rather than using the PrimaryBeam API