Beam Interface

The BeamInterface object is designed to provide a unified interface for UVBeam and AnalyticBeam objects to compute beam response values. It can be constructed with either a pyuvdata.UVBeam or AnalyticBeam and the beam response can be calculated using the pyuvdata.BeamInterface.compute_response() method.

Note

Our tutorial uses small data files for examples. The data files are hosted in the the RASG datasets repo, organized by data type and telescope. In the tutorials this data is downloaded and cached using the pooch package via the pyuvdata.datasets.fetch_data function. To run those commands you’ll need to have pooch installed (you can install it yourself or use pip install pyuvdata[tutorial]). Note that pooch will download the file the first time you ask for it and save it in a cache folder, subsequent calls to fetch that data will not re-download it.

Using BeamInterface

The following code shows how to set up two BeamInterface objects, one with an analytic beam and one with a UVBeam. Then each is evalated at the same frequency and directions using the same call to pyuvdata.BeamInterface.compute_response(). The value of the BeamInterface object is that it unifies the interface so the code calling it does not need to know if the beam that is attached to it is an analytic beam or a UVBeam.

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LogNorm

from pyuvdata import ShortDipoleBeam, BeamInterface, UVBeam
from pyuvdata.datasets import fetch_data

filename = fetch_data("mwa_full_EE")

dipole_beam = BeamInterface(ShortDipoleBeam(), beam_type="power")
mwa_beam = BeamInterface(UVBeam.from_file(filename, pixels_per_deg=1), beam_type="power")

# set up zenith angle, azimuth and frequency arrays to evaluate with
az_grid = np.deg2rad(np.arange(0, 360))
za_grid = np.deg2rad(np.arange(0, 91))
az_array, za_array = np.meshgrid(az_grid, za_grid)

az_array = az_array.flatten()
za_array = za_array.flatten()

# The MWA beam we have in our test data is small, it only has 3 frequencies,
# so we will just get the value at one of those frequencies rather than
# trying to interpolate to a new frequency.
freqs = np.array([mwa_beam.beam.freq_array[-1]])

dipole_beam_vals = dipole_beam.compute_response(
    az_array=az_array, za_array=za_array, freq_array=freqs
)

mwa_beam_vals = mwa_beam.compute_response(
    az_array=az_array, za_array=za_array, freq_array=freqs
)
assert dipole_beam_vals.shape == (1, 4, 1, 91 * 360)
assert mwa_beam_vals.shape == (1, 4, 1, 91 * 360)
assert dipole_beam_vals.dtype == np.complex128
assert mwa_beam_vals.dtype == np.complex128