Source code for astrohack.visualization.array_cfg_plot

import numpy as np

from astrohack.utils.conversion import convert_unit
from astrohack.utils.constants import fontsize
from astrohack.utils.tools import get_telescope_lat_lon_rad
from astrohack.utils.algorithms import compute_antenna_relative_off
from astrohack.antenna.telescope import get_proper_telescope
from astrohack.visualization.plot_tools import (
    create_figure_and_axes,
    close_figure,
    plot_boxes_limits_and_labels,
)


[docs] def plot_array_configuration(input_dict, xdtree, caller): """ Plot array configuration with an inner and an outer box. Args: input_dict: Dictionary of input parameters xdtree: Xarray xdtree containing the antenna information as attributes. caller: Who is calling this function Returns: None """ telescope_name = xdtree.attrs["telescope_name"] telescope = get_proper_telescope(telescope_name) stations = input_dict["stations"] display = input_dict["display"] figure_size = input_dict["figure_size"] dpi = input_dict["dpi"] destination = input_dict["destination"] filename = f"{destination}/{caller}_array_configuration.png" length_unit = input_dict["unit"] plot_zoff = input_dict["zoff"] len_fac = convert_unit("m", length_unit, "length") tel_lon, tel_lat, tel_rad = get_telescope_lat_lon_rad(telescope) ant_offs = [] ant_texts = [] for ant_xdtree in xdtree.values(): ant_info = ant_xdtree.attrs["antenna_info"] ew_off, ns_off, el_off, _ = compute_antenna_relative_off( ant_info, tel_lon, tel_lat, tel_rad, len_fac ) text = f' {ant_info["name"]}' if stations: text += f'@{ant_info["station"]}' if plot_zoff: text += f" {el_off:.1f} {length_unit}" ant_offs.append([ew_off, ns_off]) ant_texts.append(text) ant_offs = np.array(ant_offs) box_size = define_inner_box_size( input_dict["box_size"], ant_offs, ) fig, axes = create_figure_and_axes(figure_size, [1, 2], default_figsize=[10, 5]) inner_ax = axes[1] outer_ax = axes[0] for i_ant, text in enumerate(ant_texts): ew_off, ns_off = ant_offs[i_ant] plot_one_antenna_position(outer_ax, inner_ax, ew_off, ns_off, text, box_size) # axes labels xlabel = f"East [{length_unit}]" ylabel = f"North [{length_unit}]" plot_boxes_limits_and_labels( outer_ax, inner_ax, xlabel, ylabel, box_size, "Outer array", "Inner array" ) title = f"{len(xdtree.keys())} antennas during observation" close_figure(fig, title, filename, dpi, display) return
[docs] def define_inner_box_size( user_box_size, antenna_offsets, box_max_size=0.2, threshold=4 ): """ Compute the inner array box size based on the distribution of the antennas if user_box_size is None Args: user_box_size: User requested box size antenna_offsets: Antenna offsets from array center box_max_size: Fractional maximum box size relative to the maximum array extent threshold: how big must be the jump between one antenna and the next relative to the previous jump Returns: user_box_size when Not None, else returns the heuristically defined box size """ if user_box_size is None: ew_min, ew_max = np.min(antenna_offsets[:, 0]), np.max(antenna_offsets[:, 0]) max_ew_range = ew_max - ew_min ns_min, ns_max = np.min(antenna_offsets[:, 1]), np.max(antenna_offsets[:, 1]) max_ns_range = ns_max - ns_min distances = np.sqrt(antenna_offsets[:, 0] ** 2 + antenna_offsets[:, 1] ** 2) min_range = np.min((max_ew_range, max_ns_range)) distances = np.sort(distances) dist_jumps = np.diff(distances) max_dist = box_max_size * min_range / 2 for i_ant, jump in enumerate(dist_jumps[1:]): prev_jump = dist_jumps[i_ant] if jump > threshold * prev_jump: max_dist = 1.05 * distances[i_ant] box_size = 2 * max_dist if box_size > box_max_size * min_range: box_size = box_max_size * min_range return box_size else: return user_box_size
[docs] def plot_one_antenna_position( outerax, innerax, xpos, ypos, text, box_size, marker="+", color="black" ): """ Plot an antenna to either the inner or outer array boxes Args: outerax: Plotting axis for the outer array box innerax: Plotting axis for the inner array box xpos: X antenna position (east-west) ypos: Y antenna position (north-south) text: Antenna label box_size: Size of the inner array box marker: Antenna position marker color: Color for the antenna position marker """ half_box = box_size / 2 if abs(xpos) > half_box or abs(ypos) > half_box: outerax.plot(xpos, ypos, marker=marker, color=color) outerax.text(xpos, ypos, text, fontsize=fontsize, ha="left", va="center") else: outerax.plot(xpos, ypos, marker=marker, color=color) innerax.plot(xpos, ypos, marker=marker, color=color) innerax.text(xpos, ypos, text, fontsize=fontsize, ha="left", va="center")