Source code for PyFHD.plotting.gridding

import numpy as np
from numpy.typing import NDArray
from pathlib import Path
from PyFHD.plotting.image import quick_image
from logging import Logger


[docs] def plot_gridding( obs: dict, image_uv: NDArray[np.complex128], weights_uv: NDArray[np.complex128], variance_uv: NDArray[np.float64], pyfhd_config: dict, model_uv: NDArray[np.complex64] | None, logger: Logger, ) -> None: """ Plot the continuum uv-planes for data, model, and weights. Parameters ---------- obs : dict Observation metadata dictionary image_uv : NDArray[np.complex128] UV-plane of the gridded data weights_uv : NDArray[np.complex128] UV-plane of the gridded weights variance_uv : NDArray[np.float64] UV-plane of the gridded variances model_uv : NDArray[np.complex128], optional UV-plane of the gridded model pyfhd_config : dict Run option dictionary logger : Logger PyFHD's logger for displaying errors and info to the log files """ # Check if image, weights, and variance contain any non-zero elements if ( (not np.any(image_uv != 0)) or (not np.any(weights_uv != 0)) or (not np.any(variance_uv != 0)) ): logger.warning( "Gridded image, weights, or variance are all zeros. Plotting skipped." ) return # Plotting paths for apparent gridded image (weighted gridded data), variance, # and apparent model (weighted gridded model) obs_id = pyfhd_config["obs_id"] grid_plot_dir = Path(pyfhd_config["output_dir"], "plots", "gridding") grid_plot_dir.mkdir(parents=True, exist_ok=True) save_path_roots = [ Path(grid_plot_dir, f"{obs_id}_grid_apparent_image"), Path(grid_plot_dir, f"{obs_id}_grid_variance"), Path(grid_plot_dir, f"{obs_id}_grid_apparent_model"), ] # Calculate the apparent image, setting inds with zero weights to zero apparent_image = np.abs(np.divide(image_uv, weights_uv, where=weights_uv != 0)) # Calculate the apparent model, setting inds with zero weights to zero if model_uv is not None: apparent_model = np.abs(np.divide(model_uv, weights_uv, where=weights_uv != 0)) # Calculate the x- and y-axis values and labels xvals = (np.arange(apparent_image.shape[1]) - apparent_image.shape[1] / 2) * obs[ "kpix" ] xtitle = "u (wavelengths)" yvals = (np.arange(apparent_image.shape[2]) - apparent_image.shape[2] / 2) * obs[ "kpix" ] ytitle = "v (wavelengths)" # Get the pol_names pol_names = obs["pol_names"] for pol_i in range(obs["n_pol"]): # Plot the apparent image, variance, and the optional model for each polarization # Add a suffix to each path save_path_pol = [ path.with_stem(path.stem + "_" + pol_names[pol_i]) for path in save_path_roots ] quick_image( apparent_image[pol_i, :, :], xvals=xvals, yvals=yvals, xtitle=xtitle, ytitle=ytitle, title="Apparent Gridded Continuum Data " + pol_names[pol_i], cb_title="Amplitude (Jy/beam)", savefile=save_path_pol[0], missing_value=0, log=True, png=True, ) quick_image( variance_uv[pol_i, :, :], xvals=xvals, yvals=yvals, xtitle=xtitle, ytitle=ytitle, title="Gridded Continuum Variance " + pol_names[pol_i], cb_title="(Jy/beam)$^2$", savefile=save_path_pol[1], missing_value=0, log=True, png=True, ) if model_uv is not None: quick_image( apparent_model[pol_i, :, :], xvals=xvals, yvals=yvals, xtitle=xtitle, ytitle=ytitle, title="Apparent Gridded Continuum Model " + pol_names[pol_i], cb_title="Amplitude (Jy/beam)", savefile=save_path_pol[2], missing_value=0, log=True, png=True, )