Remove old signal tool

This commit is contained in:
linarphy 2024-05-29 10:31:57 +02:00
parent d86b8ecfef
commit b8d54cdd21
No known key found for this signature in database
GPG key ID: E61920135EFF2295

View file

@ -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,
)