# Source code for egegsignals.parameters

```# egegsignals - Software for processing electrogastroenterography signals.

# Copyright (C) 2013 -- 2017 Aleksandr Popov

# This program is free software: you can redistribute it and/or modify
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

""" Parametes of electrogastroenterography signals and some help functions.

"""

import numpy as np
import scipy.fftpack
from scipy import signal

egeg_fs = {
'colon' : (0.01, 0.03),
'stomach' : (0.03, 0.07),
'ileum' : (0.07, 0,13),
'nestis' : (0.13, 0.18),
'duodenum' : (0.18, 0.25),
}

[docs]def spectrum(x):
"""Return amplitude spectrum of signal.

Parameters
----------
x : array_like
Signal.

Returns
-------
: numpy.array
Two-side amplitude spectrum.

"""
return abs(scipy.fftpack.fft(x))

[docs]def expand_to(x, new_len):
"""Add zeros to signal. For doing magick with resolution in spectrum.

Returns
-------
: numpy.array
Signal expanded by zeros.

"""
if new_len <= len(x):
return x
x_exp = np.zeros(new_len)
x_exp[0 : len(x)] = x
return x_exp

[docs]def dominant_frequency(spectrum, dt, fs):
"""
Return dominant frequency of signal in band of frequencies.

Parameters
----------
spectrum : array_like
Pre-calculated spectrum.
dt : float
Sampling period.
fs : array_like
Two frequencies bounds.

Returns
-------
: float
Value of parameter.

"""
f = np.fft.fftfreq(len(spectrum), dt)
ind = (f>=fs[0]) & (f<=fs[1])
df_ind = spectrum[ind].argmax()
return f[ind][df_ind]

[docs]def energy(spectrum, dt, fs):
"""
Return the energy of the part of the specturm.

Parameters
----------
spectrum : array_like
Pre-calculated spectrum.
dt : float
Sampling period
fs : array_like
Two frequencies bounds

Returns
-------
: float
Value of parameter.

"""
f = np.fft.fftfreq(len(spectrum),dt)
ind = (f>=fs[0]) & (f<=fs[1])
return dt * sum(spectrum[ind]**2) / len(spectrum)

[docs]def power(spectrum, dt, fs):
"""
Return the power of the part of the specturm.

Parameters
----------
spectrum : array_like
Pre-calculated spectrum.
dt : float
Sampling period
fs : array_like
Two frequencies bounds

Returns
-------
: float
Value of parameter.

"""
return energy(spectrum, dt, fs) / (len(spectrum) * dt)

[docs]def rhythmicity(spectrum, dt, fs):
"""
Return Gastroscan-GEM version of the rhythmicity coefficient. Do not use it.

Parameters
----------
spectrum : array_like
Pre-calculated spectrum.
dt : float
Sampling period
fs : array_like
Two frequencies bounds

Returns
-------
: float
Value of parameter.

"""
f = np.fft.fftfreq(len(spectrum),dt)
ind = (f>=fs[0]) & (f<=fs[1])
spectrum = spectrum[ind]
envelope = sum([abs(spectrum[i] - spectrum[i-1]) for i in range(len(spectrum))])
return  envelope / len(spectrum)

[docs]def rhythmicity_norm(spectrum, dt, fs):
"""
Return normalized Gastroscan-GEM version of the rhythmicity coefficient.

Parameters
----------
spectrum : array_like
Pre-calculated spectrum.
dt : float
Sampling period
fs : array_like
Two frequencies bounds

Returns
-------
: float
Value of parameter.

"""
f = np.fft.fftfreq(len(spectrum),dt)
ind = (f>=fs[0]) & (f<=fs[1])
spectrum = spectrum[ind]
envelope = sum([abs(spectrum[i] - spectrum[i-1]) for i in range(len(spectrum))])
return  envelope / len(spectrum) / np.max(spectrum)

[docs]def stft(x, dt, nseg, nstep, window='hanning', nfft=None, padded=False):
"""
Return result of short-time fourier transform.

Parameters
----------
x : numpy.ndarray
Signal.
dt : float
Sampling period.
window : str
Type of window.
nseg : int
Length of segment (in samples).
nstep : int
Length of step (in samples).
nfft : int
Length of the FFT. If None or less than nseg, the FFT length is nseg.

Returns
-------

: list of numpy.ndarray
Result of STFT.

"""
wind = signal.get_window(window, nseg)
Xs=[]
L = len(x) + (nseg - len(x) % nseg) % nseg
x = expand_to(x, L)

if not nfft:
nseg_exp = nseg
else:
nseg_exp = max(nseg, nfft)

for i in range(0, len(x)-nseg + 1, nstep):
seg = x[i : i+nseg] * wind
seg = expand_to(seg, nseg_exp)
X = spectrum(seg)
Xs.append(X)
return Xs

[docs]def dfic(fs, x, dt, nseg, nstep, window='hanning', nfft=None, padded=False):
"""
Return dominant frequency instability coefficient.

Parameters
----------
fs : array_like
Two frequencies bounds
x : numpy.ndarray
Signal.
dt : float
Sampling period.
window : str
Type of window.
nseg : int
Length of segment (in samples).
nstep : int
Length of step (in samples).
nfft : int
Length of the FFT. Use it for doing magick with resolution in spectrum. If None or less than nseg, the FFT length is nseg.

Returns
-------
: float
Value of parameter.

"""
Xs = stft(x, dt, nseg, nstep, window, nfft, padded)
dfs = np.array([dominant_frequency(X, dt, fs) for X in Xs])
return np.std(dfs) / np.average(dfs)
```