#!/usr/bin/env python3 """ Test the functions in lib concerning beacon generation and removing the geometrical phase work correctly together. """ import matplotlib.pyplot as plt import numpy as np from earsim import Antenna import lib seed = 12345 dt = 1 # ns frequency = 52.12345e-3 # GHz N = 5e2 t_clock = 0 beacon_amplitude = 1 c_light = lib.c_light t = np.arange(0, 10*int(1e3), dt, dtype=float) rng = np.random.default_rng(seed) tx = Antenna(x=0,y=0,z=0,name='tx') rx = Antenna(x=tx.x,y=tx.y,z=tx.z,name='rx') # Vary both the base time and the phase t_extra = 0 phase_res = np.zeros(int(N)) amp_res = np.zeros(int(N)) for i in range(int(N)): # Change timebase t -= t_extra t_extra = (2*rng.uniform(size=1) - 1) *1e3 t += t_extra # Randomise Antenna Location if True: rx.x, rx.y, rx.z = (2*rng.uniform(size=3) -1) * 1e4 # Randomly phased beacon # at Antenna phase = lib.phase_mod(np.pi*(2*rng.uniform(size=1) -1)) # rad beacon = beacon_amplitude * lib.beacon_from(tx, rx, frequency, t, t0=0, phase=phase, peak_at_t0=False, c_light=c_light, radiate_rsq=False) if False: # blank part of the beacon blank_low, blank_high = int(0.2*len(t)), int(0.4*len(t)) t_mask = np.ones(len(t), dtype=bool) t_mask[blank_low:blank_high] = False t = t[t_mask] beacon = beacon[t_mask] # Introduce clock errors t += t_clock _, measured_phases, measured_amplitudes = lib.find_beacon_in_traces([beacon], t, frequency, frequency_fit=False) t -= t_clock calculated_phases = lib.remove_antenna_geometry_phase(tx, rx, frequency, measured_phases, c_light=c_light) # Save residuals phase_res[i] = lib.phase_mod(calculated_phases[0] - phase) amp_res[i] = measured_amplitudes[0] - beacon_amplitude ### ## Present figures ### phase2time = lambda x: x/(2*np.pi*frequency) time2phase = lambda x: 2*np.pi*x*frequency fig, ax = plt.subplots() ax.set_title("Measured phase at Antenna - geometrical phase") ax.set_xlabel("$\\varphi_{meas} - \\varphi_{true}$ [rad]") ax.set_ylabel("#") ax.hist(phase_res, bins='sqrt') if True: ax.axvline( -1*lib.phase_mod(t_clock*frequency*2*np.pi), color='red', lw=5, alpha=0.8, label='true t_clock') if True: secax = ax.secondary_xaxis(1.0, functions=(phase2time, time2phase)) secax.set_xlabel('Time [ns]') ax.legend(title='N={:.1e}'.format(len(t))) phase_xlims = ax.get_xlim() fig.tight_layout() amp_xlims = None if True: fig, ax = plt.subplots() ax.set_title("Amplitude") ax.set_xlabel("$A_{meas} - 1$") ax.set_ylabel("#") ax.legend(title='N={:.1e}'.format(len(t))) ax.hist(amp_res, bins='sqrt') fig.tight_layout() amp_xlims = ax.get_xlim() if True: fig, ax = plt.subplots() ax.grid() ax.set_xlabel("Phase Res [rad]") ax.set_ylabel("Amplitude Res") sc = ax.scatter( phase_res, amp_res ) #fig.colorbar(sc, ax=ax) ax.set_xlim(phase_xlims) if amp_xlims is not None: ax.set_ylim(amp_xlims) if True: ax.axvline( -1*lib.phase_mod(t_clock*frequency*2*np.pi), color='red', lw=5, alpha=0.8, label='true t_clock') if True: secax = ax.secondary_xaxis(1.0, functions=(phase2time, time2phase)) secax.set_xlabel('Time [ns]') ax.legend(title='N={:.1e}'.format(len(t))) fig.tight_layout() plt.show()