From 8ac7306f23c1f74e299d9419b7030b5621a813ac Mon Sep 17 00:00:00 2001 From: Eric Teunis de Boone Date: Thu, 6 Oct 2022 09:20:14 +0200 Subject: [PATCH] figure beacon_field: three antenna setup + zoom on tx + variable vmax --- figures/beacon/Makefile | 35 +++++++++ figures/beacon/src/beacon_field.py | 109 ++++++++++++++++++++++------- 2 files changed, 120 insertions(+), 24 deletions(-) diff --git a/figures/beacon/Makefile b/figures/beacon/Makefile index 7401f75..7bf6c17 100644 --- a/figures/beacon/Makefile +++ b/figures/beacon/Makefile @@ -4,6 +4,7 @@ all: dist dist: \ single_beacon \ field_single \ + field_three \ field_square \ antenna_setup \ # @@ -15,6 +16,10 @@ dist-clean: rm -v field_single_left_phase.* rm -v field_single_center_time.* rm -v field_single_center_phase.* + rm -v field_three_left_time.* + rm -v field_three_left_phase.* + rm -v field_three_center_time.* + rm -v field_three_center_phase.* rm -v field_square_all_time.* rm -v field_square_all_phase.* rm -v field_square_ref0_time.* @@ -51,12 +56,33 @@ field_single_center_time.%: src/beacon_field.py field_single_center_phase.%: src/beacon_field.py $< --phase $@ single-center +field_three: \ + field_three_left_time.pdf field_three_left_time.png \ + field_three_left_phase.pdf field_three_left_phase.png \ + field_three_center_time.pdf field_three_center_time.png \ + field_three_center_phase.pdf field_three_center_phase.png \ + # + +field_three_left_time.%: src/beacon_field.py + $< --time $@ three-left +field_three_left_phase.%: src/beacon_field.py + $< --phase $@ three-left + +field_three_center_time.%: src/beacon_field.py + $< --time $@ three-center +field_three_center_phase.%: src/beacon_field.py + $< --phase $@ three-center + field_square: \ field_square_all_time.pdf field_square_all_time.png \ field_square_all_phase.pdf field_square_all_phase.png \ field_square_ref0_time.pdf field_square_ref0_time.png \ field_square_ref0_phase.pdf field_square_ref0_phase.png \ + field_square_all_time_zoomtx.pdf field_square_all_time_zoomtx.png \ + field_square_all_phase_zoomtx.pdf field_square_all_phase_zoomtx.png \ + field_square_ref0_time_zoomtx.pdf field_square_ref0_time_zoomtx.png \ + field_square_ref0_phase_zoomtx.pdf field_square_ref0_phase_zoomtx.png \ # field_square_ref0_time.%: src/beacon_field.py @@ -68,6 +94,15 @@ field_square_all_time.%: src/beacon_field.py field_square_all_phase.%: src/beacon_field.py $< --phase $@ square +field_square_ref0_time_zoomtx.%: src/beacon_field.py + $< --time $@ square --ref 0 --zoom tx +field_square_ref0_phase_zoomtx.%: src/beacon_field.py + $< --phase $@ square --ref 0 --zoom tx +field_square_all_time_zoomtx.%: src/beacon_field.py + $< --time $@ square --zoom tx +field_square_all_phase_zoomtx.%: src/beacon_field.py + $< --phase $@ square --zoom tx + antenna_setup: \ antenna_setup_four.pdf antenna_setup_four.png \ antenna_setup_three.pdf antenna_setup_three.png \ diff --git a/figures/beacon/src/beacon_field.py b/figures/beacon/src/beacon_field.py index 1970f22..79ce15e 100755 --- a/figures/beacon/src/beacon_field.py +++ b/figures/beacon/src/beacon_field.py @@ -49,19 +49,24 @@ def phase(a,b,f=f_beacon,wrap=False): return phase -def grid_plot(grid, ax=None, **plot_kwargs): +def grid_plot(grid, text_dx=(0,0), ax=None, plot_kwargs={}, annot_kwargs={}): if ax is None: ax = plt.gca() if not grid: return + default_plot_kwargs=dict(color='k', marker='x', markersize=10, linestyle='None') + plot_kwargs = {**default_plot_kwargs, **plot_kwargs} + x = [a.x for a in grid] y = [a.y for a in grid] l = [a.name for a in grid] - ax.plot(x,y,'kx', **plot_kwargs) - for x_,y_,l_ in zip(x,y,l): - ax.annotate(l_,(x_,y_)) + ax.plot(x, y, **plot_kwargs) + + if annot_kwargs is not None: + for x_,y_,l_ in zip(x,y,l): + ax.annotate(l_,(x_,y_), xytext=(x_+text_dx[0], y_+text_dx[0]), **annot_kwargs) def antenna_combinations(ants, ref_ant=None): if ref_ant is not None: # use only one reference antenna for the baselines @@ -111,10 +116,13 @@ def plot_field( ref_ant=None, plot_phase=None, mask=None, color_label='$\\left( t - \\tau \\right)^2$', ax=None, bin_type='square', colorbar=True, + grid_kwargs={}, **scatter_kwargs ): if ax is None: ax = plt.gca() + ax.set_xlabel('x') + ax.set_ylabel('y') default_scatter_kwargs = {} default_scatter_kwargs['cmap'] = 'Spectral_r' @@ -131,12 +139,48 @@ def plot_field( scatter_kwargs = {**default_scatter_kwargs, **scatter_kwargs} if tx or ants: - grid_plot([tx] + ants, ax=ax) + grid_plot_kwargs = dict(marker='X', color='w', alpha=0.8, markeredgecolor='k', markeredgewidth=1) + grid_text_kwargs = dict( + fontsize='large', + color='k', + bbox=dict(boxstyle='Round', alpha=0.5, facecolor='w') + ) - if ref_ant is not None: - ax.set_title("Single baseline\n reference antenna={}, f={}MHz".format(ref_ant.name, f_beacon/1e6)) + if 'plot_kwargs' in grid_kwargs: + grid_plot_kwargs = {**grid_plot_kwargs, **grid_kwargs['plot_kwargs']} + if 'text_kwargs' in grid_kwargs: + grid_text_kwargs = {**grid_text_kwargs, **grid_kwargs['text_kwargs']} + + if tx: + grid_plot([tx], text_dx=(20, 0), ax=ax, plot_kwargs=grid_plot_kwargs, annot_kwargs=grid_text_kwargs) + + if len(ants) > 3: + grid_text_kwargs = None + + grid_plot(ants, text_dx=(20, 0), ax=ax, plot_kwargs=grid_plot_kwargs, annot_kwargs=grid_text_kwargs) + + title = '' + if len(ants) == 1: + title += "Single Antenna\n" + elif len(ants) == 2: + title += "Single Baseline\n" else: - ax.set_title("All baselines\n f={} MHz".format(f_beacon/1e6)) + if len(ants) == 3: + title += "Three Baseline" + else: + if ref_ant is not None: + title += "MultiBaseline" + else: + title += "All Baselines" + + if ref_ant is not None: + title += " with Reference antenna={}".format(ref_ant.name) + + title += "\n" + + title += "f=${}$MHz".format(f_beacon/1e6) + + ax.set_title(title) if bin_type == 'hex': # hexbin sc = ax.hexbin(xx, yy, C=val, **scatter_kwargs) @@ -175,27 +219,28 @@ if __name__ == "__main__": parser = ArgumentParser(description=__doc__) parser.add_argument("fname", metavar="path/to/figure[/]", nargs="?", help="Location for generated figure, will append __file__ if a directory. If not supplied, figure is shown.") - - - parser.add_argument("type", choices=['single-left', 'single-center', 'square', 'tri', 'preset']) - + parser.add_argument("type", choices=['single-left', 'single-center','three-left', 'three-center', 'square', 'tri', 'preset']) command_group = parser.add_mutually_exclusive_group(required=True) command_group.add_argument('--time', help='Use the time difference for the field', action='store_false') command_group.add_argument('--phase', help='Use wrapped phase for the field', action='store_true') parser.add_argument('--ref', dest='ref_ant', metavar='ref_antenna', type=int, help='Number of antenna to use as reference') + parser.add_argument('--max-rms', dest='max_rms', metavar='max_rms', type=float, help='Maximum rms to show in colorbar', default=True) + parser.add_argument('--zoom', choices=['none', 'tx'], help='Zoom to object', default='none') args = parser.parse_args() if args.fname is not None and path.isdir(args.fname): - args.fname = path.join(args.fname, path.splitext(path.basename(__file__))[0] + ".pdf") + args.fname = path.join(args.fname, path.splitext(path.basename(__file__))[0]) # leave off extension + + if not path.splitext(args.fname)[1]: + args.fname = [ args.fname+ext for ext in ['.pdf', '.png'] ] args.plot_phase = args.phase or args.time del args.time, args.phase - - if 'single' in args.type: # single baseline + if 'single' in args.type or 'three' in args.type: # single baseline ### Field x_low, x_high, N_x = -300, 300, 151 y_low, y_high, N_y = -300, 300, 151 @@ -206,7 +251,10 @@ if __name__ == "__main__": Antenna(x=50,y=0,z=0,name="b"), ] - if args.type == 'single-center': + if 'three' in args.type: + ants.append(Antenna(x=0, y=-50,z=0, name='c')) + + if 'center' in args.type: tx = Antenna(x=-000,y=200,z=0,name="tx") else: tx = Antenna(x=-200,y=200,z=0,name="tx") @@ -218,7 +266,7 @@ if __name__ == "__main__": ### Geometry tx = Antenna(x=-800,y=300,z=0,name="tx") - x_start, dx, ant_N_x = 0, 50, 2 + x_start, dx, ant_N_x = 0, 50, 3 y_start, dy, ant_N_y = 0, dx, ant_N_x if args.type == 'square': # square grid @@ -244,11 +292,18 @@ if __name__ == "__main__": Antenna(x=125,y=180,z=0,name="d"), ] + if args.zoom != 'none': # tx zoom + if args.zoom == 'tx': + x_low, x_high, N_x = tx.x - 40, tx.x + 40, 81 + y_low, y_high, N_y = -x_low, x_high, N_x + else: + raise NotImplementedError# args.zoom + ### ### Options ### plot_phase = args.plot_phase - if args.ref_ant: + if args.ref_ant is not None: ref_ant = ants[args.ref_ant] else: ref_ant = None @@ -265,21 +320,23 @@ if __name__ == "__main__": kwargs = {} mask = None if plot_phase: - color_label='$\\sqrt{ \\sum \\left(\\varphi(x) - \\Delta \\varphi\\right)^2}$' + color_label='$\\sqrt{ \\sum_{(i,j)} \\left(\\Delta\\varphi_{ij}(x) - \\Delta \\varphi_{ij}\\right)^2}$' mask = abs(val) > np.pi else: - color_label='$\\sqrt{ \\sum \\left(t(x) - \\Delta t\\right)^2}$ [ns]' + color_label='$\\sqrt{ \\sum_{(i,j)} \\left(\Delta t_{ij}(x) - \\Delta t_{ij}\\right)^2}$ [ns]' val *= 1e9 - kwargs['vmax'] = 100 + if args.max_rms: + kwargs['vmax'] = 100 if args.max_rms is True else args.max_rms + if not True: mask = abs(val) > 1.1*kwargs['vmax'] if mask is not None: - ax = plot_field([], [], xx, yy, val, cmap='Greys', colorbar=False) + ax = plot_field([], [], xx, yy, val, cmap='Greys', colorbar=False, alpha=0.5) ax = plot_field(tx, ants, xx, yy, val, ref_ant=ref_ant, mask=mask, color_label=color_label, **kwargs) - + # if plot_phase: # N_lowest = np.min(len(ant_combi)-1, 10) # lowest_idx = np.argpartition(val, N_lowest)[:N_lowest] @@ -289,6 +346,10 @@ if __name__ == "__main__": # print( list(zip(np.array(xx)[lowest_idx], np.array(yy)[lowest_idx])) ) if args.fname is not None: - plt.savefig(args.fname) + if isinstance(args.fname, str): + args.fname = [args.fname] + + for fname in args.fname: + plt.savefig(fname) else: plt.show()