Remove old signal tool
This commit is contained in:
parent
d86b8ecfef
commit
b8d54cdd21
1 changed files with 0 additions and 275 deletions
|
@ -1,275 +0,0 @@
|
||||||
from __future__ import annotations
|
|
||||||
from numpy.typing import ArrayLike, NDArray
|
|
||||||
from backscattering_analyzer.settings import Settings
|
|
||||||
from backscattering_analyzer import interpolate
|
|
||||||
|
|
||||||
from scipy.signal import welch, detrend
|
|
||||||
from scipy.fft import irfft, rfft, rfftfreq
|
|
||||||
from scipy.interpolate import CubicSpline
|
|
||||||
from numpy import logical_and, where, sin, cos, array, sqrt, float64
|
|
||||||
|
|
||||||
|
|
||||||
class Signal:
|
|
||||||
"""
|
|
||||||
A given signal, with its time/frequency coordinates
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
x: NDArray[float64],
|
|
||||||
value: NDArray[float64],
|
|
||||||
settings: Settings,
|
|
||||||
) -> None:
|
|
||||||
if x.shape != value.shape:
|
|
||||||
raise Exception(
|
|
||||||
"x and y does not have the same dimension ({x} and {y})".format(
|
|
||||||
x=x.shape, y=value.shape
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.sampling = x[1] - x[0]
|
|
||||||
self.rate = 1 / self.sampling
|
|
||||||
self.x = x
|
|
||||||
self.frequencies = self.x # alias
|
|
||||||
self.time = self.x # alias
|
|
||||||
self.y = value
|
|
||||||
self.value = self.y # alias
|
|
||||||
self.settings = settings
|
|
||||||
self.length = value.shape[0]
|
|
||||||
|
|
||||||
def psd(self, fft_length: int = 10) -> Signal:
|
|
||||||
"""
|
|
||||||
Compute psd of a given signal
|
|
||||||
"""
|
|
||||||
self.settings.log("computing psd of the signal")
|
|
||||||
|
|
||||||
return Signal(
|
|
||||||
*welch(
|
|
||||||
self.value,
|
|
||||||
self.rate,
|
|
||||||
nperseg=int(fft_length * self.rate),
|
|
||||||
detrend="linear",
|
|
||||||
),
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
def sqrt(self) -> Signal:
|
|
||||||
""" """
|
|
||||||
return Signal(
|
|
||||||
self.x,
|
|
||||||
sqrt(self.y),
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
def detrend(self, type: str = "linear") -> Signal:
|
|
||||||
"""
|
|
||||||
Short alias for scipy.detrend with default value
|
|
||||||
"""
|
|
||||||
return Signal(
|
|
||||||
self.x,
|
|
||||||
detrend(self.y, type=type),
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
def cut_x(self, start: float, end: float) -> Signal:
|
|
||||||
"""
|
|
||||||
Cut signal from a start value to an end value
|
|
||||||
"""
|
|
||||||
indexes = where(logical_and(self.x > start, self.x < end))
|
|
||||||
return Signal(
|
|
||||||
self.x[indexes],
|
|
||||||
self.y[indexes],
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
def low_pass_filter(self, cutoff: float) -> Signal:
|
|
||||||
"""
|
|
||||||
Cut higher frequencies than cutoff for this signal
|
|
||||||
"""
|
|
||||||
self.settings.log("filtering with a low pass filter")
|
|
||||||
|
|
||||||
freq_x = rfftfreq(self.length, self.sampling)
|
|
||||||
freq_y = rfft(self.y)
|
|
||||||
index_to_remove = where(abs(freq_x) > cutoff)
|
|
||||||
freq_y[index_to_remove] = 0
|
|
||||||
y = irfft(freq_y)
|
|
||||||
signal = Signal(
|
|
||||||
self.x[: len(y)],
|
|
||||||
y[: len(self.x)],
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
return signal
|
|
||||||
|
|
||||||
def plot(self) -> None:
|
|
||||||
"""
|
|
||||||
Plot the signal
|
|
||||||
"""
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
|
|
||||||
plt.plot(self.x, self.y)
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def abs(self) -> Signal:
|
|
||||||
"""
|
|
||||||
Abs of the signal (alias)
|
|
||||||
"""
|
|
||||||
return self.__abs__()
|
|
||||||
|
|
||||||
def cos(self) -> Signal:
|
|
||||||
"""
|
|
||||||
Cosinus of the signal (hacky way)
|
|
||||||
"""
|
|
||||||
return Signal(
|
|
||||||
self.x,
|
|
||||||
cos(self.y),
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
def sin(self) -> Signal:
|
|
||||||
"""
|
|
||||||
Sinus of the signal (hacky way)
|
|
||||||
"""
|
|
||||||
return Signal(
|
|
||||||
self.x,
|
|
||||||
sin(self.y),
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
def spline(self) -> CubicSpline:
|
|
||||||
"""
|
|
||||||
Return interpolation of this signal
|
|
||||||
"""
|
|
||||||
return CubicSpline(
|
|
||||||
self.x,
|
|
||||||
self.y,
|
|
||||||
)
|
|
||||||
|
|
||||||
def __sub__(self, other: ArrayLike | Signal) -> Signal:
|
|
||||||
"""
|
|
||||||
Substract float or a signal to another
|
|
||||||
"""
|
|
||||||
if isinstance(other, Signal):
|
|
||||||
if len(other) != len(self):
|
|
||||||
signal_1, signal_2 = interpolate((self, other))
|
|
||||||
else:
|
|
||||||
signal_1, signal_2 = self, other
|
|
||||||
|
|
||||||
return Signal(
|
|
||||||
signal_1.frequencies,
|
|
||||||
signal_2.y - signal_1.y,
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return Signal(
|
|
||||||
self.x,
|
|
||||||
self.y - other,
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
def __add__(self, other: ArrayLike | Signal) -> Signal:
|
|
||||||
"""
|
|
||||||
Add a float or a signal to another
|
|
||||||
"""
|
|
||||||
if isinstance(other, Signal):
|
|
||||||
if len(other) != len(self):
|
|
||||||
signal_1, signal_2 = interpolate((self, other))
|
|
||||||
else:
|
|
||||||
signal_1, signal_2 = self, other
|
|
||||||
|
|
||||||
return Signal(
|
|
||||||
signal_1.x,
|
|
||||||
signal_1.y + signal_2.y,
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return Signal(
|
|
||||||
self.x,
|
|
||||||
self.y + other,
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
def __mul__(self, other: ArrayLike | Signal) -> Signal:
|
|
||||||
"""
|
|
||||||
Multiply a signal by a value or another signal
|
|
||||||
"""
|
|
||||||
if isinstance(other, Signal):
|
|
||||||
if len(other) != len(self):
|
|
||||||
signal_1, signal_2 = interpolate((self, other))
|
|
||||||
else:
|
|
||||||
signal_1, signal_2 = self, other
|
|
||||||
|
|
||||||
return Signal(
|
|
||||||
signal_1.frequencies,
|
|
||||||
signal_1.y * signal_2.y,
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return Signal(
|
|
||||||
self.x,
|
|
||||||
other * self.y,
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
def __truediv__(self, other: ArrayLike | Signal) -> Signal:
|
|
||||||
"""
|
|
||||||
Divide a signal by a value
|
|
||||||
"""
|
|
||||||
if isinstance(other, Signal):
|
|
||||||
if len(other) != len(self):
|
|
||||||
signal_1, signal_2 = interpolate((self, other))
|
|
||||||
else:
|
|
||||||
signal_1, signal_2 = self, other
|
|
||||||
|
|
||||||
return Signal(
|
|
||||||
signal_1.frequencies,
|
|
||||||
signal_1.y / signal_2.y,
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return Signal(
|
|
||||||
self.x,
|
|
||||||
self.y / other,
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
def __array__(self) -> NDArray[float64]:
|
|
||||||
"""
|
|
||||||
Convert to a numpy array
|
|
||||||
"""
|
|
||||||
return array(
|
|
||||||
[
|
|
||||||
self.x,
|
|
||||||
self.y,
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
def __abs__(self) -> Signal:
|
|
||||||
"""
|
|
||||||
Absolute value of the signal
|
|
||||||
"""
|
|
||||||
return Signal(
|
|
||||||
self.x,
|
|
||||||
abs(self.y),
|
|
||||||
self.settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
def __getitem__(self, key: int) -> float64:
|
|
||||||
"""
|
|
||||||
Get an element of the signal
|
|
||||||
"""
|
|
||||||
return self.y[key]
|
|
||||||
|
|
||||||
def __len__(self) -> int:
|
|
||||||
"""
|
|
||||||
Get length of a signal
|
|
||||||
"""
|
|
||||||
return len(self.x)
|
|
||||||
|
|
||||||
def __pow__(self, other: float | int) -> Signal:
|
|
||||||
"""
|
|
||||||
Signal put to power
|
|
||||||
"""
|
|
||||||
return Signal(
|
|
||||||
self.x,
|
|
||||||
self.y**other,
|
|
||||||
self.settings,
|
|
||||||
)
|
|
Loading…
Reference in a new issue