mirror of
https://gitlab.science.ru.nl/mthesis-edeboone/m-thesis-introduction.git
synced 2024-11-13 10:03:32 +01:00
193 lines
5.8 KiB
Python
193 lines
5.8 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
__doc__ = \
|
||
|
"""
|
||
|
For each antenna i calculate the differences with the other antennas j,
|
||
|
Do these sets of differences match upto an initial difference \Delta_{ii'}?
|
||
|
"""
|
||
|
|
||
|
from itertools import chain, combinations, product
|
||
|
import numpy as np
|
||
|
import matplotlib.pyplot as plt
|
||
|
rng = np.random.default_rng()
|
||
|
|
||
|
ns = 1e-9 # s
|
||
|
km = 1e3 # m
|
||
|
c_light = 3e8*ns # m/s
|
||
|
|
||
|
class Antenna:
|
||
|
"""
|
||
|
Simple Antenna class
|
||
|
"""
|
||
|
def __init__(self,x=0,y=0,z=0,t0=0,name=""):
|
||
|
self.x = x
|
||
|
self.y = y
|
||
|
self.z = z
|
||
|
self.t = t0
|
||
|
self.name = name
|
||
|
|
||
|
def __repr__(self):
|
||
|
cls = self.__class__.__name__
|
||
|
|
||
|
return f'{cls}(x={self.x!r},y={self.y!r},z={self.z!r},t0={self.t!r},name={self.name!r})'
|
||
|
|
||
|
def distance(x1, x2):
|
||
|
"""
|
||
|
Calculate the Euclidean distance between two locations x1 and x2
|
||
|
"""
|
||
|
|
||
|
assert type(x1) in [Antenna]
|
||
|
x1 = np.array([x1.x, x1.y, x1.z])
|
||
|
|
||
|
assert type(x2) in [Antenna]
|
||
|
x2 = np.array([x2.x, x2.y, x2.z])
|
||
|
|
||
|
return np.sqrt( np.sum( (x1-x2)**2 ) )
|
||
|
|
||
|
def geometry_time(dist, x2=None, c_light=c_light):
|
||
|
if x2 is not None:
|
||
|
dist = distance(dist, x2)
|
||
|
|
||
|
return dist/c_light
|
||
|
|
||
|
def antenna_triangles(antennas):
|
||
|
return combinations(antennas, 3)
|
||
|
|
||
|
def antenna_baselines(antennas):
|
||
|
return combinations(antennas, 2)
|
||
|
|
||
|
def add_spatial_time_delay(tx, antennas, time=geometry_time, t_scale=1):
|
||
|
""" Modifies antennas inplace """
|
||
|
for ant in antennas:
|
||
|
ant.t += time(tx, ant)/t_scale
|
||
|
|
||
|
def random_antenna(N_ant=1, antenna_ranges=[10e3,10e3,10e3], max_clock_skew=1):
|
||
|
antennas = []
|
||
|
for i in range(N_ant):
|
||
|
loc = antenna_ranges*rng.random(3)
|
||
|
if max_clock_skew is None:
|
||
|
t0 = 0
|
||
|
else:
|
||
|
t0 = rng.normal(0, max_clock_skew)
|
||
|
|
||
|
ant = Antenna(name=i, x=loc[0], y=loc[1], z=loc[1], t0=t0)
|
||
|
antennas.append(ant)
|
||
|
|
||
|
return antennas
|
||
|
|
||
|
def single_baseline_referenced_sigmas(tx, baseline, all_antennas):
|
||
|
N_ant = len(all_antennas)
|
||
|
|
||
|
baseline_ts = np.array([b.t for b in baseline])
|
||
|
baseline_geo = np.array([geometry_time(tx,b) for b in baseline])
|
||
|
|
||
|
not_baseline = lambda ant: ant not in baseline
|
||
|
|
||
|
sigmas = np.empty( (N_ant-2, 2) )
|
||
|
for j, ant in enumerate(filter(not_baseline, all_antennas)):
|
||
|
t_diff = ant.t - baseline_ts
|
||
|
geo_diff = geometry_time(tx, ant) - baseline_geo
|
||
|
sigmas[j] = t_diff - geo_diff
|
||
|
|
||
|
return sigmas
|
||
|
|
||
|
def reference_antenna_sigmas(tx, ref_ant, all_antennas):
|
||
|
N_ant = len(all_antennas)
|
||
|
|
||
|
ref_geo = geometry_time(tx, ref_ant)
|
||
|
|
||
|
sigmas = np.empty( (N_ant) )
|
||
|
for i, ant in enumerate(all_antennas):
|
||
|
if False and ant is ref_ant:
|
||
|
sigmas[i] = 0
|
||
|
|
||
|
t_diff = ant.t - ref_ant.t
|
||
|
geo_diff = geometry_time(tx, ant) - ref_geo
|
||
|
sigmas[i] = t_diff - geo_diff
|
||
|
|
||
|
return sigmas
|
||
|
|
||
|
def all_sigmas_using_reference_antenna(tx, all_antennas):
|
||
|
N_ant = len(all_antennas)
|
||
|
|
||
|
sigmas = np.empty( (N_ant,N_ant) )
|
||
|
for i, ant in enumerate(all_antennas):
|
||
|
sigmas[i] = reference_antenna_sigmas(tx, ant, all_antennas)
|
||
|
|
||
|
return sigmas
|
||
|
|
||
|
def main(tx, antennas, spatial_unit=None, time_unit=None, ref_idx = [0, 1, -2, -1]):
|
||
|
# Use each baseline once as a reference
|
||
|
# and loop over the remaining antennas
|
||
|
N_ant = len(antennas)
|
||
|
fig = None
|
||
|
|
||
|
baseline = [antennas[0], antennas[1]]
|
||
|
#for i, baseline in enumerate(antenna_baselines(antennas)):
|
||
|
if False:
|
||
|
sigmas = single_baseline_referenced_sigmas(tx, baseline, antennas)
|
||
|
print("Baseline {},{}".format(baseline[0].name, baseline[1].name))
|
||
|
print(sigmas)
|
||
|
print(-1*np.diff(sigmas, axis=1))
|
||
|
print("Direct", np.diff([a.t for a in baseline]))
|
||
|
print()
|
||
|
|
||
|
if True:
|
||
|
sigmas = all_sigmas_using_reference_antenna(tx, antennas)
|
||
|
|
||
|
fig, axs = plt.subplots(2,2, sharex=True, sharey=True)
|
||
|
|
||
|
antenna_locs = list(zip(*[(ant.x, ant.y) for ant in antennas]))
|
||
|
for i, ax in enumerate(axs.flat):
|
||
|
ax.set_title("Ref Antenna: {}".format(ref_idx[i]))
|
||
|
ax.set_xlabel('x' if spatial_unit is None else 'x [{}]'.format(spatial_unit))
|
||
|
ax.set_ylabel('y' if spatial_unit is None else 'y [{}]'.format(spatial_unit))
|
||
|
|
||
|
sc = ax.scatter(*antenna_locs, c=sigmas[ref_idx[i]])
|
||
|
fig.colorbar(sc, ax=ax, label='t' if time_unit is None else 't ['+time_unit+']')
|
||
|
ax.plot(antennas[ref_idx[i]].x, antennas[ref_idx[i]].y, 'rx')
|
||
|
|
||
|
|
||
|
return fig, sigmas
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
from argparse import ArgumentParser
|
||
|
from os import path
|
||
|
rng = np.random.default_rng(1)
|
||
|
|
||
|
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('num_ant', help='Number of antennas to use', nargs='?', default=5, type=int)
|
||
|
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
if args.fname == 'none':
|
||
|
args.fname = None
|
||
|
|
||
|
if args.fname is not None:
|
||
|
if path.isdir(args.fname):
|
||
|
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'] ]
|
||
|
|
||
|
######
|
||
|
antenna_ranges = np.array([10*km,10*km,5*km])
|
||
|
antenna_max_clock_skew = 100*ns/ns # 0.1 us
|
||
|
|
||
|
tx = Antenna(name='tx', x=-300*km, y=200*km, z=0)
|
||
|
antennas = random_antenna(args.num_ant, antenna_ranges, antenna_max_clock_skew)
|
||
|
add_spatial_time_delay(tx, antennas)
|
||
|
|
||
|
fig, sigmas = main(tx, antennas, spatial_unit='m', time_unit='ns')
|
||
|
|
||
|
###### Output
|
||
|
if args.fname is not None:
|
||
|
if isinstance(args.fname, str):
|
||
|
args.fname = [args.fname]
|
||
|
|
||
|
for fname in args.fname:
|
||
|
plt.savefig(fname)
|
||
|
else:
|
||
|
plt.show()
|