Source code for matvis.plot

"""Plotting convenience functions to help in analyzing matvis output."""

import numpy as np

from . import conversions


def _source_az_za_beam(
    lst, crd_eq, beam, ref_freq=100.0e6, latitude=-30.7215 * np.pi / 180.0
):
    """
    Calculate the Az, ZA, and beam values of a set of sources at a given LST.

    Parameters
    ----------
    lst : float
        Local sidereal time, in radians.
    crd_eq : array_like
        Per-source Cartesian coordinate array.
    beam : UVBeam object
        Beam object. Used to calculate the value of the beam ('ee' polarization)
        for each source.
    ref_freq : float, optional
        Reference frequency to evaluate the beam at, in Hz.
    latitude : float, optional
        The latitude of the center of the array, in radians. The default is the
        HERA latitude = -30.7215 * pi / 180.

    Returns
    -------
    az, za : array_like
        Azimuth and zenith angle of each source, in radians.
    A : array_like
        Value of the beam (E-field, not power, unless the beam object contains
        only the power beam) for each source.
    """
    # Get coordinate transforms as a function of LST
    eq2top = conversions.eci_to_enu_matrix(lst, latitude)

    # Get source az, za (note the azimuth convention used by UVBeam)
    tx, ty, tz = np.dot(eq2top, crd_eq)
    az, za = conversions.enu_to_az_za(enu_e=tx, enu_n=ty, orientation="uvbeam")

    # Get beam values
    interp_beam = beam.interp(az, za, np.atleast_1d(ref_freq))[0]
    A_s = interp_beam[0, 1, 0]  # (2, 2, 1, Nptsrc)

    # Horizon cut
    A_s = np.where(tz > 0, A_s, np.nan)

    return az, za, A_s


[docs] def animate_source_map( ra, dec, lsts, beam, interval=200, ref_freq=100.0e6, latitude=-30.7215 * np.pi / 180.0, ): """ Create an animated map of sources as a function of LST, Az, and ZA. The sources are colored by the beam value. Note that the ``IPython`` package is required by this function. NOTE: If you get an error about the ``ffmpeg`` encoder not being installed, you may need to change the path setting in ``matplotlib``: ``plt.rcParams['animation.ffmpeg_path'] = '/path/to/ffmpeg'``. Parameters ---------- ra, dec : array_like RA and Dec coordinates of sources, in radians. lsts : array_like Array of LSTs to plot, in radians. beam : UVBeam object Beam object, used to color the point sources. interval : int, optional Interval between frames, in ms. ref_freq : float, optional Reference frequency to evaluate the beam at, in Hz. latitude : float, optional The latitude of the center of the array, in radians. The default is the HERA latitude = -30.7215 * pi / 180. Returns ------- anim : matplotlib HTML animation Animation object HTML, for display in a Jupyter notebook. """ import pylab as plt from IPython.display import HTML from matplotlib import animation, rc # Point source coordinate transform, from equatorial to Cartesian crd_eq = conversions.point_source_crd_eq(ra, dec) # Calculate source positions for all LSTs y = np.array( [ _source_az_za_beam( lst, crd_eq, beam=beam, ref_freq=ref_freq, latitude=latitude ) for lst in lsts ] ) all_az = y[:, 0, :] all_za = y[:, 1, :] * 180.0 / np.pi all_As = y[:, 2, :] # Plot initial positions fig, ax = plt.subplots(subplot_kw={"projection": "polar"}) scatter = ax.scatter(all_az[0], all_za[0], c=all_As[0], s=3.0, cmap="cool") ax.set_xlabel("az") ax.set_ylabel("za") fig.set_size_inches((8.0, 8.0)) def animate(i): # Set scatter plot values/colours scatter.set_offsets(np.column_stack([all_az[i], all_za[i]])) # x,y scatter.set_array(all_As[i]) # colour ax.set_title("LST = %4.4f" % (lsts[i])) return (scatter,) def init(): # Set scatter plot values/colours scatter.set_offsets(np.column_stack([all_az[0], all_za[0]])) # x,y scatter.set_array(all_As[0]) # colour ax.set_title("LST = %4.4f" % (lsts[0])) return (scatter,) # Make animation anim = animation.FuncAnimation( fig, animate, init_func=init, frames=lsts.size, interval=interval, blit=True ) return HTML(anim.to_html5_video())