Ejemplo n.º 1
0
def autoregressiveSpectrogram(data,
                              window=2.0,
                              overlap=1.0,
                              frequency_resolution=0.5,
                              fs=100,
                              order=50):
    configuration = {"Window": window, "Overlap": overlap}
    window = int(window * fs)
    overlap = int(overlap * fs)
    NFFT = int(fs / frequency_resolution)
    epochs = getIndices(len(data), window, overlap)
    frequency = np.array(
        pyule(np.array(1), order, NFFT=NFFT, sampling=fs).frequencies())
    spectrum = np.ndarray((len(frequency), len(epochs)))
    for index in range(len(epochs)):
        p = pyule(data[epochs[index]:epochs[index] + window],
                  order,
                  NFFT=NFFT,
                  sampling=fs)
        spectrum[:, index] = p.psd
    time = (epochs + window) / fs

    return dict({
        "Time": time,
        "Frequency": frequency,
        "Power": spectrum,
        "logPower": 10 * np.log10(spectrum),
        "Config": configuration
    })
Ejemplo n.º 2
0
def create_all_psd():

    f = pylab.linspace(0, 1, 4096)

    pylab.figure(figsize=(12,8))

    # MA model
    p = spectrum.pma(xx, 64,128); p(); p.plot()
    """
    #ARMA 15 order
    a, b, rho = spectrum.arma_estimate(data, 15,15, 30)
    psd = spectrum.arma2psd(A=a,B=b, rho=rho)
    newpsd = tools.cshift(psd, len(psd)//2) # switch positive and negative freq
    pylab.plot(f, 10 * pylab.log10(newpsd/max(newpsd)), label='ARMA 15,15')
    """
    # YULE WALKER
    p = spectrum.pyule(xx, 7 , NFFT=4096, scale_by_freq=False); p.plot()
    # equivalent to
    # plot([x for x in p.frequencies()] , 10*log10(p.psd)); grid(True)

    #burg method
    p = spectrum.pburg(xx, 7, scale_by_freq=False);  p.plot()

    #pcovar
    p = spectrum.pcovar(xx, 7, scale_by_freq=False);  p.plot()

    #pmodcovar
    p = spectrum.pmodcovar(xx, 7, scale_by_freq=False); p.plot()

    # correlogram
    p = spectrum.pcorrelogram(xx, lag=60, NFFT=512, scale_by_freq=False); p.plot()

    # minvar
    p = spectrum.pminvar(xx, 7, NFFT=256, scale_by_freq=False); p.plot()

    # pmusic
    p = spectrum.pmusic(xx, 10,4, scale_by_freq=False); p.plot()

    # pmusic
    p = spectrum.pev(xx, 10, 4, scale_by_freq=False); p.plot()

    # periodogram
    p = spectrum.Periodogram(xx, scale_by_freq=False); p.plot()

    #
    legend( ["MA 32", "pyule 7", "pburg 7", "pcovar", "pmodcovar", "correlogram",
                "minvar", "pmusic", "pev", "periodgram"])


    pylab.ylim([-80,80])
Ejemplo n.º 3
0
        def apply_(self, d):
            S = self.noise_filter.apply_(d).data[:, -self.noise_filter.nsamples:, :]
            nchannels, nsamples, ntrials = S.shape

            data = np.zeros((self.nfrequencies, d.ninstances))
            for trial in range(ntrials):
                P = np.zeros((self.nharmonics, nchannels, self.nfrequencies))
                for freq in range(self.nfrequencies):
                    for ch in range(nchannels):
                        for harm in range(self.nharmonics):
                            P[harm,ch,freq] = np.linalg.norm(S[ch,:,trial].dot(self.data[...,harm,freq]))            
                P = P**2
                
                tildeS = S[...,trial].dot(self.noise_filter.SSVEPRemovalMatrix)
                
                Pxx = np.zeros((np.ceil((nsamples+1)/2.0), nchannels))
                nPxxRows = Pxx.shape[0]
                
                for ch in range(nchannels):
                    p = spectrum.pyule(tildeS[ch,:], self.ar_order, NFFT=nsamples)
                    p()
                    Pxx[:,ch] = p.psd
                    
                sigma = np.zeros((self.nharmonics, nchannels, self.nfrequencies))
                div = self.sample_rate / float(nsamples)
                
                for f, freq in enumerate(self.frequencies):
                    for ch in range(nchannels):
                        for h, harm in enumerate(self.harmonics):
                            ind = round(freq * harm / div)
                            sigma[h,ch,f] = np.mean(Pxx[max(0,ind-1):min(ind+2, nPxxRows-1),ch])
                            
                SNRs = np.reshape(P / sigma, (self.nharmonics*nchannels, self.nfrequencies))
                nSNRs = SNRs.shape[0]
                
                if self.weights is None:
                    self.weights = np.ones(nSNRs) / float(nSNRs)
                else:
                    if len(self.weights) > nSNRs:
                        self.weights = self.weights[:nSNRs]
                    elif len(self.weights) < nSNRs:
                         raise ValueError('inconsistent weight vector size')
                            
                data[:,trial] = self.weights.dot(SNRs)

            feat_lab = ['%d Hz' % f for f in self.frequencies] 

            return DataSet(data=data, feat_lab=feat_lab, default=d)
