diff --git a/simulations/lib/__init__.py b/simulations/lib/__init__.py index 3e40392..f255874 100644 --- a/simulations/lib/__init__.py +++ b/simulations/lib/__init__.py @@ -1,6 +1,6 @@ -from . import signal +from . import signals from . import location from .util import * -TravelSignal = signal.TravelSignal +TravelSignal = signals.DigitisedSignal diff --git a/simulations/lib/signal/__init__.py b/simulations/lib/signal/__init__.py deleted file mode 100644 index 62d8dd0..0000000 --- a/simulations/lib/signal/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .travelsignal import * diff --git a/simulations/lib/signals/__init__.py b/simulations/lib/signals/__init__.py new file mode 100644 index 0000000..3cfa872 --- /dev/null +++ b/simulations/lib/signals/__init__.py @@ -0,0 +1,2 @@ +from .signal import * +from .digitisedsignal import * diff --git a/simulations/lib/signal/travelsignal.py b/simulations/lib/signals/digitisedsignal.py similarity index 70% rename from simulations/lib/signal/travelsignal.py rename to simulations/lib/signals/digitisedsignal.py index cba4e54..5d2a09c 100755 --- a/simulations/lib/signal/travelsignal.py +++ b/simulations/lib/signals/digitisedsignal.py @@ -1,17 +1,13 @@ #!/usr/bin/env python3 -""" -Define the TravelSignal class. -""" - import numpy as np import scipy.interpolate as interp try: - from _signal import * + from .signal import * except ImportError: - from ._signal import * + from signal import * -class TravelSignal: +class DigitisedSignal(Signal): """ Model an arbitrary digitised signal that can be translated to another position and time. """ @@ -40,6 +36,7 @@ class TravelSignal: velocity : float, optional Defaults to the speed of light in m/s. """ + super().__init__(t_0=t_0, x_0=x_0, velocity=velocity) self.raw = np.asarray(signal) self.periodic = periodic @@ -48,11 +45,6 @@ class TravelSignal: self.sample_length = len(self.raw) self.time_length = self.sample_length*sample_rate # s - self.velocity = 299792458 if velocity is None else velocity # m / s - - self.x_0 = x_0 # m - self.t_0 = t_0 # s - # choose interpolation method if not interp1d_kw: self.interp_f = None @@ -83,12 +75,6 @@ class TravelSignal: def __len__(self): return self.sample_length - def __call__(self, t_f = None, x_f = None, **kwargs): - """ - Allow this class to be used as a function. - """ - return self._translate(t_f, x_f, **kwargs)[0] - def _translate(self, t_f = None, x_f = None, t_0 = None, x_0 = None, velocity = None): """ Translate the signal from (t_0, x_0) to (t_f, x_f) with optional velocity. @@ -149,53 +135,6 @@ class TravelSignal: return amplitude, total_time_offset - def spatial_time(self, x_f, velocity=None, x_0=None): - """ - Calculate the time offset caused by a spatial difference. - """ - if velocity is None: - velocity = self.velocity - - if x_0 is None: - x_0 = self.x_0 - - return np.sum(np.sqrt( (x_f - x_0)**2 )/velocity) - - def total_time_offset(self, t_f = None, x_f = None, t_0 = None, x_0 = None, velocity = None): - """ - Calculate how much time shifting is needed to go from (t_0, x_0) to (t_f, x_f). - - Convention: - (t_0, x_0) < (t_f, x_0) gives a positive time shift, - (t_0, x_0) != (t_0, x_f) gives a negative time shift - - Returns: - the time shift - """ - - ## spatial offset - if x_f is None: - spatial_time_offset = 0 - else: - x_f = np.asarray(x_f) - if x_0 is None: - x_0 = self.x_0 - - spatial_time_offset = self.spatial_time(x_f, x_0=x_0, velocity=velocity) - - ## temporal offset - if t_f is None: - temporal_time_offset = 0 - else: - t_f = np.asarray(t_f) - - if t_0 is None: - t_0 = self.t_0 - - temporal_time_offset = t_f - t_0 - - return temporal_time_offset - spatial_time_offset - if __name__ == "__main__": import matplotlib.pyplot as plt from scipy.stats import norm @@ -210,17 +149,17 @@ if __name__ == "__main__": signal = norm.pdf(time, time[len(time)//2], (time[-1] - time[0])/10) - mysignal = TravelSignal(signal, sample_rate, t_0 = t_offset, periodic=True) - mysignal2 = TravelSignal(signal, sample_rate, t_0 = t_offset, periodic=False) + mysignal = DigitisedSignal(signal, sample_rate, t_0 = t_offset, periodic=True) + mysignal2 = DigitisedSignal(signal, sample_rate, t_0 = t_offset, periodic=False) fig, ax = plt.subplots(1, 1, figsize=(16,4)) - ax.set_title("Raw and TravelSignal") + ax.set_title("Raw and DigitisedSignal") ax.set_ylabel("Amplitude") ax.set_xlabel("Time") ax.plot(time, signal, label='Raw signal') - ax.plot(time2, mysignal(time2) +0.5, '.-', label='TravelSignal(periodic)+0.5') - ax.plot(time2, mysignal2(time2)-0.5, '.-', label='TravelSignal-0.5') + ax.plot(time2, mysignal(time2) +0.5, '.-', label='DigitisedSignal(periodic)+0.5') + ax.plot(time2, mysignal2(time2)-0.5, '.-', label='DigitisedSignal-0.5') ax.legend() diff --git a/simulations/lib/signals/signal.py b/simulations/lib/signals/signal.py new file mode 100644 index 0000000..4b3935d --- /dev/null +++ b/simulations/lib/signals/signal.py @@ -0,0 +1,91 @@ +""" +Define the super Signal class +""" + +import numpy as np + +class Signal(): + """ + An arbitrary signal that can be translated to another position and time. + Note that position can be of any length. + + Super object, cannot be used directly. + """ + def __init__(self, t_0 = 0, x_0 = 0, velocity=None): + """ + Parameters + ---------- + t_0 : float, optional + Time that this signal is sent out. + x_0 : float, optional + Location that this signal is sent out from. + velocity : float, optional + Defaults to the speed of light in m/s. + """ + + self.velocity = 299792458 if velocity is None else velocity # m / s + + self.x_0 = x_0 # m + self.t_0 = t_0 # s + + def __call__(self, t_f = None, x_f = None, **kwargs): + """ + Allow this class to be used as a function. + """ + return self._translate(t_f, x_f, **kwargs)[0] + + def _translate(self, t_f = None, x_f = None, t_0 = None, x_0 = None, velocity = None): + """ + Translate the signal from (t_0, x_0) to (t_f, x_f) with optional velocity. + + Returns the signal at (t_f, x_f) + """ + + raise NotImplementedError + + def spatial_time(self, x_f, velocity=None, x_0=None): + """ + Calculate the time offset caused by a spatial difference. + """ + if velocity is None: + velocity = self.velocity + + if x_0 is None: + x_0 = self.x_0 + + return np.sum(np.sqrt( (x_f - x_0)**2 )/velocity) + + def total_time_offset(self, t_f = None, x_f = None, t_0 = None, x_0 = None, velocity = None): + """ + Calculate how much time shifting is needed to go from (t_0, x_0) to (t_f, x_f). + + Convention: + (t_0, x_0) < (t_f, x_0) gives a positive time shift, + (t_0, x_0) != (t_0, x_f) gives a negative time shift + + Returns: + the time shift + """ + + ## spatial offset + if x_f is None: + spatial_time_offset = 0 + else: + x_f = np.asarray(x_f) + if x_0 is None: + x_0 = self.x_0 + + spatial_time_offset = self.spatial_time(x_f, x_0=x_0, velocity=velocity) + + ## temporal offset + if t_f is None: + temporal_time_offset = 0 + else: + t_f = np.asarray(t_f) + + if t_0 is None: + t_0 = self.t_0 + + temporal_time_offset = t_f - t_0 + + return temporal_time_offset - spatial_time_offset