From 004c4d47dc9b5cda334538b98f4611af720320dd Mon Sep 17 00:00:00 2001 From: "Mads M. Pedersen" <mmpe@dtu.dk> Date: Wed, 29 Mar 2017 11:45:23 +0200 Subject: [PATCH] Adding missing modules --- wetb/signal/__init__.py | 12 ++ wetb/signal/filters/__init__.py | 1 + wetb/signal/filters/_differentiation.py | 37 ++++++ wetb/signal/filters/frq_filters.py | 144 ++++++++++++++++++++++++ wetb/signal/nan_replace.py | 22 ++++ 5 files changed, 216 insertions(+) create mode 100644 wetb/signal/__init__.py create mode 100644 wetb/signal/filters/_differentiation.py create mode 100644 wetb/signal/filters/frq_filters.py create mode 100644 wetb/signal/nan_replace.py diff --git a/wetb/signal/__init__.py b/wetb/signal/__init__.py new file mode 100644 index 00000000..42d8da65 --- /dev/null +++ b/wetb/signal/__init__.py @@ -0,0 +1,12 @@ + +d = None +d = dir() + +from .interpolation import interpolate + + +__all__ = [m for m in set(dir()) - set(d)] + + + + diff --git a/wetb/signal/filters/__init__.py b/wetb/signal/filters/__init__.py index 8de8c9ca..ebe5b72c 100644 --- a/wetb/signal/filters/__init__.py +++ b/wetb/signal/filters/__init__.py @@ -1 +1,2 @@ +from ._despike import * from ._differentiation import * \ No newline at end of file diff --git a/wetb/signal/filters/_differentiation.py b/wetb/signal/filters/_differentiation.py new file mode 100644 index 00000000..16caa027 --- /dev/null +++ b/wetb/signal/filters/_differentiation.py @@ -0,0 +1,37 @@ +''' +Created on 29. mar. 2017 + +@author: mmpe +''' +from wetb.signal.filters.frq_filters import low_pass +import numpy as np +def differentiation(x,sample_frq=None, cutoff_frq=None): + """Differentiate the signal + + Parameters + ---------- + x : array_like + The input signal + sample_frq : int, float or None, optional + sample frequency of signal (only required if low pass filer is applied) + cutoff_frq : int, float or None, optional + Low pass filter cut off (frequencies higher than this frequency will be suppressed) + Returns + ------- + y : ndarray + differentiated signal + + + Examples + -------- + >>> differentiation([1,2,1,0,1,1]) + """ + + + if cutoff_frq is not None: + assert sample_frq is not None, "Argument sample_frq must be set to apply low pass filter" + x = low_pass(x, sample_frq, cutoff_frq) + else: + x = np.array(x) + dy = np.r_[x[1]-x[0], (x[2:]-x[:-2])/2, x[-1]-x[-2]] + return dy \ No newline at end of file diff --git a/wetb/signal/filters/frq_filters.py b/wetb/signal/filters/frq_filters.py new file mode 100644 index 00000000..58dec73c --- /dev/null +++ b/wetb/signal/filters/frq_filters.py @@ -0,0 +1,144 @@ +''' +Created on 27. mar. 2017 + +@author: mmpe +''' +import numpy as np +from scipy import signal + +def sine_generator(sample_frq, sine_frq, duration): + """Create a sine signal for filter test + + Parameters + ---------- + sample_frq : int, float + Sample frequency of returned signal [Hz] + sine_frq : int, float + Frequency of sine signal [Hz] + duration : int, float + Duration of returned signal [s] + + Returns + ------- + t,sig : ndarray, ndarray + time (t) and sine signal (sig) + + Examples + -------- + >>> sine_generator(10,1,2) + """ + T = duration + nsamples = sample_frq * T + w = 2. * np.pi * sine_frq + t = np.linspace(0, T, nsamples, endpoint=False) + sig = np.sin(w * t) + return t, sig + + +def low_pass(x, sample_frq, cutoff_frq, order=5): + """Low pass filter (butterworth) + + Parameters + ---------- + x : array_like + Input signal + sample_frq : int, float + Sample frequency [Hz] + cutoff_frq : int, float + Cut off frequency [Hz] + order : int + Order of the filter (1th order: 20db per decade, 2th order:) + + Returns + ------- + y : ndarray + Low pass filtered signal + + + Examples + -------- + >>> + """ + nyquist_frq = 0.5 * sample_frq + normal_cutoff = cutoff_frq / nyquist_frq + b,a = signal.butter(order, normal_cutoff, btype='low', analog=False) + return signal.filtfilt(b, a, x) + +def high_pass(x, sample_frq, cutoff_frq, order=5): + """Low pass filter (butterworth) + + Parameters + ---------- + x : array_like + Input signal + sample_frq : int, float + Sample frequency [Hz] + cutoff_frq : int, float + Cut off frequency [Hz] + order : int + Order of the filter (1th order: 20db per decade, 2th order:) + + Returns + ------- + y : ndarray + Low pass filtered signal + + + Examples + -------- + >>> + """ + nyquist_frq = 0.5 * sample_frq + normal_cutoff = cutoff_frq / nyquist_frq + b,a = signal.butter(order, normal_cutoff, btype='high', analog=False) + return signal.filtfilt(b, a, x) + +def frequency_response(sample_frq, cutoff_frq, type, order, plt=None): + """Frequency response of low/high pass filter (butterworth + + Parameters + ---------- + sample_frq : int, float + Sample frequency [Hz] + cutoff_frq : int, float + Cut off frequency [Hz] + type : {'low','high'} + Low or high pass filter + order : int + Order of the filter (1th order: 20db per decade, 2th order: 40db per decade) + plt : pyplot, optional + If specified, the frequency response is plotted + + Returns + ------- + w,h : ndarray, ndarray + Frequency (w) in Hz and filter response in db + + + Examples + -------- + >>> + """ + nyquist_frq = 0.5 * sample_frq + normal_cutoff = cutoff_frq / nyquist_frq + assert 0<normal_cutoff<1, "cutoff frequency must be <= nyquist frequency" + b,a = signal.butter(order, cutoff_frq, btype=type, analog=True) + w, h = signal.freqs(b, a) + h_db = 20 * np.log10(abs(h)) + if plt: + plt.plot(w, h_db, label='%d order filter response'%order) + + plt.legend(loc=0) + + title = 'Butterworth filter frequency response' + if plt.axes().get_title()!=title: + plt.title(title) + plt.xlabel('Frequency [Hz]') + plt.ylabel('Amplitude [dB]') + plt.margins(.1, .1) + plt.xscale('log') + + plt.grid(which='both', axis='both') + plt.axvline(cutoff_frq, color='green') # cutoff frequency + + return w,h_db \ No newline at end of file diff --git a/wetb/signal/nan_replace.py b/wetb/signal/nan_replace.py new file mode 100644 index 00000000..ffc691d0 --- /dev/null +++ b/wetb/signal/nan_replace.py @@ -0,0 +1,22 @@ +''' +Created on 02/11/2015 + +@author: MMPE +''' + +import numpy as np +from wetb.signal.filters import replacer +def replace_by_mean(x): + return replacer.replace_by_mean(x, np.isnan(x)) + + +def replace_by_line(x): + return replacer.replace_by_line(x, np.isnan(x)) + +def replace_by_polynomial(x, deg=3, no_base_points=12): + return replacer.replace_by_polynomial(x, np.isnan(x), deg, no_base_points) + +def max_no_nan(x): + return replacer.max_cont_mask_length(np.isnan(x)) + + -- GitLab