Ejemplo n.º 4
0
def create_all_psd():

    f = pylab.linspace(0, 1, 4096)

    pylab.figure(figsize=(12, 8))

    # MA model
    p = spectrum.pma(xx, 64, 128)
    p()
    p.plot()
    """
    #ARMA 15 order
    a, b, rho = spectrum.arma_estimate(data, 15,15, 30)
    psd = spectrum.arma2psd(A=a,B=b, rho=rho)
    newpsd = tools.cshift(psd, len(psd)//2) # switch positive and negative freq
    pylab.plot(f, 10 * pylab.log10(newpsd/max(newpsd)), label='ARMA 15,15')
    """
    # YULE WALKER
    p = spectrum.pyule(xx, 7, NFFT=4096, scale_by_freq=False)
    p.plot()
    # equivalent to
    # plot([x for x in p.frequencies()] , 10*log10(p.psd)); grid(True)

    #burg method
    p = spectrum.pburg(xx, 7, scale_by_freq=False)
    p.plot()

    #pcovar
    p = spectrum.pcovar(xx, 7, scale_by_freq=False)
    p.plot()

    #pmodcovar
    p = spectrum.pmodcovar(xx, 7, scale_by_freq=False)
    p.plot()

    # correlogram
    p = spectrum.pcorrelogram(xx, lag=60, NFFT=512, scale_by_freq=False)
    p.plot()

    # minvar
    p = spectrum.pminvar(xx, 7, NFFT=256, scale_by_freq=False)
    p.plot()

    # pmusic
    p = spectrum.pmusic(xx, 10, 4, scale_by_freq=False)
    p.plot()

    # pmusic
    p = spectrum.pev(xx, 10, 4, scale_by_freq=False)
    p.plot()

    # periodogram
    p = spectrum.Periodogram(xx, scale_by_freq=False)
    p.plot()

    #
    legend([
        "MA 32", "pyule 7", "pburg 7", "pcovar", "pmodcovar", "correlogram",
        "minvar", "pmusic", "pev", "periodgram"
    ])

    pylab.ylim([-80, 80])
