m-thesis-introduction/simulations/airshower_beacon_simulation/ba_measure_beacon_phase.py

251 lines
8.7 KiB
Python
Raw Normal View History

2022-11-14 20:49:35 +01:00
#!/usr/bin/env python3
# vim: fdm=indent ts=4
"""
Find beacon phases in antenna traces
And save these to a file
"""
2022-11-14 20:49:35 +01:00
import h5py
import matplotlib.pyplot as plt
import numpy as np
2022-11-14 20:49:35 +01:00
import aa_generate_beacon as beacon
import lib
2022-11-14 20:49:35 +01:00
if __name__ == "__main__":
from os import path
import sys
2022-12-05 17:48:58 +01:00
import matplotlib
2022-12-08 14:41:33 +01:00
import os
if os.name == 'posix' and "DISPLAY" not in os.environ:
matplotlib.use('Agg')
2022-11-18 19:31:24 +01:00
2022-11-14 20:49:35 +01:00
f_beacon_band = (49e-3,55e-3) #GHz
2022-11-18 19:31:24 +01:00
allow_frequency_fitting = False
2022-11-14 20:49:35 +01:00
read_frequency_from_file = True
2022-11-25 17:46:02 +01:00
use_AxB_trace = True if len(sys.argv) < 2 else bool(int(sys.argv[1]))
use_beacon_trace = True # only applicable if AxB = False
2022-11-18 19:31:24 +01:00
show_plots = True
2022-11-14 20:49:35 +01:00
fname = "ZH_airshower/mysim.sry"
2022-12-02 19:06:44 +01:00
print("use_AxB_trace:", use_AxB_trace, "use_beacon_trace:",use_beacon_trace)
2022-11-14 20:49:35 +01:00
####
fname_dir = path.dirname(fname)
antennas_fname = path.join(fname_dir, beacon.antennas_fname)
2022-12-05 17:48:58 +01:00
fig_dir = "./figures" # set None to disable saving
2022-11-14 20:49:35 +01:00
if not path.isfile(antennas_fname):
print("Antenna file cannot be found, did you try generating a beacon?")
sys.exit(1)
# read in antennas
with h5py.File(antennas_fname, 'a') as fp:
if 'antennas' not in fp.keys():
print("Antenna file corrupted? no antennas")
sys.exit(1)
group = fp['antennas']
f_beacon = None
if read_frequency_from_file and 'tx' in fp:
tx = fp['tx']
if 'f_beacon' in tx.attrs:
f_beacon = tx.attrs['f_beacon']
else:
print("No frequency found in file.")
sys.exit(2)
f_beacon_estimate_band = 0.01*f_beacon
elif allow_frequency_fitting:
f_beacon_estimate_band = (f_beacon_band[1] - f_beacon_band[0])/2
f_beacon = f_beacon_band[1] - f_beacon_estimate_band
else:
print("Not allowed to fit frequency and no tx group found in file.")
sys.exit(2)
N_antennas = len(group.keys())
# just for funzies
found_data = np.zeros((N_antennas, 3))
# Determine frequency and phase
for i, name in enumerate(group.keys()):
h5ant = group[name]
2022-11-14 20:49:35 +01:00
2022-11-22 10:22:23 +01:00
# use E_AxB only instead of polarisations
if use_AxB_trace:
if 'E_AxB' not in h5ant.keys():
2022-11-22 10:22:23 +01:00
print(f"Antenna does not have 'E_AxB' in {name}")
sys.exit(1)
2022-11-14 20:49:35 +01:00
traces = h5ant['E_AxB']
2022-11-18 19:31:24 +01:00
2022-11-22 10:22:23 +01:00
t_trace = traces[0]
test_traces = [ traces[1] ]
orients = ['E_AxB']
2022-11-18 19:31:24 +01:00
# TODO: refine masking
# use beacon but remove where E_AxB-Beacon != 0
if True:
if not True:
t_mask = np.isclose(h5ant['E_AxB'][1], h5ant['traces'][4], rtol=1e-3, atol=1e-3)
else:
t_mask = np.ones(len(t_trace), dtype=bool)
t_mask[1500:3000] = False # magic numbers from aa_generate_beacon
t_trace = t_trace[t_mask]
for j, t in enumerate(test_traces):
test_traces[j] = t[t_mask]
orients[j] = orients[j] + ' masked'
2022-11-22 10:22:23 +01:00
# use separate polarisations
else:
if 'traces' not in h5ant.keys():
2022-11-22 10:22:23 +01:00
print(f"Antenna file corrupted? no 'traces' in {name}")
sys.exit(1)
traces = h5ant['traces']
2022-11-22 10:22:23 +01:00
t_trace = traces[0]
if use_beacon_trace:
2022-11-22 10:22:23 +01:00
# only take the Beacon trace
test_traces = [traces[4]]
orients = ['B']
else:
test_traces = traces[1:]
orients = ['Ex', 'Ey', 'Ez', 'B']
# modify the length of the traces
if False:
t_trace = t_trace[:len(t_trace)//2]
half_traces = []
for trace in test_traces:
half_traces.append( trace[:len(trace)//2])
test_traces = half_traces
2022-11-22 10:22:23 +01:00
# Do Fourier Transforms
# to find phases and amplitudes
2022-11-18 19:31:24 +01:00
if True:
freqs, phases, amps = lib.find_beacon_in_traces(
test_traces, t_trace,
f_beacon_estimate=f_beacon,
frequency_fit=allow_frequency_fitting,
f_beacon_estimate_band=f_beacon_estimate_band
)
else:
# Testing
freqs = [f_beacon]
t0 = h5ant.attrs['t0']
2022-11-18 19:31:24 +01:00
phases = [ 2*np.pi*t0*f_beacon ]
amps = [ 3e-7 ]
2022-11-14 20:49:35 +01:00
2022-11-18 19:31:24 +01:00
# choose highest amp
idx = 0
2022-11-22 10:22:23 +01:00
if False and len(phases) > 1:
#idx = np.argmax(amplitudes, axis=-1)
raise NotImplementedError
2022-11-14 20:49:35 +01:00
2022-11-18 19:31:24 +01:00
frequency = freqs[idx]
phase = phases[idx]
amplitude = amps[idx]
orientation = orients[idx]
2022-11-14 20:49:35 +01:00
# Correct for phase by t_trace[0]
corr_phase = lib.phase_mod(2*np.pi*f_beacon*t_trace[0])
if False:
# Subtract phase due to not starting at t=0
# This is already done in beacon_find_traces
phase = lib.phase_mod(phase + corr_phase)
2022-11-22 11:40:00 +01:00
# for reporting using plots
found_data[i] = frequency, phase, amplitude
if (show_plots or fig_dir) and (i == 0 or i == 72 or i == 70):
p2t = lambda phase: phase/(2*np.pi*f_beacon)
2022-11-18 19:31:24 +01:00
fig, ax = plt.subplots()
2022-12-02 19:06:44 +01:00
ax.set_title(f"Beacon at antenna {h5ant.attrs['name']}\nF:{frequency:.2e}, P:{phase:.4f}, A:{amplitude:.1e}")
ax.set_xlabel("t [ns]")
ax.set_ylabel("Amplitude")
2022-11-18 19:31:24 +01:00
if True:
# let the trace start at t=0
t_0 = min(t_trace)
extra_phase = corr_phase
else:
t_0 = 0
extra_phase = -1*corr_phase
for j, trace in enumerate(test_traces):
ax.plot(t_trace - t_0, test_traces[j], marker='.', label='trace '+orients[j])
myt = np.linspace(min(t_trace), max(t_trace), 10*len(t_trace)) - t_0
ax.plot(myt, lib.sine_beacon(frequency, myt, amplitude=amplitude, t0=0, phase=phase+extra_phase), ls='dotted', label='simulated beacon')
ax.axvline( p2t(lib.phase_mod(-1*(phase+extra_phase), low=0)), color='r', ls='dashed', label='$t_\\varphi$')
2022-12-02 19:06:44 +01:00
ax.axvline(0,color='grey',alpha=0.5)
ax.axhline(0,color='grey',alpha=0.5)
2022-12-02 19:06:44 +01:00
2022-11-18 19:31:24 +01:00
ax.legend()
2022-11-14 20:49:35 +01:00
2022-12-05 17:48:58 +01:00
if fig_dir:
old_xlims = ax.get_xlim()
ax.set_xlim(min(t_trace)-t_0-10,min(t_trace)-t_0+40)
fig.savefig(path.join(fig_dir, path.basename(__file__) + f".A{h5ant.attrs['name']}.zoomed.pdf"))
ax.set_xlim(*old_xlims)
fig.savefig(path.join(fig_dir, path.basename(__file__) + f".A{h5ant.attrs['name']}.pdf"))
2022-12-05 17:48:58 +01:00
2022-11-22 11:40:00 +01:00
# save to file
h5beacon_info = h5ant.require_group('beacon_info')
2022-11-14 20:49:35 +01:00
2022-11-22 11:40:00 +01:00
# only take n_sig significant digits into account
# for naming in hdf5 file
n_sig = 3
2022-11-22 11:40:00 +01:00
decimal = int(np.floor(np.log10(abs(frequency))))
freq_name = str(np.around(frequency, n_sig-decimal))
# delete previous values
if freq_name in h5beacon_info:
del h5beacon_info[freq_name]
2022-11-22 11:40:00 +01:00
h5beacon_freq_info = h5beacon_info.create_group(freq_name)
2022-11-22 11:40:00 +01:00
h5attrs = h5beacon_freq_info.attrs
2022-11-22 11:40:00 +01:00
h5attrs['freq'] = frequency
h5attrs['phase'] = phase
h5attrs['amplitude'] = amplitude
h5attrs['orientation'] = orientation
2022-11-14 20:49:35 +01:00
2022-11-18 19:31:24 +01:00
print("Beacon Phases, Amplitudes and Frequencies written to", antennas_fname)
2022-11-14 20:49:35 +01:00
# show histogram of found frequencies
2022-12-05 17:48:58 +01:00
if show_plots or fig_dir:
2022-11-14 20:49:35 +01:00
if True or allow_frequency_fitting:
fig, ax = plt.subplots()
ax.set_xlabel("Frequency")
ax.set_ylabel("Counts")
2022-11-18 19:31:24 +01:00
ax.axvline(f_beacon, ls='dashed', color='g')
ax.hist(found_data[:,0], bins='sqrt', density=False)
2022-12-05 17:48:58 +01:00
if fig_dir:
fig.savefig(path.join(fig_dir, path.basename(__file__) + f".hist_freq.pdf"))
2022-11-14 20:49:35 +01:00
if True:
fig, ax = plt.subplots()
ax.set_xlabel("Amplitudes")
ax.set_ylabel("Counts")
2022-11-18 19:31:24 +01:00
ax.hist(found_data[:,2], bins='sqrt', density=False)
2022-12-05 17:48:58 +01:00
if fig_dir:
fig.savefig(path.join(fig_dir, path.basename(__file__) + f".hist_amp.pdf"))
2022-11-14 20:49:35 +01:00
2022-12-05 17:48:58 +01:00
if show_plots:
plt.show()