2022-03-24 12:13:34 +01:00
|
|
|
from functools import partial
|
|
|
|
|
2022-03-24 15:45:40 +01:00
|
|
|
from .location import Location
|
2022-03-24 17:14:47 +01:00
|
|
|
from ..sampling import Digitizer
|
2022-03-24 12:13:34 +01:00
|
|
|
|
|
|
|
class Antenna(Location):
|
|
|
|
"""
|
|
|
|
A location able to interact with a signal.
|
|
|
|
|
|
|
|
Either emitting or receiving.
|
|
|
|
|
2022-03-24 17:14:47 +01:00
|
|
|
Optionally uses digitizer to transform the signal
|
|
|
|
when receiving.
|
2022-03-24 12:13:34 +01:00
|
|
|
"""
|
2022-03-24 17:14:47 +01:00
|
|
|
def __init__(self, x, digitizer=None):
|
|
|
|
super().__init__(x)
|
|
|
|
|
|
|
|
self.digitizer = digitizer
|
|
|
|
|
2022-03-24 12:13:34 +01:00
|
|
|
def __repr__(self):
|
2022-03-24 17:14:47 +01:00
|
|
|
return "Antenna({}, {})".format(repr(self.x), repr(self.x))
|
|
|
|
|
|
|
|
def _digitise_partial(self, signal: callable, *args, digitise=True, **kwargs) -> callable:
|
|
|
|
"""
|
|
|
|
A wrapper around functools.partial to support optionally
|
|
|
|
digitising the returned signal.
|
|
|
|
"""
|
|
|
|
if self.digitizer and digitise:
|
|
|
|
signal = self.digitizer.digitise(signal)
|
2022-03-24 12:13:34 +01:00
|
|
|
|
2022-03-24 17:14:47 +01:00
|
|
|
return partial(signal, *args, **kwargs)
|
2022-03-24 15:48:12 +01:00
|
|
|
|
2022-03-24 17:14:47 +01:00
|
|
|
|
|
|
|
def emit(self, signal: callable, digitise=False) -> callable:
|
|
|
|
"""
|
|
|
|
Return a function that emits a signal from the antenna's location
|
|
|
|
"""
|
|
|
|
return self._digitise_partial(signal, x_0=self.x, digitise=digitise)
|
|
|
|
|
|
|
|
def recv(self, signal: callable, digitise=True) -> callable:
|
2022-03-24 12:13:34 +01:00
|
|
|
"""
|
|
|
|
Return a function that traces the signal as a function of time
|
|
|
|
at the antenna's location
|
|
|
|
"""
|
2022-03-24 17:14:47 +01:00
|
|
|
return self._digitise_partial(signal, x_f=self.x, digitise=digitise)
|
2022-03-24 12:13:34 +01:00
|
|
|
|
|
|
|
receive = recv
|
|
|
|
|
2022-03-24 17:14:47 +01:00
|
|
|
# math
|
|
|
|
def __add__(self, other):
|
|
|
|
if isinstance(other, Location):
|
|
|
|
other = other.x
|
|
|
|
|
|
|
|
return self.__class__(self.x + other, self.digitizer)
|
|
|
|
|
|
|
|
def __sub__(self, other):
|
|
|
|
if isinstance(other, Location):
|
|
|
|
other = other.x
|
|
|
|
|
|
|
|
return self.__class__(self.x - other, self.digitizer)
|
|
|
|
|
|
|
|
def __mul__(self, other):
|
|
|
|
return self.__class__(self.x * other, self.digitizer)
|
|
|
|
|
2022-03-24 12:13:34 +01:00
|
|
|
class Receiver(Antenna):
|
|
|
|
"""
|
|
|
|
An antenna which main purpose is to trace a signal over time.
|
|
|
|
|
|
|
|
Optionally applies a transformation to the traced signal.
|
|
|
|
"""
|
|
|
|
def __repr__(self):
|
|
|
|
return "Receiver({})".format(repr(self.x))
|
|
|
|
|
|
|
|
class Emitter(Antenna):
|
|
|
|
"""
|
|
|
|
An antenna which main purpose is to emit a signal.
|
|
|
|
"""
|
|
|
|
def __repr__(self):
|
|
|
|
return "Emitter({})".format(repr(self.x))
|