Ejemplo n.º 5
0
def ar_psd(nni=None,
		   rpeaks=None,
		   fbands=None,
		   nfft=2**12,
		   order=16,
		   show=True,
		   show_param=True,
		   legend=True,
		   mode='normal'):
	"""Computes a Power Spectral Density (PSD) estimation from the NNI series using the Autoregressive method
	and computes all frequency domain parameters from this PSD according to the specified frequency bands.

	References: [Electrophysiology1996], [Kuusela2014], [Kallas2012], [Boardman2002]
				(additionally recommended: [Miranda2012])
	Docs:		https://pyhrv.readthedocs.io/en/latest/_pages/api/frequency.html#autoregressive-method-ar-psd

	Parameters
	----------
	rpeaks : array
		R-peak locations in [ms] or [s]
	nni : array
		NN-Intervals in [ms] or [s]
	fbands : dict, optional
		Dictionary with frequency bands (2-element tuples or list)
		Value format:	(lower_freq_band_boundary, upper_freq_band_boundary)
		Keys:	'ulf'	Ultra low frequency		(default: none) optional
				'vlf'	Very low frequency		(default: (0.003Hz, 0.04Hz))
				'lf'	Low frequency			(default: (0.04Hz - 0.15Hz))
				'hf'	High frequency			(default: (0.15Hz - 0.4Hz))´
	nfft : int, optional
		Number of points computed for the entire AR result (default: 2**12)
	order : int, optional
		Autoregressive model order (default: 16)
	show : bool, optional
		If true, show PSD plot (default: True)
	show_param : bool, optional
		If true, list all computed PSD parameters next to the plot (default: True)
	legend : bool, optional
		If true, add a legend with frequency bands to the plot (default: True)

	Returns
	-------
	results : biosppy.utils.ReturnTuple object
		All results of the Autoregressive PSD estimation (see list and keys below)

	Returned Parameters & Keys
	--------------------------
	..	Peak frequencies of all frequency bands in [Hz] (key: 'ar_peak')
	..	Absolute powers of all frequency bands in [ms^2][(key: 'ar_abs')
	..	Relative powers of all frequency bands [%] (key: 'ar_rel')
	..	Logarithmic powers of all frequency bands [-] (key: 'ar_log')
	..	Normalized powers of all frequency bands [-] (key: 'ar_norms')
	..	LF/HF ratio [-] (key: 'ar_ratio')
	..	Total power over all frequency bands in [ms^2] (key: 'ar_total')
	..	Interpolation method (key: 'ar_interpolation')
	..	Resampling frequency (key: 'ar_resampling_frequency')
	.. 	AR model order (key: 'ar_order')
	.. 	Number of PSD samples (key: 'ar_nfft')

	Notes
	-----
	..	The returned BioSPPy ReturnTuple object contains all frequency band parameters in parameter specific tuples
		of length 4 when using the ULF frequency band or of length 3 when NOT using the ULF frequency band.
		The structures of those tuples are shown in this example below (lomb_results = ReturnTuple object returned by
		this function):

			Using ULF, VLF, LF and HF frequency bands:
				lomb['ar_peak'] = (ulf_peak, vlf_peak, lf_peak, hf_peak)

			Using VLF, LF and HF frequency bands:
				lomb['ar_peak'] = (vlf_peak, lf_peak, hf_peak)

	..	If 'show_param' is true, the parameters (incl. frequency band limits) will be listed next to the graph and no
		legend with frequency band limits will be added to the plot graph itself, i.e. the effect of 'show_param'
		will be used over the 'legend' effect.
	..	Only one type of input data is required.
	.. 	If both 'nni' and 'rpeaks' are provided, 'rpeaks' will be chosen over the 'nni' and the 'nni' data will be computed
		from the 'rpeaks'.
	..	NN and R-peak series provided in [s] format will be converted to [ms] format.

	"""
	# Check input
	nn = tools.check_input(nni, rpeaks)

	# Verify or set default frequency bands
	fbands = _check_freq_bands(fbands)

	# Resampling (with 4Hz) and interpolate
	# Because RRi are unevenly spaced we must interpolate it for accurate PSD estimation.
	fs = 4
	t = np.cumsum(nn)
	t -= t[0]
	f_interpol = sp.interpolate.interp1d(t, nn, 'cubic')
	t_interpol = np.arange(t[0], t[-1], 1000./fs)
	nn_interpol = f_interpol(t_interpol)

	# Compute autoregressive PSD
	ar = spectrum.pyule(data=nn_interpol, order=order, NFFT=nfft, sampling=fs, scale_by_freq=False)
	ar()

	# Get frequencies and powers
	frequencies = np.asarray(ar.frequencies())
	psd = np.asarray(ar.psd)
	powers = np.asarray(10 * np.log10(psd) * 10**3) 	# * 10**3 to compensate with ms^2 to s^2 conversion
														# in the upcoming steps

	# Define metadata
	meta = utils.ReturnTuple((nfft, order, fs, 'cubic'), ('ar_nfft', 'ar_order', 'ar_resampling_frequency',
														  'ar_interpolation'))

	if mode not in ['normal', 'dev', 'devplot']:
		warnings.warn("Unknown mode '%s'. Will proceed with 'normal' mode." % mode, stacklevel=2)
		mode = 'normal'

	# Normal Mode:
	# Returns frequency parameters, PSD plot figure and no frequency & power series/arrays
	if mode == 'normal':
		# Compute frequency parameters
		params, freq_i = _compute_parameters('ar', frequencies, powers, fbands)

		# Plot PSD
		figure = _plot_psd('ar', frequencies, powers, freq_i, params, show, show_param, legend)
		figure = utils.ReturnTuple((figure, ), ('ar_plot', ))

		# Complete output
		return tools.join_tuples(params, figure)

	# Dev Mode:
	# Returns frequency parameters and frequency & power series/array; does not create a plot figure nor plot the data
	elif mode == 'dev':
		# Compute frequency parameters
		params, _ = _compute_parameters('ar', frequencies, powers, fbands)

		# Output
		return tools.join_tuples(params, meta), frequencies, (powers / 10 ** 6)

	# Devplot Mode:
	# Returns frequency parameters, PSD plot figure, and frequency & power series/arrays
	elif mode == 'devplot':
		# Compute frequency parameters
		params, freq_i = _compute_parameters('ar', frequencies, powers, fbands)

		# Plot PSD
		figure = _plot_psd('ar', frequencies, powers, freq_i, params, show, show_param, legend)
		figure = utils.ReturnTuple((figure, ), ('ar_plot', ))

		# Complete output
		return tools.join_tuples(params, figure, meta), frequencies, (powers / 10 ** 6)
    def ar_psd(self,
               nni=None,
               rpeaks=None,
               fbands=None,
               nfft=2**12,
               order=16,
               show=True,
               show_param=True,
               legend=True,
               mode='normal'):
        # Check input
        nn = tools.check_input(nni, rpeaks)

        # Verify or set default frequency bands
        fbands = self._check_freq_bands(fbands)

        # Resampling (with 4Hz) and interpolate
        # Because RRi are unevenly spaced we must interpolate it for accurate PSD estimation.
        fs = 4
        t = np.cumsum(nn)
        t -= t[0]
        f_interpol = sp.interpolate.interp1d(t, nn, 'cubic')
        t_interpol = np.arange(t[0], t[-1], 1000. / fs)
        nn_interpol = f_interpol(t_interpol)

        # Compute autoregressive PSD
        ar = spectrum.pyule(data=nn_interpol,
                            order=order,
                            NFFT=nfft,
                            sampling=fs,
                            scale_by_freq=False)
        ar()

        # Get frequencies and powers
        frequencies = np.asarray(ar.frequencies())
        psd = np.asarray(ar.psd)
        powers = np.asarray(
            10 * np.log10(psd) *
            10**3)  # * 10**3 to compensate with ms^2 to s^2 conversion
        # in the upcoming steps

        # Define metadata
        meta = utils.ReturnTuple(
            (nfft, order, fs, 'cubic'),
            ('ar_nfft', 'ar_order', 'ar_resampling_frequency',
             'ar_interpolation'))

        if mode not in ['normal', 'dev', 'devplot']:
            warnings.warn(
                "Unknown mode '%s'. Will proceed with 'normal' mode." % mode,
                stacklevel=2)
            mode = 'normal'

        # Normal Mode:
        # Returns frequency parameters, PSD plot figure and no frequency & power series/arrays
        if mode == 'normal':
            # Compute frequency parameters
            params, freq_i = self._compute_parameters('ar', frequencies,
                                                      powers, fbands)

            # Plot PSD
            figure = self._plot_psd('ar', frequencies, powers, freq_i, params,
                                    show, show_param, legend)
            figure = utils.ReturnTuple((figure, ), ('ar_plot', ))

            # Complete output
            return tools.join_tuples(params, figure)

        # Dev Mode:
        # Returns frequency parameters and frequency & power series/array; does not create a plot figure nor plot the data
        elif mode == 'dev':
            # Compute frequency parameters
            params, _ = self._compute_parameters('ar', frequencies, powers,
                                                 fbands)

            # Output
            return tools.join_tuples(params,
                                     meta), frequencies, (powers / 10**6)

        # Devplot Mode:
        # Returns frequency parameters, PSD plot figure, and frequency & power series/arrays
        elif mode == 'devplot':
            # Compute frequency parameters
            params, freq_i = self._compute_parameters('ar', frequencies,
                                                      powers, fbands)

            # Plot PSD
            figure = self._plot_psd('ar', frequencies, powers, freq_i, params,
                                    show, show_param, legend)
            figure = utils.ReturnTuple((figure, ), ('ar_plot', ))

            # Complete output
            return tools.join_tuples(params, figure,
                                     meta), frequencies, (powers / 10**6)
