def beam_slices(map_file, fee_map, nside): """Returns pairs of [NS,EW] slices of maps, for each pointing""" t_name, r_name, _, _ = Path(map_file).stem.split("_") pointings = ["0", "2", "4"] maps = [] # load data from map .npz file tile_map = np.load(map_file, allow_pickle=True) fee_m = np.load(fee_map, allow_pickle=True) for p in pointings: tile = tile_map[p] if "XX" in t_name: fee = fee_m[p][0] else: fee = fee_m[p][1] # rotate maps so slices can be taken fee_r = rotate_map(nside, angle=-np.pi / 4, healpix_array=fee) tile_r = rotate_map(nside, angle=-np.pi / 4, healpix_array=tile) # fee_r[PB_0] = np.nan # tile_r[PB_0] = np.nan # slice the tile and fee maps along NS, EW # zenith angle thresh of 70 to determine fit gain factor NS_f, EW_f = healpix_cardinal_slices(nside, fee_r, 70) NS_t, EW_t = map_slices(nside, tile_r, 70) gain_NS = chisq_fit_gain(data=NS_t[0], model=NS_f[0]) gain_EW = chisq_fit_gain(data=EW_t[0], model=EW_f[0]) # slice the tile and fee maps along NS, EW. # the above gain factor is applied to full beam slices NS_fee, EW_fee = healpix_cardinal_slices(nside, fee_r, 85) NS_tile, EW_tile = map_slices(nside, tile_r, 85) # Scale the data so that it best fits the beam slice NS_tile_med = NS_tile[0] - gain_NS[0] EW_tile_med = EW_tile[0] - gain_EW[0] # delta powers del_NS = NS_tile_med - NS_fee[0] del_EW = EW_tile_med - EW_fee[0] # 3rd order poly fits for residuals fit_NS = poly_fit(NS_tile[2], del_NS, NS_tile[0], 3) fit_EW = poly_fit(EW_tile[2], del_EW, EW_tile[0], 3) maps.append([ [NS_tile, NS_fee, NS_tile_med, del_NS, fit_NS], [EW_tile, EW_fee, EW_tile_med, del_EW, fit_EW], ]) return maps
def test_plt_slice(): NS, _ = map_slices(nside, map_data["0"], 90) fig = plt.figure() ax = plt_slice( fig=fig, sub=[1, 1, 1], zen_angle=NS[2], map_slice=NS[0], model_slice=NS[0], delta_pow=NS[0], slice_label="test", pow_fit=NS[0], xlabel=True, ylabel=True, ) assert type(ax).__name__ == "AxesSubplot"
def null_test(nside, za_max, ref_model, map_dir, out_dir): """Plot all null tests for reference beam maps :param nside: Healpix nside :param za_max: Maximum zenith angle :param ref_model: Path to feko reference model, saved by :func:`~embers.tile_maps.ref_fee_healpix.ref_healpix_save` :param map_dir: Path to directory with tile_maps_raw, created by :func:`~embers.tile_maps.tile_maps.project_tile_healpix` :param out_dir: Output directory where null test plots will be saved :returns: - Null test plot saved to out_dir - Reference residuals saved to out_dir """ out_dir.mkdir(parents=True, exist_ok=True) tile_pairs = [ ["S35XX", "rf0XX"], ["S35YY", "rf0YY"], ["S35XX", "rf1XX"], ["S35YY", "rf1YY"], ] good_rf0XX = rotate_map( nside, angle=+(1 * np.pi) / 4.0, healpix_array=np.asarray(good_ref_maps(nside, map_dir, tile_pairs[0])), ) good_rf0YY = rotate_map( nside, angle=+(1 * np.pi) / 4.0, healpix_array=np.asarray(good_ref_maps(nside, map_dir, tile_pairs[1])), ) good_rf1XX = rotate_map( nside, angle=+(1 * np.pi) / 4.0, healpix_array=np.asarray(good_ref_maps(nside, map_dir, tile_pairs[2])), ) good_rf1YY = rotate_map( nside, angle=+(1 * np.pi) / 4.0, healpix_array=np.asarray(good_ref_maps(nside, map_dir, tile_pairs[3])), ) # NS, EW slices of all four reference tiles rf0XX_NS, rf0XX_EW = map_slices(nside, good_rf0XX, za_max) rf0YY_NS, rf0YY_EW = map_slices(nside, good_rf0YY, za_max) rf1XX_NS, rf1XX_EW = map_slices(nside, good_rf1XX, za_max) rf1YY_NS, rf1YY_EW = map_slices(nside, good_rf1YY, za_max) # Null test diff in power b/w rf0 & rf1 ref01_XX_NS = rf0XX_NS[0] - rf1XX_NS[0] ref01_XX_EW = rf0XX_EW[0] - rf1XX_EW[0] ref01_YY_NS = rf0YY_NS[0] - rf1YY_NS[0] ref01_YY_EW = rf0YY_EW[0] - rf1YY_EW[0] # Error propogation in null test error_ref01_XX_NS = np.sqrt((rf0XX_NS[1])**2 + (rf1XX_NS[1])**2) error_ref01_XX_EW = np.sqrt((rf0XX_EW[1])**2 + (rf1XX_EW[1])**2) error_ref01_YY_NS = np.sqrt((rf0YY_NS[1])**2 + (rf1YY_NS[1])**2) error_ref01_YY_EW = np.sqrt((rf0YY_EW[1])**2 + (rf1YY_EW[1])**2) # Load reference FEE model ref_fee_model = np.load(ref_model, allow_pickle=True) beam_XX = ref_fee_model["XX"] beam_YY = ref_fee_model["YY"] # Rotate beam models by pi/4 to match rotation of data rotated_XX = rotate_map(nside, angle=-(1 * np.pi) / 4.0, healpix_array=beam_XX) rotated_YY = rotate_map(nside, angle=-(1 * np.pi) / 4.0, healpix_array=beam_YY) # slice the XX rotated map along NS, EW XX_NS, XX_EW = healpix_cardinal_slices(nside, rotated_XX, za_max) XX_NS_slice, za_NS = XX_NS XX_EW_slice, za_EW = XX_EW # slice the YY rotated map along NS, EW YY_NS, YY_EW = healpix_cardinal_slices(nside, rotated_YY, za_max) YY_NS_slice, za_NS = YY_NS YY_EW_slice, za_EW = YY_EW # Gain offsets for the 8 combinations of data and beam slices gain_ref0_XX_NS = chisq_fit_gain(data=rf0XX_NS[0], model=XX_NS_slice) gain_ref0_XX_EW = chisq_fit_gain(data=rf0XX_EW[0], model=XX_EW_slice) gain_ref1_XX_NS = chisq_fit_gain(data=rf1XX_NS[0], model=XX_NS_slice) gain_ref1_XX_EW = chisq_fit_gain(data=rf1XX_EW[0], model=XX_EW_slice) gain_ref0_YY_NS = chisq_fit_gain(data=rf0YY_NS[0], model=YY_NS_slice) gain_ref0_YY_EW = chisq_fit_gain(data=rf0YY_EW[0], model=YY_EW_slice) gain_ref1_YY_NS = chisq_fit_gain(data=rf1YY_NS[0], model=YY_NS_slice) gain_ref1_YY_EW = chisq_fit_gain(data=rf1YY_EW[0], model=YY_EW_slice) # Scale the data so that it best fits the beam slice rf0XX_NS = rf0XX_NS - gain_ref0_XX_NS rf0XX_EW = rf0XX_EW - gain_ref0_XX_EW rf0YY_NS = rf0YY_NS - gain_ref0_YY_NS rf0YY_EW = rf0YY_EW - gain_ref0_YY_EW rf1XX_NS = rf1XX_NS - gain_ref1_XX_NS rf1XX_EW = rf1XX_EW - gain_ref1_XX_EW rf1YY_NS = rf1YY_NS - gain_ref1_YY_NS rf1YY_EW = rf1YY_EW - gain_ref1_YY_EW # Difference b/w beam model slices. # Always 0 because we have only one model for both rf0, rf1 beam_ref01_XX_NS = XX_NS_slice - XX_NS_slice beam_ref01_XX_EW = XX_EW_slice - XX_EW_slice beam_ref01_YY_NS = YY_NS_slice - YY_NS_slice beam_ref01_YY_EW = YY_EW_slice - YY_EW_slice # delta powers del_pow_ref0_XX_NS = rf0XX_NS[0] - XX_NS_slice del_pow_ref0_XX_EW = rf0XX_EW[0] - XX_EW_slice del_pow_ref1_XX_NS = rf1XX_NS[0] - XX_NS_slice del_pow_ref1_XX_EW = rf1XX_EW[0] - XX_EW_slice del_pow_ref0_YY_NS = rf0YY_NS[0] - YY_NS_slice del_pow_ref0_YY_EW = rf0YY_EW[0] - YY_EW_slice del_pow_ref1_YY_NS = rf1YY_NS[0] - YY_NS_slice del_pow_ref1_YY_EW = rf1YY_EW[0] - YY_EW_slice # 3rd order poly fits for residuals fit_ref0_XX_NS = poly_fit(za_NS, del_pow_ref0_XX_NS, rf0XX_NS[0], 3) fit_ref0_XX_EW = poly_fit(za_EW, del_pow_ref0_XX_EW, rf0XX_EW[0], 3) fit_ref1_XX_NS = poly_fit(za_NS, del_pow_ref1_XX_NS, rf1XX_NS[0], 3) fit_ref1_XX_EW = poly_fit(za_EW, del_pow_ref1_XX_EW, rf1XX_EW[0], 3) fit_ref0_YY_NS = poly_fit(za_NS, del_pow_ref0_YY_NS, rf0YY_NS[0], 3) fit_ref0_YY_EW = poly_fit(za_EW, del_pow_ref0_YY_EW, rf0YY_EW[0], 3) fit_ref1_YY_NS = poly_fit(za_NS, del_pow_ref1_YY_NS, rf1YY_NS[0], 3) fit_ref1_YY_EW = poly_fit(za_EW, del_pow_ref1_YY_EW, rf1YY_EW[0], 3) # Difference of power b/w ref0 & ref1 fits fit_ref01_XX_NS = fit_ref0_XX_NS - fit_ref1_XX_NS fit_ref01_XX_EW = fit_ref0_XX_EW - fit_ref1_XX_EW fit_ref01_YY_NS = fit_ref0_YY_NS - fit_ref1_YY_NS fit_ref01_YY_EW = fit_ref0_YY_EW - fit_ref1_YY_EW ref_res = { "za": za_NS, "rf0_XX_NS": fit_ref0_XX_NS, "rf0_XX_EW": fit_ref0_XX_EW, "rf0_YY_NS": fit_ref0_YY_NS, "rf0_YY_EW": fit_ref0_YY_EW, "rf1_XX_NS": fit_ref1_XX_NS, "rf1_XX_EW": fit_ref1_XX_EW, "rf1_YY_NS": fit_ref1_YY_NS, "rf1_YY_EW": fit_ref1_YY_EW, } # Save reference residuals to numpy file in out_dir # Will be used for errorbars in beam slice plots np.save(f"{out_dir}/ref_res", ref_res) plt.style.use("seaborn") nice_fonts = { "font.family": "sans-serif", "axes.labelsize": 10, "font.size": 10, "legend.fontsize": 6, "xtick.labelsize": 8, "ytick.labelsize": 8, } plt.rcParams.update(nice_fonts) fig1 = plt.figure(figsize=(12, 7)) ax1 = plt_slice( fig=fig1, sub=(3, 4, 1), zen_angle=za_NS, map_slice=rf0XX_NS[0], map_error=rf0XX_NS[1], model_slice=XX_NS_slice, delta_pow=del_pow_ref0_XX_NS, pow_fit=fit_ref0_XX_NS, slice_label="ref0XX NS", model_label="FEE XX NS", title=r"($i$)", ) ax2 = plt_slice( fig=fig1, sub=(3, 4, 2), zen_angle=za_EW, map_slice=rf0XX_EW[0], map_error=rf0XX_EW[1], model_slice=XX_EW_slice, delta_pow=del_pow_ref0_XX_EW, pow_fit=fit_ref0_XX_EW, slice_label="ref0XX EW", model_label="FEE XX EW", ylabel=False, title=r"($ii$)", ) ax3 = plt_slice( fig=fig1, sub=(3, 4, 5), zen_angle=za_NS, map_slice=rf1XX_NS[0], map_error=rf1XX_NS[1], model_slice=XX_NS_slice, delta_pow=del_pow_ref1_XX_NS, pow_fit=fit_ref1_XX_NS, slice_label="ref1XX NS", model_label="FEE XX NS", title=r"($v$)", ) ax4 = plt_slice( fig=fig1, sub=(3, 4, 6), zen_angle=za_EW, map_slice=rf1XX_EW[0], map_error=rf1XX_EW[1], model_slice=XX_EW_slice, delta_pow=del_pow_ref1_XX_EW, pow_fit=fit_ref1_XX_EW, slice_label="ref1XX EW", model_label="FEE XX EW", ylabel=False, title=r"($vi$)", ) ax5 = plt_null_test( fig=fig1, sub=(3, 4, 9), zen_angle=za_NS, del_pow=ref01_XX_NS, del_err=error_ref01_XX_NS, del_beam=beam_ref01_XX_NS, del_fit=fit_ref01_XX_NS, null_label="NS rf0-rf1", beam_label="FEE Null", fit_label="Fit rf0-rf1", title=r"($ix$)", ) ax6 = plt_null_test( fig=fig1, sub=(3, 4, 10), zen_angle=za_EW, del_pow=ref01_XX_EW, del_err=error_ref01_XX_EW, del_beam=beam_ref01_XX_EW, del_fit=fit_ref01_XX_EW, null_label="EW rf0-rf1", beam_label="FEE Null", fit_label="Fit rf0-rf1", ylabel=False, title=r"($x$)", ) ax7 = plt_slice( fig=fig1, sub=(3, 4, 3), zen_angle=za_NS, map_slice=rf0YY_NS[0], map_error=rf0YY_NS[1], model_slice=YY_NS_slice, delta_pow=del_pow_ref0_YY_NS, pow_fit=fit_ref0_YY_NS, slice_label="ref0YY NS", model_label="FEE YY NS", ylabel=False, title=r"($iii$)", ) ax8 = plt_slice( fig=fig1, sub=(3, 4, 4), zen_angle=za_EW, map_slice=rf0YY_EW[0], map_error=rf0YY_EW[1], model_slice=YY_EW_slice, delta_pow=del_pow_ref0_YY_EW, pow_fit=fit_ref0_YY_EW, slice_label="ref0YY EW", model_label="FEE YY EW", ylabel=False, title=r"($iv$)", ) ax9 = plt_slice( fig=fig1, sub=(3, 4, 7), zen_angle=za_NS, map_slice=rf1YY_NS[0], map_error=rf1YY_NS[1], model_slice=YY_NS_slice, delta_pow=del_pow_ref1_YY_NS, pow_fit=fit_ref1_YY_NS, slice_label="ref1YY NS", model_label="FEE YY NS", ylabel=False, title=r"($vii$)", ) ax10 = plt_slice( fig=fig1, sub=(3, 4, 8), zen_angle=za_EW, map_slice=rf1YY_EW[0], map_error=rf1YY_EW[1], model_slice=YY_EW_slice, delta_pow=del_pow_ref1_YY_EW, pow_fit=fit_ref1_YY_EW, slice_label="ref1YY EW", model_label="FEE YY EW", ylabel=False, title=r"($viii$)", ) ax11 = plt_null_test( fig=fig1, sub=(3, 4, 11), zen_angle=za_NS, del_pow=ref01_YY_NS, del_err=error_ref01_YY_NS, del_beam=beam_ref01_YY_NS, del_fit=fit_ref01_YY_NS, null_label="NS rf0-rf1", beam_label="FEE Null", fit_label="Fit rf0-rf1", ylabel=False, title=r"($xi$)", ) ax12 = plt_null_test( fig=fig1, sub=(3, 4, 12), zen_angle=za_EW, del_pow=ref01_YY_EW, del_err=error_ref01_YY_EW, del_beam=beam_ref01_YY_EW, del_fit=fit_ref01_YY_EW, null_label="EW rf0-rf1", beam_label="FEE Null", fit_label="Fit rf0-rf1", ylabel=False, title=r"($xii$)", ) plt.tight_layout() fig1.savefig(f"{out_dir}/null_test.pdf", bbox_inches="tight")
def test_map_slices(): NS, EW = map_slices(nside, map_data["0"], 90) assert round(NS[2][0]) == -89
def beam_slice(nside, tile_map, fee_map, out_dir): """Compare slices of measured beam maps and FEE models. NS & EW slices of measured MWA beam maps are compared to corresponding slices of FEE models. Complete sky maps are plotted to display power gradients across the beam. :param nside: Healpix nside :param tile_map: Clean MWA tile map created by :func:`~embers.tile_maps.tile_maps.mwa_clean_maps` :param fee_map: MWA FEE model created my :func:`~embers.mwa_utils.mwa_fee` :param out_dir: Path to output directory where diagnostic plots will be saved """ t_name, r_name, _, _ = tile_map.stem.split("_") pointings = ["0", "2", "4", "41"] # load data from map .npz file tile_map = np.load(tile_map, allow_pickle=True) fee_m = np.load(fee_map, allow_pickle=True) # MWA beam pointings pointings = ["0", "2", "4", "41"] for p in pointings: Path(f"{out_dir}/{p}/").mkdir(parents=True, exist_ok=True) try: tile = tile_map[p] if "XX" in t_name: fee = fee_m[p][0] else: fee = fee_m[p][1] # rotate maps so slices can be taken fee_r = rotate_map(nside, angle=-np.pi / 4, healpix_array=fee) tile_r = rotate_map(nside, angle=-np.pi / 4, healpix_array=tile) # slice the tile and fee maps along NS, EW # zenith angle thresh of 70 to determine fit gain factor NS_f, EW_f = healpix_cardinal_slices(nside, fee_r, 70) NS_t, EW_t = map_slices(nside, tile_r, 70) gain_NS = chisq_fit_gain(data=NS_t[0], model=NS_f[0]) gain_EW = chisq_fit_gain(data=EW_t[0], model=EW_f[0]) # slice the tile and fee maps along NS, EW. # the above gain factor is applied to full beam slices NS_fee, EW_fee = healpix_cardinal_slices(nside, fee_r, 90) NS_tile, EW_tile = map_slices(nside, tile_r, 90) # Scale the data so that it best fits the beam slice NS_tile_med = NS_tile[0] - gain_NS[0] EW_tile_med = EW_tile[0] - gain_EW[0] # delta powers del_NS = NS_tile_med - NS_fee[0] del_EW = EW_tile_med - EW_fee[0] # 3rd order poly fits for residuals fit_NS = poly_fit(NS_tile[2], del_NS, NS_tile[0], 3) fit_EW = poly_fit(EW_tile[2], del_EW, EW_tile[0], 3) # Visualize the tile map and diff map # healpix meadian map tile_med = np.asarray([(np.nanmedian(j) if j != [] else np.nan) for j in tile]) residuals = tile_med - fee residuals[np.where(fee < -30)] = np.nan residuals[np.where(tile_med == np.nan)] = np.nan # This is an Awesome plot plt.style.use("seaborn") fig1 = plt.figure(figsize=(10, 8)) ax = plt.gca() ax.set_axis_off() plt.gca() plt_slice( fig=fig1, sub=(2, 2, 1), zen_angle=NS_tile[2], map_slice=NS_tile_med, map_error=NS_tile[1], model_slice=NS_fee[0], delta_pow=del_NS, pow_fit=fit_NS, slice_label="Tile NS", model_label="FEE NS", xlim=[-90, 90], ylim=[-54, 4], ) fig1.add_axes([0.48, 0.52, 0.48, 0.43]) plot_healpix( data_map=tile_med, sub=(2, 2, 2), fig=fig1, title="tile map", cmap=jade, vmin=-50, vmax=0, cbar=False, ) ax1 = plt.gca() image = ax1.get_images()[0] cax = fig1.add_axes([0.92, 0.52, 0.015, 0.43]) fig1.colorbar(image, cax=cax, label="dB") plt.gca() plt_slice( fig=fig1, sub=(2, 2, 3), zen_angle=EW_tile[2], map_slice=EW_tile_med, map_error=EW_tile[1], model_slice=EW_fee[0], delta_pow=del_EW, pow_fit=fit_EW, slice_label="Tile EW", model_label="FEE EW", xlabel=True, xlim=[-90, 90], ylim=[-54, 4], ) fig1.add_axes([0.48, 0.02, 0.48, 0.43]) plot_healpix( data_map=residuals, sub=(2, 2, 4), fig=fig1, title="diff map", cmap="RdYlGn", vmin=-10, vmax=5, cbar=False, ) ax2 = plt.gca() image = ax2.get_images()[0] cax = fig1.add_axes([0.92, 0.02, 0.015, 0.43]) fig1.colorbar(image, cax=cax, label="dB") plt.tight_layout() plt.savefig(f"{out_dir}/{p}/{t_name}_{r_name}_{p}_beam_slices.png") plt.close() except Exception as e: print(e)