Ejemplo n.º 7
0
pyule
=======================


"""
###########################################################
# Context
# ----------

##############################################
# Example
# --------
#
# In the following example, we use pyule to analyse 1000 noisy signals.
# We plot them in gray and the average in red.
#
from spectrum import pyule
from scipy.signal import lfilter
from pylab import plot, mean, log10, randn
from numpy import array
allpsds = []
a = array([1, -2.2137, 2.9403, -2.1697, 0.9606])

for this in range(1000):
    x = lfilter([1], a, randn(1, 256))
    p = pyule(x[0], 4, scale_by_freq=False, NFFT=256)
    p.plot(color='gray', alpha=0.1)
    allpsds.append(p.psd)

plot(p.frequencies(), 10 * log10(mean(allpsds, axis=0)), "red")
Ejemplo n.º 8
0

"""
###########################################################
# Context
# ----------

##############################################
# Example 
# --------
#
# In the following example, we use pyule to analyse 1000 noisy signals.
# We plot them in gray and the average in red.
#
from spectrum import pyule
from scipy.signal import lfilter
from pylab import plot, mean, log10, randn
from numpy import array
allpsds = []
a = array([1,-2.2137,2.9403,-2.1697,0.9606])

for this in range(1000):
    x = lfilter([1], a, randn(1,256))
    p = pyule(x[0],4, scale_by_freq=False, NFFT=256)
    p.plot(color='gray', alpha=0.1)
    allpsds.append(p.psd)

plot(p.frequencies(), 10*log10(mean(allpsds, axis=0)), "red")


Ejemplo n.º 9
0
def ar_psd(nni=None,
           rpeaks=None,
           fbands=None,
           nfft=2**10,
           detrend=True,
           order=16,
           fs=4,
           show=True,
           show_param=True,
           legend=True,
           mode='normal'):
    """
    Parameters
	----------
	rpeaks : array
		R-peak locations in [ms] or [s]
	nni : array
		NN-Intervals in [ms] or [s]
	fbands : dict, optional
		Dictionary with frequency bands (2-element tuples or list)
		Value format:	(lower_freq_band_boundary, upper_freq_band_boundary)
		Keys:	'ulf'	Ultra low frequency		(default: none) optional
				'vlf'	Very low frequency		(default: (0.003Hz, 0.04Hz))
				'lf'	Low frequency			(default: (0.04Hz - 0.15Hz))
				'hf'	High frequency			(default: (0.15Hz - 0.4Hz))´
	nfft : int, optional
		Number of points computed for the entire AR result (default: 2**12)
	order : int, optional
		Autoregressive model order (default: 16)
	show : bool, optional
		If true, show PSD plot (default: True)
	show_param : bool, optional
		If true, list all computed PSD parameters next to the plot (default: True)
	legend : bool, optional
		If true, add a legend with frequency bands to the plot (default: True)

	Returns
	-------
	results : biosppy.utils.ReturnTuple object
		All results of the Autoregressive PSD estimation (see list and keys below)

	Returned Parameters & Keys
	--------------------------
	..	Peak frequencies of all frequency bands in [Hz] (key: 'ar_peak')
	..	Absolute powers of all frequency bands in [ms^2][(key: 'ar_abs')
	..	Relative powers of all frequency bands [%] (key: 'ar_rel')
	..	Logarithmic powers of all frequency bands [-] (key: 'ar_log')
	..	Normalized powers of all frequency bands [-] (key: 'ar_norms')
	..	LF/HF ratio [-] (key: 'ar_ratio')
	..	Total power over all frequency bands in [ms^2] (key: 'ar_total')
	..	Interpolation method (key: 'ar_interpolation')
	..	Resampling frequency (key: 'ar_resampling_frequency')
	.. 	AR model order (key: 'ar_order')
	.. 	Number of PSD samples (key: 'ar_nfft')
    """

    # Check input
    nn = tools.check_input(nni, rpeaks)

    # Verify or set default frequency bands
    fbands = fd._check_freq_bands(fbands)

    # 外れ値をスプライン補間
    #nni = _artefact_correction(nni,threshold=0.25)

    # 4Hzでリサンプリング
    nn_interpol = detrending.resample_to_4Hz(nni, fs)

    # 平滑化
    if detrend:
        nn_interpol = detrending.detrend(nn_interpol, Lambda=500)

    # deternd means
    nn_interpol = nn_interpol - np.mean(nn_interpol)

    # Compute autoregressive PSD
    ar = spectrum.pyule(data=nn_interpol,
                        order=order,
                        NFFT=nfft,
                        sampling=fs,
                        scale_by_freq=False)

    # Get frequencies and powers
    frequencies = np.asarray(ar.frequencies())
    powers = np.asarray(ar.psd)

    # Compute frequency parameters
    params, freq_i = fd._compute_parameters('ar', frequencies, powers, fbands)

    # Plot PSD
    #figure = fd._plot_psd('ar', frequencies, powers, freq_i, params, show, show_param, legend)
    #figure = biosppy.utils.ReturnTuple((figure, ), ('ar_plot', ))

    # Complete output
    #return tools.join_tuples(params, figure)
    return params